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