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