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