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