wined3d: Implement more GLSL instructions and a little cleanup.
[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         if (accountSize) *accountSize = strlen(ac)+1;
1489         if (account && (*accountSize > strlen(ac)))
1490           strcpy(account, ac);
1491
1492         if (domainSize) *domainSize = strlen(dm)+1;
1493         if (domain && (*domainSize > strlen(dm)))
1494           strcpy(domain,dm);
1495
1496         if (name_use) *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         if (accountSize) *accountSize = strlenW(ac)+1;
1531         if (account && (*accountSize > strlenW(ac)))
1532             strcpyW(account, ac);
1533
1534         if (domainSize) *domainSize = strlenW(dm)+1;
1535         if (domain && (*domainSize > strlenW(dm)))
1536             strcpyW(domain,dm);
1537
1538         if (name_use) *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     NTSTATUS Status;
1679     HANDLE ImpersonationToken;
1680     TOKEN_TYPE Type = TokenImpersonation;
1681
1682     FIXME( "(%p)\n", hToken );
1683
1684     /* FIXME: get token type */
1685
1686     if (Type == TokenPrimary)
1687     {
1688         OBJECT_ATTRIBUTES ObjectAttributes;
1689
1690         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
1691
1692         Status = NtDuplicateToken( hToken,
1693                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
1694                                    &ObjectAttributes,
1695                                    SecurityImpersonation,
1696                                    TokenImpersonation,
1697                                    &ImpersonationToken );
1698         if (Status != STATUS_SUCCESS)
1699         {
1700             ERR( "NtDuplicateToken failed with error 0x%08lx\n", Status );
1701             SetLastError( RtlNtStatusToDosError( Status ) );
1702             return FALSE;
1703         }
1704     }
1705     else
1706         ImpersonationToken = hToken;
1707
1708     Status = NtSetInformationThread( GetCurrentThread(),
1709                                      ThreadImpersonationToken,
1710                                      &ImpersonationToken,
1711                                      sizeof(ImpersonationToken) );
1712
1713     if (Type == TokenPrimary)
1714         NtClose( ImpersonationToken );
1715
1716     if (Status != STATUS_SUCCESS)
1717     {
1718         ERR( "NtSetInformationThread failed with error 0x%08lx\n", Status );
1719         SetLastError( RtlNtStatusToDosError( Status ) );
1720         return FALSE;
1721     }
1722
1723     return TRUE;
1724 }
1725
1726 /******************************************************************************
1727  * AccessCheck [ADVAPI32.@]
1728  */
1729 BOOL WINAPI
1730 AccessCheck(
1731         PSECURITY_DESCRIPTOR SecurityDescriptor,
1732         HANDLE ClientToken,
1733         DWORD DesiredAccess,
1734         PGENERIC_MAPPING GenericMapping,
1735         PPRIVILEGE_SET PrivilegeSet,
1736         LPDWORD PrivilegeSetLength,
1737         LPDWORD GrantedAccess,
1738         LPBOOL AccessStatus)
1739 {
1740     NTSTATUS access_status;
1741     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
1742                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
1743                                            GrantedAccess, &access_status) );
1744     if (ret) *AccessStatus = set_ntstatus( access_status );
1745     return ret;
1746 }
1747
1748
1749 /******************************************************************************
1750  * AccessCheckByType [ADVAPI32.@]
1751  */
1752 BOOL WINAPI AccessCheckByType(
1753     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
1754     PSID PrincipalSelfSid,
1755     HANDLE ClientToken, 
1756     DWORD DesiredAccess, 
1757     POBJECT_TYPE_LIST ObjectTypeList,
1758     DWORD ObjectTypeListLength,
1759     PGENERIC_MAPPING GenericMapping,
1760     PPRIVILEGE_SET PrivilegeSet,
1761     LPDWORD PrivilegeSetLength, 
1762     LPDWORD GrantedAccess,
1763     LPBOOL AccessStatus)
1764 {
1765         FIXME("stub\n");
1766
1767         *AccessStatus = TRUE;
1768
1769         return !*AccessStatus;
1770 }
1771
1772 /******************************************************************************
1773  * MapGenericMask [ADVAPI32.@]
1774  *
1775  * Maps generic access rights into specific access rights according to the
1776  * supplied mapping.
1777  *
1778  * PARAMS
1779  *  AccessMask     [I/O] Access rights.
1780  *  GenericMapping [I] The mapping between generic and specific rights.
1781  *
1782  * RETURNS
1783  *  Nothing.
1784  */
1785 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
1786 {
1787     RtlMapGenericMask( AccessMask, GenericMapping );
1788 }
1789
1790 /*************************************************************************
1791  * SetKernelObjectSecurity [ADVAPI32.@]
1792  */
1793 BOOL WINAPI SetKernelObjectSecurity (
1794         IN HANDLE Handle,
1795         IN SECURITY_INFORMATION SecurityInformation,
1796         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
1797 {
1798     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
1799 }
1800
1801
1802 /******************************************************************************
1803  *  AddAuditAccessAce [ADVAPI32.@]
1804  */
1805 BOOL WINAPI AddAuditAccessAce(
1806     IN OUT PACL pAcl, 
1807     IN DWORD dwAceRevision, 
1808     IN DWORD dwAccessMask, 
1809     IN PSID pSid, 
1810     IN BOOL bAuditSuccess, 
1811     IN BOOL bAuditFailure) 
1812 {
1813     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
1814                                               bAuditSuccess, bAuditFailure) ); 
1815 }
1816
1817 /******************************************************************************
1818  * LookupAccountNameA [ADVAPI32.@]
1819  */
1820 BOOL WINAPI
1821 LookupAccountNameA(
1822         IN LPCSTR system,
1823         IN LPCSTR account,
1824         OUT PSID sid,
1825         OUT LPDWORD cbSid,
1826         LPSTR ReferencedDomainName,
1827         IN OUT LPDWORD cbReferencedDomainName,
1828         OUT PSID_NAME_USE name_use )
1829 {
1830     BOOL ret;
1831     UNICODE_STRING lpSystemW;
1832     UNICODE_STRING lpAccountW;
1833     LPWSTR lpReferencedDomainNameW = NULL;
1834
1835     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
1836     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
1837
1838     if (ReferencedDomainName)
1839         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
1840
1841     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
1842         cbReferencedDomainName, name_use);
1843
1844     if (ret && lpReferencedDomainNameW)
1845     {
1846         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
1847             ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
1848     }
1849
1850     RtlFreeUnicodeString(&lpSystemW);
1851     RtlFreeUnicodeString(&lpAccountW);
1852     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1853
1854     return ret;
1855 }
1856
1857 /******************************************************************************
1858  * LookupAccountNameW [ADVAPI32.@]
1859  */
1860 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
1861                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
1862                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
1863 {
1864     /* Default implementation: Always return a default SID */
1865     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1866     BOOL ret;
1867     PSID pSid;
1868     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1869
1870     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
1871           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1872
1873     ret = AllocateAndInitializeSid(&identifierAuthority,
1874         2,
1875         SECURITY_BUILTIN_DOMAIN_RID,
1876         DOMAIN_ALIAS_RID_ADMINS,
1877         0, 0, 0, 0, 0, 0,
1878         &pSid);
1879
1880     if (!ret)
1881        return FALSE;
1882
1883     if (!RtlValidSid(pSid))
1884     {
1885        FreeSid(pSid);
1886        return FALSE;
1887     }
1888
1889     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1890        CopySid(*cbSid, Sid, pSid);
1891     if (*cbSid < GetLengthSid(pSid))
1892     {
1893        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1894        ret = FALSE;
1895     }
1896     *cbSid = GetLengthSid(pSid);
1897     
1898     if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
1899       strcpyW(ReferencedDomainName, dm);
1900
1901     if (*cchReferencedDomainName <= strlenW(dm))
1902     {
1903        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1904        ret = FALSE;
1905     }
1906
1907     *cchReferencedDomainName = strlenW(dm)+1;
1908
1909     FreeSid(pSid);
1910
1911     return ret;
1912 }
1913
1914 /******************************************************************************
1915  * PrivilegeCheck [ADVAPI32.@]
1916  */
1917 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
1918 {
1919     BOOL ret;
1920     BOOLEAN Result;
1921
1922     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
1923
1924     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
1925     if (ret)
1926         *pfResult = Result;
1927     return ret;
1928 }
1929
1930 /******************************************************************************
1931  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1932  */
1933 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
1934   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1935   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1936   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1937 {
1938         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
1939                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
1940                 SecurityDescriptor, DesiredAccess, GenericMapping,
1941                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1942         return TRUE;
1943 }
1944
1945 /******************************************************************************
1946  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
1947  */
1948 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
1949   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1950   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1951   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1952 {
1953         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
1954                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
1955                 SecurityDescriptor, DesiredAccess, GenericMapping,
1956                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1957         return TRUE;
1958 }
1959
1960 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1961 {
1962     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
1963
1964     return TRUE;
1965 }
1966
1967 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1968 {
1969     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
1970
1971     return TRUE;
1972 }
1973
1974 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1975 {
1976     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
1977
1978     return TRUE;
1979 }
1980
1981 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
1982   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
1983   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
1984   LPBOOL GenerateOnClose)
1985 {
1986         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
1987                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
1988         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
1989         GenerateOnClose);
1990
1991     return TRUE;
1992 }
1993
1994 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
1995   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
1996   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
1997   LPBOOL GenerateOnClose)
1998 {
1999     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2000         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2001         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2002         GenerateOnClose);
2003
2004     return TRUE;
2005 }
2006
2007 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2008   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2009 {
2010     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2011           DesiredAccess, Privileges, AccessGranted);
2012
2013     return TRUE;
2014 }
2015
2016 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2017   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2018 {
2019     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2020           DesiredAccess, Privileges, AccessGranted);
2021
2022     return TRUE;
2023 }
2024
2025 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2026                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2027 {
2028     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2029           ClientToken, Privileges, AccessGranted);
2030
2031     return TRUE;
2032 }
2033
2034 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2035                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2036 {
2037     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2038           ClientToken, Privileges, AccessGranted);
2039
2040     return TRUE;
2041 }
2042
2043 /******************************************************************************
2044  * GetSecurityInfo [ADVAPI32.@]
2045  */
2046 DWORD WINAPI GetSecurityInfo(
2047     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2048     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2049     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2050     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2051 )
2052 {
2053   FIXME("stub!\n");
2054   return ERROR_BAD_PROVIDER;
2055 }
2056
2057 /******************************************************************************
2058  * GetSecurityInfoExW [ADVAPI32.@]
2059  */
2060 DWORD WINAPI GetSecurityInfoExW(
2061         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2062         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2063         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2064         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2065 )
2066 {
2067   FIXME("stub!\n");
2068   return ERROR_BAD_PROVIDER; 
2069 }
2070
2071 /******************************************************************************
2072  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2073  */
2074 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2075                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2076                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2077 {
2078     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_a(pTrusteeName),
2079           AccessPermissions, AccessMode, Inheritance);
2080
2081     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2082     pExplicitAccess->grfAccessMode = AccessMode;
2083     pExplicitAccess->grfInheritance = Inheritance;
2084
2085     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2086     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2087     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2088     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2089     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2090 }
2091
2092 /******************************************************************************
2093  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2094  */
2095 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2096                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2097                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2098 {
2099     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_w(pTrusteeName),
2100           AccessPermissions, AccessMode, Inheritance);
2101
2102     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2103     pExplicitAccess->grfAccessMode = AccessMode;
2104     pExplicitAccess->grfInheritance = Inheritance;
2105
2106     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2107     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2108     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2109     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2110     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2111 }
2112
2113 /******************************************************************************
2114  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2115  */
2116 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2117                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2118                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2119 {
2120     DWORD ObjectsPresent = 0;
2121
2122     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2123           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2124
2125     /* Fill the OBJECTS_AND_NAME structure */
2126     pObjName->ObjectType = ObjectType;
2127     if (ObjectTypeName != NULL)
2128     {
2129         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2130     }
2131
2132     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2133     if (InheritedObjectTypeName != NULL)
2134     {
2135         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2136     }
2137
2138     pObjName->ObjectsPresent = ObjectsPresent;
2139     pObjName->ptstrName = Name;
2140
2141     /* Fill the TRUSTEE structure */
2142     pTrustee->pMultipleTrustee = NULL;
2143     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2144     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2145     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2146     pTrustee->ptstrName = (LPSTR)pObjName;
2147 }
2148
2149 /******************************************************************************
2150  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2151  */
2152 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2153                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2154                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2155 {
2156     DWORD ObjectsPresent = 0;
2157
2158     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2159           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2160
2161     /* Fill the OBJECTS_AND_NAME structure */
2162     pObjName->ObjectType = ObjectType;
2163     if (ObjectTypeName != NULL)
2164     {
2165         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2166     }
2167
2168     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2169     if (InheritedObjectTypeName != NULL)
2170     {
2171         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2172     }
2173
2174     pObjName->ObjectsPresent = ObjectsPresent;
2175     pObjName->ptstrName = Name;
2176
2177     /* Fill the TRUSTEE structure */
2178     pTrustee->pMultipleTrustee = NULL;
2179     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2180     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2181     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2182     pTrustee->ptstrName = (LPWSTR)pObjName;
2183 }
2184
2185 /******************************************************************************
2186  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2187  */
2188 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2189                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2190 {
2191     DWORD ObjectsPresent = 0;
2192
2193     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2194
2195     /* Fill the OBJECTS_AND_SID structure */
2196     if (pObjectGuid != NULL)
2197     {
2198         pObjSid->ObjectTypeGuid = *pObjectGuid;
2199         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2200     }
2201     else
2202     {
2203         ZeroMemory(&pObjSid->ObjectTypeGuid,
2204                    sizeof(GUID));
2205     }
2206
2207     if (pInheritedObjectGuid != NULL)
2208     {
2209         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2210         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2211     }
2212     else
2213     {
2214         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2215                    sizeof(GUID));
2216     }
2217
2218     pObjSid->ObjectsPresent = ObjectsPresent;
2219     pObjSid->pSid = pSid;
2220
2221     /* Fill the TRUSTEE structure */
2222     pTrustee->pMultipleTrustee = NULL;
2223     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2224     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2225     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2226     pTrustee->ptstrName = (LPSTR) pObjSid;
2227 }
2228
2229 /******************************************************************************
2230  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2231  */
2232 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2233                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2234 {
2235     DWORD ObjectsPresent = 0;
2236
2237     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2238
2239     /* Fill the OBJECTS_AND_SID structure */
2240     if (pObjectGuid != NULL)
2241     {
2242         pObjSid->ObjectTypeGuid = *pObjectGuid;
2243         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2244     }
2245     else
2246     {
2247         ZeroMemory(&pObjSid->ObjectTypeGuid,
2248                    sizeof(GUID));
2249     }
2250
2251     if (pInheritedObjectGuid != NULL)
2252     {
2253         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2254         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2255     }
2256     else
2257     {
2258         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2259                    sizeof(GUID));
2260     }
2261
2262     pObjSid->ObjectsPresent = ObjectsPresent;
2263     pObjSid->pSid = pSid;
2264
2265     /* Fill the TRUSTEE structure */
2266     pTrustee->pMultipleTrustee = NULL;
2267     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2268     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2269     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2270     pTrustee->ptstrName = (LPWSTR) pObjSid;
2271 }
2272
2273 /******************************************************************************
2274  * BuildTrusteeWithSidA [ADVAPI32.@]
2275  */
2276 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2277 {
2278     TRACE("%p %p\n", pTrustee, pSid);
2279
2280     pTrustee->pMultipleTrustee = NULL;
2281     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2282     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2283     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2284     pTrustee->ptstrName = (LPSTR) pSid;
2285 }
2286
2287 /******************************************************************************
2288  * BuildTrusteeWithSidW [ADVAPI32.@]
2289  */
2290 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2291 {
2292     TRACE("%p %p\n", pTrustee, pSid);
2293
2294     pTrustee->pMultipleTrustee = NULL;
2295     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2296     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2297     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2298     pTrustee->ptstrName = (LPWSTR) pSid;
2299 }
2300
2301 /******************************************************************************
2302  * BuildTrusteeWithNameA [ADVAPI32.@]
2303  */
2304 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2305 {
2306     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2307
2308     pTrustee->pMultipleTrustee = NULL;
2309     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2310     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2311     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2312     pTrustee->ptstrName = name;
2313 }
2314
2315 /******************************************************************************
2316  * BuildTrusteeWithNameW [ADVAPI32.@]
2317  */
2318 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2319 {
2320     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2321
2322     pTrustee->pMultipleTrustee = NULL;
2323     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2324     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2325     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2326     pTrustee->ptstrName = name;
2327 }
2328
2329 /****************************************************************************** 
2330  * GetTrusteeFormA [ADVAPI32.@] 
2331  */ 
2332 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
2333 {  
2334     TRACE("(%p)\n", pTrustee); 
2335   
2336     if (!pTrustee) 
2337         return TRUSTEE_BAD_FORM; 
2338   
2339     return pTrustee->TrusteeForm; 
2340 }  
2341   
2342 /****************************************************************************** 
2343  * GetTrusteeFormW [ADVAPI32.@] 
2344  */ 
2345 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
2346 {  
2347     TRACE("(%p)\n", pTrustee); 
2348   
2349     if (!pTrustee) 
2350         return TRUSTEE_BAD_FORM; 
2351   
2352     return pTrustee->TrusteeForm; 
2353 }  
2354   
2355 /****************************************************************************** 
2356  * GetTrusteeNameA [ADVAPI32.@] 
2357  */ 
2358 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
2359 {  
2360     TRACE("(%p)\n", pTrustee); 
2361   
2362     if (!pTrustee) 
2363         return NULL; 
2364   
2365     return pTrustee->ptstrName; 
2366 }  
2367   
2368 /****************************************************************************** 
2369  * GetTrusteeNameW [ADVAPI32.@] 
2370  */ 
2371 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
2372 {  
2373     TRACE("(%p)\n", pTrustee); 
2374   
2375     if (!pTrustee) 
2376         return NULL; 
2377   
2378     return pTrustee->ptstrName; 
2379 }  
2380   
2381 /****************************************************************************** 
2382  * GetTrusteeTypeA [ADVAPI32.@] 
2383  */ 
2384 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
2385 {  
2386     TRACE("(%p)\n", pTrustee); 
2387   
2388     if (!pTrustee) 
2389         return TRUSTEE_IS_UNKNOWN; 
2390   
2391     return pTrustee->TrusteeType; 
2392 }  
2393   
2394 /****************************************************************************** 
2395  * GetTrusteeTypeW [ADVAPI32.@] 
2396  */ 
2397 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
2398 {  
2399     TRACE("(%p)\n", pTrustee); 
2400   
2401     if (!pTrustee) 
2402         return TRUSTEE_IS_UNKNOWN; 
2403   
2404     return pTrustee->TrusteeType; 
2405
2406  
2407 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2408                                DWORD nAclInformationLength,
2409                                ACL_INFORMATION_CLASS dwAclInformationClass )
2410 {
2411     FIXME("%p %p 0x%08lx 0x%08x - stub\n", pAcl, pAclInformation,
2412           nAclInformationLength, dwAclInformationClass);
2413
2414     return TRUE;
2415 }
2416
2417 /******************************************************************************
2418  * SetEntriesInAclA [ADVAPI32.@]
2419  */
2420 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2421                                PACL OldAcl, PACL* NewAcl )
2422 {
2423     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2424     return ERROR_CALL_NOT_IMPLEMENTED;
2425 }
2426
2427 /******************************************************************************
2428  * SetEntriesInAclW [ADVAPI32.@]
2429  */
2430 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2431                                PACL OldAcl, PACL* NewAcl )
2432 {
2433     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2434     return ERROR_CALL_NOT_IMPLEMENTED;
2435 }
2436
2437 /******************************************************************************
2438  * SetNamedSecurityInfoA [ADVAPI32.@]
2439  */
2440 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2441         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2442         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2443 {
2444     DWORD len;
2445     LPWSTR wstr = NULL;
2446     DWORD r;
2447
2448     TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2449            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2450
2451     if( pObjectName )
2452     {
2453         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2454         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2455         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2456     }
2457
2458     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2459                            psidGroup, pDacl, pSacl );
2460
2461     HeapFree( GetProcessHeap(), 0, wstr );
2462
2463     return r;
2464 }
2465
2466 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2467     PSECURITY_DESCRIPTOR ModificationDescriptor,
2468     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2469     PGENERIC_MAPPING GenericMapping,
2470     HANDLE Token )
2471 {
2472     FIXME("0x%08lx %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2473           ObjectsSecurityDescriptor, GenericMapping, Token);
2474
2475     return TRUE;
2476 }
2477
2478 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2479   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2480   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2481 {
2482     FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2483           ControlBitsToSet);
2484
2485     return TRUE;
2486 }
2487
2488 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2489 {
2490     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2491 }
2492
2493 /******************************************************************************
2494  * AreAnyAccessesGranted [ADVAPI32.@]
2495  *
2496  * Determines whether or not any of a set of specified access permissions have
2497  * been granted or not.
2498  *
2499  * PARAMS
2500  *   GrantedAccess [I] The permissions that have been granted.
2501  *   DesiredAccess [I] The permissions that you want to have.
2502  *
2503  * RETURNS
2504  *   Nonzero if any of the permissions have been granted, zero if none of the
2505  *   permissions have been granted.
2506  */
2507
2508 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2509 {
2510     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
2511 }
2512
2513 /******************************************************************************
2514  * SetNamedSecurityInfoW [ADVAPI32.@]
2515  */
2516 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
2517         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2518         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2519 {
2520     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
2521            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2522     return ERROR_SUCCESS;
2523 }
2524
2525 /******************************************************************************
2526  * GetExplicitEntriesFromAclA [ADVAPI32.@]
2527  */
2528 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
2529         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
2530 {
2531     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2532     return ERROR_CALL_NOT_IMPLEMENTED;
2533 }
2534
2535 /******************************************************************************
2536  * GetExplicitEntriesFromAclW [ADVAPI32.@]
2537  */
2538 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
2539         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
2540 {
2541     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2542     return ERROR_CALL_NOT_IMPLEMENTED;
2543 }
2544
2545
2546 /******************************************************************************
2547  * ParseAclStringFlags
2548  */
2549 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2550 {
2551     DWORD flags = 0;
2552     LPCWSTR szAcl = *StringAcl;
2553
2554     while (*szAcl != '(')
2555     {
2556         if (*szAcl == 'P')
2557         {
2558             flags |= SE_DACL_PROTECTED;
2559         }
2560         else if (*szAcl == 'A')
2561         {
2562             szAcl++;
2563             if (*szAcl == 'R')
2564                 flags |= SE_DACL_AUTO_INHERIT_REQ;
2565             else if (*szAcl == 'I')
2566                 flags |= SE_DACL_AUTO_INHERITED;
2567         }
2568         szAcl++;
2569     }
2570
2571     *StringAcl = szAcl;
2572     return flags;
2573 }
2574
2575 /******************************************************************************
2576  * ParseAceStringType
2577  */
2578 static const ACEFLAG AceType[] =
2579 {
2580     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2581     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
2582     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
2583     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
2584     /*
2585     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2586     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
2587     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
2588     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2589     */
2590     { NULL, 0 },
2591 };
2592
2593 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2594 {
2595     UINT len = 0;
2596     LPCWSTR szAcl = *StringAcl;
2597     const ACEFLAG *lpaf = AceType;
2598
2599     while (lpaf->wstr &&
2600         (len = strlenW(lpaf->wstr)) &&
2601         strncmpW(lpaf->wstr, szAcl, len))
2602         lpaf++;
2603
2604     if (!lpaf->wstr)
2605         return 0;
2606
2607     *StringAcl += len;
2608     return lpaf->value;
2609 }
2610
2611
2612 /******************************************************************************
2613  * ParseAceStringFlags
2614  */
2615 static const ACEFLAG AceFlags[] =
2616 {
2617     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2618     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
2619     { SDDL_INHERITED,         INHERITED_ACE },
2620     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
2621     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
2622     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
2623     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
2624     { NULL, 0 },
2625 };
2626
2627 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2628 {
2629     UINT len = 0;
2630     BYTE flags = 0;
2631     LPCWSTR szAcl = *StringAcl;
2632
2633     while (*szAcl != ';')
2634     {
2635         const ACEFLAG *lpaf = AceFlags;
2636
2637         while (lpaf->wstr &&
2638                (len = strlenW(lpaf->wstr)) &&
2639                strncmpW(lpaf->wstr, szAcl, len))
2640             lpaf++;
2641
2642         if (!lpaf->wstr)
2643             return 0;
2644
2645         flags |= lpaf->value;
2646         szAcl += len;
2647     }
2648
2649     *StringAcl = szAcl;
2650     return flags;
2651 }
2652
2653
2654 /******************************************************************************
2655  * ParseAceStringRights
2656  */
2657 static const ACEFLAG AceRights[] =
2658 {
2659     { SDDL_GENERIC_ALL,     GENERIC_ALL },
2660     { SDDL_GENERIC_READ,    GENERIC_READ },
2661     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
2662     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2663     { SDDL_READ_CONTROL,    READ_CONTROL },
2664     { SDDL_STANDARD_DELETE, DELETE },
2665     { SDDL_WRITE_DAC,       WRITE_DAC },
2666     { SDDL_WRITE_OWNER,     WRITE_OWNER },
2667     { NULL, 0 },
2668 };
2669
2670 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2671 {
2672     UINT len = 0;
2673     DWORD rights = 0;
2674     LPCWSTR szAcl = *StringAcl;
2675
2676     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2677     {
2678         LPCWSTR p = szAcl;
2679
2680         while (*p && *p != ';')
2681             p++;
2682
2683         if (p - szAcl <= 8)
2684         {
2685             rights = strtoulW(szAcl, NULL, 16);
2686             *StringAcl = p;
2687         }
2688         else
2689             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2690     }
2691     else
2692     {
2693         while (*szAcl != ';')
2694         {
2695             const ACEFLAG *lpaf = AceRights;
2696
2697             while (lpaf->wstr &&
2698                (len = strlenW(lpaf->wstr)) &&
2699                strncmpW(lpaf->wstr, szAcl, len))
2700             {
2701                lpaf++;
2702             }
2703
2704             if (!lpaf->wstr)
2705                 return 0;
2706
2707             rights |= lpaf->value;
2708             szAcl += len;
2709         }
2710     }
2711
2712     *StringAcl = szAcl;
2713     return rights;
2714 }
2715
2716
2717 /******************************************************************************
2718  * ParseStringAclToAcl
2719  * 
2720  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
2721  */
2722 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
2723     PACL pAcl, LPDWORD cBytes)
2724 {
2725     DWORD val;
2726     DWORD sidlen;
2727     DWORD length = sizeof(ACL);
2728     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
2729
2730     TRACE("%s\n", debugstr_w(StringAcl));
2731
2732     if (!StringAcl)
2733         return FALSE;
2734
2735     if (pAcl) /* pAce is only useful if we're setting values */
2736         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
2737
2738     /* Parse ACL flags */
2739     *lpdwFlags = ParseAclStringFlags(&StringAcl);
2740
2741     /* Parse ACE */
2742     while (*StringAcl == '(')
2743     {
2744         StringAcl++;
2745
2746         /* Parse ACE type */
2747         val = ParseAceStringType(&StringAcl);
2748         if (pAce)
2749             pAce->Header.AceType = (BYTE) val;
2750         if (*StringAcl != ';')
2751             goto lerr;
2752         StringAcl++;
2753
2754         /* Parse ACE flags */
2755         val = ParseAceStringFlags(&StringAcl);
2756         if (pAce)
2757             pAce->Header.AceFlags = (BYTE) val;
2758         if (*StringAcl != ';')
2759             goto lerr;
2760         StringAcl++;
2761
2762         /* Parse ACE rights */
2763         val = ParseAceStringRights(&StringAcl);
2764         if (pAce)
2765             pAce->Mask = val;
2766         if (*StringAcl != ';')
2767             goto lerr;
2768         StringAcl++;
2769
2770         /* Parse ACE object guid */
2771         if (*StringAcl != ';')
2772         {
2773             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2774             goto lerr;
2775         }
2776         StringAcl++;
2777
2778         /* Parse ACE inherit object guid */
2779         if (*StringAcl != ';')
2780         {
2781             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2782             goto lerr;
2783         }
2784         StringAcl++;
2785
2786         /* Parse ACE account sid */
2787         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
2788         {
2789             while (*StringAcl && *StringAcl != ')')
2790                 StringAcl++;
2791         }
2792
2793         if (*StringAcl != ')')
2794             goto lerr;
2795         StringAcl++;
2796
2797         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
2798     }
2799
2800     *cBytes = length;
2801     return TRUE;
2802
2803 lerr:
2804     WARN("Invalid ACE string format\n");
2805     return FALSE;
2806 }
2807
2808
2809 /******************************************************************************
2810  * ParseStringSecurityDescriptorToSecurityDescriptor
2811  */
2812 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
2813     LPCWSTR StringSecurityDescriptor,
2814     SECURITY_DESCRIPTOR* SecurityDescriptor,
2815     LPDWORD cBytes)
2816 {
2817     BOOL bret = FALSE;
2818     WCHAR toktype;
2819     WCHAR tok[MAX_PATH];
2820     LPCWSTR lptoken;
2821     LPBYTE lpNext = NULL;
2822     DWORD len;
2823
2824     *cBytes = 0;
2825
2826     if (SecurityDescriptor)
2827         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
2828
2829     while (*StringSecurityDescriptor)
2830     {
2831         toktype = *StringSecurityDescriptor;
2832
2833         /* Expect char identifier followed by ':' */
2834         StringSecurityDescriptor++;
2835         if (*StringSecurityDescriptor != ':')
2836         {
2837             SetLastError(ERROR_INVALID_PARAMETER);
2838             goto lend;
2839         }
2840         StringSecurityDescriptor++;
2841
2842         /* Extract token */
2843         lptoken = StringSecurityDescriptor;
2844         while (*lptoken && *lptoken != ':')
2845             lptoken++;
2846
2847         if (*lptoken)
2848             lptoken--;
2849
2850         len = lptoken - StringSecurityDescriptor;
2851         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
2852         tok[len] = 0;
2853
2854         switch (toktype)
2855         {
2856             case 'O':
2857             {
2858                 DWORD bytes;
2859
2860                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2861                     goto lend;
2862
2863                 if (SecurityDescriptor)
2864                 {
2865                     SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
2866                     lpNext += bytes; /* Advance to next token */
2867                 }
2868
2869                 *cBytes += bytes;
2870
2871                 break;
2872             }
2873
2874             case 'G':
2875             {
2876                 DWORD bytes;
2877
2878                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2879                     goto lend;
2880
2881                 if (SecurityDescriptor)
2882                 {
2883                     SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
2884                     lpNext += bytes; /* Advance to next token */
2885                 }
2886
2887                 *cBytes += bytes;
2888
2889                 break;
2890             }
2891
2892             case 'D':
2893             {
2894                 DWORD flags;
2895                 DWORD bytes;
2896
2897                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2898                     goto lend;
2899
2900                 if (SecurityDescriptor)
2901                 {
2902                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
2903                     SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
2904                     lpNext += bytes; /* Advance to next token */
2905                 }
2906
2907                 *cBytes += bytes;
2908
2909                 break;
2910             }
2911
2912             case 'S':
2913             {
2914                 DWORD flags;
2915                 DWORD bytes;
2916
2917                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2918                     goto lend;
2919
2920                 if (SecurityDescriptor)
2921                 {
2922                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
2923                     SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
2924                     lpNext += bytes; /* Advance to next token */
2925                 }
2926
2927                 *cBytes += bytes;
2928
2929                 break;
2930             }
2931
2932             default:
2933                 FIXME("Unknown token\n");
2934                 SetLastError(ERROR_INVALID_PARAMETER);
2935                 goto lend;
2936         }
2937
2938         StringSecurityDescriptor = lptoken;
2939     }
2940
2941     bret = TRUE;
2942
2943 lend:
2944     return bret;
2945 }
2946
2947 /******************************************************************************
2948  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2949  */
2950 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
2951         LPCSTR StringSecurityDescriptor,
2952         DWORD StringSDRevision,
2953         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2954         PULONG SecurityDescriptorSize)
2955 {
2956     UINT len;
2957     BOOL ret = FALSE;
2958     LPWSTR StringSecurityDescriptorW;
2959
2960     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
2961     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2962
2963     if (StringSecurityDescriptorW)
2964     {
2965         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
2966
2967         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
2968                                                                    StringSDRevision, SecurityDescriptor,
2969                                                                    SecurityDescriptorSize);
2970         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
2971     }
2972
2973     return ret;
2974 }
2975
2976 /******************************************************************************
2977  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2978  */
2979 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2980         LPCWSTR StringSecurityDescriptor,
2981         DWORD StringSDRevision,
2982         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2983         PULONG SecurityDescriptorSize)
2984 {
2985     DWORD cBytes;
2986     SECURITY_DESCRIPTOR* psd;
2987     BOOL bret = FALSE;
2988
2989     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2990
2991     if (GetVersion() & 0x80000000)
2992     {
2993         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2994         goto lend;
2995     }
2996     else if (StringSDRevision != SID_REVISION)
2997     {
2998         SetLastError(ERROR_UNKNOWN_REVISION);
2999         goto lend;
3000     }
3001
3002     /* Compute security descriptor length */
3003     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3004         NULL, &cBytes))
3005         goto lend;
3006
3007     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3008         GMEM_ZEROINIT, cBytes);
3009
3010     psd->Revision = SID_REVISION;
3011     psd->Control |= SE_SELF_RELATIVE;
3012
3013     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3014         psd, &cBytes))
3015     {
3016         LocalFree(psd);
3017         goto lend;
3018     }
3019
3020     if (SecurityDescriptorSize)
3021         *SecurityDescriptorSize = cBytes;
3022
3023     bret = TRUE;
3024  
3025 lend:
3026     TRACE(" ret=%d\n", bret);
3027     return bret;
3028 }
3029
3030 /******************************************************************************
3031  * ConvertStringSidToSidW [ADVAPI32.@]
3032  */
3033 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3034 {
3035     BOOL bret = FALSE;
3036     DWORD cBytes;
3037
3038     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3039     if (GetVersion() & 0x80000000)
3040         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3041     else if (!StringSid || !Sid)
3042         SetLastError(ERROR_INVALID_PARAMETER);
3043     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3044     {
3045         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
3046
3047         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3048         if (!bret)
3049             LocalFree(*Sid); 
3050     }
3051     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3052     return bret;
3053 }
3054
3055 /******************************************************************************
3056  * ConvertStringSidToSidA [ADVAPI32.@]
3057  */
3058 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3059 {
3060     BOOL bret = FALSE;
3061
3062     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3063     if (GetVersion() & 0x80000000)
3064         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3065     else if (!StringSid || !Sid)
3066         SetLastError(ERROR_INVALID_PARAMETER);
3067     else
3068     {
3069         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
3070         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
3071          len * sizeof(WCHAR));
3072
3073         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
3074         bret = ConvertStringSidToSidW(wStringSid, Sid);
3075         HeapFree(GetProcessHeap(), 0, wStringSid);
3076     }
3077     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3078     return bret;
3079 }
3080
3081 /******************************************************************************
3082  * ConvertSidToStringSidW [ADVAPI32.@]
3083  *
3084  *  format of SID string is:
3085  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3086  *  where
3087  *    <rev> is the revision of the SID encoded as decimal
3088  *    <auth> is the identifier authority encoded as hex
3089  *    <subauthN> is the subauthority id encoded as decimal
3090  */
3091 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
3092 {
3093     DWORD sz, i;
3094     LPWSTR str;
3095     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3096     WCHAR subauthfmt[] = { '-','%','u',0 };
3097     SID* pisid=pSid;
3098
3099     TRACE("%p %p\n", pSid, pstr );
3100
3101     if( !IsValidSid( pSid ) )
3102         return FALSE;
3103
3104     if (pisid->Revision != SDDL_REVISION)
3105         return FALSE;
3106     if (pisid->IdentifierAuthority.Value[0] ||
3107      pisid->IdentifierAuthority.Value[1])
3108     {
3109         FIXME("not matching MS' bugs\n");
3110         return FALSE;
3111     }
3112
3113     sz = 14 + pisid->SubAuthorityCount * 11;
3114     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
3115     sprintfW( str, fmt, pisid->Revision, MAKELONG(
3116      MAKEWORD( pisid->IdentifierAuthority.Value[5],
3117      pisid->IdentifierAuthority.Value[4] ),
3118      MAKEWORD( pisid->IdentifierAuthority.Value[3],
3119      pisid->IdentifierAuthority.Value[2] ) ) );
3120     for( i=0; i<pisid->SubAuthorityCount; i++ )
3121         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
3122     *pstr = str;
3123
3124     return TRUE;
3125 }
3126
3127 /******************************************************************************
3128  * ConvertSidToStringSidA [ADVAPI32.@]
3129  */
3130 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
3131 {
3132     LPWSTR wstr = NULL;
3133     LPSTR str;
3134     UINT len;
3135
3136     TRACE("%p %p\n", pSid, pstr );
3137
3138     if( !ConvertSidToStringSidW( pSid, &wstr ) )
3139         return FALSE;
3140
3141     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
3142     str = LocalAlloc( 0, len );
3143     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
3144     LocalFree( wstr );
3145
3146     *pstr = str;
3147
3148     return TRUE;
3149 }
3150
3151 BOOL WINAPI CreatePrivateObjectSecurity(
3152         PSECURITY_DESCRIPTOR ParentDescriptor,
3153         PSECURITY_DESCRIPTOR CreatorDescriptor,
3154         PSECURITY_DESCRIPTOR* NewDescriptor,
3155         BOOL IsDirectoryObject,
3156         HANDLE Token,
3157         PGENERIC_MAPPING GenericMapping )
3158 {
3159     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
3160           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
3161
3162     return FALSE;
3163 }
3164
3165 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
3166 {
3167     FIXME("%p - stub\n", ObjectDescriptor);
3168
3169     return TRUE;
3170 }
3171
3172 BOOL WINAPI CreateProcessAsUserA(
3173         HANDLE hToken,
3174         LPCSTR lpApplicationName,
3175         LPSTR lpCommandLine,
3176         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3177         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3178         BOOL bInheritHandles,
3179         DWORD dwCreationFlags,
3180         LPVOID lpEnvironment,
3181         LPCSTR lpCurrentDirectory,
3182         LPSTARTUPINFOA lpStartupInfo,
3183         LPPROCESS_INFORMATION lpProcessInformation )
3184 {
3185     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
3186           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3187           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3188
3189     return FALSE;
3190 }
3191
3192 BOOL WINAPI CreateProcessAsUserW(
3193         HANDLE hToken,
3194         LPCWSTR lpApplicationName,
3195         LPWSTR lpCommandLine,
3196         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3197         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3198         BOOL bInheritHandles,
3199         DWORD dwCreationFlags,
3200         LPVOID lpEnvironment,
3201         LPCWSTR lpCurrentDirectory,
3202         LPSTARTUPINFOW lpStartupInfo,
3203         LPPROCESS_INFORMATION lpProcessInformation )
3204 {
3205     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - semi- stub\n", hToken, 
3206           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
3207           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
3208           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3209
3210     /* We should create the process with a suspended main thread */
3211     if (!CreateProcessW (lpApplicationName,
3212                          lpCommandLine,
3213                          lpProcessAttributes,
3214                          lpThreadAttributes,
3215                          bInheritHandles,
3216                          dwCreationFlags, /* CREATE_SUSPENDED */
3217                          lpEnvironment,
3218                          lpCurrentDirectory,
3219                          lpStartupInfo,
3220                          lpProcessInformation))
3221     {
3222       return FALSE;
3223     }
3224
3225     return TRUE;
3226 }
3227
3228 BOOL WINAPI DuplicateTokenEx(
3229         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
3230         LPSECURITY_ATTRIBUTES lpTokenAttributes,
3231         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3232         TOKEN_TYPE TokenType,
3233         PHANDLE DuplicateTokenHandle )
3234 {
3235     OBJECT_ATTRIBUTES ObjectAttributes;
3236
3237     TRACE("%p 0x%08lx 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3238           ImpersonationLevel, TokenType, DuplicateTokenHandle);
3239
3240     InitializeObjectAttributes(
3241         &ObjectAttributes,
3242         NULL,
3243         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
3244         NULL,
3245         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
3246
3247     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
3248                                            dwDesiredAccess,
3249                                            &ObjectAttributes,
3250                                            ImpersonationLevel,
3251                                            TokenType,
3252                                            DuplicateTokenHandle ) );
3253 }
3254
3255 BOOL WINAPI DuplicateToken(
3256         HANDLE ExistingTokenHandle,
3257         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3258         PHANDLE DuplicateTokenHandle )
3259 {
3260     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
3261                              NULL, ImpersonationLevel, TokenImpersonation,
3262                              DuplicateTokenHandle );
3263 }
3264
3265 BOOL WINAPI EnumDependentServicesA(
3266         SC_HANDLE hService,
3267         DWORD dwServiceState,
3268         LPENUM_SERVICE_STATUSA lpServices,
3269         DWORD cbBufSize,
3270         LPDWORD pcbBytesNeeded,
3271         LPDWORD lpServicesReturned )
3272 {
3273     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3274           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3275
3276     return FALSE;
3277 }
3278
3279 BOOL WINAPI EnumDependentServicesW(
3280         SC_HANDLE hService,
3281         DWORD dwServiceState,
3282         LPENUM_SERVICE_STATUSW lpServices,
3283         DWORD cbBufSize,
3284         LPDWORD pcbBytesNeeded,
3285         LPDWORD lpServicesReturned )
3286 {
3287     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3288           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3289
3290     return FALSE;
3291 }
3292
3293 static const WELLKNOWNSID WellKnownSids[] =
3294 {
3295     { {'W','D'}, { SECURITY_WORLD_SID_AUTHORITY }, 1, { SECURITY_WORLD_RID } },
3296     { {'B','A'}, { SECURITY_NT_AUTHORITY }, 2, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_GROUP_RID_ADMINS } },
3297     { {'B','G'}, { SECURITY_NT_AUTHORITY }, 2, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_GROUP_RID_GUESTS } },
3298     { {'B','U'}, { SECURITY_NT_AUTHORITY }, 2, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_GROUP_RID_USERS } },
3299     { {'I','U'}, { SECURITY_NT_AUTHORITY }, 1, { SECURITY_INTERACTIVE_RID } },
3300     { {'L','S'}, { SECURITY_NT_AUTHORITY }, 1, { SECURITY_SERVICE_RID } },
3301     { {'S','Y'}, { SECURITY_NT_AUTHORITY }, 1, { SECURITY_LOCAL_SYSTEM_RID } },
3302 };
3303
3304 /******************************************************************************
3305  * ComputeStringSidSize
3306  */
3307 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3308 {
3309     DWORD size = sizeof(SID);
3310
3311     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3312     {
3313         int ctok = 0;
3314         while (*StringSid)
3315         {
3316             if (*StringSid == '-')
3317                 ctok++;
3318             StringSid++;
3319         }
3320
3321         if (ctok > 3)
3322             size += (ctok - 3) * sizeof(DWORD);
3323     }
3324     else /* String constant format  - Only available in winxp and above */
3325     {
3326         int i;
3327
3328         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3329             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3330                 size += (WellKnownSids[i].nSubAuthorityCount - 1) * sizeof(DWORD);
3331     }
3332
3333     return size;
3334 }
3335
3336 /******************************************************************************
3337  * ParseStringSidToSid
3338  */
3339 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3340 {
3341     BOOL bret = FALSE;
3342     SID* pisid=pSid;
3343
3344     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3345     if (!StringSid)
3346     {
3347         SetLastError(ERROR_INVALID_PARAMETER);
3348         TRACE("StringSid is NULL, returning FALSE\n");
3349         return FALSE;
3350     }
3351
3352     *cBytes = ComputeStringSidSize(StringSid);
3353     if (!pisid) /* Simply compute the size */
3354     {
3355         TRACE("only size requested, returning TRUE\n");
3356         return TRUE;
3357     }
3358
3359     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3360     {
3361         DWORD i = 0, identAuth;
3362         DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
3363
3364         StringSid += 2; /* Advance to Revision */
3365         pisid->Revision = atoiW(StringSid);
3366
3367         if (pisid->Revision != SDDL_REVISION)
3368         {
3369             TRACE("Revision %d is unknown\n", pisid->Revision);
3370             goto lend; /* ERROR_INVALID_SID */
3371         }
3372         if (csubauth == 0)
3373         {
3374             TRACE("SubAuthorityCount is 0\n");
3375             goto lend; /* ERROR_INVALID_SID */
3376         }
3377
3378         pisid->SubAuthorityCount = csubauth;
3379
3380         /* Advance to identifier authority */
3381         while (*StringSid && *StringSid != '-')
3382             StringSid++;
3383         if (*StringSid == '-')
3384             StringSid++;
3385
3386         /* MS' implementation can't handle values greater than 2^32 - 1, so
3387          * we don't either; assume most significant bytes are always 0
3388          */
3389         pisid->IdentifierAuthority.Value[0] = 0;
3390         pisid->IdentifierAuthority.Value[1] = 0;
3391         identAuth = atoiW(StringSid);
3392         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3393         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3394         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3395         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3396
3397         /* Advance to first sub authority */
3398         while (*StringSid && *StringSid != '-')
3399             StringSid++;
3400         if (*StringSid == '-')
3401             StringSid++;
3402
3403         while (*StringSid)
3404         {
3405             while (*StringSid && *StringSid != '-')
3406                 StringSid++;
3407             if (*StringSid == '-')
3408                 StringSid++;
3409
3410             pisid->SubAuthority[i++] = atoiW(StringSid);
3411         }
3412
3413         if (i != pisid->SubAuthorityCount)
3414             goto lend; /* ERROR_INVALID_SID */
3415
3416         bret = TRUE;
3417     }
3418     else /* String constant format  - Only available in winxp and above */
3419     {
3420         int i;
3421         pisid->Revision = SDDL_REVISION;
3422
3423         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3424             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3425             {
3426                 DWORD j;
3427                 pisid->SubAuthorityCount = WellKnownSids[i].nSubAuthorityCount;
3428                 pisid->IdentifierAuthority = WellKnownSids[i].auth;
3429                 for (j = 0; j < WellKnownSids[i].nSubAuthorityCount; j++)
3430                     pisid->SubAuthority[j] = WellKnownSids[i].SubAuthority[j];
3431                 bret = TRUE;
3432             }
3433
3434         if (!bret)
3435             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3436     }
3437
3438 lend:
3439     if (!bret)
3440         SetLastError(ERROR_INVALID_SID);
3441
3442     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3443     return bret;
3444 }
3445
3446 /******************************************************************************
3447  * GetNamedSecurityInfoA [ADVAPI32.@]
3448  */
3449 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
3450         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3451         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3452         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3453 {
3454     DWORD len;
3455     LPWSTR wstr = NULL;
3456     DWORD r;
3457
3458     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3459         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3460
3461     if( pObjectName )
3462     {
3463         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3464         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3465         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3466     }
3467
3468     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3469                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3470
3471     HeapFree( GetProcessHeap(), 0, wstr );
3472
3473     return r;
3474 }
3475
3476 /******************************************************************************
3477  * GetNamedSecurityInfoW [ADVAPI32.@]
3478  */
3479 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
3480     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
3481     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
3482 {
3483     DWORD needed, offset;
3484     SECURITY_DESCRIPTOR_RELATIVE *relative;
3485     BYTE *buffer;
3486
3487     TRACE( "%s %d %ld %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
3488            group, dacl, sacl, descriptor );
3489
3490     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
3491
3492     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3493     if (info & OWNER_SECURITY_INFORMATION)
3494         needed += sizeof(sidWorld);
3495     if (info & GROUP_SECURITY_INFORMATION)
3496         needed += sizeof(sidWorld);
3497     if (info & DACL_SECURITY_INFORMATION)
3498         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3499     if (info & SACL_SECURITY_INFORMATION)
3500         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3501
3502     /* must be freed by caller */
3503     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
3504     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
3505
3506     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
3507     {
3508         HeapFree( GetProcessHeap(), 0, *descriptor );
3509         return ERROR_INVALID_SECURITY_DESCR;
3510     }
3511
3512     relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
3513     relative->Control |= SE_SELF_RELATIVE;
3514     buffer = (BYTE *)relative;
3515     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3516
3517     if (owner && (info & OWNER_SECURITY_INFORMATION))
3518     {
3519         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3520         relative->Owner = offset;
3521         *owner = buffer + offset;
3522         offset += sizeof(sidWorld);
3523     }
3524     if (group && (info & GROUP_SECURITY_INFORMATION))
3525     {
3526         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3527         relative->Group = offset;
3528         *group = buffer + offset;
3529         offset += sizeof(sidWorld);
3530     }
3531     if (dacl && (info & DACL_SECURITY_INFORMATION))
3532     {
3533         GetWorldAccessACL( (PACL)(buffer + offset) );
3534         relative->Dacl = offset;
3535         *dacl = (PACL)(buffer + offset);
3536         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3537     }
3538     if (sacl && (info & SACL_SECURITY_INFORMATION))
3539     {
3540         GetWorldAccessACL( (PACL)(buffer + offset) );
3541         relative->Sacl = offset;
3542         *sacl = (PACL)(buffer + offset);
3543     }
3544     return ERROR_SUCCESS;
3545 }
3546
3547 /******************************************************************************
3548  * DecryptFileW [ADVAPI32.@]
3549  */
3550 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
3551 {
3552     FIXME("%s %08lx\n", debugstr_w(lpFileName), dwReserved);
3553     return TRUE;
3554 }
3555
3556 /******************************************************************************
3557  * DecryptFileA [ADVAPI32.@]
3558  */
3559 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
3560 {
3561     FIXME("%s %08lx\n", debugstr_a(lpFileName), dwReserved);
3562     return TRUE;
3563 }
3564
3565 /******************************************************************************
3566  * EncryptFileW [ADVAPI32.@]
3567  */
3568 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
3569 {
3570     FIXME("%s\n", debugstr_w(lpFileName));
3571     return TRUE;
3572 }
3573
3574 /******************************************************************************
3575  * EncryptFileA [ADVAPI32.@]
3576  */
3577 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
3578 {
3579     FIXME("%s\n", debugstr_a(lpFileName));
3580     return TRUE;
3581 }
3582
3583 /******************************************************************************
3584  * FileEncryptionStatusW [ADVAPI32.@]
3585  */
3586 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
3587 {
3588     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
3589     if (!lpStatus)
3590         return FALSE;
3591     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
3592     return TRUE;
3593 }
3594
3595 /******************************************************************************
3596  * FileEncryptionStatusA [ADVAPI32.@]
3597  */
3598 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
3599 {
3600     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
3601     if (!lpStatus)
3602         return FALSE;
3603     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
3604     return TRUE;
3605 }
3606
3607 /******************************************************************************
3608  * SetSecurityInfo [ADVAPI32.@]
3609  */
3610 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
3611                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
3612                       PSID psidGroup, PACL pDacl, PACL pSacl) {
3613     FIXME("stub\n");
3614     return ERROR_SUCCESS;
3615 }