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