advapi32: Retrieve the current user SID from the server in lookup_user_account_name.
[wine] / dlls / advapi32 / security.c
1 /*
2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4  * Copyright 2006 Robert Reif
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "winreg.h"
31 #include "winsafer.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "objbase.h"
40 #include "iads.h"
41 #include "advapi32_misc.h"
42 #include "lmcons.h"
43
44 #include "wine/debug.h"
45 #include "wine/unicode.h"
46
47 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
48
49 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
50 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
51     PACL pAcl, LPDWORD cBytes);
52 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
53 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
54 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
55 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
56     LPCWSTR StringSecurityDescriptor,
57     SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
58     LPDWORD cBytes);
59 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
60
61 typedef struct _ACEFLAG
62 {
63    LPCWSTR wstr;
64    DWORD value;
65 } ACEFLAG, *LPACEFLAG;
66
67 typedef struct _MAX_SID
68 {
69     /* same fields as struct _SID */
70     BYTE Revision;
71     BYTE SubAuthorityCount;
72     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
73     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
74 } MAX_SID;
75
76 typedef struct WELLKNOWNSID
77 {
78     WCHAR wstr[2];
79     WELL_KNOWN_SID_TYPE Type;
80     MAX_SID Sid;
81 } WELLKNOWNSID;
82
83 static const WELLKNOWNSID WellKnownSids[] =
84 {
85     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
86     { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
87     { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
88     { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
89     { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
90     { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
91     { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
92     { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
93     { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
94     { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
95     { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
96     { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
97     { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
98     { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
99     { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
100     { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
101     { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
102     { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
103     { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
104     { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
105     { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
106     { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
107     { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
108     { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
109     { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
110     { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
111     { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
112     { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
113     { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
114     { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
115     { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
116     { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
117     { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
118     { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
119     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
120     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
121     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
122     { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
123     { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
124     { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
125     { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
126     { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
127     { {0,0}, WinBuiltinIncomingForestTrustBuildersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_INCOMING_FOREST_TRUST_BUILDERS  } } },
128     { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
129     { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
130     { {0,0}, WinBuiltinAuthorizationAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_AUTHORIZATIONACCESS } } },
131     { {0,0}, WinBuiltinTerminalServerLicenseServersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_TS_LICENSE_SERVERS } } },
132     { {0,0}, WinBuiltinDCOMUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_DCOM_USERS } } },
133     { {'L','W'}, WinLowLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_LOW_RID} } },
134     { {'M','E'}, WinMediumLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_MEDIUM_RID } } },
135     { {'H','I'}, WinHighLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_HIGH_RID } } },
136     { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } },
137 };
138
139 /* these SIDs must be constructed as relative to some domain - only the RID is well-known */
140 typedef struct WELLKNOWNRID
141 {
142     WELL_KNOWN_SID_TYPE Type;
143     DWORD Rid;
144 } WELLKNOWNRID;
145
146 static const WELLKNOWNRID WellKnownRids[] = {
147     { WinAccountAdministratorSid,    DOMAIN_USER_RID_ADMIN },
148     { WinAccountGuestSid,            DOMAIN_USER_RID_GUEST },
149     { WinAccountKrbtgtSid,           DOMAIN_USER_RID_KRBTGT },
150     { WinAccountDomainAdminsSid,     DOMAIN_GROUP_RID_ADMINS },
151     { WinAccountDomainUsersSid,      DOMAIN_GROUP_RID_USERS },
152     { WinAccountDomainGuestsSid,     DOMAIN_GROUP_RID_GUESTS },
153     { WinAccountComputersSid,        DOMAIN_GROUP_RID_COMPUTERS },
154     { WinAccountControllersSid,      DOMAIN_GROUP_RID_CONTROLLERS },
155     { WinAccountCertAdminsSid,       DOMAIN_GROUP_RID_CERT_ADMINS },
156     { WinAccountSchemaAdminsSid,     DOMAIN_GROUP_RID_SCHEMA_ADMINS },
157     { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS },
158     { WinAccountPolicyAdminsSid,     DOMAIN_GROUP_RID_POLICY_ADMINS },
159     { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS },
160 };
161
162
163 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
164
165 typedef struct _AccountSid {
166     WELL_KNOWN_SID_TYPE type;
167     LPCWSTR account;
168     LPCWSTR domain;
169     SID_NAME_USE name_use;
170     LPCWSTR alias;
171 } AccountSid;
172
173 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
174 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
175 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
176 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
177 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
178 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
179 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
180 static const WCHAR Blank[] = { 0 };
181 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
182 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
183 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
184 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
185 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
186 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
187 static const WCHAR CURRENT_USER[] = { 'C','U','R','R','E','N','T','_','U','S','E','R',0 };
188 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
189 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
190 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
191 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
192 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
193 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
194 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
195 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
196 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
197 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
198 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
199 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
200 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
201 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
202 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
203 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
204 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
205 static const WCHAR LOCAL_SERVICE2[] = { 'L','O','C','A','L','S','E','R','V','I','C','E',0 };
206 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
207 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
208 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
209 static const WCHAR NETWORK_SERVICE2[] = { 'N','E','T','W','O','R','K','S','E','R','V','I','C','E',0 };
210 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
211 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
212 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
213 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
214 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
215 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
216 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
217 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
218 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
219 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
220 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
221 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
222 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
223 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
224 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
225 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
226 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
227 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
228 static const WCHAR SELF[] = { 'S','E','L','F',0 };
229 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
230 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
231 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
232 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
233 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
234 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
235
236 static const AccountSid ACCOUNT_SIDS[] = {
237     { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
238     { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
239     { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
240     { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
241     { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
242     { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
243     { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
244     { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
245     { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
246     { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
247     { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
248     { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
249     { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
250     { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
251     { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
252     { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
253     { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
254     { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
255     { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
256     { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
257     { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
258     { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
259     { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup, LOCAL_SERVICE2 },
260     { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup , NETWORK_SERVICE2},
261     { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
262     { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
263     { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
264     { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
265     { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
266     { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
267     { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
268     { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
269     { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
270     { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
271     { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
272     { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
273     { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
274     { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
275     { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
276     { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
277     { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
278     { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
279     { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
280     { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
281 };
282 /*
283  * ACE access rights
284  */
285 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
286 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
287 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
288 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
289
290 static const WCHAR SDDL_READ_PROPERTY[]    = {'R','P',0};
291 static const WCHAR SDDL_WRITE_PROPERTY[]   = {'W','P',0};
292 static const WCHAR SDDL_CREATE_CHILD[]     = {'C','C',0};
293 static const WCHAR SDDL_DELETE_CHILD[]     = {'D','C',0};
294 static const WCHAR SDDL_LIST_CHILDREN[]    = {'L','C',0};
295 static const WCHAR SDDL_SELF_WRITE[]       = {'S','W',0};
296 static const WCHAR SDDL_LIST_OBJECT[]      = {'L','O',0};
297 static const WCHAR SDDL_DELETE_TREE[]      = {'D','T',0};
298 static const WCHAR SDDL_CONTROL_ACCESS[]   = {'C','R',0};
299
300 static const WCHAR SDDL_FILE_ALL[]         = {'F','A',0};
301 static const WCHAR SDDL_FILE_READ[]        = {'F','R',0};
302 static const WCHAR SDDL_FILE_WRITE[]       = {'F','W',0};
303 static const WCHAR SDDL_FILE_EXECUTE[]     = {'F','X',0};
304
305 static const WCHAR SDDL_KEY_ALL[]          = {'K','A',0};
306 static const WCHAR SDDL_KEY_READ[]         = {'K','R',0};
307 static const WCHAR SDDL_KEY_WRITE[]        = {'K','W',0};
308 static const WCHAR SDDL_KEY_EXECUTE[]      = {'K','X',0};
309
310 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
311 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
312 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
313 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
314
315 /*
316  * ACL flags
317  */
318 static const WCHAR SDDL_PROTECTED[]             = {'P',0};
319 static const WCHAR SDDL_AUTO_INHERIT_REQ[]      = {'A','R',0};
320 static const WCHAR SDDL_AUTO_INHERITED[]        = {'A','I',0};
321
322 /*
323  * ACE types
324  */
325 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
326 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
327 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
328 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
329 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
330 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
331 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
332 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
333
334 /*
335  * ACE flags
336  */
337 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
338 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
339 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
340 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
341 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
342 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
343 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
344
345 const char * debugstr_sid(PSID sid)
346 {
347     int auth = 0;
348     SID * psid = sid;
349
350     if (psid == NULL)
351         return "(null)";
352
353     auth = psid->IdentifierAuthority.Value[5] +
354            (psid->IdentifierAuthority.Value[4] << 8) +
355            (psid->IdentifierAuthority.Value[3] << 16) +
356            (psid->IdentifierAuthority.Value[2] << 24);
357
358     switch (psid->SubAuthorityCount) {
359     case 0:
360         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
361     case 1:
362         return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
363             psid->SubAuthority[0]);
364     case 2:
365         return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
366             psid->SubAuthority[0], psid->SubAuthority[1]);
367     case 3:
368         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
369             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
370     case 4:
371         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
372             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
373             psid->SubAuthority[3]);
374     case 5:
375         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
376             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
377             psid->SubAuthority[3], psid->SubAuthority[4]);
378     case 6:
379         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
380             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
381             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
382     case 7:
383         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
384             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
385             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
386             psid->SubAuthority[6]);
387     case 8:
388         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
389             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
390             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
391             psid->SubAuthority[6], psid->SubAuthority[7]);
392     }
393     return "(too-big)";
394 }
395
396 /* set last error code from NT status and get the proper boolean return value */
397 /* used for functions that are a simple wrapper around the corresponding ntdll API */
398 static inline BOOL set_ntstatus( NTSTATUS status )
399 {
400     if (status) SetLastError( RtlNtStatusToDosError( status ));
401     return !status;
402 }
403
404 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
405
406 static void GetWorldAccessACL(PACL pACL)
407 {
408     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
409
410     pACL->AclRevision = ACL_REVISION;
411     pACL->Sbz1 = 0;
412     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
413     pACL->AceCount = 1;
414     pACL->Sbz2 = 0;
415
416     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
417     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
418     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
419     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
420     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
421 }
422
423 /************************************************************
424  *                ADVAPI_IsLocalComputer
425  *
426  * Checks whether the server name indicates local machine.
427  */
428 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
429 {
430     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
431     BOOL Result;
432     LPWSTR buf;
433
434     if (!ServerName || !ServerName[0])
435         return TRUE;
436
437     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
438     Result = GetComputerNameW(buf,  &dwSize);
439     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
440         ServerName += 2;
441     Result = Result && !lstrcmpW(ServerName, buf);
442     HeapFree(GetProcessHeap(), 0, buf);
443
444     return Result;
445 }
446
447 /************************************************************
448  *                ADVAPI_GetComputerSid
449  *
450  * Reads the computer SID from the registry.
451  */
452 BOOL ADVAPI_GetComputerSid(PSID sid)
453 {
454     HKEY key;
455     LONG ret;
456     BOOL retval = FALSE;
457     static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
458     static const WCHAR V[] = { 'V',0 };
459
460     if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
461         KEY_READ, &key)) == ERROR_SUCCESS)
462     {
463         DWORD size = 0;
464         ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
465         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
466         {
467             BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
468             if (data)
469             {
470                 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
471                      data, &size)) == ERROR_SUCCESS)
472                 {
473                     /* the SID is in the last 24 bytes of the binary data */
474                     CopyMemory(sid, &data[size-24], 24);
475                     retval = TRUE;
476                 }
477                 HeapFree(GetProcessHeap(), 0, data);
478             }
479         }
480         RegCloseKey(key);
481     }
482
483     if(retval == TRUE) return retval;
484
485     /* create a new random SID */
486     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
487         0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
488     {
489         PSID new_sid;
490         SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
491         DWORD id[3];
492
493         if (RtlGenRandom(id, sizeof(id)))
494         {
495             if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
496             {
497                 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
498                     retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
499
500                 FreeSid(new_sid);
501             }
502         }
503         RegCloseKey(key);
504     }
505
506     return retval;
507 }
508
509 /*      ##############################
510         ######  TOKEN FUNCTIONS ######
511         ##############################
512 */
513
514 /******************************************************************************
515  * OpenProcessToken                     [ADVAPI32.@]
516  * Opens the access token associated with a process handle.
517  *
518  * PARAMS
519  *   ProcessHandle [I] Handle to process
520  *   DesiredAccess [I] Desired access to process
521  *   TokenHandle   [O] Pointer to handle of open access token
522  *
523  * RETURNS
524  *  Success: TRUE. TokenHandle contains the access token.
525  *  Failure: FALSE.
526  *
527  * NOTES
528  *  See NtOpenProcessToken.
529  */
530 BOOL WINAPI
531 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
532                   HANDLE *TokenHandle )
533 {
534         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
535 }
536
537 /******************************************************************************
538  * OpenThreadToken [ADVAPI32.@]
539  *
540  * Opens the access token associated with a thread handle.
541  *
542  * PARAMS
543  *   ThreadHandle  [I] Handle to process
544  *   DesiredAccess [I] Desired access to the thread
545  *   OpenAsSelf    [I] ???
546  *   TokenHandle   [O] Destination for the token handle
547  *
548  * RETURNS
549  *  Success: TRUE. TokenHandle contains the access token.
550  *  Failure: FALSE.
551  *
552  * NOTES
553  *  See NtOpenThreadToken.
554  */
555 BOOL WINAPI
556 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
557                  BOOL OpenAsSelf, HANDLE *TokenHandle)
558 {
559         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
560 }
561
562 BOOL WINAPI
563 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
564                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
565 {
566     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
567                                              PreviousState, ReturnLength));
568 }
569
570 /******************************************************************************
571  * AdjustTokenPrivileges [ADVAPI32.@]
572  *
573  * Adjust the privileges of an open token handle.
574  * 
575  * PARAMS
576  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
577  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
578  *  NewState             [I]   Desired new privileges of the token
579  *  BufferLength         [I]   Length of NewState
580  *  PreviousState        [O]   Destination for the previous state
581  *  ReturnLength         [I/O] Size of PreviousState
582  *
583  *
584  * RETURNS
585  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
586  *  Failure: FALSE.
587  *
588  * NOTES
589  *  See NtAdjustPrivilegesToken.
590  */
591 BOOL WINAPI
592 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
593                        PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
594                        PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
595 {
596     NTSTATUS status;
597
598     TRACE("\n");
599     
600     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
601                                                      NewState, BufferLength, PreviousState,
602                                                      ReturnLength);
603     SetLastError( RtlNtStatusToDosError( status ));
604     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
605         return TRUE;
606     else
607         return FALSE;
608 }
609
610 /******************************************************************************
611  * CheckTokenMembership [ADVAPI32.@]
612  *
613  * Determine if an access token is a member of a SID.
614  * 
615  * PARAMS
616  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
617  *   SidToCheck  [I] SID that possibly contains the token
618  *   IsMember    [O] Destination for result.
619  *
620  * RETURNS
621  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
622  *  Failure: FALSE.
623  */
624 BOOL WINAPI
625 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
626                       PBOOL IsMember )
627 {
628   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
629
630   *IsMember = TRUE;
631   return(TRUE);
632 }
633
634 /******************************************************************************
635  * GetTokenInformation [ADVAPI32.@]
636  *
637  * Get a type of information about an access token.
638  *
639  * PARAMS
640  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
641  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
642  *   tokeninfo       [O] Destination for token information
643  *   tokeninfolength [I] Length of tokeninfo
644  *   retlen          [O] Destination for returned token information length
645  *
646  * RETURNS
647  *  Success: TRUE. tokeninfo contains retlen bytes of token information
648  *  Failure: FALSE.
649  *
650  * NOTES
651  *  See NtQueryInformationToken.
652  */
653 BOOL WINAPI
654 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
655                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
656 {
657     TRACE("(%p, %s, %p, %d, %p):\n",
658           token,
659           (tokeninfoclass == TokenUser) ? "TokenUser" :
660           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
661           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
662           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
663           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
664           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
665           (tokeninfoclass == TokenSource) ? "TokenSource" :
666           (tokeninfoclass == TokenType) ? "TokenType" :
667           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
668           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
669           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
670           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
671           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
672           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
673           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
674           "Unknown",
675           tokeninfo, tokeninfolength, retlen);
676     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
677                                                   tokeninfolength, retlen));
678 }
679
680 /******************************************************************************
681  * SetTokenInformation [ADVAPI32.@]
682  *
683  * Set information for an access token.
684  *
685  * PARAMS
686  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
687  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
688  *   tokeninfo       [I] Token information to set
689  *   tokeninfolength [I] Length of tokeninfo
690  *
691  * RETURNS
692  *  Success: TRUE. The information for the token is set to tokeninfo.
693  *  Failure: FALSE.
694  */
695 BOOL WINAPI
696 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
697                      LPVOID tokeninfo, DWORD tokeninfolength )
698 {
699     TRACE("(%p, %s, %p, %d): stub\n",
700           token,
701           (tokeninfoclass == TokenUser) ? "TokenUser" :
702           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
703           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
704           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
705           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
706           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
707           (tokeninfoclass == TokenSource) ? "TokenSource" :
708           (tokeninfoclass == TokenType) ? "TokenType" :
709           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
710           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
711           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
712           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
713           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
714           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
715           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
716           "Unknown",
717           tokeninfo, tokeninfolength);
718
719     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
720 }
721
722 /*************************************************************************
723  * SetThreadToken [ADVAPI32.@]
724  *
725  * Assigns an 'impersonation token' to a thread so it can assume the
726  * security privileges of another thread or process.  Can also remove
727  * a previously assigned token. 
728  *
729  * PARAMS
730  *   thread          [O] Handle to thread to set the token for
731  *   token           [I] Token to set
732  *
733  * RETURNS
734  *  Success: TRUE. The threads access token is set to token
735  *  Failure: FALSE.
736  *
737  * NOTES
738  *  Only supported on NT or higher. On Win9X this function does nothing.
739  *  See SetTokenInformation.
740  */
741 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
742 {
743     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
744                                                  ThreadImpersonationToken, &token, sizeof token ));
745 }
746
747 /*************************************************************************
748  * CreateRestrictedToken [ADVAPI32.@]
749  *
750  * Create a new more restricted token from an existing token.
751  *
752  * PARAMS
753  *   baseToken       [I] Token to base the new restricted token on
754  *   flags           [I] Options
755  *   nDisableSids    [I] Length of disableSids array
756  *   disableSids     [I] Array of SIDs to disable in the new token
757  *   nDeletePrivs    [I] Length of deletePrivs array
758  *   deletePrivs     [I] Array of privileges to delete in the new token
759  *   nRestrictSids   [I] Length of restrictSids array
760  *   restrictSids    [I] Array of SIDs to restrict in the new token
761  *   newToken        [O] Address where the new token is stored
762  *
763  * RETURNS
764  *  Success: TRUE
765  *  Failure: FALSE
766  */
767 BOOL WINAPI CreateRestrictedToken(
768     HANDLE baseToken,
769     DWORD flags,
770     DWORD nDisableSids,
771     PSID_AND_ATTRIBUTES disableSids,
772     DWORD nDeletePrivs,
773     PLUID_AND_ATTRIBUTES deletePrivs,
774     DWORD nRestrictSids,
775     PSID_AND_ATTRIBUTES restrictSids,
776     PHANDLE newToken)
777 {
778     FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
779           baseToken, flags, nDisableSids, disableSids,
780           nDeletePrivs, deletePrivs,
781           nRestrictSids, restrictSids,
782           newToken);
783     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
784     return FALSE;
785 }
786
787 /*      ##############################
788         ######  SID FUNCTIONS   ######
789         ##############################
790 */
791
792 /******************************************************************************
793  * AllocateAndInitializeSid [ADVAPI32.@]
794  *
795  * PARAMS
796  *   pIdentifierAuthority []
797  *   nSubAuthorityCount   []
798  *   nSubAuthority0       []
799  *   nSubAuthority1       []
800  *   nSubAuthority2       []
801  *   nSubAuthority3       []
802  *   nSubAuthority4       []
803  *   nSubAuthority5       []
804  *   nSubAuthority6       []
805  *   nSubAuthority7       []
806  *   pSid                 []
807  */
808 BOOL WINAPI
809 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
810                           BYTE nSubAuthorityCount,
811                           DWORD nSubAuthority0, DWORD nSubAuthority1,
812                           DWORD nSubAuthority2, DWORD nSubAuthority3,
813                           DWORD nSubAuthority4, DWORD nSubAuthority5,
814                           DWORD nSubAuthority6, DWORD nSubAuthority7,
815                           PSID *pSid )
816 {
817     return set_ntstatus( RtlAllocateAndInitializeSid(
818                              pIdentifierAuthority, nSubAuthorityCount,
819                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
820                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
821                              pSid ));
822 }
823
824 /******************************************************************************
825  * FreeSid [ADVAPI32.@]
826  *
827  * PARAMS
828  *   pSid []
829  */
830 PVOID WINAPI
831 FreeSid( PSID pSid )
832 {
833         RtlFreeSid(pSid);
834         return NULL; /* is documented like this */
835 }
836
837 /******************************************************************************
838  * CopySid [ADVAPI32.@]
839  *
840  * PARAMS
841  *   nDestinationSidLength []
842  *   pDestinationSid       []
843  *   pSourceSid            []
844  */
845 BOOL WINAPI
846 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
847 {
848         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
849 }
850
851 /******************************************************************************
852  * CreateWellKnownSid [ADVAPI32.@]
853  */
854 BOOL WINAPI
855 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
856                     PSID DomainSid,
857                     PSID pSid,
858                     DWORD* cbSid)
859 {
860     unsigned int i;
861     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
862
863     if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
864     {
865         SetLastError(ERROR_INVALID_PARAMETER);
866         return FALSE;
867     }
868
869     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
870         if (WellKnownSids[i].Type == WellKnownSidType) {
871             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
872
873             if (*cbSid < length)
874             {
875                 *cbSid = length;
876                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
877                 return FALSE;
878             }
879             if (!pSid)
880             {
881                 SetLastError(ERROR_INVALID_PARAMETER);
882                 return FALSE;
883             }
884             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
885             *cbSid = length;
886             return TRUE;
887         }
888     }
889
890     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
891     {
892         SetLastError(ERROR_INVALID_PARAMETER);
893         return FALSE;
894     }
895
896     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
897         if (WellKnownRids[i].Type == WellKnownSidType) {
898             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
899             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
900             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
901
902             if (*cbSid < output_sid_length)
903             {
904                 *cbSid = output_sid_length;
905                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
906                 return FALSE;
907             }
908             if (!pSid)
909             {
910                 SetLastError(ERROR_INVALID_PARAMETER);
911                 return FALSE;
912             }
913             CopyMemory(pSid, DomainSid, domain_sid_length);
914             (*GetSidSubAuthorityCount(pSid))++;
915             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
916             *cbSid = output_sid_length;
917             return TRUE;
918         }
919
920     SetLastError(ERROR_INVALID_PARAMETER);
921     return FALSE;
922 }
923
924 /******************************************************************************
925  * IsWellKnownSid [ADVAPI32.@]
926  */
927 BOOL WINAPI
928 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
929 {
930     unsigned int i;
931     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
932
933     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
934         if (WellKnownSids[i].Type == WellKnownSidType)
935             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
936                 return TRUE;
937
938     return FALSE;
939 }
940
941 BOOL WINAPI
942 IsTokenRestricted( HANDLE TokenHandle )
943 {
944     TOKEN_GROUPS *groups;
945     DWORD size;
946     NTSTATUS status;
947     BOOL restricted;
948
949     TRACE("(%p)\n", TokenHandle);
950  
951     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
952     if (status != STATUS_BUFFER_TOO_SMALL)
953         return FALSE;
954  
955     groups = HeapAlloc(GetProcessHeap(), 0, size);
956     if (!groups)
957     {
958         SetLastError(ERROR_OUTOFMEMORY);
959         return FALSE;
960     }
961  
962     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
963     if (status != STATUS_SUCCESS)
964     {
965         HeapFree(GetProcessHeap(), 0, groups);
966         return set_ntstatus(status);
967     }
968  
969     if (groups->GroupCount)
970         restricted = TRUE;
971     else
972         restricted = FALSE;
973      
974     HeapFree(GetProcessHeap(), 0, groups);
975  
976     return restricted;
977 }
978
979 /******************************************************************************
980  * IsValidSid [ADVAPI32.@]
981  *
982  * PARAMS
983  *   pSid []
984  */
985 BOOL WINAPI
986 IsValidSid( PSID pSid )
987 {
988         return RtlValidSid( pSid );
989 }
990
991 /******************************************************************************
992  * EqualSid [ADVAPI32.@]
993  *
994  * PARAMS
995  *   pSid1 []
996  *   pSid2 []
997  */
998 BOOL WINAPI
999 EqualSid( PSID pSid1, PSID pSid2 )
1000 {
1001         return RtlEqualSid( pSid1, pSid2 );
1002 }
1003
1004 /******************************************************************************
1005  * EqualPrefixSid [ADVAPI32.@]
1006  */
1007 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1008 {
1009         return RtlEqualPrefixSid(pSid1, pSid2);
1010 }
1011
1012 /******************************************************************************
1013  * GetSidLengthRequired [ADVAPI32.@]
1014  *
1015  * PARAMS
1016  *   nSubAuthorityCount []
1017  */
1018 DWORD WINAPI
1019 GetSidLengthRequired( BYTE nSubAuthorityCount )
1020 {
1021         return RtlLengthRequiredSid(nSubAuthorityCount);
1022 }
1023
1024 /******************************************************************************
1025  * InitializeSid [ADVAPI32.@]
1026  *
1027  * PARAMS
1028  *   pIdentifierAuthority []
1029  */
1030 BOOL WINAPI
1031 InitializeSid (
1032         PSID pSid,
1033         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1034         BYTE nSubAuthorityCount)
1035 {
1036         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1037 }
1038
1039 DWORD WINAPI
1040 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1041 {
1042     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1043
1044     return 1;
1045 }
1046
1047 DWORD WINAPI
1048 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1049 {
1050     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1051
1052     return 1;
1053 }
1054
1055 /******************************************************************************
1056  * GetSidIdentifierAuthority [ADVAPI32.@]
1057  *
1058  * PARAMS
1059  *   pSid []
1060  */
1061 PSID_IDENTIFIER_AUTHORITY WINAPI
1062 GetSidIdentifierAuthority( PSID pSid )
1063 {
1064         return RtlIdentifierAuthoritySid(pSid);
1065 }
1066
1067 /******************************************************************************
1068  * GetSidSubAuthority [ADVAPI32.@]
1069  *
1070  * PARAMS
1071  *   pSid          []
1072  *   nSubAuthority []
1073  */
1074 PDWORD WINAPI
1075 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1076 {
1077         SetLastError(ERROR_SUCCESS);
1078         return RtlSubAuthoritySid(pSid, nSubAuthority);
1079 }
1080
1081 /******************************************************************************
1082  * GetSidSubAuthorityCount [ADVAPI32.@]
1083  *
1084  * PARAMS
1085  *   pSid []
1086  */
1087 PUCHAR WINAPI
1088 GetSidSubAuthorityCount (PSID pSid)
1089 {
1090         SetLastError(ERROR_SUCCESS);
1091         return RtlSubAuthorityCountSid(pSid);
1092 }
1093
1094 /******************************************************************************
1095  * GetLengthSid [ADVAPI32.@]
1096  *
1097  * PARAMS
1098  *   pSid []
1099  */
1100 DWORD WINAPI
1101 GetLengthSid (PSID pSid)
1102 {
1103         return RtlLengthSid(pSid);
1104 }
1105
1106 /*      ##############################################
1107         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
1108         ##############################################
1109 */
1110
1111  /****************************************************************************** 
1112  * BuildSecurityDescriptorA [ADVAPI32.@]
1113  *
1114  * Builds a SD from 
1115  *
1116  * PARAMS
1117  *  pOwner                [I]
1118  *  pGroup                [I]
1119  *  cCountOfAccessEntries [I]
1120  *  pListOfAccessEntries  [I]
1121  *  cCountOfAuditEntries  [I]
1122  *  pListofAuditEntries   [I]
1123  *  pOldSD                [I]
1124  *  lpdwBufferLength      [I/O]
1125  *  pNewSD                [O]
1126  *
1127  * RETURNS
1128  *  Success: ERROR_SUCCESS
1129  *  Failure: nonzero error code from Winerror.h
1130  */
1131 DWORD WINAPI BuildSecurityDescriptorA(
1132     IN PTRUSTEEA pOwner,
1133     IN PTRUSTEEA pGroup,
1134     IN ULONG cCountOfAccessEntries,
1135     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1136     IN ULONG cCountOfAuditEntries,
1137     IN PEXPLICIT_ACCESSA pListofAuditEntries,
1138     IN PSECURITY_DESCRIPTOR pOldSD,
1139     IN OUT PULONG lpdwBufferLength,
1140     OUT PSECURITY_DESCRIPTOR* pNewSD)
1141
1142     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1143           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1144           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1145  
1146     return ERROR_CALL_NOT_IMPLEMENTED;
1147
1148  
1149 /******************************************************************************
1150  * BuildSecurityDescriptorW [ADVAPI32.@]
1151  *
1152  * See BuildSecurityDescriptorA.
1153  */
1154 DWORD WINAPI BuildSecurityDescriptorW(
1155     IN PTRUSTEEW pOwner,
1156     IN PTRUSTEEW pGroup,
1157     IN ULONG cCountOfAccessEntries,
1158     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1159     IN ULONG cCountOfAuditEntries,
1160     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1161     IN PSECURITY_DESCRIPTOR pOldSD,
1162     IN OUT PULONG lpdwBufferLength,
1163     OUT PSECURITY_DESCRIPTOR* pNewSD)
1164
1165     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1166           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1167           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1168  
1169     return ERROR_CALL_NOT_IMPLEMENTED;
1170
1171
1172 /******************************************************************************
1173  * InitializeSecurityDescriptor [ADVAPI32.@]
1174  *
1175  * PARAMS
1176  *   pDescr   []
1177  *   revision []
1178  */
1179 BOOL WINAPI
1180 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1181 {
1182         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1183 }
1184
1185
1186 /******************************************************************************
1187  * MakeAbsoluteSD [ADVAPI32.@]
1188  */
1189 BOOL WINAPI MakeAbsoluteSD (
1190         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1191         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1192         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1193         OUT PACL pDacl,
1194         OUT LPDWORD lpdwDaclSize,
1195         OUT PACL pSacl,
1196         OUT LPDWORD lpdwSaclSize,
1197         OUT PSID pOwner,
1198         OUT LPDWORD lpdwOwnerSize,
1199         OUT PSID pPrimaryGroup,
1200         OUT LPDWORD lpdwPrimaryGroupSize)
1201 {
1202     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1203                                                      pAbsoluteSecurityDescriptor,
1204                                                      lpdwAbsoluteSecurityDescriptorSize,
1205                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1206                                                      pOwner, lpdwOwnerSize,
1207                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1208 }
1209
1210 /******************************************************************************
1211  * GetKernelObjectSecurity [ADVAPI32.@]
1212  */
1213 BOOL WINAPI GetKernelObjectSecurity(
1214         HANDLE Handle,
1215         SECURITY_INFORMATION RequestedInformation,
1216         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1217         DWORD nLength,
1218         LPDWORD lpnLengthNeeded )
1219 {
1220     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1221           pSecurityDescriptor, nLength, lpnLengthNeeded);
1222
1223     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1224                                                nLength, lpnLengthNeeded ));
1225 }
1226
1227 /******************************************************************************
1228  * GetPrivateObjectSecurity [ADVAPI32.@]
1229  */
1230 BOOL WINAPI GetPrivateObjectSecurity(
1231         PSECURITY_DESCRIPTOR ObjectDescriptor,
1232         SECURITY_INFORMATION SecurityInformation,
1233         PSECURITY_DESCRIPTOR ResultantDescriptor,
1234         DWORD DescriptorLength,
1235         PDWORD ReturnLength )
1236 {
1237     SECURITY_DESCRIPTOR desc;
1238     BOOL defaulted, present;
1239     PACL pacl;
1240     PSID psid;
1241
1242     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1243           ResultantDescriptor, DescriptorLength, ReturnLength);
1244
1245     if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1246         return FALSE;
1247
1248     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1249     {
1250         if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1251             return FALSE;
1252         SetSecurityDescriptorOwner(&desc, psid, defaulted);
1253     }
1254
1255     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1256     {
1257         if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1258             return FALSE;
1259         SetSecurityDescriptorGroup(&desc, psid, defaulted);
1260     }
1261
1262     if (SecurityInformation & DACL_SECURITY_INFORMATION)
1263     {
1264         if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1265             return FALSE;
1266         SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1267     }
1268
1269     if (SecurityInformation & SACL_SECURITY_INFORMATION)
1270     {
1271         if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1272             return FALSE;
1273         SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1274     }
1275
1276     *ReturnLength = DescriptorLength;
1277     return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1278 }
1279
1280 /******************************************************************************
1281  * GetSecurityDescriptorLength [ADVAPI32.@]
1282  */
1283 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1284 {
1285         return RtlLengthSecurityDescriptor(pDescr);
1286 }
1287
1288 /******************************************************************************
1289  * GetSecurityDescriptorOwner [ADVAPI32.@]
1290  *
1291  * PARAMS
1292  *   pOwner            []
1293  *   lpbOwnerDefaulted []
1294  */
1295 BOOL WINAPI
1296 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1297                             LPBOOL lpbOwnerDefaulted )
1298 {
1299     BOOLEAN defaulted;
1300     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1301     *lpbOwnerDefaulted = defaulted;
1302     return ret;
1303 }
1304
1305 /******************************************************************************
1306  * SetSecurityDescriptorOwner [ADVAPI32.@]
1307  *
1308  * PARAMS
1309  */
1310 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1311                                    PSID pOwner, BOOL bOwnerDefaulted)
1312 {
1313     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1314 }
1315 /******************************************************************************
1316  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1317  */
1318 BOOL WINAPI GetSecurityDescriptorGroup(
1319         PSECURITY_DESCRIPTOR SecurityDescriptor,
1320         PSID *Group,
1321         LPBOOL GroupDefaulted)
1322 {
1323     BOOLEAN defaulted;
1324     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1325     *GroupDefaulted = defaulted;
1326     return ret;
1327 }
1328 /******************************************************************************
1329  * SetSecurityDescriptorGroup [ADVAPI32.@]
1330  */
1331 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1332                                            PSID Group, BOOL GroupDefaulted)
1333 {
1334     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1335 }
1336
1337 /******************************************************************************
1338  * IsValidSecurityDescriptor [ADVAPI32.@]
1339  *
1340  * PARAMS
1341  *   lpsecdesc []
1342  */
1343 BOOL WINAPI
1344 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1345 {
1346     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1347 }
1348
1349 /******************************************************************************
1350  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1351  */
1352 BOOL WINAPI GetSecurityDescriptorDacl(
1353         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1354         OUT LPBOOL lpbDaclPresent,
1355         OUT PACL *pDacl,
1356         OUT LPBOOL lpbDaclDefaulted)
1357 {
1358     BOOLEAN present, defaulted;
1359     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1360     *lpbDaclPresent = present;
1361     *lpbDaclDefaulted = defaulted;
1362     return ret;
1363 }
1364
1365 /******************************************************************************
1366  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1367  */
1368 BOOL WINAPI
1369 SetSecurityDescriptorDacl (
1370         PSECURITY_DESCRIPTOR lpsd,
1371         BOOL daclpresent,
1372         PACL dacl,
1373         BOOL dacldefaulted )
1374 {
1375     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1376 }
1377 /******************************************************************************
1378  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1379  */
1380 BOOL WINAPI GetSecurityDescriptorSacl(
1381         IN PSECURITY_DESCRIPTOR lpsd,
1382         OUT LPBOOL lpbSaclPresent,
1383         OUT PACL *pSacl,
1384         OUT LPBOOL lpbSaclDefaulted)
1385 {
1386     BOOLEAN present, defaulted;
1387     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1388     *lpbSaclPresent = present;
1389     *lpbSaclDefaulted = defaulted;
1390     return ret;
1391 }
1392
1393 /**************************************************************************
1394  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1395  */
1396 BOOL WINAPI SetSecurityDescriptorSacl (
1397         PSECURITY_DESCRIPTOR lpsd,
1398         BOOL saclpresent,
1399         PACL lpsacl,
1400         BOOL sacldefaulted)
1401 {
1402     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1403 }
1404 /******************************************************************************
1405  * MakeSelfRelativeSD [ADVAPI32.@]
1406  *
1407  * PARAMS
1408  *   lpabssecdesc  []
1409  *   lpselfsecdesc []
1410  *   lpbuflen      []
1411  */
1412 BOOL WINAPI
1413 MakeSelfRelativeSD(
1414         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1415         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1416         IN OUT LPDWORD lpdwBufferLength)
1417 {
1418     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1419                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1420 }
1421
1422 /******************************************************************************
1423  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1424  */
1425
1426 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1427                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1428 {
1429     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1430 }
1431
1432 /******************************************************************************
1433  * SetSecurityDescriptorControl                 [ADVAPI32.@]
1434  */
1435 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1436   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1437   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1438 {
1439     return set_ntstatus( RtlSetControlSecurityDescriptor(
1440         pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1441 }
1442
1443 /*      ##############################
1444         ######  ACL FUNCTIONS   ######
1445         ##############################
1446 */
1447
1448 /*************************************************************************
1449  * InitializeAcl [ADVAPI32.@]
1450  */
1451 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1452 {
1453     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1454 }
1455
1456 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1457 {
1458     IO_STATUS_BLOCK io_block;
1459
1460     TRACE("(%p)\n", hNamedPipe);
1461
1462     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1463                          &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1464 }
1465
1466 /******************************************************************************
1467  *  AddAccessAllowedAce [ADVAPI32.@]
1468  */
1469 BOOL WINAPI AddAccessAllowedAce(
1470         IN OUT PACL pAcl,
1471         IN DWORD dwAceRevision,
1472         IN DWORD AccessMask,
1473         IN PSID pSid)
1474 {
1475     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1476 }
1477
1478 /******************************************************************************
1479  *  AddAccessAllowedAceEx [ADVAPI32.@]
1480  */
1481 BOOL WINAPI AddAccessAllowedAceEx(
1482         IN OUT PACL pAcl,
1483         IN DWORD dwAceRevision,
1484         IN DWORD AceFlags,
1485         IN DWORD AccessMask,
1486         IN PSID pSid)
1487 {
1488     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1489 }
1490
1491 /******************************************************************************
1492  *  AddAccessDeniedAce [ADVAPI32.@]
1493  */
1494 BOOL WINAPI AddAccessDeniedAce(
1495         IN OUT PACL pAcl,
1496         IN DWORD dwAceRevision,
1497         IN DWORD AccessMask,
1498         IN PSID pSid)
1499 {
1500     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1501 }
1502
1503 /******************************************************************************
1504  *  AddAccessDeniedAceEx [ADVAPI32.@]
1505  */
1506 BOOL WINAPI AddAccessDeniedAceEx(
1507         IN OUT PACL pAcl,
1508         IN DWORD dwAceRevision,
1509         IN DWORD AceFlags,
1510         IN DWORD AccessMask,
1511         IN PSID pSid)
1512 {
1513     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1514 }
1515
1516 /******************************************************************************
1517  *  AddAce [ADVAPI32.@]
1518  */
1519 BOOL WINAPI AddAce(
1520         IN OUT PACL pAcl,
1521         IN DWORD dwAceRevision,
1522         IN DWORD dwStartingAceIndex,
1523         LPVOID pAceList,
1524         DWORD nAceListLength)
1525 {
1526     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1527 }
1528
1529 /******************************************************************************
1530  * DeleteAce [ADVAPI32.@]
1531  */
1532 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1533 {
1534     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1535 }
1536
1537 /******************************************************************************
1538  *  FindFirstFreeAce [ADVAPI32.@]
1539  */
1540 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1541 {
1542         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1543 }
1544
1545 /******************************************************************************
1546  * GetAce [ADVAPI32.@]
1547  */
1548 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1549 {
1550     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1551 }
1552
1553 /******************************************************************************
1554  * GetAclInformation [ADVAPI32.@]
1555  */
1556 BOOL WINAPI GetAclInformation(
1557   PACL pAcl,
1558   LPVOID pAclInformation,
1559   DWORD nAclInformationLength,
1560   ACL_INFORMATION_CLASS dwAclInformationClass)
1561 {
1562     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1563                                                nAclInformationLength, dwAclInformationClass));
1564 }
1565
1566 /******************************************************************************
1567  *  IsValidAcl [ADVAPI32.@]
1568  */
1569 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1570 {
1571         return RtlValidAcl(pAcl);
1572 }
1573
1574 /*      ##############################
1575         ######  MISC FUNCTIONS  ######
1576         ##############################
1577 */
1578
1579 /******************************************************************************
1580  * AllocateLocallyUniqueId [ADVAPI32.@]
1581  *
1582  * PARAMS
1583  *   lpLuid []
1584  */
1585 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1586 {
1587     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1588 }
1589
1590 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1591  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1592 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1593  { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1594 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1595  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1596 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1597  { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1598 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1599  { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1600 static const WCHAR SE_TCB_NAME_W[] =
1601  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1602 static const WCHAR SE_SECURITY_NAME_W[] =
1603  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1604 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1605  { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1606 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1607  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1608 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1609  { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1610 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1611  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1612 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1613  { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1614 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1615  { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1616 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1617  { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1618 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1619  { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1620 static const WCHAR SE_BACKUP_NAME_W[] =
1621  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1622 static const WCHAR SE_RESTORE_NAME_W[] =
1623  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1624 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1625  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1626 static const WCHAR SE_DEBUG_NAME_W[] =
1627  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1628 static const WCHAR SE_AUDIT_NAME_W[] =
1629  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1630 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1631  { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1632 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1633  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1634 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1635  { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1636 static const WCHAR SE_UNDOCK_NAME_W[] =
1637  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1638 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1639  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1640 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1641  { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1642 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1643  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1644 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1645  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1646 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1647  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1648
1649 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1650 {
1651     NULL,
1652     NULL,
1653     SE_CREATE_TOKEN_NAME_W,
1654     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1655     SE_LOCK_MEMORY_NAME_W,
1656     SE_INCREASE_QUOTA_NAME_W,
1657     SE_MACHINE_ACCOUNT_NAME_W,
1658     SE_TCB_NAME_W,
1659     SE_SECURITY_NAME_W,
1660     SE_TAKE_OWNERSHIP_NAME_W,
1661     SE_LOAD_DRIVER_NAME_W,
1662     SE_SYSTEM_PROFILE_NAME_W,
1663     SE_SYSTEMTIME_NAME_W,
1664     SE_PROF_SINGLE_PROCESS_NAME_W,
1665     SE_INC_BASE_PRIORITY_NAME_W,
1666     SE_CREATE_PAGEFILE_NAME_W,
1667     SE_CREATE_PERMANENT_NAME_W,
1668     SE_BACKUP_NAME_W,
1669     SE_RESTORE_NAME_W,
1670     SE_SHUTDOWN_NAME_W,
1671     SE_DEBUG_NAME_W,
1672     SE_AUDIT_NAME_W,
1673     SE_SYSTEM_ENVIRONMENT_NAME_W,
1674     SE_CHANGE_NOTIFY_NAME_W,
1675     SE_REMOTE_SHUTDOWN_NAME_W,
1676     SE_UNDOCK_NAME_W,
1677     SE_SYNC_AGENT_NAME_W,
1678     SE_ENABLE_DELEGATION_NAME_W,
1679     SE_MANAGE_VOLUME_NAME_W,
1680     SE_IMPERSONATE_NAME_W,
1681     SE_CREATE_GLOBAL_NAME_W,
1682 };
1683
1684 /******************************************************************************
1685  * LookupPrivilegeValueW                        [ADVAPI32.@]
1686  *
1687  * See LookupPrivilegeValueA.
1688  */
1689 BOOL WINAPI
1690 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1691 {
1692     UINT i;
1693
1694     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1695
1696     if (!ADVAPI_IsLocalComputer(lpSystemName))
1697     {
1698         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1699         return FALSE;
1700     }
1701     if (!lpName)
1702     {
1703         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1704         return FALSE;
1705     }
1706     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1707     {
1708         if( !WellKnownPrivNames[i] )
1709             continue;
1710         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1711             continue;
1712         lpLuid->LowPart = i;
1713         lpLuid->HighPart = 0;
1714         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1715                lpLuid->HighPart, lpLuid->LowPart );
1716         return TRUE;
1717     }
1718     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1719     return FALSE;
1720 }
1721
1722 /******************************************************************************
1723  * LookupPrivilegeValueA                        [ADVAPI32.@]
1724  *
1725  * Retrieves LUID used on a system to represent the privilege name.
1726  *
1727  * PARAMS
1728  *  lpSystemName [I] Name of the system
1729  *  lpName       [I] Name of the privilege
1730  *  lpLuid       [O] Destination for the resulting LUID
1731  *
1732  * RETURNS
1733  *  Success: TRUE. lpLuid contains the requested LUID.
1734  *  Failure: FALSE.
1735  */
1736 BOOL WINAPI
1737 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1738 {
1739     UNICODE_STRING lpSystemNameW;
1740     UNICODE_STRING lpNameW;
1741     BOOL ret;
1742
1743     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1744     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1745     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1746     RtlFreeUnicodeString(&lpNameW);
1747     RtlFreeUnicodeString(&lpSystemNameW);
1748     return ret;
1749 }
1750
1751 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1752                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1753 {
1754     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1755           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1756
1757     return FALSE;
1758 }
1759
1760 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1761                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1762 {
1763     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1764           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1765
1766     return FALSE;
1767 }
1768
1769 /******************************************************************************
1770  * LookupPrivilegeNameA                 [ADVAPI32.@]
1771  *
1772  * See LookupPrivilegeNameW.
1773  */
1774 BOOL WINAPI
1775 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1776  LPDWORD cchName)
1777 {
1778     UNICODE_STRING lpSystemNameW;
1779     BOOL ret;
1780     DWORD wLen = 0;
1781
1782     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1783
1784     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1785     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1786     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1787     {
1788         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1789
1790         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1791          &wLen);
1792         if (ret)
1793         {
1794             /* Windows crashes if cchName is NULL, so will I */
1795             unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1796              *cchName, NULL, NULL);
1797
1798             if (len == 0)
1799             {
1800                 /* WideCharToMultiByte failed */
1801                 ret = FALSE;
1802             }
1803             else if (len > *cchName)
1804             {
1805                 *cchName = len;
1806                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1807                 ret = FALSE;
1808             }
1809             else
1810             {
1811                 /* WideCharToMultiByte succeeded, output length needs to be
1812                  * length not including NULL terminator
1813                  */
1814                 *cchName = len - 1;
1815             }
1816         }
1817         HeapFree(GetProcessHeap(), 0, lpNameW);
1818     }
1819     RtlFreeUnicodeString(&lpSystemNameW);
1820     return ret;
1821 }
1822
1823 /******************************************************************************
1824  * LookupPrivilegeNameW                 [ADVAPI32.@]
1825  *
1826  * Retrieves the privilege name referred to by the LUID lpLuid.
1827  *
1828  * PARAMS
1829  *  lpSystemName [I]   Name of the system
1830  *  lpLuid       [I]   Privilege value
1831  *  lpName       [O]   Name of the privilege
1832  *  cchName      [I/O] Number of characters in lpName.
1833  *
1834  * RETURNS
1835  *  Success: TRUE. lpName contains the name of the privilege whose value is
1836  *  *lpLuid.
1837  *  Failure: FALSE.
1838  *
1839  * REMARKS
1840  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1841  *  using this function.
1842  *  If the length of lpName is too small, on return *cchName will contain the
1843  *  number of WCHARs needed to contain the privilege, including the NULL
1844  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1845  *  On success, *cchName will contain the number of characters stored in
1846  *  lpName, NOT including the NULL terminator.
1847  */
1848 BOOL WINAPI
1849 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1850  LPDWORD cchName)
1851 {
1852     size_t privNameLen;
1853
1854     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1855
1856     if (!ADVAPI_IsLocalComputer(lpSystemName))
1857     {
1858         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1859         return FALSE;
1860     }
1861     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1862      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1863     {
1864         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1865         return FALSE;
1866     }
1867     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1868     /* Windows crashes if cchName is NULL, so will I */
1869     if (*cchName <= privNameLen)
1870     {
1871         *cchName = privNameLen + 1;
1872         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1873         return FALSE;
1874     }
1875     else
1876     {
1877         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1878         *cchName = privNameLen;
1879         return TRUE;
1880     }
1881 }
1882
1883 /******************************************************************************
1884  * GetFileSecurityA [ADVAPI32.@]
1885  *
1886  * Obtains Specified information about the security of a file or directory.
1887  *
1888  * PARAMS
1889  *  lpFileName           [I] Name of the file to get info for
1890  *  RequestedInformation [I] SE_ flags from "winnt.h"
1891  *  pSecurityDescriptor  [O] Destination for security information
1892  *  nLength              [I] Length of pSecurityDescriptor
1893  *  lpnLengthNeeded      [O] Destination for length of returned security information
1894  *
1895  * RETURNS
1896  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1897  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1898  *
1899  * NOTES
1900  *  The information returned is constrained by the callers access rights and
1901  *  privileges.
1902  */
1903 BOOL WINAPI
1904 GetFileSecurityA( LPCSTR lpFileName,
1905                     SECURITY_INFORMATION RequestedInformation,
1906                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1907                     DWORD nLength, LPDWORD lpnLengthNeeded )
1908 {
1909     DWORD len;
1910     BOOL r;
1911     LPWSTR name = NULL;
1912
1913     if( lpFileName )
1914     {
1915         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1916         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1917         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1918     }
1919
1920     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1921                           nLength, lpnLengthNeeded );
1922     HeapFree( GetProcessHeap(), 0, name );
1923
1924     return r;
1925 }
1926
1927 /******************************************************************************
1928  * GetFileSecurityW [ADVAPI32.@]
1929  *
1930  * See GetFileSecurityA.
1931  */
1932 BOOL WINAPI
1933 GetFileSecurityW( LPCWSTR lpFileName,
1934                     SECURITY_INFORMATION RequestedInformation,
1935                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1936                     DWORD nLength, LPDWORD lpnLengthNeeded )
1937 {
1938     HANDLE hfile;
1939     NTSTATUS status;
1940     DWORD access = 0;
1941
1942     TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1943           RequestedInformation, pSecurityDescriptor,
1944           nLength, lpnLengthNeeded);
1945
1946     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1947                                 DACL_SECURITY_INFORMATION))
1948         access |= READ_CONTROL;
1949     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1950         access |= ACCESS_SYSTEM_SECURITY;
1951
1952     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1953                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1954     if ( hfile == INVALID_HANDLE_VALUE )
1955         return FALSE;
1956
1957     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1958                                     nLength, lpnLengthNeeded );
1959     CloseHandle( hfile );
1960     return set_ntstatus( status );
1961 }
1962
1963
1964 /******************************************************************************
1965  * LookupAccountSidA [ADVAPI32.@]
1966  */
1967 BOOL WINAPI
1968 LookupAccountSidA(
1969         IN LPCSTR system,
1970         IN PSID sid,
1971         OUT LPSTR account,
1972         IN OUT LPDWORD accountSize,
1973         OUT LPSTR domain,
1974         IN OUT LPDWORD domainSize,
1975         OUT PSID_NAME_USE name_use )
1976 {
1977     DWORD len;
1978     BOOL r;
1979     LPWSTR systemW = NULL;
1980     LPWSTR accountW = NULL;
1981     LPWSTR domainW = NULL;
1982     DWORD accountSizeW = *accountSize;
1983     DWORD domainSizeW = *domainSize;
1984
1985     if (system) {
1986         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1987         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1988         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1989     }
1990     if (account)
1991         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1992     if (domain)
1993         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1994
1995     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1996
1997     if (r) {
1998         if (accountW && *accountSize) {
1999             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2000             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2001             *accountSize = len;
2002         } else
2003             *accountSize = accountSizeW + 1;
2004
2005         if (domainW && *domainSize) {
2006             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2007             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2008             *domainSize = len;
2009         } else
2010             *domainSize = domainSizeW + 1;
2011     }
2012
2013     HeapFree( GetProcessHeap(), 0, systemW );
2014     HeapFree( GetProcessHeap(), 0, accountW );
2015     HeapFree( GetProcessHeap(), 0, domainW );
2016
2017     return r;
2018 }
2019
2020 /******************************************************************************
2021  * LookupAccountSidW [ADVAPI32.@]
2022  *
2023  * PARAMS
2024  *   system      []
2025  *   sid         []
2026  *   account     []
2027  *   accountSize []
2028  *   domain      []
2029  *   domainSize  []
2030  *   name_use    []
2031  */
2032
2033 BOOL WINAPI
2034 LookupAccountSidW(
2035         IN LPCWSTR system,
2036         IN PSID sid,
2037         OUT LPWSTR account,
2038         IN OUT LPDWORD accountSize,
2039         OUT LPWSTR domain,
2040         IN OUT LPDWORD domainSize,
2041         OUT PSID_NAME_USE name_use )
2042 {
2043     unsigned int i, j;
2044     const WCHAR * ac = NULL;
2045     const WCHAR * dm = NULL;
2046     SID_NAME_USE use = 0;
2047     LPWSTR computer_name = NULL;
2048     LPWSTR account_name = NULL;
2049
2050     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2051           debugstr_w(system),debugstr_sid(sid),
2052           account,accountSize,accountSize?*accountSize:0,
2053           domain,domainSize,domainSize?*domainSize:0,
2054           name_use);
2055
2056     if (!ADVAPI_IsLocalComputer(system)) {
2057         FIXME("Only local computer supported!\n");
2058         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2059         return FALSE;
2060     }
2061
2062     /* check the well known SIDs first */
2063     for (i = 0; i <= 60; i++) {
2064         if (IsWellKnownSid(sid, i)) {
2065             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2066                 if (ACCOUNT_SIDS[j].type == i) {
2067                     ac = ACCOUNT_SIDS[j].account;
2068                     dm = ACCOUNT_SIDS[j].domain;
2069                     use = ACCOUNT_SIDS[j].name_use;
2070                 }
2071             }
2072             break;
2073         }
2074     }
2075
2076     if (dm == NULL) {
2077         MAX_SID local;
2078
2079         /* check for the local computer next */
2080         if (ADVAPI_GetComputerSid(&local)) {
2081             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2082             BOOL result;
2083
2084             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2085             result = GetComputerNameW(computer_name,  &size);
2086
2087             if (result) {
2088                 if (EqualSid(sid, &local)) {
2089                     dm = computer_name;
2090                     ac = Blank;
2091                     use = 3;
2092                 } else {
2093                     local.SubAuthorityCount++;
2094
2095                     if (EqualPrefixSid(sid, &local)) {
2096                         dm = computer_name;
2097                         use = 1;
2098                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2099                         case DOMAIN_USER_RID_ADMIN:
2100                             ac = Administrator;
2101                             break;
2102                         case DOMAIN_USER_RID_GUEST:
2103                             ac = Guest;
2104                             break;
2105                         case DOMAIN_GROUP_RID_ADMINS:
2106                             ac = Domain_Admins;
2107                             break;
2108                         case DOMAIN_GROUP_RID_USERS:
2109                             ac = Domain_Users;
2110                             break;
2111                         case DOMAIN_GROUP_RID_GUESTS:
2112                             ac = Domain_Guests;
2113                             break;
2114                         case DOMAIN_GROUP_RID_COMPUTERS:
2115                             ac = Domain_Computers;
2116                             break;
2117                         case DOMAIN_GROUP_RID_CONTROLLERS:
2118                             ac = Domain_Controllers;
2119                             break;
2120                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2121                             ac = Cert_Publishers;
2122                             break;
2123                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2124                             ac = Schema_Admins;
2125                             break;
2126                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2127                             ac = Enterprise_Admins;
2128                             break;
2129                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2130                             ac = Group_Policy_Creator_Owners;
2131                             break;
2132                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2133                             ac = RAS_and_IAS_Servers;
2134                             break;
2135                         case 1000:      /* first user account */
2136                             size = UNLEN + 1;
2137                             account_name = HeapAlloc(
2138                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2139                             if (GetUserNameW(account_name, &size))
2140                                 ac = account_name;
2141                             else
2142                                 dm = NULL;
2143
2144                             break;
2145                         default:
2146                             dm = NULL;
2147                             break;
2148                         }
2149                     }
2150                 }
2151             }
2152         }
2153     }
2154
2155     if (dm) {
2156         DWORD ac_len = lstrlenW(ac);
2157         DWORD dm_len = lstrlenW(dm);
2158         BOOL status = TRUE;
2159
2160         if (*accountSize > ac_len) {
2161             if (account)
2162                 lstrcpyW(account, ac);
2163         }
2164         if (*domainSize > dm_len) {
2165             if (domain)
2166                 lstrcpyW(domain, dm);
2167         }
2168         if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2169             ((*domainSize != 0) && (*domainSize < dm_len))) {
2170             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2171             status = FALSE;
2172         }
2173         if (*domainSize)
2174             *domainSize = dm_len;
2175         else
2176             *domainSize = dm_len + 1;
2177         if (*accountSize)
2178             *accountSize = ac_len;
2179         else
2180             *accountSize = ac_len + 1;
2181         *name_use = use;
2182         HeapFree(GetProcessHeap(), 0, account_name);
2183         HeapFree(GetProcessHeap(), 0, computer_name);
2184         return status;
2185     }
2186
2187     HeapFree(GetProcessHeap(), 0, account_name);
2188     HeapFree(GetProcessHeap(), 0, computer_name);
2189     SetLastError(ERROR_NONE_MAPPED);
2190     return FALSE;
2191 }
2192
2193 /******************************************************************************
2194  * SetFileSecurityA [ADVAPI32.@]
2195  *
2196  * See SetFileSecurityW.
2197  */
2198 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2199                                 SECURITY_INFORMATION RequestedInformation,
2200                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2201 {
2202     DWORD len;
2203     BOOL r;
2204     LPWSTR name = NULL;
2205
2206     if( lpFileName )
2207     {
2208         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2209         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2210         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2211     }
2212
2213     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2214     HeapFree( GetProcessHeap(), 0, name );
2215
2216     return r;
2217 }
2218
2219 /******************************************************************************
2220  * SetFileSecurityW [ADVAPI32.@]
2221  *
2222  * Sets the security of a file or directory.
2223  *
2224  * PARAMS
2225  *   lpFileName           []
2226  *   RequestedInformation []
2227  *   pSecurityDescriptor  []
2228  *
2229  * RETURNS
2230  *  Success: TRUE.
2231  *  Failure: FALSE.
2232  */
2233 BOOL WINAPI
2234 SetFileSecurityW( LPCWSTR lpFileName,
2235                     SECURITY_INFORMATION RequestedInformation,
2236                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2237 {
2238     HANDLE file;
2239     DWORD access = 0;
2240     NTSTATUS status;
2241
2242     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2243           pSecurityDescriptor );
2244
2245     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2246         RequestedInformation & GROUP_SECURITY_INFORMATION)
2247         access |= WRITE_OWNER;
2248     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2249         access |= ACCESS_SYSTEM_SECURITY;
2250     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2251         access |= WRITE_DAC;
2252
2253     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2254                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2255     if (file == INVALID_HANDLE_VALUE)
2256         return FALSE;
2257
2258     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2259     CloseHandle( file );
2260     return set_ntstatus( status );
2261 }
2262
2263 /******************************************************************************
2264  * QueryWindows31FilesMigration [ADVAPI32.@]
2265  *
2266  * PARAMS
2267  *   x1 []
2268  */
2269 BOOL WINAPI
2270 QueryWindows31FilesMigration( DWORD x1 )
2271 {
2272         FIXME("(%d):stub\n",x1);
2273         return TRUE;
2274 }
2275
2276 /******************************************************************************
2277  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2278  *
2279  * PARAMS
2280  *   x1 []
2281  *   x2 []
2282  *   x3 []
2283  *   x4 []
2284  */
2285 BOOL WINAPI
2286 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2287                                                DWORD x4 )
2288 {
2289         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2290         return TRUE;
2291 }
2292
2293 /******************************************************************************
2294  * NotifyBootConfigStatus [ADVAPI32.@]
2295  *
2296  * PARAMS
2297  *   x1 []
2298  */
2299 BOOL WINAPI
2300 NotifyBootConfigStatus( BOOL x1 )
2301 {
2302         FIXME("(0x%08d):stub\n",x1);
2303         return 1;
2304 }
2305
2306 /******************************************************************************
2307  * RevertToSelf [ADVAPI32.@]
2308  *
2309  * Ends the impersonation of a user.
2310  *
2311  * PARAMS
2312  *   void []
2313  *
2314  * RETURNS
2315  *  Success: TRUE.
2316  *  Failure: FALSE.
2317  */
2318 BOOL WINAPI
2319 RevertToSelf( void )
2320 {
2321     HANDLE Token = NULL;
2322     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2323         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2324 }
2325
2326 /******************************************************************************
2327  * ImpersonateSelf [ADVAPI32.@]
2328  *
2329  * Makes an impersonation token that represents the process user and assigns
2330  * to the current thread.
2331  *
2332  * PARAMS
2333  *  ImpersonationLevel [I] Level at which to impersonate.
2334  *
2335  * RETURNS
2336  *  Success: TRUE.
2337  *  Failure: FALSE.
2338  */
2339 BOOL WINAPI
2340 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2341 {
2342     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2343 }
2344
2345 /******************************************************************************
2346  * ImpersonateLoggedOnUser [ADVAPI32.@]
2347  */
2348 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2349 {
2350     DWORD size;
2351     NTSTATUS Status;
2352     HANDLE ImpersonationToken;
2353     TOKEN_TYPE Type;
2354     static BOOL warn = TRUE;
2355
2356     if (warn)
2357     {
2358         FIXME( "(%p)\n", hToken );
2359         warn = FALSE;
2360     }
2361     if (!GetTokenInformation( hToken, TokenType, &Type,
2362                               sizeof(TOKEN_TYPE), &size ))
2363         return FALSE;
2364
2365     if (Type == TokenPrimary)
2366     {
2367         OBJECT_ATTRIBUTES ObjectAttributes;
2368
2369         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2370
2371         Status = NtDuplicateToken( hToken,
2372                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2373                                    &ObjectAttributes,
2374                                    SecurityImpersonation,
2375                                    TokenImpersonation,
2376                                    &ImpersonationToken );
2377         if (Status != STATUS_SUCCESS)
2378         {
2379             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2380             SetLastError( RtlNtStatusToDosError( Status ) );
2381             return FALSE;
2382         }
2383     }
2384     else
2385         ImpersonationToken = hToken;
2386
2387     Status = NtSetInformationThread( GetCurrentThread(),
2388                                      ThreadImpersonationToken,
2389                                      &ImpersonationToken,
2390                                      sizeof(ImpersonationToken) );
2391
2392     if (Type == TokenPrimary)
2393         NtClose( ImpersonationToken );
2394
2395     if (Status != STATUS_SUCCESS)
2396     {
2397         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2398         SetLastError( RtlNtStatusToDosError( Status ) );
2399         return FALSE;
2400     }
2401
2402     return TRUE;
2403 }
2404
2405 /******************************************************************************
2406  * AccessCheck [ADVAPI32.@]
2407  */
2408 BOOL WINAPI
2409 AccessCheck(
2410         PSECURITY_DESCRIPTOR SecurityDescriptor,
2411         HANDLE ClientToken,
2412         DWORD DesiredAccess,
2413         PGENERIC_MAPPING GenericMapping,
2414         PPRIVILEGE_SET PrivilegeSet,
2415         LPDWORD PrivilegeSetLength,
2416         LPDWORD GrantedAccess,
2417         LPBOOL AccessStatus)
2418 {
2419     NTSTATUS access_status;
2420     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2421                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2422                                            GrantedAccess, &access_status) );
2423     if (ret) *AccessStatus = set_ntstatus( access_status );
2424     return ret;
2425 }
2426
2427
2428 /******************************************************************************
2429  * AccessCheckByType [ADVAPI32.@]
2430  */
2431 BOOL WINAPI AccessCheckByType(
2432     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2433     PSID PrincipalSelfSid,
2434     HANDLE ClientToken, 
2435     DWORD DesiredAccess, 
2436     POBJECT_TYPE_LIST ObjectTypeList,
2437     DWORD ObjectTypeListLength,
2438     PGENERIC_MAPPING GenericMapping,
2439     PPRIVILEGE_SET PrivilegeSet,
2440     LPDWORD PrivilegeSetLength, 
2441     LPDWORD GrantedAccess,
2442     LPBOOL AccessStatus)
2443 {
2444         FIXME("stub\n");
2445
2446         *AccessStatus = TRUE;
2447
2448         return !*AccessStatus;
2449 }
2450
2451 /******************************************************************************
2452  * MapGenericMask [ADVAPI32.@]
2453  *
2454  * Maps generic access rights into specific access rights according to the
2455  * supplied mapping.
2456  *
2457  * PARAMS
2458  *  AccessMask     [I/O] Access rights.
2459  *  GenericMapping [I] The mapping between generic and specific rights.
2460  *
2461  * RETURNS
2462  *  Nothing.
2463  */
2464 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2465 {
2466     RtlMapGenericMask( AccessMask, GenericMapping );
2467 }
2468
2469 /*************************************************************************
2470  * SetKernelObjectSecurity [ADVAPI32.@]
2471  */
2472 BOOL WINAPI SetKernelObjectSecurity (
2473         IN HANDLE Handle,
2474         IN SECURITY_INFORMATION SecurityInformation,
2475         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2476 {
2477     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2478 }
2479
2480
2481 /******************************************************************************
2482  *  AddAuditAccessAce [ADVAPI32.@]
2483  */
2484 BOOL WINAPI AddAuditAccessAce(
2485     IN OUT PACL pAcl, 
2486     IN DWORD dwAceRevision, 
2487     IN DWORD dwAccessMask, 
2488     IN PSID pSid, 
2489     IN BOOL bAuditSuccess, 
2490     IN BOOL bAuditFailure) 
2491 {
2492     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2493                                               bAuditSuccess, bAuditFailure) ); 
2494 }
2495
2496 /******************************************************************************
2497  *  AddAuditAccessAce [ADVAPI32.@]
2498  */
2499 BOOL WINAPI AddAuditAccessAceEx(
2500     IN OUT PACL pAcl,
2501     IN DWORD dwAceRevision,
2502     IN DWORD dwAceFlags,
2503     IN DWORD dwAccessMask,
2504     IN PSID pSid,
2505     IN BOOL bAuditSuccess,
2506     IN BOOL bAuditFailure)
2507 {
2508     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2509                                               bAuditSuccess, bAuditFailure) );
2510 }
2511
2512 /******************************************************************************
2513  * LookupAccountNameA [ADVAPI32.@]
2514  */
2515 BOOL WINAPI
2516 LookupAccountNameA(
2517         IN LPCSTR system,
2518         IN LPCSTR account,
2519         OUT PSID sid,
2520         OUT LPDWORD cbSid,
2521         LPSTR ReferencedDomainName,
2522         IN OUT LPDWORD cbReferencedDomainName,
2523         OUT PSID_NAME_USE name_use )
2524 {
2525     BOOL ret;
2526     UNICODE_STRING lpSystemW;
2527     UNICODE_STRING lpAccountW;
2528     LPWSTR lpReferencedDomainNameW = NULL;
2529
2530     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2531     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2532
2533     if (ReferencedDomainName)
2534         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2535
2536     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2537         cbReferencedDomainName, name_use);
2538
2539     if (ret && lpReferencedDomainNameW)
2540     {
2541         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2542             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2543     }
2544
2545     RtlFreeUnicodeString(&lpSystemW);
2546     RtlFreeUnicodeString(&lpAccountW);
2547     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2548
2549     return ret;
2550 }
2551
2552 /******************************************************************************
2553  * lookup_user_account_name
2554  */
2555 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2556                                      LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2557 {
2558     char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2559     DWORD len = sizeof(buffer);
2560     HANDLE token;
2561     BOOL ret;
2562     PSID pSid;
2563     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2564     DWORD nameLen;
2565     LPCWSTR domainName;
2566
2567     if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2568     {
2569         if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2570         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2571     }
2572
2573     ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2574     CloseHandle( token );
2575
2576     if (!ret) return FALSE;
2577
2578     pSid = ((TOKEN_USER *)buffer)->User.Sid;
2579
2580     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2581        CopySid(*cbSid, Sid, pSid);
2582     if (*cbSid < GetLengthSid(pSid))
2583     {
2584        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2585        ret = FALSE;
2586     }
2587     *cbSid = GetLengthSid(pSid);
2588
2589     domainName = dm;
2590     nameLen = strlenW(domainName);
2591
2592     if (*cchReferencedDomainName <= nameLen || !ret)
2593     {
2594         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2595         nameLen += 1;
2596         ret = FALSE;
2597     }
2598     else if (ReferencedDomainName)
2599         strcpyW(ReferencedDomainName, domainName);
2600
2601     *cchReferencedDomainName = nameLen;
2602
2603     if (ret)
2604         *peUse = SidTypeUser;
2605
2606     return ret;
2607 }
2608
2609 /******************************************************************************
2610  * lookup_computer_account_name
2611  */
2612 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2613                                          LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2614 {
2615     MAX_SID local;
2616     BOOL ret;
2617     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2618     DWORD nameLen;
2619     LPCWSTR domainName;
2620
2621     if ((ret = ADVAPI_GetComputerSid(&local)))
2622     {
2623         if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2624            CopySid(*cbSid, Sid, &local);
2625         if (*cbSid < GetLengthSid(&local))
2626         {
2627            SetLastError(ERROR_INSUFFICIENT_BUFFER);
2628            ret = FALSE;
2629         }
2630         *cbSid = GetLengthSid(&local);
2631     }
2632
2633     domainName = dm;
2634     nameLen = strlenW(domainName);
2635
2636     if (*cchReferencedDomainName <= nameLen || !ret)
2637     {
2638         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2639         nameLen += 1;
2640         ret = FALSE;
2641     }
2642     else if (ReferencedDomainName)
2643         strcpyW(ReferencedDomainName, domainName);
2644
2645     *cchReferencedDomainName = nameLen;
2646
2647     if (ret)
2648         *peUse = SidTypeDomain;
2649
2650     return ret;
2651 }
2652
2653 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2654                                   LSA_UNICODE_STRING *domain )
2655 {
2656     WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2657
2658     while (p > str->Buffer && *p != '\\') p--;
2659
2660     if (*p == '\\')
2661     {
2662         domain->Buffer = str->Buffer;
2663         domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2664
2665         account->Buffer = p + 1;
2666         account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2667     }
2668     else
2669     {
2670         domain->Buffer = NULL;
2671         domain->Length = 0;
2672
2673         account->Buffer = str->Buffer;
2674         account->Length = str->Length;
2675     }
2676 }
2677
2678 static BOOL match_domain( ULONG idx, LSA_UNICODE_STRING *domain )
2679 {
2680     ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2681
2682     if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2683         return TRUE;
2684
2685     return FALSE;
2686 }
2687
2688 static BOOL match_account( ULONG idx, LSA_UNICODE_STRING *account )
2689 {
2690     ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2691
2692     if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2693         return TRUE;
2694
2695     if (ACCOUNT_SIDS[idx].alias)
2696     {
2697         len = strlenW( ACCOUNT_SIDS[idx].alias );
2698         if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2699             return TRUE;
2700     }
2701     return FALSE;
2702 }
2703
2704 /*
2705  * Helper function for LookupAccountNameW
2706  */
2707 BOOL lookup_local_wellknown_name( LSA_UNICODE_STRING *account_and_domain,
2708                                   PSID Sid, LPDWORD cbSid,
2709                                   LPWSTR ReferencedDomainName,
2710                                   LPDWORD cchReferencedDomainName,
2711                                   PSID_NAME_USE peUse, BOOL *handled )
2712 {
2713     PSID pSid;
2714     LSA_UNICODE_STRING account, domain;
2715     BOOL ret = TRUE;
2716     ULONG i;
2717
2718     *handled = FALSE;
2719     split_domain_account( account_and_domain, &account, &domain );
2720
2721     for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2722     {
2723         /* check domain first */
2724         if (domain.Buffer && !match_domain( i, &domain )) continue;
2725
2726         if (match_account( i, &account ))
2727         {
2728             DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2729
2730             if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2731
2732             if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2733             {
2734                 if (*cbSid < sidLen)
2735                 {
2736                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2737                     ret = FALSE;
2738                 }
2739                 else if (Sid)
2740                 {
2741                     CopySid(*cbSid, Sid, pSid);
2742                 }
2743                 *cbSid = sidLen;
2744             }
2745
2746             len = strlenW( ACCOUNT_SIDS[i].domain );
2747             if (*cchReferencedDomainName <= len || !ret)
2748             {
2749                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2750                 len++;
2751                 ret = FALSE;
2752             }
2753             else if (ReferencedDomainName)
2754             {
2755                 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2756             }
2757
2758             *cchReferencedDomainName = len;
2759             if (ret)
2760                 *peUse = ACCOUNT_SIDS[i].name_use;
2761
2762             HeapFree(GetProcessHeap(), 0, pSid);
2763             *handled = TRUE;
2764             return ret;
2765         }
2766     }
2767     return ret;
2768 }
2769
2770 BOOL lookup_local_user_name( LSA_UNICODE_STRING *account_and_domain,
2771                              PSID Sid, LPDWORD cbSid,
2772                              LPWSTR ReferencedDomainName,
2773                              LPDWORD cchReferencedDomainName,
2774                              PSID_NAME_USE peUse, BOOL *handled )
2775 {
2776     DWORD nameLen;
2777     LPWSTR userName = NULL;
2778     LSA_UNICODE_STRING account, domain;
2779     BOOL ret = TRUE;
2780
2781     *handled = FALSE;
2782     split_domain_account( account_and_domain, &account, &domain );
2783
2784     /* Let the current Unix user id masquerade as first Windows user account */
2785
2786     nameLen = UNLEN + 1;
2787     if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2788
2789     if (domain.Buffer)
2790     {
2791         /* check to make sure this account is on this computer */
2792         if (GetComputerNameW( userName, &nameLen ) &&
2793             (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2794         {
2795             SetLastError(ERROR_NONE_MAPPED);
2796             ret = FALSE;
2797         }
2798         nameLen = UNLEN + 1;
2799     }
2800
2801     if (GetUserNameW( userName, &nameLen ) &&
2802         account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2803     {
2804             ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2805             *handled = TRUE;
2806     }
2807     else
2808     {
2809         nameLen = UNLEN + 1;
2810         if (GetComputerNameW( userName, &nameLen ) &&
2811             account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2812         {
2813             ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2814             *handled = TRUE;
2815         }
2816     }
2817
2818     HeapFree(GetProcessHeap(), 0, userName);
2819     return ret;
2820 }
2821
2822 /******************************************************************************
2823  * LookupAccountNameW [ADVAPI32.@]
2824  */
2825 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2826                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2827                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2828 {
2829     BOOL ret, handled;
2830     LSA_UNICODE_STRING account;
2831
2832     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2833           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2834
2835     if (!ADVAPI_IsLocalComputer( lpSystemName ))
2836     {
2837         SetLastError( RPC_S_SERVER_UNAVAILABLE );
2838         return FALSE;
2839     }
2840
2841     if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2842     {
2843         lpAccountName = BUILTIN;
2844     }
2845
2846     RtlInitUnicodeString( &account, lpAccountName );
2847
2848     /* Check well known SIDs first */
2849     ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2850                                        cchReferencedDomainName, peUse, &handled );
2851     if (handled)
2852         return ret;
2853
2854     /* Check user names */
2855     ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2856                                   cchReferencedDomainName, peUse, &handled);
2857     if (handled)
2858         return ret;
2859
2860     SetLastError( ERROR_NONE_MAPPED );
2861     return FALSE;
2862 }
2863
2864 /******************************************************************************
2865  * PrivilegeCheck [ADVAPI32.@]
2866  */
2867 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2868 {
2869     BOOL ret;
2870     BOOLEAN Result;
2871
2872     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2873
2874     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2875     if (ret)
2876         *pfResult = Result;
2877     return ret;
2878 }
2879
2880 /******************************************************************************
2881  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2882  */
2883 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2884   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2885   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2886   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2887 {
2888         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2889                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2890                 SecurityDescriptor, DesiredAccess, GenericMapping,
2891                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2892         return TRUE;
2893 }
2894
2895 /******************************************************************************
2896  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2897  */
2898 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2899   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2900   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2901   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2902 {
2903         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2904                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2905                 SecurityDescriptor, DesiredAccess, GenericMapping,
2906                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2907         return TRUE;
2908 }
2909
2910 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2911 {
2912     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2913
2914     return TRUE;
2915 }
2916
2917 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2918 {
2919     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2920
2921     return TRUE;
2922 }
2923
2924 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2925 {
2926     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2927
2928     return TRUE;
2929 }
2930
2931 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2932   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2933   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2934   LPBOOL GenerateOnClose)
2935 {
2936         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2937                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2938         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2939         GenerateOnClose);
2940
2941     return TRUE;
2942 }
2943
2944 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2945   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2946   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2947   LPBOOL GenerateOnClose)
2948 {
2949     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2950         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2951         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2952         GenerateOnClose);
2953
2954     return TRUE;
2955 }
2956
2957 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2958   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2959 {
2960     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2961           DesiredAccess, Privileges, AccessGranted);
2962
2963     return TRUE;
2964 }
2965
2966 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2967   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2968 {
2969     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2970           DesiredAccess, Privileges, AccessGranted);
2971
2972     return TRUE;
2973 }
2974
2975 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2976                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2977 {
2978     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2979           ClientToken, Privileges, AccessGranted);
2980
2981     return TRUE;
2982 }
2983
2984 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2985                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2986 {
2987     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2988           ClientToken, Privileges, AccessGranted);
2989
2990     return TRUE;
2991 }
2992
2993 /******************************************************************************
2994  * GetSecurityInfo [ADVAPI32.@]
2995  *
2996  * Retrieves a copy of the security descriptor associated with an object.
2997  *
2998  * PARAMS
2999  *  hObject              [I] A handle for the object.
3000  *  ObjectType           [I] The type of object.
3001  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
3002  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
3003  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
3004  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
3005  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
3006  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3007  *                           which must be freed with LocalFree.
3008  *
3009  * RETURNS
3010  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3011  */
3012 DWORD WINAPI GetSecurityInfo(
3013     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3014     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3015     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3016     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3017 )
3018 {
3019     PSECURITY_DESCRIPTOR sd;
3020     NTSTATUS status;
3021     ULONG n1, n2;
3022     BOOL present, defaulted;
3023
3024     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3025     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3026         return RtlNtStatusToDosError(status);
3027
3028     sd = LocalAlloc(0, n1);
3029     if (!sd)
3030         return ERROR_NOT_ENOUGH_MEMORY;
3031
3032     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3033     if (status != STATUS_SUCCESS)
3034     {
3035         LocalFree(sd);
3036         return RtlNtStatusToDosError(status);
3037     }
3038
3039     if (ppsidOwner)
3040     {
3041         *ppsidOwner = NULL;
3042         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3043     }
3044     if (ppsidGroup)
3045     {
3046         *ppsidGroup = NULL;
3047         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3048     }
3049     if (ppDacl)
3050     {
3051         *ppDacl = NULL;
3052         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3053     }
3054     if (ppSacl)
3055     {
3056         *ppSacl = NULL;
3057         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3058     }
3059     if (ppSecurityDescriptor)
3060         *ppSecurityDescriptor = sd;
3061
3062     return ERROR_SUCCESS;
3063 }
3064
3065 /******************************************************************************
3066  * GetSecurityInfoExA [ADVAPI32.@]
3067  */
3068 DWORD WINAPI GetSecurityInfoExA(
3069         HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3070         SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3071         LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3072         PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3073 )
3074 {
3075   FIXME("stub!\n");
3076   return ERROR_BAD_PROVIDER;
3077 }
3078
3079 /******************************************************************************
3080  * GetSecurityInfoExW [ADVAPI32.@]
3081  */
3082 DWORD WINAPI GetSecurityInfoExW(
3083         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
3084         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3085         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
3086         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3087 )
3088 {
3089   FIXME("stub!\n");
3090   return ERROR_BAD_PROVIDER; 
3091 }
3092
3093 /******************************************************************************
3094  * BuildExplicitAccessWithNameA [ADVAPI32.@]
3095  */
3096 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3097                                           LPSTR pTrusteeName, DWORD AccessPermissions,
3098                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3099 {
3100     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3101           AccessPermissions, AccessMode, Inheritance);
3102
3103     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3104     pExplicitAccess->grfAccessMode = AccessMode;
3105     pExplicitAccess->grfInheritance = Inheritance;
3106
3107     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3108     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3109     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3110     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3111     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3112 }
3113
3114 /******************************************************************************
3115  * BuildExplicitAccessWithNameW [ADVAPI32.@]
3116  */
3117 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3118                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
3119                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3120 {
3121     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3122           AccessPermissions, AccessMode, Inheritance);
3123
3124     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3125     pExplicitAccess->grfAccessMode = AccessMode;
3126     pExplicitAccess->grfInheritance = Inheritance;
3127
3128     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3129     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3130     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3131     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3132     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3133 }
3134
3135 /******************************************************************************
3136  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3137  */
3138 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3139                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3140                                              LPSTR InheritedObjectTypeName, LPSTR Name )
3141 {
3142     DWORD ObjectsPresent = 0;
3143
3144     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3145           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3146
3147     /* Fill the OBJECTS_AND_NAME structure */
3148     pObjName->ObjectType = ObjectType;
3149     if (ObjectTypeName != NULL)
3150     {
3151         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3152     }
3153
3154     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3155     if (InheritedObjectTypeName != NULL)
3156     {
3157         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3158     }
3159
3160     pObjName->ObjectsPresent = ObjectsPresent;
3161     pObjName->ptstrName = Name;
3162
3163     /* Fill the TRUSTEE structure */
3164     pTrustee->pMultipleTrustee = NULL;
3165     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3166     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3167     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3168     pTrustee->ptstrName = (LPSTR)pObjName;
3169 }
3170
3171 /******************************************************************************
3172  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3173  */
3174 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3175                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3176                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
3177 {
3178     DWORD ObjectsPresent = 0;
3179
3180     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3181           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3182
3183     /* Fill the OBJECTS_AND_NAME structure */
3184     pObjName->ObjectType = ObjectType;
3185     if (ObjectTypeName != NULL)
3186     {
3187         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3188     }
3189
3190     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3191     if (InheritedObjectTypeName != NULL)
3192     {
3193         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3194     }
3195
3196     pObjName->ObjectsPresent = ObjectsPresent;
3197     pObjName->ptstrName = Name;
3198
3199     /* Fill the TRUSTEE structure */
3200     pTrustee->pMultipleTrustee = NULL;
3201     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3202     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3203     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3204     pTrustee->ptstrName = (LPWSTR)pObjName;
3205 }
3206
3207 /******************************************************************************
3208  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3209  */
3210 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3211                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3212 {
3213     DWORD ObjectsPresent = 0;
3214
3215     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3216
3217     /* Fill the OBJECTS_AND_SID structure */
3218     if (pObjectGuid != NULL)
3219     {
3220         pObjSid->ObjectTypeGuid = *pObjectGuid;
3221         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3222     }
3223     else
3224     {
3225         ZeroMemory(&pObjSid->ObjectTypeGuid,
3226                    sizeof(GUID));
3227     }
3228
3229     if (pInheritedObjectGuid != NULL)
3230     {
3231         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3232         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3233     }
3234     else
3235     {
3236         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3237                    sizeof(GUID));
3238     }
3239
3240     pObjSid->ObjectsPresent = ObjectsPresent;
3241     pObjSid->pSid = pSid;
3242
3243     /* Fill the TRUSTEE structure */
3244     pTrustee->pMultipleTrustee = NULL;
3245     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3246     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3247     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3248     pTrustee->ptstrName = (LPSTR) pObjSid;
3249 }
3250
3251 /******************************************************************************
3252  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3253  */
3254 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3255                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3256 {
3257     DWORD ObjectsPresent = 0;
3258
3259     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3260
3261     /* Fill the OBJECTS_AND_SID structure */
3262     if (pObjectGuid != NULL)
3263     {
3264         pObjSid->ObjectTypeGuid = *pObjectGuid;
3265         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3266     }
3267     else
3268     {
3269         ZeroMemory(&pObjSid->ObjectTypeGuid,
3270                    sizeof(GUID));
3271     }
3272
3273     if (pInheritedObjectGuid != NULL)
3274     {
3275         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3276         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3277     }
3278     else
3279     {
3280         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3281                    sizeof(GUID));
3282     }
3283
3284     pObjSid->ObjectsPresent = ObjectsPresent;
3285     pObjSid->pSid = pSid;
3286
3287     /* Fill the TRUSTEE structure */
3288     pTrustee->pMultipleTrustee = NULL;
3289     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3290     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3291     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3292     pTrustee->ptstrName = (LPWSTR) pObjSid;
3293 }
3294
3295 /******************************************************************************
3296  * BuildTrusteeWithSidA [ADVAPI32.@]
3297  */
3298 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3299 {
3300     TRACE("%p %p\n", pTrustee, pSid);
3301
3302     pTrustee->pMultipleTrustee = NULL;
3303     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3304     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3305     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3306     pTrustee->ptstrName = pSid;
3307 }
3308
3309 /******************************************************************************
3310  * BuildTrusteeWithSidW [ADVAPI32.@]
3311  */
3312 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3313 {
3314     TRACE("%p %p\n", pTrustee, pSid);
3315
3316     pTrustee->pMultipleTrustee = NULL;
3317     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3318     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3319     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3320     pTrustee->ptstrName = pSid;
3321 }
3322
3323 /******************************************************************************
3324  * BuildTrusteeWithNameA [ADVAPI32.@]
3325  */
3326 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3327 {
3328     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3329
3330     pTrustee->pMultipleTrustee = NULL;
3331     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3332     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3333     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3334     pTrustee->ptstrName = name;
3335 }
3336
3337 /******************************************************************************
3338  * BuildTrusteeWithNameW [ADVAPI32.@]
3339  */
3340 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3341 {
3342     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3343
3344     pTrustee->pMultipleTrustee = NULL;
3345     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3346     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3347     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3348     pTrustee->ptstrName = name;
3349 }
3350
3351 /****************************************************************************** 
3352  * GetTrusteeFormA [ADVAPI32.@] 
3353  */ 
3354 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
3355 {  
3356     TRACE("(%p)\n", pTrustee); 
3357   
3358     if (!pTrustee) 
3359         return TRUSTEE_BAD_FORM; 
3360   
3361     return pTrustee->TrusteeForm; 
3362 }  
3363   
3364 /****************************************************************************** 
3365  * GetTrusteeFormW [ADVAPI32.@] 
3366  */ 
3367 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
3368 {  
3369     TRACE("(%p)\n", pTrustee); 
3370   
3371     if (!pTrustee) 
3372         return TRUSTEE_BAD_FORM; 
3373   
3374     return pTrustee->TrusteeForm; 
3375 }  
3376   
3377 /****************************************************************************** 
3378  * GetTrusteeNameA [ADVAPI32.@] 
3379  */ 
3380 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
3381 {  
3382     TRACE("(%p)\n", pTrustee); 
3383   
3384     if (!pTrustee) 
3385         return NULL; 
3386   
3387     return pTrustee->ptstrName; 
3388 }  
3389   
3390 /****************************************************************************** 
3391  * GetTrusteeNameW [ADVAPI32.@] 
3392  */ 
3393 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
3394 {  
3395     TRACE("(%p)\n", pTrustee); 
3396   
3397     if (!pTrustee) 
3398         return NULL; 
3399   
3400     return pTrustee->ptstrName; 
3401 }  
3402   
3403 /****************************************************************************** 
3404  * GetTrusteeTypeA [ADVAPI32.@] 
3405  */ 
3406 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
3407 {  
3408     TRACE("(%p)\n", pTrustee); 
3409   
3410     if (!pTrustee) 
3411         return TRUSTEE_IS_UNKNOWN; 
3412   
3413     return pTrustee->TrusteeType; 
3414 }  
3415   
3416 /****************************************************************************** 
3417  * GetTrusteeTypeW [ADVAPI32.@] 
3418  */ 
3419 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
3420 {  
3421     TRACE("(%p)\n", pTrustee); 
3422   
3423     if (!pTrustee) 
3424         return TRUSTEE_IS_UNKNOWN; 
3425   
3426     return pTrustee->TrusteeType; 
3427
3428  
3429 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3430                                DWORD nAclInformationLength,
3431                                ACL_INFORMATION_CLASS dwAclInformationClass )
3432 {
3433     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3434           nAclInformationLength, dwAclInformationClass);
3435
3436     return TRUE;
3437 }
3438
3439 /******************************************************************************
3440  * SetEntriesInAclA [ADVAPI32.@]
3441  */
3442 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3443                                PACL OldAcl, PACL* NewAcl )
3444 {
3445     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3446     if (NewAcl)
3447          *NewAcl = NULL;
3448     return ERROR_SUCCESS;
3449 }
3450
3451 /******************************************************************************
3452  * SetEntriesInAclW [ADVAPI32.@]
3453  */
3454 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3455                                PACL OldAcl, PACL* NewAcl )
3456 {
3457     ULONG i;
3458     PSID *ppsid;
3459     DWORD ret = ERROR_SUCCESS;
3460     DWORD acl_size = sizeof(ACL);
3461     NTSTATUS status;
3462
3463     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3464
3465     *NewAcl = NULL;
3466
3467     if (!count && !OldAcl)
3468         return ERROR_SUCCESS;
3469
3470     /* allocate array of maximum sized sids allowed */
3471     ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3472     if (!ppsid)
3473         return ERROR_OUTOFMEMORY;
3474
3475     for (i = 0; i < count; i++)
3476     {
3477         ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3478
3479         TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3480               "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3481               "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3482               pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3483               pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3484               pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3485               pEntries[i].Trustee.ptstrName);
3486
3487         if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3488         {
3489             WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3490             ret = ERROR_INVALID_PARAMETER;
3491             goto exit;
3492         }
3493
3494         switch (pEntries[i].Trustee.TrusteeForm)
3495         {
3496         case TRUSTEE_IS_SID:
3497             if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3498                          ppsid[i], pEntries[i].Trustee.ptstrName))
3499             {
3500                 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3501                 ret = ERROR_INVALID_PARAMETER;
3502                 goto exit;
3503             }
3504             break;
3505         case TRUSTEE_IS_NAME:
3506         {
3507             DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3508             DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3509             SID_NAME_USE use;
3510             if ( strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ) &&
3511                  !LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3512             {
3513                 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3514                 ret = ERROR_INVALID_PARAMETER;
3515                 goto exit;
3516             }
3517             break;
3518         }
3519         case TRUSTEE_IS_OBJECTS_AND_SID:
3520             FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3521             break;
3522         case TRUSTEE_IS_OBJECTS_AND_NAME:
3523             FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3524             break;
3525         default:
3526             WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3527             ret = ERROR_INVALID_PARAMETER;
3528             goto exit;
3529         }
3530
3531         /* Note: we overestimate the ACL size here as a tradeoff between
3532          * instructions (simplicity) and memory */
3533         switch (pEntries[i].grfAccessMode)
3534         {
3535         case GRANT_ACCESS:
3536         case SET_ACCESS:
3537             acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3538             break;
3539         case DENY_ACCESS:
3540             acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3541             break;
3542         case SET_AUDIT_SUCCESS:
3543         case SET_AUDIT_FAILURE:
3544             acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3545             break;
3546         case REVOKE_ACCESS:
3547             break;
3548         default:
3549             WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3550             ret = ERROR_INVALID_PARAMETER;
3551             goto exit;
3552         }
3553     }
3554
3555     if (OldAcl)
3556     {
3557         ACL_SIZE_INFORMATION size_info;
3558
3559         status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3560         if (status != STATUS_SUCCESS)
3561         {
3562             ret = RtlNtStatusToDosError(status);
3563             goto exit;
3564         }
3565         acl_size += size_info.AclBytesInUse - sizeof(ACL);
3566     }
3567
3568     *NewAcl = LocalAlloc(0, acl_size);
3569     if (!*NewAcl)
3570     {
3571         ret = ERROR_OUTOFMEMORY;
3572         goto exit;
3573     }
3574
3575     status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3576     if (status != STATUS_SUCCESS)
3577     {
3578         ret = RtlNtStatusToDosError(status);
3579         goto exit;
3580     }
3581
3582     for (i = 0; i < count; i++)
3583     {
3584         switch (pEntries[i].grfAccessMode)
3585         {
3586         case GRANT_ACCESS:
3587             status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3588                                               pEntries[i].grfInheritance,
3589                                               pEntries[i].grfAccessPermissions,
3590                                               ppsid[i]);
3591             break;
3592         case SET_ACCESS:
3593         {
3594             ULONG j;
3595             BOOL add = TRUE;
3596             if (OldAcl)
3597             {
3598                 for (j = 0; ; j++)
3599                 {
3600                     const ACE_HEADER *existing_ace_header;
3601                     status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3602                     if (status != STATUS_SUCCESS)
3603                         break;
3604                     if (pEntries[i].grfAccessMode == SET_ACCESS &&
3605                         existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3606                         EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3607                     {
3608                         add = FALSE;
3609                         break;
3610                     }
3611                 }
3612             }
3613             if (add)
3614                 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3615                                                   pEntries[i].grfInheritance,
3616                                                   pEntries[i].grfAccessPermissions,
3617                                                   ppsid[i]);
3618             break;
3619         }
3620         case DENY_ACCESS:
3621             status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3622                                              pEntries[i].grfInheritance,
3623                                              pEntries[i].grfAccessPermissions,
3624                                              ppsid[i]);
3625             break;
3626         case SET_AUDIT_SUCCESS:
3627             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3628                                             pEntries[i].grfInheritance,
3629                                             pEntries[i].grfAccessPermissions,
3630                                             ppsid[i], TRUE, FALSE);
3631             break;
3632         case SET_AUDIT_FAILURE:
3633             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3634                                             pEntries[i].grfInheritance,
3635                                             pEntries[i].grfAccessPermissions,
3636                                             ppsid[i], FALSE, TRUE);
3637             break;
3638         default:
3639             FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3640         }
3641     }
3642
3643     if (OldAcl)
3644     {
3645         for (i = 0; ; i++)
3646         {
3647             BOOL add = TRUE;
3648             ULONG j;
3649             const ACE_HEADER *old_ace_header;
3650             status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3651             if (status != STATUS_SUCCESS) break;
3652             for (j = 0; j < count; j++)
3653             {
3654                 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3655                     old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3656                     EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3657                 {
3658                     status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3659                     add = FALSE;
3660                     break;
3661                 }
3662                 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3663                 {
3664                     switch (old_ace_header->AceType)
3665                     {
3666                     case ACCESS_ALLOWED_ACE_TYPE:
3667                         if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3668                             add = FALSE;
3669                         break;
3670                     case ACCESS_DENIED_ACE_TYPE:
3671                         if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3672                             add = FALSE;
3673                         break;
3674                     case SYSTEM_AUDIT_ACE_TYPE:
3675                         if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3676                             add = FALSE;
3677                         break;
3678                     case SYSTEM_ALARM_ACE_TYPE:
3679                         if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3680                             add = FALSE;
3681                         break;
3682                     default:
3683                         FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3684                     }
3685
3686                     if (!add)
3687                         break;
3688                 }
3689             }
3690             if (add)
3691                 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3692             if (status != STATUS_SUCCESS)
3693             {
3694                 WARN("RtlAddAce failed with error 0x%08x\n", status);
3695                 ret = RtlNtStatusToDosError(status);
3696                 break;
3697             }
3698         }
3699     }
3700
3701 exit:
3702     HeapFree(GetProcessHeap(), 0, ppsid);
3703     return ret;
3704 }
3705
3706 /******************************************************************************
3707  * SetNamedSecurityInfoA [ADVAPI32.@]
3708  */
3709 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3710         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3711         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3712 {
3713     DWORD len;
3714     LPWSTR wstr = NULL;
3715     DWORD r;
3716
3717     TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3718            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3719
3720     if( pObjectName )
3721     {
3722         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3723         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3724         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3725     }
3726
3727     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3728                            psidGroup, pDacl, pSacl );
3729
3730     HeapFree( GetProcessHeap(), 0, wstr );
3731
3732     return r;
3733 }
3734
3735 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3736     PSECURITY_DESCRIPTOR ModificationDescriptor,
3737     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3738     PGENERIC_MAPPING GenericMapping,
3739     HANDLE Token )
3740 {
3741     FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3742           ObjectsSecurityDescriptor, GenericMapping, Token);
3743
3744     return TRUE;
3745 }
3746
3747 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3748 {
3749     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3750 }
3751
3752 /******************************************************************************
3753  * AreAnyAccessesGranted [ADVAPI32.@]
3754  *
3755  * Determines whether or not any of a set of specified access permissions have
3756  * been granted or not.
3757  *
3758  * PARAMS
3759  *   GrantedAccess [I] The permissions that have been granted.
3760  *   DesiredAccess [I] The permissions that you want to have.
3761  *
3762  * RETURNS
3763  *   Nonzero if any of the permissions have been granted, zero if none of the
3764  *   permissions have been granted.
3765  */
3766
3767 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3768 {
3769     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3770 }
3771
3772 /******************************************************************************
3773  * SetNamedSecurityInfoW [ADVAPI32.@]
3774  */
3775 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3776         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3777         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3778 {
3779     FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3780            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3781     return ERROR_SUCCESS;
3782 }
3783
3784 /******************************************************************************
3785  * GetExplicitEntriesFromAclA [ADVAPI32.@]
3786  */
3787 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3788         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3789 {
3790     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3791     return ERROR_CALL_NOT_IMPLEMENTED;
3792 }
3793
3794 /******************************************************************************
3795  * GetExplicitEntriesFromAclW [ADVAPI32.@]
3796  */
3797 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3798         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3799 {
3800     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3801     return ERROR_CALL_NOT_IMPLEMENTED;
3802 }
3803
3804 /******************************************************************************
3805  * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3806  */
3807 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3808         PACCESS_MASK pFailedAuditRights)
3809 {
3810     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3811     return ERROR_CALL_NOT_IMPLEMENTED;
3812
3813 }
3814
3815 /******************************************************************************
3816  * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3817  */
3818 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3819         PACCESS_MASK pFailedAuditRights)
3820 {
3821     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3822     return ERROR_CALL_NOT_IMPLEMENTED;
3823
3824 }
3825
3826 /******************************************************************************
3827  * ParseAclStringFlags
3828  */
3829 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3830 {
3831     DWORD flags = 0;
3832     LPCWSTR szAcl = *StringAcl;
3833
3834     while (*szAcl != '(')
3835     {
3836         if (*szAcl == 'P')
3837         {
3838             flags |= SE_DACL_PROTECTED;
3839         }
3840         else if (*szAcl == 'A')
3841         {
3842             szAcl++;
3843             if (*szAcl == 'R')
3844                 flags |= SE_DACL_AUTO_INHERIT_REQ;
3845             else if (*szAcl == 'I')
3846                 flags |= SE_DACL_AUTO_INHERITED;
3847         }
3848         szAcl++;
3849     }
3850
3851     *StringAcl = szAcl;
3852     return flags;
3853 }
3854
3855 /******************************************************************************
3856  * ParseAceStringType
3857  */
3858 static const ACEFLAG AceType[] =
3859 {
3860     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
3861     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
3862     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3863     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
3864     /*
3865     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3866     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
3867     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
3868     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3869     */
3870     { NULL, 0 },
3871 };
3872
3873 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3874 {
3875     UINT len = 0;
3876     LPCWSTR szAcl = *StringAcl;
3877     const ACEFLAG *lpaf = AceType;
3878
3879     while (lpaf->wstr &&
3880         (len = strlenW(lpaf->wstr)) &&
3881         strncmpW(lpaf->wstr, szAcl, len))
3882         lpaf++;
3883
3884     if (!lpaf->wstr)
3885         return 0;
3886
3887     *StringAcl += len;
3888     return lpaf->value;
3889 }
3890
3891
3892 /******************************************************************************
3893  * ParseAceStringFlags
3894  */
3895 static const ACEFLAG AceFlags[] =
3896 {
3897     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3898     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
3899     { SDDL_INHERITED,         INHERITED_ACE },
3900     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
3901     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
3902     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
3903     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
3904     { NULL, 0 },
3905 };
3906
3907 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3908 {
3909     UINT len = 0;
3910     BYTE flags = 0;
3911     LPCWSTR szAcl = *StringAcl;
3912
3913     while (*szAcl != ';')
3914     {
3915         const ACEFLAG *lpaf = AceFlags;
3916
3917         while (lpaf->wstr &&
3918                (len = strlenW(lpaf->wstr)) &&
3919                strncmpW(lpaf->wstr, szAcl, len))
3920             lpaf++;
3921
3922         if (!lpaf->wstr)
3923             return 0;
3924
3925         flags |= lpaf->value;
3926         szAcl += len;
3927     }
3928
3929     *StringAcl = szAcl;
3930     return flags;
3931 }
3932
3933
3934 /******************************************************************************
3935  * ParseAceStringRights
3936  */
3937 static const ACEFLAG AceRights[] =
3938 {
3939     { SDDL_GENERIC_ALL,     GENERIC_ALL },
3940     { SDDL_GENERIC_READ,    GENERIC_READ },
3941     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
3942     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3943
3944     { SDDL_READ_CONTROL,    READ_CONTROL },
3945     { SDDL_STANDARD_DELETE, DELETE },
3946     { SDDL_WRITE_DAC,       WRITE_DAC },
3947     { SDDL_WRITE_OWNER,     WRITE_OWNER },
3948
3949     { SDDL_READ_PROPERTY,   ADS_RIGHT_DS_READ_PROP},
3950     { SDDL_WRITE_PROPERTY,  ADS_RIGHT_DS_WRITE_PROP},
3951     { SDDL_CREATE_CHILD,    ADS_RIGHT_DS_CREATE_CHILD},
3952     { SDDL_DELETE_CHILD,    ADS_RIGHT_DS_DELETE_CHILD},
3953     { SDDL_LIST_CHILDREN,   ADS_RIGHT_ACTRL_DS_LIST},
3954     { SDDL_SELF_WRITE,      ADS_RIGHT_DS_SELF},
3955     { SDDL_LIST_OBJECT,     ADS_RIGHT_DS_LIST_OBJECT},
3956     { SDDL_DELETE_TREE,     ADS_RIGHT_DS_DELETE_TREE},
3957     { SDDL_CONTROL_ACCESS,  ADS_RIGHT_DS_CONTROL_ACCESS},
3958
3959     { SDDL_FILE_ALL,        FILE_ALL_ACCESS },
3960     { SDDL_FILE_READ,       FILE_GENERIC_READ },
3961     { SDDL_FILE_WRITE,      FILE_GENERIC_WRITE },
3962     { SDDL_FILE_EXECUTE,    FILE_GENERIC_EXECUTE },
3963
3964     { SDDL_KEY_ALL,         KEY_ALL_ACCESS },
3965     { SDDL_KEY_READ,        KEY_READ },
3966     { SDDL_KEY_WRITE,       KEY_WRITE },
3967     { SDDL_KEY_EXECUTE,     KEY_EXECUTE },
3968     { NULL, 0 },
3969 };
3970
3971 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3972 {
3973     UINT len = 0;
3974     DWORD rights = 0;
3975     LPCWSTR szAcl = *StringAcl;
3976
3977     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3978     {
3979         LPCWSTR p = szAcl;
3980
3981         while (*p && *p != ';')
3982             p++;
3983
3984         if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3985         {
3986             rights = strtoulW(szAcl, NULL, 16);
3987             szAcl = p;
3988         }
3989         else
3990             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3991     }
3992     else
3993     {
3994         while (*szAcl != ';')
3995         {
3996             const ACEFLAG *lpaf = AceRights;
3997
3998             while (lpaf->wstr &&
3999                (len = strlenW(lpaf->wstr)) &&
4000                strncmpW(lpaf->wstr, szAcl, len))
4001             {
4002                lpaf++;
4003             }
4004
4005             if (!lpaf->wstr)
4006                 return 0;
4007
4008             rights |= lpaf->value;
4009             szAcl += len;
4010         }
4011     }
4012
4013     *StringAcl = szAcl;
4014     return rights;
4015 }
4016
4017
4018 /******************************************************************************
4019  * ParseStringAclToAcl
4020  * 
4021  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
4022  */
4023 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
4024     PACL pAcl, LPDWORD cBytes)
4025 {
4026     DWORD val;
4027     DWORD sidlen;
4028     DWORD length = sizeof(ACL);
4029     DWORD acesize = 0;
4030     DWORD acecount = 0;
4031     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4032
4033     TRACE("%s\n", debugstr_w(StringAcl));
4034
4035     if (!StringAcl)
4036         return FALSE;
4037
4038     if (pAcl) /* pAce is only useful if we're setting values */
4039         pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4040
4041     /* Parse ACL flags */
4042     *lpdwFlags = ParseAclStringFlags(&StringAcl);
4043
4044     /* Parse ACE */
4045     while (*StringAcl == '(')
4046     {
4047         StringAcl++;
4048
4049         /* Parse ACE type */
4050         val = ParseAceStringType(&StringAcl);
4051         if (pAce)
4052             pAce->Header.AceType = (BYTE) val;
4053         if (*StringAcl != ';')
4054             goto lerr;
4055         StringAcl++;
4056
4057         /* Parse ACE flags */
4058         val = ParseAceStringFlags(&StringAcl);
4059         if (pAce)
4060             pAce->Header.AceFlags = (BYTE) val;
4061         if (*StringAcl != ';')
4062             goto lerr;
4063         StringAcl++;
4064
4065         /* Parse ACE rights */
4066         val = ParseAceStringRights(&StringAcl);
4067         if (pAce)
4068             pAce->Mask = val;
4069         if (*StringAcl != ';')
4070             goto lerr;
4071         StringAcl++;
4072
4073         /* Parse ACE object guid */
4074         if (*StringAcl != ';')
4075         {
4076             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4077             goto lerr;
4078         }
4079         StringAcl++;
4080
4081         /* Parse ACE inherit object guid */
4082         if (*StringAcl != ';')
4083         {
4084             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4085             goto lerr;
4086         }
4087         StringAcl++;
4088
4089         /* Parse ACE account sid */
4090         if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4091         {
4092             while (*StringAcl && *StringAcl != ')')
4093                 StringAcl++;
4094         }
4095
4096         if (*StringAcl != ')')
4097             goto lerr;
4098         StringAcl++;
4099
4100         acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4101         length += acesize;
4102         if (pAce)
4103         {
4104             pAce->Header.AceSize = acesize;
4105             pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4106         }
4107         acecount++;
4108     }
4109
4110     *cBytes = length;
4111
4112     if (length > 0xffff)
4113     {
4114         ERR("ACL too large\n");
4115         goto lerr;
4116     }
4117
4118     if (pAcl)
4119     {
4120         pAcl->AclRevision = ACL_REVISION;
4121         pAcl->Sbz1 = 0;
4122         pAcl->AclSize = length;
4123         pAcl->AceCount = acecount++;
4124         pAcl->Sbz2 = 0;
4125     }
4126     return TRUE;
4127
4128 lerr:
4129     SetLastError(ERROR_INVALID_ACL);
4130     WARN("Invalid ACE string format\n");
4131     return FALSE;
4132 }
4133
4134
4135 /******************************************************************************
4136  * ParseStringSecurityDescriptorToSecurityDescriptor
4137  */
4138 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4139     LPCWSTR StringSecurityDescriptor,
4140     SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4141     LPDWORD cBytes)
4142 {
4143     BOOL bret = FALSE;
4144     WCHAR toktype;
4145     WCHAR tok[MAX_PATH];
4146     LPCWSTR lptoken;
4147     LPBYTE lpNext = NULL;
4148     DWORD len;
4149
4150     *cBytes = sizeof(SECURITY_DESCRIPTOR);
4151
4152     if (SecurityDescriptor)
4153         lpNext = (LPBYTE)(SecurityDescriptor + 1);
4154
4155     while (*StringSecurityDescriptor)
4156     {
4157         toktype = *StringSecurityDescriptor;
4158
4159         /* Expect char identifier followed by ':' */
4160         StringSecurityDescriptor++;
4161         if (*StringSecurityDescriptor != ':')
4162         {
4163             SetLastError(ERROR_INVALID_PARAMETER);
4164             goto lend;
4165         }
4166         StringSecurityDescriptor++;
4167
4168         /* Extract token */
4169         lptoken = StringSecurityDescriptor;
4170         while (*lptoken && *lptoken != ':')
4171             lptoken++;
4172
4173         if (*lptoken)
4174             lptoken--;
4175
4176         len = lptoken - StringSecurityDescriptor;
4177         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4178         tok[len] = 0;
4179
4180         switch (toktype)
4181         {
4182             case 'O':
4183             {
4184                 DWORD bytes;
4185
4186                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4187                     goto lend;
4188
4189                 if (SecurityDescriptor)
4190                 {
4191                     SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4192                     lpNext += bytes; /* Advance to next token */
4193                 }
4194
4195                 *cBytes += bytes;
4196
4197                 break;
4198             }
4199
4200             case 'G':
4201             {
4202                 DWORD bytes;
4203
4204                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4205                     goto lend;
4206
4207                 if (SecurityDescriptor)
4208                 {
4209                     SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4210                     lpNext += bytes; /* Advance to next token */
4211                 }
4212
4213                 *cBytes += bytes;
4214
4215                 break;
4216             }
4217
4218             case 'D':
4219             {
4220                 DWORD flags;
4221                 DWORD bytes;
4222
4223                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4224                     goto lend;
4225
4226                 if (SecurityDescriptor)
4227                 {
4228                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4229                     SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4230                     lpNext += bytes; /* Advance to next token */
4231                 }
4232
4233                 *cBytes += bytes;
4234
4235                 break;
4236             }
4237
4238             case 'S':
4239             {
4240                 DWORD flags;
4241                 DWORD bytes;
4242
4243                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4244                     goto lend;
4245
4246                 if (SecurityDescriptor)
4247                 {
4248                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4249                     SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4250                     lpNext += bytes; /* Advance to next token */
4251                 }
4252
4253                 *cBytes += bytes;
4254
4255                 break;
4256             }
4257
4258             default:
4259                 FIXME("Unknown token\n");
4260                 SetLastError(ERROR_INVALID_PARAMETER);
4261                 goto lend;
4262         }
4263
4264         StringSecurityDescriptor = lptoken;
4265     }
4266
4267     bret = TRUE;
4268
4269 lend:
4270     return bret;
4271 }
4272
4273 /******************************************************************************
4274  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4275  */
4276 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4277         LPCSTR StringSecurityDescriptor,
4278         DWORD StringSDRevision,
4279         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4280         PULONG SecurityDescriptorSize)
4281 {
4282     UINT len;
4283     BOOL ret = FALSE;
4284     LPWSTR StringSecurityDescriptorW;
4285
4286     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4287     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4288
4289     if (StringSecurityDescriptorW)
4290     {
4291         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4292
4293         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4294                                                                    StringSDRevision, SecurityDescriptor,
4295                                                                    SecurityDescriptorSize);
4296         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4297     }
4298
4299     return ret;
4300 }
4301
4302 /******************************************************************************
4303  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4304  */
4305 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4306         LPCWSTR StringSecurityDescriptor,
4307         DWORD StringSDRevision,
4308         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4309         PULONG SecurityDescriptorSize)
4310 {
4311     DWORD cBytes;
4312     SECURITY_DESCRIPTOR* psd;
4313     BOOL bret = FALSE;
4314
4315     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4316
4317     if (GetVersion() & 0x80000000)
4318     {
4319         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4320         goto lend;
4321     }
4322     else if (!StringSecurityDescriptor || !SecurityDescriptor)
4323     {
4324         SetLastError(ERROR_INVALID_PARAMETER);
4325         goto lend;
4326     }
4327     else if (StringSDRevision != SID_REVISION)
4328     {
4329         SetLastError(ERROR_UNKNOWN_REVISION);
4330         goto lend;
4331     }
4332
4333     /* Compute security descriptor length */
4334     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4335         NULL, &cBytes))
4336         goto lend;
4337
4338     psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4339     if (!psd) goto lend;
4340
4341     psd->Revision = SID_REVISION;
4342     psd->Control |= SE_SELF_RELATIVE;
4343
4344     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4345              (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4346     {
4347         LocalFree(psd);
4348         goto lend;
4349     }
4350
4351     if (SecurityDescriptorSize)
4352         *SecurityDescriptorSize = cBytes;
4353
4354     bret = TRUE;
4355  
4356 lend:
4357     TRACE(" ret=%d\n", bret);
4358     return bret;
4359 }
4360
4361 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4362 {
4363     if (cch == -1)
4364         cch = strlenW(string);
4365
4366     if (plen)
4367         *plen += cch;
4368
4369     if (pwptr)
4370     {
4371         memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4372         *pwptr += cch;
4373     }
4374 }
4375
4376 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4377 {
4378     DWORD i;
4379     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4380     WCHAR subauthfmt[] = { '-','%','u',0 };
4381     WCHAR buf[26];
4382     SID *pisid = psid;
4383
4384     if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4385     {
4386         SetLastError(ERROR_INVALID_SID);
4387         return FALSE;
4388     }
4389
4390     if (pisid->IdentifierAuthority.Value[0] ||
4391      pisid->IdentifierAuthority.Value[1])
4392     {
4393         FIXME("not matching MS' bugs\n");
4394         SetLastError(ERROR_INVALID_SID);
4395         return FALSE;
4396     }
4397
4398     sprintfW( buf, fmt, pisid->Revision,
4399         MAKELONG(
4400             MAKEWORD( pisid->IdentifierAuthority.Value[5],
4401                     pisid->IdentifierAuthority.Value[4] ),
4402             MAKEWORD( pisid->IdentifierAuthority.Value[3],
4403                     pisid->IdentifierAuthority.Value[2] )
4404         ) );
4405     DumpString(buf, -1, pwptr, plen);
4406
4407     for( i=0; i<pisid->SubAuthorityCount; i++ )
4408     {
4409         sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4410         DumpString(buf, -1, pwptr, plen);
4411     }
4412     return TRUE;
4413 }
4414
4415 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4416 {
4417     size_t i;
4418     for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4419     {
4420         if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4421         {
4422             DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4423             return TRUE;
4424         }
4425     }
4426
4427     return DumpSidNumeric(psid, pwptr, plen);
4428 }
4429
4430 static const LPCWSTR AceRightBitNames[32] = {
4431         SDDL_CREATE_CHILD,        /*  0 */
4432         SDDL_DELETE_CHILD,
4433         SDDL_LIST_CHILDREN,
4434         SDDL_SELF_WRITE,
4435         SDDL_READ_PROPERTY,       /*  4 */
4436         SDDL_WRITE_PROPERTY,
4437         SDDL_DELETE_TREE,
4438         SDDL_LIST_OBJECT,
4439         SDDL_CONTROL_ACCESS,      /*  8 */
4440         NULL,
4441         NULL,
4442         NULL,
4443         NULL,                     /* 12 */
4444         NULL,
4445         NULL,
4446         NULL,
4447         SDDL_STANDARD_DELETE,     /* 16 */
4448         SDDL_READ_CONTROL,
4449         SDDL_WRITE_DAC,
4450         SDDL_WRITE_OWNER,
4451         NULL,                     /* 20 */
4452         NULL,
4453         NULL,
4454         NULL,
4455         NULL,                     /* 24 */
4456         NULL,
4457         NULL,
4458         NULL,
4459         SDDL_GENERIC_ALL,         /* 28 */
4460         SDDL_GENERIC_EXECUTE,
4461         SDDL_GENERIC_WRITE,
4462         SDDL_GENERIC_READ
4463 };
4464
4465 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4466 {
4467     static const WCHAR fmtW[] = {'0','x','%','x',0};
4468     WCHAR buf[15];
4469     size_t i;
4470
4471     if (mask == 0)
4472         return;
4473
4474     /* first check if the right have name */
4475     for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4476     {
4477         if (AceRights[i].wstr == NULL)
4478             break;
4479         if (mask == AceRights[i].value)
4480         {
4481             DumpString(AceRights[i].wstr, -1, pwptr, plen);
4482             return;
4483         }
4484     }
4485
4486     /* then check if it can be built from bit names */
4487     for (i = 0; i < 32; i++)
4488     {
4489         if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4490         {
4491             /* can't be built from bit names */
4492             sprintfW(buf, fmtW, mask);
4493             DumpString(buf, -1, pwptr, plen);
4494             return;
4495         }
4496     }
4497
4498     /* build from bit names */
4499     for (i = 0; i < 32; i++)
4500         if (mask & (1 << i))
4501             DumpString(AceRightBitNames[i], -1, pwptr, plen);
4502 }
4503
4504 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4505 {
4506     ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4507     static const WCHAR openbr = '(';
4508     static const WCHAR closebr = ')';
4509     static const WCHAR semicolon = ';';
4510
4511     if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4512     {
4513         SetLastError(ERROR_INVALID_ACL);
4514         return FALSE;
4515     }
4516
4517     piace = pace;
4518     DumpString(&openbr, 1, pwptr, plen);
4519     switch (piace->Header.AceType)
4520     {
4521         case ACCESS_ALLOWED_ACE_TYPE:
4522             DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4523             break;
4524         case ACCESS_DENIED_ACE_TYPE:
4525             DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4526             break;
4527         case SYSTEM_AUDIT_ACE_TYPE:
4528             DumpString(SDDL_AUDIT, -1, pwptr, plen);
4529             break;
4530         case SYSTEM_ALARM_ACE_TYPE:
4531             DumpString(SDDL_ALARM, -1, pwptr, plen);
4532             break;
4533     }
4534     DumpString(&semicolon, 1, pwptr, plen);
4535
4536     if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4537         DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4538     if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4539         DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4540     if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4541         DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4542     if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4543         DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4544     if (piace->Header.AceFlags & INHERITED_ACE)
4545         DumpString(SDDL_INHERITED, -1, pwptr, plen);
4546     if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4547         DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4548     if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4549         DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4550     DumpString(&semicolon, 1, pwptr, plen);
4551     DumpRights(piace->Mask, pwptr, plen);
4552     DumpString(&semicolon, 1, pwptr, plen);
4553     /* objects not supported */
4554     DumpString(&semicolon, 1, pwptr, plen);
4555     /* objects not supported */
4556     DumpString(&semicolon, 1, pwptr, plen);
4557     if (!DumpSid(&piace->SidStart, pwptr, plen))
4558         return FALSE;
4559     DumpString(&closebr, 1, pwptr, plen);
4560     return TRUE;
4561 }
4562
4563 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4564 {
4565     WORD count;
4566     int i;
4567
4568     if (protected)
4569         DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4570     if (autoInheritReq)
4571         DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4572     if (autoInherited)
4573         DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4574
4575     if (pacl == NULL)
4576         return TRUE;
4577
4578     if (!IsValidAcl(pacl))
4579         return FALSE;
4580
4581     count = pacl->AceCount;
4582     for (i = 0; i < count; i++)
4583     {
4584         LPVOID ace;
4585         if (!GetAce(pacl, i, &ace))
4586             return FALSE;
4587         if (!DumpAce(ace, pwptr, plen))
4588             return FALSE;
4589     }
4590
4591     return TRUE;
4592 }
4593
4594 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4595 {
4596     static const WCHAR prefix[] = {'O',':',0};
4597     BOOL bDefaulted;
4598     PSID psid;
4599
4600     if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4601         return FALSE;
4602
4603     if (psid == NULL)
4604         return TRUE;
4605
4606     DumpString(prefix, -1, pwptr, plen);
4607     if (!DumpSid(psid, pwptr, plen))
4608         return FALSE;
4609     return TRUE;
4610 }
4611
4612 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4613 {
4614     static const WCHAR prefix[] = {'G',':',0};
4615     BOOL bDefaulted;
4616     PSID psid;
4617
4618     if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4619         return FALSE;
4620
4621     if (psid == NULL)
4622         return TRUE;
4623
4624     DumpString(prefix, -1, pwptr, plen);
4625     if (!DumpSid(psid, pwptr, plen))
4626         return FALSE;
4627     return TRUE;
4628 }
4629
4630 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4631 {
4632     static const WCHAR dacl[] = {'D',':',0};
4633     SECURITY_DESCRIPTOR_CONTROL control;
4634     BOOL present, defaulted;
4635     DWORD revision;
4636     PACL pacl;
4637
4638     if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4639         return FALSE;
4640
4641     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4642         return FALSE;
4643
4644     if (!present)
4645         return TRUE;
4646
4647     DumpString(dacl, 2, pwptr, plen);
4648     if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4649         return FALSE;
4650     return TRUE;
4651 }
4652
4653 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4654 {
4655     static const WCHAR sacl[] = {'S',':',0};
4656     SECURITY_DESCRIPTOR_CONTROL control;
4657     BOOL present, defaulted;
4658     DWORD revision;
4659     PACL pacl;
4660
4661     if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4662         return FALSE;
4663
4664     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4665         return FALSE;
4666
4667     if (!present)
4668         return TRUE;
4669
4670     DumpString(sacl, 2, pwptr, plen);
4671     if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4672         return FALSE;
4673     return TRUE;
4674 }
4675
4676 /******************************************************************************
4677  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4678  */
4679 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4680 {
4681     ULONG len;
4682     WCHAR *wptr, *wstr;
4683
4684     if (SDRevision != SDDL_REVISION_1)
4685     {
4686         ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4687         SetLastError(ERROR_UNKNOWN_REVISION);
4688         return FALSE;
4689     }
4690
4691     len = 0;
4692     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4693         if (!DumpOwner(SecurityDescriptor, NULL, &len))
4694             return FALSE;
4695     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4696         if (!DumpGroup(SecurityDescriptor, NULL, &len))
4697             return FALSE;
4698     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4699         if (!DumpDacl(SecurityDescriptor, NULL, &len))
4700             return FALSE;
4701     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4702         if (!DumpSacl(SecurityDescriptor, NULL, &len))
4703             return FALSE;
4704
4705     wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4706     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4707         if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4708             return FALSE;
4709     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4710         if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4711             return FALSE;
4712     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4713         if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4714             return FALSE;
4715     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4716         if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4717             return FALSE;
4718     *wptr = 0;
4719
4720     TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4721     *OutputString = wstr;
4722     if (OutputLen)
4723         *OutputLen = strlenW(*OutputString)+1;
4724     return TRUE;
4725 }
4726
4727 /******************************************************************************
4728  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4729  */
4730 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4731 {
4732     LPWSTR wstr;
4733     ULONG len;
4734     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4735     {
4736         int lenA;
4737
4738         lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4739         *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4740         WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4741         LocalFree(wstr);
4742
4743         if (OutputLen != NULL)
4744             *OutputLen = lenA;
4745         return TRUE;
4746     }
4747     else
4748     {
4749         *OutputString = NULL;
4750         if (OutputLen)
4751             *OutputLen = 0;
4752         return FALSE;
4753     }
4754 }
4755
4756 /******************************************************************************
4757  * ConvertStringSidToSidW [ADVAPI32.@]
4758  */
4759 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4760 {
4761     BOOL bret = FALSE;
4762     DWORD cBytes;
4763
4764     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4765     if (GetVersion() & 0x80000000)
4766         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4767     else if (!StringSid || !Sid)
4768         SetLastError(ERROR_INVALID_PARAMETER);
4769     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4770     {
4771         PSID pSid = *Sid = LocalAlloc(0, cBytes);
4772
4773         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4774         if (!bret)
4775             LocalFree(*Sid); 
4776     }
4777     return bret;
4778 }
4779
4780 /******************************************************************************
4781  * ConvertStringSidToSidA [ADVAPI32.@]
4782  */
4783 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4784 {
4785     BOOL bret = FALSE;
4786
4787     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4788     if (GetVersion() & 0x80000000)
4789         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4790     else if (!StringSid || !Sid)
4791         SetLastError(ERROR_INVALID_PARAMETER);
4792     else
4793     {
4794         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4795         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4796          len * sizeof(WCHAR));
4797
4798         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4799         bret = ConvertStringSidToSidW(wStringSid, Sid);
4800         HeapFree(GetProcessHeap(), 0, wStringSid);
4801     }
4802     return bret;
4803 }
4804
4805 /******************************************************************************
4806  * ConvertSidToStringSidW [ADVAPI32.@]
4807  *
4808  *  format of SID string is:
4809  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4810  *  where
4811  *    <rev> is the revision of the SID encoded as decimal
4812  *    <auth> is the identifier authority encoded as hex
4813  *    <subauthN> is the subauthority id encoded as decimal
4814  */
4815 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4816 {
4817     DWORD len = 0;
4818     LPWSTR wstr, wptr;
4819
4820     TRACE("%p %p\n", pSid, pstr );
4821
4822     len = 0;
4823     if (!DumpSidNumeric(pSid, NULL, &len))
4824         return FALSE;
4825     wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4826     DumpSidNumeric(pSid, &wptr, NULL);
4827     *wptr = 0;
4828
4829     *pstr = wstr;
4830     return TRUE;
4831 }
4832
4833 /******************************************************************************
4834  * ConvertSidToStringSidA [ADVAPI32.@]
4835  */
4836 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4837 {
4838     LPWSTR wstr = NULL;
4839     LPSTR str;
4840     UINT len;
4841
4842     TRACE("%p %p\n", pSid, pstr );
4843
4844     if( !ConvertSidToStringSidW( pSid, &wstr ) )
4845         return FALSE;
4846
4847     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4848     str = LocalAlloc( 0, len );
4849     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4850     LocalFree( wstr );
4851
4852     *pstr = str;
4853
4854     return TRUE;
4855 }
4856
4857 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4858         PSECURITY_DESCRIPTOR pdesc,
4859         PSECURITY_DESCRIPTOR cdesc,
4860         PSECURITY_DESCRIPTOR* ndesc,
4861         GUID* objtype,
4862         BOOL isdir,
4863         PGENERIC_MAPPING genmap )
4864 {
4865     FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4866
4867     return FALSE;
4868 }
4869
4870 BOOL WINAPI CreatePrivateObjectSecurity(
4871         PSECURITY_DESCRIPTOR ParentDescriptor,
4872         PSECURITY_DESCRIPTOR CreatorDescriptor,
4873         PSECURITY_DESCRIPTOR* NewDescriptor,
4874         BOOL IsDirectoryObject,
4875         HANDLE Token,
4876         PGENERIC_MAPPING GenericMapping )
4877 {
4878     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4879           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4880
4881     return FALSE;
4882 }
4883
4884 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4885 {
4886     FIXME("%p - stub\n", ObjectDescriptor);
4887
4888     return TRUE;
4889 }
4890
4891 BOOL WINAPI CreateProcessAsUserA(
4892         HANDLE hToken,
4893         LPCSTR lpApplicationName,
4894         LPSTR lpCommandLine,
4895         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4896         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4897         BOOL bInheritHandles,
4898         DWORD dwCreationFlags,
4899         LPVOID lpEnvironment,
4900         LPCSTR lpCurrentDirectory,
4901         LPSTARTUPINFOA lpStartupInfo,
4902         LPPROCESS_INFORMATION lpProcessInformation )
4903 {
4904     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4905           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4906           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4907
4908     return FALSE;
4909 }
4910
4911 BOOL WINAPI CreateProcessAsUserW(
4912         HANDLE hToken,
4913         LPCWSTR lpApplicationName,
4914         LPWSTR lpCommandLine,
4915         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4916         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4917         BOOL bInheritHandles,
4918         DWORD dwCreationFlags,
4919         LPVOID lpEnvironment,
4920         LPCWSTR lpCurrentDirectory,
4921         LPSTARTUPINFOW lpStartupInfo,
4922         LPPROCESS_INFORMATION lpProcessInformation )
4923 {
4924     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken, 
4925           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4926           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
4927           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4928
4929     /* We should create the process with a suspended main thread */
4930     if (!CreateProcessW (lpApplicationName,
4931                          lpCommandLine,
4932                          lpProcessAttributes,
4933                          lpThreadAttributes,
4934                          bInheritHandles,
4935                          dwCreationFlags, /* CREATE_SUSPENDED */
4936                          lpEnvironment,
4937                          lpCurrentDirectory,
4938                          lpStartupInfo,
4939                          lpProcessInformation))
4940     {
4941       return FALSE;
4942     }
4943
4944     return TRUE;
4945 }
4946
4947 /******************************************************************************
4948  * CreateProcessWithLogonW
4949  */
4950 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4951     LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4952     LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4953 {
4954     FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4955     debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4956     debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4957     lpStartupInfo, lpProcessInformation);
4958
4959     return FALSE;
4960 }
4961
4962 /******************************************************************************
4963  * DuplicateTokenEx [ADVAPI32.@]
4964  */
4965 BOOL WINAPI DuplicateTokenEx(
4966         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4967         LPSECURITY_ATTRIBUTES lpTokenAttributes,
4968         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4969         TOKEN_TYPE TokenType,
4970         PHANDLE DuplicateTokenHandle )
4971 {
4972     OBJECT_ATTRIBUTES ObjectAttributes;
4973
4974     TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4975           ImpersonationLevel, TokenType, DuplicateTokenHandle);
4976
4977     InitializeObjectAttributes(
4978         &ObjectAttributes,
4979         NULL,
4980         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4981         NULL,
4982         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4983
4984     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4985                                            dwDesiredAccess,
4986                                            &ObjectAttributes,
4987                                            ImpersonationLevel,
4988                                            TokenType,
4989                                            DuplicateTokenHandle ) );
4990 }
4991
4992 BOOL WINAPI DuplicateToken(
4993         HANDLE ExistingTokenHandle,
4994         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4995         PHANDLE DuplicateTokenHandle )
4996 {
4997     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4998                              NULL, ImpersonationLevel, TokenImpersonation,
4999                              DuplicateTokenHandle );
5000 }
5001
5002 /******************************************************************************
5003  * ComputeStringSidSize
5004  */
5005 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5006 {
5007     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5008     {
5009         int ctok = 0;
5010         while (*StringSid)
5011         {
5012             if (*StringSid == '-')
5013                 ctok++;
5014             StringSid++;
5015         }
5016
5017         if (ctok >= 3)
5018             return GetSidLengthRequired(ctok - 2);
5019     }
5020     else /* String constant format  - Only available in winxp and above */
5021     {
5022         unsigned int i;
5023
5024         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5025             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5026                 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5027     }
5028
5029     return GetSidLengthRequired(0);
5030 }
5031
5032 /******************************************************************************
5033  * ParseStringSidToSid
5034  */
5035 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5036 {
5037     BOOL bret = FALSE;
5038     SID* pisid=pSid;
5039
5040     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5041     if (!StringSid)
5042     {
5043         SetLastError(ERROR_INVALID_PARAMETER);
5044         TRACE("StringSid is NULL, returning FALSE\n");
5045         return FALSE;
5046     }
5047
5048     *cBytes = ComputeStringSidSize(StringSid);
5049     if (!pisid) /* Simply compute the size */
5050     {
5051         TRACE("only size requested, returning TRUE\n");
5052         return TRUE;
5053     }
5054
5055     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5056     {
5057         DWORD i = 0, identAuth;
5058         DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5059
5060         StringSid += 2; /* Advance to Revision */
5061         pisid->Revision = atoiW(StringSid);
5062
5063         if (pisid->Revision != SDDL_REVISION)
5064         {
5065             TRACE("Revision %d is unknown\n", pisid->Revision);
5066             goto lend; /* ERROR_INVALID_SID */
5067         }
5068         if (csubauth == 0)
5069         {
5070             TRACE("SubAuthorityCount is 0\n");
5071             goto lend; /* ERROR_INVALID_SID */
5072         }
5073
5074         pisid->SubAuthorityCount = csubauth;
5075
5076         /* Advance to identifier authority */
5077         while (*StringSid && *StringSid != '-')
5078             StringSid++;
5079         if (*StringSid == '-')
5080             StringSid++;
5081
5082         /* MS' implementation can't handle values greater than 2^32 - 1, so
5083          * we don't either; assume most significant bytes are always 0
5084          */
5085         pisid->IdentifierAuthority.Value[0] = 0;
5086         pisid->IdentifierAuthority.Value[1] = 0;
5087         identAuth = atoiW(StringSid);
5088         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5089         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5090         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5091         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5092
5093         /* Advance to first sub authority */
5094         while (*StringSid && *StringSid != '-')
5095             StringSid++;
5096         if (*StringSid == '-')
5097             StringSid++;
5098
5099         while (*StringSid)
5100         {
5101             pisid->SubAuthority[i++] = atoiW(StringSid);
5102
5103             while (*StringSid && *StringSid != '-')
5104                 StringSid++;
5105             if (*StringSid == '-')
5106                 StringSid++;
5107         }
5108
5109         if (i != pisid->SubAuthorityCount)
5110             goto lend; /* ERROR_INVALID_SID */
5111
5112         bret = TRUE;
5113     }
5114     else /* String constant format  - Only available in winxp and above */
5115     {
5116         unsigned int i;
5117         pisid->Revision = SDDL_REVISION;
5118
5119         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5120             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5121             {
5122                 DWORD j;
5123                 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5124                 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5125                 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5126                     pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5127                 bret = TRUE;
5128             }
5129
5130         if (!bret)
5131             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5132     }
5133
5134 lend:
5135     if (!bret)
5136         SetLastError(ERROR_INVALID_SID);
5137
5138     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5139     return bret;
5140 }
5141
5142 /******************************************************************************
5143  * GetNamedSecurityInfoA [ADVAPI32.@]
5144  */
5145 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5146         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5147         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5148         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5149 {
5150     DWORD len;
5151     LPWSTR wstr = NULL;
5152     DWORD r;
5153
5154     TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5155         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5156
5157     if( pObjectName )
5158     {
5159         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5160         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5161         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5162     }
5163
5164     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5165                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5166
5167     HeapFree( GetProcessHeap(), 0, wstr );
5168
5169     return r;
5170 }
5171
5172 /******************************************************************************
5173  * GetNamedSecurityInfoW [ADVAPI32.@]
5174  */
5175 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5176     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5177     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5178 {
5179     DWORD needed, offset;
5180     SECURITY_DESCRIPTOR_RELATIVE *relative;
5181     BYTE *buffer;
5182
5183     TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5184            group, dacl, sacl, descriptor );
5185
5186     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
5187
5188     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5189     if (info & OWNER_SECURITY_INFORMATION)
5190         needed += sizeof(sidWorld);
5191     if (info & GROUP_SECURITY_INFORMATION)
5192         needed += sizeof(sidWorld);
5193     if (info & DACL_SECURITY_INFORMATION)
5194         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5195     if (info & SACL_SECURITY_INFORMATION)
5196         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5197
5198     /* must be freed by caller */
5199     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5200     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5201
5202     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5203     {
5204         HeapFree( GetProcessHeap(), 0, *descriptor );
5205         return ERROR_INVALID_SECURITY_DESCR;
5206     }
5207
5208     relative = *descriptor;
5209     relative->Control |= SE_SELF_RELATIVE;
5210     buffer = (BYTE *)relative;
5211     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5212
5213     if (info & OWNER_SECURITY_INFORMATION)
5214     {
5215         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5216         relative->Owner = offset;
5217         if (owner)
5218             *owner = buffer + offset;
5219         offset += sizeof(sidWorld);
5220     }
5221     if (info & GROUP_SECURITY_INFORMATION)
5222     {
5223         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5224         relative->Group = offset;
5225         if (group)
5226             *group = buffer + offset;
5227         offset += sizeof(sidWorld);
5228     }
5229     if (info & DACL_SECURITY_INFORMATION)
5230     {
5231         relative->Control |= SE_DACL_PRESENT;
5232         GetWorldAccessACL( (PACL)(buffer + offset) );
5233         relative->Dacl = offset;
5234         if (dacl)
5235             *dacl = (PACL)(buffer + offset);
5236         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5237     }
5238     if (info & SACL_SECURITY_INFORMATION)
5239     {
5240         relative->Control |= SE_SACL_PRESENT;
5241         GetWorldAccessACL( (PACL)(buffer + offset) );
5242         relative->Sacl = offset;
5243         if (sacl)
5244             *sacl = (PACL)(buffer + offset);
5245     }
5246     return ERROR_SUCCESS;
5247 }
5248
5249 /******************************************************************************
5250  * DecryptFileW [ADVAPI32.@]
5251  */
5252 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5253 {
5254     FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5255     return TRUE;
5256 }
5257
5258 /******************************************************************************
5259  * DecryptFileA [ADVAPI32.@]
5260  */
5261 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5262 {
5263     FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5264     return TRUE;
5265 }
5266
5267 /******************************************************************************
5268  * EncryptFileW [ADVAPI32.@]
5269  */
5270 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5271 {
5272     FIXME("%s\n", debugstr_w(lpFileName));
5273     return TRUE;
5274 }
5275
5276 /******************************************************************************
5277  * EncryptFileA [ADVAPI32.@]
5278  */
5279 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5280 {
5281     FIXME("%s\n", debugstr_a(lpFileName));
5282     return TRUE;
5283 }
5284
5285 /******************************************************************************
5286  * FileEncryptionStatusW [ADVAPI32.@]
5287  */
5288 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5289 {
5290     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5291     if (!lpStatus)
5292         return FALSE;
5293     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5294     return TRUE;
5295 }
5296
5297 /******************************************************************************
5298  * FileEncryptionStatusA [ADVAPI32.@]
5299  */
5300 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5301 {
5302     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5303     if (!lpStatus)
5304         return FALSE;
5305     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5306     return TRUE;
5307 }
5308
5309 /******************************************************************************
5310  * SetSecurityInfo [ADVAPI32.@]
5311  */
5312 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
5313                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5314                       PSID psidGroup, PACL pDacl, PACL pSacl) {
5315     FIXME("stub\n");
5316     return ERROR_SUCCESS;
5317 }
5318
5319 /******************************************************************************
5320  * SaferCreateLevel   [ADVAPI32.@]
5321  */
5322 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5323                              SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5324 {
5325     FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5326     return FALSE;
5327 }
5328
5329 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5330                 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5331                 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5332                 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5333                 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5334 {
5335     FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p  Stub\n",
5336         debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5337         pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5338
5339     return ERROR_SUCCESS;
5340 }
5341
5342 /******************************************************************************
5343  * SaferGetPolicyInformation   [ADVAPI32.@]
5344  */
5345 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5346                                       PVOID buffer, PDWORD required, LPVOID lpReserved)
5347 {
5348     FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5349     return FALSE;
5350 }