Implement A->W call for GetNamedSecurityInfo.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  *
19  *  FIXME: for all functions thunking down to Rtl* functions:  implement SetLastError()
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24
25 #include "windef.h"
26 #include "winbase.h"
27 #include "winerror.h"
28 #include "rpcnterr.h"
29 #include "winreg.h"
30 #include "winternl.h"
31 #include "ntstatus.h"
32 #include "ntsecapi.h"
33 #include "accctrl.h"
34 #include "sddl.h"
35
36 #include "aclapi.h"
37
38 #include "wine/debug.h"
39 #include "wine/unicode.h"
40
41 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
42
43 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
44 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
45     PACL pAcl, LPDWORD cBytes);
46 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
47 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
48 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
49 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
50     LPCWSTR StringSecurityDescriptor,
51     PSECURITY_DESCRIPTOR SecurityDescriptor, 
52     LPDWORD cBytes);
53 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
54
55 typedef struct _ACEFLAG
56 {
57    LPCWSTR wstr;
58    DWORD value;
59 } ACEFLAG, *LPACEFLAG;
60
61 /*
62  * ACE access rights
63  */
64 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
65 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
66 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
67 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
68 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
69 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
70 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
71 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
72
73 /*
74  * ACE types
75  */
76 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
77 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
78 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
79 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
80 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
81 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
82 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
83 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
84
85 /*
86  * ACE flags
87  */
88 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
89 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
90 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
91 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
92 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
93 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
94 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
95
96 #define CallWin32ToNt(func) \
97         { NTSTATUS ret; \
98           ret = (func); \
99           if (ret !=STATUS_SUCCESS) \
100           { SetLastError (RtlNtStatusToDosError(ret)); return FALSE; } \
101           return TRUE; \
102         }
103
104 static void dumpLsaAttributes( PLSA_OBJECT_ATTRIBUTES oa )
105 {
106         if (oa)
107         {
108           TRACE("\n\tlength=%lu, rootdir=%p, objectname=%s\n\tattr=0x%08lx, sid=%p qos=%p\n",
109                 oa->Length, oa->RootDirectory,
110                 oa->ObjectName?debugstr_w(oa->ObjectName->Buffer):"null",
111                 oa->Attributes, oa->SecurityDescriptor, oa->SecurityQualityOfService);
112         }
113 }
114
115 /************************************************************
116  *                ADVAPI_IsLocalComputer
117  *
118  * Checks whether the server name indicates local machine.
119  */
120 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
121 {
122     if (!ServerName)
123     {
124         return TRUE;
125     }
126     else
127     {
128         DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
129         BOOL Result;
130         LPWSTR buf;
131
132         buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
133         Result = GetComputerNameW(buf,  &dwSize);
134         if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
135             ServerName += 2;
136         Result = Result && !lstrcmpW(ServerName, buf);
137         HeapFree(GetProcessHeap(), 0, buf);
138
139         return Result;
140     }
141 }
142
143 #define ADVAPI_ForceLocalComputer(ServerName, FailureCode) \
144     if (!ADVAPI_IsLocalComputer(ServerName)) \
145     { \
146         FIXME("Action Implemented for local computer only. " \
147               "Requested for server %s\n", debugstr_w(ServerName)); \
148         return FailureCode; \
149     }
150
151 /*      ##############################
152         ######  TOKEN FUNCTIONS ######
153         ##############################
154 */
155
156 /******************************************************************************
157  * OpenProcessToken                     [ADVAPI32.@]
158  * Opens the access token associated with a process handle.
159  *
160  * PARAMS
161  *   ProcessHandle [I] Handle to process
162  *   DesiredAccess [I] Desired access to process
163  *   TokenHandle   [O] Pointer to handle of open access token
164  *
165  * RETURNS
166  *  Success: TRUE. TokenHandle contains the access token.
167  *  Failure: FALSE.
168  *
169  * NOTES
170  *  See NtOpenProcessToken.
171  */
172 BOOL WINAPI
173 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
174                   HANDLE *TokenHandle )
175 {
176         CallWin32ToNt(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
177 }
178
179 /******************************************************************************
180  * OpenThreadToken [ADVAPI32.@]
181  *
182  * Opens the access token associated with a thread handle.
183  *
184  * PARAMS
185  *   ThreadHandle  [I] Handle to process
186  *   DesiredAccess [I] Desired access to the thread
187  *   OpenAsSelf    [I] ???
188  *   TokenHandle   [O] Destination for the token handle
189  *
190  * RETURNS
191  *  Success: TRUE. TokenHandle contains the access token.
192  *  Failure: FALSE.
193  *
194  * NOTES
195  *  See NtOpenThreadToken.
196  */
197 BOOL WINAPI
198 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
199                  BOOL OpenAsSelf, HANDLE *TokenHandle)
200 {
201         CallWin32ToNt (NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
202 }
203
204 /******************************************************************************
205  * AdjustTokenPrivileges [ADVAPI32.@]
206  *
207  * Adjust the privileges of an open token handle.
208  * 
209  * PARAMS
210  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
211  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
212  *  NewState             [I]   Desired new privileges of the token
213  *  BufferLength         [I]   Length of NewState
214  *  PreviousState        [O]   Destination for the previous state
215  *  ReturnLength         [I/O] Size of PreviousState
216  *
217  *
218  * RETURNS
219  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
220  *  Failure: FALSE.
221  *
222  * NOTES
223  *  See NtAdjustPrivilegesToken.
224  */
225 BOOL WINAPI
226 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
227                        LPVOID NewState, DWORD BufferLength,
228                        LPVOID PreviousState, LPDWORD ReturnLength )
229 {
230         CallWin32ToNt(NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength));
231 }
232
233 /******************************************************************************
234  * CheckTokenMembership [ADVAPI32.@]
235  *
236  * Determine if an access token is a member of a SID.
237  * 
238  * PARAMS
239  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
240  *   SidToCheck  [I] SID that possibly contains the token
241  *   IsMember    [O] Destination for result.
242  *
243  * RETURNS
244  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
245  *  Failure: FALSE.
246  */
247 BOOL WINAPI
248 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
249                       PBOOL IsMember )
250 {
251   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
252
253   *IsMember = TRUE;
254   return(TRUE);
255 }
256
257 /******************************************************************************
258  * GetTokenInformation [ADVAPI32.@]
259  *
260  * PARAMS
261  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
262  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
263  *   tokeninfo       [O] Destination for token information
264  *   tokeninfolength [I] Length of tokeninfo
265  *   retlen          [O] Destination for returned token information length
266  *
267  * RETURNS
268  *  Success: TRUE. tokeninfo contains retlen bytes of token information
269  *  Failure: FALSE.
270  *
271  * NOTES
272  *  See NtQueryInformationToken.
273  */
274 BOOL WINAPI
275 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
276                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
277 {
278     TRACE("(%p, %s, %p, %ld, %p): \n",
279           token,
280           (tokeninfoclass == TokenUser) ? "TokenUser" :
281           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
282           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
283           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
284           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
285           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
286           (tokeninfoclass == TokenSource) ? "TokenSource" :
287           (tokeninfoclass == TokenType) ? "TokenType" :
288           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
289           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
290           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
291           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
292           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
293           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
294           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
295           "Unknown",
296           tokeninfo, tokeninfolength, retlen);
297     CallWin32ToNt (NtQueryInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength, retlen));
298 }
299
300 /******************************************************************************
301  * SetTokenInformation [ADVAPI32.@]
302  *
303  * Set information for an access token.
304  *
305  * PARAMS
306  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
307  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
308  *   tokeninfo       [I] Token information to set
309  *   tokeninfolength [I] Length of tokeninfo
310  *
311  * RETURNS
312  *  Success: TRUE. The information for the token is set to tokeninfo.
313  *  Failure: FALSE.
314  */
315 BOOL WINAPI
316 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
317                      LPVOID tokeninfo, DWORD tokeninfolength )
318 {
319     FIXME("(%p, %s, %p, %ld): stub\n",
320           token,
321           (tokeninfoclass == TokenUser) ? "TokenUser" :
322           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
323           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
324           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
325           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
326           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
327           (tokeninfoclass == TokenSource) ? "TokenSource" :
328           (tokeninfoclass == TokenType) ? "TokenType" :
329           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
330           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
331           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
332           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
333           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
334           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
335           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
336           "Unknown",
337           tokeninfo, tokeninfolength);
338
339     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
340
341     return FALSE;
342 }
343
344 /*************************************************************************
345  * SetThreadToken [ADVAPI32.@]
346  *
347  * Assigns an 'impersonation token' to a thread so it can assume the
348  * security privileges of another thread or process.  Can also remove
349  * a previously assigned token. 
350  *
351  * PARAMS
352  *   thread          [O] Handle to thread to set the token for
353  *   token           [I] Token to set
354  *
355  * RETURNS
356  *  Success: TRUE. The threads access token is set to token
357  *  Failure: FALSE.
358  *
359  * NOTES
360  *  Only supported on NT or higher. On Win9X this function does nothing.
361  *  See SetTokenInformation.
362  */
363 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
364 {
365     FIXME("(%p, %p): stub (NT impl. only)\n", thread, token);
366
367     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
368
369     return FALSE;
370 }
371
372 /*      ##############################
373         ######  SID FUNCTIONS   ######
374         ##############################
375 */
376
377 /******************************************************************************
378  * AllocateAndInitializeSid [ADVAPI32.@]
379  *
380  * PARAMS
381  *   pIdentifierAuthority []
382  *   nSubAuthorityCount   []
383  *   nSubAuthority0       []
384  *   nSubAuthority1       []
385  *   nSubAuthority2       []
386  *   nSubAuthority3       []
387  *   nSubAuthority4       []
388  *   nSubAuthority5       []
389  *   nSubAuthority6       []
390  *   nSubAuthority7       []
391  *   pSid                 []
392  */
393 BOOL WINAPI
394 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
395                           BYTE nSubAuthorityCount,
396                           DWORD nSubAuthority0, DWORD nSubAuthority1,
397                           DWORD nSubAuthority2, DWORD nSubAuthority3,
398                           DWORD nSubAuthority4, DWORD nSubAuthority5,
399                           DWORD nSubAuthority6, DWORD nSubAuthority7,
400                           PSID *pSid )
401 {
402         CallWin32ToNt (RtlAllocateAndInitializeSid(
403                 pIdentifierAuthority, nSubAuthorityCount,
404                 nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
405                 nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
406                 pSid ));
407 }
408
409 /******************************************************************************
410  * FreeSid [ADVAPI32.@]
411  *
412  * PARAMS
413  *   pSid []
414  */
415 PVOID WINAPI
416 FreeSid( PSID pSid )
417 {
418         RtlFreeSid(pSid);
419         return NULL; /* is documented like this */
420 }
421
422 /******************************************************************************
423  * CopySid [ADVAPI32.@]
424  *
425  * PARAMS
426  *   nDestinationSidLength []
427  *   pDestinationSid       []
428  *   pSourceSid            []
429  */
430 BOOL WINAPI
431 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
432 {
433         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
434 }
435
436 /******************************************************************************
437  * IsValidSid [ADVAPI32.@]
438  *
439  * PARAMS
440  *   pSid []
441  */
442 BOOL WINAPI
443 IsValidSid( PSID pSid )
444 {
445         return RtlValidSid( pSid );
446 }
447
448 /******************************************************************************
449  * EqualSid [ADVAPI32.@]
450  *
451  * PARAMS
452  *   pSid1 []
453  *   pSid2 []
454  */
455 BOOL WINAPI
456 EqualSid( PSID pSid1, PSID pSid2 )
457 {
458         return RtlEqualSid( pSid1, pSid2 );
459 }
460
461 /******************************************************************************
462  * EqualPrefixSid [ADVAPI32.@]
463  */
464 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
465 {
466         return RtlEqualPrefixSid(pSid1, pSid2);
467 }
468
469 /******************************************************************************
470  * GetSidLengthRequired [ADVAPI32.@]
471  *
472  * PARAMS
473  *   nSubAuthorityCount []
474  */
475 DWORD WINAPI
476 GetSidLengthRequired( BYTE nSubAuthorityCount )
477 {
478         return RtlLengthRequiredSid(nSubAuthorityCount);
479 }
480
481 /******************************************************************************
482  * InitializeSid [ADVAPI32.@]
483  *
484  * PARAMS
485  *   pIdentifierAuthority []
486  */
487 BOOL WINAPI
488 InitializeSid (
489         PSID pSid,
490         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
491         BYTE nSubAuthorityCount)
492 {
493         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
494 }
495
496 /******************************************************************************
497  * GetSidIdentifierAuthority [ADVAPI32.@]
498  *
499  * PARAMS
500  *   pSid []
501  */
502 PSID_IDENTIFIER_AUTHORITY WINAPI
503 GetSidIdentifierAuthority( PSID pSid )
504 {
505         return RtlIdentifierAuthoritySid(pSid);
506 }
507
508 /******************************************************************************
509  * GetSidSubAuthority [ADVAPI32.@]
510  *
511  * PARAMS
512  *   pSid          []
513  *   nSubAuthority []
514  */
515 PDWORD WINAPI
516 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
517 {
518         return RtlSubAuthoritySid(pSid, nSubAuthority);
519 }
520
521 /******************************************************************************
522  * GetSidSubAuthorityCount [ADVAPI32.@]
523  *
524  * PARAMS
525  *   pSid []
526  */
527 PUCHAR WINAPI
528 GetSidSubAuthorityCount (PSID pSid)
529 {
530         return RtlSubAuthorityCountSid(pSid);
531 }
532
533 /******************************************************************************
534  * GetLengthSid [ADVAPI32.@]
535  *
536  * PARAMS
537  *   pSid []
538  */
539 DWORD WINAPI
540 GetLengthSid (PSID pSid)
541 {
542         return RtlLengthSid(pSid);
543 }
544
545 /*      ##############################################
546         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
547         ##############################################
548 */
549
550 /******************************************************************************
551  * InitializeSecurityDescriptor [ADVAPI32.@]
552  *
553  * PARAMS
554  *   pDescr   []
555  *   revision []
556  */
557 BOOL WINAPI
558 InitializeSecurityDescriptor( SECURITY_DESCRIPTOR *pDescr, DWORD revision )
559 {
560         CallWin32ToNt (RtlCreateSecurityDescriptor(pDescr, revision ));
561 }
562
563
564 /******************************************************************************
565  * MakeAbsoluteSD [ADVAPI32.@]
566  */
567 BOOL WINAPI MakeAbsoluteSD (
568         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
569         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
570         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
571         OUT PACL pDacl,
572         OUT LPDWORD lpdwDaclSize,
573         OUT PACL pSacl,
574         OUT LPDWORD lpdwSaclSize,
575         OUT PSID pOwner,
576         OUT LPDWORD lpdwOwnerSize,
577         OUT PSID pPrimaryGroup,
578         OUT LPDWORD lpdwPrimaryGroupSize)
579 {
580         CallWin32ToNt (RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
581             pAbsoluteSecurityDescriptor, lpdwAbsoluteSecurityDescriptorSize,
582             pDacl, lpdwDaclSize, pSacl, lpdwSaclSize, pOwner, lpdwOwnerSize,
583             pPrimaryGroup, lpdwPrimaryGroupSize));
584 }
585
586
587 /******************************************************************************
588  * GetSecurityDescriptorLength [ADVAPI32.@]
589  */
590 DWORD WINAPI GetSecurityDescriptorLength( SECURITY_DESCRIPTOR *pDescr)
591 {
592         return (RtlLengthSecurityDescriptor(pDescr));
593 }
594
595 /******************************************************************************
596  * GetSecurityDescriptorOwner [ADVAPI32.@]
597  *
598  * PARAMS
599  *   pOwner            []
600  *   lpbOwnerDefaulted []
601  */
602 BOOL WINAPI
603 GetSecurityDescriptorOwner( SECURITY_DESCRIPTOR *pDescr, PSID *pOwner,
604                             LPBOOL lpbOwnerDefaulted )
605 {
606         CallWin32ToNt (RtlGetOwnerSecurityDescriptor( pDescr, pOwner, (PBOOLEAN)lpbOwnerDefaulted ));
607 }
608
609 /******************************************************************************
610  * SetSecurityDescriptorOwner [ADVAPI32.@]
611  *
612  * PARAMS
613  */
614 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
615                                    PSID pOwner, BOOL bOwnerDefaulted)
616 {
617         CallWin32ToNt (RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
618 }
619 /******************************************************************************
620  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
621  */
622 BOOL WINAPI GetSecurityDescriptorGroup(
623         PSECURITY_DESCRIPTOR SecurityDescriptor,
624         PSID *Group,
625         LPBOOL GroupDefaulted)
626 {
627         CallWin32ToNt (RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, (PBOOLEAN)GroupDefaulted));
628 }
629 /******************************************************************************
630  * SetSecurityDescriptorGroup [ADVAPI32.@]
631  */
632 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
633                                            PSID Group, BOOL GroupDefaulted)
634 {
635         CallWin32ToNt (RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
636 }
637
638 /******************************************************************************
639  * IsValidSecurityDescriptor [ADVAPI32.@]
640  *
641  * PARAMS
642  *   lpsecdesc []
643  */
644 BOOL WINAPI
645 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
646 {
647         CallWin32ToNt (RtlValidSecurityDescriptor(SecurityDescriptor));
648 }
649
650 /******************************************************************************
651  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
652  */
653 BOOL WINAPI GetSecurityDescriptorDacl(
654         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
655         OUT LPBOOL lpbDaclPresent,
656         OUT PACL *pDacl,
657         OUT LPBOOL lpbDaclDefaulted)
658 {
659         CallWin32ToNt (RtlGetDaclSecurityDescriptor(pSecurityDescriptor, (PBOOLEAN)lpbDaclPresent,
660                                                pDacl, (PBOOLEAN)lpbDaclDefaulted));
661 }
662
663 /******************************************************************************
664  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
665  */
666 BOOL WINAPI
667 SetSecurityDescriptorDacl (
668         PSECURITY_DESCRIPTOR lpsd,
669         BOOL daclpresent,
670         PACL dacl,
671         BOOL dacldefaulted )
672 {
673         CallWin32ToNt (RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ));
674 }
675 /******************************************************************************
676  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
677  */
678 BOOL WINAPI GetSecurityDescriptorSacl(
679         IN PSECURITY_DESCRIPTOR lpsd,
680         OUT LPBOOL lpbSaclPresent,
681         OUT PACL *pSacl,
682         OUT LPBOOL lpbSaclDefaulted)
683 {
684         CallWin32ToNt (RtlGetSaclSecurityDescriptor(lpsd,
685            (PBOOLEAN)lpbSaclPresent, pSacl, (PBOOLEAN)lpbSaclDefaulted));
686 }
687
688 /**************************************************************************
689  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
690  */
691 BOOL WINAPI SetSecurityDescriptorSacl (
692         PSECURITY_DESCRIPTOR lpsd,
693         BOOL saclpresent,
694         PACL lpsacl,
695         BOOL sacldefaulted)
696 {
697         CallWin32ToNt (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
698 }
699 /******************************************************************************
700  * MakeSelfRelativeSD [ADVAPI32.@]
701  *
702  * PARAMS
703  *   lpabssecdesc  []
704  *   lpselfsecdesc []
705  *   lpbuflen      []
706  */
707 BOOL WINAPI
708 MakeSelfRelativeSD(
709         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
710         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
711         IN OUT LPDWORD lpdwBufferLength)
712 {
713         CallWin32ToNt (RtlMakeSelfRelativeSD(pAbsoluteSecurityDescriptor,pSelfRelativeSecurityDescriptor, lpdwBufferLength));
714 }
715
716 /******************************************************************************
717  * GetSecurityDescriptorControl                 [ADVAPI32.@]
718  */
719
720 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
721                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
722 {
723         CallWin32ToNt (RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
724 }
725
726 /*      ##############################
727         ######  ACL FUNCTIONS   ######
728         ##############################
729 */
730
731 /*************************************************************************
732  * InitializeAcl [ADVAPI32.@]
733  */
734 DWORD WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
735 {
736         CallWin32ToNt (RtlCreateAcl(acl, size, rev));
737 }
738
739 /******************************************************************************
740  *  AddAccessAllowedAce [ADVAPI32.@]
741  */
742 BOOL WINAPI AddAccessAllowedAce(
743         IN OUT PACL pAcl,
744         IN DWORD dwAceRevision,
745         IN DWORD AccessMask,
746         IN PSID pSid)
747 {
748         CallWin32ToNt(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
749 }
750
751 /******************************************************************************
752  *  AddAccessAllowedAceEx [ADVAPI32.@]
753  */
754 BOOL WINAPI AddAccessAllowedAceEx(
755         IN OUT PACL pAcl,
756         IN DWORD dwAceRevision,
757         IN DWORD AceFlags,
758         IN DWORD AccessMask,
759         IN PSID pSid)
760 {
761         CallWin32ToNt(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
762 }
763
764 /******************************************************************************
765  *  AddAccessDeniedAce [ADVAPI32.@]
766  */
767 BOOL WINAPI AddAccessDeniedAce(
768         IN OUT PACL pAcl,
769         IN DWORD dwAceRevision,
770         IN DWORD AccessMask,
771         IN PSID pSid)
772 {
773         CallWin32ToNt(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
774 }
775
776 /******************************************************************************
777  *  AddAccessDeniedAceEx [ADVAPI32.@]
778  */
779 BOOL WINAPI AddAccessDeniedAceEx(
780         IN OUT PACL pAcl,
781         IN DWORD dwAceRevision,
782         IN DWORD AceFlags,
783         IN DWORD AccessMask,
784         IN PSID pSid)
785 {
786         CallWin32ToNt(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
787 }
788
789 /******************************************************************************
790  *  AddAce [ADVAPI32.@]
791  */
792 BOOL WINAPI AddAce(
793         IN OUT PACL pAcl,
794         IN DWORD dwAceRevision,
795         IN DWORD dwStartingAceIndex,
796         LPVOID pAceList,
797         DWORD nAceListLength)
798 {
799         CallWin32ToNt(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
800 }
801
802 /******************************************************************************
803  * DeleteAce [ADVAPI32.@]
804  */
805 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
806 {
807     CallWin32ToNt(RtlDeleteAce(pAcl, dwAceIndex));
808 }
809
810 /******************************************************************************
811  *  FindFirstFreeAce [ADVAPI32.@]
812  */
813 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
814 {
815         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
816 }
817
818 /******************************************************************************
819  * GetAce [ADVAPI32.@]
820  */
821 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
822 {
823     CallWin32ToNt(RtlGetAce(pAcl, dwAceIndex, pAce));
824 }
825
826 /******************************************************************************
827  * GetAclInformation [ADVAPI32.@]
828  */
829 BOOL WINAPI GetAclInformation(
830   PACL pAcl,
831   LPVOID pAclInformation,
832   DWORD nAclInformationLength,
833   ACL_INFORMATION_CLASS dwAclInformationClass)
834 {
835         CallWin32ToNt(RtlQueryInformationAcl(pAcl, pAclInformation,
836                 nAclInformationLength, dwAclInformationClass));
837 }
838
839 /******************************************************************************
840  *  IsValidAcl [ADVAPI32.@]
841  */
842 BOOL WINAPI IsValidAcl(IN PACL pAcl)
843 {
844         return RtlValidAcl(pAcl);
845 }
846
847 /*      ##############################
848         ######  MISC FUNCTIONS  ######
849         ##############################
850 */
851
852 static const char * const DefaultPrivNames[] =
853 {
854     NULL, NULL,
855     "SeCreateTokenPrivilege", "SeAssignPrimaryTokenPrivilege",
856     "SeLockMemoryPrivilege", "SeIncreaseQuotaPrivilege",
857     "SeUnsolicitedInputPrivilege", "SeMachineAccountPrivilege",
858     "SeTcbPrivilege", "SeSecurityPrivilege",
859     "SeTakeOwnershipPrivilege", "SeLoadDriverPrivilege",
860     "SeSystemProfilePrivilege", "SeSystemtimePrivilege",
861     "SeProfileSingleProcessPrivilege", "SeIncreaseBasePriorityPrivilege",
862     "SeCreatePagefilePrivilege", "SeCreatePermanentPrivilege",
863     "SeBackupPrivilege", "SeRestorePrivilege",
864     "SeShutdownPrivilege", "SeDebugPrivilege",
865     "SeAuditPrivilege", "SeSystemEnvironmentPrivilege",
866     "SeChangeNotifyPrivilege", "SeRemoteShutdownPrivilege",
867     "SeUndockPrivilege", "SeSyncAgentPrivilege",
868     "SeEnableDelegationPrivilege", "SeManageVolumePrivilege",
869     "SeImpersonatePrivilege", "SeCreateGlobalPrivilege",
870 };
871 #define NUMPRIVS (sizeof DefaultPrivNames/sizeof DefaultPrivNames[0])
872
873 /******************************************************************************
874  * LookupPrivilegeValueW                        [ADVAPI32.@]
875  *
876  * See LookupPrivilegeValueA.
877  */
878 BOOL WINAPI
879 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
880 {
881     UINT i;
882     WCHAR priv[0x28];
883
884     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
885
886     for( i=0; i<NUMPRIVS; i++ )
887     {
888         if( !DefaultPrivNames[i] )
889             continue;
890         MultiByteToWideChar( CP_ACP, 0, DefaultPrivNames[i], -1,
891                              priv, sizeof priv );
892         if( strcmpW( priv, lpName) )
893             continue;
894         lpLuid->LowPart = i;
895         lpLuid->HighPart = 0;
896         TRACE( "%s -> %08lx-%08lx\n",debugstr_w( lpSystemName ),
897                lpLuid->HighPart, lpLuid->LowPart );
898         return TRUE;
899     }
900     return FALSE;
901 }
902
903 /******************************************************************************
904  * LookupPrivilegeValueA                        [ADVAPI32.@]
905  *
906  * Retrieves LUID used on a system to represent the privilege name.
907  *
908  * PARAMS
909  *  lpSystemName [I] Name of the system
910  *  lpName       [I] Name of the privilege
911  *  lpLuid       [O] Destination for the resulting LUID
912  *
913  * RETURNS
914  *  Success: TRUE. lpLuid contains the requested LUID.
915  *  Failure: FALSE.
916  */
917 BOOL WINAPI
918 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
919 {
920     UNICODE_STRING lpSystemNameW;
921     UNICODE_STRING lpNameW;
922     BOOL ret;
923
924     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
925     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
926     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
927     RtlFreeUnicodeString(&lpNameW);
928     RtlFreeUnicodeString(&lpSystemNameW);
929     return ret;
930 }
931
932
933 /******************************************************************************
934  * LookupPrivilegeNameA                 [ADVAPI32.@]
935  */
936 BOOL WINAPI
937 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName, LPDWORD cchName)
938 {
939     FIXME("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
940     return FALSE;
941 }
942
943 /******************************************************************************
944  * LookupPrivilegeNameW                 [ADVAPI32.@]
945  */
946 BOOL WINAPI
947 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPSTR lpName, LPDWORD cchName)
948 {
949     FIXME("%s %p %p %p\n", debugstr_w(lpSystemName), lpLuid, lpName, cchName);
950     return FALSE;
951 }
952
953 /******************************************************************************
954  * GetFileSecurityA [ADVAPI32.@]
955  *
956  * Obtains Specified information about the security of a file or directory.
957  *
958  * PARAMS
959  *  lpFileName           [I] Name of the file to get info for
960  *  RequestedInformation [I] SE_ flags from "winnt.h"
961  *  pSecurityDescriptor  [O] Destination for security information
962  *  nLength              [I] Length of pSecurityDescriptor
963  *  lpnLengthNeeded      [O] Destination for length of returned security information
964  *
965  * RETURNS
966  *  Success: TRUE. pSecurityDescriptor contains the requested information.
967  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
968  *
969  * NOTES
970  *  The information returned is constrained by the callers access rights and
971  *  privileges.
972  */
973 BOOL WINAPI
974 GetFileSecurityA( LPCSTR lpFileName,
975                     SECURITY_INFORMATION RequestedInformation,
976                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
977                     DWORD nLength, LPDWORD lpnLengthNeeded )
978 {
979   FIXME("(%s) : stub\n", debugstr_a(lpFileName));
980   return TRUE;
981 }
982
983 /******************************************************************************
984  * GetFileSecurityW [ADVAPI32.@]
985  *
986  * See GetFileSecurityA.
987  */
988 BOOL WINAPI
989 GetFileSecurityW( LPCWSTR lpFileName,
990                     SECURITY_INFORMATION RequestedInformation,
991                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
992                     DWORD nLength, LPDWORD lpnLengthNeeded )
993 {
994   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
995   return TRUE;
996 }
997
998
999 /******************************************************************************
1000  * LookupAccountSidA [ADVAPI32.@]
1001  */
1002 BOOL WINAPI
1003 LookupAccountSidA(
1004         IN LPCSTR system,
1005         IN PSID sid,
1006         OUT LPSTR account,
1007         IN OUT LPDWORD accountSize,
1008         OUT LPSTR domain,
1009         IN OUT LPDWORD domainSize,
1010         OUT PSID_NAME_USE name_use )
1011 {
1012         static const char ac[] = "Administrator";
1013         static const char dm[] = "DOMAIN";
1014         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1015               debugstr_a(system),sid,
1016               account,accountSize,accountSize?*accountSize:0,
1017               domain,domainSize,domainSize?*domainSize:0,
1018               name_use);
1019
1020         if (accountSize) *accountSize = strlen(ac)+1;
1021         if (account && (*accountSize > strlen(ac)))
1022           strcpy(account, ac);
1023
1024         if (domainSize) *domainSize = strlen(dm)+1;
1025         if (domain && (*domainSize > strlen(dm)))
1026           strcpy(domain,dm);
1027
1028         if (name_use) *name_use = SidTypeUser;
1029         return TRUE;
1030 }
1031
1032 /******************************************************************************
1033  * LookupAccountSidW [ADVAPI32.@]
1034  *
1035  * PARAMS
1036  *   system      []
1037  *   sid         []
1038  *   account     []
1039  *   accountSize []
1040  *   domain      []
1041  *   domainSize  []
1042  *   name_use    []
1043  */
1044 BOOL WINAPI
1045 LookupAccountSidW(
1046         IN LPCWSTR system,
1047         IN PSID sid,
1048         OUT LPWSTR account,
1049         IN OUT LPDWORD accountSize,
1050         OUT LPWSTR domain,
1051         IN OUT LPDWORD domainSize,
1052         OUT PSID_NAME_USE name_use )
1053 {
1054     static const WCHAR ac[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0};
1055     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1056         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1057               debugstr_w(system),sid,
1058               account,accountSize,accountSize?*accountSize:0,
1059               domain,domainSize,domainSize?*domainSize:0,
1060               name_use);
1061
1062         if (accountSize) *accountSize = strlenW(ac)+1;
1063         if (account && (*accountSize > strlenW(ac)))
1064             strcpyW(account, ac);
1065
1066         if (domainSize) *domainSize = strlenW(dm)+1;
1067         if (domain && (*domainSize > strlenW(dm)))
1068             strcpyW(domain,dm);
1069
1070         if (name_use) *name_use = SidTypeUser;
1071         return TRUE;
1072 }
1073
1074 /******************************************************************************
1075  * SetFileSecurityA [ADVAPI32.@]
1076  * Sets the security of a file or directory
1077  */
1078 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1079                                 SECURITY_INFORMATION RequestedInformation,
1080                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1081 {
1082   FIXME("(%s) : stub\n", debugstr_a(lpFileName));
1083   return TRUE;
1084 }
1085
1086 /******************************************************************************
1087  * SetFileSecurityW [ADVAPI32.@]
1088  * Sets the security of a file or directory
1089  *
1090  * PARAMS
1091  *   lpFileName           []
1092  *   RequestedInformation []
1093  *   pSecurityDescriptor  []
1094  */
1095 BOOL WINAPI
1096 SetFileSecurityW( LPCWSTR lpFileName,
1097                     SECURITY_INFORMATION RequestedInformation,
1098                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
1099 {
1100   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
1101   return TRUE;
1102 }
1103
1104 /******************************************************************************
1105  * QueryWindows31FilesMigration [ADVAPI32.@]
1106  *
1107  * PARAMS
1108  *   x1 []
1109  */
1110 BOOL WINAPI
1111 QueryWindows31FilesMigration( DWORD x1 )
1112 {
1113         FIXME("(%ld):stub\n",x1);
1114         return TRUE;
1115 }
1116
1117 /******************************************************************************
1118  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1119  *
1120  * PARAMS
1121  *   x1 []
1122  *   x2 []
1123  *   x3 []
1124  *   x4 []
1125  */
1126 BOOL WINAPI
1127 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1128                                                DWORD x4 )
1129 {
1130         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
1131         return TRUE;
1132 }
1133
1134 /******************************************************************************
1135  * LsaOpenPolicy [ADVAPI32.@]
1136  *
1137  * PARAMS
1138  *   x1 []
1139  *   x2 []
1140  *   x3 []
1141  *   x4 []
1142  */
1143 NTSTATUS WINAPI
1144 LsaOpenPolicy(
1145         IN PLSA_UNICODE_STRING SystemName,
1146         IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
1147         IN ACCESS_MASK DesiredAccess,
1148         IN OUT PLSA_HANDLE PolicyHandle)
1149 {
1150         FIXME("(%s,%p,0x%08lx,%p):stub\n",
1151               SystemName?debugstr_w(SystemName->Buffer):"null",
1152               ObjectAttributes, DesiredAccess, PolicyHandle);
1153         ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
1154                                   STATUS_ACCESS_VIOLATION);
1155         dumpLsaAttributes(ObjectAttributes);
1156         if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
1157         return STATUS_SUCCESS;
1158 }
1159
1160 /******************************************************************************
1161  * LsaQueryInformationPolicy [ADVAPI32.@]
1162  */
1163 NTSTATUS WINAPI
1164 LsaQueryInformationPolicy(
1165         IN LSA_HANDLE PolicyHandle,
1166         IN POLICY_INFORMATION_CLASS InformationClass,
1167         OUT PVOID *Buffer)
1168 {
1169         FIXME("(%p,0x%08x,%p):stub\n",
1170               PolicyHandle, InformationClass, Buffer);
1171
1172         if(!Buffer) return FALSE;
1173         switch (InformationClass)
1174         {
1175           case PolicyAuditEventsInformation: /* 2 */
1176             {
1177               PPOLICY_AUDIT_EVENTS_INFO p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POLICY_AUDIT_EVENTS_INFO));
1178               p->AuditingMode = FALSE; /* no auditing */
1179               *Buffer = p;
1180             }
1181             break;
1182           case PolicyPrimaryDomainInformation: /* 3 */
1183           case PolicyAccountDomainInformation: /* 5 */
1184             {
1185               struct di
1186               { POLICY_PRIMARY_DOMAIN_INFO ppdi;
1187                 SID sid;
1188               };
1189               SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
1190
1191               struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(xdi));
1192               HKEY key;
1193               BOOL useDefault = TRUE;
1194               LONG ret;
1195
1196               if ((ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
1197                "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0,
1198                KEY_READ, &key)) == ERROR_SUCCESS)
1199               {
1200                   DWORD size = 0;
1201                   static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
1202
1203                   ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
1204                   if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
1205                   {
1206                       xdi->ppdi.Name.Buffer = HeapAlloc(GetProcessHeap(),
1207                        HEAP_ZERO_MEMORY, size);
1208                       if ((ret = RegQueryValueExW(key, wg, NULL, NULL,
1209                        (LPBYTE)xdi->ppdi.Name.Buffer, &size)) == ERROR_SUCCESS)
1210                       {
1211                           xdi->ppdi.Name.Length = (USHORT)size;
1212                           useDefault = FALSE;
1213                       }
1214                       else
1215                       {
1216                           HeapFree(GetProcessHeap(), 0, xdi->ppdi.Name.Buffer);
1217                           xdi->ppdi.Name.Buffer = NULL;
1218                       }
1219                   }
1220                   RegCloseKey(key);
1221               }
1222               if (useDefault)
1223                   RtlCreateUnicodeStringFromAsciiz(&(xdi->ppdi.Name), "DOMAIN");
1224               TRACE("setting domain to %s\n", debugstr_w(xdi->ppdi.Name.Buffer));
1225
1226               xdi->ppdi.Sid = &(xdi->sid);
1227               xdi->sid.Revision = SID_REVISION;
1228               xdi->sid.SubAuthorityCount = 1;
1229               xdi->sid.IdentifierAuthority = localSidAuthority;
1230               xdi->sid.SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
1231               *Buffer = xdi;
1232             }
1233             break;
1234           case  PolicyAuditLogInformation:
1235           case  PolicyPdAccountInformation:
1236           case  PolicyLsaServerRoleInformation:
1237           case  PolicyReplicaSourceInformation:
1238           case  PolicyDefaultQuotaInformation:
1239           case  PolicyModificationInformation:
1240           case  PolicyAuditFullSetInformation:
1241           case  PolicyAuditFullQueryInformation:
1242           case  PolicyDnsDomainInformation:
1243             {
1244               FIXME("category not implemented\n");
1245               return FALSE;
1246             }
1247         }
1248         return TRUE;
1249 }
1250
1251 /******************************************************************************
1252  * LsaLookupSids [ADVAPI32.@]
1253  */
1254 typedef struct
1255 {
1256         SID_NAME_USE Use;
1257         LSA_UNICODE_STRING Name;
1258         LONG DomainIndex;
1259 } LSA_TRANSLATED_NAME, *PLSA_TRANSLATED_NAME;
1260
1261 typedef struct
1262 {
1263         LSA_UNICODE_STRING Name;
1264         PSID Sid;
1265 } LSA_TRUST_INFORMATION, *PLSA_TRUST_INFORMATION;
1266
1267 typedef struct
1268 {
1269         ULONG Entries;
1270         PLSA_TRUST_INFORMATION Domains;
1271 } LSA_REFERENCED_DOMAIN_LIST, *PLSA_REFERENCED_DOMAIN_LIST;
1272
1273 NTSTATUS WINAPI
1274 LsaLookupSids(
1275         IN LSA_HANDLE PolicyHandle,
1276         IN ULONG Count,
1277         IN PSID *Sids,
1278         OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1279         OUT PLSA_TRANSLATED_NAME *Names )
1280 {
1281         FIXME("%p %lu %p %p %p\n",
1282           PolicyHandle, Count, Sids, ReferencedDomains, Names);
1283         return FALSE;
1284 }
1285
1286 /******************************************************************************
1287  * LsaFreeMemory [ADVAPI32.@]
1288  */
1289 NTSTATUS WINAPI
1290 LsaFreeMemory(IN PVOID Buffer)
1291 {
1292         TRACE("(%p)\n",Buffer);
1293         return HeapFree(GetProcessHeap(), 0, Buffer);
1294 }
1295 /******************************************************************************
1296  * LsaClose [ADVAPI32.@]
1297  */
1298 NTSTATUS WINAPI
1299 LsaClose(IN LSA_HANDLE ObjectHandle)
1300 {
1301         FIXME("(%p):stub\n",ObjectHandle);
1302         return 0xc0000000;
1303 }
1304
1305 /******************************************************************************
1306  * LsaNtStatusToWinError [ADVAPI32.@]
1307  *
1308  * PARAMS
1309  *   Status [I]
1310  */
1311 ULONG WINAPI
1312 LsaNtStatusToWinError(NTSTATUS Status)
1313 {
1314     return RtlNtStatusToDosError(Status);
1315 }
1316
1317 /******************************************************************************
1318  * NotifyBootConfigStatus [ADVAPI32.@]
1319  *
1320  * PARAMS
1321  *   x1 []
1322  */
1323 BOOL WINAPI
1324 NotifyBootConfigStatus( DWORD x1 )
1325 {
1326         FIXME("(0x%08lx):stub\n",x1);
1327         return 1;
1328 }
1329
1330 /******************************************************************************
1331  * RevertToSelf [ADVAPI32.@]
1332  *
1333  * PARAMS
1334  *   void []
1335  */
1336 BOOL WINAPI
1337 RevertToSelf( void )
1338 {
1339         FIXME("(), stub\n");
1340         return TRUE;
1341 }
1342
1343 /******************************************************************************
1344  * ImpersonateSelf [ADVAPI32.@]
1345  */
1346 BOOL WINAPI
1347 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1348 {
1349         return RtlImpersonateSelf(ImpersonationLevel);
1350 }
1351
1352 /******************************************************************************
1353  * ImpersonateLoggedOnUser [ADVAPI32.@]
1354  */
1355 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
1356 {
1357     FIXME("(%p):stub returning FALSE\n", hToken);
1358     return FALSE;
1359 }
1360
1361 /******************************************************************************
1362  * AccessCheck [ADVAPI32.@]
1363  *
1364  * FIXME check cast LPBOOL to PBOOLEAN
1365  */
1366 BOOL WINAPI
1367 AccessCheck(
1368         PSECURITY_DESCRIPTOR SecurityDescriptor,
1369         HANDLE ClientToken,
1370         DWORD DesiredAccess,
1371         PGENERIC_MAPPING GenericMapping,
1372         PPRIVILEGE_SET PrivilegeSet,
1373         LPDWORD PrivilegeSetLength,
1374         LPDWORD GrantedAccess,
1375         LPBOOL AccessStatus)
1376 {
1377         CallWin32ToNt (NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
1378           GenericMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess, (PBOOLEAN)AccessStatus));
1379 }
1380
1381
1382 /******************************************************************************
1383  * AccessCheckByType [ADVAPI32.@]
1384  */
1385 BOOL WINAPI AccessCheckByType(
1386     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
1387     PSID PrincipalSelfSid,
1388     HANDLE ClientToken, 
1389     DWORD DesiredAccess, 
1390     POBJECT_TYPE_LIST ObjectTypeList,
1391     DWORD ObjectTypeListLength,
1392     PGENERIC_MAPPING GenericMapping,
1393     PPRIVILEGE_SET PrivilegeSet,
1394     LPDWORD PrivilegeSetLength, 
1395     LPDWORD GrantedAccess,
1396     LPBOOL AccessStatus)
1397 {
1398         FIXME("stub\n");
1399
1400         *AccessStatus = TRUE;
1401
1402         return !*AccessStatus;
1403 }
1404
1405
1406 /*************************************************************************
1407  * SetKernelObjectSecurity [ADVAPI32.@]
1408  */
1409 BOOL WINAPI SetKernelObjectSecurity (
1410         IN HANDLE Handle,
1411         IN SECURITY_INFORMATION SecurityInformation,
1412         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
1413 {
1414         CallWin32ToNt (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
1415 }
1416
1417
1418 /******************************************************************************
1419  *  AddAuditAccessAce [ADVAPI32.@]
1420  */
1421 BOOL WINAPI AddAuditAccessAce(
1422         IN OUT PACL pAcl,
1423         IN DWORD dwAceRevision,
1424         IN DWORD dwAccessMask,
1425         IN PSID pSid,
1426         IN BOOL bAuditSuccess,
1427         IN BOOL bAuditFailure)
1428 {
1429         FIXME("Stub\n");
1430         return TRUE;
1431 }
1432
1433 /******************************************************************************
1434  * LookupAccountNameA [ADVAPI32.@]
1435  */
1436 BOOL WINAPI
1437 LookupAccountNameA(
1438         IN LPCSTR system,
1439         IN LPCSTR account,
1440         OUT PSID sid,
1441         OUT LPDWORD cbSid,
1442         LPSTR ReferencedDomainName,
1443         IN OUT LPDWORD cbReferencedDomainName,
1444         OUT PSID_NAME_USE name_use )
1445 {
1446     FIXME("(%s,%s,%p,%p,%p,%p,%p), stub.\n",system,account,sid,cbSid,ReferencedDomainName,cbReferencedDomainName,name_use);
1447     return FALSE;
1448 }
1449
1450 /******************************************************************************
1451  * PrivilegeCheck [ADVAPI32.@]
1452  */
1453 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
1454 {
1455         FIXME("stub %p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
1456         if (pfResult)
1457                 *pfResult=TRUE;
1458         return TRUE;
1459 }
1460
1461 /******************************************************************************
1462  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1463  */
1464 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
1465   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1466   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1467   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1468 {
1469         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
1470                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
1471                 SecurityDescriptor, DesiredAccess, GenericMapping,
1472                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1473         return TRUE;
1474 }
1475
1476 /******************************************************************************
1477  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
1478  */
1479 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
1480   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1481   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1482   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1483 {
1484         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
1485                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
1486                 SecurityDescriptor, DesiredAccess, GenericMapping,
1487                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1488         return TRUE;
1489 }
1490
1491
1492 /******************************************************************************
1493  * GetSecurityInfoExW [ADVAPI32.@]
1494  */
1495 DWORD WINAPI GetSecurityInfoExW(
1496         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
1497         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
1498         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
1499         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
1500 )
1501 {
1502   FIXME("stub!\n");
1503   return ERROR_BAD_PROVIDER; 
1504 }
1505
1506 /******************************************************************************
1507  * BuildTrusteeWithSidA [ADVAPI32.@]
1508  */
1509 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
1510 {
1511     FIXME("%p %p\n", pTrustee, pSid);
1512 }
1513
1514 /******************************************************************************
1515  * BuildTrusteeWithSidW [ADVAPI32.@]
1516  */
1517 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
1518 {
1519     FIXME("%p %p\n", pTrustee, pSid);
1520 }
1521
1522 /******************************************************************************
1523  * SetEntriesInAclA [ADVAPI32.@]
1524  */
1525 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
1526                                PACL OldAcl, PACL* NewAcl )
1527 {
1528     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1529     return ERROR_CALL_NOT_IMPLEMENTED;
1530 }
1531
1532 /******************************************************************************
1533  * SetEntriesInAclW [ADVAPI32.@]
1534  */
1535 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
1536                                PACL OldAcl, PACL* NewAcl )
1537 {
1538     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1539     return ERROR_CALL_NOT_IMPLEMENTED;
1540 }
1541
1542 /******************************************************************************
1543  * SetNamedSecurityInfoA [ADVAPI32.@]
1544  */
1545 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
1546         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1547         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1548 {
1549     FIXME("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
1550            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1551     return ERROR_CALL_NOT_IMPLEMENTED;
1552 }
1553
1554 /******************************************************************************
1555  * AreAnyAccessesGranted [ADVAPI32.@]
1556  *
1557  * Determines whether or not any of a set of specified access permissions have
1558  * been granted or not.
1559  *
1560  * PARAMS
1561  *   GrantedAccess [I] The permissions that have been granted.
1562  *   DesiredAccess [I] The permissions that you want to have.
1563  *
1564  * RETURNS
1565  *   Nonzero if any of the permissions have been granted, zero if none of the
1566  *   permissions have been granted.
1567  */
1568
1569 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
1570 {
1571     return (GrantedAccess & DesiredAccess) != 0;
1572 }
1573
1574 /******************************************************************************
1575  * SetNamedSecurityInfoW [ADVAPI32.@]
1576  */
1577 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
1578         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1579         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1580 {
1581     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
1582            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1583     return ERROR_CALL_NOT_IMPLEMENTED;
1584 }
1585
1586 /******************************************************************************
1587  * GetExplicitEntriesFromAclA [ADVAPI32.@]
1588  */
1589 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
1590         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
1591 {
1592     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1593     return ERROR_CALL_NOT_IMPLEMENTED;
1594 }
1595
1596 /******************************************************************************
1597  * GetExplicitEntriesFromAclW [ADVAPI32.@]
1598  */
1599 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
1600         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
1601 {
1602     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1603     return ERROR_CALL_NOT_IMPLEMENTED;
1604 }
1605
1606
1607 /******************************************************************************
1608  * ParseAclStringFlags
1609  */
1610 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
1611 {
1612     DWORD flags = 0;
1613     LPCWSTR szAcl = *StringAcl;
1614
1615     while (*szAcl != '(')
1616     {
1617         if (*szAcl == 'P')
1618         {
1619             flags |= SE_DACL_PROTECTED;
1620         }
1621         else if (*szAcl == 'A')
1622         {
1623             szAcl++;
1624             if (*szAcl == 'R')
1625                 flags |= SE_DACL_AUTO_INHERIT_REQ;
1626             else if (*szAcl == 'I')
1627                 flags |= SE_DACL_AUTO_INHERITED;
1628         }
1629         szAcl++;
1630     }
1631
1632     *StringAcl = szAcl;
1633     return flags;
1634 }
1635
1636 /******************************************************************************
1637  * ParseAceStringType
1638  */
1639 ACEFLAG AceType[] =
1640 {
1641     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
1642     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
1643     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
1644     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
1645     /*
1646     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
1647     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
1648     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
1649     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
1650     */
1651     { NULL, 0 },
1652 };
1653
1654 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
1655 {
1656     UINT len = 0;
1657     LPCWSTR szAcl = *StringAcl;
1658     LPACEFLAG lpaf = AceType;
1659
1660     while (lpaf->wstr &&
1661         (len = strlenW(lpaf->wstr)) &&
1662         strncmpW(lpaf->wstr, szAcl, len))
1663         lpaf++;
1664
1665     if (!lpaf->wstr)
1666         return 0;
1667
1668     *StringAcl += len;
1669     return lpaf->value;
1670 }
1671
1672
1673 /******************************************************************************
1674  * ParseAceStringFlags
1675  */
1676 ACEFLAG AceFlags[] =
1677 {
1678     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
1679     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
1680     { SDDL_INHERITED,         INHERITED_ACE },
1681     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
1682     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
1683     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
1684     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
1685     { NULL, 0 },
1686 };
1687
1688 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
1689 {
1690     UINT len = 0;
1691     BYTE flags = 0;
1692     LPCWSTR szAcl = *StringAcl;
1693
1694     while (*szAcl != ';')
1695     {
1696         LPACEFLAG lpaf = AceFlags;
1697
1698         while (lpaf->wstr &&
1699                (len = strlenW(lpaf->wstr)) &&
1700                strncmpW(lpaf->wstr, szAcl, len))
1701             lpaf++;
1702
1703         if (!lpaf->wstr)
1704             return 0;
1705
1706         flags |= lpaf->value;
1707         szAcl += len;
1708     }
1709
1710     *StringAcl = szAcl;
1711     return flags;
1712 }
1713
1714
1715 /******************************************************************************
1716  * ParseAceStringRights
1717  */
1718 ACEFLAG AceRights[] =
1719 {
1720     { SDDL_GENERIC_ALL,     GENERIC_ALL },
1721     { SDDL_GENERIC_READ,    GENERIC_READ },
1722     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
1723     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
1724     { SDDL_READ_CONTROL,    READ_CONTROL },
1725     { SDDL_STANDARD_DELETE, DELETE },
1726     { SDDL_WRITE_DAC,       WRITE_DAC },
1727     { SDDL_WRITE_OWNER,     WRITE_OWNER },
1728     { NULL, 0 },
1729 };
1730
1731 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
1732 {
1733     UINT len = 0;
1734     DWORD rights = 0;
1735     LPCWSTR szAcl = *StringAcl;
1736
1737     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
1738     {
1739         LPCWSTR p = szAcl;
1740
1741         while (*p && *p != ';')
1742             p++;
1743
1744         if (p - szAcl <= 8)
1745         {
1746             rights = strtoulW(szAcl, NULL, 16);
1747             *StringAcl = p;
1748         }
1749         else
1750             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
1751     }
1752     else
1753     {
1754         while (*szAcl != ';')
1755         {
1756             LPACEFLAG lpaf = AceRights;
1757
1758             while (lpaf->wstr &&
1759                (len = strlenW(lpaf->wstr)) &&
1760                strncmpW(lpaf->wstr, szAcl, len))
1761             {
1762                lpaf++;
1763             }
1764
1765             if (!lpaf->wstr)
1766                 return 0;
1767
1768             rights |= lpaf->value;
1769             szAcl += len;
1770         }
1771     }
1772
1773     *StringAcl = szAcl;
1774     return rights;
1775 }
1776
1777
1778 /******************************************************************************
1779  * ParseStringAclToAcl
1780  * 
1781  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
1782  */
1783 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
1784     PACL pAcl, LPDWORD cBytes)
1785 {
1786     DWORD val;
1787     DWORD sidlen;
1788     DWORD length = sizeof(ACL);
1789     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
1790
1791     TRACE("%s\n", debugstr_w(StringAcl));
1792
1793     if (!StringAcl)
1794         return FALSE;
1795
1796     if (pAcl) /* pAce is only useful if we're setting values */
1797         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
1798
1799     /* Parse ACL flags */
1800     *lpdwFlags = ParseAclStringFlags(&StringAcl);
1801
1802     /* Parse ACE */
1803     while (*StringAcl == '(')
1804     {
1805         StringAcl++;
1806
1807         /* Parse ACE type */
1808         val = ParseAceStringType(&StringAcl);
1809         if (pAce)
1810             pAce->Header.AceType = (BYTE) val;
1811         if (*StringAcl != ';')
1812             goto lerr;
1813         StringAcl++;
1814
1815         /* Parse ACE flags */
1816         val = ParseAceStringFlags(&StringAcl);
1817         if (pAce)
1818             pAce->Header.AceFlags = (BYTE) val;
1819         if (*StringAcl != ';')
1820             goto lerr;
1821         StringAcl++;
1822
1823         /* Parse ACE rights */
1824         val = ParseAceStringRights(&StringAcl);
1825         if (pAce)
1826             pAce->Mask = val;
1827         if (*StringAcl != ';')
1828             goto lerr;
1829         StringAcl++;
1830
1831         /* Parse ACE object guid */
1832         if (*StringAcl != ';')
1833         {
1834             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1835             goto lerr;
1836         }
1837         StringAcl++;
1838
1839         /* Parse ACE inherit object guid */
1840         if (*StringAcl != ';')
1841         {
1842             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
1843             goto lerr;
1844         }
1845         StringAcl++;
1846
1847         /* Parse ACE account sid */
1848         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
1849         {
1850             while (*StringAcl && *StringAcl != ')')
1851                 StringAcl++;
1852         }
1853
1854         if (*StringAcl != ')')
1855             goto lerr;
1856         StringAcl++;
1857
1858         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
1859     }
1860
1861     *cBytes = length;
1862     return TRUE;
1863
1864 lerr:
1865     WARN("Invalid ACE string format\n");
1866     return FALSE;
1867 }
1868
1869
1870 /******************************************************************************
1871  * ParseStringSecurityDescriptorToSecurityDescriptor
1872  */
1873 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
1874     LPCWSTR StringSecurityDescriptor,
1875     PSECURITY_DESCRIPTOR SecurityDescriptor,
1876     LPDWORD cBytes)
1877 {
1878     BOOL bret = FALSE;
1879     WCHAR toktype;
1880     WCHAR tok[MAX_PATH];
1881     LPCWSTR lptoken;
1882     LPBYTE lpNext = NULL;
1883
1884     *cBytes = 0;
1885
1886     if (SecurityDescriptor)
1887         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
1888
1889     while (*StringSecurityDescriptor)
1890     {
1891         toktype = *StringSecurityDescriptor;
1892
1893         /* Expect char identifier followed by ':' */
1894         StringSecurityDescriptor++;
1895         if (*StringSecurityDescriptor != ':')
1896         {
1897             SetLastError(ERROR_INVALID_PARAMETER);
1898             goto lend;
1899         }
1900         StringSecurityDescriptor++;
1901
1902         /* Extract token */
1903         lptoken = StringSecurityDescriptor;
1904         while (*lptoken && *lptoken != ':')
1905             lptoken++;
1906
1907         if (*lptoken)
1908             lptoken--;
1909
1910         strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor);
1911
1912         switch (toktype)
1913         {
1914             case 'O':
1915             {
1916                 DWORD bytes;
1917
1918                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
1919                     goto lend;
1920
1921                 if (SecurityDescriptor)
1922                 {
1923                     SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
1924                         (DWORD) SecurityDescriptor);
1925                     lpNext += bytes; /* Advance to next token */
1926                 }
1927
1928                 *cBytes += bytes;
1929
1930                 break;
1931             }
1932
1933             case 'G':
1934             {
1935                 DWORD bytes;
1936
1937                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
1938                     goto lend;
1939
1940                 if (SecurityDescriptor)
1941                 {
1942                     SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - 
1943                         (DWORD) SecurityDescriptor);
1944                     lpNext += bytes; /* Advance to next token */
1945                 }
1946
1947                 *cBytes += bytes;
1948
1949                 break;
1950             }
1951
1952             case 'D':
1953             {
1954                 DWORD flags;
1955                 DWORD bytes;
1956
1957                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
1958                     goto lend;
1959
1960                 if (SecurityDescriptor)
1961                 {
1962                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
1963                     SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
1964                         (DWORD) SecurityDescriptor);
1965                     lpNext += bytes; /* Advance to next token */
1966                 }
1967
1968                 *cBytes += bytes;
1969
1970                 break;
1971             }
1972
1973             case 'S':
1974             {
1975                 DWORD flags;
1976                 DWORD bytes;
1977
1978                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
1979                     goto lend;
1980
1981                 if (SecurityDescriptor)
1982                 {
1983                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
1984                     SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
1985                         (DWORD) SecurityDescriptor);
1986                     lpNext += bytes; /* Advance to next token */
1987                 }
1988
1989                 *cBytes += bytes;
1990
1991                 break;
1992             }
1993
1994             default:
1995                 FIXME("Unknown token\n");
1996                 SetLastError(ERROR_INVALID_PARAMETER);
1997                 goto lend;
1998         }
1999
2000         StringSecurityDescriptor = lptoken;
2001     }
2002
2003     bret = TRUE;
2004
2005 lend:
2006     return bret;
2007 }
2008
2009 /******************************************************************************
2010  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2011  */
2012 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2013         LPCWSTR StringSecurityDescriptor,
2014         DWORD StringSDRevision,
2015         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2016         PULONG SecurityDescriptorSize)
2017 {
2018     DWORD cBytes;
2019     PSECURITY_DESCRIPTOR psd;
2020     BOOL bret = FALSE;
2021
2022     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2023
2024     if (GetVersion() & 0x80000000)
2025     {
2026         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2027         goto lend;
2028     }
2029     else if (StringSDRevision != SID_REVISION)
2030     {
2031         SetLastError(ERROR_UNKNOWN_REVISION);
2032         goto lend;
2033     }
2034
2035     /* Compute security descriptor length */
2036     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2037         NULL, &cBytes))
2038         goto lend;
2039
2040     psd = *SecurityDescriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(
2041         GMEM_ZEROINIT, cBytes);
2042
2043     psd->Revision = SID_REVISION;
2044     psd->Control |= SE_SELF_RELATIVE;
2045
2046     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2047         psd, &cBytes))
2048     {
2049         LocalFree(psd);
2050         goto lend;
2051     }
2052
2053     if (SecurityDescriptorSize)
2054         *SecurityDescriptorSize = cBytes;
2055
2056     bret = TRUE;
2057  
2058 lend:
2059     TRACE(" ret=%d\n", bret);
2060     return bret;
2061 }
2062
2063 /******************************************************************************
2064  * ConvertStringSidToSidW [ADVAPI32.@]
2065  */
2066 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
2067 {
2068     BOOL bret = FALSE;
2069     DWORD cBytes;
2070
2071     if (GetVersion() & 0x80000000)
2072         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2073     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
2074     {
2075         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
2076
2077         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
2078         if (!bret)
2079             LocalFree(*Sid); 
2080     }
2081
2082     return bret;
2083 }
2084
2085 /******************************************************************************
2086  * ComputeStringSidSize
2087  */
2088 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
2089 {
2090     int ctok = 0;
2091     DWORD size = sizeof(SID);
2092
2093     while (*StringSid)
2094     {
2095         if (*StringSid == '-')
2096             ctok++;
2097         StringSid++;
2098     }
2099
2100     if (ctok > 3)
2101         size += (ctok - 3) * sizeof(DWORD);
2102
2103     return size;
2104 }
2105
2106 /******************************************************************************
2107  * ParseStringSidToSid
2108  */
2109 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
2110 {
2111     BOOL bret = FALSE;
2112
2113     if (!StringSid)
2114     {
2115         SetLastError(ERROR_INVALID_PARAMETER);
2116         return FALSE;
2117     }
2118
2119     *cBytes = ComputeStringSidSize(StringSid);
2120     if (!pSid) /* Simply compute the size */
2121         return TRUE;
2122
2123     if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
2124     {
2125         int i = 0;
2126         int csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
2127
2128         StringSid += 2; /* Advance to Revision */
2129         pSid->Revision = atoiW(StringSid);
2130
2131         if (pSid->Revision != SDDL_REVISION)
2132            goto lend; /* ERROR_INVALID_SID */
2133
2134         pSid->SubAuthorityCount = csubauth;
2135
2136         while (*StringSid && *StringSid != '-')
2137             StringSid++; /* Advance to identifier authority */
2138
2139         pSid->IdentifierAuthority.Value[5] = atoiW(StringSid);
2140
2141         if (pSid->IdentifierAuthority.Value[5] > 5)
2142             goto lend; /* ERROR_INVALID_SID */
2143     
2144         while (*StringSid)
2145         {       
2146             while (*StringSid && *StringSid != '-')
2147                 StringSid++;
2148
2149             pSid->SubAuthority[i++] = atoiW(StringSid);
2150         }
2151
2152         if (i != pSid->SubAuthorityCount)
2153             goto lend; /* ERROR_INVALID_SID */
2154
2155         bret = TRUE;
2156     }
2157     else /* String constant format  - Only available in winxp and above */
2158     {
2159         pSid->Revision = SDDL_REVISION;
2160         pSid->SubAuthorityCount = 1;
2161
2162         FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
2163
2164         /* TODO: Lookup string of well-known SIDs in table */
2165         pSid->IdentifierAuthority.Value[5] = 0;
2166         pSid->SubAuthority[0] = 0;
2167
2168         bret = TRUE;
2169     }
2170
2171 lend:
2172     if (!bret)
2173         SetLastError(ERROR_INVALID_SID);
2174
2175     return bret;
2176 }
2177
2178 /******************************************************************************
2179  * GetNamedSecurityInfoA [ADVAPI32.@]
2180  */
2181 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
2182         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2183         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2184         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2185 {
2186     DWORD len;
2187     LPWSTR wstr = NULL;
2188     DWORD r;
2189
2190     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
2191         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2192
2193     if( pObjectName )
2194     {
2195         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2196         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2197         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2198     }
2199
2200     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
2201                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
2202
2203     if( wstr )
2204         HeapFree( GetProcessHeap(), 0, wstr );
2205
2206     return r;
2207 }
2208
2209 /******************************************************************************
2210  * GetNamedSecurityInfoW [ADVAPI32.@]
2211  */
2212 DWORD WINAPI GetNamedSecurityInfoW(LPWSTR pObjectName,
2213         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2214         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2215         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2216 {
2217     FIXME("%s %d %ld %p %p %p %p %p\n", debugstr_w(pObjectName), ObjectType, SecurityInfo,
2218         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2219     return ERROR_CALL_NOT_IMPLEMENTED;
2220 }