Prevent crash when no URL is specified.
[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     FIXME("(%s) : returns fake SECURITY_DESCRIPTOR\n", debugstr_w(lpFileName) );
1327
1328     nNeeded = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1329     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1330         nNeeded += sizeof(sidWorld);
1331     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1332         nNeeded += sizeof(sidWorld);
1333     if (RequestedInformation & DACL_SECURITY_INFORMATION)
1334         nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1335     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1336         nNeeded += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1337
1338     *lpnLengthNeeded = nNeeded;
1339
1340     if (nNeeded > nLength)
1341             return TRUE;
1342
1343     if (!InitializeSecurityDescriptor(pSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION))
1344         return FALSE;
1345
1346     pSDRelative = (PISECURITY_DESCRIPTOR_RELATIVE) pSecurityDescriptor;
1347     pSDRelative->Control |= SE_SELF_RELATIVE;
1348     pBuffer = (LPBYTE) pSDRelative;
1349     iLocNow = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
1350
1351     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
1352     {
1353         memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1354         pSDRelative->Owner = iLocNow;
1355         iLocNow += sizeof(sidWorld);
1356     }
1357     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
1358     {
1359         memcpy(pBuffer + iLocNow, &sidWorld, sizeof(sidWorld));
1360         pSDRelative->Group = iLocNow;
1361         iLocNow += sizeof(sidWorld);
1362     }
1363     if (RequestedInformation & DACL_SECURITY_INFORMATION)
1364     {
1365         GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1366         pSDRelative->Dacl = iLocNow;
1367         iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL;
1368     }
1369     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1370     {
1371         GetWorldAccessACL((PACL) (pBuffer + iLocNow));
1372         pSDRelative->Sacl = iLocNow;
1373         /* iLocNow += WINE_SIZE_OF_WORLD_ACCESS_ACL; */
1374     }
1375     return TRUE;
1376 }
1377
1378
1379 /******************************************************************************
1380  * LookupAccountSidA [ADVAPI32.@]
1381  */
1382 BOOL WINAPI
1383 LookupAccountSidA(
1384         IN LPCSTR system,
1385         IN PSID sid,
1386         OUT LPSTR account,
1387         IN OUT LPDWORD accountSize,
1388         OUT LPSTR domain,
1389         IN OUT LPDWORD domainSize,
1390         OUT PSID_NAME_USE name_use )
1391 {
1392         static const char ac[] = "Administrator";
1393         static const char dm[] = "DOMAIN";
1394         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1395               debugstr_a(system),sid,
1396               account,accountSize,accountSize?*accountSize:0,
1397               domain,domainSize,domainSize?*domainSize:0,
1398               name_use);
1399
1400         if (accountSize) *accountSize = strlen(ac)+1;
1401         if (account && (*accountSize > strlen(ac)))
1402           strcpy(account, ac);
1403
1404         if (domainSize) *domainSize = strlen(dm)+1;
1405         if (domain && (*domainSize > strlen(dm)))
1406           strcpy(domain,dm);
1407
1408         if (name_use) *name_use = SidTypeUser;
1409         return TRUE;
1410 }
1411
1412 /******************************************************************************
1413  * LookupAccountSidW [ADVAPI32.@]
1414  *
1415  * PARAMS
1416  *   system      []
1417  *   sid         []
1418  *   account     []
1419  *   accountSize []
1420  *   domain      []
1421  *   domainSize  []
1422  *   name_use    []
1423  */
1424 BOOL WINAPI
1425 LookupAccountSidW(
1426         IN LPCWSTR system,
1427         IN PSID sid,
1428         OUT LPWSTR account,
1429         IN OUT LPDWORD accountSize,
1430         OUT LPWSTR domain,
1431         IN OUT LPDWORD domainSize,
1432         OUT PSID_NAME_USE name_use )
1433 {
1434     static const WCHAR ac[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0};
1435     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
1436         FIXME("(%s,sid=%p,%p,%p(%lu),%p,%p(%lu),%p): semi-stub\n",
1437               debugstr_w(system),sid,
1438               account,accountSize,accountSize?*accountSize:0,
1439               domain,domainSize,domainSize?*domainSize:0,
1440               name_use);
1441
1442         if (accountSize) *accountSize = strlenW(ac)+1;
1443         if (account && (*accountSize > strlenW(ac)))
1444             strcpyW(account, ac);
1445
1446         if (domainSize) *domainSize = strlenW(dm)+1;
1447         if (domain && (*domainSize > strlenW(dm)))
1448             strcpyW(domain,dm);
1449
1450         if (name_use) *name_use = SidTypeUser;
1451         return TRUE;
1452 }
1453
1454 /******************************************************************************
1455  * SetFileSecurityA [ADVAPI32.@]
1456  * Sets the security of a file or directory
1457  */
1458 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1459                                 SECURITY_INFORMATION RequestedInformation,
1460                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1461 {
1462     DWORD len;
1463     BOOL r;
1464     LPWSTR name = NULL;
1465
1466     if( lpFileName )
1467     {
1468         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1469         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1470         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1471     }
1472
1473     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
1474     HeapFree( GetProcessHeap(), 0, name );
1475
1476     return r;
1477 }
1478
1479 /******************************************************************************
1480  * SetFileSecurityW [ADVAPI32.@]
1481  * Sets the security of a file or directory
1482  *
1483  * PARAMS
1484  *   lpFileName           []
1485  *   RequestedInformation []
1486  *   pSecurityDescriptor  []
1487  */
1488 BOOL WINAPI
1489 SetFileSecurityW( LPCWSTR lpFileName,
1490                     SECURITY_INFORMATION RequestedInformation,
1491                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
1492 {
1493   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
1494   return TRUE;
1495 }
1496
1497 /******************************************************************************
1498  * QueryWindows31FilesMigration [ADVAPI32.@]
1499  *
1500  * PARAMS
1501  *   x1 []
1502  */
1503 BOOL WINAPI
1504 QueryWindows31FilesMigration( DWORD x1 )
1505 {
1506         FIXME("(%ld):stub\n",x1);
1507         return TRUE;
1508 }
1509
1510 /******************************************************************************
1511  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
1512  *
1513  * PARAMS
1514  *   x1 []
1515  *   x2 []
1516  *   x3 []
1517  *   x4 []
1518  */
1519 BOOL WINAPI
1520 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
1521                                                DWORD x4 )
1522 {
1523         FIXME("(0x%08lx,0x%08lx,0x%08lx,0x%08lx):stub\n",x1,x2,x3,x4);
1524         return TRUE;
1525 }
1526
1527 NTSTATUS WINAPI
1528 LsaEnumerateTrustedDomains(
1529     LSA_HANDLE PolicyHandle,
1530     PLSA_ENUMERATION_HANDLE EnumerationContext,
1531     PVOID* Buffer,
1532     ULONG PreferedMaximumLength,
1533     PULONG CountReturned)
1534 {
1535     FIXME("(%p,%p,%p,0x%08lx,%p):stub\n", PolicyHandle, EnumerationContext,
1536           Buffer, PreferedMaximumLength, CountReturned);
1537
1538     if (CountReturned) *CountReturned = 0;
1539     return STATUS_SUCCESS;
1540 }
1541
1542 NTSTATUS WINAPI
1543 LsaLookupNames(
1544   LSA_HANDLE PolicyHandle,
1545   ULONG Count,
1546   PLSA_UNICODE_STRING Names,
1547   PLSA_REFERENCED_DOMAIN_LIST* ReferencedDomains,
1548   PLSA_TRANSLATED_SID* Sids)
1549 {
1550     FIXME("(%p,0x%08lx,%p,%p,%p):stub\n", PolicyHandle, Count, Names,
1551           ReferencedDomains, Sids);
1552
1553     return STATUS_NONE_MAPPED;
1554 }
1555
1556 /******************************************************************************
1557  * LsaOpenPolicy [ADVAPI32.@]
1558  *
1559  * PARAMS
1560  *   SystemName       [I]
1561  *   ObjectAttributes [I]
1562  *   DesiredAccess    [I]
1563  *   PolicyHandle     [I/O]
1564  */
1565 NTSTATUS WINAPI
1566 LsaOpenPolicy(
1567         IN PLSA_UNICODE_STRING SystemName,
1568         IN PLSA_OBJECT_ATTRIBUTES ObjectAttributes,
1569         IN ACCESS_MASK DesiredAccess,
1570         IN OUT PLSA_HANDLE PolicyHandle)
1571 {
1572         FIXME("(%s,%p,0x%08lx,%p):stub\n",
1573               SystemName?debugstr_w(SystemName->Buffer):"null",
1574               ObjectAttributes, DesiredAccess, PolicyHandle);
1575         ADVAPI_ForceLocalComputer(SystemName ? SystemName->Buffer : NULL,
1576                                   STATUS_ACCESS_VIOLATION);
1577         dumpLsaAttributes(ObjectAttributes);
1578         if(PolicyHandle) *PolicyHandle = (LSA_HANDLE)0xcafe;
1579         return STATUS_SUCCESS;
1580 }
1581
1582 /******************************************************************************
1583  * LsaQueryInformationPolicy [ADVAPI32.@]
1584  */
1585 NTSTATUS WINAPI
1586 LsaQueryInformationPolicy(
1587         IN LSA_HANDLE PolicyHandle,
1588         IN POLICY_INFORMATION_CLASS InformationClass,
1589         OUT PVOID *Buffer)
1590 {
1591         FIXME("(%p,0x%08x,%p):stub\n",
1592               PolicyHandle, InformationClass, Buffer);
1593
1594         if(!Buffer) return FALSE;
1595         switch (InformationClass)
1596         {
1597           case PolicyAuditEventsInformation: /* 2 */
1598             {
1599               PPOLICY_AUDIT_EVENTS_INFO p = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(POLICY_AUDIT_EVENTS_INFO));
1600               p->AuditingMode = FALSE; /* no auditing */
1601               *Buffer = p;
1602             }
1603             break;
1604           case PolicyPrimaryDomainInformation: /* 3 */
1605           case PolicyAccountDomainInformation: /* 5 */
1606             {
1607               struct di
1608               { POLICY_PRIMARY_DOMAIN_INFO ppdi;
1609                 SID sid;
1610               };
1611               SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY};
1612
1613               struct di * xdi = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(xdi));
1614               HKEY key;
1615               BOOL useDefault = TRUE;
1616               LONG ret;
1617
1618               if ((ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
1619                "System\\CurrentControlSet\\Services\\VxD\\VNETSUP", 0,
1620                KEY_READ, &key)) == ERROR_SUCCESS)
1621               {
1622                   DWORD size = 0;
1623                   static const WCHAR wg[] = { 'W','o','r','k','g','r','o','u','p',0 };
1624
1625                   ret = RegQueryValueExW(key, wg, NULL, NULL, NULL, &size);
1626                   if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
1627                   {
1628                       xdi->ppdi.Name.Buffer = HeapAlloc(GetProcessHeap(),
1629                        HEAP_ZERO_MEMORY, size);
1630                       if ((ret = RegQueryValueExW(key, wg, NULL, NULL,
1631                        (LPBYTE)xdi->ppdi.Name.Buffer, &size)) == ERROR_SUCCESS)
1632                       {
1633                           xdi->ppdi.Name.Length = (USHORT)size;
1634                           useDefault = FALSE;
1635                       }
1636                       else
1637                       {
1638                           HeapFree(GetProcessHeap(), 0, xdi->ppdi.Name.Buffer);
1639                           xdi->ppdi.Name.Buffer = NULL;
1640                       }
1641                   }
1642                   RegCloseKey(key);
1643               }
1644               if (useDefault)
1645                   RtlCreateUnicodeStringFromAsciiz(&(xdi->ppdi.Name), "DOMAIN");
1646               TRACE("setting domain to %s\n", debugstr_w(xdi->ppdi.Name.Buffer));
1647
1648               xdi->ppdi.Sid = &(xdi->sid);
1649               xdi->sid.Revision = SID_REVISION;
1650               xdi->sid.SubAuthorityCount = 1;
1651               xdi->sid.IdentifierAuthority = localSidAuthority;
1652               xdi->sid.SubAuthority[0] = SECURITY_LOCAL_SYSTEM_RID;
1653               *Buffer = xdi;
1654             }
1655             break;
1656           case  PolicyAuditLogInformation:
1657           case  PolicyPdAccountInformation:
1658           case  PolicyLsaServerRoleInformation:
1659           case  PolicyReplicaSourceInformation:
1660           case  PolicyDefaultQuotaInformation:
1661           case  PolicyModificationInformation:
1662           case  PolicyAuditFullSetInformation:
1663           case  PolicyAuditFullQueryInformation:
1664           case  PolicyDnsDomainInformation:
1665             {
1666               FIXME("category not implemented\n");
1667               return FALSE;
1668             }
1669         }
1670         return TRUE;
1671 }
1672
1673 NTSTATUS WINAPI
1674 LsaSetInformationPolicy(
1675     LSA_HANDLE PolicyHandle,
1676     POLICY_INFORMATION_CLASS InformationClass,
1677     PVOID Buffer)
1678 {
1679     FIXME("(%p,0x%08x,%p):stub\n", PolicyHandle, InformationClass, Buffer);
1680
1681     return STATUS_UNSUCCESSFUL;    
1682 }
1683
1684 /******************************************************************************
1685  * LsaLookupSids [ADVAPI32.@]
1686  */
1687 NTSTATUS WINAPI
1688 LsaLookupSids(
1689         IN LSA_HANDLE PolicyHandle,
1690         IN ULONG Count,
1691         IN PSID *Sids,
1692         OUT PLSA_REFERENCED_DOMAIN_LIST *ReferencedDomains,
1693         OUT PLSA_TRANSLATED_NAME *Names )
1694 {
1695         FIXME("%p %lu %p %p %p\n",
1696           PolicyHandle, Count, Sids, ReferencedDomains, Names);
1697         return FALSE;
1698 }
1699
1700 /******************************************************************************
1701  * LsaFreeMemory [ADVAPI32.@]
1702  */
1703 NTSTATUS WINAPI
1704 LsaFreeMemory(IN PVOID Buffer)
1705 {
1706         TRACE("(%p)\n",Buffer);
1707         return HeapFree(GetProcessHeap(), 0, Buffer);
1708 }
1709 /******************************************************************************
1710  * LsaClose [ADVAPI32.@]
1711  */
1712 NTSTATUS WINAPI
1713 LsaClose(IN LSA_HANDLE ObjectHandle)
1714 {
1715         FIXME("(%p):stub\n",ObjectHandle);
1716         return 0xc0000000;
1717 }
1718
1719 /******************************************************************************
1720  * LsaStorePrivateData [ADVAPI32.@]
1721  */
1722 NTSTATUS WINAPI LsaStorePrivateData( LSA_HANDLE PolicyHandle,
1723     PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING PrivateData)
1724 {
1725     FIXME("%p %p %p\n", PolicyHandle, KeyName, PrivateData);
1726     return STATUS_OBJECT_NAME_NOT_FOUND;
1727 }
1728
1729 /******************************************************************************
1730  * LsaRetrievePrivateData [ADVAPI32.@]
1731  */
1732 NTSTATUS WINAPI LsaRetrievePrivateData( LSA_HANDLE PolicyHandle,
1733     PLSA_UNICODE_STRING KeyName, PLSA_UNICODE_STRING* PrivateData)
1734 {
1735     FIXME("%p %p %p\n", PolicyHandle, KeyName, PrivateData);
1736     return STATUS_OBJECT_NAME_NOT_FOUND;
1737 }
1738
1739 /******************************************************************************
1740  * LsaNtStatusToWinError [ADVAPI32.@]
1741  *
1742  * PARAMS
1743  *   Status [I]
1744  */
1745 ULONG WINAPI
1746 LsaNtStatusToWinError(NTSTATUS Status)
1747 {
1748     return RtlNtStatusToDosError(Status);
1749 }
1750
1751 /******************************************************************************
1752  * NotifyBootConfigStatus [ADVAPI32.@]
1753  *
1754  * PARAMS
1755  *   x1 []
1756  */
1757 BOOL WINAPI
1758 NotifyBootConfigStatus( DWORD x1 )
1759 {
1760         FIXME("(0x%08lx):stub\n",x1);
1761         return 1;
1762 }
1763
1764 /******************************************************************************
1765  * RevertToSelf [ADVAPI32.@]
1766  *
1767  * PARAMS
1768  *   void []
1769  */
1770 BOOL WINAPI
1771 RevertToSelf( void )
1772 {
1773         FIXME("(), stub\n");
1774         return TRUE;
1775 }
1776
1777 /******************************************************************************
1778  * ImpersonateSelf [ADVAPI32.@]
1779  */
1780 BOOL WINAPI
1781 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
1782 {
1783         return RtlImpersonateSelf(ImpersonationLevel);
1784 }
1785
1786 /******************************************************************************
1787  * ImpersonateLoggedOnUser [ADVAPI32.@]
1788  */
1789 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
1790 {
1791     FIXME("(%p):stub returning FALSE\n", hToken);
1792     return FALSE;
1793 }
1794
1795 /******************************************************************************
1796  * AccessCheck [ADVAPI32.@]
1797  */
1798 BOOL WINAPI
1799 AccessCheck(
1800         PSECURITY_DESCRIPTOR SecurityDescriptor,
1801         HANDLE ClientToken,
1802         DWORD DesiredAccess,
1803         PGENERIC_MAPPING GenericMapping,
1804         PPRIVILEGE_SET PrivilegeSet,
1805         LPDWORD PrivilegeSetLength,
1806         LPDWORD GrantedAccess,
1807         LPBOOL AccessStatus)
1808 {
1809     NTSTATUS access_status;
1810     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
1811                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
1812                                            GrantedAccess, &access_status) );
1813     if (ret) *AccessStatus = set_ntstatus( access_status );
1814     return ret;
1815 }
1816
1817
1818 /******************************************************************************
1819  * AccessCheckByType [ADVAPI32.@]
1820  */
1821 BOOL WINAPI AccessCheckByType(
1822     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
1823     PSID PrincipalSelfSid,
1824     HANDLE ClientToken, 
1825     DWORD DesiredAccess, 
1826     POBJECT_TYPE_LIST ObjectTypeList,
1827     DWORD ObjectTypeListLength,
1828     PGENERIC_MAPPING GenericMapping,
1829     PPRIVILEGE_SET PrivilegeSet,
1830     LPDWORD PrivilegeSetLength, 
1831     LPDWORD GrantedAccess,
1832     LPBOOL AccessStatus)
1833 {
1834         FIXME("stub\n");
1835
1836         *AccessStatus = TRUE;
1837
1838         return !*AccessStatus;
1839 }
1840
1841 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
1842 {
1843         FIXME("%p %p - stub\n", AccessMask, GenericMapping);
1844
1845     *AccessMask |= GenericMapping->GenericRead;
1846     *AccessMask |= GenericMapping->GenericWrite;
1847     *AccessMask |= GenericMapping->GenericExecute;
1848     *AccessMask |= GenericMapping->GenericAll;
1849 }
1850
1851 /*************************************************************************
1852  * SetKernelObjectSecurity [ADVAPI32.@]
1853  */
1854 BOOL WINAPI SetKernelObjectSecurity (
1855         IN HANDLE Handle,
1856         IN SECURITY_INFORMATION SecurityInformation,
1857         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
1858 {
1859     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
1860 }
1861
1862
1863 /******************************************************************************
1864  *  AddAuditAccessAce [ADVAPI32.@]
1865  */
1866 BOOL WINAPI AddAuditAccessAce(
1867         IN OUT PACL pAcl,
1868         IN DWORD dwAceRevision,
1869         IN DWORD dwAccessMask,
1870         IN PSID pSid,
1871         IN BOOL bAuditSuccess,
1872         IN BOOL bAuditFailure)
1873 {
1874         FIXME("Stub\n");
1875         return TRUE;
1876 }
1877
1878 /******************************************************************************
1879  * LookupAccountNameA [ADVAPI32.@]
1880  */
1881 BOOL WINAPI
1882 LookupAccountNameA(
1883         IN LPCSTR system,
1884         IN LPCSTR account,
1885         OUT PSID sid,
1886         OUT LPDWORD cbSid,
1887         LPSTR ReferencedDomainName,
1888         IN OUT LPDWORD cbReferencedDomainName,
1889         OUT PSID_NAME_USE name_use )
1890 {
1891     /* Default implementation: Always return a default SID */
1892     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1893     BOOL ret;
1894     PSID pSid;
1895     static const char dm[] = "DOMAIN";
1896
1897     FIXME("(%s,%s,%p,%p,%p,%p,%p), stub.\n",system,account,sid,cbSid,ReferencedDomainName,cbReferencedDomainName,name_use);
1898
1899     ret = AllocateAndInitializeSid(&identifierAuthority,
1900         2,
1901         SECURITY_BUILTIN_DOMAIN_RID,
1902         DOMAIN_ALIAS_RID_ADMINS,
1903         0, 0, 0, 0, 0, 0,
1904         &pSid);
1905
1906     if (!ret)
1907        return FALSE;
1908     if(!RtlValidSid(pSid))
1909     {
1910        FreeSid(pSid);
1911        return FALSE;
1912     }
1913
1914     if (sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1915        CopySid(*cbSid, sid, pSid);
1916     if (*cbSid < GetLengthSid(pSid))
1917     {
1918        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1919        ret = FALSE;
1920     }
1921     *cbSid = GetLengthSid(pSid);
1922     
1923     if (ReferencedDomainName != NULL && (*cbReferencedDomainName > strlen(dm)))
1924       strcpy(ReferencedDomainName, dm);
1925     if (*cbReferencedDomainName <= strlen(dm))
1926     {
1927        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1928        ret = FALSE;
1929     }
1930     *cbReferencedDomainName = strlen(dm)+1;
1931
1932     FreeSid(pSid);
1933
1934     return ret;
1935 }
1936
1937 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
1938                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
1939                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
1940 {
1941     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
1942           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1943
1944     return FALSE;
1945 }
1946
1947 /******************************************************************************
1948  * PrivilegeCheck [ADVAPI32.@]
1949  */
1950 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
1951 {
1952         FIXME("stub %p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
1953         if (pfResult)
1954                 *pfResult=TRUE;
1955         return TRUE;
1956 }
1957
1958 /******************************************************************************
1959  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1960  */
1961 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
1962   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1963   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1964   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1965 {
1966         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
1967                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
1968                 SecurityDescriptor, DesiredAccess, GenericMapping,
1969                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1970         return TRUE;
1971 }
1972
1973 /******************************************************************************
1974  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
1975  */
1976 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
1977   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1978   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1979   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1980 {
1981         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
1982                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
1983                 SecurityDescriptor, DesiredAccess, GenericMapping,
1984                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1985         return TRUE;
1986 }
1987
1988 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1989 {
1990     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
1991
1992     return TRUE;
1993 }
1994
1995 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1996 {
1997     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
1998
1999     return TRUE;
2000 }
2001
2002 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2003   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2004   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2005   LPBOOL GenerateOnClose)
2006 {
2007         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2008                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2009         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2010         GenerateOnClose);
2011
2012     return TRUE;
2013 }
2014
2015 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2016   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2017   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2018   LPBOOL GenerateOnClose)
2019 {
2020     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2021         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2022         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2023         GenerateOnClose);
2024
2025     return TRUE;
2026 }
2027
2028 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2029   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2030 {
2031     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2032           DesiredAccess, Privileges, AccessGranted);
2033
2034     return TRUE;
2035 }
2036
2037 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2038   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2039 {
2040     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2041           DesiredAccess, Privileges, AccessGranted);
2042
2043     return TRUE;
2044 }
2045
2046 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2047                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2048 {
2049     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2050           ClientToken, Privileges, AccessGranted);
2051
2052     return TRUE;
2053 }
2054
2055 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2056                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2057 {
2058     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2059           ClientToken, Privileges, AccessGranted);
2060
2061     return TRUE;
2062 }
2063
2064 /******************************************************************************
2065  * GetSecurityInfo [ADVAPI32.@]
2066  */
2067 DWORD WINAPI GetSecurityInfo(
2068     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2069     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2070     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2071     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2072 )
2073 {
2074   FIXME("stub!\n");
2075   return ERROR_BAD_PROVIDER;
2076 }
2077
2078 /******************************************************************************
2079  * GetSecurityInfoExW [ADVAPI32.@]
2080  */
2081 DWORD WINAPI GetSecurityInfoExW(
2082         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2083         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2084         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2085         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2086 )
2087 {
2088   FIXME("stub!\n");
2089   return ERROR_BAD_PROVIDER; 
2090 }
2091
2092 /******************************************************************************
2093  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2094  */
2095 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2096                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2097                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2098 {
2099     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_a(pTrusteeName),
2100           AccessPermissions, AccessMode, Inheritance);
2101
2102     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2103     pExplicitAccess->grfAccessMode = AccessMode;
2104     pExplicitAccess->grfInheritance = Inheritance;
2105
2106     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2107     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2108     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2109     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2110     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2111 }
2112
2113 /******************************************************************************
2114  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2115  */
2116 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2117                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2118                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2119 {
2120     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_w(pTrusteeName),
2121           AccessPermissions, AccessMode, Inheritance);
2122
2123     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2124     pExplicitAccess->grfAccessMode = AccessMode;
2125     pExplicitAccess->grfInheritance = Inheritance;
2126
2127     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2128     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2129     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2130     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2131     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2132 }
2133
2134 /******************************************************************************
2135  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2136  */
2137 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2138                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2139                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2140 {
2141     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2142           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2143
2144     pTrustee->pMultipleTrustee = NULL;
2145     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2146     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2147     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2148     pTrustee->ptstrName = Name;
2149 }
2150
2151 /******************************************************************************
2152  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2153  */
2154 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2155                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2156                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2157 {
2158     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2159           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2160
2161     pTrustee->pMultipleTrustee = NULL;
2162     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2163     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2164     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2165     pTrustee->ptstrName = Name;
2166 }
2167
2168 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2169                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2170 {
2171     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2172
2173     pTrustee->pMultipleTrustee = NULL;
2174     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2175     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2176     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2177     pTrustee->ptstrName = (LPSTR) pSid;
2178 }
2179
2180 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2181                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2182 {
2183     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2184
2185     pTrustee->pMultipleTrustee = NULL;
2186     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2187     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2188     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2189     pTrustee->ptstrName = (LPWSTR) pSid;
2190 }
2191
2192 /******************************************************************************
2193  * BuildTrusteeWithSidA [ADVAPI32.@]
2194  */
2195 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2196 {
2197     TRACE("%p %p\n", pTrustee, pSid);
2198
2199     pTrustee->pMultipleTrustee = NULL;
2200     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2201     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2202     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2203     pTrustee->ptstrName = (LPSTR) pSid;
2204 }
2205
2206 /******************************************************************************
2207  * BuildTrusteeWithSidW [ADVAPI32.@]
2208  */
2209 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2210 {
2211     TRACE("%p %p\n", pTrustee, pSid);
2212
2213     pTrustee->pMultipleTrustee = NULL;
2214     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2215     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2216     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2217     pTrustee->ptstrName = (LPWSTR) pSid;
2218 }
2219
2220 /******************************************************************************
2221  * BuildTrusteeWithNameA [ADVAPI32.@]
2222  */
2223 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2224 {
2225     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2226
2227     pTrustee->pMultipleTrustee = NULL;
2228     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2229     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2230     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2231     pTrustee->ptstrName = name;
2232 }
2233
2234 /******************************************************************************
2235  * BuildTrusteeWithNameW [ADVAPI32.@]
2236  */
2237 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2238 {
2239     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2240
2241     pTrustee->pMultipleTrustee = NULL;
2242     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2243     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2244     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2245     pTrustee->ptstrName = name;
2246 }
2247
2248 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2249                                DWORD nAclInformationLength,
2250                                ACL_INFORMATION_CLASS dwAclInformationClass )
2251 {
2252     FIXME("%p %p 0x%08lx 0x%08x - stub\n", pAcl, pAclInformation,
2253           nAclInformationLength, dwAclInformationClass);
2254
2255     return TRUE;
2256 }
2257
2258 /******************************************************************************
2259  * SetEntriesInAclA [ADVAPI32.@]
2260  */
2261 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2262                                PACL OldAcl, PACL* NewAcl )
2263 {
2264     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2265     return ERROR_CALL_NOT_IMPLEMENTED;
2266 }
2267
2268 /******************************************************************************
2269  * SetEntriesInAclW [ADVAPI32.@]
2270  */
2271 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2272                                PACL OldAcl, PACL* NewAcl )
2273 {
2274     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2275     return ERROR_CALL_NOT_IMPLEMENTED;
2276 }
2277
2278 /******************************************************************************
2279  * SetNamedSecurityInfoA [ADVAPI32.@]
2280  */
2281 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2282         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2283         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2284 {
2285     DWORD len;
2286     LPWSTR wstr = NULL;
2287     DWORD r;
2288
2289     TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2290            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2291
2292     if( pObjectName )
2293     {
2294         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2295         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2296         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2297     }
2298
2299     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2300                            psidGroup, pDacl, pSacl );
2301
2302     HeapFree( GetProcessHeap(), 0, wstr );
2303
2304     return r;
2305 }
2306
2307 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2308     PSECURITY_DESCRIPTOR ModificationDescriptor,
2309     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2310     PGENERIC_MAPPING GenericMapping,
2311     HANDLE Token )
2312 {
2313     FIXME("0x%08lx %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2314           ObjectsSecurityDescriptor, GenericMapping, Token);
2315
2316     return TRUE;
2317 }
2318
2319 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2320   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2321   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2322 {
2323     FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2324           ControlBitsToSet);
2325
2326     return TRUE;
2327 }
2328
2329 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2330 {
2331     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2332 }
2333
2334 /******************************************************************************
2335  * AreAnyAccessesGranted [ADVAPI32.@]
2336  *
2337  * Determines whether or not any of a set of specified access permissions have
2338  * been granted or not.
2339  *
2340  * PARAMS
2341  *   GrantedAccess [I] The permissions that have been granted.
2342  *   DesiredAccess [I] The permissions that you want to have.
2343  *
2344  * RETURNS
2345  *   Nonzero if any of the permissions have been granted, zero if none of the
2346  *   permissions have been granted.
2347  */
2348
2349 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2350 {
2351     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
2352 }
2353
2354 /******************************************************************************
2355  * SetNamedSecurityInfoW [ADVAPI32.@]
2356  */
2357 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
2358         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2359         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2360 {
2361     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
2362            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2363     return ERROR_CALL_NOT_IMPLEMENTED;
2364 }
2365
2366 /******************************************************************************
2367  * GetExplicitEntriesFromAclA [ADVAPI32.@]
2368  */
2369 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
2370         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
2371 {
2372     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2373     return ERROR_CALL_NOT_IMPLEMENTED;
2374 }
2375
2376 /******************************************************************************
2377  * GetExplicitEntriesFromAclW [ADVAPI32.@]
2378  */
2379 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
2380         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
2381 {
2382     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2383     return ERROR_CALL_NOT_IMPLEMENTED;
2384 }
2385
2386
2387 /******************************************************************************
2388  * ParseAclStringFlags
2389  */
2390 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2391 {
2392     DWORD flags = 0;
2393     LPCWSTR szAcl = *StringAcl;
2394
2395     while (*szAcl != '(')
2396     {
2397         if (*szAcl == 'P')
2398         {
2399             flags |= SE_DACL_PROTECTED;
2400         }
2401         else if (*szAcl == 'A')
2402         {
2403             szAcl++;
2404             if (*szAcl == 'R')
2405                 flags |= SE_DACL_AUTO_INHERIT_REQ;
2406             else if (*szAcl == 'I')
2407                 flags |= SE_DACL_AUTO_INHERITED;
2408         }
2409         szAcl++;
2410     }
2411
2412     *StringAcl = szAcl;
2413     return flags;
2414 }
2415
2416 /******************************************************************************
2417  * ParseAceStringType
2418  */
2419 ACEFLAG AceType[] =
2420 {
2421     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2422     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
2423     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
2424     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
2425     /*
2426     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2427     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
2428     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
2429     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2430     */
2431     { NULL, 0 },
2432 };
2433
2434 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2435 {
2436     UINT len = 0;
2437     LPCWSTR szAcl = *StringAcl;
2438     LPACEFLAG lpaf = AceType;
2439
2440     while (lpaf->wstr &&
2441         (len = strlenW(lpaf->wstr)) &&
2442         strncmpW(lpaf->wstr, szAcl, len))
2443         lpaf++;
2444
2445     if (!lpaf->wstr)
2446         return 0;
2447
2448     *StringAcl += len;
2449     return lpaf->value;
2450 }
2451
2452
2453 /******************************************************************************
2454  * ParseAceStringFlags
2455  */
2456 ACEFLAG AceFlags[] =
2457 {
2458     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2459     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
2460     { SDDL_INHERITED,         INHERITED_ACE },
2461     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
2462     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
2463     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
2464     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
2465     { NULL, 0 },
2466 };
2467
2468 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2469 {
2470     UINT len = 0;
2471     BYTE flags = 0;
2472     LPCWSTR szAcl = *StringAcl;
2473
2474     while (*szAcl != ';')
2475     {
2476         LPACEFLAG lpaf = AceFlags;
2477
2478         while (lpaf->wstr &&
2479                (len = strlenW(lpaf->wstr)) &&
2480                strncmpW(lpaf->wstr, szAcl, len))
2481             lpaf++;
2482
2483         if (!lpaf->wstr)
2484             return 0;
2485
2486         flags |= lpaf->value;
2487         szAcl += len;
2488     }
2489
2490     *StringAcl = szAcl;
2491     return flags;
2492 }
2493
2494
2495 /******************************************************************************
2496  * ParseAceStringRights
2497  */
2498 ACEFLAG AceRights[] =
2499 {
2500     { SDDL_GENERIC_ALL,     GENERIC_ALL },
2501     { SDDL_GENERIC_READ,    GENERIC_READ },
2502     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
2503     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2504     { SDDL_READ_CONTROL,    READ_CONTROL },
2505     { SDDL_STANDARD_DELETE, DELETE },
2506     { SDDL_WRITE_DAC,       WRITE_DAC },
2507     { SDDL_WRITE_OWNER,     WRITE_OWNER },
2508     { NULL, 0 },
2509 };
2510
2511 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2512 {
2513     UINT len = 0;
2514     DWORD rights = 0;
2515     LPCWSTR szAcl = *StringAcl;
2516
2517     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2518     {
2519         LPCWSTR p = szAcl;
2520
2521         while (*p && *p != ';')
2522             p++;
2523
2524         if (p - szAcl <= 8)
2525         {
2526             rights = strtoulW(szAcl, NULL, 16);
2527             *StringAcl = p;
2528         }
2529         else
2530             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2531     }
2532     else
2533     {
2534         while (*szAcl != ';')
2535         {
2536             LPACEFLAG lpaf = AceRights;
2537
2538             while (lpaf->wstr &&
2539                (len = strlenW(lpaf->wstr)) &&
2540                strncmpW(lpaf->wstr, szAcl, len))
2541             {
2542                lpaf++;
2543             }
2544
2545             if (!lpaf->wstr)
2546                 return 0;
2547
2548             rights |= lpaf->value;
2549             szAcl += len;
2550         }
2551     }
2552
2553     *StringAcl = szAcl;
2554     return rights;
2555 }
2556
2557
2558 /******************************************************************************
2559  * ParseStringAclToAcl
2560  * 
2561  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
2562  */
2563 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
2564     PACL pAcl, LPDWORD cBytes)
2565 {
2566     DWORD val;
2567     DWORD sidlen;
2568     DWORD length = sizeof(ACL);
2569     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
2570
2571     TRACE("%s\n", debugstr_w(StringAcl));
2572
2573     if (!StringAcl)
2574         return FALSE;
2575
2576     if (pAcl) /* pAce is only useful if we're setting values */
2577         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
2578
2579     /* Parse ACL flags */
2580     *lpdwFlags = ParseAclStringFlags(&StringAcl);
2581
2582     /* Parse ACE */
2583     while (*StringAcl == '(')
2584     {
2585         StringAcl++;
2586
2587         /* Parse ACE type */
2588         val = ParseAceStringType(&StringAcl);
2589         if (pAce)
2590             pAce->Header.AceType = (BYTE) val;
2591         if (*StringAcl != ';')
2592             goto lerr;
2593         StringAcl++;
2594
2595         /* Parse ACE flags */
2596         val = ParseAceStringFlags(&StringAcl);
2597         if (pAce)
2598             pAce->Header.AceFlags = (BYTE) val;
2599         if (*StringAcl != ';')
2600             goto lerr;
2601         StringAcl++;
2602
2603         /* Parse ACE rights */
2604         val = ParseAceStringRights(&StringAcl);
2605         if (pAce)
2606             pAce->Mask = val;
2607         if (*StringAcl != ';')
2608             goto lerr;
2609         StringAcl++;
2610
2611         /* Parse ACE object guid */
2612         if (*StringAcl != ';')
2613         {
2614             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2615             goto lerr;
2616         }
2617         StringAcl++;
2618
2619         /* Parse ACE inherit object guid */
2620         if (*StringAcl != ';')
2621         {
2622             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2623             goto lerr;
2624         }
2625         StringAcl++;
2626
2627         /* Parse ACE account sid */
2628         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
2629         {
2630             while (*StringAcl && *StringAcl != ')')
2631                 StringAcl++;
2632         }
2633
2634         if (*StringAcl != ')')
2635             goto lerr;
2636         StringAcl++;
2637
2638         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
2639     }
2640
2641     *cBytes = length;
2642     return TRUE;
2643
2644 lerr:
2645     WARN("Invalid ACE string format\n");
2646     return FALSE;
2647 }
2648
2649
2650 /******************************************************************************
2651  * ParseStringSecurityDescriptorToSecurityDescriptor
2652  */
2653 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
2654     LPCWSTR StringSecurityDescriptor,
2655     SECURITY_DESCRIPTOR* SecurityDescriptor,
2656     LPDWORD cBytes)
2657 {
2658     BOOL bret = FALSE;
2659     WCHAR toktype;
2660     WCHAR tok[MAX_PATH];
2661     LPCWSTR lptoken;
2662     LPBYTE lpNext = NULL;
2663
2664     *cBytes = 0;
2665
2666     if (SecurityDescriptor)
2667         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
2668
2669     while (*StringSecurityDescriptor)
2670     {
2671         toktype = *StringSecurityDescriptor;
2672
2673         /* Expect char identifier followed by ':' */
2674         StringSecurityDescriptor++;
2675         if (*StringSecurityDescriptor != ':')
2676         {
2677             SetLastError(ERROR_INVALID_PARAMETER);
2678             goto lend;
2679         }
2680         StringSecurityDescriptor++;
2681
2682         /* Extract token */
2683         lptoken = StringSecurityDescriptor;
2684         while (*lptoken && *lptoken != ':')
2685             lptoken++;
2686
2687         if (*lptoken)
2688             lptoken--;
2689
2690         strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor);
2691
2692         switch (toktype)
2693         {
2694             case 'O':
2695             {
2696                 DWORD bytes;
2697
2698                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2699                     goto lend;
2700
2701                 if (SecurityDescriptor)
2702                 {
2703                     SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
2704                         (DWORD) SecurityDescriptor);
2705                     lpNext += bytes; /* Advance to next token */
2706                 }
2707
2708                 *cBytes += bytes;
2709
2710                 break;
2711             }
2712
2713             case 'G':
2714             {
2715                 DWORD bytes;
2716
2717                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2718                     goto lend;
2719
2720                 if (SecurityDescriptor)
2721                 {
2722                     SecurityDescriptor->Group = (PSID) ((DWORD) lpNext - 
2723                         (DWORD) SecurityDescriptor);
2724                     lpNext += bytes; /* Advance to next token */
2725                 }
2726
2727                 *cBytes += bytes;
2728
2729                 break;
2730             }
2731
2732             case 'D':
2733             {
2734                 DWORD flags;
2735                 DWORD bytes;
2736
2737                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2738                     goto lend;
2739
2740                 if (SecurityDescriptor)
2741                 {
2742                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
2743                     SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
2744                         (DWORD) SecurityDescriptor);
2745                     lpNext += bytes; /* Advance to next token */
2746                 }
2747
2748                 *cBytes += bytes;
2749
2750                 break;
2751             }
2752
2753             case 'S':
2754             {
2755                 DWORD flags;
2756                 DWORD bytes;
2757
2758                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2759                     goto lend;
2760
2761                 if (SecurityDescriptor)
2762                 {
2763                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
2764                     SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
2765                         (DWORD) SecurityDescriptor);
2766                     lpNext += bytes; /* Advance to next token */
2767                 }
2768
2769                 *cBytes += bytes;
2770
2771                 break;
2772             }
2773
2774             default:
2775                 FIXME("Unknown token\n");
2776                 SetLastError(ERROR_INVALID_PARAMETER);
2777                 goto lend;
2778         }
2779
2780         StringSecurityDescriptor = lptoken;
2781     }
2782
2783     bret = TRUE;
2784
2785 lend:
2786     return bret;
2787 }
2788
2789 /******************************************************************************
2790  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2791  */
2792 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
2793         LPCSTR StringSecurityDescriptor,
2794         DWORD StringSDRevision,
2795         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2796         PULONG SecurityDescriptorSize)
2797 {
2798     UINT len;
2799     BOOL ret = FALSE;
2800     LPWSTR StringSecurityDescriptorW;
2801
2802     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
2803     StringSecurityDescriptorW = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2804
2805     if (StringSecurityDescriptorW)
2806     {
2807         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
2808
2809         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
2810                                                                    StringSDRevision, SecurityDescriptor,
2811                                                                    SecurityDescriptorSize);
2812         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
2813     }
2814
2815     return ret;
2816 }
2817
2818 /******************************************************************************
2819  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2820  */
2821 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2822         LPCWSTR StringSecurityDescriptor,
2823         DWORD StringSDRevision,
2824         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2825         PULONG SecurityDescriptorSize)
2826 {
2827     DWORD cBytes;
2828     SECURITY_DESCRIPTOR* psd;
2829     BOOL bret = FALSE;
2830
2831     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2832
2833     if (GetVersion() & 0x80000000)
2834     {
2835         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2836         goto lend;
2837     }
2838     else if (StringSDRevision != SID_REVISION)
2839     {
2840         SetLastError(ERROR_UNKNOWN_REVISION);
2841         goto lend;
2842     }
2843
2844     /* Compute security descriptor length */
2845     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2846         NULL, &cBytes))
2847         goto lend;
2848
2849     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
2850         GMEM_ZEROINIT, cBytes);
2851
2852     psd->Revision = SID_REVISION;
2853     psd->Control |= SE_SELF_RELATIVE;
2854
2855     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2856         psd, &cBytes))
2857     {
2858         LocalFree(psd);
2859         goto lend;
2860     }
2861
2862     if (SecurityDescriptorSize)
2863         *SecurityDescriptorSize = cBytes;
2864
2865     bret = TRUE;
2866  
2867 lend:
2868     TRACE(" ret=%d\n", bret);
2869     return bret;
2870 }
2871
2872 /******************************************************************************
2873  * ConvertStringSidToSidW [ADVAPI32.@]
2874  */
2875 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
2876 {
2877     BOOL bret = FALSE;
2878     DWORD cBytes;
2879
2880     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
2881     if (GetVersion() & 0x80000000)
2882         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2883     else if (!StringSid || !Sid)
2884         SetLastError(ERROR_INVALID_PARAMETER);
2885     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
2886     {
2887         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
2888
2889         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
2890         if (!bret)
2891             LocalFree(*Sid); 
2892     }
2893     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
2894     return bret;
2895 }
2896
2897 /******************************************************************************
2898  * ConvertStringSidToSidA [ADVAPI32.@]
2899  */
2900 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
2901 {
2902     BOOL bret = FALSE;
2903
2904     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
2905     if (GetVersion() & 0x80000000)
2906         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2907     else if (!StringSid || !Sid)
2908         SetLastError(ERROR_INVALID_PARAMETER);
2909     else
2910     {
2911         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
2912         LPWSTR wStringSid = (LPWSTR)HeapAlloc(GetProcessHeap(), 0,
2913          len * sizeof(WCHAR));
2914
2915         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
2916         bret = ConvertStringSidToSidW(wStringSid, Sid);
2917         HeapFree(GetProcessHeap(), 0, wStringSid);
2918     }
2919     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
2920     return bret;
2921 }
2922
2923 /******************************************************************************
2924  * ConvertSidToStringSidW [ADVAPI32.@]
2925  *
2926  *  format of SID string is:
2927  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
2928  *  where
2929  *    <rev> is the revision of the SID encoded as decimal
2930  *    <auth> is the identifier authority encoded as hex
2931  *    <subauthN> is the subauthority id encoded as decimal
2932  */
2933 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
2934 {
2935     DWORD sz, i;
2936     LPWSTR str;
2937     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
2938     WCHAR subauthfmt[] = { '-','%','u',0 };
2939     SID* pisid=pSid;
2940
2941     TRACE("%p %p\n", pSid, pstr );
2942
2943     if( !IsValidSid( pSid ) )
2944         return FALSE;
2945
2946     if (pisid->Revision != SDDL_REVISION)
2947         return FALSE;
2948     if (pisid->IdentifierAuthority.Value[0] ||
2949      pisid->IdentifierAuthority.Value[1])
2950     {
2951         FIXME("not matching MS' bugs\n");
2952         return FALSE;
2953     }
2954
2955     sz = 14 + pisid->SubAuthorityCount * 11;
2956     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
2957     sprintfW( str, fmt, pisid->Revision, MAKELONG(
2958      MAKEWORD( pisid->IdentifierAuthority.Value[5],
2959      pisid->IdentifierAuthority.Value[4] ),
2960      MAKEWORD( pisid->IdentifierAuthority.Value[3],
2961      pisid->IdentifierAuthority.Value[2] ) ) );
2962     for( i=0; i<pisid->SubAuthorityCount; i++ )
2963         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
2964     *pstr = str;
2965
2966     return TRUE;
2967 }
2968
2969 /******************************************************************************
2970  * ConvertSidToStringSidA [ADVAPI32.@]
2971  */
2972 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
2973 {
2974     LPWSTR wstr = NULL;
2975     LPSTR str;
2976     UINT len;
2977
2978     TRACE("%p %p\n", pSid, pstr );
2979
2980     if( !ConvertSidToStringSidW( pSid, &wstr ) )
2981         return FALSE;
2982
2983     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
2984     str = LocalAlloc( 0, len );
2985     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
2986     LocalFree( wstr );
2987
2988     *pstr = str;
2989
2990     return TRUE;
2991 }
2992
2993 BOOL WINAPI CreatePrivateObjectSecurity(
2994         PSECURITY_DESCRIPTOR ParentDescriptor,
2995         PSECURITY_DESCRIPTOR CreatorDescriptor,
2996         PSECURITY_DESCRIPTOR* NewDescriptor,
2997         BOOL IsDirectoryObject,
2998         HANDLE Token,
2999         PGENERIC_MAPPING GenericMapping )
3000 {
3001     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
3002           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
3003
3004     return FALSE;
3005 }
3006
3007 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
3008 {
3009     FIXME("%p - stub\n", ObjectDescriptor);
3010
3011     return TRUE;
3012 }
3013
3014 BOOL WINAPI CreateProcessAsUserA(
3015         HANDLE hToken,
3016         LPCSTR lpApplicationName,
3017         LPSTR lpCommandLine,
3018         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3019         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3020         BOOL bInheritHandles,
3021         DWORD dwCreationFlags,
3022         LPVOID lpEnvironment,
3023         LPCSTR lpCurrentDirectory,
3024         LPSTARTUPINFOA lpStartupInfo,
3025         LPPROCESS_INFORMATION lpProcessInformation )
3026 {
3027     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
3028           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3029           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3030
3031     return FALSE;
3032 }
3033
3034 BOOL WINAPI CreateProcessAsUserW(
3035         HANDLE hToken,
3036         LPCWSTR lpApplicationName,
3037         LPWSTR lpCommandLine,
3038         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3039         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3040         BOOL bInheritHandles,
3041         DWORD dwCreationFlags,
3042         LPVOID lpEnvironment,
3043         LPCWSTR lpCurrentDirectory,
3044         LPSTARTUPINFOW lpStartupInfo,
3045         LPPROCESS_INFORMATION lpProcessInformation )
3046 {
3047     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - stub\n", hToken, debugstr_w(lpApplicationName),
3048           debugstr_w(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3049           dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3050
3051     return FALSE;
3052 }
3053
3054 /******************************************************************************
3055  * ComputeStringSidSize
3056  */
3057 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3058 {
3059     int ctok = 0;
3060     DWORD size = sizeof(SID);
3061
3062     while (*StringSid)
3063     {
3064         if (*StringSid == '-')
3065             ctok++;
3066         StringSid++;
3067     }
3068
3069     if (ctok > 3)
3070         size += (ctok - 3) * sizeof(DWORD);
3071
3072     return size;
3073 }
3074
3075 BOOL WINAPI DuplicateTokenEx(
3076         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
3077         LPSECURITY_ATTRIBUTES lpTokenAttributes,
3078         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3079         TOKEN_TYPE TokenType,
3080         PHANDLE DuplicateTokenHandle )
3081 {
3082     OBJECT_ATTRIBUTES ObjectAttributes;
3083
3084     TRACE("%p 0x%08lx 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3085           ImpersonationLevel, TokenType, DuplicateTokenHandle);
3086
3087     InitializeObjectAttributes(
3088         &ObjectAttributes,
3089         NULL,
3090         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
3091         NULL,
3092         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
3093
3094     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
3095                                            dwDesiredAccess,
3096                                            &ObjectAttributes,
3097                                            ImpersonationLevel,
3098                                            TokenType,
3099                                            DuplicateTokenHandle ) );
3100 }
3101
3102 BOOL WINAPI DuplicateToken(
3103         HANDLE ExistingTokenHandle,
3104         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3105         PHANDLE DuplicateTokenHandle )
3106 {
3107     return DuplicateTokenEx( ExistingTokenHandle, 0, NULL, ImpersonationLevel,
3108                              TokenImpersonation, DuplicateTokenHandle );
3109 }
3110
3111 BOOL WINAPI EnumDependentServicesA(
3112         SC_HANDLE hService,
3113         DWORD dwServiceState,
3114         LPENUM_SERVICE_STATUSA lpServices,
3115         DWORD cbBufSize,
3116         LPDWORD pcbBytesNeeded,
3117         LPDWORD lpServicesReturned )
3118 {
3119     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3120           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3121
3122     return FALSE;
3123 }
3124
3125 BOOL WINAPI EnumDependentServicesW(
3126         SC_HANDLE hService,
3127         DWORD dwServiceState,
3128         LPENUM_SERVICE_STATUSW lpServices,
3129         DWORD cbBufSize,
3130         LPDWORD pcbBytesNeeded,
3131         LPDWORD lpServicesReturned )
3132 {
3133     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3134           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3135
3136     return FALSE;
3137 }
3138
3139 /******************************************************************************
3140  * ParseStringSidToSid
3141  */
3142 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3143 {
3144     BOOL bret = FALSE;
3145     SID* pisid=pSid;
3146
3147     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3148     if (!StringSid)
3149     {
3150         SetLastError(ERROR_INVALID_PARAMETER);
3151         TRACE("StringSid is NULL, returning FALSE\n");
3152         return FALSE;
3153     }
3154
3155     *cBytes = ComputeStringSidSize(StringSid);
3156     if (!pisid) /* Simply compute the size */
3157     {
3158         TRACE("only size requested, returning TRUE\n");
3159         return TRUE;
3160     }
3161
3162     if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
3163     {
3164         DWORD i = 0, identAuth;
3165         DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
3166
3167         StringSid += 2; /* Advance to Revision */
3168         pisid->Revision = atoiW(StringSid);
3169
3170         if (pisid->Revision != SDDL_REVISION)
3171         {
3172             TRACE("Revision %d is unknown\n", pisid->Revision);
3173             goto lend; /* ERROR_INVALID_SID */
3174         }
3175         if (csubauth == 0)
3176         {
3177             TRACE("SubAuthorityCount is 0\n");
3178             goto lend; /* ERROR_INVALID_SID */
3179         }
3180
3181         pisid->SubAuthorityCount = csubauth;
3182
3183         /* Advance to identifier authority */
3184         while (*StringSid && *StringSid != '-')
3185             StringSid++;
3186         if (*StringSid == '-')
3187             StringSid++;
3188
3189         /* MS' implementation can't handle values greater than 2^32 - 1, so
3190          * we don't either; assume most significant bytes are always 0
3191          */
3192         pisid->IdentifierAuthority.Value[0] = 0;
3193         pisid->IdentifierAuthority.Value[1] = 0;
3194         identAuth = atoiW(StringSid);
3195         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3196         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3197         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3198         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3199
3200         /* Advance to first sub authority */
3201         while (*StringSid && *StringSid != '-')
3202             StringSid++;
3203         if (*StringSid == '-')
3204             StringSid++;
3205
3206         while (*StringSid)
3207         {       
3208             while (*StringSid && *StringSid != '-')
3209                 StringSid++;
3210
3211             pisid->SubAuthority[i++] = atoiW(StringSid);
3212         }
3213
3214         if (i != pisid->SubAuthorityCount)
3215             goto lend; /* ERROR_INVALID_SID */
3216
3217         bret = TRUE;
3218     }
3219     else /* String constant format  - Only available in winxp and above */
3220     {
3221         pisid->Revision = SDDL_REVISION;
3222         pisid->SubAuthorityCount = 1;
3223
3224         FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3225
3226         /* TODO: Lookup string of well-known SIDs in table */
3227         pisid->IdentifierAuthority.Value[5] = 0;
3228         pisid->SubAuthority[0] = 0;
3229
3230         bret = TRUE;
3231     }
3232
3233 lend:
3234     if (!bret)
3235         SetLastError(ERROR_INVALID_SID);
3236
3237     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3238     return bret;
3239 }
3240
3241 /******************************************************************************
3242  * GetNamedSecurityInfoA [ADVAPI32.@]
3243  */
3244 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
3245         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3246         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3247         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3248 {
3249     DWORD len;
3250     LPWSTR wstr = NULL;
3251     DWORD r;
3252
3253     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3254         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3255
3256     if( pObjectName )
3257     {
3258         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3259         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3260         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3261     }
3262
3263     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3264                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3265
3266     HeapFree( GetProcessHeap(), 0, wstr );
3267
3268     return r;
3269 }
3270
3271 /******************************************************************************
3272  * GetNamedSecurityInfoW [ADVAPI32.@]
3273  */
3274 DWORD WINAPI GetNamedSecurityInfoW(LPWSTR pObjectName,
3275         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3276         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3277         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3278 {
3279     FIXME("%s %d %ld %p %p %p %p %p\n", debugstr_w(pObjectName), ObjectType, SecurityInfo,
3280         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3281     return ERROR_CALL_NOT_IMPLEMENTED;
3282 }
3283
3284 /******************************************************************************
3285  * DecryptFileW [ADVAPI32.@]
3286  */
3287 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
3288 {
3289     FIXME("%s %08lx\n", debugstr_w(lpFileName), dwReserved);
3290     return TRUE;
3291 }
3292
3293 /******************************************************************************
3294  * DecryptFileA [ADVAPI32.@]
3295  */
3296 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
3297 {
3298     FIXME("%s %08lx\n", debugstr_a(lpFileName), dwReserved);
3299     return TRUE;
3300 }
3301
3302 /******************************************************************************
3303  * EncryptFileW [ADVAPI32.@]
3304  */
3305 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
3306 {
3307     FIXME("%s\n", debugstr_w(lpFileName));
3308     return TRUE;
3309 }
3310
3311 /******************************************************************************
3312  * EncryptFileA [ADVAPI32.@]
3313  */
3314 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
3315 {
3316     FIXME("%s\n", debugstr_a(lpFileName));
3317     return TRUE;
3318 }
3319
3320 /******************************************************************************
3321  * SetSecurityInfo [ADVAPI32.@]
3322  */
3323 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
3324                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
3325                       PSID psidGroup, PACL pDacl, PACL pSacl) {
3326     FIXME("stub\n");
3327     return ERROR_SUCCESS;
3328 }