crypt32: Implement file stores.
[wine] / dlls / advapi32 / security.c
1 /*
2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  *
19  */
20
21 #include <stdarg.h>
22 #include <string.h>
23
24 #include "ntstatus.h"
25 #define WIN32_NO_STATUS
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "rpcnterr.h"
30 #include "winreg.h"
31 #include "winternl.h"
32 #include "winioctl.h"
33 #include "ntsecapi.h"
34 #include "accctrl.h"
35 #include "sddl.h"
36 #include "winsvc.h"
37 #include "aclapi.h"
38
39 #include "wine/debug.h"
40 #include "wine/unicode.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
43
44 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
45 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
46     PACL pAcl, LPDWORD cBytes);
47 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
48 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
49 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
50 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
51     LPCWSTR StringSecurityDescriptor,
52     SECURITY_DESCRIPTOR* SecurityDescriptor,
53     LPDWORD cBytes);
54 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
55
56 typedef struct _ACEFLAG
57 {
58    LPCWSTR wstr;
59    DWORD value;
60 } ACEFLAG, *LPACEFLAG;
61
62 typedef struct WELLKNOWNSID
63 {
64     WCHAR wstr[2];
65     WELL_KNOWN_SID_TYPE Type;
66
67     /* same fields as struct _SID */
68     BYTE Revision;
69     BYTE SubAuthorityCount;
70     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
71     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
72 } WELLKNOWNSID;
73
74 static const WELLKNOWNSID WellKnownSids[] =
75 {
76     { {0,0}, WinNullSid, SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } },
77     { {'W','D'}, WinWorldSid, SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } },
78     { {0,0}, WinLocalSid, SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } },
79     { {'C','O'}, WinCreatorOwnerSid, SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } },
80     { {'C','G'}, WinCreatorGroupSid, SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } },
81     { {0,0}, WinCreatorOwnerServerSid, SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } },
82     { {0,0}, WinCreatorGroupServerSid, SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } },
83     { {0,0}, WinNtAuthoritySid, SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { } },
84     { {0,0}, WinDialupSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } },
85     { {'N','U'}, WinNetworkSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } },
86     { {0,0}, WinBatchSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } },
87     { {'I','U'}, WinInteractiveSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } },
88     { {'S','U'}, WinServiceSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } },
89     { {'A','N'}, WinAnonymousSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } },
90     { {0,0}, WinProxySid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } },
91     { {'E','D'}, WinEnterpriseControllersSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } },
92     { {'P','S'}, WinSelfSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } },
93     { {'A','U'}, WinAuthenticatedUserSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } },
94     { {'R','C'}, WinRestrictedCodeSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } },
95     { {0,0}, WinTerminalServerSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } },
96     { {0,0}, WinRemoteLogonIdSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } },
97     { {'S','Y'}, WinLocalSystemSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } },
98     { {'L','S'}, WinLocalServiceSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } },
99     { {'N','S'}, WinNetworkServiceSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } },
100     { {0,0}, WinBuiltinDomainSid, SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } },
101     { {'B','A'}, WinBuiltinAdministratorsSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } },
102     { {'B','U'}, WinBuiltinUsersSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } },
103     { {'B','G'}, WinBuiltinGuestsSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } },
104     { {'P','U'}, WinBuiltinPowerUsersSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } },
105     { {'A','O'}, WinBuiltinAccountOperatorsSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } },
106     { {'S','O'}, WinBuiltinSystemOperatorsSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } },
107     { {'P','O'}, WinBuiltinPrintOperatorsSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } },
108     { {'B','O'}, WinBuiltinBackupOperatorsSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } },
109     { {'R','E'}, WinBuiltinReplicatorSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } },
110     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } },
111     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } },
112     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } },
113 };
114
115 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
116
117 typedef struct _AccountSid {
118     WELL_KNOWN_SID_TYPE type;
119     LPCWSTR account;
120     LPCWSTR domain;
121     SID_NAME_USE name_use;
122 } AccountSid;
123
124 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
125 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
126 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
127 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
128 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
129 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
130 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
131 static const WCHAR Blank[] = { 0 };
132 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
133 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
134 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 };
135 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
136 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 };
137 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
138 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
139 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 };
140 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
141 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
142 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
143 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
144 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
145 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
146 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 };
147 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
148 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
149 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
150 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
151 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
152 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
153 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
154 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 };
155 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 };
156 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
157 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
158 static const WCHAR SELF[] = { 'S','E','L','F',0 };
159 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
160 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
161 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
162 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 };
163 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
164
165 static const AccountSid ACCOUNT_SIDS[] = {
166     { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
167     { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
168     { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
169     { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
170     { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
171     { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
172     { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
173     { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
174     { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
175     { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
176     { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
177     { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
178     { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
179     { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
180     { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
181     { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
182     { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
183     { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
184     { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
185     { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
186     { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
187     { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
188     { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
189     { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
190     { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
191     { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
192     { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
193     { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
194     { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
195     { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
196     { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
197     { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
198     { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
199     { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
200     { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
201     { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
202 };
203 /*
204  * ACE access rights
205  */
206 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
207 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
208 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
209 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
210 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
211 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
212 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
213 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
214
215 /*
216  * ACE types
217  */
218 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
219 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
220 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
221 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
222 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
223 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
224 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
225 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
226
227 /*
228  * ACE flags
229  */
230 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
231 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
232 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
233 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
234 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
235 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
236 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
237
238 static const char * debugstr_sid(PSID sid)
239 {
240     int auth = 0;
241     SID * psid = (SID *)sid;
242
243     if (psid == NULL)
244         return "(null)";
245
246     auth = psid->IdentifierAuthority.Value[5] +
247            (psid->IdentifierAuthority.Value[4] << 8) +
248            (psid->IdentifierAuthority.Value[3] << 16) +
249            (psid->IdentifierAuthority.Value[2] << 24);
250
251     switch (psid->SubAuthorityCount) {
252     case 0:
253         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
254     case 1:
255         return wine_dbg_sprintf("S-%d-%d-%ld", psid->Revision, auth,
256             psid->SubAuthority[0]);
257     case 2:
258         return wine_dbg_sprintf("S-%d-%d-%ld-%ld", psid->Revision, auth,
259             psid->SubAuthority[0], psid->SubAuthority[1]);
260     case 3:
261         return wine_dbg_sprintf("S-%d-%d-%ld-%ld-%ld", psid->Revision, auth,
262             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
263     case 4:
264         return wine_dbg_sprintf("S-%d-%d-%ld-%ld-%ld-%ld", psid->Revision, auth,
265             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
266             psid->SubAuthority[3]);
267     case 5:
268         return wine_dbg_sprintf("S-%d-%d-%ld-%ld-%ld-%ld-%ld", psid->Revision, auth,
269             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
270             psid->SubAuthority[3], psid->SubAuthority[4]);
271     case 6:
272         return wine_dbg_sprintf("S-%d-%d-%ld-%ld-%ld-%ld-%ld-%ld", psid->Revision, auth,
273             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
274             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
275     case 7:
276         return wine_dbg_sprintf("S-%d-%d-%ld-%ld-%ld-%ld-%ld-%ld-%ld", psid->Revision, auth,
277             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
278             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
279             psid->SubAuthority[6]);
280     case 8:
281         return wine_dbg_sprintf("S-%d-%d-%ld-%ld-%ld-%ld-%ld-%ld-%ld-%ld", psid->Revision, auth,
282             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
283             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
284             psid->SubAuthority[6], psid->SubAuthority[7]);
285     }
286     return "(too-big)";
287 }
288
289 /* set last error code from NT status and get the proper boolean return value */
290 /* used for functions that are a simple wrapper around the corresponding ntdll API */
291 static inline BOOL set_ntstatus( NTSTATUS status )
292 {
293     if (status) SetLastError( RtlNtStatusToDosError( status ));
294     return !status;
295 }
296
297 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
298
299 static void GetWorldAccessACL(PACL pACL)
300 {
301     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
302
303     pACL->AclRevision = ACL_REVISION;
304     pACL->Sbz1 = 0;
305     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
306     pACL->AceCount = 1;
307     pACL->Sbz2 = 0;
308
309     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
310     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
311     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
312     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
313     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
314 }
315
316 /************************************************************
317  *                ADVAPI_IsLocalComputer
318  *
319  * Checks whether the server name indicates local machine.
320  */
321 static BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
322 {
323     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
324     BOOL Result;
325     LPWSTR buf;
326
327     if (!ServerName || !ServerName[0])
328         return TRUE;
329     
330     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
331     Result = GetComputerNameW(buf,  &dwSize);
332     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
333         ServerName += 2;
334     Result = Result && !lstrcmpW(ServerName, buf);
335     HeapFree(GetProcessHeap(), 0, buf);
336
337     return Result;
338 }
339
340 /*      ##############################
341         ######  TOKEN FUNCTIONS ######
342         ##############################
343 */
344
345 /******************************************************************************
346  * OpenProcessToken                     [ADVAPI32.@]
347  * Opens the access token associated with a process handle.
348  *
349  * PARAMS
350  *   ProcessHandle [I] Handle to process
351  *   DesiredAccess [I] Desired access to process
352  *   TokenHandle   [O] Pointer to handle of open access token
353  *
354  * RETURNS
355  *  Success: TRUE. TokenHandle contains the access token.
356  *  Failure: FALSE.
357  *
358  * NOTES
359  *  See NtOpenProcessToken.
360  */
361 BOOL WINAPI
362 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
363                   HANDLE *TokenHandle )
364 {
365         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
366 }
367
368 /******************************************************************************
369  * OpenThreadToken [ADVAPI32.@]
370  *
371  * Opens the access token associated with a thread handle.
372  *
373  * PARAMS
374  *   ThreadHandle  [I] Handle to process
375  *   DesiredAccess [I] Desired access to the thread
376  *   OpenAsSelf    [I] ???
377  *   TokenHandle   [O] Destination for the token handle
378  *
379  * RETURNS
380  *  Success: TRUE. TokenHandle contains the access token.
381  *  Failure: FALSE.
382  *
383  * NOTES
384  *  See NtOpenThreadToken.
385  */
386 BOOL WINAPI
387 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
388                  BOOL OpenAsSelf, HANDLE *TokenHandle)
389 {
390         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
391 }
392
393 BOOL WINAPI
394 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
395                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
396 {
397     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
398                                              PreviousState, ReturnLength));
399 }
400
401 /******************************************************************************
402  * AdjustTokenPrivileges [ADVAPI32.@]
403  *
404  * Adjust the privileges of an open token handle.
405  * 
406  * PARAMS
407  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
408  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
409  *  NewState             [I]   Desired new privileges of the token
410  *  BufferLength         [I]   Length of NewState
411  *  PreviousState        [O]   Destination for the previous state
412  *  ReturnLength         [I/O] Size of PreviousState
413  *
414  *
415  * RETURNS
416  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
417  *  Failure: FALSE.
418  *
419  * NOTES
420  *  See NtAdjustPrivilegesToken.
421  */
422 BOOL WINAPI
423 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
424                        LPVOID NewState, DWORD BufferLength,
425                        LPVOID PreviousState, LPDWORD ReturnLength )
426 {
427     NTSTATUS status;
428
429     TRACE("\n");
430     
431     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
432                                                      NewState, BufferLength, PreviousState,
433                                                      ReturnLength);
434     SetLastError( RtlNtStatusToDosError( status ));
435     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
436         return TRUE;
437     else
438         return FALSE;
439 }
440
441 /******************************************************************************
442  * CheckTokenMembership [ADVAPI32.@]
443  *
444  * Determine if an access token is a member of a SID.
445  * 
446  * PARAMS
447  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
448  *   SidToCheck  [I] SID that possibly contains the token
449  *   IsMember    [O] Destination for result.
450  *
451  * RETURNS
452  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
453  *  Failure: FALSE.
454  */
455 BOOL WINAPI
456 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
457                       PBOOL IsMember )
458 {
459   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
460
461   *IsMember = TRUE;
462   return(TRUE);
463 }
464
465 /******************************************************************************
466  * GetTokenInformation [ADVAPI32.@]
467  *
468  * Get a type of information about an access token.
469  *
470  * PARAMS
471  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
472  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
473  *   tokeninfo       [O] Destination for token information
474  *   tokeninfolength [I] Length of tokeninfo
475  *   retlen          [O] Destination for returned token information length
476  *
477  * RETURNS
478  *  Success: TRUE. tokeninfo contains retlen bytes of token information
479  *  Failure: FALSE.
480  *
481  * NOTES
482  *  See NtQueryInformationToken.
483  */
484 BOOL WINAPI
485 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
486                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
487 {
488     TRACE("(%p, %s, %p, %ld, %p):\n",
489           token,
490           (tokeninfoclass == TokenUser) ? "TokenUser" :
491           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
492           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
493           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
494           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
495           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
496           (tokeninfoclass == TokenSource) ? "TokenSource" :
497           (tokeninfoclass == TokenType) ? "TokenType" :
498           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
499           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
500           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
501           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
502           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
503           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
504           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
505           "Unknown",
506           tokeninfo, tokeninfolength, retlen);
507     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
508                                                   tokeninfolength, retlen));
509 }
510
511 /******************************************************************************
512  * SetTokenInformation [ADVAPI32.@]
513  *
514  * Set information for an access token.
515  *
516  * PARAMS
517  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
518  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
519  *   tokeninfo       [I] Token information to set
520  *   tokeninfolength [I] Length of tokeninfo
521  *
522  * RETURNS
523  *  Success: TRUE. The information for the token is set to tokeninfo.
524  *  Failure: FALSE.
525  */
526 BOOL WINAPI
527 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
528                      LPVOID tokeninfo, DWORD tokeninfolength )
529 {
530     TRACE("(%p, %s, %p, %ld): stub\n",
531           token,
532           (tokeninfoclass == TokenUser) ? "TokenUser" :
533           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
534           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
535           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
536           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
537           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
538           (tokeninfoclass == TokenSource) ? "TokenSource" :
539           (tokeninfoclass == TokenType) ? "TokenType" :
540           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
541           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
542           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
543           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
544           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
545           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
546           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
547           "Unknown",
548           tokeninfo, tokeninfolength);
549
550     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
551 }
552
553 /*************************************************************************
554  * SetThreadToken [ADVAPI32.@]
555  *
556  * Assigns an 'impersonation token' to a thread so it can assume the
557  * security privileges of another thread or process.  Can also remove
558  * a previously assigned token. 
559  *
560  * PARAMS
561  *   thread          [O] Handle to thread to set the token for
562  *   token           [I] Token to set
563  *
564  * RETURNS
565  *  Success: TRUE. The threads access token is set to token
566  *  Failure: FALSE.
567  *
568  * NOTES
569  *  Only supported on NT or higher. On Win9X this function does nothing.
570  *  See SetTokenInformation.
571  */
572 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
573 {
574     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
575                                                  ThreadImpersonationToken, &token, sizeof token ));
576 }
577
578 /*      ##############################
579         ######  SID FUNCTIONS   ######
580         ##############################
581 */
582
583 /******************************************************************************
584  * AllocateAndInitializeSid [ADVAPI32.@]
585  *
586  * PARAMS
587  *   pIdentifierAuthority []
588  *   nSubAuthorityCount   []
589  *   nSubAuthority0       []
590  *   nSubAuthority1       []
591  *   nSubAuthority2       []
592  *   nSubAuthority3       []
593  *   nSubAuthority4       []
594  *   nSubAuthority5       []
595  *   nSubAuthority6       []
596  *   nSubAuthority7       []
597  *   pSid                 []
598  */
599 BOOL WINAPI
600 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
601                           BYTE nSubAuthorityCount,
602                           DWORD nSubAuthority0, DWORD nSubAuthority1,
603                           DWORD nSubAuthority2, DWORD nSubAuthority3,
604                           DWORD nSubAuthority4, DWORD nSubAuthority5,
605                           DWORD nSubAuthority6, DWORD nSubAuthority7,
606                           PSID *pSid )
607 {
608     return set_ntstatus( RtlAllocateAndInitializeSid(
609                              pIdentifierAuthority, nSubAuthorityCount,
610                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
611                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
612                              pSid ));
613 }
614
615 /******************************************************************************
616  * FreeSid [ADVAPI32.@]
617  *
618  * PARAMS
619  *   pSid []
620  */
621 PVOID WINAPI
622 FreeSid( PSID pSid )
623 {
624         RtlFreeSid(pSid);
625         return NULL; /* is documented like this */
626 }
627
628 /******************************************************************************
629  * CopySid [ADVAPI32.@]
630  *
631  * PARAMS
632  *   nDestinationSidLength []
633  *   pDestinationSid       []
634  *   pSourceSid            []
635  */
636 BOOL WINAPI
637 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
638 {
639         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
640 }
641
642 /******************************************************************************
643  * CreateWellKnownSid [ADVAPI32.@]
644  */
645 BOOL WINAPI
646 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
647                     PSID DomainSid,
648                     PSID pSid,
649                     DWORD* cbSid)
650 {
651     int i;
652     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
653
654     if (DomainSid != NULL) {
655         FIXME("Only local computer supported!\n");
656         SetLastError(ERROR_INVALID_PARAMETER);  /* FIXME */
657         return FALSE;
658     }
659
660     if (cbSid == NULL || pSid == NULL) {
661         SetLastError(ERROR_INVALID_PARAMETER);
662         return FALSE;
663     }
664
665     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
666         if (WellKnownSids[i].Type == WellKnownSidType) {
667             DWORD length = GetSidLengthRequired(WellKnownSids[i].SubAuthorityCount);
668
669             if (*cbSid < length) {
670                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
671                 return FALSE;
672             }
673
674             CopyMemory(pSid, &WellKnownSids[i].Revision, length);
675             *cbSid = length;
676             return TRUE;
677         }
678     }
679
680     SetLastError(ERROR_INVALID_PARAMETER);
681     return FALSE;
682 }
683
684 /******************************************************************************
685  * IsWellKnownSid [ADVAPI32.@]
686  */
687 BOOL WINAPI
688 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
689 {
690     int i;
691     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
692
693     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
694         if (WellKnownSids[i].Type == WellKnownSidType)
695             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Revision)))
696                 return TRUE;
697
698     return FALSE;
699 }
700
701 BOOL WINAPI
702 IsTokenRestricted( HANDLE TokenHandle )
703 {
704     TOKEN_GROUPS *groups;
705     DWORD size;
706     NTSTATUS status;
707     BOOL restricted;
708
709     TRACE("(%p)\n", TokenHandle);
710  
711     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
712     if (status != STATUS_BUFFER_TOO_SMALL)
713         return FALSE;
714  
715     groups = HeapAlloc(GetProcessHeap(), 0, size);
716     if (!groups)
717     {
718         SetLastError(ERROR_OUTOFMEMORY);
719         return FALSE;
720     }
721  
722     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
723     if (status != STATUS_SUCCESS)
724     {
725         HeapFree(GetProcessHeap(), 0, groups);
726         return set_ntstatus(status);
727     }
728  
729     if (groups->GroupCount)
730         restricted = TRUE;
731     else
732         restricted = FALSE;
733      
734     HeapFree(GetProcessHeap(), 0, groups);
735  
736     return restricted;
737 }
738
739 /******************************************************************************
740  * IsValidSid [ADVAPI32.@]
741  *
742  * PARAMS
743  *   pSid []
744  */
745 BOOL WINAPI
746 IsValidSid( PSID pSid )
747 {
748         return RtlValidSid( pSid );
749 }
750
751 /******************************************************************************
752  * EqualSid [ADVAPI32.@]
753  *
754  * PARAMS
755  *   pSid1 []
756  *   pSid2 []
757  */
758 BOOL WINAPI
759 EqualSid( PSID pSid1, PSID pSid2 )
760 {
761         return RtlEqualSid( pSid1, pSid2 );
762 }
763
764 /******************************************************************************
765  * EqualPrefixSid [ADVAPI32.@]
766  */
767 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
768 {
769         return RtlEqualPrefixSid(pSid1, pSid2);
770 }
771
772 /******************************************************************************
773  * GetSidLengthRequired [ADVAPI32.@]
774  *
775  * PARAMS
776  *   nSubAuthorityCount []
777  */
778 DWORD WINAPI
779 GetSidLengthRequired( BYTE nSubAuthorityCount )
780 {
781         return RtlLengthRequiredSid(nSubAuthorityCount);
782 }
783
784 /******************************************************************************
785  * InitializeSid [ADVAPI32.@]
786  *
787  * PARAMS
788  *   pIdentifierAuthority []
789  */
790 BOOL WINAPI
791 InitializeSid (
792         PSID pSid,
793         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
794         BYTE nSubAuthorityCount)
795 {
796         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
797 }
798
799 DWORD WINAPI
800 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
801 {
802     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
803
804     return 1;
805 }
806
807 DWORD WINAPI
808 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
809 {
810     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
811
812     return 1;
813 }
814
815 /******************************************************************************
816  * GetSidIdentifierAuthority [ADVAPI32.@]
817  *
818  * PARAMS
819  *   pSid []
820  */
821 PSID_IDENTIFIER_AUTHORITY WINAPI
822 GetSidIdentifierAuthority( PSID pSid )
823 {
824         return RtlIdentifierAuthoritySid(pSid);
825 }
826
827 /******************************************************************************
828  * GetSidSubAuthority [ADVAPI32.@]
829  *
830  * PARAMS
831  *   pSid          []
832  *   nSubAuthority []
833  */
834 PDWORD WINAPI
835 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
836 {
837         return RtlSubAuthoritySid(pSid, nSubAuthority);
838 }
839
840 /******************************************************************************
841  * GetSidSubAuthorityCount [ADVAPI32.@]
842  *
843  * PARAMS
844  *   pSid []
845  */
846 PUCHAR WINAPI
847 GetSidSubAuthorityCount (PSID pSid)
848 {
849         return RtlSubAuthorityCountSid(pSid);
850 }
851
852 /******************************************************************************
853  * GetLengthSid [ADVAPI32.@]
854  *
855  * PARAMS
856  *   pSid []
857  */
858 DWORD WINAPI
859 GetLengthSid (PSID pSid)
860 {
861         return RtlLengthSid(pSid);
862 }
863
864 /*      ##############################################
865         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
866         ##############################################
867 */
868
869  /****************************************************************************** 
870  * BuildSecurityDescriptorA [ADVAPI32.@]
871  *
872  * Builds a SD from 
873  *
874  * PARAMS
875  *  pOwner                [I]
876  *  pGroup                [I]
877  *  cCountOfAccessEntries [I]
878  *  pListOfAccessEntries  [I]
879  *  cCountOfAuditEntries  [I]
880  *  pListofAuditEntries   [I]
881  *  pOldSD                [I]
882  *  lpdwBufferLength      [I/O]
883  *  pNewSD                [O]
884  *
885  * RETURNS
886  *  Success: ERROR_SUCCESS
887  *  Failure: nonzero error code from Winerror.h
888  */
889 DWORD WINAPI BuildSecurityDescriptorA(
890     IN PTRUSTEEA pOwner,
891     IN PTRUSTEEA pGroup,
892     IN ULONG cCountOfAccessEntries,
893     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
894     IN ULONG cCountOfAuditEntries,
895     IN PEXPLICIT_ACCESSA pListofAuditEntries,
896     IN PSECURITY_DESCRIPTOR pOldSD,
897     IN OUT PULONG lpdwBufferLength,
898     OUT PSECURITY_DESCRIPTOR* pNewSD)
899
900     FIXME("(%p,%p,%ld,%p,%ld,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
901           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
902           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
903  
904     return ERROR_CALL_NOT_IMPLEMENTED;
905
906  
907 /******************************************************************************
908  * BuildSecurityDescriptorW [ADVAPI32.@]
909  *
910  * See BuildSecurityDescriptorA.
911  */
912 DWORD WINAPI BuildSecurityDescriptorW(
913     IN PTRUSTEEW pOwner,
914     IN PTRUSTEEW pGroup,
915     IN ULONG cCountOfAccessEntries,
916     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
917     IN ULONG cCountOfAuditEntries,
918     IN PEXPLICIT_ACCESSW pListofAuditEntries,
919     IN PSECURITY_DESCRIPTOR pOldSD,
920     IN OUT PULONG lpdwBufferLength,
921     OUT PSECURITY_DESCRIPTOR* pNewSD)
922
923     FIXME("(%p,%p,%ld,%p,%ld,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
924           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
925           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
926  
927     return ERROR_CALL_NOT_IMPLEMENTED;
928
929
930 /******************************************************************************
931  * InitializeSecurityDescriptor [ADVAPI32.@]
932  *
933  * PARAMS
934  *   pDescr   []
935  *   revision []
936  */
937 BOOL WINAPI
938 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
939 {
940         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
941 }
942
943
944 /******************************************************************************
945  * MakeAbsoluteSD [ADVAPI32.@]
946  */
947 BOOL WINAPI MakeAbsoluteSD (
948         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
949         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
950         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
951         OUT PACL pDacl,
952         OUT LPDWORD lpdwDaclSize,
953         OUT PACL pSacl,
954         OUT LPDWORD lpdwSaclSize,
955         OUT PSID pOwner,
956         OUT LPDWORD lpdwOwnerSize,
957         OUT PSID pPrimaryGroup,
958         OUT LPDWORD lpdwPrimaryGroupSize)
959 {
960     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
961                                                      pAbsoluteSecurityDescriptor,
962                                                      lpdwAbsoluteSecurityDescriptorSize,
963                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
964                                                      pOwner, lpdwOwnerSize,
965                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
966 }
967
968 /******************************************************************************
969  * GetKernelObjectSecurity [ADVAPI32.@]
970  */
971 BOOL WINAPI GetKernelObjectSecurity(
972         HANDLE Handle,
973         SECURITY_INFORMATION RequestedInformation,
974         PSECURITY_DESCRIPTOR pSecurityDescriptor,
975         DWORD nLength,
976         LPDWORD lpnLengthNeeded )
977 {
978     TRACE("(%p,0x%08lx,%p,0x%08lx,%p)\n", Handle, RequestedInformation,
979           pSecurityDescriptor, nLength, lpnLengthNeeded);
980
981     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
982                                                nLength, lpnLengthNeeded ));
983 }
984
985 /******************************************************************************
986  * GetPrivateObjectSecurity [ADVAPI32.@]
987  */
988 BOOL WINAPI GetPrivateObjectSecurity(
989         PSECURITY_DESCRIPTOR ObjectDescriptor,
990         SECURITY_INFORMATION SecurityInformation,
991         PSECURITY_DESCRIPTOR ResultantDescriptor,
992         DWORD DescriptorLength,
993         PDWORD ReturnLength )
994 {
995     TRACE("(%p,0x%08lx,%p,0x%08lx,%p)\n", ObjectDescriptor, SecurityInformation,
996           ResultantDescriptor, DescriptorLength, ReturnLength);
997
998     return set_ntstatus( NtQuerySecurityObject(ObjectDescriptor, SecurityInformation,
999                                                ResultantDescriptor, DescriptorLength, ReturnLength ));
1000 }
1001
1002 /******************************************************************************
1003  * GetSecurityDescriptorLength [ADVAPI32.@]
1004  */
1005 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1006 {
1007         return RtlLengthSecurityDescriptor(pDescr);
1008 }
1009
1010 /******************************************************************************
1011  * GetSecurityDescriptorOwner [ADVAPI32.@]
1012  *
1013  * PARAMS
1014  *   pOwner            []
1015  *   lpbOwnerDefaulted []
1016  */
1017 BOOL WINAPI
1018 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1019                             LPBOOL lpbOwnerDefaulted )
1020 {
1021     BOOLEAN defaulted;
1022     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1023     *lpbOwnerDefaulted = defaulted;
1024     return ret;
1025 }
1026
1027 /******************************************************************************
1028  * SetSecurityDescriptorOwner [ADVAPI32.@]
1029  *
1030  * PARAMS
1031  */
1032 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1033                                    PSID pOwner, BOOL bOwnerDefaulted)
1034 {
1035     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1036 }
1037 /******************************************************************************
1038  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1039  */
1040 BOOL WINAPI GetSecurityDescriptorGroup(
1041         PSECURITY_DESCRIPTOR SecurityDescriptor,
1042         PSID *Group,
1043         LPBOOL GroupDefaulted)
1044 {
1045     BOOLEAN defaulted;
1046     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1047     *GroupDefaulted = defaulted;
1048     return ret;
1049 }
1050 /******************************************************************************
1051  * SetSecurityDescriptorGroup [ADVAPI32.@]
1052  */
1053 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1054                                            PSID Group, BOOL GroupDefaulted)
1055 {
1056     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1057 }
1058
1059 /******************************************************************************
1060  * IsValidSecurityDescriptor [ADVAPI32.@]
1061  *
1062  * PARAMS
1063  *   lpsecdesc []
1064  */
1065 BOOL WINAPI
1066 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1067 {
1068     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1069 }
1070
1071 /******************************************************************************
1072  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1073  */
1074 BOOL WINAPI GetSecurityDescriptorDacl(
1075         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1076         OUT LPBOOL lpbDaclPresent,
1077         OUT PACL *pDacl,
1078         OUT LPBOOL lpbDaclDefaulted)
1079 {
1080     BOOLEAN present, defaulted;
1081     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1082     *lpbDaclPresent = present;
1083     *lpbDaclDefaulted = defaulted;
1084     return ret;
1085 }
1086
1087 /******************************************************************************
1088  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1089  */
1090 BOOL WINAPI
1091 SetSecurityDescriptorDacl (
1092         PSECURITY_DESCRIPTOR lpsd,
1093         BOOL daclpresent,
1094         PACL dacl,
1095         BOOL dacldefaulted )
1096 {
1097     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1098 }
1099 /******************************************************************************
1100  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1101  */
1102 BOOL WINAPI GetSecurityDescriptorSacl(
1103         IN PSECURITY_DESCRIPTOR lpsd,
1104         OUT LPBOOL lpbSaclPresent,
1105         OUT PACL *pSacl,
1106         OUT LPBOOL lpbSaclDefaulted)
1107 {
1108     BOOLEAN present, defaulted;
1109     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1110     *lpbSaclPresent = present;
1111     *lpbSaclDefaulted = defaulted;
1112     return ret;
1113 }
1114
1115 /**************************************************************************
1116  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1117  */
1118 BOOL WINAPI SetSecurityDescriptorSacl (
1119         PSECURITY_DESCRIPTOR lpsd,
1120         BOOL saclpresent,
1121         PACL lpsacl,
1122         BOOL sacldefaulted)
1123 {
1124     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1125 }
1126 /******************************************************************************
1127  * MakeSelfRelativeSD [ADVAPI32.@]
1128  *
1129  * PARAMS
1130  *   lpabssecdesc  []
1131  *   lpselfsecdesc []
1132  *   lpbuflen      []
1133  */
1134 BOOL WINAPI
1135 MakeSelfRelativeSD(
1136         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1137         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1138         IN OUT LPDWORD lpdwBufferLength)
1139 {
1140     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1141                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1142 }
1143
1144 /******************************************************************************
1145  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1146  */
1147
1148 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1149                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1150 {
1151     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1152 }
1153
1154 /*      ##############################
1155         ######  ACL FUNCTIONS   ######
1156         ##############################
1157 */
1158
1159 /*************************************************************************
1160  * InitializeAcl [ADVAPI32.@]
1161  */
1162 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1163 {
1164     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1165 }
1166
1167 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1168 {
1169     TRACE("(%p)\n", hNamedPipe);
1170
1171     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL, NULL,
1172                          FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1173 }
1174
1175 /******************************************************************************
1176  *  AddAccessAllowedAce [ADVAPI32.@]
1177  */
1178 BOOL WINAPI AddAccessAllowedAce(
1179         IN OUT PACL pAcl,
1180         IN DWORD dwAceRevision,
1181         IN DWORD AccessMask,
1182         IN PSID pSid)
1183 {
1184     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1185 }
1186
1187 /******************************************************************************
1188  *  AddAccessAllowedAceEx [ADVAPI32.@]
1189  */
1190 BOOL WINAPI AddAccessAllowedAceEx(
1191         IN OUT PACL pAcl,
1192         IN DWORD dwAceRevision,
1193         IN DWORD AceFlags,
1194         IN DWORD AccessMask,
1195         IN PSID pSid)
1196 {
1197     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1198 }
1199
1200 /******************************************************************************
1201  *  AddAccessDeniedAce [ADVAPI32.@]
1202  */
1203 BOOL WINAPI AddAccessDeniedAce(
1204         IN OUT PACL pAcl,
1205         IN DWORD dwAceRevision,
1206         IN DWORD AccessMask,
1207         IN PSID pSid)
1208 {
1209     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1210 }
1211
1212 /******************************************************************************
1213  *  AddAccessDeniedAceEx [ADVAPI32.@]
1214  */
1215 BOOL WINAPI AddAccessDeniedAceEx(
1216         IN OUT PACL pAcl,
1217         IN DWORD dwAceRevision,
1218         IN DWORD AceFlags,
1219         IN DWORD AccessMask,
1220         IN PSID pSid)
1221 {
1222     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1223 }
1224
1225 /******************************************************************************
1226  *  AddAce [ADVAPI32.@]
1227  */
1228 BOOL WINAPI AddAce(
1229         IN OUT PACL pAcl,
1230         IN DWORD dwAceRevision,
1231         IN DWORD dwStartingAceIndex,
1232         LPVOID pAceList,
1233         DWORD nAceListLength)
1234 {
1235     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1236 }
1237
1238 /******************************************************************************
1239  * DeleteAce [ADVAPI32.@]
1240  */
1241 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1242 {
1243     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1244 }
1245
1246 /******************************************************************************
1247  *  FindFirstFreeAce [ADVAPI32.@]
1248  */
1249 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1250 {
1251         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1252 }
1253
1254 /******************************************************************************
1255  * GetAce [ADVAPI32.@]
1256  */
1257 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1258 {
1259     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1260 }
1261
1262 /******************************************************************************
1263  * GetAclInformation [ADVAPI32.@]
1264  */
1265 BOOL WINAPI GetAclInformation(
1266   PACL pAcl,
1267   LPVOID pAclInformation,
1268   DWORD nAclInformationLength,
1269   ACL_INFORMATION_CLASS dwAclInformationClass)
1270 {
1271     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1272                                                nAclInformationLength, dwAclInformationClass));
1273 }
1274
1275 /******************************************************************************
1276  *  IsValidAcl [ADVAPI32.@]
1277  */
1278 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1279 {
1280         return RtlValidAcl(pAcl);
1281 }
1282
1283 /*      ##############################
1284         ######  MISC FUNCTIONS  ######
1285         ##############################
1286 */
1287
1288 /******************************************************************************
1289  * AllocateLocallyUniqueId [ADVAPI32.@]
1290  *
1291  * PARAMS
1292  *   lpLuid []
1293  */
1294 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1295 {
1296     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1297 }
1298
1299 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1300  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1301 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1302  { '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 };
1303 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1304  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1305 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1306  { '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 };
1307 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1308  { '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 };
1309 static const WCHAR SE_TCB_NAME_W[] =
1310  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1311 static const WCHAR SE_SECURITY_NAME_W[] =
1312  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1313 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1314  { '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 };
1315 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1316  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1317 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1318  { '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 };
1319 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1320  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1321 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1322  { '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 };
1323 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1324  { '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 };
1325 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1326  { '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 };
1327 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1328  { '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 };
1329 static const WCHAR SE_BACKUP_NAME_W[] =
1330  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1331 static const WCHAR SE_RESTORE_NAME_W[] =
1332  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1333 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1334  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1335 static const WCHAR SE_DEBUG_NAME_W[] =
1336  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1337 static const WCHAR SE_AUDIT_NAME_W[] =
1338  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1339 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1340  { '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 };
1341 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1342  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1343 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1344  { '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 };
1345 static const WCHAR SE_UNDOCK_NAME_W[] =
1346  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1347 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1348  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1349 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1350  { '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 };
1351 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1352  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1353 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1354  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1355 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1356  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1357
1358 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1359 {
1360     NULL,
1361     NULL,
1362     SE_CREATE_TOKEN_NAME_W,
1363     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1364     SE_LOCK_MEMORY_NAME_W,
1365     SE_INCREASE_QUOTA_NAME_W,
1366     SE_MACHINE_ACCOUNT_NAME_W,
1367     SE_TCB_NAME_W,
1368     SE_SECURITY_NAME_W,
1369     SE_TAKE_OWNERSHIP_NAME_W,
1370     SE_LOAD_DRIVER_NAME_W,
1371     SE_SYSTEM_PROFILE_NAME_W,
1372     SE_SYSTEMTIME_NAME_W,
1373     SE_PROF_SINGLE_PROCESS_NAME_W,
1374     SE_INC_BASE_PRIORITY_NAME_W,
1375     SE_CREATE_PAGEFILE_NAME_W,
1376     SE_CREATE_PERMANENT_NAME_W,
1377     SE_BACKUP_NAME_W,
1378     SE_RESTORE_NAME_W,
1379     SE_SHUTDOWN_NAME_W,
1380     SE_DEBUG_NAME_W,
1381     SE_AUDIT_NAME_W,
1382     SE_SYSTEM_ENVIRONMENT_NAME_W,
1383     SE_CHANGE_NOTIFY_NAME_W,
1384     SE_REMOTE_SHUTDOWN_NAME_W,
1385     SE_UNDOCK_NAME_W,
1386     SE_SYNC_AGENT_NAME_W,
1387     SE_ENABLE_DELEGATION_NAME_W,
1388     SE_MANAGE_VOLUME_NAME_W,
1389     SE_IMPERSONATE_NAME_W,
1390     SE_CREATE_GLOBAL_NAME_W,
1391 };
1392
1393 /******************************************************************************
1394  * LookupPrivilegeValueW                        [ADVAPI32.@]
1395  *
1396  * See LookupPrivilegeValueA.
1397  */
1398 BOOL WINAPI
1399 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1400 {
1401     UINT i;
1402
1403     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1404
1405     if (!ADVAPI_IsLocalComputer(lpSystemName))
1406     {
1407         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1408         return FALSE;
1409     }
1410     if (!lpName)
1411     {
1412         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1413         return FALSE;
1414     }
1415     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1416     {
1417         if( !WellKnownPrivNames[i] )
1418             continue;
1419         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1420             continue;
1421         lpLuid->LowPart = i;
1422         lpLuid->HighPart = 0;
1423         TRACE( "%s -> %08lx-%08lx\n",debugstr_w( lpSystemName ),
1424                lpLuid->HighPart, lpLuid->LowPart );
1425         return TRUE;
1426     }
1427     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1428     return FALSE;
1429 }
1430
1431 /******************************************************************************
1432  * LookupPrivilegeValueA                        [ADVAPI32.@]
1433  *
1434  * Retrieves LUID used on a system to represent the privilege name.
1435  *
1436  * PARAMS
1437  *  lpSystemName [I] Name of the system
1438  *  lpName       [I] Name of the privilege
1439  *  lpLuid       [O] Destination for the resulting LUID
1440  *
1441  * RETURNS
1442  *  Success: TRUE. lpLuid contains the requested LUID.
1443  *  Failure: FALSE.
1444  */
1445 BOOL WINAPI
1446 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1447 {
1448     UNICODE_STRING lpSystemNameW;
1449     UNICODE_STRING lpNameW;
1450     BOOL ret;
1451
1452     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1453     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1454     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1455     RtlFreeUnicodeString(&lpNameW);
1456     RtlFreeUnicodeString(&lpSystemNameW);
1457     return ret;
1458 }
1459
1460 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1461                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1462 {
1463     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1464           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1465
1466     return FALSE;
1467 }
1468
1469 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1470                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1471 {
1472     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1473           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1474
1475     return FALSE;
1476 }
1477
1478 /******************************************************************************
1479  * LookupPrivilegeNameA                 [ADVAPI32.@]
1480  *
1481  * See LookupPrivilegeNameW.
1482  */
1483 BOOL WINAPI
1484 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1485  LPDWORD cchName)
1486 {
1487     UNICODE_STRING lpSystemNameW;
1488     BOOL ret;
1489     DWORD wLen = 0;
1490
1491     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1492
1493     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1494     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1495     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1496     {
1497         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1498
1499         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1500          &wLen);
1501         if (ret)
1502         {
1503             /* Windows crashes if cchName is NULL, so will I */
1504             int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1505              *cchName, NULL, NULL);
1506
1507             if (len == 0)
1508             {
1509                 /* WideCharToMultiByte failed */
1510                 ret = FALSE;
1511             }
1512             else if (len > *cchName)
1513             {
1514                 *cchName = len;
1515                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1516                 ret = FALSE;
1517             }
1518             else
1519             {
1520                 /* WideCharToMultiByte succeeded, output length needs to be
1521                  * length not including NULL terminator
1522                  */
1523                 *cchName = len - 1;
1524             }
1525         }
1526         HeapFree(GetProcessHeap(), 0, lpNameW);
1527     }
1528     RtlFreeUnicodeString(&lpSystemNameW);
1529     return ret;
1530 }
1531
1532 /******************************************************************************
1533  * LookupPrivilegeNameW                 [ADVAPI32.@]
1534  *
1535  * Retrieves the privilege name referred to by the LUID lpLuid.
1536  *
1537  * PARAMS
1538  *  lpSystemName [I]   Name of the system
1539  *  lpLuid       [I]   Privilege value
1540  *  lpName       [O]   Name of the privilege
1541  *  cchName      [I/O] Number of characters in lpName.
1542  *
1543  * RETURNS
1544  *  Success: TRUE. lpName contains the name of the privilege whose value is
1545  *  *lpLuid.
1546  *  Failure: FALSE.
1547  *
1548  * REMARKS
1549  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1550  *  using this function.
1551  *  If the length of lpName is too small, on return *cchName will contain the
1552  *  number of WCHARs needed to contain the privilege, including the NULL
1553  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1554  *  On success, *cchName will contain the number of characters stored in
1555  *  lpName, NOT including the NULL terminator.
1556  */
1557 BOOL WINAPI
1558 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1559  LPDWORD cchName)
1560 {
1561     size_t privNameLen;
1562
1563     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1564
1565     if (!ADVAPI_IsLocalComputer(lpSystemName))
1566     {
1567         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1568         return FALSE;
1569     }
1570     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1571      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1572     {
1573         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1574         return FALSE;
1575     }
1576     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1577     /* Windows crashes if cchName is NULL, so will I */
1578     if (*cchName <= privNameLen)
1579     {
1580         *cchName = privNameLen + 1;
1581         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1582         return FALSE;
1583     }
1584     else
1585     {
1586         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1587         *cchName = privNameLen;
1588         return TRUE;
1589     }
1590 }
1591
1592 /******************************************************************************
1593  * GetFileSecurityA [ADVAPI32.@]
1594  *
1595  * Obtains Specified information about the security of a file or directory.
1596  *
1597  * PARAMS
1598  *  lpFileName           [I] Name of the file to get info for
1599  *  RequestedInformation [I] SE_ flags from "winnt.h"
1600  *  pSecurityDescriptor  [O] Destination for security information
1601  *  nLength              [I] Length of pSecurityDescriptor
1602  *  lpnLengthNeeded      [O] Destination for length of returned security information
1603  *
1604  * RETURNS
1605  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1606  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1607  *
1608  * NOTES
1609  *  The information returned is constrained by the callers access rights and
1610  *  privileges.
1611  */
1612 BOOL WINAPI
1613 GetFileSecurityA( LPCSTR lpFileName,
1614                     SECURITY_INFORMATION RequestedInformation,
1615                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1616                     DWORD nLength, LPDWORD lpnLengthNeeded )
1617 {
1618     DWORD len;
1619     BOOL r;
1620     LPWSTR name = NULL;
1621
1622     if( lpFileName )
1623     {
1624         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1625         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1626         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1627     }
1628
1629     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1630                           nLength, lpnLengthNeeded );
1631     HeapFree( GetProcessHeap(), 0, name );
1632
1633     return r;
1634 }
1635
1636 /******************************************************************************
1637  * GetFileSecurityW [ADVAPI32.@]
1638  *
1639  * See GetFileSecurityA.
1640  */
1641 BOOL WINAPI
1642 GetFileSecurityW( LPCWSTR lpFileName,
1643                     SECURITY_INFORMATION RequestedInformation,
1644                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1645                     DWORD nLength, LPDWORD lpnLengthNeeded )
1646 {
1647     DWORD               nNeeded;
1648     LPBYTE      pBuffer;
1649     DWORD               iLocNow;
1650     SECURITY_DESCRIPTOR_RELATIVE *pSDRelative;
1651
1652     if(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(lpFileName))
1653         return FALSE;
1654
1655     FIXME("(%s) : returns fake SECURITY_DESCRIPTOR\n", debugstr_w(lpFileName) );
1656
1657     nNeeded = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1658     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1659         nNeeded += sizeof(sidWorld);
1660     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1661         nNeeded += sizeof(sidWorld);
1662     if (RequestedInformation & DACL_SECURITY_INFORMATION)
1663         nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1664     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1665         nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1666
1667     *lpnLengthNeeded = nNeeded;
1668
1669     if (nNeeded > nLength)
1670             return TRUE;
1671
1672     if (!InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
1673         return FALSE;
1674
1675     pSDRelative = (PISECURITY_DESCRIPTOR_RELATIVE) pSecurityDescriptor;
1676     pSDRelative->Control |= SE_SELF_RELATIVE;
1677     pBuffer = (LPBYTE) pSDRelative;
1678     iLocNow = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1679
1680     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1681     {
1682         memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1683         pSDRelative->Owner = iLocNow;
1684         iLocNow += sizeof(sidWorld);
1685     }
1686     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1687     {
1688         memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1689         pSDRelative->Group = iLocNow;
1690         iLocNow += sizeof(sidWorld);
1691     }
1692     if (RequestedInformation & DACL_SECURITY_INFORMATION)
1693     {
1694         GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1695         pSDRelative->Dacl = iLocNow;
1696         iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1697     }
1698     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1699     {
1700         GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1701         pSDRelative->Sacl = iLocNow;
1702         /* iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL; */
1703     }
1704     return TRUE;
1705 }
1706
1707
1708 /******************************************************************************
1709  * LookupAccountSidA [ADVAPI32.@]
1710  */
1711 BOOL WINAPI
1712 LookupAccountSidA(
1713         IN LPCSTR system,
1714         IN PSID sid,
1715         OUT LPSTR account,
1716         IN OUT LPDWORD accountSize,
1717         OUT LPSTR domain,
1718         IN OUT LPDWORD domainSize,
1719         OUT PSID_NAME_USE name_use )
1720 {
1721     DWORD len;
1722     BOOL r;
1723     LPWSTR systemW = NULL;
1724     LPWSTR accountW = NULL;
1725     LPWSTR domainW = NULL;
1726     DWORD accountSizeW = *accountSize * sizeof(WCHAR);
1727     DWORD domainSizeW = *domainSize * sizeof(WCHAR);
1728
1729     TRACE("(%s,sid=%s,%p,%p(%lu),%p,%p(%lu),%p)\n",
1730           debugstr_a(system),debugstr_sid(sid),
1731           account,accountSize,accountSize?*accountSize:0,
1732           domain,domainSize,domainSize?*domainSize:0,
1733           name_use);
1734
1735     if (system) {
1736         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1737         systemW = HeapAlloc( GetProcessHeap(), 0, (len+1)*sizeof(WCHAR) );
1738         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1739     }
1740     accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW );
1741     domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW );
1742
1743     r = LookupAccountSidW(systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1744
1745     if (r) {
1746         len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1747         WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1748         *accountSize = len;
1749
1750         len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1751         WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1752         *domainSize = len;
1753     }
1754
1755     HeapFree( GetProcessHeap(), 0, systemW );
1756     HeapFree( GetProcessHeap(), 0, accountW );
1757     HeapFree( GetProcessHeap(), 0, domainW );
1758
1759     return r;
1760 }
1761
1762 /******************************************************************************
1763  * LookupAccountSidW [ADVAPI32.@]
1764  *
1765  * PARAMS
1766  *   system      []
1767  *   sid         []
1768  *   account     []
1769  *   accountSize []
1770  *   domain      []
1771  *   domainSize  []
1772  *   name_use    []
1773  */
1774
1775 BOOL WINAPI
1776 LookupAccountSidW(
1777         IN LPCWSTR system,
1778         IN PSID sid,
1779         OUT LPWSTR account,
1780         IN OUT LPDWORD accountSize,
1781         OUT LPWSTR domain,
1782         IN OUT LPDWORD domainSize,
1783         OUT PSID_NAME_USE name_use )
1784 {
1785     int i, j;
1786     const WCHAR * ac = Administrator;   /* FIXME */
1787     const WCHAR * dm = DOMAIN;          /* FIXME */
1788     SID_NAME_USE use = SidTypeUser;     /* FIXME */
1789
1790     TRACE("(%s,sid=%s,%p,%p(%lu),%p,%p(%lu),%p)\n",
1791           debugstr_w(system),debugstr_sid(sid),
1792           account,accountSize,accountSize?*accountSize:0,
1793           domain,domainSize,domainSize?*domainSize:0,
1794           name_use);
1795
1796     if (!ADVAPI_IsLocalComputer(system)) {
1797         FIXME("Only local computer supported!\n");
1798         SetLastError(ERROR_NONE_MAPPED);
1799         return FALSE;
1800     }
1801     
1802     for (i = 0; i <= 60; i++) {
1803         if (IsWellKnownSid(sid, i)) {
1804             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
1805                 if (ACCOUNT_SIDS[j].type == i) {
1806                     ac = ACCOUNT_SIDS[j].account;
1807                     dm = ACCOUNT_SIDS[j].domain;
1808                     use = ACCOUNT_SIDS[j].name_use;
1809                 }
1810             }
1811             break;
1812         }
1813     }
1814
1815     *accountSize = strlenW(ac)+1;
1816     if (account && (*accountSize > strlenW(ac)))
1817         strcpyW(account, ac);
1818
1819     *domainSize = strlenW(dm)+1;
1820     if (domain && (*domainSize > strlenW(dm)))
1821         strcpyW(domain,dm);
1822
1823     *name_use = use;
1824     return TRUE;
1825 }
1826
1827 /******************************************************************************
1828  * SetFileSecurityA [ADVAPI32.@]
1829  *
1830  * See SetFileSecurityW.
1831  */
1832 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1833                                 SECURITY_INFORMATION RequestedInformation,
1834                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1835 {
1836     DWORD len;
1837     BOOL r;
1838     LPWSTR name = NULL;
1839
1840     if( lpFileName )
1841     {
1842         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1843         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1844         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1845     }
1846
1847     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
1848     HeapFree( GetProcessHeap(), 0, name );
1849
1850     return r;
1851 }
1852
1853 /******************************************************************************
1854  * SetFileSecurityW [ADVAPI32.@]
1855  *
1856  * Sets the security of a file or directory.
1857  *
1858  * PARAMS
1859  *   lpFileName           []
1860  *   RequestedInformation []
1861  *   pSecurityDescriptor  []
1862  *
1863  * RETURNS
1864  *  Success: TRUE.
1865  *  Failure: FALSE.
1866  */
1867 BOOL WINAPI
1868 SetFileSecurityW( LPCWSTR lpFileName,
1869                     SECURITY_INFORMATION RequestedInformation,
1870                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
1871 {
1872   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
1873   return TRUE;
1874 }
1875
1876 /******************************************************************************
1877  * QueryWindows31FilesMigration [ADVAPI32.@]
1878  *
1879  * PARAMS
1880  *   x1 []
1881  */
1882 BOOL WINAPI
1883 QueryWindows31FilesMigration( DWORD x1 )
1884 {
1885         FIXME("(%ld):stub\n",x1);
1886         return TRUE;
1887 }
1888
1889 /******************************************************************************
1890  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1891  *
1892  * PARAMS
1893  *   x1 []
1894  *   x2 []
1895  *   x3 []
1896  *   x4 []
1897  */
1898 BOOL WINAPI
1899 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1900                                                DWORD x4 )
1901 {
1902         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
1903         return TRUE;
1904 }
1905
1906 /******************************************************************************
1907  * NotifyBootConfigStatus [ADVAPI32.@]
1908  *
1909  * PARAMS
1910  *   x1 []
1911  */
1912 BOOL WINAPI
1913 NotifyBootConfigStatus( BOOL x1 )
1914 {
1915         FIXME("(0x%08d):stub\n",x1);
1916         return 1;
1917 }
1918
1919 /******************************************************************************
1920  * RevertToSelf [ADVAPI32.@]
1921  *
1922  * Ends the impersonation of a user.
1923  *
1924  * PARAMS
1925  *   void []
1926  *
1927  * RETURNS
1928  *  Success: TRUE.
1929  *  Failure: FALSE.
1930  */
1931 BOOL WINAPI
1932 RevertToSelf( void )
1933 {
1934     HANDLE Token = NULL;
1935     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
1936         ThreadImpersonationToken, &Token, sizeof(Token) ) );
1937 }
1938
1939 /******************************************************************************
1940  * ImpersonateSelf [ADVAPI32.@]
1941  *
1942  * Makes an impersonation token that represents the process user and assigns
1943  * to the current thread.
1944  *
1945  * PARAMS
1946  *  ImpersonationLevel [I] Level at which to impersonate.
1947  *
1948  * RETURNS
1949  *  Success: TRUE.
1950  *  Failure: FALSE.
1951  */
1952 BOOL WINAPI
1953 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1954 {
1955     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
1956 }
1957
1958 /******************************************************************************
1959  * ImpersonateLoggedOnUser [ADVAPI32.@]
1960  */
1961 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
1962 {
1963     DWORD size;
1964     NTSTATUS Status;
1965     HANDLE ImpersonationToken;
1966     TOKEN_TYPE Type;
1967
1968     FIXME( "(%p)\n", hToken );
1969
1970     if (!GetTokenInformation( hToken, TokenType, &Type,
1971                               sizeof(TOKEN_TYPE), &size ))
1972         return FALSE;
1973
1974     if (Type == TokenPrimary)
1975     {
1976         OBJECT_ATTRIBUTES ObjectAttributes;
1977
1978         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
1979
1980         Status = NtDuplicateToken( hToken,
1981                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
1982                                    &ObjectAttributes,
1983                                    SecurityImpersonation,
1984                                    TokenImpersonation,
1985                                    &ImpersonationToken );
1986         if (Status != STATUS_SUCCESS)
1987         {
1988             ERR( "NtDuplicateToken failed with error 0x%08lx\n", Status );
1989             SetLastError( RtlNtStatusToDosError( Status ) );
1990             return FALSE;
1991         }
1992     }
1993     else
1994         ImpersonationToken = hToken;
1995
1996     Status = NtSetInformationThread( GetCurrentThread(),
1997                                      ThreadImpersonationToken,
1998                                      &ImpersonationToken,
1999                                      sizeof(ImpersonationToken) );
2000
2001     if (Type == TokenPrimary)
2002         NtClose( ImpersonationToken );
2003
2004     if (Status != STATUS_SUCCESS)
2005     {
2006         ERR( "NtSetInformationThread failed with error 0x%08lx\n", Status );
2007         SetLastError( RtlNtStatusToDosError( Status ) );
2008         return FALSE;
2009     }
2010
2011     return TRUE;
2012 }
2013
2014 /******************************************************************************
2015  * AccessCheck [ADVAPI32.@]
2016  */
2017 BOOL WINAPI
2018 AccessCheck(
2019         PSECURITY_DESCRIPTOR SecurityDescriptor,
2020         HANDLE ClientToken,
2021         DWORD DesiredAccess,
2022         PGENERIC_MAPPING GenericMapping,
2023         PPRIVILEGE_SET PrivilegeSet,
2024         LPDWORD PrivilegeSetLength,
2025         LPDWORD GrantedAccess,
2026         LPBOOL AccessStatus)
2027 {
2028     NTSTATUS access_status;
2029     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2030                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2031                                            GrantedAccess, &access_status) );
2032     if (ret) *AccessStatus = set_ntstatus( access_status );
2033     return ret;
2034 }
2035
2036
2037 /******************************************************************************
2038  * AccessCheckByType [ADVAPI32.@]
2039  */
2040 BOOL WINAPI AccessCheckByType(
2041     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2042     PSID PrincipalSelfSid,
2043     HANDLE ClientToken, 
2044     DWORD DesiredAccess, 
2045     POBJECT_TYPE_LIST ObjectTypeList,
2046     DWORD ObjectTypeListLength,
2047     PGENERIC_MAPPING GenericMapping,
2048     PPRIVILEGE_SET PrivilegeSet,
2049     LPDWORD PrivilegeSetLength, 
2050     LPDWORD GrantedAccess,
2051     LPBOOL AccessStatus)
2052 {
2053         FIXME("stub\n");
2054
2055         *AccessStatus = TRUE;
2056
2057         return !*AccessStatus;
2058 }
2059
2060 /******************************************************************************
2061  * MapGenericMask [ADVAPI32.@]
2062  *
2063  * Maps generic access rights into specific access rights according to the
2064  * supplied mapping.
2065  *
2066  * PARAMS
2067  *  AccessMask     [I/O] Access rights.
2068  *  GenericMapping [I] The mapping between generic and specific rights.
2069  *
2070  * RETURNS
2071  *  Nothing.
2072  */
2073 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2074 {
2075     RtlMapGenericMask( AccessMask, GenericMapping );
2076 }
2077
2078 /*************************************************************************
2079  * SetKernelObjectSecurity [ADVAPI32.@]
2080  */
2081 BOOL WINAPI SetKernelObjectSecurity (
2082         IN HANDLE Handle,
2083         IN SECURITY_INFORMATION SecurityInformation,
2084         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2085 {
2086     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2087 }
2088
2089
2090 /******************************************************************************
2091  *  AddAuditAccessAce [ADVAPI32.@]
2092  */
2093 BOOL WINAPI AddAuditAccessAce(
2094     IN OUT PACL pAcl, 
2095     IN DWORD dwAceRevision, 
2096     IN DWORD dwAccessMask, 
2097     IN PSID pSid, 
2098     IN BOOL bAuditSuccess, 
2099     IN BOOL bAuditFailure) 
2100 {
2101     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2102                                               bAuditSuccess, bAuditFailure) ); 
2103 }
2104
2105 /******************************************************************************
2106  * LookupAccountNameA [ADVAPI32.@]
2107  */
2108 BOOL WINAPI
2109 LookupAccountNameA(
2110         IN LPCSTR system,
2111         IN LPCSTR account,
2112         OUT PSID sid,
2113         OUT LPDWORD cbSid,
2114         LPSTR ReferencedDomainName,
2115         IN OUT LPDWORD cbReferencedDomainName,
2116         OUT PSID_NAME_USE name_use )
2117 {
2118     BOOL ret;
2119     UNICODE_STRING lpSystemW;
2120     UNICODE_STRING lpAccountW;
2121     LPWSTR lpReferencedDomainNameW = NULL;
2122
2123     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2124     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2125
2126     if (ReferencedDomainName)
2127         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2128
2129     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2130         cbReferencedDomainName, name_use);
2131
2132     if (ret && lpReferencedDomainNameW)
2133     {
2134         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2135             ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2136     }
2137
2138     RtlFreeUnicodeString(&lpSystemW);
2139     RtlFreeUnicodeString(&lpAccountW);
2140     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2141
2142     return ret;
2143 }
2144
2145 /******************************************************************************
2146  * LookupAccountNameW [ADVAPI32.@]
2147  */
2148 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2149                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2150                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2151 {
2152     /* Default implementation: Always return a default SID */
2153     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2154     BOOL ret;
2155     PSID pSid;
2156     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2157
2158     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2159           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2160
2161     ret = AllocateAndInitializeSid(&identifierAuthority,
2162         2,
2163         SECURITY_BUILTIN_DOMAIN_RID,
2164         DOMAIN_ALIAS_RID_ADMINS,
2165         0, 0, 0, 0, 0, 0,
2166         &pSid);
2167
2168     if (!ret)
2169        return FALSE;
2170
2171     if (!RtlValidSid(pSid))
2172     {
2173        FreeSid(pSid);
2174        return FALSE;
2175     }
2176
2177     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2178        CopySid(*cbSid, Sid, pSid);
2179     if (*cbSid < GetLengthSid(pSid))
2180     {
2181        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2182        ret = FALSE;
2183     }
2184     *cbSid = GetLengthSid(pSid);
2185     
2186     if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2187       strcpyW(ReferencedDomainName, dm);
2188
2189     if (*cchReferencedDomainName <= strlenW(dm))
2190     {
2191        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2192        ret = FALSE;
2193     }
2194
2195     *cchReferencedDomainName = strlenW(dm)+1;
2196
2197     FreeSid(pSid);
2198
2199     return ret;
2200 }
2201
2202 /******************************************************************************
2203  * PrivilegeCheck [ADVAPI32.@]
2204  */
2205 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2206 {
2207     BOOL ret;
2208     BOOLEAN Result;
2209
2210     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2211
2212     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2213     if (ret)
2214         *pfResult = Result;
2215     return ret;
2216 }
2217
2218 /******************************************************************************
2219  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2220  */
2221 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2222   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2223   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2224   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2225 {
2226         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2227                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2228                 SecurityDescriptor, DesiredAccess, GenericMapping,
2229                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2230         return TRUE;
2231 }
2232
2233 /******************************************************************************
2234  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2235  */
2236 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2237   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2238   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2239   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2240 {
2241         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2242                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2243                 SecurityDescriptor, DesiredAccess, GenericMapping,
2244                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2245         return TRUE;
2246 }
2247
2248 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2249 {
2250     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2251
2252     return TRUE;
2253 }
2254
2255 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2256 {
2257     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2258
2259     return TRUE;
2260 }
2261
2262 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2263 {
2264     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2265
2266     return TRUE;
2267 }
2268
2269 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2270   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2271   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2272   LPBOOL GenerateOnClose)
2273 {
2274         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2275                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2276         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2277         GenerateOnClose);
2278
2279     return TRUE;
2280 }
2281
2282 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2283   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2284   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2285   LPBOOL GenerateOnClose)
2286 {
2287     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2288         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2289         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2290         GenerateOnClose);
2291
2292     return TRUE;
2293 }
2294
2295 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2296   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2297 {
2298     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2299           DesiredAccess, Privileges, AccessGranted);
2300
2301     return TRUE;
2302 }
2303
2304 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2305   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2306 {
2307     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2308           DesiredAccess, Privileges, AccessGranted);
2309
2310     return TRUE;
2311 }
2312
2313 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2314                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2315 {
2316     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2317           ClientToken, Privileges, AccessGranted);
2318
2319     return TRUE;
2320 }
2321
2322 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2323                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2324 {
2325     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2326           ClientToken, Privileges, AccessGranted);
2327
2328     return TRUE;
2329 }
2330
2331 /******************************************************************************
2332  * GetSecurityInfo [ADVAPI32.@]
2333  */
2334 DWORD WINAPI GetSecurityInfo(
2335     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2336     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2337     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2338     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2339 )
2340 {
2341   FIXME("stub!\n");
2342   return ERROR_BAD_PROVIDER;
2343 }
2344
2345 /******************************************************************************
2346  * GetSecurityInfoExW [ADVAPI32.@]
2347  */
2348 DWORD WINAPI GetSecurityInfoExW(
2349         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2350         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2351         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2352         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2353 )
2354 {
2355   FIXME("stub!\n");
2356   return ERROR_BAD_PROVIDER; 
2357 }
2358
2359 /******************************************************************************
2360  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2361  */
2362 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2363                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2364                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2365 {
2366     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_a(pTrusteeName),
2367           AccessPermissions, AccessMode, Inheritance);
2368
2369     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2370     pExplicitAccess->grfAccessMode = AccessMode;
2371     pExplicitAccess->grfInheritance = Inheritance;
2372
2373     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2374     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2375     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2376     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2377     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2378 }
2379
2380 /******************************************************************************
2381  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2382  */
2383 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2384                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2385                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2386 {
2387     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_w(pTrusteeName),
2388           AccessPermissions, AccessMode, Inheritance);
2389
2390     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2391     pExplicitAccess->grfAccessMode = AccessMode;
2392     pExplicitAccess->grfInheritance = Inheritance;
2393
2394     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2395     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2396     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2397     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2398     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2399 }
2400
2401 /******************************************************************************
2402  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2403  */
2404 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2405                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2406                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2407 {
2408     DWORD ObjectsPresent = 0;
2409
2410     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2411           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2412
2413     /* Fill the OBJECTS_AND_NAME structure */
2414     pObjName->ObjectType = ObjectType;
2415     if (ObjectTypeName != NULL)
2416     {
2417         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2418     }
2419
2420     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2421     if (InheritedObjectTypeName != NULL)
2422     {
2423         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2424     }
2425
2426     pObjName->ObjectsPresent = ObjectsPresent;
2427     pObjName->ptstrName = Name;
2428
2429     /* Fill the TRUSTEE structure */
2430     pTrustee->pMultipleTrustee = NULL;
2431     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2432     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2433     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2434     pTrustee->ptstrName = (LPSTR)pObjName;
2435 }
2436
2437 /******************************************************************************
2438  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2439  */
2440 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2441                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2442                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2443 {
2444     DWORD ObjectsPresent = 0;
2445
2446     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2447           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2448
2449     /* Fill the OBJECTS_AND_NAME structure */
2450     pObjName->ObjectType = ObjectType;
2451     if (ObjectTypeName != NULL)
2452     {
2453         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2454     }
2455
2456     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2457     if (InheritedObjectTypeName != NULL)
2458     {
2459         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2460     }
2461
2462     pObjName->ObjectsPresent = ObjectsPresent;
2463     pObjName->ptstrName = Name;
2464
2465     /* Fill the TRUSTEE structure */
2466     pTrustee->pMultipleTrustee = NULL;
2467     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2468     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2469     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2470     pTrustee->ptstrName = (LPWSTR)pObjName;
2471 }
2472
2473 /******************************************************************************
2474  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2475  */
2476 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2477                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2478 {
2479     DWORD ObjectsPresent = 0;
2480
2481     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2482
2483     /* Fill the OBJECTS_AND_SID structure */
2484     if (pObjectGuid != NULL)
2485     {
2486         pObjSid->ObjectTypeGuid = *pObjectGuid;
2487         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2488     }
2489     else
2490     {
2491         ZeroMemory(&pObjSid->ObjectTypeGuid,
2492                    sizeof(GUID));
2493     }
2494
2495     if (pInheritedObjectGuid != NULL)
2496     {
2497         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2498         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2499     }
2500     else
2501     {
2502         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2503                    sizeof(GUID));
2504     }
2505
2506     pObjSid->ObjectsPresent = ObjectsPresent;
2507     pObjSid->pSid = pSid;
2508
2509     /* Fill the TRUSTEE structure */
2510     pTrustee->pMultipleTrustee = NULL;
2511     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2512     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2513     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2514     pTrustee->ptstrName = (LPSTR) pObjSid;
2515 }
2516
2517 /******************************************************************************
2518  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2519  */
2520 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2521                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2522 {
2523     DWORD ObjectsPresent = 0;
2524
2525     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2526
2527     /* Fill the OBJECTS_AND_SID structure */
2528     if (pObjectGuid != NULL)
2529     {
2530         pObjSid->ObjectTypeGuid = *pObjectGuid;
2531         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2532     }
2533     else
2534     {
2535         ZeroMemory(&pObjSid->ObjectTypeGuid,
2536                    sizeof(GUID));
2537     }
2538
2539     if (pInheritedObjectGuid != NULL)
2540     {
2541         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2542         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2543     }
2544     else
2545     {
2546         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2547                    sizeof(GUID));
2548     }
2549
2550     pObjSid->ObjectsPresent = ObjectsPresent;
2551     pObjSid->pSid = pSid;
2552
2553     /* Fill the TRUSTEE structure */
2554     pTrustee->pMultipleTrustee = NULL;
2555     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2556     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2557     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2558     pTrustee->ptstrName = (LPWSTR) pObjSid;
2559 }
2560
2561 /******************************************************************************
2562  * BuildTrusteeWithSidA [ADVAPI32.@]
2563  */
2564 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2565 {
2566     TRACE("%p %p\n", pTrustee, pSid);
2567
2568     pTrustee->pMultipleTrustee = NULL;
2569     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2570     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2571     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2572     pTrustee->ptstrName = (LPSTR) pSid;
2573 }
2574
2575 /******************************************************************************
2576  * BuildTrusteeWithSidW [ADVAPI32.@]
2577  */
2578 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2579 {
2580     TRACE("%p %p\n", pTrustee, pSid);
2581
2582     pTrustee->pMultipleTrustee = NULL;
2583     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2584     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2585     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2586     pTrustee->ptstrName = (LPWSTR) pSid;
2587 }
2588
2589 /******************************************************************************
2590  * BuildTrusteeWithNameA [ADVAPI32.@]
2591  */
2592 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2593 {
2594     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2595
2596     pTrustee->pMultipleTrustee = NULL;
2597     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2598     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2599     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2600     pTrustee->ptstrName = name;
2601 }
2602
2603 /******************************************************************************
2604  * BuildTrusteeWithNameW [ADVAPI32.@]
2605  */
2606 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2607 {
2608     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2609
2610     pTrustee->pMultipleTrustee = NULL;
2611     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2612     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2613     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2614     pTrustee->ptstrName = name;
2615 }
2616
2617 /****************************************************************************** 
2618  * GetTrusteeFormA [ADVAPI32.@] 
2619  */ 
2620 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
2621 {  
2622     TRACE("(%p)\n", pTrustee); 
2623   
2624     if (!pTrustee) 
2625         return TRUSTEE_BAD_FORM; 
2626   
2627     return pTrustee->TrusteeForm; 
2628 }  
2629   
2630 /****************************************************************************** 
2631  * GetTrusteeFormW [ADVAPI32.@] 
2632  */ 
2633 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
2634 {  
2635     TRACE("(%p)\n", pTrustee); 
2636   
2637     if (!pTrustee) 
2638         return TRUSTEE_BAD_FORM; 
2639   
2640     return pTrustee->TrusteeForm; 
2641 }  
2642   
2643 /****************************************************************************** 
2644  * GetTrusteeNameA [ADVAPI32.@] 
2645  */ 
2646 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
2647 {  
2648     TRACE("(%p)\n", pTrustee); 
2649   
2650     if (!pTrustee) 
2651         return NULL; 
2652   
2653     return pTrustee->ptstrName; 
2654 }  
2655   
2656 /****************************************************************************** 
2657  * GetTrusteeNameW [ADVAPI32.@] 
2658  */ 
2659 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
2660 {  
2661     TRACE("(%p)\n", pTrustee); 
2662   
2663     if (!pTrustee) 
2664         return NULL; 
2665   
2666     return pTrustee->ptstrName; 
2667 }  
2668   
2669 /****************************************************************************** 
2670  * GetTrusteeTypeA [ADVAPI32.@] 
2671  */ 
2672 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
2673 {  
2674     TRACE("(%p)\n", pTrustee); 
2675   
2676     if (!pTrustee) 
2677         return TRUSTEE_IS_UNKNOWN; 
2678   
2679     return pTrustee->TrusteeType; 
2680 }  
2681   
2682 /****************************************************************************** 
2683  * GetTrusteeTypeW [ADVAPI32.@] 
2684  */ 
2685 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
2686 {  
2687     TRACE("(%p)\n", pTrustee); 
2688   
2689     if (!pTrustee) 
2690         return TRUSTEE_IS_UNKNOWN; 
2691   
2692     return pTrustee->TrusteeType; 
2693
2694  
2695 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2696                                DWORD nAclInformationLength,
2697                                ACL_INFORMATION_CLASS dwAclInformationClass )
2698 {
2699     FIXME("%p %p 0x%08lx 0x%08x - stub\n", pAcl, pAclInformation,
2700           nAclInformationLength, dwAclInformationClass);
2701
2702     return TRUE;
2703 }
2704
2705 /******************************************************************************
2706  * SetEntriesInAclA [ADVAPI32.@]
2707  */
2708 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2709                                PACL OldAcl, PACL* NewAcl )
2710 {
2711     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2712     return ERROR_CALL_NOT_IMPLEMENTED;
2713 }
2714
2715 /******************************************************************************
2716  * SetEntriesInAclW [ADVAPI32.@]
2717  */
2718 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2719                                PACL OldAcl, PACL* NewAcl )
2720 {
2721     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2722     return ERROR_CALL_NOT_IMPLEMENTED;
2723 }
2724
2725 /******************************************************************************
2726  * SetNamedSecurityInfoA [ADVAPI32.@]
2727  */
2728 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2729         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2730         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2731 {
2732     DWORD len;
2733     LPWSTR wstr = NULL;
2734     DWORD r;
2735
2736     TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2737            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2738
2739     if( pObjectName )
2740     {
2741         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2742         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2743         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2744     }
2745
2746     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2747                            psidGroup, pDacl, pSacl );
2748
2749     HeapFree( GetProcessHeap(), 0, wstr );
2750
2751     return r;
2752 }
2753
2754 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2755     PSECURITY_DESCRIPTOR ModificationDescriptor,
2756     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2757     PGENERIC_MAPPING GenericMapping,
2758     HANDLE Token )
2759 {
2760     FIXME("0x%08lx %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2761           ObjectsSecurityDescriptor, GenericMapping, Token);
2762
2763     return TRUE;
2764 }
2765
2766 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2767   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2768   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2769 {
2770     FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2771           ControlBitsToSet);
2772
2773     return TRUE;
2774 }
2775
2776 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2777 {
2778     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2779 }
2780
2781 /******************************************************************************
2782  * AreAnyAccessesGranted [ADVAPI32.@]
2783  *
2784  * Determines whether or not any of a set of specified access permissions have
2785  * been granted or not.
2786  *
2787  * PARAMS
2788  *   GrantedAccess [I] The permissions that have been granted.
2789  *   DesiredAccess [I] The permissions that you want to have.
2790  *
2791  * RETURNS
2792  *   Nonzero if any of the permissions have been granted, zero if none of the
2793  *   permissions have been granted.
2794  */
2795
2796 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2797 {
2798     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
2799 }
2800
2801 /******************************************************************************
2802  * SetNamedSecurityInfoW [ADVAPI32.@]
2803  */
2804 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
2805         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2806         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2807 {
2808     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
2809            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2810     return ERROR_SUCCESS;
2811 }
2812
2813 /******************************************************************************
2814  * GetExplicitEntriesFromAclA [ADVAPI32.@]
2815  */
2816 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
2817         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
2818 {
2819     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2820     return ERROR_CALL_NOT_IMPLEMENTED;
2821 }
2822
2823 /******************************************************************************
2824  * GetExplicitEntriesFromAclW [ADVAPI32.@]
2825  */
2826 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
2827         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
2828 {
2829     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2830     return ERROR_CALL_NOT_IMPLEMENTED;
2831 }
2832
2833
2834 /******************************************************************************
2835  * ParseAclStringFlags
2836  */
2837 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2838 {
2839     DWORD flags = 0;
2840     LPCWSTR szAcl = *StringAcl;
2841
2842     while (*szAcl != '(')
2843     {
2844         if (*szAcl == 'P')
2845         {
2846             flags |= SE_DACL_PROTECTED;
2847         }
2848         else if (*szAcl == 'A')
2849         {
2850             szAcl++;
2851             if (*szAcl == 'R')
2852                 flags |= SE_DACL_AUTO_INHERIT_REQ;
2853             else if (*szAcl == 'I')
2854                 flags |= SE_DACL_AUTO_INHERITED;
2855         }
2856         szAcl++;
2857     }
2858
2859     *StringAcl = szAcl;
2860     return flags;
2861 }
2862
2863 /******************************************************************************
2864  * ParseAceStringType
2865  */
2866 static const ACEFLAG AceType[] =
2867 {
2868     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2869     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
2870     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
2871     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
2872     /*
2873     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2874     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
2875     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
2876     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2877     */
2878     { NULL, 0 },
2879 };
2880
2881 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2882 {
2883     UINT len = 0;
2884     LPCWSTR szAcl = *StringAcl;
2885     const ACEFLAG *lpaf = AceType;
2886
2887     while (lpaf->wstr &&
2888         (len = strlenW(lpaf->wstr)) &&
2889         strncmpW(lpaf->wstr, szAcl, len))
2890         lpaf++;
2891
2892     if (!lpaf->wstr)
2893         return 0;
2894
2895     *StringAcl += len;
2896     return lpaf->value;
2897 }
2898
2899
2900 /******************************************************************************
2901  * ParseAceStringFlags
2902  */
2903 static const ACEFLAG AceFlags[] =
2904 {
2905     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2906     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
2907     { SDDL_INHERITED,         INHERITED_ACE },
2908     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
2909     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
2910     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
2911     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
2912     { NULL, 0 },
2913 };
2914
2915 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2916 {
2917     UINT len = 0;
2918     BYTE flags = 0;
2919     LPCWSTR szAcl = *StringAcl;
2920
2921     while (*szAcl != ';')
2922     {
2923         const ACEFLAG *lpaf = AceFlags;
2924
2925         while (lpaf->wstr &&
2926                (len = strlenW(lpaf->wstr)) &&
2927                strncmpW(lpaf->wstr, szAcl, len))
2928             lpaf++;
2929
2930         if (!lpaf->wstr)
2931             return 0;
2932
2933         flags |= lpaf->value;
2934         szAcl += len;
2935     }
2936
2937     *StringAcl = szAcl;
2938     return flags;
2939 }
2940
2941
2942 /******************************************************************************
2943  * ParseAceStringRights
2944  */
2945 static const ACEFLAG AceRights[] =
2946 {
2947     { SDDL_GENERIC_ALL,     GENERIC_ALL },
2948     { SDDL_GENERIC_READ,    GENERIC_READ },
2949     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
2950     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2951     { SDDL_READ_CONTROL,    READ_CONTROL },
2952     { SDDL_STANDARD_DELETE, DELETE },
2953     { SDDL_WRITE_DAC,       WRITE_DAC },
2954     { SDDL_WRITE_OWNER,     WRITE_OWNER },
2955     { NULL, 0 },
2956 };
2957
2958 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2959 {
2960     UINT len = 0;
2961     DWORD rights = 0;
2962     LPCWSTR szAcl = *StringAcl;
2963
2964     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2965     {
2966         LPCWSTR p = szAcl;
2967
2968         while (*p && *p != ';')
2969             p++;
2970
2971         if (p - szAcl <= 8)
2972         {
2973             rights = strtoulW(szAcl, NULL, 16);
2974             *StringAcl = p;
2975         }
2976         else
2977             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2978     }
2979     else
2980     {
2981         while (*szAcl != ';')
2982         {
2983             const ACEFLAG *lpaf = AceRights;
2984
2985             while (lpaf->wstr &&
2986                (len = strlenW(lpaf->wstr)) &&
2987                strncmpW(lpaf->wstr, szAcl, len))
2988             {
2989                lpaf++;
2990             }
2991
2992             if (!lpaf->wstr)
2993                 return 0;
2994
2995             rights |= lpaf->value;
2996             szAcl += len;
2997         }
2998     }
2999
3000     *StringAcl = szAcl;
3001     return rights;
3002 }
3003
3004
3005 /******************************************************************************
3006  * ParseStringAclToAcl
3007  * 
3008  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
3009  */
3010 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
3011     PACL pAcl, LPDWORD cBytes)
3012 {
3013     DWORD val;
3014     DWORD sidlen;
3015     DWORD length = sizeof(ACL);
3016     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3017
3018     TRACE("%s\n", debugstr_w(StringAcl));
3019
3020     if (!StringAcl)
3021         return FALSE;
3022
3023     if (pAcl) /* pAce is only useful if we're setting values */
3024         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
3025
3026     /* Parse ACL flags */
3027     *lpdwFlags = ParseAclStringFlags(&StringAcl);
3028
3029     /* Parse ACE */
3030     while (*StringAcl == '(')
3031     {
3032         StringAcl++;
3033
3034         /* Parse ACE type */
3035         val = ParseAceStringType(&StringAcl);
3036         if (pAce)
3037             pAce->Header.AceType = (BYTE) val;
3038         if (*StringAcl != ';')
3039             goto lerr;
3040         StringAcl++;
3041
3042         /* Parse ACE flags */
3043         val = ParseAceStringFlags(&StringAcl);
3044         if (pAce)
3045             pAce->Header.AceFlags = (BYTE) val;
3046         if (*StringAcl != ';')
3047             goto lerr;
3048         StringAcl++;
3049
3050         /* Parse ACE rights */
3051         val = ParseAceStringRights(&StringAcl);
3052         if (pAce)
3053             pAce->Mask = val;
3054         if (*StringAcl != ';')
3055             goto lerr;
3056         StringAcl++;
3057
3058         /* Parse ACE object guid */
3059         if (*StringAcl != ';')
3060         {
3061             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3062             goto lerr;
3063         }
3064         StringAcl++;
3065
3066         /* Parse ACE inherit object guid */
3067         if (*StringAcl != ';')
3068         {
3069             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3070             goto lerr;
3071         }
3072         StringAcl++;
3073
3074         /* Parse ACE account sid */
3075         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3076         {
3077             while (*StringAcl && *StringAcl != ')')
3078                 StringAcl++;
3079         }
3080
3081         if (*StringAcl != ')')
3082             goto lerr;
3083         StringAcl++;
3084
3085         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3086     }
3087
3088     *cBytes = length;
3089     return TRUE;
3090
3091 lerr:
3092     WARN("Invalid ACE string format\n");
3093     return FALSE;
3094 }
3095
3096
3097 /******************************************************************************
3098  * ParseStringSecurityDescriptorToSecurityDescriptor
3099  */
3100 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3101     LPCWSTR StringSecurityDescriptor,
3102     SECURITY_DESCRIPTOR* SecurityDescriptor,
3103     LPDWORD cBytes)
3104 {
3105     BOOL bret = FALSE;
3106     WCHAR toktype;
3107     WCHAR tok[MAX_PATH];
3108     LPCWSTR lptoken;
3109     LPBYTE lpNext = NULL;
3110     DWORD len;
3111
3112     *cBytes = 0;
3113
3114     if (SecurityDescriptor)
3115         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3116
3117     while (*StringSecurityDescriptor)
3118     {
3119         toktype = *StringSecurityDescriptor;
3120
3121         /* Expect char identifier followed by ':' */
3122         StringSecurityDescriptor++;
3123         if (*StringSecurityDescriptor != ':')
3124         {
3125             SetLastError(ERROR_INVALID_PARAMETER);
3126             goto lend;
3127         }
3128         StringSecurityDescriptor++;
3129
3130         /* Extract token */
3131         lptoken = StringSecurityDescriptor;
3132         while (*lptoken && *lptoken != ':')
3133             lptoken++;
3134
3135         if (*lptoken)
3136             lptoken--;
3137
3138         len = lptoken - StringSecurityDescriptor;
3139         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3140         tok[len] = 0;
3141
3142         switch (toktype)
3143         {
3144             case 'O':
3145             {
3146                 DWORD bytes;
3147
3148                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3149                     goto lend;
3150
3151                 if (SecurityDescriptor)
3152                 {
3153                     SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3154                     lpNext += bytes; /* Advance to next token */
3155                 }
3156
3157                 *cBytes += bytes;
3158
3159                 break;
3160             }
3161
3162             case 'G':
3163             {
3164                 DWORD bytes;
3165
3166                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3167                     goto lend;
3168
3169                 if (SecurityDescriptor)
3170                 {
3171                     SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3172                     lpNext += bytes; /* Advance to next token */
3173                 }
3174
3175                 *cBytes += bytes;
3176
3177                 break;
3178             }
3179
3180             case 'D':
3181             {
3182                 DWORD flags;
3183                 DWORD bytes;
3184
3185                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3186                     goto lend;
3187
3188                 if (SecurityDescriptor)
3189                 {
3190                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3191                     SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3192                     lpNext += bytes; /* Advance to next token */
3193                 }
3194
3195                 *cBytes += bytes;
3196
3197                 break;
3198             }
3199
3200             case 'S':
3201             {
3202                 DWORD flags;
3203                 DWORD bytes;
3204
3205                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3206                     goto lend;
3207
3208                 if (SecurityDescriptor)
3209                 {
3210                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3211                     SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3212                     lpNext += bytes; /* Advance to next token */
3213                 }
3214
3215                 *cBytes += bytes;
3216
3217                 break;
3218             }
3219
3220             default:
3221                 FIXME("Unknown token\n");
3222                 SetLastError(ERROR_INVALID_PARAMETER);
3223                 goto lend;
3224         }
3225
3226         StringSecurityDescriptor = lptoken;
3227     }
3228
3229     bret = TRUE;
3230
3231 lend:
3232     return bret;
3233 }
3234
3235 /******************************************************************************
3236  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3237  */
3238 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3239         LPCSTR StringSecurityDescriptor,
3240         DWORD StringSDRevision,
3241         PSECURITY_DESCRIPTOR* SecurityDescriptor,
3242         PULONG SecurityDescriptorSize)
3243 {
3244     UINT len;
3245     BOOL ret = FALSE;
3246     LPWSTR StringSecurityDescriptorW;
3247
3248     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3249     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3250
3251     if (StringSecurityDescriptorW)
3252     {
3253         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3254
3255         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3256                                                                    StringSDRevision, SecurityDescriptor,
3257                                                                    SecurityDescriptorSize);
3258         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3259     }
3260
3261     return ret;
3262 }
3263
3264 /******************************************************************************
3265  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3266  */
3267 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3268         LPCWSTR StringSecurityDescriptor,
3269         DWORD StringSDRevision,
3270         PSECURITY_DESCRIPTOR* SecurityDescriptor,
3271         PULONG SecurityDescriptorSize)
3272 {
3273     DWORD cBytes;
3274     SECURITY_DESCRIPTOR* psd;
3275     BOOL bret = FALSE;
3276
3277     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3278
3279     if (GetVersion() & 0x80000000)
3280     {
3281         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3282         goto lend;
3283     }
3284     else if (StringSDRevision != SID_REVISION)
3285     {
3286         SetLastError(ERROR_UNKNOWN_REVISION);
3287         goto lend;
3288     }
3289
3290     /* Compute security descriptor length */
3291     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3292         NULL, &cBytes))
3293         goto lend;
3294
3295     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3296         GMEM_ZEROINIT, cBytes);
3297
3298     psd->Revision = SID_REVISION;
3299     psd->Control |= SE_SELF_RELATIVE;
3300
3301     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3302         psd, &cBytes))
3303     {
3304         LocalFree(psd);
3305         goto lend;
3306     }
3307
3308     if (SecurityDescriptorSize)
3309         *SecurityDescriptorSize = cBytes;
3310
3311     bret = TRUE;
3312  
3313 lend:
3314     TRACE(" ret=%d\n", bret);
3315     return bret;
3316 }
3317
3318 /******************************************************************************
3319  * ConvertStringSidToSidW [ADVAPI32.@]
3320  */
3321 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3322 {
3323     BOOL bret = FALSE;
3324     DWORD cBytes;
3325
3326     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3327     if (GetVersion() & 0x80000000)
3328         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3329     else if (!StringSid || !Sid)
3330         SetLastError(ERROR_INVALID_PARAMETER);
3331     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3332     {
3333         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
3334
3335         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3336         if (!bret)
3337             LocalFree(*Sid); 
3338     }
3339     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3340     return bret;
3341 }
3342
3343 /******************************************************************************
3344  * ConvertStringSidToSidA [ADVAPI32.@]
3345  */
3346 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3347 {
3348     BOOL bret = FALSE;
3349
3350     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3351     if (GetVersion() & 0x80000000)
3352         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3353     else if (!StringSid || !Sid)
3354         SetLastError(ERROR_INVALID_PARAMETER);
3355     else
3356     {
3357         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
3358         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
3359          len * sizeof(WCHAR));
3360
3361         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
3362         bret = ConvertStringSidToSidW(wStringSid, Sid);
3363         HeapFree(GetProcessHeap(), 0, wStringSid);
3364     }
3365     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3366     return bret;
3367 }
3368
3369 /******************************************************************************
3370  * ConvertSidToStringSidW [ADVAPI32.@]
3371  *
3372  *  format of SID string is:
3373  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3374  *  where
3375  *    <rev> is the revision of the SID encoded as decimal
3376  *    <auth> is the identifier authority encoded as hex
3377  *    <subauthN> is the subauthority id encoded as decimal
3378  */
3379 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
3380 {
3381     DWORD sz, i;
3382     LPWSTR str;
3383     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3384     WCHAR subauthfmt[] = { '-','%','u',0 };
3385     SID* pisid=pSid;
3386
3387     TRACE("%p %p\n", pSid, pstr );
3388
3389     if( !IsValidSid( pSid ) )
3390         return FALSE;
3391
3392     if (pisid->Revision != SDDL_REVISION)
3393         return FALSE;
3394     if (pisid->IdentifierAuthority.Value[0] ||
3395      pisid->IdentifierAuthority.Value[1])
3396     {
3397         FIXME("not matching MS' bugs\n");
3398         return FALSE;
3399     }
3400
3401     sz = 14 + pisid->SubAuthorityCount * 11;
3402     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
3403     sprintfW( str, fmt, pisid->Revision, MAKELONG(
3404      MAKEWORD( pisid->IdentifierAuthority.Value[5],
3405      pisid->IdentifierAuthority.Value[4] ),
3406      MAKEWORD( pisid->IdentifierAuthority.Value[3],
3407      pisid->IdentifierAuthority.Value[2] ) ) );
3408     for( i=0; i<pisid->SubAuthorityCount; i++ )
3409         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
3410     *pstr = str;
3411
3412     return TRUE;
3413 }
3414
3415 /******************************************************************************
3416  * ConvertSidToStringSidA [ADVAPI32.@]
3417  */
3418 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
3419 {
3420     LPWSTR wstr = NULL;
3421     LPSTR str;
3422     UINT len;
3423
3424     TRACE("%p %p\n", pSid, pstr );
3425
3426     if( !ConvertSidToStringSidW( pSid, &wstr ) )
3427         return FALSE;
3428
3429     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
3430     str = LocalAlloc( 0, len );
3431     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
3432     LocalFree( wstr );
3433
3434     *pstr = str;
3435
3436     return TRUE;
3437 }
3438
3439 BOOL WINAPI CreatePrivateObjectSecurity(
3440         PSECURITY_DESCRIPTOR ParentDescriptor,
3441         PSECURITY_DESCRIPTOR CreatorDescriptor,
3442         PSECURITY_DESCRIPTOR* NewDescriptor,
3443         BOOL IsDirectoryObject,
3444         HANDLE Token,
3445         PGENERIC_MAPPING GenericMapping )
3446 {
3447     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
3448           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
3449
3450     return FALSE;
3451 }
3452
3453 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
3454 {
3455     FIXME("%p - stub\n", ObjectDescriptor);
3456
3457     return TRUE;
3458 }
3459
3460 BOOL WINAPI CreateProcessAsUserA(
3461         HANDLE hToken,
3462         LPCSTR lpApplicationName,
3463         LPSTR lpCommandLine,
3464         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3465         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3466         BOOL bInheritHandles,
3467         DWORD dwCreationFlags,
3468         LPVOID lpEnvironment,
3469         LPCSTR lpCurrentDirectory,
3470         LPSTARTUPINFOA lpStartupInfo,
3471         LPPROCESS_INFORMATION lpProcessInformation )
3472 {
3473     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
3474           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3475           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3476
3477     return FALSE;
3478 }
3479
3480 BOOL WINAPI CreateProcessAsUserW(
3481         HANDLE hToken,
3482         LPCWSTR lpApplicationName,
3483         LPWSTR lpCommandLine,
3484         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3485         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3486         BOOL bInheritHandles,
3487         DWORD dwCreationFlags,
3488         LPVOID lpEnvironment,
3489         LPCWSTR lpCurrentDirectory,
3490         LPSTARTUPINFOW lpStartupInfo,
3491         LPPROCESS_INFORMATION lpProcessInformation )
3492 {
3493     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - semi- stub\n", hToken, 
3494           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
3495           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
3496           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3497
3498     /* We should create the process with a suspended main thread */
3499     if (!CreateProcessW (lpApplicationName,
3500                          lpCommandLine,
3501                          lpProcessAttributes,
3502                          lpThreadAttributes,
3503                          bInheritHandles,
3504                          dwCreationFlags, /* CREATE_SUSPENDED */
3505                          lpEnvironment,
3506                          lpCurrentDirectory,
3507                          lpStartupInfo,
3508                          lpProcessInformation))
3509     {
3510       return FALSE;
3511     }
3512
3513     return TRUE;
3514 }
3515
3516 BOOL WINAPI DuplicateTokenEx(
3517         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
3518         LPSECURITY_ATTRIBUTES lpTokenAttributes,
3519         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3520         TOKEN_TYPE TokenType,
3521         PHANDLE DuplicateTokenHandle )
3522 {
3523     OBJECT_ATTRIBUTES ObjectAttributes;
3524
3525     TRACE("%p 0x%08lx 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3526           ImpersonationLevel, TokenType, DuplicateTokenHandle);
3527
3528     InitializeObjectAttributes(
3529         &ObjectAttributes,
3530         NULL,
3531         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
3532         NULL,
3533         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
3534
3535     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
3536                                            dwDesiredAccess,
3537                                            &ObjectAttributes,
3538                                            ImpersonationLevel,
3539                                            TokenType,
3540                                            DuplicateTokenHandle ) );
3541 }
3542
3543 BOOL WINAPI DuplicateToken(
3544         HANDLE ExistingTokenHandle,
3545         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3546         PHANDLE DuplicateTokenHandle )
3547 {
3548     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
3549                              NULL, ImpersonationLevel, TokenImpersonation,
3550                              DuplicateTokenHandle );
3551 }
3552
3553 BOOL WINAPI EnumDependentServicesA(
3554         SC_HANDLE hService,
3555         DWORD dwServiceState,
3556         LPENUM_SERVICE_STATUSA lpServices,
3557         DWORD cbBufSize,
3558         LPDWORD pcbBytesNeeded,
3559         LPDWORD lpServicesReturned )
3560 {
3561     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3562           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3563
3564     return FALSE;
3565 }
3566
3567 BOOL WINAPI EnumDependentServicesW(
3568         SC_HANDLE hService,
3569         DWORD dwServiceState,
3570         LPENUM_SERVICE_STATUSW lpServices,
3571         DWORD cbBufSize,
3572         LPDWORD pcbBytesNeeded,
3573         LPDWORD lpServicesReturned )
3574 {
3575     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3576           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3577
3578     return FALSE;
3579 }
3580
3581 /******************************************************************************
3582  * ComputeStringSidSize
3583  */
3584 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3585 {
3586     DWORD size = sizeof(SID);
3587
3588     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3589     {
3590         int ctok = 0;
3591         while (*StringSid)
3592         {
3593             if (*StringSid == '-')
3594                 ctok++;
3595             StringSid++;
3596         }
3597
3598         if (ctok > 3)
3599             size += (ctok - 3) * sizeof(DWORD);
3600     }
3601     else /* String constant format  - Only available in winxp and above */
3602     {
3603         int i;
3604
3605         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3606             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3607                 size += (WellKnownSids[i].SubAuthorityCount - 1) * sizeof(DWORD);
3608     }
3609
3610     return size;
3611 }
3612
3613 /******************************************************************************
3614  * ParseStringSidToSid
3615  */
3616 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3617 {
3618     BOOL bret = FALSE;
3619     SID* pisid=pSid;
3620
3621     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3622     if (!StringSid)
3623     {
3624         SetLastError(ERROR_INVALID_PARAMETER);
3625         TRACE("StringSid is NULL, returning FALSE\n");
3626         return FALSE;
3627     }
3628
3629     *cBytes = ComputeStringSidSize(StringSid);
3630     if (!pisid) /* Simply compute the size */
3631     {
3632         TRACE("only size requested, returning TRUE\n");
3633         return TRUE;
3634     }
3635
3636     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3637     {
3638         DWORD i = 0, identAuth;
3639         DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
3640
3641         StringSid += 2; /* Advance to Revision */
3642         pisid->Revision = atoiW(StringSid);
3643
3644         if (pisid->Revision != SDDL_REVISION)
3645         {
3646             TRACE("Revision %d is unknown\n", pisid->Revision);
3647             goto lend; /* ERROR_INVALID_SID */
3648         }
3649         if (csubauth == 0)
3650         {
3651             TRACE("SubAuthorityCount is 0\n");
3652             goto lend; /* ERROR_INVALID_SID */
3653         }
3654
3655         pisid->SubAuthorityCount = csubauth;
3656
3657         /* Advance to identifier authority */
3658         while (*StringSid && *StringSid != '-')
3659             StringSid++;
3660         if (*StringSid == '-')
3661             StringSid++;
3662
3663         /* MS' implementation can't handle values greater than 2^32 - 1, so
3664          * we don't either; assume most significant bytes are always 0
3665          */
3666         pisid->IdentifierAuthority.Value[0] = 0;
3667         pisid->IdentifierAuthority.Value[1] = 0;
3668         identAuth = atoiW(StringSid);
3669         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3670         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3671         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3672         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3673
3674         /* Advance to first sub authority */
3675         while (*StringSid && *StringSid != '-')
3676             StringSid++;
3677         if (*StringSid == '-')
3678             StringSid++;
3679
3680         while (*StringSid)
3681         {
3682             while (*StringSid && *StringSid != '-')
3683                 StringSid++;
3684             if (*StringSid == '-')
3685                 StringSid++;
3686
3687             pisid->SubAuthority[i++] = atoiW(StringSid);
3688         }
3689
3690         if (i != pisid->SubAuthorityCount)
3691             goto lend; /* ERROR_INVALID_SID */
3692
3693         bret = TRUE;
3694     }
3695     else /* String constant format  - Only available in winxp and above */
3696     {
3697         int i;
3698         pisid->Revision = SDDL_REVISION;
3699
3700         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3701             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3702             {
3703                 DWORD j;
3704                 pisid->SubAuthorityCount = WellKnownSids[i].SubAuthorityCount;
3705                 pisid->IdentifierAuthority = WellKnownSids[i].IdentifierAuthority;
3706                 for (j = 0; j < WellKnownSids[i].SubAuthorityCount; j++)
3707                     pisid->SubAuthority[j] = WellKnownSids[i].SubAuthority[j];
3708                 bret = TRUE;
3709             }
3710
3711         if (!bret)
3712             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3713     }
3714
3715 lend:
3716     if (!bret)
3717         SetLastError(ERROR_INVALID_SID);
3718
3719     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3720     return bret;
3721 }
3722
3723 /******************************************************************************
3724  * GetNamedSecurityInfoA [ADVAPI32.@]
3725  */
3726 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
3727         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3728         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3729         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3730 {
3731     DWORD len;
3732     LPWSTR wstr = NULL;
3733     DWORD r;
3734
3735     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3736         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3737
3738     if( pObjectName )
3739     {
3740         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3741         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3742         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3743     }
3744
3745     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3746                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3747
3748     HeapFree( GetProcessHeap(), 0, wstr );
3749
3750     return r;
3751 }
3752
3753 /******************************************************************************
3754  * GetNamedSecurityInfoW [ADVAPI32.@]
3755  */
3756 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
3757     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
3758     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
3759 {
3760     DWORD needed, offset;
3761     SECURITY_DESCRIPTOR_RELATIVE *relative;
3762     BYTE *buffer;
3763
3764     TRACE( "%s %d %ld %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
3765            group, dacl, sacl, descriptor );
3766
3767     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
3768
3769     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3770     if (info & OWNER_SECURITY_INFORMATION)
3771         needed += sizeof(sidWorld);
3772     if (info & GROUP_SECURITY_INFORMATION)
3773         needed += sizeof(sidWorld);
3774     if (info & DACL_SECURITY_INFORMATION)
3775         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3776     if (info & SACL_SECURITY_INFORMATION)
3777         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3778
3779     /* must be freed by caller */
3780     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
3781     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
3782
3783     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
3784     {
3785         HeapFree( GetProcessHeap(), 0, *descriptor );
3786         return ERROR_INVALID_SECURITY_DESCR;
3787     }
3788
3789     relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
3790     relative->Control |= SE_SELF_RELATIVE;
3791     buffer = (BYTE *)relative;
3792     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3793
3794     if (owner && (info & OWNER_SECURITY_INFORMATION))
3795     {
3796         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3797         relative->Owner = offset;
3798         *owner = buffer + offset;
3799         offset += sizeof(sidWorld);
3800     }
3801     if (group && (info & GROUP_SECURITY_INFORMATION))
3802     {
3803         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3804         relative->Group = offset;
3805         *group = buffer + offset;
3806         offset += sizeof(sidWorld);
3807     }
3808     if (dacl && (info & DACL_SECURITY_INFORMATION))
3809     {
3810         GetWorldAccessACL( (PACL)(buffer + offset) );
3811         relative->Dacl = offset;
3812         *dacl = (PACL)(buffer + offset);
3813         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3814     }
3815     if (sacl && (info & SACL_SECURITY_INFORMATION))
3816     {
3817         GetWorldAccessACL( (PACL)(buffer + offset) );
3818         relative->Sacl = offset;
3819         *sacl = (PACL)(buffer + offset);
3820     }
3821     return ERROR_SUCCESS;
3822 }
3823
3824 /******************************************************************************
3825  * DecryptFileW [ADVAPI32.@]
3826  */
3827 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
3828 {
3829     FIXME("%s %08lx\n", debugstr_w(lpFileName), dwReserved);
3830     return TRUE;
3831 }
3832
3833 /******************************************************************************
3834  * DecryptFileA [ADVAPI32.@]
3835  */
3836 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
3837 {
3838     FIXME("%s %08lx\n", debugstr_a(lpFileName), dwReserved);
3839     return TRUE;
3840 }
3841
3842 /******************************************************************************
3843  * EncryptFileW [ADVAPI32.@]
3844  */
3845 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
3846 {
3847     FIXME("%s\n", debugstr_w(lpFileName));
3848     return TRUE;
3849 }
3850
3851 /******************************************************************************
3852  * EncryptFileA [ADVAPI32.@]
3853  */
3854 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
3855 {
3856     FIXME("%s\n", debugstr_a(lpFileName));
3857     return TRUE;
3858 }
3859
3860 /******************************************************************************
3861  * FileEncryptionStatusW [ADVAPI32.@]
3862  */
3863 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
3864 {
3865     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
3866     if (!lpStatus)
3867         return FALSE;
3868     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
3869     return TRUE;
3870 }
3871
3872 /******************************************************************************
3873  * FileEncryptionStatusA [ADVAPI32.@]
3874  */
3875 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
3876 {
3877     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
3878     if (!lpStatus)
3879         return FALSE;
3880     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
3881     return TRUE;
3882 }
3883
3884 /******************************************************************************
3885  * SetSecurityInfo [ADVAPI32.@]
3886  */
3887 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
3888                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
3889                       PSID psidGroup, PACL pDacl, PACL pSacl) {
3890     FIXME("stub\n");
3891     return ERROR_SUCCESS;
3892 }