Implement IsTokenRestricted.
[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 #include "winsvc.h"
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 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
61
62 /*
63  * ACE access rights
64  */
65 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
66 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
67 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
68 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
69 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
70 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
71 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
72 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
73
74 /*
75  * ACE types
76  */
77 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
78 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
79 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
80 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
81 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
82 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
83 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
84 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
85
86 /*
87  * ACE flags
88  */
89 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
90 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
91 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
92 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
93 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
94 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
95 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
96
97 /* set last error code from NT status and get the proper boolean return value */
98 /* used for functions that are a simple wrapper around the corresponding ntdll API */
99 static inline BOOL set_ntstatus( NTSTATUS status )
100 {
101     if (status) SetLastError( RtlNtStatusToDosError( status ));
102     return !status;
103 }
104
105 static void dumpLsaAttributes( PLSA_OBJECT_ATTRIBUTES oa )
106 {
107         if (oa)
108         {
109           TRACE("\n\tlength=%lu, rootdir=%p, objectname=%s\n\tattr=0x%08lx, sid=%p qos=%p\n",
110                 oa->Length, oa->RootDirectory,
111                 oa->ObjectName?debugstr_w(oa->ObjectName->Buffer):"null",
112                 oa->Attributes, oa->SecurityDescriptor, oa->SecurityQualityOfService);
113         }
114 }
115
116 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
117
118 static void GetWorldAccessACL(PACL pACL)
119 {
120     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
121
122     pACL->AclRevision = ACL_REVISION;
123     pACL->Sbz1 = 0;
124     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
125     pACL->AceCount = 1;
126     pACL->Sbz2 = 0;
127
128     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
129     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
130     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
131     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
132     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
133 }
134
135 /************************************************************
136  *                ADVAPI_IsLocalComputer
137  *
138  * Checks whether the server name indicates local machine.
139  */
140 static BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
141 {
142     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
143     BOOL Result;
144     LPWSTR buf;
145
146     if (!ServerName || !ServerName[0])
147         return TRUE;
148     
149     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
150     Result = GetComputerNameW(buf,  &dwSize);
151     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
152         ServerName += 2;
153     Result = Result && !lstrcmpW(ServerName, buf);
154     HeapFree(GetProcessHeap(), 0, buf);
155
156     return Result;
157 }
158
159 #define ADVAPI_ForceLocalComputer(ServerName, FailureCode) \
160     if (!ADVAPI_IsLocalComputer(ServerName)) \
161     { \
162         FIXME("Action Implemented for local computer only. " \
163               "Requested for server %s\n", debugstr_w(ServerName)); \
164         return FailureCode; \
165     }
166
167 /*      ##############################
168         ######  TOKEN FUNCTIONS ######
169         ##############################
170 */
171
172 /******************************************************************************
173  * OpenProcessToken                     [ADVAPI32.@]
174  * Opens the access token associated with a process handle.
175  *
176  * PARAMS
177  *   ProcessHandle [I] Handle to process
178  *   DesiredAccess [I] Desired access to process
179  *   TokenHandle   [O] Pointer to handle of open access token
180  *
181  * RETURNS
182  *  Success: TRUE. TokenHandle contains the access token.
183  *  Failure: FALSE.
184  *
185  * NOTES
186  *  See NtOpenProcessToken.
187  */
188 BOOL WINAPI
189 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
190                   HANDLE *TokenHandle )
191 {
192         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
193 }
194
195 /******************************************************************************
196  * OpenThreadToken [ADVAPI32.@]
197  *
198  * Opens the access token associated with a thread handle.
199  *
200  * PARAMS
201  *   ThreadHandle  [I] Handle to process
202  *   DesiredAccess [I] Desired access to the thread
203  *   OpenAsSelf    [I] ???
204  *   TokenHandle   [O] Destination for the token handle
205  *
206  * RETURNS
207  *  Success: TRUE. TokenHandle contains the access token.
208  *  Failure: FALSE.
209  *
210  * NOTES
211  *  See NtOpenThreadToken.
212  */
213 BOOL WINAPI
214 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
215                  BOOL OpenAsSelf, HANDLE *TokenHandle)
216 {
217         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
218 }
219
220 BOOL WINAPI
221 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
222                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
223 {
224     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
225                                              PreviousState, ReturnLength));
226 }
227
228 /******************************************************************************
229  * AdjustTokenPrivileges [ADVAPI32.@]
230  *
231  * Adjust the privileges of an open token handle.
232  * 
233  * PARAMS
234  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
235  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
236  *  NewState             [I]   Desired new privileges of the token
237  *  BufferLength         [I]   Length of NewState
238  *  PreviousState        [O]   Destination for the previous state
239  *  ReturnLength         [I/O] Size of PreviousState
240  *
241  *
242  * RETURNS
243  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
244  *  Failure: FALSE.
245  *
246  * NOTES
247  *  See NtAdjustPrivilegesToken.
248  */
249 BOOL WINAPI
250 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
251                        LPVOID NewState, DWORD BufferLength,
252                        LPVOID PreviousState, LPDWORD ReturnLength )
253 {
254     NTSTATUS status;
255
256     TRACE("\n");
257     
258     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
259                                                      NewState, BufferLength, PreviousState,
260                                                      ReturnLength);
261     SetLastError( RtlNtStatusToDosError( status ));
262     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
263         return TRUE;
264     else
265         return FALSE;
266 }
267
268 /******************************************************************************
269  * CheckTokenMembership [ADVAPI32.@]
270  *
271  * Determine if an access token is a member of a SID.
272  * 
273  * PARAMS
274  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
275  *   SidToCheck  [I] SID that possibly contains the token
276  *   IsMember    [O] Destination for result.
277  *
278  * RETURNS
279  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
280  *  Failure: FALSE.
281  */
282 BOOL WINAPI
283 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
284                       PBOOL IsMember )
285 {
286   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
287
288   *IsMember = TRUE;
289   return(TRUE);
290 }
291
292 /******************************************************************************
293  * GetTokenInformation [ADVAPI32.@]
294  *
295  * PARAMS
296  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
297  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
298  *   tokeninfo       [O] Destination for token information
299  *   tokeninfolength [I] Length of tokeninfo
300  *   retlen          [O] Destination for returned token information length
301  *
302  * RETURNS
303  *  Success: TRUE. tokeninfo contains retlen bytes of token information
304  *  Failure: FALSE.
305  *
306  * NOTES
307  *  See NtQueryInformationToken.
308  */
309 BOOL WINAPI
310 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
311                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
312 {
313     TRACE("(%p, %s, %p, %ld, %p): \n",
314           token,
315           (tokeninfoclass == TokenUser) ? "TokenUser" :
316           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
317           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
318           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
319           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
320           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
321           (tokeninfoclass == TokenSource) ? "TokenSource" :
322           (tokeninfoclass == TokenType) ? "TokenType" :
323           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
324           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
325           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
326           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
327           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
328           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
329           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
330           "Unknown",
331           tokeninfo, tokeninfolength, retlen);
332     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
333                                                   tokeninfolength, retlen));
334 }
335
336 /******************************************************************************
337  * SetTokenInformation [ADVAPI32.@]
338  *
339  * Set information for an access token.
340  *
341  * PARAMS
342  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
343  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
344  *   tokeninfo       [I] Token information to set
345  *   tokeninfolength [I] Length of tokeninfo
346  *
347  * RETURNS
348  *  Success: TRUE. The information for the token is set to tokeninfo.
349  *  Failure: FALSE.
350  */
351 BOOL WINAPI
352 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
353                      LPVOID tokeninfo, DWORD tokeninfolength )
354 {
355     TRACE("(%p, %s, %p, %ld): stub\n",
356           token,
357           (tokeninfoclass == TokenUser) ? "TokenUser" :
358           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
359           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
360           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
361           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
362           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
363           (tokeninfoclass == TokenSource) ? "TokenSource" :
364           (tokeninfoclass == TokenType) ? "TokenType" :
365           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
366           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
367           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
368           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
369           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
370           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
371           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
372           "Unknown",
373           tokeninfo, tokeninfolength);
374
375     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
376 }
377
378 /*************************************************************************
379  * SetThreadToken [ADVAPI32.@]
380  *
381  * Assigns an 'impersonation token' to a thread so it can assume the
382  * security privileges of another thread or process.  Can also remove
383  * a previously assigned token. 
384  *
385  * PARAMS
386  *   thread          [O] Handle to thread to set the token for
387  *   token           [I] Token to set
388  *
389  * RETURNS
390  *  Success: TRUE. The threads access token is set to token
391  *  Failure: FALSE.
392  *
393  * NOTES
394  *  Only supported on NT or higher. On Win9X this function does nothing.
395  *  See SetTokenInformation.
396  */
397 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
398 {
399     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
400                                                  ThreadImpersonationToken, &token, sizeof token ));
401 }
402
403 /*      ##############################
404         ######  SID FUNCTIONS   ######
405         ##############################
406 */
407
408 /******************************************************************************
409  * AllocateAndInitializeSid [ADVAPI32.@]
410  *
411  * PARAMS
412  *   pIdentifierAuthority []
413  *   nSubAuthorityCount   []
414  *   nSubAuthority0       []
415  *   nSubAuthority1       []
416  *   nSubAuthority2       []
417  *   nSubAuthority3       []
418  *   nSubAuthority4       []
419  *   nSubAuthority5       []
420  *   nSubAuthority6       []
421  *   nSubAuthority7       []
422  *   pSid                 []
423  */
424 BOOL WINAPI
425 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
426                           BYTE nSubAuthorityCount,
427                           DWORD nSubAuthority0, DWORD nSubAuthority1,
428                           DWORD nSubAuthority2, DWORD nSubAuthority3,
429                           DWORD nSubAuthority4, DWORD nSubAuthority5,
430                           DWORD nSubAuthority6, DWORD nSubAuthority7,
431                           PSID *pSid )
432 {
433     return set_ntstatus( RtlAllocateAndInitializeSid(
434                              pIdentifierAuthority, nSubAuthorityCount,
435                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
436                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
437                              pSid ));
438 }
439
440 /******************************************************************************
441  * FreeSid [ADVAPI32.@]
442  *
443  * PARAMS
444  *   pSid []
445  */
446 PVOID WINAPI
447 FreeSid( PSID pSid )
448 {
449         RtlFreeSid(pSid);
450         return NULL; /* is documented like this */
451 }
452
453 /******************************************************************************
454  * CopySid [ADVAPI32.@]
455  *
456  * PARAMS
457  *   nDestinationSidLength []
458  *   pDestinationSid       []
459  *   pSourceSid            []
460  */
461 BOOL WINAPI
462 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
463 {
464         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
465 }
466
467 BOOL WINAPI
468 IsTokenRestricted( HANDLE TokenHandle )
469 {
470     TOKEN_GROUPS *groups;
471     DWORD size;
472     NTSTATUS status;
473     BOOL restricted;
474
475     TRACE("(%p)\n", TokenHandle);
476  
477     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
478     if (status != STATUS_BUFFER_TOO_SMALL)
479         return FALSE;
480  
481     groups = HeapAlloc(GetProcessHeap(), 0, size);
482     if (!groups)
483     {
484         SetLastError(ERROR_OUTOFMEMORY);
485         return FALSE;
486     }
487  
488     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
489     if (status != STATUS_SUCCESS)
490     {
491         HeapFree(GetProcessHeap(), 0, groups);
492         return set_ntstatus(status);
493     }
494  
495     if (groups->GroupCount)
496         restricted = TRUE;
497     else
498         restricted = FALSE;
499      
500     HeapFree(GetProcessHeap(), 0, groups);
501  
502     return restricted;
503 }
504
505 /******************************************************************************
506  * IsValidSid [ADVAPI32.@]
507  *
508  * PARAMS
509  *   pSid []
510  */
511 BOOL WINAPI
512 IsValidSid( PSID pSid )
513 {
514         return RtlValidSid( pSid );
515 }
516
517 /******************************************************************************
518  * EqualSid [ADVAPI32.@]
519  *
520  * PARAMS
521  *   pSid1 []
522  *   pSid2 []
523  */
524 BOOL WINAPI
525 EqualSid( PSID pSid1, PSID pSid2 )
526 {
527         return RtlEqualSid( pSid1, pSid2 );
528 }
529
530 /******************************************************************************
531  * EqualPrefixSid [ADVAPI32.@]
532  */
533 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
534 {
535         return RtlEqualPrefixSid(pSid1, pSid2);
536 }
537
538 /******************************************************************************
539  * GetSidLengthRequired [ADVAPI32.@]
540  *
541  * PARAMS
542  *   nSubAuthorityCount []
543  */
544 DWORD WINAPI
545 GetSidLengthRequired( BYTE nSubAuthorityCount )
546 {
547         return RtlLengthRequiredSid(nSubAuthorityCount);
548 }
549
550 /******************************************************************************
551  * InitializeSid [ADVAPI32.@]
552  *
553  * PARAMS
554  *   pIdentifierAuthority []
555  */
556 BOOL WINAPI
557 InitializeSid (
558         PSID pSid,
559         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
560         BYTE nSubAuthorityCount)
561 {
562         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
563 }
564
565 DWORD WINAPI
566 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
567 {
568     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
569
570     return 1;
571 }
572
573 DWORD WINAPI
574 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
575 {
576     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
577
578     return 1;
579 }
580
581 /******************************************************************************
582  * GetSidIdentifierAuthority [ADVAPI32.@]
583  *
584  * PARAMS
585  *   pSid []
586  */
587 PSID_IDENTIFIER_AUTHORITY WINAPI
588 GetSidIdentifierAuthority( PSID pSid )
589 {
590         return RtlIdentifierAuthoritySid(pSid);
591 }
592
593 /******************************************************************************
594  * GetSidSubAuthority [ADVAPI32.@]
595  *
596  * PARAMS
597  *   pSid          []
598  *   nSubAuthority []
599  */
600 PDWORD WINAPI
601 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
602 {
603         return RtlSubAuthoritySid(pSid, nSubAuthority);
604 }
605
606 /******************************************************************************
607  * GetSidSubAuthorityCount [ADVAPI32.@]
608  *
609  * PARAMS
610  *   pSid []
611  */
612 PUCHAR WINAPI
613 GetSidSubAuthorityCount (PSID pSid)
614 {
615         return RtlSubAuthorityCountSid(pSid);
616 }
617
618 /******************************************************************************
619  * GetLengthSid [ADVAPI32.@]
620  *
621  * PARAMS
622  *   pSid []
623  */
624 DWORD WINAPI
625 GetLengthSid (PSID pSid)
626 {
627         return RtlLengthSid(pSid);
628 }
629
630 /*      ##############################################
631         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
632         ##############################################
633 */
634
635 /******************************************************************************
636  * InitializeSecurityDescriptor [ADVAPI32.@]
637  *
638  * PARAMS
639  *   pDescr   []
640  *   revision []
641  */
642 BOOL WINAPI
643 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
644 {
645         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
646 }
647
648
649 /******************************************************************************
650  * MakeAbsoluteSD [ADVAPI32.@]
651  */
652 BOOL WINAPI MakeAbsoluteSD (
653         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
654         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
655         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
656         OUT PACL pDacl,
657         OUT LPDWORD lpdwDaclSize,
658         OUT PACL pSacl,
659         OUT LPDWORD lpdwSaclSize,
660         OUT PSID pOwner,
661         OUT LPDWORD lpdwOwnerSize,
662         OUT PSID pPrimaryGroup,
663         OUT LPDWORD lpdwPrimaryGroupSize)
664 {
665     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
666                                                      pAbsoluteSecurityDescriptor,
667                                                      lpdwAbsoluteSecurityDescriptorSize,
668                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
669                                                      pOwner, lpdwOwnerSize,
670                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
671 }
672
673 /******************************************************************************
674  * GetKernelObjectSecurity [ADVAPI32.@]
675  */
676 BOOL WINAPI GetKernelObjectSecurity(
677         HANDLE Handle,
678         SECURITY_INFORMATION RequestedInformation,
679         PSECURITY_DESCRIPTOR pSecurityDescriptor,
680         DWORD nLength,
681         LPDWORD lpnLengthNeeded )
682 {
683     TRACE("(%p,0x%08lx,%p,0x%08lx,%p)\n", Handle, RequestedInformation,
684           pSecurityDescriptor, nLength, lpnLengthNeeded);
685
686     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
687                                                nLength, lpnLengthNeeded ));
688 }
689
690 /******************************************************************************
691  * GetPrivateObjectSecurity [ADVAPI32.@]
692  */
693 BOOL WINAPI GetPrivateObjectSecurity(
694         PSECURITY_DESCRIPTOR ObjectDescriptor,
695         SECURITY_INFORMATION SecurityInformation,
696         PSECURITY_DESCRIPTOR ResultantDescriptor,
697         DWORD DescriptorLength,
698         PDWORD ReturnLength )
699 {
700     TRACE("(%p,0x%08lx,%p,0x%08lx,%p)\n", ObjectDescriptor, SecurityInformation,
701           ResultantDescriptor, DescriptorLength, ReturnLength);
702
703     return set_ntstatus( NtQuerySecurityObject(ObjectDescriptor, SecurityInformation,
704                                                ResultantDescriptor, DescriptorLength, ReturnLength ));
705 }
706
707 /******************************************************************************
708  * GetSecurityDescriptorLength [ADVAPI32.@]
709  */
710 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
711 {
712         return RtlLengthSecurityDescriptor(pDescr);
713 }
714
715 /******************************************************************************
716  * GetSecurityDescriptorOwner [ADVAPI32.@]
717  *
718  * PARAMS
719  *   pOwner            []
720  *   lpbOwnerDefaulted []
721  */
722 BOOL WINAPI
723 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
724                             LPBOOL lpbOwnerDefaulted )
725 {
726     BOOLEAN defaulted;
727     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
728     *lpbOwnerDefaulted = defaulted;
729     return ret;
730 }
731
732 /******************************************************************************
733  * SetSecurityDescriptorOwner [ADVAPI32.@]
734  *
735  * PARAMS
736  */
737 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
738                                    PSID pOwner, BOOL bOwnerDefaulted)
739 {
740     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
741 }
742 /******************************************************************************
743  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
744  */
745 BOOL WINAPI GetSecurityDescriptorGroup(
746         PSECURITY_DESCRIPTOR SecurityDescriptor,
747         PSID *Group,
748         LPBOOL GroupDefaulted)
749 {
750     BOOLEAN defaulted;
751     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
752     *GroupDefaulted = defaulted;
753     return ret;
754 }
755 /******************************************************************************
756  * SetSecurityDescriptorGroup [ADVAPI32.@]
757  */
758 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
759                                            PSID Group, BOOL GroupDefaulted)
760 {
761     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
762 }
763
764 /******************************************************************************
765  * IsValidSecurityDescriptor [ADVAPI32.@]
766  *
767  * PARAMS
768  *   lpsecdesc []
769  */
770 BOOL WINAPI
771 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
772 {
773     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
774 }
775
776 /******************************************************************************
777  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
778  */
779 BOOL WINAPI GetSecurityDescriptorDacl(
780         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
781         OUT LPBOOL lpbDaclPresent,
782         OUT PACL *pDacl,
783         OUT LPBOOL lpbDaclDefaulted)
784 {
785     BOOLEAN present, defaulted;
786     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
787     *lpbDaclPresent = present;
788     *lpbDaclDefaulted = defaulted;
789     return ret;
790 }
791
792 /******************************************************************************
793  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
794  */
795 BOOL WINAPI
796 SetSecurityDescriptorDacl (
797         PSECURITY_DESCRIPTOR lpsd,
798         BOOL daclpresent,
799         PACL dacl,
800         BOOL dacldefaulted )
801 {
802     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
803 }
804 /******************************************************************************
805  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
806  */
807 BOOL WINAPI GetSecurityDescriptorSacl(
808         IN PSECURITY_DESCRIPTOR lpsd,
809         OUT LPBOOL lpbSaclPresent,
810         OUT PACL *pSacl,
811         OUT LPBOOL lpbSaclDefaulted)
812 {
813     BOOLEAN present, defaulted;
814     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
815     *lpbSaclPresent = present;
816     *lpbSaclDefaulted = defaulted;
817     return ret;
818 }
819
820 /**************************************************************************
821  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
822  */
823 BOOL WINAPI SetSecurityDescriptorSacl (
824         PSECURITY_DESCRIPTOR lpsd,
825         BOOL saclpresent,
826         PACL lpsacl,
827         BOOL sacldefaulted)
828 {
829     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
830 }
831 /******************************************************************************
832  * MakeSelfRelativeSD [ADVAPI32.@]
833  *
834  * PARAMS
835  *   lpabssecdesc  []
836  *   lpselfsecdesc []
837  *   lpbuflen      []
838  */
839 BOOL WINAPI
840 MakeSelfRelativeSD(
841         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
842         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
843         IN OUT LPDWORD lpdwBufferLength)
844 {
845     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
846                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
847 }
848
849 /******************************************************************************
850  * GetSecurityDescriptorControl                 [ADVAPI32.@]
851  */
852
853 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
854                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
855 {
856     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
857 }
858
859 /*      ##############################
860         ######  ACL FUNCTIONS   ######
861         ##############################
862 */
863
864 /*************************************************************************
865  * InitializeAcl [ADVAPI32.@]
866  */
867 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
868 {
869     return set_ntstatus( RtlCreateAcl(acl, size, rev));
870 }
871
872 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
873 {
874     FIXME("%p - stub\n", hNamedPipe);
875
876     return FALSE;
877 }
878
879 /******************************************************************************
880  *  AddAccessAllowedAce [ADVAPI32.@]
881  */
882 BOOL WINAPI AddAccessAllowedAce(
883         IN OUT PACL pAcl,
884         IN DWORD dwAceRevision,
885         IN DWORD AccessMask,
886         IN PSID pSid)
887 {
888     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
889 }
890
891 /******************************************************************************
892  *  AddAccessAllowedAceEx [ADVAPI32.@]
893  */
894 BOOL WINAPI AddAccessAllowedAceEx(
895         IN OUT PACL pAcl,
896         IN DWORD dwAceRevision,
897         IN DWORD AceFlags,
898         IN DWORD AccessMask,
899         IN PSID pSid)
900 {
901     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
902 }
903
904 /******************************************************************************
905  *  AddAccessDeniedAce [ADVAPI32.@]
906  */
907 BOOL WINAPI AddAccessDeniedAce(
908         IN OUT PACL pAcl,
909         IN DWORD dwAceRevision,
910         IN DWORD AccessMask,
911         IN PSID pSid)
912 {
913     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
914 }
915
916 /******************************************************************************
917  *  AddAccessDeniedAceEx [ADVAPI32.@]
918  */
919 BOOL WINAPI AddAccessDeniedAceEx(
920         IN OUT PACL pAcl,
921         IN DWORD dwAceRevision,
922         IN DWORD AceFlags,
923         IN DWORD AccessMask,
924         IN PSID pSid)
925 {
926     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
927 }
928
929 /******************************************************************************
930  *  AddAce [ADVAPI32.@]
931  */
932 BOOL WINAPI AddAce(
933         IN OUT PACL pAcl,
934         IN DWORD dwAceRevision,
935         IN DWORD dwStartingAceIndex,
936         LPVOID pAceList,
937         DWORD nAceListLength)
938 {
939     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
940 }
941
942 /******************************************************************************
943  * DeleteAce [ADVAPI32.@]
944  */
945 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
946 {
947     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
948 }
949
950 /******************************************************************************
951  *  FindFirstFreeAce [ADVAPI32.@]
952  */
953 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
954 {
955         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
956 }
957
958 /******************************************************************************
959  * GetAce [ADVAPI32.@]
960  */
961 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
962 {
963     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
964 }
965
966 /******************************************************************************
967  * GetAclInformation [ADVAPI32.@]
968  */
969 BOOL WINAPI GetAclInformation(
970   PACL pAcl,
971   LPVOID pAclInformation,
972   DWORD nAclInformationLength,
973   ACL_INFORMATION_CLASS dwAclInformationClass)
974 {
975     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
976                                                nAclInformationLength, dwAclInformationClass));
977 }
978
979 /******************************************************************************
980  *  IsValidAcl [ADVAPI32.@]
981  */
982 BOOL WINAPI IsValidAcl(IN PACL pAcl)
983 {
984         return RtlValidAcl(pAcl);
985 }
986
987 /*      ##############################
988         ######  MISC FUNCTIONS  ######
989         ##############################
990 */
991
992 /******************************************************************************
993  * AllocateLocallyUniqueId [ADVAPI32.@]
994  *
995  * PARAMS
996  *   lpLuid []
997  */
998 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
999 {
1000     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1001 }
1002
1003 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1004  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1005 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1006  { '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 };
1007 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1008  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1009 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1010  { '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 };
1011 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1012  { '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 };
1013 static const WCHAR SE_TCB_NAME_W[] =
1014  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1015 static const WCHAR SE_SECURITY_NAME_W[] =
1016  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1017 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1018  { '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 };
1019 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1020  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1021 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1022  { '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 };
1023 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1024  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1025 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1026  { '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 };
1027 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1028  { '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 };
1029 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1030  { '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 };
1031 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1032  { '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 };
1033 static const WCHAR SE_BACKUP_NAME_W[] =
1034  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1035 static const WCHAR SE_RESTORE_NAME_W[] =
1036  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1037 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1038  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1039 static const WCHAR SE_DEBUG_NAME_W[] =
1040  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1041 static const WCHAR SE_AUDIT_NAME_W[] =
1042  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1043 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1044  { '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 };
1045 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1046  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1047 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1048  { '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 };
1049 static const WCHAR SE_UNDOCK_NAME_W[] =
1050  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1051 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1052  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1053 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1054  { '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 };
1055 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1056  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1057 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1058  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1059 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1060  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1061
1062 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1063 {
1064     NULL,
1065     NULL,
1066     SE_CREATE_TOKEN_NAME_W,
1067     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1068     SE_LOCK_MEMORY_NAME_W,
1069     SE_INCREASE_QUOTA_NAME_W,
1070     SE_MACHINE_ACCOUNT_NAME_W,
1071     SE_TCB_NAME_W,
1072     SE_SECURITY_NAME_W,
1073     SE_TAKE_OWNERSHIP_NAME_W,
1074     SE_LOAD_DRIVER_NAME_W,
1075     SE_SYSTEM_PROFILE_NAME_W,
1076     SE_SYSTEMTIME_NAME_W,
1077     SE_PROF_SINGLE_PROCESS_NAME_W,
1078     SE_INC_BASE_PRIORITY_NAME_W,
1079     SE_CREATE_PAGEFILE_NAME_W,
1080     SE_CREATE_PERMANENT_NAME_W,
1081     SE_BACKUP_NAME_W,
1082     SE_RESTORE_NAME_W,
1083     SE_SHUTDOWN_NAME_W,
1084     SE_DEBUG_NAME_W,
1085     SE_AUDIT_NAME_W,
1086     SE_SYSTEM_ENVIRONMENT_NAME_W,
1087     SE_CHANGE_NOTIFY_NAME_W,
1088     SE_REMOTE_SHUTDOWN_NAME_W,
1089     SE_UNDOCK_NAME_W,
1090     SE_SYNC_AGENT_NAME_W,
1091     SE_ENABLE_DELEGATION_NAME_W,
1092     SE_MANAGE_VOLUME_NAME_W,
1093     SE_IMPERSONATE_NAME_W,
1094     SE_CREATE_GLOBAL_NAME_W,
1095 };
1096
1097 /******************************************************************************
1098  * LookupPrivilegeValueW                        [ADVAPI32.@]
1099  *
1100  * See LookupPrivilegeValueA.
1101  */
1102 BOOL WINAPI
1103 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1104 {
1105     UINT i;
1106
1107     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1108
1109     if (!ADVAPI_IsLocalComputer(lpSystemName))
1110     {
1111         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1112         return FALSE;
1113     }
1114     if (!lpName)
1115     {
1116         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1117         return FALSE;
1118     }
1119     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1120     {
1121         if( !WellKnownPrivNames[i] )
1122             continue;
1123         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1124             continue;
1125         lpLuid->LowPart = i;
1126         lpLuid->HighPart = 0;
1127         TRACE( "%s -> %08lx-%08lx\n",debugstr_w( lpSystemName ),
1128                lpLuid->HighPart, lpLuid->LowPart );
1129         return TRUE;
1130     }
1131     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1132     return FALSE;
1133 }
1134
1135 /******************************************************************************
1136  * LookupPrivilegeValueA                        [ADVAPI32.@]
1137  *
1138  * Retrieves LUID used on a system to represent the privilege name.
1139  *
1140  * PARAMS
1141  *  lpSystemName [I] Name of the system
1142  *  lpName       [I] Name of the privilege
1143  *  lpLuid       [O] Destination for the resulting LUID
1144  *
1145  * RETURNS
1146  *  Success: TRUE. lpLuid contains the requested LUID.
1147  *  Failure: FALSE.
1148  */
1149 BOOL WINAPI
1150 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1151 {
1152     UNICODE_STRING lpSystemNameW;
1153     UNICODE_STRING lpNameW;
1154     BOOL ret;
1155
1156     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1157     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1158     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1159     RtlFreeUnicodeString(&lpNameW);
1160     RtlFreeUnicodeString(&lpSystemNameW);
1161     return ret;
1162 }
1163
1164 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1165                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1166 {
1167     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1168           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1169
1170     return FALSE;
1171 }
1172
1173 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1174                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1175 {
1176     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1177           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1178
1179     return FALSE;
1180 }
1181
1182 /******************************************************************************
1183  * LookupPrivilegeNameA                 [ADVAPI32.@]
1184  *
1185  * See LookupPrivilegeNameW
1186  */
1187 BOOL WINAPI
1188 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1189  LPDWORD cchName)
1190 {
1191     UNICODE_STRING lpSystemNameW;
1192     BOOL ret;
1193     DWORD wLen = 0;
1194
1195     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1196
1197     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1198     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1199     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1200     {
1201         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1202
1203         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1204          &wLen);
1205         if (ret)
1206         {
1207             /* Windows crashes if cchName is NULL, so will I */
1208             int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1209              *cchName, NULL, NULL);
1210
1211             if (len == 0)
1212             {
1213                 /* WideCharToMultiByte failed */
1214                 ret = FALSE;
1215             }
1216             else if (len > *cchName)
1217             {
1218                 *cchName = len;
1219                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1220                 ret = FALSE;
1221             }
1222             else
1223             {
1224                 /* WideCharToMultiByte succeeded, output length needs to be
1225                  * length not including NULL terminator
1226                  */
1227                 *cchName = len - 1;
1228             }
1229         }
1230         HeapFree(GetProcessHeap(), 0, lpNameW);
1231     }
1232     RtlFreeUnicodeString(&lpSystemNameW);
1233     return ret;
1234 }
1235
1236 /******************************************************************************
1237  * LookupPrivilegeNameW                 [ADVAPI32.@]
1238  *
1239  * Retrieves the privilege name referred to by the LUID lpLuid.
1240  *
1241  * PARAMS
1242  *  lpSystemName [I]   Name of the system
1243  *  lpLuid       [I]   Privilege value
1244  *  lpName       [O]   Name of the privilege
1245  *  cchName      [I/O] Number of characters in lpName.
1246  *
1247  * RETURNS
1248  *  Success: TRUE. lpName contains the name of the privilege whose value is
1249  *  *lpLuid.
1250  *  Failure: FALSE.
1251  *
1252  * REMARKS
1253  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1254  *  using this function.
1255  *  If the length of lpName is too small, on return *cchName will contain the
1256  *  number of WCHARs needed to contain the privilege, including the NULL
1257  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1258  *  On success, *cchName will contain the number of characters stored in
1259  *  lpName, NOT including the NULL terminator.
1260  */
1261 BOOL WINAPI
1262 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1263  LPDWORD cchName)
1264 {
1265     size_t privNameLen;
1266
1267     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1268
1269     if (!ADVAPI_IsLocalComputer(lpSystemName))
1270     {
1271         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1272         return FALSE;
1273     }
1274     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1275      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1276     {
1277         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1278         return FALSE;
1279     }
1280     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1281     /* Windows crashes if cchName is NULL, so will I */
1282     if (*cchName <= privNameLen)
1283     {
1284         *cchName = privNameLen + 1;
1285         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1286         return FALSE;
1287     }
1288     else
1289     {
1290         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1291         *cchName = privNameLen;
1292         return TRUE;
1293     }
1294 }
1295
1296 /******************************************************************************
1297  * GetFileSecurityA [ADVAPI32.@]
1298  *
1299  * Obtains Specified information about the security of a file or directory.
1300  *
1301  * PARAMS
1302  *  lpFileName           [I] Name of the file to get info for
1303  *  RequestedInformation [I] SE_ flags from "winnt.h"
1304  *  pSecurityDescriptor  [O] Destination for security information
1305  *  nLength              [I] Length of pSecurityDescriptor
1306  *  lpnLengthNeeded      [O] Destination for length of returned security information
1307  *
1308  * RETURNS
1309  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1310  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1311  *
1312  * NOTES
1313  *  The information returned is constrained by the callers access rights and
1314  *  privileges.
1315  */
1316 BOOL WINAPI
1317 GetFileSecurityA( LPCSTR lpFileName,
1318                     SECURITY_INFORMATION RequestedInformation,
1319                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1320                     DWORD nLength, LPDWORD lpnLengthNeeded )
1321 {
1322     DWORD len;
1323     BOOL r;
1324     LPWSTR name = NULL;
1325
1326     if( lpFileName )
1327     {
1328         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1329         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1330         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1331     }
1332
1333     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1334                           nLength, lpnLengthNeeded );
1335     HeapFree( GetProcessHeap(), 0, name );
1336
1337     return r;
1338 }
1339
1340 /******************************************************************************
1341  * GetFileSecurityW [ADVAPI32.@]
1342  *
1343  * See GetFileSecurityA.
1344  */
1345 BOOL WINAPI
1346 GetFileSecurityW( LPCWSTR lpFileName,
1347                     SECURITY_INFORMATION RequestedInformation,
1348                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1349                     DWORD nLength, LPDWORD lpnLengthNeeded )
1350 {
1351     DWORD               nNeeded;
1352     LPBYTE      pBuffer;
1353     DWORD               iLocNow;
1354     SECURITY_DESCRIPTOR_RELATIVE *pSDRelative;
1355
1356     if(INVALID_FILE_ATTRIBUTES == GetFileAttributesW(lpFileName))
1357         return FALSE;
1358
1359     FIXME("(%s) : returns fake SECURITY_DESCRIPTOR\n", debugstr_w(lpFileName) );
1360
1361     nNeeded = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1362     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1363         nNeeded += sizeof(sidWorld);
1364     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1365         nNeeded += sizeof(sidWorld);
1366     if (RequestedInformation & DACL_SECURITY_INFORMATION)
1367         nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1368     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1369         nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1370
1371     *lpnLengthNeeded = nNeeded;
1372
1373     if (nNeeded > nLength)
1374             return TRUE;
1375
1376     if (!InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
1377         return FALSE;
1378
1379     pSDRelative = (PISECURITY_DESCRIPTOR_RELATIVE) pSecurityDescriptor;
1380     pSDRelative->Control |= SE_SELF_RELATIVE;
1381     pBuffer = (LPBYTE) pSDRelative;
1382     iLocNow = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1383
1384     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1385     {
1386         memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1387         pSDRelative->Owner = iLocNow;
1388         iLocNow += sizeof(sidWorld);
1389     }
1390     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1391     {
1392         memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1393         pSDRelative->Group = iLocNow;
1394         iLocNow += sizeof(sidWorld);
1395     }
1396     if (RequestedInformation & DACL_SECURITY_INFORMATION)
1397     {
1398         GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1399         pSDRelative->Dacl = iLocNow;
1400         iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1401     }
1402     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1403     {
1404         GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1405         pSDRelative->Sacl = iLocNow;
1406         /* iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL; */
1407     }
1408     return TRUE;
1409 }
1410
1411
1412 /******************************************************************************
1413  * LookupAccountSidA [ADVAPI32.@]
1414  */
1415 BOOL WINAPI
1416 LookupAccountSidA(
1417         IN LPCSTR system,
1418         IN PSID sid,
1419         OUT LPSTR account,
1420         IN OUT LPDWORD accountSize,
1421         OUT LPSTR domain,
1422         IN OUT LPDWORD domainSize,
1423         OUT PSID_NAME_USE name_use )
1424 {
1425         static const char ac[] = "Administrator";
1426         static const char dm[] = "DOMAIN";
1427         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1428               debugstr_a(system),sid,
1429               account,accountSize,accountSize?*accountSize:0,
1430               domain,domainSize,domainSize?*domainSize:0,
1431               name_use);
1432
1433         if (accountSize) *accountSize = strlen(ac)+1;
1434         if (account && (*accountSize > strlen(ac)))
1435           strcpy(account, ac);
1436
1437         if (domainSize) *domainSize = strlen(dm)+1;
1438         if (domain && (*domainSize > strlen(dm)))
1439           strcpy(domain,dm);
1440
1441         if (name_use) *name_use = SidTypeUser;
1442         return TRUE;
1443 }
1444
1445 /******************************************************************************
1446  * LookupAccountSidW [ADVAPI32.@]
1447  *
1448  * PARAMS
1449  *   system      []
1450  *   sid         []
1451  *   account     []
1452  *   accountSize []
1453  *   domain      []
1454  *   domainSize  []
1455  *   name_use    []
1456  */
1457 BOOL WINAPI
1458 LookupAccountSidW(
1459         IN LPCWSTR system,
1460         IN PSID sid,
1461         OUT LPWSTR account,
1462         IN OUT LPDWORD accountSize,
1463         OUT LPWSTR domain,
1464         IN OUT LPDWORD domainSize,
1465         OUT PSID_NAME_USE name_use )
1466 {
1467     static const WCHAR ac[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0};
1468     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1469         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1470               debugstr_w(system),sid,
1471               account,accountSize,accountSize?*accountSize:0,
1472               domain,domainSize,domainSize?*domainSize:0,
1473               name_use);
1474
1475         if (accountSize) *accountSize = strlenW(ac)+1;
1476         if (account && (*accountSize > strlenW(ac)))
1477             strcpyW(account, ac);
1478
1479         if (domainSize) *domainSize = strlenW(dm)+1;
1480         if (domain && (*domainSize > strlenW(dm)))
1481             strcpyW(domain,dm);
1482
1483         if (name_use) *name_use = SidTypeUser;
1484         return TRUE;
1485 }
1486
1487 /******************************************************************************
1488  * SetFileSecurityA [ADVAPI32.@]
1489  * Sets the security of a file or directory
1490  */
1491 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1492                                 SECURITY_INFORMATION RequestedInformation,
1493                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1494 {
1495     DWORD len;
1496     BOOL r;
1497     LPWSTR name = NULL;
1498
1499     if( lpFileName )
1500     {
1501         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1502         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1503         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1504     }
1505
1506     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
1507     HeapFree( GetProcessHeap(), 0, name );
1508
1509     return r;
1510 }
1511
1512 /******************************************************************************
1513  * SetFileSecurityW [ADVAPI32.@]
1514  * Sets the security of a file or directory
1515  *
1516  * PARAMS
1517  *   lpFileName           []
1518  *   RequestedInformation []
1519  *   pSecurityDescriptor  []
1520  */
1521 BOOL WINAPI
1522 SetFileSecurityW( LPCWSTR lpFileName,
1523                     SECURITY_INFORMATION RequestedInformation,
1524                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
1525 {
1526   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
1527   return TRUE;
1528 }
1529
1530 /******************************************************************************
1531  * QueryWindows31FilesMigration [ADVAPI32.@]
1532  *
1533  * PARAMS
1534  *   x1 []
1535  */
1536 BOOL WINAPI
1537 QueryWindows31FilesMigration( DWORD x1 )
1538 {
1539         FIXME("(%ld):stub\n",x1);
1540         return TRUE;
1541 }
1542
1543 /******************************************************************************
1544  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1545  *
1546  * PARAMS
1547  *   x1 []
1548  *   x2 []
1549  *   x3 []
1550  *   x4 []
1551  */
1552 BOOL WINAPI
1553 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1554                                                DWORD x4 )
1555 {
1556         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
1557         return TRUE;
1558 }
1559
1560 NTSTATUS WINAPI
1561 LsaEnumerateTrustedDomains(
1562     LSA_HANDLE PolicyHandle,
1563     PLSA_ENUMERATION_HANDLE EnumerationContext,
1564     PVOID* Buffer,
1565     ULONG PreferedMaximumLength,
1566     PULONG CountReturned)
1567 {
1568     FIXME("(%p,%p,%p,0x%08lx,%p):stub\n", PolicyHandle, EnumerationContext,
1569           Buffer, PreferedMaximumLength, CountReturned);
1570
1571     if (CountReturned) *CountReturned = 0;
1572     return STATUS_SUCCESS;
1573 }
1574
1575 NTSTATUS WINAPI
1576 LsaLookupNames(
1577   LSA_HANDLE PolicyHandle,
1578   ULONG Count,
1579   PLSA_UNICODE_STRING Names,
1580   PLSA_REFERENCED_DOMAIN_LIST* ReferencedDomains,
1581   PLSA_TRANSLATED_SID* Sids)
1582 {
1583     FIXME("(%p,0x%08lx,%p,%p,%p):stub\n", PolicyHandle, Count, Names,
1584           ReferencedDomains, Sids);
1585
1586     return STATUS_NONE_MAPPED;
1587 }
1588
1589 /******************************************************************************
1590  * LsaOpenPolicy [ADVAPI32.@]
1591  *
1592  * PARAMS
1593  *   SystemName       [I]
1594  *   ObjectAttributes [I]
1595  *   DesiredAccess    [I]
1596  *   PolicyHandle     [I/O]
1597  */
1598 NTSTATUS WINAPI
1599 LsaOpenPolicy(
1600         IN PLSA_UNICODE_STRING SystemName,
1601         IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
1602         IN ACCESS_MASK DesiredAccess,
1603         IN OUT PLSA_HANDLE PolicyHandle)
1604 {
1605         FIXME("(%s,%p,0x%08lx,%p):stub\n",
1606               SystemName?debugstr_w(SystemName->Buffer):"null",
1607               ObjectAttributes, DesiredAccess, PolicyHandle);
1608         ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
1609                                   STATUS_ACCESS_VIOLATION);
1610         dumpLsaAttributes(ObjectAttributes);
1611         if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
1612         return STATUS_SUCCESS;
1613 }
1614
1615 /******************************************************************************
1616  * LsaQueryInformationPolicy [ADVAPI32.@]
1617  */
1618 NTSTATUS WINAPI
1619 LsaQueryInformationPolicy(
1620         IN LSA_HANDLE PolicyHandle,
1621         IN POLICY_INFORMATION_CLASS InformationClass,
1622         OUT PVOID *Buffer)
1623 {
1624         FIXME("(%p,0x%08x,%p):stub\n",
1625               PolicyHandle, InformationClass, Buffer);
1626
1627         if(!Buffer) return FALSE;
1628         switch (InformationClass)
1629         {
1630           case PolicyAuditEventsInformation: /* 2 */
1631             {
1632               PPOLICY_AUDIT_EVENTS_INFO p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POLICY_AUDIT_EVENTS_INFO));
1633               p->AuditingMode = FALSE; /* no auditing */
1634               *Buffer = p;
1635             }
1636             break;
1637           case PolicyPrimaryDomainInformation: /* 3 */
1638           case PolicyAccountDomainInformation: /* 5 */
1639             {
1640               struct di
1641               { POLICY_PRIMARY_DOMAIN_INFO ppdi;
1642                 SID sid;
1643               };
1644               SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
1645
1646               struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(xdi));
1647               HKEY key;
1648               BOOL useDefault = TRUE;
1649               LONG ret;
1650
1651               if ((ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
1652                "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0,
1653                KEY_READ, &key)) == ERROR_SUCCESS)
1654               {
1655                   DWORD size = 0;
1656                   static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
1657
1658                   ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
1659                   if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
1660                   {
1661                       xdi->ppdi.Name.Buffer = HeapAlloc(GetProcessHeap(),
1662                        HEAP_ZERO_MEMORY, size);
1663                       if ((ret = RegQueryValueExW(key, wg, NULL, NULL,
1664                        (LPBYTE)xdi->ppdi.Name.Buffer, &size)) == ERROR_SUCCESS)
1665                       {
1666                           xdi->ppdi.Name.Length = (USHORT)size;
1667                           useDefault = FALSE;
1668                       }
1669                       else
1670                       {
1671                           HeapFree(GetProcessHeap(), 0, xdi->ppdi.Name.Buffer);
1672                           xdi->ppdi.Name.Buffer = NULL;
1673                       }
1674                   }
1675                   RegCloseKey(key);
1676               }
1677               if (useDefault)
1678                   RtlCreateUnicodeStringFromAsciiz(&(xdi->ppdi.Name), "DOMAIN");
1679               TRACE("setting domain to %s\n", debugstr_w(xdi->ppdi.Name.Buffer));
1680
1681               xdi->ppdi.Sid = &(xdi->sid);
1682               xdi->sid.Revision = SID_REVISION;
1683               xdi->sid.SubAuthorityCount = 1;
1684               xdi->sid.IdentifierAuthority = localSidAuthority;
1685               xdi->sid.SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
1686               *Buffer = xdi;
1687             }
1688             break;
1689           case  PolicyAuditLogInformation:
1690           case  PolicyPdAccountInformation:
1691           case  PolicyLsaServerRoleInformation:
1692           case  PolicyReplicaSourceInformation:
1693           case  PolicyDefaultQuotaInformation:
1694           case  PolicyModificationInformation:
1695           case  PolicyAuditFullSetInformation:
1696           case  PolicyAuditFullQueryInformation:
1697           case  PolicyDnsDomainInformation:
1698             {
1699               FIXME("category not implemented\n");
1700               return FALSE;
1701             }
1702         }
1703         return TRUE;
1704 }
1705
1706 /******************************************************************************
1707  * LsaSetInformationPolicy [ADVAPI32.@]
1708  */
1709 NTSTATUS WINAPI
1710 LsaSetInformationPolicy(
1711     LSA_HANDLE PolicyHandle,
1712     POLICY_INFORMATION_CLASS InformationClass,
1713     PVOID Buffer)
1714 {
1715     FIXME("(%p,0x%08x,%p):stub\n", PolicyHandle, InformationClass, Buffer);
1716
1717     return STATUS_UNSUCCESSFUL;    
1718 }
1719
1720 /******************************************************************************
1721  * LsaLookupSids [ADVAPI32.@]
1722  */
1723 NTSTATUS WINAPI
1724 LsaLookupSids(
1725         IN LSA_HANDLE PolicyHandle,
1726         IN ULONG Count,
1727         IN PSID *Sids,
1728         OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1729         OUT PLSA_TRANSLATED_NAME *Names )
1730 {
1731         FIXME("%p %lu %p %p %p\n",
1732           PolicyHandle, Count, Sids, ReferencedDomains, Names);
1733         return FALSE;
1734 }
1735
1736 /******************************************************************************
1737  * LsaFreeMemory [ADVAPI32.@]
1738  */
1739 NTSTATUS WINAPI
1740 LsaFreeMemory(IN PVOID Buffer)
1741 {
1742         TRACE("(%p)\n",Buffer);
1743         return HeapFree(GetProcessHeap(), 0, Buffer);
1744 }
1745 /******************************************************************************
1746  * LsaClose [ADVAPI32.@]
1747  */
1748 NTSTATUS WINAPI
1749 LsaClose(IN LSA_HANDLE ObjectHandle)
1750 {
1751         FIXME("(%p):stub\n",ObjectHandle);
1752         return 0xc0000000;
1753 }
1754
1755 /******************************************************************************
1756  * LsaStorePrivateData [ADVAPI32.@]
1757  */
1758 NTSTATUS WINAPI LsaStorePrivateData( LSA_HANDLE PolicyHandle,
1759     PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING PrivateData)
1760 {
1761     FIXME("%p %p %p\n", PolicyHandle, KeyName, PrivateData);
1762     return STATUS_OBJECT_NAME_NOT_FOUND;
1763 }
1764
1765 /******************************************************************************
1766  * LsaRetrievePrivateData [ADVAPI32.@]
1767  */
1768 NTSTATUS WINAPI LsaRetrievePrivateData( LSA_HANDLE PolicyHandle,
1769     PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING* PrivateData)
1770 {
1771     FIXME("%p %p %p\n", PolicyHandle, KeyName, PrivateData);
1772     return STATUS_OBJECT_NAME_NOT_FOUND;
1773 }
1774
1775 /******************************************************************************
1776  * LsaNtStatusToWinError [ADVAPI32.@]
1777  *
1778  * PARAMS
1779  *   Status [I]
1780  */
1781 ULONG WINAPI
1782 LsaNtStatusToWinError(NTSTATUS Status)
1783 {
1784     return RtlNtStatusToDosError(Status);
1785 }
1786
1787 /******************************************************************************
1788  * NotifyBootConfigStatus [ADVAPI32.@]
1789  *
1790  * PARAMS
1791  *   x1 []
1792  */
1793 BOOL WINAPI
1794 NotifyBootConfigStatus( DWORD x1 )
1795 {
1796         FIXME("(0x%08lx):stub\n",x1);
1797         return 1;
1798 }
1799
1800 /******************************************************************************
1801  * RevertToSelf [ADVAPI32.@]
1802  *
1803  * Ends the impersonation of a user.
1804  *
1805  * PARAMS
1806  *   void []
1807  *
1808  * RETURNS
1809  *  Success: TRUE.
1810  *  Failure: FALSE.
1811  */
1812 BOOL WINAPI
1813 RevertToSelf( void )
1814 {
1815     HANDLE Token = NULL;
1816     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
1817         ThreadImpersonationToken, &Token, sizeof(Token) ) );
1818 }
1819
1820 /******************************************************************************
1821  * ImpersonateSelf [ADVAPI32.@]
1822  *
1823  * Makes an impersonation token that represents the process user and assigns
1824  * to the current thread.
1825  *
1826  * PARAMS
1827  *  ImpersonationLevel [I] Level at which to impersonate.
1828  *
1829  * RETURNS
1830  *  Success: TRUE.
1831  *  Failure: FALSE.
1832  */
1833 BOOL WINAPI
1834 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1835 {
1836     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
1837 }
1838
1839 /******************************************************************************
1840  * ImpersonateLoggedOnUser [ADVAPI32.@]
1841  */
1842 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
1843 {
1844     FIXME("(%p):stub returning FALSE\n", hToken);
1845     return FALSE;
1846 }
1847
1848 /******************************************************************************
1849  * AccessCheck [ADVAPI32.@]
1850  */
1851 BOOL WINAPI
1852 AccessCheck(
1853         PSECURITY_DESCRIPTOR SecurityDescriptor,
1854         HANDLE ClientToken,
1855         DWORD DesiredAccess,
1856         PGENERIC_MAPPING GenericMapping,
1857         PPRIVILEGE_SET PrivilegeSet,
1858         LPDWORD PrivilegeSetLength,
1859         LPDWORD GrantedAccess,
1860         LPBOOL AccessStatus)
1861 {
1862     NTSTATUS access_status;
1863     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
1864                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
1865                                            GrantedAccess, &access_status) );
1866     if (ret) *AccessStatus = set_ntstatus( access_status );
1867     return ret;
1868 }
1869
1870
1871 /******************************************************************************
1872  * AccessCheckByType [ADVAPI32.@]
1873  */
1874 BOOL WINAPI AccessCheckByType(
1875     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
1876     PSID PrincipalSelfSid,
1877     HANDLE ClientToken, 
1878     DWORD DesiredAccess, 
1879     POBJECT_TYPE_LIST ObjectTypeList,
1880     DWORD ObjectTypeListLength,
1881     PGENERIC_MAPPING GenericMapping,
1882     PPRIVILEGE_SET PrivilegeSet,
1883     LPDWORD PrivilegeSetLength, 
1884     LPDWORD GrantedAccess,
1885     LPBOOL AccessStatus)
1886 {
1887         FIXME("stub\n");
1888
1889         *AccessStatus = TRUE;
1890
1891         return !*AccessStatus;
1892 }
1893
1894 /******************************************************************************
1895  * MapGenericMask [ADVAPI32.@]
1896  *
1897  * Maps generic access rights into specific access rights according to the
1898  * supplied mapping.
1899  *
1900  * PARAMS
1901  *  AccessMask     [I/O] Access rights.
1902  *  GenericMapping [I] The mapping between generic and specific rights.
1903  *
1904  * RETURNS
1905  *  Nothing.
1906  */
1907 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
1908 {
1909     RtlMapGenericMask( AccessMask, GenericMapping );
1910 }
1911
1912 /*************************************************************************
1913  * SetKernelObjectSecurity [ADVAPI32.@]
1914  */
1915 BOOL WINAPI SetKernelObjectSecurity (
1916         IN HANDLE Handle,
1917         IN SECURITY_INFORMATION SecurityInformation,
1918         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
1919 {
1920     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
1921 }
1922
1923
1924 /******************************************************************************
1925  *  AddAuditAccessAce [ADVAPI32.@]
1926  */
1927 BOOL WINAPI AddAuditAccessAce(
1928         IN OUT PACL pAcl,
1929         IN DWORD dwAceRevision,
1930         IN DWORD dwAccessMask,
1931         IN PSID pSid,
1932         IN BOOL bAuditSuccess,
1933         IN BOOL bAuditFailure)
1934 {
1935         FIXME("Stub\n");
1936         return TRUE;
1937 }
1938
1939 /******************************************************************************
1940  * LookupAccountNameA [ADVAPI32.@]
1941  */
1942 BOOL WINAPI
1943 LookupAccountNameA(
1944         IN LPCSTR system,
1945         IN LPCSTR account,
1946         OUT PSID sid,
1947         OUT LPDWORD cbSid,
1948         LPSTR ReferencedDomainName,
1949         IN OUT LPDWORD cbReferencedDomainName,
1950         OUT PSID_NAME_USE name_use )
1951 {
1952     /* Default implementation: Always return a default SID */
1953     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1954     BOOL ret;
1955     PSID pSid;
1956     static const char dm[] = "DOMAIN";
1957
1958     FIXME("(%s,%s,%p,%p,%p,%p,%p), stub.\n",system,account,sid,cbSid,ReferencedDomainName,cbReferencedDomainName,name_use);
1959
1960     ret = AllocateAndInitializeSid(&identifierAuthority,
1961         2,
1962         SECURITY_BUILTIN_DOMAIN_RID,
1963         DOMAIN_ALIAS_RID_ADMINS,
1964         0, 0, 0, 0, 0, 0,
1965         &pSid);
1966
1967     if (!ret)
1968        return FALSE;
1969     if(!RtlValidSid(pSid))
1970     {
1971        FreeSid(pSid);
1972        return FALSE;
1973     }
1974
1975     if (sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1976        CopySid(*cbSid, sid, pSid);
1977     if (*cbSid < GetLengthSid(pSid))
1978     {
1979        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1980        ret = FALSE;
1981     }
1982     *cbSid = GetLengthSid(pSid);
1983     
1984     if (ReferencedDomainName != NULL && (*cbReferencedDomainName > strlen(dm)))
1985       strcpy(ReferencedDomainName, dm);
1986     if (*cbReferencedDomainName <= strlen(dm))
1987     {
1988        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1989        ret = FALSE;
1990     }
1991     *cbReferencedDomainName = strlen(dm)+1;
1992
1993     FreeSid(pSid);
1994
1995     return ret;
1996 }
1997
1998 /******************************************************************************
1999  * LookupAccountNameW [ADVAPI32.@]
2000  */
2001 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2002                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2003                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2004 {
2005     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2006           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2007
2008     return FALSE;
2009 }
2010
2011 /******************************************************************************
2012  * PrivilegeCheck [ADVAPI32.@]
2013  */
2014 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2015 {
2016     BOOL ret;
2017     BOOLEAN Result;
2018
2019     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2020
2021     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2022     if (ret)
2023         *pfResult = Result;
2024     return ret;
2025 }
2026
2027 /******************************************************************************
2028  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2029  */
2030 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2031   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2032   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2033   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2034 {
2035         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2036                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2037                 SecurityDescriptor, DesiredAccess, GenericMapping,
2038                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2039         return TRUE;
2040 }
2041
2042 /******************************************************************************
2043  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2044  */
2045 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2046   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2047   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2048   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2049 {
2050         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2051                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2052                 SecurityDescriptor, DesiredAccess, GenericMapping,
2053                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2054         return TRUE;
2055 }
2056
2057 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2058 {
2059     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2060
2061     return TRUE;
2062 }
2063
2064 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2065 {
2066     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2067
2068     return TRUE;
2069 }
2070
2071 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2072   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2073   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2074   LPBOOL GenerateOnClose)
2075 {
2076         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2077                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2078         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2079         GenerateOnClose);
2080
2081     return TRUE;
2082 }
2083
2084 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2085   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2086   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2087   LPBOOL GenerateOnClose)
2088 {
2089     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2090         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2091         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2092         GenerateOnClose);
2093
2094     return TRUE;
2095 }
2096
2097 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2098   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2099 {
2100     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2101           DesiredAccess, Privileges, AccessGranted);
2102
2103     return TRUE;
2104 }
2105
2106 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2107   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2108 {
2109     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2110           DesiredAccess, Privileges, AccessGranted);
2111
2112     return TRUE;
2113 }
2114
2115 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2116                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2117 {
2118     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2119           ClientToken, Privileges, AccessGranted);
2120
2121     return TRUE;
2122 }
2123
2124 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2125                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2126 {
2127     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2128           ClientToken, Privileges, AccessGranted);
2129
2130     return TRUE;
2131 }
2132
2133 /******************************************************************************
2134  * GetSecurityInfo [ADVAPI32.@]
2135  */
2136 DWORD WINAPI GetSecurityInfo(
2137     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2138     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2139     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2140     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2141 )
2142 {
2143   FIXME("stub!\n");
2144   return ERROR_BAD_PROVIDER;
2145 }
2146
2147 /******************************************************************************
2148  * GetSecurityInfoExW [ADVAPI32.@]
2149  */
2150 DWORD WINAPI GetSecurityInfoExW(
2151         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2152         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2153         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2154         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2155 )
2156 {
2157   FIXME("stub!\n");
2158   return ERROR_BAD_PROVIDER; 
2159 }
2160
2161 /******************************************************************************
2162  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2163  */
2164 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2165                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2166                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2167 {
2168     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_a(pTrusteeName),
2169           AccessPermissions, AccessMode, Inheritance);
2170
2171     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2172     pExplicitAccess->grfAccessMode = AccessMode;
2173     pExplicitAccess->grfInheritance = Inheritance;
2174
2175     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2176     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2177     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2178     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2179     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2180 }
2181
2182 /******************************************************************************
2183  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2184  */
2185 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2186                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2187                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2188 {
2189     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_w(pTrusteeName),
2190           AccessPermissions, AccessMode, Inheritance);
2191
2192     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2193     pExplicitAccess->grfAccessMode = AccessMode;
2194     pExplicitAccess->grfInheritance = Inheritance;
2195
2196     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2197     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2198     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2199     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2200     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2201 }
2202
2203 /******************************************************************************
2204  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2205  */
2206 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2207                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2208                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2209 {
2210     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2211           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2212
2213     pTrustee->pMultipleTrustee = NULL;
2214     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2215     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2216     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2217     pTrustee->ptstrName = Name;
2218 }
2219
2220 /******************************************************************************
2221  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2222  */
2223 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2224                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2225                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2226 {
2227     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2228           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2229
2230     pTrustee->pMultipleTrustee = NULL;
2231     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2232     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2233     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2234     pTrustee->ptstrName = Name;
2235 }
2236
2237 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2238                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2239 {
2240     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2241
2242     pTrustee->pMultipleTrustee = NULL;
2243     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2244     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2245     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2246     pTrustee->ptstrName = (LPSTR) pSid;
2247 }
2248
2249 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2250                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2251 {
2252     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2253
2254     pTrustee->pMultipleTrustee = NULL;
2255     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2256     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2257     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2258     pTrustee->ptstrName = (LPWSTR) pSid;
2259 }
2260
2261 /******************************************************************************
2262  * BuildTrusteeWithSidA [ADVAPI32.@]
2263  */
2264 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2265 {
2266     TRACE("%p %p\n", pTrustee, pSid);
2267
2268     pTrustee->pMultipleTrustee = NULL;
2269     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2270     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2271     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2272     pTrustee->ptstrName = (LPSTR) pSid;
2273 }
2274
2275 /******************************************************************************
2276  * BuildTrusteeWithSidW [ADVAPI32.@]
2277  */
2278 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2279 {
2280     TRACE("%p %p\n", pTrustee, pSid);
2281
2282     pTrustee->pMultipleTrustee = NULL;
2283     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2284     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2285     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2286     pTrustee->ptstrName = (LPWSTR) pSid;
2287 }
2288
2289 /******************************************************************************
2290  * BuildTrusteeWithNameA [ADVAPI32.@]
2291  */
2292 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2293 {
2294     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2295
2296     pTrustee->pMultipleTrustee = NULL;
2297     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2298     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2299     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2300     pTrustee->ptstrName = name;
2301 }
2302
2303 /******************************************************************************
2304  * BuildTrusteeWithNameW [ADVAPI32.@]
2305  */
2306 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2307 {
2308     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2309
2310     pTrustee->pMultipleTrustee = NULL;
2311     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2312     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2313     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2314     pTrustee->ptstrName = name;
2315 }
2316
2317 /****************************************************************************** 
2318  * GetTrusteeFormA [ADVAPI32.@] 
2319  */ 
2320 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
2321 {  
2322     TRACE("(%p)\n", pTrustee); 
2323   
2324     if (!pTrustee) 
2325         return TRUSTEE_BAD_FORM; 
2326   
2327     return pTrustee->TrusteeForm; 
2328 }  
2329   
2330 /****************************************************************************** 
2331  * GetTrusteeFormW [ADVAPI32.@] 
2332  */ 
2333 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
2334 {  
2335     TRACE("(%p)\n", pTrustee); 
2336   
2337     if (!pTrustee) 
2338         return TRUSTEE_BAD_FORM; 
2339   
2340     return pTrustee->TrusteeForm; 
2341 }  
2342   
2343 /****************************************************************************** 
2344  * GetTrusteeNameA [ADVAPI32.@] 
2345  */ 
2346 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
2347 {  
2348     TRACE("(%p)\n", pTrustee); 
2349   
2350     if (!pTrustee) 
2351         return NULL; 
2352   
2353     return pTrustee->ptstrName; 
2354 }  
2355   
2356 /****************************************************************************** 
2357  * GetTrusteeNameW [ADVAPI32.@] 
2358  */ 
2359 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
2360 {  
2361     TRACE("(%p)\n", pTrustee); 
2362   
2363     if (!pTrustee) 
2364         return NULL; 
2365   
2366     return pTrustee->ptstrName; 
2367 }  
2368   
2369 /****************************************************************************** 
2370  * GetTrusteeTypeA [ADVAPI32.@] 
2371  */ 
2372 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
2373 {  
2374     TRACE("(%p)\n", pTrustee); 
2375   
2376     if (!pTrustee) 
2377         return TRUSTEE_IS_UNKNOWN; 
2378   
2379     return pTrustee->TrusteeType; 
2380 }  
2381   
2382 /****************************************************************************** 
2383  * GetTrusteeTypeW [ADVAPI32.@] 
2384  */ 
2385 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
2386 {  
2387     TRACE("(%p)\n", pTrustee); 
2388   
2389     if (!pTrustee) 
2390         return TRUSTEE_IS_UNKNOWN; 
2391   
2392     return pTrustee->TrusteeType; 
2393
2394  
2395 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2396                                DWORD nAclInformationLength,
2397                                ACL_INFORMATION_CLASS dwAclInformationClass )
2398 {
2399     FIXME("%p %p 0x%08lx 0x%08x - stub\n", pAcl, pAclInformation,
2400           nAclInformationLength, dwAclInformationClass);
2401
2402     return TRUE;
2403 }
2404
2405 /******************************************************************************
2406  * SetEntriesInAclA [ADVAPI32.@]
2407  */
2408 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2409                                PACL OldAcl, PACL* NewAcl )
2410 {
2411     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2412     return ERROR_CALL_NOT_IMPLEMENTED;
2413 }
2414
2415 /******************************************************************************
2416  * SetEntriesInAclW [ADVAPI32.@]
2417  */
2418 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2419                                PACL OldAcl, PACL* NewAcl )
2420 {
2421     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2422     return ERROR_CALL_NOT_IMPLEMENTED;
2423 }
2424
2425 /******************************************************************************
2426  * SetNamedSecurityInfoA [ADVAPI32.@]
2427  */
2428 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2429         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2430         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2431 {
2432     DWORD len;
2433     LPWSTR wstr = NULL;
2434     DWORD r;
2435
2436     TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2437            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2438
2439     if( pObjectName )
2440     {
2441         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2442         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2443         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2444     }
2445
2446     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2447                            psidGroup, pDacl, pSacl );
2448
2449     HeapFree( GetProcessHeap(), 0, wstr );
2450
2451     return r;
2452 }
2453
2454 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2455     PSECURITY_DESCRIPTOR ModificationDescriptor,
2456     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2457     PGENERIC_MAPPING GenericMapping,
2458     HANDLE Token )
2459 {
2460     FIXME("0x%08lx %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2461           ObjectsSecurityDescriptor, GenericMapping, Token);
2462
2463     return TRUE;
2464 }
2465
2466 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2467   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2468   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2469 {
2470     FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2471           ControlBitsToSet);
2472
2473     return TRUE;
2474 }
2475
2476 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2477 {
2478     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2479 }
2480
2481 /******************************************************************************
2482  * AreAnyAccessesGranted [ADVAPI32.@]
2483  *
2484  * Determines whether or not any of a set of specified access permissions have
2485  * been granted or not.
2486  *
2487  * PARAMS
2488  *   GrantedAccess [I] The permissions that have been granted.
2489  *   DesiredAccess [I] The permissions that you want to have.
2490  *
2491  * RETURNS
2492  *   Nonzero if any of the permissions have been granted, zero if none of the
2493  *   permissions have been granted.
2494  */
2495
2496 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2497 {
2498     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
2499 }
2500
2501 /******************************************************************************
2502  * SetNamedSecurityInfoW [ADVAPI32.@]
2503  */
2504 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
2505         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2506         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2507 {
2508     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
2509            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2510     return ERROR_SUCCESS;
2511 }
2512
2513 /******************************************************************************
2514  * GetExplicitEntriesFromAclA [ADVAPI32.@]
2515  */
2516 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
2517         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
2518 {
2519     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2520     return ERROR_CALL_NOT_IMPLEMENTED;
2521 }
2522
2523 /******************************************************************************
2524  * GetExplicitEntriesFromAclW [ADVAPI32.@]
2525  */
2526 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
2527         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
2528 {
2529     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2530     return ERROR_CALL_NOT_IMPLEMENTED;
2531 }
2532
2533
2534 /******************************************************************************
2535  * ParseAclStringFlags
2536  */
2537 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2538 {
2539     DWORD flags = 0;
2540     LPCWSTR szAcl = *StringAcl;
2541
2542     while (*szAcl != '(')
2543     {
2544         if (*szAcl == 'P')
2545         {
2546             flags |= SE_DACL_PROTECTED;
2547         }
2548         else if (*szAcl == 'A')
2549         {
2550             szAcl++;
2551             if (*szAcl == 'R')
2552                 flags |= SE_DACL_AUTO_INHERIT_REQ;
2553             else if (*szAcl == 'I')
2554                 flags |= SE_DACL_AUTO_INHERITED;
2555         }
2556         szAcl++;
2557     }
2558
2559     *StringAcl = szAcl;
2560     return flags;
2561 }
2562
2563 /******************************************************************************
2564  * ParseAceStringType
2565  */
2566 ACEFLAG AceType[] =
2567 {
2568     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2569     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
2570     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
2571     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
2572     /*
2573     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2574     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
2575     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
2576     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2577     */
2578     { NULL, 0 },
2579 };
2580
2581 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2582 {
2583     UINT len = 0;
2584     LPCWSTR szAcl = *StringAcl;
2585     LPACEFLAG lpaf = AceType;
2586
2587     while (lpaf->wstr &&
2588         (len = strlenW(lpaf->wstr)) &&
2589         strncmpW(lpaf->wstr, szAcl, len))
2590         lpaf++;
2591
2592     if (!lpaf->wstr)
2593         return 0;
2594
2595     *StringAcl += len;
2596     return lpaf->value;
2597 }
2598
2599
2600 /******************************************************************************
2601  * ParseAceStringFlags
2602  */
2603 ACEFLAG AceFlags[] =
2604 {
2605     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2606     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
2607     { SDDL_INHERITED,         INHERITED_ACE },
2608     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
2609     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
2610     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
2611     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
2612     { NULL, 0 },
2613 };
2614
2615 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2616 {
2617     UINT len = 0;
2618     BYTE flags = 0;
2619     LPCWSTR szAcl = *StringAcl;
2620
2621     while (*szAcl != ';')
2622     {
2623         LPACEFLAG lpaf = AceFlags;
2624
2625         while (lpaf->wstr &&
2626                (len = strlenW(lpaf->wstr)) &&
2627                strncmpW(lpaf->wstr, szAcl, len))
2628             lpaf++;
2629
2630         if (!lpaf->wstr)
2631             return 0;
2632
2633         flags |= lpaf->value;
2634         szAcl += len;
2635     }
2636
2637     *StringAcl = szAcl;
2638     return flags;
2639 }
2640
2641
2642 /******************************************************************************
2643  * ParseAceStringRights
2644  */
2645 ACEFLAG AceRights[] =
2646 {
2647     { SDDL_GENERIC_ALL,     GENERIC_ALL },
2648     { SDDL_GENERIC_READ,    GENERIC_READ },
2649     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
2650     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2651     { SDDL_READ_CONTROL,    READ_CONTROL },
2652     { SDDL_STANDARD_DELETE, DELETE },
2653     { SDDL_WRITE_DAC,       WRITE_DAC },
2654     { SDDL_WRITE_OWNER,     WRITE_OWNER },
2655     { NULL, 0 },
2656 };
2657
2658 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2659 {
2660     UINT len = 0;
2661     DWORD rights = 0;
2662     LPCWSTR szAcl = *StringAcl;
2663
2664     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2665     {
2666         LPCWSTR p = szAcl;
2667
2668         while (*p && *p != ';')
2669             p++;
2670
2671         if (p - szAcl <= 8)
2672         {
2673             rights = strtoulW(szAcl, NULL, 16);
2674             *StringAcl = p;
2675         }
2676         else
2677             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2678     }
2679     else
2680     {
2681         while (*szAcl != ';')
2682         {
2683             LPACEFLAG lpaf = AceRights;
2684
2685             while (lpaf->wstr &&
2686                (len = strlenW(lpaf->wstr)) &&
2687                strncmpW(lpaf->wstr, szAcl, len))
2688             {
2689                lpaf++;
2690             }
2691
2692             if (!lpaf->wstr)
2693                 return 0;
2694
2695             rights |= lpaf->value;
2696             szAcl += len;
2697         }
2698     }
2699
2700     *StringAcl = szAcl;
2701     return rights;
2702 }
2703
2704
2705 /******************************************************************************
2706  * ParseStringAclToAcl
2707  * 
2708  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
2709  */
2710 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
2711     PACL pAcl, LPDWORD cBytes)
2712 {
2713     DWORD val;
2714     DWORD sidlen;
2715     DWORD length = sizeof(ACL);
2716     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
2717
2718     TRACE("%s\n", debugstr_w(StringAcl));
2719
2720     if (!StringAcl)
2721         return FALSE;
2722
2723     if (pAcl) /* pAce is only useful if we're setting values */
2724         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
2725
2726     /* Parse ACL flags */
2727     *lpdwFlags = ParseAclStringFlags(&StringAcl);
2728
2729     /* Parse ACE */
2730     while (*StringAcl == '(')
2731     {
2732         StringAcl++;
2733
2734         /* Parse ACE type */
2735         val = ParseAceStringType(&StringAcl);
2736         if (pAce)
2737             pAce->Header.AceType = (BYTE) val;
2738         if (*StringAcl != ';')
2739             goto lerr;
2740         StringAcl++;
2741
2742         /* Parse ACE flags */
2743         val = ParseAceStringFlags(&StringAcl);
2744         if (pAce)
2745             pAce->Header.AceFlags = (BYTE) val;
2746         if (*StringAcl != ';')
2747             goto lerr;
2748         StringAcl++;
2749
2750         /* Parse ACE rights */
2751         val = ParseAceStringRights(&StringAcl);
2752         if (pAce)
2753             pAce->Mask = val;
2754         if (*StringAcl != ';')
2755             goto lerr;
2756         StringAcl++;
2757
2758         /* Parse ACE object guid */
2759         if (*StringAcl != ';')
2760         {
2761             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2762             goto lerr;
2763         }
2764         StringAcl++;
2765
2766         /* Parse ACE inherit object guid */
2767         if (*StringAcl != ';')
2768         {
2769             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2770             goto lerr;
2771         }
2772         StringAcl++;
2773
2774         /* Parse ACE account sid */
2775         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
2776         {
2777             while (*StringAcl && *StringAcl != ')')
2778                 StringAcl++;
2779         }
2780
2781         if (*StringAcl != ')')
2782             goto lerr;
2783         StringAcl++;
2784
2785         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
2786     }
2787
2788     *cBytes = length;
2789     return TRUE;
2790
2791 lerr:
2792     WARN("Invalid ACE string format\n");
2793     return FALSE;
2794 }
2795
2796
2797 /******************************************************************************
2798  * ParseStringSecurityDescriptorToSecurityDescriptor
2799  */
2800 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
2801     LPCWSTR StringSecurityDescriptor,
2802     SECURITY_DESCRIPTOR* SecurityDescriptor,
2803     LPDWORD cBytes)
2804 {
2805     BOOL bret = FALSE;
2806     WCHAR toktype;
2807     WCHAR tok[MAX_PATH];
2808     LPCWSTR lptoken;
2809     LPBYTE lpNext = NULL;
2810     DWORD len;
2811
2812     *cBytes = 0;
2813
2814     if (SecurityDescriptor)
2815         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
2816
2817     while (*StringSecurityDescriptor)
2818     {
2819         toktype = *StringSecurityDescriptor;
2820
2821         /* Expect char identifier followed by ':' */
2822         StringSecurityDescriptor++;
2823         if (*StringSecurityDescriptor != ':')
2824         {
2825             SetLastError(ERROR_INVALID_PARAMETER);
2826             goto lend;
2827         }
2828         StringSecurityDescriptor++;
2829
2830         /* Extract token */
2831         lptoken = StringSecurityDescriptor;
2832         while (*lptoken && *lptoken != ':')
2833             lptoken++;
2834
2835         if (*lptoken)
2836             lptoken--;
2837
2838         len = lptoken - StringSecurityDescriptor;
2839         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
2840         tok[len] = 0;
2841
2842         switch (toktype)
2843         {
2844             case 'O':
2845             {
2846                 DWORD bytes;
2847
2848                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2849                     goto lend;
2850
2851                 if (SecurityDescriptor)
2852                 {
2853                     SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
2854                         (DWORD) SecurityDescriptor);
2855                     lpNext += bytes; /* Advance to next token */
2856                 }
2857
2858                 *cBytes += bytes;
2859
2860                 break;
2861             }
2862
2863             case 'G':
2864             {
2865                 DWORD bytes;
2866
2867                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2868                     goto lend;
2869
2870                 if (SecurityDescriptor)
2871                 {
2872                     SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - 
2873                         (DWORD) SecurityDescriptor);
2874                     lpNext += bytes; /* Advance to next token */
2875                 }
2876
2877                 *cBytes += bytes;
2878
2879                 break;
2880             }
2881
2882             case 'D':
2883             {
2884                 DWORD flags;
2885                 DWORD bytes;
2886
2887                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2888                     goto lend;
2889
2890                 if (SecurityDescriptor)
2891                 {
2892                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
2893                     SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
2894                         (DWORD) SecurityDescriptor);
2895                     lpNext += bytes; /* Advance to next token */
2896                 }
2897
2898                 *cBytes += bytes;
2899
2900                 break;
2901             }
2902
2903             case 'S':
2904             {
2905                 DWORD flags;
2906                 DWORD bytes;
2907
2908                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2909                     goto lend;
2910
2911                 if (SecurityDescriptor)
2912                 {
2913                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
2914                     SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
2915                         (DWORD) SecurityDescriptor);
2916                     lpNext += bytes; /* Advance to next token */
2917                 }
2918
2919                 *cBytes += bytes;
2920
2921                 break;
2922             }
2923
2924             default:
2925                 FIXME("Unknown token\n");
2926                 SetLastError(ERROR_INVALID_PARAMETER);
2927                 goto lend;
2928         }
2929
2930         StringSecurityDescriptor = lptoken;
2931     }
2932
2933     bret = TRUE;
2934
2935 lend:
2936     return bret;
2937 }
2938
2939 /******************************************************************************
2940  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2941  */
2942 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
2943         LPCSTR StringSecurityDescriptor,
2944         DWORD StringSDRevision,
2945         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2946         PULONG SecurityDescriptorSize)
2947 {
2948     UINT len;
2949     BOOL ret = FALSE;
2950     LPWSTR StringSecurityDescriptorW;
2951
2952     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
2953     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2954
2955     if (StringSecurityDescriptorW)
2956     {
2957         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
2958
2959         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
2960                                                                    StringSDRevision, SecurityDescriptor,
2961                                                                    SecurityDescriptorSize);
2962         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
2963     }
2964
2965     return ret;
2966 }
2967
2968 /******************************************************************************
2969  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2970  */
2971 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2972         LPCWSTR StringSecurityDescriptor,
2973         DWORD StringSDRevision,
2974         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2975         PULONG SecurityDescriptorSize)
2976 {
2977     DWORD cBytes;
2978     SECURITY_DESCRIPTOR* psd;
2979     BOOL bret = FALSE;
2980
2981     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2982
2983     if (GetVersion() & 0x80000000)
2984     {
2985         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2986         goto lend;
2987     }
2988     else if (StringSDRevision != SID_REVISION)
2989     {
2990         SetLastError(ERROR_UNKNOWN_REVISION);
2991         goto lend;
2992     }
2993
2994     /* Compute security descriptor length */
2995     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2996         NULL, &cBytes))
2997         goto lend;
2998
2999     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3000         GMEM_ZEROINIT, cBytes);
3001
3002     psd->Revision = SID_REVISION;
3003     psd->Control |= SE_SELF_RELATIVE;
3004
3005     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3006         psd, &cBytes))
3007     {
3008         LocalFree(psd);
3009         goto lend;
3010     }
3011
3012     if (SecurityDescriptorSize)
3013         *SecurityDescriptorSize = cBytes;
3014
3015     bret = TRUE;
3016  
3017 lend:
3018     TRACE(" ret=%d\n", bret);
3019     return bret;
3020 }
3021
3022 /******************************************************************************
3023  * ConvertStringSidToSidW [ADVAPI32.@]
3024  */
3025 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3026 {
3027     BOOL bret = FALSE;
3028     DWORD cBytes;
3029
3030     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3031     if (GetVersion() & 0x80000000)
3032         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3033     else if (!StringSid || !Sid)
3034         SetLastError(ERROR_INVALID_PARAMETER);
3035     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3036     {
3037         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
3038
3039         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3040         if (!bret)
3041             LocalFree(*Sid); 
3042     }
3043     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3044     return bret;
3045 }
3046
3047 /******************************************************************************
3048  * ConvertStringSidToSidA [ADVAPI32.@]
3049  */
3050 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3051 {
3052     BOOL bret = FALSE;
3053
3054     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3055     if (GetVersion() & 0x80000000)
3056         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3057     else if (!StringSid || !Sid)
3058         SetLastError(ERROR_INVALID_PARAMETER);
3059     else
3060     {
3061         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
3062         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
3063          len * sizeof(WCHAR));
3064
3065         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
3066         bret = ConvertStringSidToSidW(wStringSid, Sid);
3067         HeapFree(GetProcessHeap(), 0, wStringSid);
3068     }
3069     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3070     return bret;
3071 }
3072
3073 /******************************************************************************
3074  * ConvertSidToStringSidW [ADVAPI32.@]
3075  *
3076  *  format of SID string is:
3077  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3078  *  where
3079  *    <rev> is the revision of the SID encoded as decimal
3080  *    <auth> is the identifier authority encoded as hex
3081  *    <subauthN> is the subauthority id encoded as decimal
3082  */
3083 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
3084 {
3085     DWORD sz, i;
3086     LPWSTR str;
3087     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3088     WCHAR subauthfmt[] = { '-','%','u',0 };
3089     SID* pisid=pSid;
3090
3091     TRACE("%p %p\n", pSid, pstr );
3092
3093     if( !IsValidSid( pSid ) )
3094         return FALSE;
3095
3096     if (pisid->Revision != SDDL_REVISION)
3097         return FALSE;
3098     if (pisid->IdentifierAuthority.Value[0] ||
3099      pisid->IdentifierAuthority.Value[1])
3100     {
3101         FIXME("not matching MS' bugs\n");
3102         return FALSE;
3103     }
3104
3105     sz = 14 + pisid->SubAuthorityCount * 11;
3106     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
3107     sprintfW( str, fmt, pisid->Revision, MAKELONG(
3108      MAKEWORD( pisid->IdentifierAuthority.Value[5],
3109      pisid->IdentifierAuthority.Value[4] ),
3110      MAKEWORD( pisid->IdentifierAuthority.Value[3],
3111      pisid->IdentifierAuthority.Value[2] ) ) );
3112     for( i=0; i<pisid->SubAuthorityCount; i++ )
3113         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
3114     *pstr = str;
3115
3116     return TRUE;
3117 }
3118
3119 /******************************************************************************
3120  * ConvertSidToStringSidA [ADVAPI32.@]
3121  */
3122 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
3123 {
3124     LPWSTR wstr = NULL;
3125     LPSTR str;
3126     UINT len;
3127
3128     TRACE("%p %p\n", pSid, pstr );
3129
3130     if( !ConvertSidToStringSidW( pSid, &wstr ) )
3131         return FALSE;
3132
3133     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
3134     str = LocalAlloc( 0, len );
3135     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
3136     LocalFree( wstr );
3137
3138     *pstr = str;
3139
3140     return TRUE;
3141 }
3142
3143 BOOL WINAPI CreatePrivateObjectSecurity(
3144         PSECURITY_DESCRIPTOR ParentDescriptor,
3145         PSECURITY_DESCRIPTOR CreatorDescriptor,
3146         PSECURITY_DESCRIPTOR* NewDescriptor,
3147         BOOL IsDirectoryObject,
3148         HANDLE Token,
3149         PGENERIC_MAPPING GenericMapping )
3150 {
3151     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
3152           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
3153
3154     return FALSE;
3155 }
3156
3157 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
3158 {
3159     FIXME("%p - stub\n", ObjectDescriptor);
3160
3161     return TRUE;
3162 }
3163
3164 BOOL WINAPI CreateProcessAsUserA(
3165         HANDLE hToken,
3166         LPCSTR lpApplicationName,
3167         LPSTR lpCommandLine,
3168         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3169         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3170         BOOL bInheritHandles,
3171         DWORD dwCreationFlags,
3172         LPVOID lpEnvironment,
3173         LPCSTR lpCurrentDirectory,
3174         LPSTARTUPINFOA lpStartupInfo,
3175         LPPROCESS_INFORMATION lpProcessInformation )
3176 {
3177     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
3178           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3179           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3180
3181     return FALSE;
3182 }
3183
3184 BOOL WINAPI CreateProcessAsUserW(
3185         HANDLE hToken,
3186         LPCWSTR lpApplicationName,
3187         LPWSTR lpCommandLine,
3188         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3189         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3190         BOOL bInheritHandles,
3191         DWORD dwCreationFlags,
3192         LPVOID lpEnvironment,
3193         LPCWSTR lpCurrentDirectory,
3194         LPSTARTUPINFOW lpStartupInfo,
3195         LPPROCESS_INFORMATION lpProcessInformation )
3196 {
3197     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - semi- stub\n", hToken, 
3198           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
3199           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
3200           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3201
3202     /* We should create the process with a suspended main thread */
3203     if (!CreateProcessW (lpApplicationName,
3204                          lpCommandLine,
3205                          lpProcessAttributes,
3206                          lpThreadAttributes,
3207                          bInheritHandles,
3208                          dwCreationFlags, /* CREATE_SUSPENDED */
3209                          lpEnvironment,
3210                          lpCurrentDirectory,
3211                          lpStartupInfo,
3212                          lpProcessInformation))
3213     {
3214       return FALSE;
3215     }
3216
3217     return TRUE;
3218 }
3219
3220 /******************************************************************************
3221  * ComputeStringSidSize
3222  */
3223 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3224 {
3225     int ctok = 0;
3226     DWORD size = sizeof(SID);
3227
3228     while (*StringSid)
3229     {
3230         if (*StringSid == '-')
3231             ctok++;
3232         StringSid++;
3233     }
3234
3235     if (ctok > 3)
3236         size += (ctok - 3) * sizeof(DWORD);
3237
3238     return size;
3239 }
3240
3241 BOOL WINAPI DuplicateTokenEx(
3242         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
3243         LPSECURITY_ATTRIBUTES lpTokenAttributes,
3244         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3245         TOKEN_TYPE TokenType,
3246         PHANDLE DuplicateTokenHandle )
3247 {
3248     OBJECT_ATTRIBUTES ObjectAttributes;
3249
3250     TRACE("%p 0x%08lx 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3251           ImpersonationLevel, TokenType, DuplicateTokenHandle);
3252
3253     InitializeObjectAttributes(
3254         &ObjectAttributes,
3255         NULL,
3256         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
3257         NULL,
3258         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
3259
3260     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
3261                                            dwDesiredAccess,
3262                                            &ObjectAttributes,
3263                                            ImpersonationLevel,
3264                                            TokenType,
3265                                            DuplicateTokenHandle ) );
3266 }
3267
3268 BOOL WINAPI DuplicateToken(
3269         HANDLE ExistingTokenHandle,
3270         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3271         PHANDLE DuplicateTokenHandle )
3272 {
3273     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
3274                              NULL, ImpersonationLevel, TokenImpersonation,
3275                              DuplicateTokenHandle );
3276 }
3277
3278 BOOL WINAPI EnumDependentServicesA(
3279         SC_HANDLE hService,
3280         DWORD dwServiceState,
3281         LPENUM_SERVICE_STATUSA lpServices,
3282         DWORD cbBufSize,
3283         LPDWORD pcbBytesNeeded,
3284         LPDWORD lpServicesReturned )
3285 {
3286     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3287           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3288
3289     return FALSE;
3290 }
3291
3292 BOOL WINAPI EnumDependentServicesW(
3293         SC_HANDLE hService,
3294         DWORD dwServiceState,
3295         LPENUM_SERVICE_STATUSW lpServices,
3296         DWORD cbBufSize,
3297         LPDWORD pcbBytesNeeded,
3298         LPDWORD lpServicesReturned )
3299 {
3300     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3301           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3302
3303     return FALSE;
3304 }
3305
3306 /******************************************************************************
3307  * ParseStringSidToSid
3308  */
3309 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3310 {
3311     BOOL bret = FALSE;
3312     SID* pisid=pSid;
3313
3314     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3315     if (!StringSid)
3316     {
3317         SetLastError(ERROR_INVALID_PARAMETER);
3318         TRACE("StringSid is NULL, returning FALSE\n");
3319         return FALSE;
3320     }
3321
3322     *cBytes = ComputeStringSidSize(StringSid);
3323     if (!pisid) /* Simply compute the size */
3324     {
3325         TRACE("only size requested, returning TRUE\n");
3326         return TRUE;
3327     }
3328
3329     if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
3330     {
3331         DWORD i = 0, identAuth;
3332         DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
3333
3334         StringSid += 2; /* Advance to Revision */
3335         pisid->Revision = atoiW(StringSid);
3336
3337         if (pisid->Revision != SDDL_REVISION)
3338         {
3339             TRACE("Revision %d is unknown\n", pisid->Revision);
3340             goto lend; /* ERROR_INVALID_SID */
3341         }
3342         if (csubauth == 0)
3343         {
3344             TRACE("SubAuthorityCount is 0\n");
3345             goto lend; /* ERROR_INVALID_SID */
3346         }
3347
3348         pisid->SubAuthorityCount = csubauth;
3349
3350         /* Advance to identifier authority */
3351         while (*StringSid && *StringSid != '-')
3352             StringSid++;
3353         if (*StringSid == '-')
3354             StringSid++;
3355
3356         /* MS' implementation can't handle values greater than 2^32 - 1, so
3357          * we don't either; assume most significant bytes are always 0
3358          */
3359         pisid->IdentifierAuthority.Value[0] = 0;
3360         pisid->IdentifierAuthority.Value[1] = 0;
3361         identAuth = atoiW(StringSid);
3362         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3363         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3364         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3365         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3366
3367         /* Advance to first sub authority */
3368         while (*StringSid && *StringSid != '-')
3369             StringSid++;
3370         if (*StringSid == '-')
3371             StringSid++;
3372
3373         while (*StringSid)
3374         {       
3375             while (*StringSid && *StringSid != '-')
3376                 StringSid++;
3377
3378             pisid->SubAuthority[i++] = atoiW(StringSid);
3379         }
3380
3381         if (i != pisid->SubAuthorityCount)
3382             goto lend; /* ERROR_INVALID_SID */
3383
3384         bret = TRUE;
3385     }
3386     else /* String constant format  - Only available in winxp and above */
3387     {
3388         pisid->Revision = SDDL_REVISION;
3389         pisid->SubAuthorityCount = 1;
3390
3391         FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3392
3393         /* TODO: Lookup string of well-known SIDs in table */
3394         pisid->IdentifierAuthority.Value[5] = 0;
3395         pisid->SubAuthority[0] = 0;
3396
3397         bret = TRUE;
3398     }
3399
3400 lend:
3401     if (!bret)
3402         SetLastError(ERROR_INVALID_SID);
3403
3404     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3405     return bret;
3406 }
3407
3408 /******************************************************************************
3409  * GetNamedSecurityInfoA [ADVAPI32.@]
3410  */
3411 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
3412         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3413         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3414         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3415 {
3416     DWORD len;
3417     LPWSTR wstr = NULL;
3418     DWORD r;
3419
3420     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3421         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3422
3423     if( pObjectName )
3424     {
3425         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3426         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3427         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3428     }
3429
3430     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3431                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3432
3433     HeapFree( GetProcessHeap(), 0, wstr );
3434
3435     return r;
3436 }
3437
3438 /******************************************************************************
3439  * GetNamedSecurityInfoW [ADVAPI32.@]
3440  */
3441 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
3442     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
3443     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
3444 {
3445     DWORD needed, offset;
3446     SECURITY_DESCRIPTOR_RELATIVE *relative;
3447     BYTE *buffer;
3448
3449     TRACE( "%s %d %ld %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
3450            group, dacl, sacl, descriptor );
3451
3452     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
3453
3454     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3455     if (info & OWNER_SECURITY_INFORMATION)
3456         needed += sizeof(sidWorld);
3457     if (info & GROUP_SECURITY_INFORMATION)
3458         needed += sizeof(sidWorld);
3459     if (info & DACL_SECURITY_INFORMATION)
3460         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3461     if (info & SACL_SECURITY_INFORMATION)
3462         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3463
3464     /* must be freed by caller */
3465     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
3466     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
3467
3468     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
3469     {
3470         HeapFree( GetProcessHeap(), 0, *descriptor );
3471         return ERROR_INVALID_SECURITY_DESCR;
3472     }
3473
3474     relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
3475     relative->Control |= SE_SELF_RELATIVE;
3476     buffer = (BYTE *)relative;
3477     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3478
3479     if (owner && (info & OWNER_SECURITY_INFORMATION))
3480     {
3481         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3482         relative->Owner = offset;
3483         *owner = buffer + offset;
3484         offset += sizeof(sidWorld);
3485     }
3486     if (group && (info & GROUP_SECURITY_INFORMATION))
3487     {
3488         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3489         relative->Group = offset;
3490         *group = buffer + offset;
3491         offset += sizeof(sidWorld);
3492     }
3493     if (dacl && (info & DACL_SECURITY_INFORMATION))
3494     {
3495         GetWorldAccessACL( (PACL)(buffer + offset) );
3496         relative->Dacl = offset;
3497         *dacl = (PACL)(buffer + offset);
3498         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3499     }
3500     if (sacl && (info & SACL_SECURITY_INFORMATION))
3501     {
3502         GetWorldAccessACL( (PACL)(buffer + offset) );
3503         relative->Sacl = offset;
3504         *sacl = (PACL)(buffer + offset);
3505     }
3506     return ERROR_SUCCESS;
3507 }
3508
3509 /******************************************************************************
3510  * DecryptFileW [ADVAPI32.@]
3511  */
3512 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
3513 {
3514     FIXME("%s %08lx\n", debugstr_w(lpFileName), dwReserved);
3515     return TRUE;
3516 }
3517
3518 /******************************************************************************
3519  * DecryptFileA [ADVAPI32.@]
3520  */
3521 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
3522 {
3523     FIXME("%s %08lx\n", debugstr_a(lpFileName), dwReserved);
3524     return TRUE;
3525 }
3526
3527 /******************************************************************************
3528  * EncryptFileW [ADVAPI32.@]
3529  */
3530 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
3531 {
3532     FIXME("%s\n", debugstr_w(lpFileName));
3533     return TRUE;
3534 }
3535
3536 /******************************************************************************
3537  * EncryptFileA [ADVAPI32.@]
3538  */
3539 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
3540 {
3541     FIXME("%s\n", debugstr_a(lpFileName));
3542     return TRUE;
3543 }
3544
3545 /******************************************************************************
3546  * SetSecurityInfo [ADVAPI32.@]
3547  */
3548 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
3549                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
3550                       PSID psidGroup, PACL pDacl, PACL pSacl) {
3551     FIXME("stub\n");
3552     return ERROR_SUCCESS;
3553 }