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