ShellExecuteEx, ExtractIconEx, SHFileOperation, SHGetFileInfo,
[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  * LsaStorePrivateData [ADVAPI32.@]
1501  */
1502 NTSTATUS WINAPI LsaStorePrivateData( LSA_HANDLE PolicyHandle,
1503     PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING PrivateData)
1504 {
1505     FIXME("%p %p %p\n", PolicyHandle, KeyName, PrivateData);
1506     return STATUS_OBJECT_NAME_NOT_FOUND;
1507 }
1508
1509 /******************************************************************************
1510  * LsaRetrievePrivateData [ADVAPI32.@]
1511  */
1512 NTSTATUS WINAPI LsaRetrievePrivateData( LSA_HANDLE PolicyHandle,
1513     PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING* PrivateData)
1514 {
1515     FIXME("%p %p %p\n", PolicyHandle, KeyName, PrivateData);
1516     return STATUS_OBJECT_NAME_NOT_FOUND;
1517 }
1518
1519 /******************************************************************************
1520  * LsaNtStatusToWinError [ADVAPI32.@]
1521  *
1522  * PARAMS
1523  *   Status [I]
1524  */
1525 ULONG WINAPI
1526 LsaNtStatusToWinError(NTSTATUS Status)
1527 {
1528     return RtlNtStatusToDosError(Status);
1529 }
1530
1531 /******************************************************************************
1532  * NotifyBootConfigStatus [ADVAPI32.@]
1533  *
1534  * PARAMS
1535  *   x1 []
1536  */
1537 BOOL WINAPI
1538 NotifyBootConfigStatus( DWORD x1 )
1539 {
1540         FIXME("(0x%08lx):stub\n",x1);
1541         return 1;
1542 }
1543
1544 /******************************************************************************
1545  * RevertToSelf [ADVAPI32.@]
1546  *
1547  * PARAMS
1548  *   void []
1549  */
1550 BOOL WINAPI
1551 RevertToSelf( void )
1552 {
1553         FIXME("(), stub\n");
1554         return TRUE;
1555 }
1556
1557 /******************************************************************************
1558  * ImpersonateSelf [ADVAPI32.@]
1559  */
1560 BOOL WINAPI
1561 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1562 {
1563         return RtlImpersonateSelf(ImpersonationLevel);
1564 }
1565
1566 /******************************************************************************
1567  * ImpersonateLoggedOnUser [ADVAPI32.@]
1568  */
1569 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
1570 {
1571     FIXME("(%p):stub returning FALSE\n", hToken);
1572     return FALSE;
1573 }
1574
1575 /******************************************************************************
1576  * AccessCheck [ADVAPI32.@]
1577  *
1578  * FIXME check cast LPBOOL to PBOOLEAN
1579  */
1580 BOOL WINAPI
1581 AccessCheck(
1582         PSECURITY_DESCRIPTOR SecurityDescriptor,
1583         HANDLE ClientToken,
1584         DWORD DesiredAccess,
1585         PGENERIC_MAPPING GenericMapping,
1586         PPRIVILEGE_SET PrivilegeSet,
1587         LPDWORD PrivilegeSetLength,
1588         LPDWORD GrantedAccess,
1589         LPBOOL AccessStatus)
1590 {
1591         CallWin32ToNt (NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
1592           GenericMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess, (PBOOLEAN)AccessStatus));
1593 }
1594
1595
1596 /******************************************************************************
1597  * AccessCheckByType [ADVAPI32.@]
1598  */
1599 BOOL WINAPI AccessCheckByType(
1600     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
1601     PSID PrincipalSelfSid,
1602     HANDLE ClientToken, 
1603     DWORD DesiredAccess, 
1604     POBJECT_TYPE_LIST ObjectTypeList,
1605     DWORD ObjectTypeListLength,
1606     PGENERIC_MAPPING GenericMapping,
1607     PPRIVILEGE_SET PrivilegeSet,
1608     LPDWORD PrivilegeSetLength, 
1609     LPDWORD GrantedAccess,
1610     LPBOOL AccessStatus)
1611 {
1612         FIXME("stub\n");
1613
1614         *AccessStatus = TRUE;
1615
1616         return !*AccessStatus;
1617 }
1618
1619
1620 /*************************************************************************
1621  * SetKernelObjectSecurity [ADVAPI32.@]
1622  */
1623 BOOL WINAPI SetKernelObjectSecurity (
1624         IN HANDLE Handle,
1625         IN SECURITY_INFORMATION SecurityInformation,
1626         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
1627 {
1628         CallWin32ToNt (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
1629 }
1630
1631
1632 /******************************************************************************
1633  *  AddAuditAccessAce [ADVAPI32.@]
1634  */
1635 BOOL WINAPI AddAuditAccessAce(
1636         IN OUT PACL pAcl,
1637         IN DWORD dwAceRevision,
1638         IN DWORD dwAccessMask,
1639         IN PSID pSid,
1640         IN BOOL bAuditSuccess,
1641         IN BOOL bAuditFailure)
1642 {
1643         FIXME("Stub\n");
1644         return TRUE;
1645 }
1646
1647 /******************************************************************************
1648  * LookupAccountNameA [ADVAPI32.@]
1649  */
1650 BOOL WINAPI
1651 LookupAccountNameA(
1652         IN LPCSTR system,
1653         IN LPCSTR account,
1654         OUT PSID sid,
1655         OUT LPDWORD cbSid,
1656         LPSTR ReferencedDomainName,
1657         IN OUT LPDWORD cbReferencedDomainName,
1658         OUT PSID_NAME_USE name_use )
1659 {
1660     /* Default implementation: Always return a default SID */
1661     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1662     BOOL ret;
1663     PSID pSid;
1664     static const char dm[] = "DOMAIN";
1665
1666     FIXME("(%s,%s,%p,%p,%p,%p,%p), stub.\n",system,account,sid,cbSid,ReferencedDomainName,cbReferencedDomainName,name_use);
1667
1668     ret = AllocateAndInitializeSid(&identifierAuthority,
1669         2,
1670         SECURITY_BUILTIN_DOMAIN_RID,
1671         DOMAIN_ALIAS_RID_ADMINS,
1672         0, 0, 0, 0, 0, 0,
1673         &pSid);
1674
1675     if (!ret)
1676        return FALSE;
1677     if(!RtlValidSid(pSid))
1678     {
1679        FreeSid(pSid);
1680        return FALSE;
1681     }
1682
1683     if (sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1684        CopySid(*cbSid, sid, pSid);
1685     if (*cbSid < GetLengthSid(pSid))
1686     {
1687        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1688        ret = FALSE;
1689     }
1690     *cbSid = GetLengthSid(pSid);
1691     
1692     if (ReferencedDomainName != NULL && (*cbReferencedDomainName > strlen(dm)))
1693       strcpy(ReferencedDomainName, dm);
1694     if (*cbReferencedDomainName <= strlen(dm))
1695     {
1696        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1697        ret = FALSE;
1698     }
1699     *cbReferencedDomainName = strlen(dm)+1;
1700
1701     FreeSid(pSid);
1702
1703     return ret;
1704 }
1705
1706 /******************************************************************************
1707  * PrivilegeCheck [ADVAPI32.@]
1708  */
1709 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
1710 {
1711         FIXME("stub %p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
1712         if (pfResult)
1713                 *pfResult=TRUE;
1714         return TRUE;
1715 }
1716
1717 /******************************************************************************
1718  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1719  */
1720 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
1721   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1722   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1723   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1724 {
1725         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
1726                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
1727                 SecurityDescriptor, DesiredAccess, GenericMapping,
1728                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1729         return TRUE;
1730 }
1731
1732 /******************************************************************************
1733  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
1734  */
1735 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
1736   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1737   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1738   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1739 {
1740         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
1741                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
1742                 SecurityDescriptor, DesiredAccess, GenericMapping,
1743                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1744         return TRUE;
1745 }
1746
1747
1748 /******************************************************************************
1749  * GetSecurityInfo [ADVAPI32.@]
1750  */
1751 DWORD WINAPI GetSecurityInfo(
1752     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
1753     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
1754     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
1755     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
1756 )
1757 {
1758   FIXME("stub!\n");
1759   return ERROR_BAD_PROVIDER;
1760 }
1761
1762 /******************************************************************************
1763  * GetSecurityInfoExW [ADVAPI32.@]
1764  */
1765 DWORD WINAPI GetSecurityInfoExW(
1766         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
1767         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
1768         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
1769         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
1770 )
1771 {
1772   FIXME("stub!\n");
1773   return ERROR_BAD_PROVIDER; 
1774 }
1775
1776 /******************************************************************************
1777  * BuildTrusteeWithSidA [ADVAPI32.@]
1778  */
1779 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
1780 {
1781     TRACE("%p %p\n", pTrustee, pSid);
1782
1783     pTrustee->pMultipleTrustee = NULL;
1784     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1785     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
1786     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1787     pTrustee->ptstrName = (LPSTR) pSid;
1788 }
1789
1790 /******************************************************************************
1791  * BuildTrusteeWithSidW [ADVAPI32.@]
1792  */
1793 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
1794 {
1795     TRACE("%p %p\n", pTrustee, pSid);
1796
1797     pTrustee->pMultipleTrustee = NULL;
1798     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1799     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
1800     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1801     pTrustee->ptstrName = (LPWSTR) pSid;
1802 }
1803
1804 /******************************************************************************
1805  * BuildTrusteeWithNameA [ADVAPI32.@]
1806  */
1807 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
1808 {
1809     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
1810
1811     pTrustee->pMultipleTrustee = NULL;
1812     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1813     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
1814     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1815     pTrustee->ptstrName = name;
1816 }
1817
1818 /******************************************************************************
1819  * BuildTrusteeWithNameW [ADVAPI32.@]
1820  */
1821 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
1822 {
1823     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
1824
1825     pTrustee->pMultipleTrustee = NULL;
1826     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
1827     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
1828     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
1829     pTrustee->ptstrName = name;
1830 }
1831
1832 /******************************************************************************
1833  * SetEntriesInAclA [ADVAPI32.@]
1834  */
1835 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
1836                                PACL OldAcl, PACL* NewAcl )
1837 {
1838     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1839     return ERROR_CALL_NOT_IMPLEMENTED;
1840 }
1841
1842 /******************************************************************************
1843  * SetEntriesInAclW [ADVAPI32.@]
1844  */
1845 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
1846                                PACL OldAcl, PACL* NewAcl )
1847 {
1848     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
1849     return ERROR_CALL_NOT_IMPLEMENTED;
1850 }
1851
1852 /******************************************************************************
1853  * SetNamedSecurityInfoA [ADVAPI32.@]
1854  */
1855 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
1856         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1857         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1858 {
1859     DWORD len;
1860     LPWSTR wstr = NULL;
1861     DWORD r;
1862
1863     TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
1864            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1865
1866     if( pObjectName )
1867     {
1868         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
1869         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
1870         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
1871     }
1872
1873     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
1874                            psidGroup, pDacl, pSacl );
1875
1876     if( wstr )
1877         HeapFree( GetProcessHeap(), 0, wstr );
1878
1879     return r;
1880 }
1881
1882 /******************************************************************************
1883  * AreAnyAccessesGranted [ADVAPI32.@]
1884  *
1885  * Determines whether or not any of a set of specified access permissions have
1886  * been granted or not.
1887  *
1888  * PARAMS
1889  *   GrantedAccess [I] The permissions that have been granted.
1890  *   DesiredAccess [I] The permissions that you want to have.
1891  *
1892  * RETURNS
1893  *   Nonzero if any of the permissions have been granted, zero if none of the
1894  *   permissions have been granted.
1895  */
1896
1897 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
1898 {
1899     return (GrantedAccess & DesiredAccess) != 0;
1900 }
1901
1902 /******************************************************************************
1903  * SetNamedSecurityInfoW [ADVAPI32.@]
1904  */
1905 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
1906         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
1907         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
1908 {
1909     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
1910            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
1911     return ERROR_CALL_NOT_IMPLEMENTED;
1912 }
1913
1914 /******************************************************************************
1915  * GetExplicitEntriesFromAclA [ADVAPI32.@]
1916  */
1917 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
1918         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
1919 {
1920     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1921     return ERROR_CALL_NOT_IMPLEMENTED;
1922 }
1923
1924 /******************************************************************************
1925  * GetExplicitEntriesFromAclW [ADVAPI32.@]
1926  */
1927 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
1928         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
1929 {
1930     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
1931     return ERROR_CALL_NOT_IMPLEMENTED;
1932 }
1933
1934
1935 /******************************************************************************
1936  * ParseAclStringFlags
1937  */
1938 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
1939 {
1940     DWORD flags = 0;
1941     LPCWSTR szAcl = *StringAcl;
1942
1943     while (*szAcl != '(')
1944     {
1945         if (*szAcl == 'P')
1946         {
1947             flags |= SE_DACL_PROTECTED;
1948         }
1949         else if (*szAcl == 'A')
1950         {
1951             szAcl++;
1952             if (*szAcl == 'R')
1953                 flags |= SE_DACL_AUTO_INHERIT_REQ;
1954             else if (*szAcl == 'I')
1955                 flags |= SE_DACL_AUTO_INHERITED;
1956         }
1957         szAcl++;
1958     }
1959
1960     *StringAcl = szAcl;
1961     return flags;
1962 }
1963
1964 /******************************************************************************
1965  * ParseAceStringType
1966  */
1967 ACEFLAG AceType[] =
1968 {
1969     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
1970     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
1971     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
1972     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
1973     /*
1974     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
1975     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
1976     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
1977     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
1978     */
1979     { NULL, 0 },
1980 };
1981
1982 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
1983 {
1984     UINT len = 0;
1985     LPCWSTR szAcl = *StringAcl;
1986     LPACEFLAG lpaf = AceType;
1987
1988     while (lpaf->wstr &&
1989         (len = strlenW(lpaf->wstr)) &&
1990         strncmpW(lpaf->wstr, szAcl, len))
1991         lpaf++;
1992
1993     if (!lpaf->wstr)
1994         return 0;
1995
1996     *StringAcl += len;
1997     return lpaf->value;
1998 }
1999
2000
2001 /******************************************************************************
2002  * ParseAceStringFlags
2003  */
2004 ACEFLAG AceFlags[] =
2005 {
2006     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2007     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
2008     { SDDL_INHERITED,         INHERITED_ACE },
2009     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
2010     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
2011     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
2012     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
2013     { NULL, 0 },
2014 };
2015
2016 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2017 {
2018     UINT len = 0;
2019     BYTE flags = 0;
2020     LPCWSTR szAcl = *StringAcl;
2021
2022     while (*szAcl != ';')
2023     {
2024         LPACEFLAG lpaf = AceFlags;
2025
2026         while (lpaf->wstr &&
2027                (len = strlenW(lpaf->wstr)) &&
2028                strncmpW(lpaf->wstr, szAcl, len))
2029             lpaf++;
2030
2031         if (!lpaf->wstr)
2032             return 0;
2033
2034         flags |= lpaf->value;
2035         szAcl += len;
2036     }
2037
2038     *StringAcl = szAcl;
2039     return flags;
2040 }
2041
2042
2043 /******************************************************************************
2044  * ParseAceStringRights
2045  */
2046 ACEFLAG AceRights[] =
2047 {
2048     { SDDL_GENERIC_ALL,     GENERIC_ALL },
2049     { SDDL_GENERIC_READ,    GENERIC_READ },
2050     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
2051     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2052     { SDDL_READ_CONTROL,    READ_CONTROL },
2053     { SDDL_STANDARD_DELETE, DELETE },
2054     { SDDL_WRITE_DAC,       WRITE_DAC },
2055     { SDDL_WRITE_OWNER,     WRITE_OWNER },
2056     { NULL, 0 },
2057 };
2058
2059 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2060 {
2061     UINT len = 0;
2062     DWORD rights = 0;
2063     LPCWSTR szAcl = *StringAcl;
2064
2065     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2066     {
2067         LPCWSTR p = szAcl;
2068
2069         while (*p && *p != ';')
2070             p++;
2071
2072         if (p - szAcl <= 8)
2073         {
2074             rights = strtoulW(szAcl, NULL, 16);
2075             *StringAcl = p;
2076         }
2077         else
2078             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2079     }
2080     else
2081     {
2082         while (*szAcl != ';')
2083         {
2084             LPACEFLAG lpaf = AceRights;
2085
2086             while (lpaf->wstr &&
2087                (len = strlenW(lpaf->wstr)) &&
2088                strncmpW(lpaf->wstr, szAcl, len))
2089             {
2090                lpaf++;
2091             }
2092
2093             if (!lpaf->wstr)
2094                 return 0;
2095
2096             rights |= lpaf->value;
2097             szAcl += len;
2098         }
2099     }
2100
2101     *StringAcl = szAcl;
2102     return rights;
2103 }
2104
2105
2106 /******************************************************************************
2107  * ParseStringAclToAcl
2108  * 
2109  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
2110  */
2111 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
2112     PACL pAcl, LPDWORD cBytes)
2113 {
2114     DWORD val;
2115     DWORD sidlen;
2116     DWORD length = sizeof(ACL);
2117     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
2118
2119     TRACE("%s\n", debugstr_w(StringAcl));
2120
2121     if (!StringAcl)
2122         return FALSE;
2123
2124     if (pAcl) /* pAce is only useful if we're setting values */
2125         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
2126
2127     /* Parse ACL flags */
2128     *lpdwFlags = ParseAclStringFlags(&StringAcl);
2129
2130     /* Parse ACE */
2131     while (*StringAcl == '(')
2132     {
2133         StringAcl++;
2134
2135         /* Parse ACE type */
2136         val = ParseAceStringType(&StringAcl);
2137         if (pAce)
2138             pAce->Header.AceType = (BYTE) val;
2139         if (*StringAcl != ';')
2140             goto lerr;
2141         StringAcl++;
2142
2143         /* Parse ACE flags */
2144         val = ParseAceStringFlags(&StringAcl);
2145         if (pAce)
2146             pAce->Header.AceFlags = (BYTE) val;
2147         if (*StringAcl != ';')
2148             goto lerr;
2149         StringAcl++;
2150
2151         /* Parse ACE rights */
2152         val = ParseAceStringRights(&StringAcl);
2153         if (pAce)
2154             pAce->Mask = val;
2155         if (*StringAcl != ';')
2156             goto lerr;
2157         StringAcl++;
2158
2159         /* Parse ACE object guid */
2160         if (*StringAcl != ';')
2161         {
2162             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2163             goto lerr;
2164         }
2165         StringAcl++;
2166
2167         /* Parse ACE inherit object guid */
2168         if (*StringAcl != ';')
2169         {
2170             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2171             goto lerr;
2172         }
2173         StringAcl++;
2174
2175         /* Parse ACE account sid */
2176         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
2177         {
2178             while (*StringAcl && *StringAcl != ')')
2179                 StringAcl++;
2180         }
2181
2182         if (*StringAcl != ')')
2183             goto lerr;
2184         StringAcl++;
2185
2186         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
2187     }
2188
2189     *cBytes = length;
2190     return TRUE;
2191
2192 lerr:
2193     WARN("Invalid ACE string format\n");
2194     return FALSE;
2195 }
2196
2197
2198 /******************************************************************************
2199  * ParseStringSecurityDescriptorToSecurityDescriptor
2200  */
2201 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
2202     LPCWSTR StringSecurityDescriptor,
2203     SECURITY_DESCRIPTOR* SecurityDescriptor,
2204     LPDWORD cBytes)
2205 {
2206     BOOL bret = FALSE;
2207     WCHAR toktype;
2208     WCHAR tok[MAX_PATH];
2209     LPCWSTR lptoken;
2210     LPBYTE lpNext = NULL;
2211
2212     *cBytes = 0;
2213
2214     if (SecurityDescriptor)
2215         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
2216
2217     while (*StringSecurityDescriptor)
2218     {
2219         toktype = *StringSecurityDescriptor;
2220
2221         /* Expect char identifier followed by ':' */
2222         StringSecurityDescriptor++;
2223         if (*StringSecurityDescriptor != ':')
2224         {
2225             SetLastError(ERROR_INVALID_PARAMETER);
2226             goto lend;
2227         }
2228         StringSecurityDescriptor++;
2229
2230         /* Extract token */
2231         lptoken = StringSecurityDescriptor;
2232         while (*lptoken && *lptoken != ':')
2233             lptoken++;
2234
2235         if (*lptoken)
2236             lptoken--;
2237
2238         strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor);
2239
2240         switch (toktype)
2241         {
2242             case 'O':
2243             {
2244                 DWORD bytes;
2245
2246                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2247                     goto lend;
2248
2249                 if (SecurityDescriptor)
2250                 {
2251                     SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
2252                         (DWORD) SecurityDescriptor);
2253                     lpNext += bytes; /* Advance to next token */
2254                 }
2255
2256                 *cBytes += bytes;
2257
2258                 break;
2259             }
2260
2261             case 'G':
2262             {
2263                 DWORD bytes;
2264
2265                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2266                     goto lend;
2267
2268                 if (SecurityDescriptor)
2269                 {
2270                     SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - 
2271                         (DWORD) SecurityDescriptor);
2272                     lpNext += bytes; /* Advance to next token */
2273                 }
2274
2275                 *cBytes += bytes;
2276
2277                 break;
2278             }
2279
2280             case 'D':
2281             {
2282                 DWORD flags;
2283                 DWORD bytes;
2284
2285                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2286                     goto lend;
2287
2288                 if (SecurityDescriptor)
2289                 {
2290                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
2291                     SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
2292                         (DWORD) SecurityDescriptor);
2293                     lpNext += bytes; /* Advance to next token */
2294                 }
2295
2296                 *cBytes += bytes;
2297
2298                 break;
2299             }
2300
2301             case 'S':
2302             {
2303                 DWORD flags;
2304                 DWORD bytes;
2305
2306                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2307                     goto lend;
2308
2309                 if (SecurityDescriptor)
2310                 {
2311                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
2312                     SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
2313                         (DWORD) SecurityDescriptor);
2314                     lpNext += bytes; /* Advance to next token */
2315                 }
2316
2317                 *cBytes += bytes;
2318
2319                 break;
2320             }
2321
2322             default:
2323                 FIXME("Unknown token\n");
2324                 SetLastError(ERROR_INVALID_PARAMETER);
2325                 goto lend;
2326         }
2327
2328         StringSecurityDescriptor = lptoken;
2329     }
2330
2331     bret = TRUE;
2332
2333 lend:
2334     return bret;
2335 }
2336
2337 /******************************************************************************
2338  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2339  */
2340 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2341         LPCWSTR StringSecurityDescriptor,
2342         DWORD StringSDRevision,
2343         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2344         PULONG SecurityDescriptorSize)
2345 {
2346     DWORD cBytes;
2347     SECURITY_DESCRIPTOR* psd;
2348     BOOL bret = FALSE;
2349
2350     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2351
2352     if (GetVersion() & 0x80000000)
2353     {
2354         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2355         goto lend;
2356     }
2357     else if (StringSDRevision != SID_REVISION)
2358     {
2359         SetLastError(ERROR_UNKNOWN_REVISION);
2360         goto lend;
2361     }
2362
2363     /* Compute security descriptor length */
2364     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2365         NULL, &cBytes))
2366         goto lend;
2367
2368     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
2369         GMEM_ZEROINIT, cBytes);
2370
2371     psd->Revision = SID_REVISION;
2372     psd->Control |= SE_SELF_RELATIVE;
2373
2374     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2375         psd, &cBytes))
2376     {
2377         LocalFree(psd);
2378         goto lend;
2379     }
2380
2381     if (SecurityDescriptorSize)
2382         *SecurityDescriptorSize = cBytes;
2383
2384     bret = TRUE;
2385  
2386 lend:
2387     TRACE(" ret=%d\n", bret);
2388     return bret;
2389 }
2390
2391 /******************************************************************************
2392  * ConvertStringSidToSidW [ADVAPI32.@]
2393  */
2394 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
2395 {
2396     BOOL bret = FALSE;
2397     DWORD cBytes;
2398
2399     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
2400     if (GetVersion() & 0x80000000)
2401         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2402     else if (!StringSid || !Sid)
2403         SetLastError(ERROR_INVALID_PARAMETER);
2404     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
2405     {
2406         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
2407
2408         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
2409         if (!bret)
2410             LocalFree(*Sid); 
2411     }
2412     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
2413     return bret;
2414 }
2415
2416 /******************************************************************************
2417  * ConvertStringSidToSidA [ADVAPI32.@]
2418  */
2419 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
2420 {
2421     BOOL bret = FALSE;
2422
2423     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
2424     if (GetVersion() & 0x80000000)
2425         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2426     else if (!StringSid || !Sid)
2427         SetLastError(ERROR_INVALID_PARAMETER);
2428     else
2429     {
2430         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
2431         LPWSTR wStringSid = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
2432          len * sizeof(WCHAR));
2433
2434         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
2435         bret = ConvertStringSidToSidW(wStringSid, Sid);
2436         HeapFree(GetProcessHeap(), 0, wStringSid);
2437     }
2438     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
2439     return bret;
2440 }
2441
2442 /******************************************************************************
2443  * ConvertSidToStringSidW [ADVAPI32.@]
2444  *
2445  *  format of SID string is:
2446  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
2447  *  where
2448  *    <rev> is the revision of the SID encoded as decimal
2449  *    <auth> is the identifier authority encoded as hex
2450  *    <subauthN> is the subauthority id encoded as decimal
2451  */
2452 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
2453 {
2454     DWORD sz, i;
2455     LPWSTR str;
2456     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
2457     WCHAR subauthfmt[] = { '-','%','u',0 };
2458     SID* pisid=pSid;
2459
2460     TRACE("%p %p\n", pSid, pstr );
2461
2462     if( !IsValidSid( pSid ) )
2463         return FALSE;
2464
2465     if (pisid->Revision != SDDL_REVISION)
2466         return FALSE;
2467     if (pisid->IdentifierAuthority.Value[0] ||
2468      pisid->IdentifierAuthority.Value[1])
2469     {
2470         FIXME("not matching MS' bugs\n");
2471         return FALSE;
2472     }
2473
2474     sz = 14 + pisid->SubAuthorityCount * 11;
2475     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
2476     sprintfW( str, fmt, pisid->Revision, MAKELONG(
2477      MAKEWORD( pisid->IdentifierAuthority.Value[5],
2478      pisid->IdentifierAuthority.Value[4] ),
2479      MAKEWORD( pisid->IdentifierAuthority.Value[3],
2480      pisid->IdentifierAuthority.Value[2] ) ) );
2481     for( i=0; i<pisid->SubAuthorityCount; i++ )
2482         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
2483     *pstr = str;
2484
2485     return TRUE;
2486 }
2487
2488 /******************************************************************************
2489  * ConvertSidToStringSidA [ADVAPI32.@]
2490  */
2491 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
2492 {
2493     LPWSTR wstr = NULL;
2494     LPSTR str;
2495     UINT len;
2496
2497     TRACE("%p %p\n", pSid, pstr );
2498
2499     if( !ConvertSidToStringSidW( pSid, &wstr ) )
2500         return FALSE;
2501
2502     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
2503     str = LocalAlloc( 0, len );
2504     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
2505     LocalFree( wstr );
2506
2507     *pstr = str;
2508
2509     return TRUE;
2510 }
2511
2512 /******************************************************************************
2513  * ComputeStringSidSize
2514  */
2515 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
2516 {
2517     int ctok = 0;
2518     DWORD size = sizeof(SID);
2519
2520     while (*StringSid)
2521     {
2522         if (*StringSid == '-')
2523             ctok++;
2524         StringSid++;
2525     }
2526
2527     if (ctok > 3)
2528         size += (ctok - 3) * sizeof(DWORD);
2529
2530     return size;
2531 }
2532
2533 /******************************************************************************
2534  * ParseStringSidToSid
2535  */
2536 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
2537 {
2538     BOOL bret = FALSE;
2539     SID* pisid=pSid;
2540
2541     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
2542     if (!StringSid)
2543     {
2544         SetLastError(ERROR_INVALID_PARAMETER);
2545         TRACE("StringSid is NULL, returning FALSE\n");
2546         return FALSE;
2547     }
2548
2549     *cBytes = ComputeStringSidSize(StringSid);
2550     if (!pisid) /* Simply compute the size */
2551     {
2552         TRACE("only size requested, returning TRUE\n");
2553         return TRUE;
2554     }
2555
2556     if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
2557     {
2558         DWORD i = 0, identAuth;
2559         DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
2560
2561         StringSid += 2; /* Advance to Revision */
2562         pisid->Revision = atoiW(StringSid);
2563
2564         if (pisid->Revision != SDDL_REVISION)
2565         {
2566             TRACE("Revision %d is unknown\n", pisid->Revision);
2567             goto lend; /* ERROR_INVALID_SID */
2568         }
2569         if (csubauth == 0)
2570         {
2571             TRACE("SubAuthorityCount is 0\n");
2572             goto lend; /* ERROR_INVALID_SID */
2573         }
2574
2575         pisid->SubAuthorityCount = csubauth;
2576
2577         /* Advance to identifier authority */
2578         while (*StringSid && *StringSid != '-')
2579             StringSid++;
2580         if (*StringSid == '-')
2581             StringSid++;
2582
2583         /* MS' implementation can't handle values greater than 2^32 - 1, so
2584          * we don't either; assume most significant bytes are always 0
2585          */
2586         pisid->IdentifierAuthority.Value[0] = 0;
2587         pisid->IdentifierAuthority.Value[1] = 0;
2588         identAuth = atoiW(StringSid);
2589         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
2590         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
2591         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
2592         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
2593
2594         /* Advance to first sub authority */
2595         while (*StringSid && *StringSid != '-')
2596             StringSid++;
2597         if (*StringSid == '-')
2598             StringSid++;
2599
2600         while (*StringSid)
2601         {       
2602             while (*StringSid && *StringSid != '-')
2603                 StringSid++;
2604
2605             pisid->SubAuthority[i++] = atoiW(StringSid);
2606         }
2607
2608         if (i != pisid->SubAuthorityCount)
2609             goto lend; /* ERROR_INVALID_SID */
2610
2611         bret = TRUE;
2612     }
2613     else /* String constant format  - Only available in winxp and above */
2614     {
2615         pisid->Revision = SDDL_REVISION;
2616         pisid->SubAuthorityCount = 1;
2617
2618         FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
2619
2620         /* TODO: Lookup string of well-known SIDs in table */
2621         pisid->IdentifierAuthority.Value[5] = 0;
2622         pisid->SubAuthority[0] = 0;
2623
2624         bret = TRUE;
2625     }
2626
2627 lend:
2628     if (!bret)
2629         SetLastError(ERROR_INVALID_SID);
2630
2631     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
2632     return bret;
2633 }
2634
2635 /******************************************************************************
2636  * GetNamedSecurityInfoA [ADVAPI32.@]
2637  */
2638 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
2639         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2640         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2641         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2642 {
2643     DWORD len;
2644     LPWSTR wstr = NULL;
2645     DWORD r;
2646
2647     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
2648         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2649
2650     if( pObjectName )
2651     {
2652         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2653         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2654         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2655     }
2656
2657     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
2658                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
2659
2660     if( wstr )
2661         HeapFree( GetProcessHeap(), 0, wstr );
2662
2663     return r;
2664 }
2665
2666 /******************************************************************************
2667  * GetNamedSecurityInfoW [ADVAPI32.@]
2668  */
2669 DWORD WINAPI GetNamedSecurityInfoW(LPWSTR pObjectName,
2670         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2671         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
2672         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
2673 {
2674     FIXME("%s %d %ld %p %p %p %p %p\n", debugstr_w(pObjectName), ObjectType, SecurityInfo,
2675         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
2676     return ERROR_CALL_NOT_IMPLEMENTED;
2677 }
2678
2679 /******************************************************************************
2680  * DecryptFileW [ADVAPI32.@]
2681  */
2682 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
2683 {
2684     FIXME("%s %08lx\n", debugstr_w(lpFileName), dwReserved);
2685     return TRUE;
2686 }
2687
2688 /******************************************************************************
2689  * DecryptFileA [ADVAPI32.@]
2690  */
2691 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
2692 {
2693     FIXME("%s %08lx\n", debugstr_a(lpFileName), dwReserved);
2694     return TRUE;
2695 }
2696
2697 /******************************************************************************
2698  * EncryptFileW [ADVAPI32.@]
2699  */
2700 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
2701 {
2702     FIXME("%s\n", debugstr_w(lpFileName));
2703     return TRUE;
2704 }
2705
2706 /******************************************************************************
2707  * EncryptFileA [ADVAPI32.@]
2708  */
2709 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
2710 {
2711     FIXME("%s\n", debugstr_a(lpFileName));
2712     return TRUE;
2713 }