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