dbghelp: Base and symbols.
[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     NTSTATUS Status;
1671     HANDLE ImpersonationToken;
1672     TOKEN_TYPE Type = TokenImpersonation;
1673
1674     FIXME( "(%p)\n", hToken );
1675
1676     /* FIXME: get token type */
1677
1678     if (Type == TokenPrimary)
1679     {
1680         OBJECT_ATTRIBUTES ObjectAttributes;
1681
1682         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
1683
1684         Status = NtDuplicateToken( hToken,
1685                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
1686                                    &ObjectAttributes,
1687                                    SecurityImpersonation,
1688                                    TokenImpersonation,
1689                                    &ImpersonationToken );
1690         if (Status != STATUS_SUCCESS)
1691         {
1692             ERR( "NtDuplicateToken failed with error 0x%08lx\n", Status );
1693             SetLastError( RtlNtStatusToDosError( Status ) );
1694             return FALSE;
1695         }
1696     }
1697     else
1698         ImpersonationToken = hToken;
1699
1700     Status = NtSetInformationThread( GetCurrentThread(),
1701                                      ThreadImpersonationToken,
1702                                      &ImpersonationToken,
1703                                      sizeof(ImpersonationToken) );
1704
1705     if (Type == TokenPrimary)
1706         NtClose( ImpersonationToken );
1707
1708     if (Status != STATUS_SUCCESS)
1709     {
1710         ERR( "NtSetInformationThread failed with error 0x%08lx\n", Status );
1711         SetLastError( RtlNtStatusToDosError( Status ) );
1712         return FALSE;
1713     }
1714
1715     return TRUE;
1716 }
1717
1718 /******************************************************************************
1719  * AccessCheck [ADVAPI32.@]
1720  */
1721 BOOL WINAPI
1722 AccessCheck(
1723         PSECURITY_DESCRIPTOR SecurityDescriptor,
1724         HANDLE ClientToken,
1725         DWORD DesiredAccess,
1726         PGENERIC_MAPPING GenericMapping,
1727         PPRIVILEGE_SET PrivilegeSet,
1728         LPDWORD PrivilegeSetLength,
1729         LPDWORD GrantedAccess,
1730         LPBOOL AccessStatus)
1731 {
1732     NTSTATUS access_status;
1733     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
1734                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
1735                                            GrantedAccess, &access_status) );
1736     if (ret) *AccessStatus = set_ntstatus( access_status );
1737     return ret;
1738 }
1739
1740
1741 /******************************************************************************
1742  * AccessCheckByType [ADVAPI32.@]
1743  */
1744 BOOL WINAPI AccessCheckByType(
1745     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
1746     PSID PrincipalSelfSid,
1747     HANDLE ClientToken, 
1748     DWORD DesiredAccess, 
1749     POBJECT_TYPE_LIST ObjectTypeList,
1750     DWORD ObjectTypeListLength,
1751     PGENERIC_MAPPING GenericMapping,
1752     PPRIVILEGE_SET PrivilegeSet,
1753     LPDWORD PrivilegeSetLength, 
1754     LPDWORD GrantedAccess,
1755     LPBOOL AccessStatus)
1756 {
1757         FIXME("stub\n");
1758
1759         *AccessStatus = TRUE;
1760
1761         return !*AccessStatus;
1762 }
1763
1764 /******************************************************************************
1765  * MapGenericMask [ADVAPI32.@]
1766  *
1767  * Maps generic access rights into specific access rights according to the
1768  * supplied mapping.
1769  *
1770  * PARAMS
1771  *  AccessMask     [I/O] Access rights.
1772  *  GenericMapping [I] The mapping between generic and specific rights.
1773  *
1774  * RETURNS
1775  *  Nothing.
1776  */
1777 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
1778 {
1779     RtlMapGenericMask( AccessMask, GenericMapping );
1780 }
1781
1782 /*************************************************************************
1783  * SetKernelObjectSecurity [ADVAPI32.@]
1784  */
1785 BOOL WINAPI SetKernelObjectSecurity (
1786         IN HANDLE Handle,
1787         IN SECURITY_INFORMATION SecurityInformation,
1788         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
1789 {
1790     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
1791 }
1792
1793
1794 /******************************************************************************
1795  *  AddAuditAccessAce [ADVAPI32.@]
1796  */
1797 BOOL WINAPI AddAuditAccessAce(
1798     IN OUT PACL pAcl, 
1799     IN DWORD dwAceRevision, 
1800     IN DWORD dwAccessMask, 
1801     IN PSID pSid, 
1802     IN BOOL bAuditSuccess, 
1803     IN BOOL bAuditFailure) 
1804 {
1805     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
1806                                               bAuditSuccess, bAuditFailure) ); 
1807 }
1808
1809 /******************************************************************************
1810  * LookupAccountNameA [ADVAPI32.@]
1811  */
1812 BOOL WINAPI
1813 LookupAccountNameA(
1814         IN LPCSTR system,
1815         IN LPCSTR account,
1816         OUT PSID sid,
1817         OUT LPDWORD cbSid,
1818         LPSTR ReferencedDomainName,
1819         IN OUT LPDWORD cbReferencedDomainName,
1820         OUT PSID_NAME_USE name_use )
1821 {
1822     BOOL ret;
1823     UNICODE_STRING lpSystemW;
1824     UNICODE_STRING lpAccountW;
1825     LPWSTR lpReferencedDomainNameW = NULL;
1826
1827     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
1828     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
1829
1830     if (ReferencedDomainName)
1831         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
1832
1833     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
1834         cbReferencedDomainName, name_use);
1835
1836     if (ret && lpReferencedDomainNameW)
1837     {
1838         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
1839             ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
1840     }
1841
1842     RtlFreeUnicodeString(&lpSystemW);
1843     RtlFreeUnicodeString(&lpAccountW);
1844
1845     if (lpReferencedDomainNameW)
1846         HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
1847
1848     return ret;
1849 }
1850
1851 /******************************************************************************
1852  * LookupAccountNameW [ADVAPI32.@]
1853  */
1854 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
1855                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
1856                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
1857 {
1858     /* Default implementation: Always return a default SID */
1859     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
1860     BOOL ret;
1861     PSID pSid;
1862     static const WCHAR dm[] = {'D','O','M','A','I','N'};
1863
1864     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
1865           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
1866
1867     ret = AllocateAndInitializeSid(&identifierAuthority,
1868         2,
1869         SECURITY_BUILTIN_DOMAIN_RID,
1870         DOMAIN_ALIAS_RID_ADMINS,
1871         0, 0, 0, 0, 0, 0,
1872         &pSid);
1873
1874     if (!ret)
1875        return FALSE;
1876
1877     if (!RtlValidSid(pSid))
1878     {
1879        FreeSid(pSid);
1880        return FALSE;
1881     }
1882
1883     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
1884        CopySid(*cbSid, Sid, pSid);
1885     if (*cbSid < GetLengthSid(pSid))
1886     {
1887        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1888        ret = FALSE;
1889     }
1890     *cbSid = GetLengthSid(pSid);
1891     
1892     if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
1893       strcpyW(ReferencedDomainName, dm);
1894
1895     if (*cchReferencedDomainName <= strlenW(dm))
1896     {
1897        SetLastError(ERROR_INSUFFICIENT_BUFFER);
1898        ret = FALSE;
1899     }
1900
1901     *cchReferencedDomainName = strlenW(dm)+1;
1902
1903     FreeSid(pSid);
1904
1905     return ret;
1906 }
1907
1908 /******************************************************************************
1909  * PrivilegeCheck [ADVAPI32.@]
1910  */
1911 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
1912 {
1913     BOOL ret;
1914     BOOLEAN Result;
1915
1916     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
1917
1918     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
1919     if (ret)
1920         *pfResult = Result;
1921     return ret;
1922 }
1923
1924 /******************************************************************************
1925  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
1926  */
1927 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
1928   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1929   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1930   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1931 {
1932         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
1933                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
1934                 SecurityDescriptor, DesiredAccess, GenericMapping,
1935                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1936         return TRUE;
1937 }
1938
1939 /******************************************************************************
1940  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
1941  */
1942 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
1943   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
1944   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
1945   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
1946 {
1947         FIXME("stub (%s,%p,%s,%s,%p,%08lx,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
1948                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
1949                 SecurityDescriptor, DesiredAccess, GenericMapping,
1950                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
1951         return TRUE;
1952 }
1953
1954 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1955 {
1956     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
1957
1958     return TRUE;
1959 }
1960
1961 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1962 {
1963     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
1964
1965     return TRUE;
1966 }
1967
1968 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
1969 {
1970     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
1971
1972     return TRUE;
1973 }
1974
1975 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
1976   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
1977   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
1978   LPBOOL GenerateOnClose)
1979 {
1980         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
1981                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
1982         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
1983         GenerateOnClose);
1984
1985     return TRUE;
1986 }
1987
1988 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
1989   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
1990   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
1991   LPBOOL GenerateOnClose)
1992 {
1993     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08lx,0x%08lx,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
1994         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
1995         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
1996         GenerateOnClose);
1997
1998     return TRUE;
1999 }
2000
2001 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2002   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2003 {
2004     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2005           DesiredAccess, Privileges, AccessGranted);
2006
2007     return TRUE;
2008 }
2009
2010 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2011   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2012 {
2013     FIXME("stub (%s,%p,%p,0x%08lx,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2014           DesiredAccess, Privileges, AccessGranted);
2015
2016     return TRUE;
2017 }
2018
2019 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2020                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2021 {
2022     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2023           ClientToken, Privileges, AccessGranted);
2024
2025     return TRUE;
2026 }
2027
2028 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2029                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2030 {
2031     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2032           ClientToken, Privileges, AccessGranted);
2033
2034     return TRUE;
2035 }
2036
2037 /******************************************************************************
2038  * GetSecurityInfo [ADVAPI32.@]
2039  */
2040 DWORD WINAPI GetSecurityInfo(
2041     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2042     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2043     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2044     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2045 )
2046 {
2047   FIXME("stub!\n");
2048   return ERROR_BAD_PROVIDER;
2049 }
2050
2051 /******************************************************************************
2052  * GetSecurityInfoExW [ADVAPI32.@]
2053  */
2054 DWORD WINAPI GetSecurityInfoExW(
2055         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2056         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2057         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2058         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2059 )
2060 {
2061   FIXME("stub!\n");
2062   return ERROR_BAD_PROVIDER; 
2063 }
2064
2065 /******************************************************************************
2066  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2067  */
2068 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2069                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2070                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2071 {
2072     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_a(pTrusteeName),
2073           AccessPermissions, AccessMode, Inheritance);
2074
2075     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2076     pExplicitAccess->grfAccessMode = AccessMode;
2077     pExplicitAccess->grfInheritance = Inheritance;
2078
2079     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2080     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2081     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2082     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2083     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2084 }
2085
2086 /******************************************************************************
2087  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2088  */
2089 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2090                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2091                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2092 {
2093     TRACE("%p %s 0x%08lx 0x%08x 0x%08lx\n", pExplicitAccess, debugstr_w(pTrusteeName),
2094           AccessPermissions, AccessMode, Inheritance);
2095
2096     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2097     pExplicitAccess->grfAccessMode = AccessMode;
2098     pExplicitAccess->grfInheritance = Inheritance;
2099
2100     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2101     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2102     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2103     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2104     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2105 }
2106
2107 /******************************************************************************
2108  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2109  */
2110 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2111                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2112                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2113 {
2114     DWORD ObjectsPresent = 0;
2115
2116     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2117           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2118
2119     /* Fill the OBJECTS_AND_NAME structure */
2120     pObjName->ObjectType = ObjectType;
2121     if (ObjectTypeName != NULL)
2122     {
2123         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2124     }
2125
2126     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2127     if (InheritedObjectTypeName != NULL)
2128     {
2129         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2130     }
2131
2132     pObjName->ObjectsPresent = ObjectsPresent;
2133     pObjName->ptstrName = Name;
2134
2135     /* Fill the TRUSTEE structure */
2136     pTrustee->pMultipleTrustee = NULL;
2137     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2138     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2139     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2140     pTrustee->ptstrName = (LPSTR)pObjName;
2141 }
2142
2143 /******************************************************************************
2144  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2145  */
2146 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2147                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2148                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2149 {
2150     DWORD ObjectsPresent = 0;
2151
2152     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2153           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2154
2155     /* Fill the OBJECTS_AND_NAME structure */
2156     pObjName->ObjectType = ObjectType;
2157     if (ObjectTypeName != NULL)
2158     {
2159         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2160     }
2161
2162     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2163     if (InheritedObjectTypeName != NULL)
2164     {
2165         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2166     }
2167
2168     pObjName->ObjectsPresent = ObjectsPresent;
2169     pObjName->ptstrName = Name;
2170
2171     /* Fill the TRUSTEE structure */
2172     pTrustee->pMultipleTrustee = NULL;
2173     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2174     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2175     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2176     pTrustee->ptstrName = (LPWSTR)pObjName;
2177 }
2178
2179 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2180                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2181 {
2182     DWORD ObjectsPresent = 0;
2183
2184     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2185
2186     /* Fill the OBJECTS_AND_SID structure */
2187     if (pObjectGuid != NULL)
2188     {
2189         pObjSid->ObjectTypeGuid = *pObjectGuid;
2190         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2191     }
2192     else
2193     {
2194         ZeroMemory(&pObjSid->ObjectTypeGuid,
2195                    sizeof(GUID));
2196     }
2197
2198     if (pInheritedObjectGuid != NULL)
2199     {
2200         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2201         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2202     }
2203     else
2204     {
2205         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2206                    sizeof(GUID));
2207     }
2208
2209     pObjSid->ObjectsPresent = ObjectsPresent;
2210     pObjSid->pSid = pSid;
2211
2212     /* Fill the TRUSTEE structure */
2213     pTrustee->pMultipleTrustee = NULL;
2214     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2215     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2216     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2217     pTrustee->ptstrName = (LPSTR) pObjSid;
2218 }
2219
2220 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2221                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2222 {
2223     DWORD ObjectsPresent = 0;
2224
2225     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2226
2227     /* Fill the OBJECTS_AND_SID structure */
2228     if (pObjectGuid != NULL)
2229     {
2230         pObjSid->ObjectTypeGuid = *pObjectGuid;
2231         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2232     }
2233     else
2234     {
2235         ZeroMemory(&pObjSid->ObjectTypeGuid,
2236                    sizeof(GUID));
2237     }
2238
2239     if (pInheritedObjectGuid != NULL)
2240     {
2241         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2242         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2243     }
2244     else
2245     {
2246         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2247                    sizeof(GUID));
2248     }
2249
2250     pObjSid->ObjectsPresent = ObjectsPresent;
2251     pObjSid->pSid = pSid;
2252
2253     /* Fill the TRUSTEE structure */
2254     pTrustee->pMultipleTrustee = NULL;
2255     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2256     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2257     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2258     pTrustee->ptstrName = (LPWSTR) pObjSid;
2259 }
2260
2261 /******************************************************************************
2262  * BuildTrusteeWithSidA [ADVAPI32.@]
2263  */
2264 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2265 {
2266     TRACE("%p %p\n", pTrustee, pSid);
2267
2268     pTrustee->pMultipleTrustee = NULL;
2269     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2270     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2271     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2272     pTrustee->ptstrName = (LPSTR) pSid;
2273 }
2274
2275 /******************************************************************************
2276  * BuildTrusteeWithSidW [ADVAPI32.@]
2277  */
2278 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2279 {
2280     TRACE("%p %p\n", pTrustee, pSid);
2281
2282     pTrustee->pMultipleTrustee = NULL;
2283     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2284     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2285     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2286     pTrustee->ptstrName = (LPWSTR) pSid;
2287 }
2288
2289 /******************************************************************************
2290  * BuildTrusteeWithNameA [ADVAPI32.@]
2291  */
2292 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2293 {
2294     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2295
2296     pTrustee->pMultipleTrustee = NULL;
2297     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2298     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2299     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2300     pTrustee->ptstrName = name;
2301 }
2302
2303 /******************************************************************************
2304  * BuildTrusteeWithNameW [ADVAPI32.@]
2305  */
2306 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2307 {
2308     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2309
2310     pTrustee->pMultipleTrustee = NULL;
2311     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2312     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2313     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2314     pTrustee->ptstrName = name;
2315 }
2316
2317 /****************************************************************************** 
2318  * GetTrusteeFormA [ADVAPI32.@] 
2319  */ 
2320 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
2321 {  
2322     TRACE("(%p)\n", pTrustee); 
2323   
2324     if (!pTrustee) 
2325         return TRUSTEE_BAD_FORM; 
2326   
2327     return pTrustee->TrusteeForm; 
2328 }  
2329   
2330 /****************************************************************************** 
2331  * GetTrusteeFormW [ADVAPI32.@] 
2332  */ 
2333 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
2334 {  
2335     TRACE("(%p)\n", pTrustee); 
2336   
2337     if (!pTrustee) 
2338         return TRUSTEE_BAD_FORM; 
2339   
2340     return pTrustee->TrusteeForm; 
2341 }  
2342   
2343 /****************************************************************************** 
2344  * GetTrusteeNameA [ADVAPI32.@] 
2345  */ 
2346 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
2347 {  
2348     TRACE("(%p)\n", pTrustee); 
2349   
2350     if (!pTrustee) 
2351         return NULL; 
2352   
2353     return pTrustee->ptstrName; 
2354 }  
2355   
2356 /****************************************************************************** 
2357  * GetTrusteeNameW [ADVAPI32.@] 
2358  */ 
2359 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
2360 {  
2361     TRACE("(%p)\n", pTrustee); 
2362   
2363     if (!pTrustee) 
2364         return NULL; 
2365   
2366     return pTrustee->ptstrName; 
2367 }  
2368   
2369 /****************************************************************************** 
2370  * GetTrusteeTypeA [ADVAPI32.@] 
2371  */ 
2372 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
2373 {  
2374     TRACE("(%p)\n", pTrustee); 
2375   
2376     if (!pTrustee) 
2377         return TRUSTEE_IS_UNKNOWN; 
2378   
2379     return pTrustee->TrusteeType; 
2380 }  
2381   
2382 /****************************************************************************** 
2383  * GetTrusteeTypeW [ADVAPI32.@] 
2384  */ 
2385 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
2386 {  
2387     TRACE("(%p)\n", pTrustee); 
2388   
2389     if (!pTrustee) 
2390         return TRUSTEE_IS_UNKNOWN; 
2391   
2392     return pTrustee->TrusteeType; 
2393
2394  
2395 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2396                                DWORD nAclInformationLength,
2397                                ACL_INFORMATION_CLASS dwAclInformationClass )
2398 {
2399     FIXME("%p %p 0x%08lx 0x%08x - stub\n", pAcl, pAclInformation,
2400           nAclInformationLength, dwAclInformationClass);
2401
2402     return TRUE;
2403 }
2404
2405 /******************************************************************************
2406  * SetEntriesInAclA [ADVAPI32.@]
2407  */
2408 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2409                                PACL OldAcl, PACL* NewAcl )
2410 {
2411     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2412     return ERROR_CALL_NOT_IMPLEMENTED;
2413 }
2414
2415 /******************************************************************************
2416  * SetEntriesInAclW [ADVAPI32.@]
2417  */
2418 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
2419                                PACL OldAcl, PACL* NewAcl )
2420 {
2421     FIXME("%ld %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2422     return ERROR_CALL_NOT_IMPLEMENTED;
2423 }
2424
2425 /******************************************************************************
2426  * SetNamedSecurityInfoA [ADVAPI32.@]
2427  */
2428 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2429         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2430         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2431 {
2432     DWORD len;
2433     LPWSTR wstr = NULL;
2434     DWORD r;
2435
2436     TRACE("%s %d %ld %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2437            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2438
2439     if( pObjectName )
2440     {
2441         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2442         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2443         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2444     }
2445
2446     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2447                            psidGroup, pDacl, pSacl );
2448
2449     HeapFree( GetProcessHeap(), 0, wstr );
2450
2451     return r;
2452 }
2453
2454 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2455     PSECURITY_DESCRIPTOR ModificationDescriptor,
2456     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2457     PGENERIC_MAPPING GenericMapping,
2458     HANDLE Token )
2459 {
2460     FIXME("0x%08lx %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2461           ObjectsSecurityDescriptor, GenericMapping, Token);
2462
2463     return TRUE;
2464 }
2465
2466 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2467   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2468   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2469 {
2470     FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2471           ControlBitsToSet);
2472
2473     return TRUE;
2474 }
2475
2476 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2477 {
2478     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2479 }
2480
2481 /******************************************************************************
2482  * AreAnyAccessesGranted [ADVAPI32.@]
2483  *
2484  * Determines whether or not any of a set of specified access permissions have
2485  * been granted or not.
2486  *
2487  * PARAMS
2488  *   GrantedAccess [I] The permissions that have been granted.
2489  *   DesiredAccess [I] The permissions that you want to have.
2490  *
2491  * RETURNS
2492  *   Nonzero if any of the permissions have been granted, zero if none of the
2493  *   permissions have been granted.
2494  */
2495
2496 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2497 {
2498     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
2499 }
2500
2501 /******************************************************************************
2502  * SetNamedSecurityInfoW [ADVAPI32.@]
2503  */
2504 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
2505         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2506         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2507 {
2508     FIXME("%s %d %ld %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
2509            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2510     return ERROR_SUCCESS;
2511 }
2512
2513 /******************************************************************************
2514  * GetExplicitEntriesFromAclA [ADVAPI32.@]
2515  */
2516 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
2517         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
2518 {
2519     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2520     return ERROR_CALL_NOT_IMPLEMENTED;
2521 }
2522
2523 /******************************************************************************
2524  * GetExplicitEntriesFromAclW [ADVAPI32.@]
2525  */
2526 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
2527         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
2528 {
2529     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
2530     return ERROR_CALL_NOT_IMPLEMENTED;
2531 }
2532
2533
2534 /******************************************************************************
2535  * ParseAclStringFlags
2536  */
2537 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
2538 {
2539     DWORD flags = 0;
2540     LPCWSTR szAcl = *StringAcl;
2541
2542     while (*szAcl != '(')
2543     {
2544         if (*szAcl == 'P')
2545         {
2546             flags |= SE_DACL_PROTECTED;
2547         }
2548         else if (*szAcl == 'A')
2549         {
2550             szAcl++;
2551             if (*szAcl == 'R')
2552                 flags |= SE_DACL_AUTO_INHERIT_REQ;
2553             else if (*szAcl == 'I')
2554                 flags |= SE_DACL_AUTO_INHERITED;
2555         }
2556         szAcl++;
2557     }
2558
2559     *StringAcl = szAcl;
2560     return flags;
2561 }
2562
2563 /******************************************************************************
2564  * ParseAceStringType
2565  */
2566 ACEFLAG AceType[] =
2567 {
2568     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
2569     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
2570     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
2571     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
2572     /*
2573     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
2574     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
2575     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
2576     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
2577     */
2578     { NULL, 0 },
2579 };
2580
2581 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
2582 {
2583     UINT len = 0;
2584     LPCWSTR szAcl = *StringAcl;
2585     LPACEFLAG lpaf = AceType;
2586
2587     while (lpaf->wstr &&
2588         (len = strlenW(lpaf->wstr)) &&
2589         strncmpW(lpaf->wstr, szAcl, len))
2590         lpaf++;
2591
2592     if (!lpaf->wstr)
2593         return 0;
2594
2595     *StringAcl += len;
2596     return lpaf->value;
2597 }
2598
2599
2600 /******************************************************************************
2601  * ParseAceStringFlags
2602  */
2603 ACEFLAG AceFlags[] =
2604 {
2605     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
2606     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
2607     { SDDL_INHERITED,         INHERITED_ACE },
2608     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
2609     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
2610     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
2611     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
2612     { NULL, 0 },
2613 };
2614
2615 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
2616 {
2617     UINT len = 0;
2618     BYTE flags = 0;
2619     LPCWSTR szAcl = *StringAcl;
2620
2621     while (*szAcl != ';')
2622     {
2623         LPACEFLAG lpaf = AceFlags;
2624
2625         while (lpaf->wstr &&
2626                (len = strlenW(lpaf->wstr)) &&
2627                strncmpW(lpaf->wstr, szAcl, len))
2628             lpaf++;
2629
2630         if (!lpaf->wstr)
2631             return 0;
2632
2633         flags |= lpaf->value;
2634         szAcl += len;
2635     }
2636
2637     *StringAcl = szAcl;
2638     return flags;
2639 }
2640
2641
2642 /******************************************************************************
2643  * ParseAceStringRights
2644  */
2645 ACEFLAG AceRights[] =
2646 {
2647     { SDDL_GENERIC_ALL,     GENERIC_ALL },
2648     { SDDL_GENERIC_READ,    GENERIC_READ },
2649     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
2650     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
2651     { SDDL_READ_CONTROL,    READ_CONTROL },
2652     { SDDL_STANDARD_DELETE, DELETE },
2653     { SDDL_WRITE_DAC,       WRITE_DAC },
2654     { SDDL_WRITE_OWNER,     WRITE_OWNER },
2655     { NULL, 0 },
2656 };
2657
2658 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
2659 {
2660     UINT len = 0;
2661     DWORD rights = 0;
2662     LPCWSTR szAcl = *StringAcl;
2663
2664     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
2665     {
2666         LPCWSTR p = szAcl;
2667
2668         while (*p && *p != ';')
2669             p++;
2670
2671         if (p - szAcl <= 8)
2672         {
2673             rights = strtoulW(szAcl, NULL, 16);
2674             *StringAcl = p;
2675         }
2676         else
2677             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
2678     }
2679     else
2680     {
2681         while (*szAcl != ';')
2682         {
2683             LPACEFLAG lpaf = AceRights;
2684
2685             while (lpaf->wstr &&
2686                (len = strlenW(lpaf->wstr)) &&
2687                strncmpW(lpaf->wstr, szAcl, len))
2688             {
2689                lpaf++;
2690             }
2691
2692             if (!lpaf->wstr)
2693                 return 0;
2694
2695             rights |= lpaf->value;
2696             szAcl += len;
2697         }
2698     }
2699
2700     *StringAcl = szAcl;
2701     return rights;
2702 }
2703
2704
2705 /******************************************************************************
2706  * ParseStringAclToAcl
2707  * 
2708  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
2709  */
2710 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
2711     PACL pAcl, LPDWORD cBytes)
2712 {
2713     DWORD val;
2714     DWORD sidlen;
2715     DWORD length = sizeof(ACL);
2716     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
2717
2718     TRACE("%s\n", debugstr_w(StringAcl));
2719
2720     if (!StringAcl)
2721         return FALSE;
2722
2723     if (pAcl) /* pAce is only useful if we're setting values */
2724         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
2725
2726     /* Parse ACL flags */
2727     *lpdwFlags = ParseAclStringFlags(&StringAcl);
2728
2729     /* Parse ACE */
2730     while (*StringAcl == '(')
2731     {
2732         StringAcl++;
2733
2734         /* Parse ACE type */
2735         val = ParseAceStringType(&StringAcl);
2736         if (pAce)
2737             pAce->Header.AceType = (BYTE) val;
2738         if (*StringAcl != ';')
2739             goto lerr;
2740         StringAcl++;
2741
2742         /* Parse ACE flags */
2743         val = ParseAceStringFlags(&StringAcl);
2744         if (pAce)
2745             pAce->Header.AceFlags = (BYTE) val;
2746         if (*StringAcl != ';')
2747             goto lerr;
2748         StringAcl++;
2749
2750         /* Parse ACE rights */
2751         val = ParseAceStringRights(&StringAcl);
2752         if (pAce)
2753             pAce->Mask = val;
2754         if (*StringAcl != ';')
2755             goto lerr;
2756         StringAcl++;
2757
2758         /* Parse ACE object guid */
2759         if (*StringAcl != ';')
2760         {
2761             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2762             goto lerr;
2763         }
2764         StringAcl++;
2765
2766         /* Parse ACE inherit object guid */
2767         if (*StringAcl != ';')
2768         {
2769             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
2770             goto lerr;
2771         }
2772         StringAcl++;
2773
2774         /* Parse ACE account sid */
2775         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
2776         {
2777             while (*StringAcl && *StringAcl != ')')
2778                 StringAcl++;
2779         }
2780
2781         if (*StringAcl != ')')
2782             goto lerr;
2783         StringAcl++;
2784
2785         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
2786     }
2787
2788     *cBytes = length;
2789     return TRUE;
2790
2791 lerr:
2792     WARN("Invalid ACE string format\n");
2793     return FALSE;
2794 }
2795
2796
2797 /******************************************************************************
2798  * ParseStringSecurityDescriptorToSecurityDescriptor
2799  */
2800 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
2801     LPCWSTR StringSecurityDescriptor,
2802     SECURITY_DESCRIPTOR* SecurityDescriptor,
2803     LPDWORD cBytes)
2804 {
2805     BOOL bret = FALSE;
2806     WCHAR toktype;
2807     WCHAR tok[MAX_PATH];
2808     LPCWSTR lptoken;
2809     LPBYTE lpNext = NULL;
2810     DWORD len;
2811
2812     *cBytes = 0;
2813
2814     if (SecurityDescriptor)
2815         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
2816
2817     while (*StringSecurityDescriptor)
2818     {
2819         toktype = *StringSecurityDescriptor;
2820
2821         /* Expect char identifier followed by ':' */
2822         StringSecurityDescriptor++;
2823         if (*StringSecurityDescriptor != ':')
2824         {
2825             SetLastError(ERROR_INVALID_PARAMETER);
2826             goto lend;
2827         }
2828         StringSecurityDescriptor++;
2829
2830         /* Extract token */
2831         lptoken = StringSecurityDescriptor;
2832         while (*lptoken && *lptoken != ':')
2833             lptoken++;
2834
2835         if (*lptoken)
2836             lptoken--;
2837
2838         len = lptoken - StringSecurityDescriptor;
2839         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
2840         tok[len] = 0;
2841
2842         switch (toktype)
2843         {
2844             case 'O':
2845             {
2846                 DWORD bytes;
2847
2848                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2849                     goto lend;
2850
2851                 if (SecurityDescriptor)
2852                 {
2853                     SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
2854                     lpNext += bytes; /* Advance to next token */
2855                 }
2856
2857                 *cBytes += bytes;
2858
2859                 break;
2860             }
2861
2862             case 'G':
2863             {
2864                 DWORD bytes;
2865
2866                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
2867                     goto lend;
2868
2869                 if (SecurityDescriptor)
2870                 {
2871                     SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
2872                     lpNext += bytes; /* Advance to next token */
2873                 }
2874
2875                 *cBytes += bytes;
2876
2877                 break;
2878             }
2879
2880             case 'D':
2881             {
2882                 DWORD flags;
2883                 DWORD bytes;
2884
2885                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2886                     goto lend;
2887
2888                 if (SecurityDescriptor)
2889                 {
2890                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
2891                     SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
2892                     lpNext += bytes; /* Advance to next token */
2893                 }
2894
2895                 *cBytes += bytes;
2896
2897                 break;
2898             }
2899
2900             case 'S':
2901             {
2902                 DWORD flags;
2903                 DWORD bytes;
2904
2905                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
2906                     goto lend;
2907
2908                 if (SecurityDescriptor)
2909                 {
2910                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
2911                     SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
2912                     lpNext += bytes; /* Advance to next token */
2913                 }
2914
2915                 *cBytes += bytes;
2916
2917                 break;
2918             }
2919
2920             default:
2921                 FIXME("Unknown token\n");
2922                 SetLastError(ERROR_INVALID_PARAMETER);
2923                 goto lend;
2924         }
2925
2926         StringSecurityDescriptor = lptoken;
2927     }
2928
2929     bret = TRUE;
2930
2931 lend:
2932     return bret;
2933 }
2934
2935 /******************************************************************************
2936  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
2937  */
2938 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
2939         LPCSTR StringSecurityDescriptor,
2940         DWORD StringSDRevision,
2941         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2942         PULONG SecurityDescriptorSize)
2943 {
2944     UINT len;
2945     BOOL ret = FALSE;
2946     LPWSTR StringSecurityDescriptorW;
2947
2948     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
2949     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
2950
2951     if (StringSecurityDescriptorW)
2952     {
2953         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
2954
2955         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
2956                                                                    StringSDRevision, SecurityDescriptor,
2957                                                                    SecurityDescriptorSize);
2958         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
2959     }
2960
2961     return ret;
2962 }
2963
2964 /******************************************************************************
2965  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
2966  */
2967 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
2968         LPCWSTR StringSecurityDescriptor,
2969         DWORD StringSDRevision,
2970         PSECURITY_DESCRIPTOR* SecurityDescriptor,
2971         PULONG SecurityDescriptorSize)
2972 {
2973     DWORD cBytes;
2974     SECURITY_DESCRIPTOR* psd;
2975     BOOL bret = FALSE;
2976
2977     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
2978
2979     if (GetVersion() & 0x80000000)
2980     {
2981         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
2982         goto lend;
2983     }
2984     else if (StringSDRevision != SID_REVISION)
2985     {
2986         SetLastError(ERROR_UNKNOWN_REVISION);
2987         goto lend;
2988     }
2989
2990     /* Compute security descriptor length */
2991     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
2992         NULL, &cBytes))
2993         goto lend;
2994
2995     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
2996         GMEM_ZEROINIT, cBytes);
2997
2998     psd->Revision = SID_REVISION;
2999     psd->Control |= SE_SELF_RELATIVE;
3000
3001     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3002         psd, &cBytes))
3003     {
3004         LocalFree(psd);
3005         goto lend;
3006     }
3007
3008     if (SecurityDescriptorSize)
3009         *SecurityDescriptorSize = cBytes;
3010
3011     bret = TRUE;
3012  
3013 lend:
3014     TRACE(" ret=%d\n", bret);
3015     return bret;
3016 }
3017
3018 /******************************************************************************
3019  * ConvertStringSidToSidW [ADVAPI32.@]
3020  */
3021 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3022 {
3023     BOOL bret = FALSE;
3024     DWORD cBytes;
3025
3026     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3027     if (GetVersion() & 0x80000000)
3028         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3029     else if (!StringSid || !Sid)
3030         SetLastError(ERROR_INVALID_PARAMETER);
3031     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3032     {
3033         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
3034
3035         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3036         if (!bret)
3037             LocalFree(*Sid); 
3038     }
3039     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3040     return bret;
3041 }
3042
3043 /******************************************************************************
3044  * ConvertStringSidToSidA [ADVAPI32.@]
3045  */
3046 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3047 {
3048     BOOL bret = FALSE;
3049
3050     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3051     if (GetVersion() & 0x80000000)
3052         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3053     else if (!StringSid || !Sid)
3054         SetLastError(ERROR_INVALID_PARAMETER);
3055     else
3056     {
3057         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
3058         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
3059          len * sizeof(WCHAR));
3060
3061         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
3062         bret = ConvertStringSidToSidW(wStringSid, Sid);
3063         HeapFree(GetProcessHeap(), 0, wStringSid);
3064     }
3065     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3066     return bret;
3067 }
3068
3069 /******************************************************************************
3070  * ConvertSidToStringSidW [ADVAPI32.@]
3071  *
3072  *  format of SID string is:
3073  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3074  *  where
3075  *    <rev> is the revision of the SID encoded as decimal
3076  *    <auth> is the identifier authority encoded as hex
3077  *    <subauthN> is the subauthority id encoded as decimal
3078  */
3079 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
3080 {
3081     DWORD sz, i;
3082     LPWSTR str;
3083     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3084     WCHAR subauthfmt[] = { '-','%','u',0 };
3085     SID* pisid=pSid;
3086
3087     TRACE("%p %p\n", pSid, pstr );
3088
3089     if( !IsValidSid( pSid ) )
3090         return FALSE;
3091
3092     if (pisid->Revision != SDDL_REVISION)
3093         return FALSE;
3094     if (pisid->IdentifierAuthority.Value[0] ||
3095      pisid->IdentifierAuthority.Value[1])
3096     {
3097         FIXME("not matching MS' bugs\n");
3098         return FALSE;
3099     }
3100
3101     sz = 14 + pisid->SubAuthorityCount * 11;
3102     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
3103     sprintfW( str, fmt, pisid->Revision, MAKELONG(
3104      MAKEWORD( pisid->IdentifierAuthority.Value[5],
3105      pisid->IdentifierAuthority.Value[4] ),
3106      MAKEWORD( pisid->IdentifierAuthority.Value[3],
3107      pisid->IdentifierAuthority.Value[2] ) ) );
3108     for( i=0; i<pisid->SubAuthorityCount; i++ )
3109         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
3110     *pstr = str;
3111
3112     return TRUE;
3113 }
3114
3115 /******************************************************************************
3116  * ConvertSidToStringSidA [ADVAPI32.@]
3117  */
3118 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
3119 {
3120     LPWSTR wstr = NULL;
3121     LPSTR str;
3122     UINT len;
3123
3124     TRACE("%p %p\n", pSid, pstr );
3125
3126     if( !ConvertSidToStringSidW( pSid, &wstr ) )
3127         return FALSE;
3128
3129     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
3130     str = LocalAlloc( 0, len );
3131     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
3132     LocalFree( wstr );
3133
3134     *pstr = str;
3135
3136     return TRUE;
3137 }
3138
3139 BOOL WINAPI CreatePrivateObjectSecurity(
3140         PSECURITY_DESCRIPTOR ParentDescriptor,
3141         PSECURITY_DESCRIPTOR CreatorDescriptor,
3142         PSECURITY_DESCRIPTOR* NewDescriptor,
3143         BOOL IsDirectoryObject,
3144         HANDLE Token,
3145         PGENERIC_MAPPING GenericMapping )
3146 {
3147     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
3148           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
3149
3150     return FALSE;
3151 }
3152
3153 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
3154 {
3155     FIXME("%p - stub\n", ObjectDescriptor);
3156
3157     return TRUE;
3158 }
3159
3160 BOOL WINAPI CreateProcessAsUserA(
3161         HANDLE hToken,
3162         LPCSTR lpApplicationName,
3163         LPSTR lpCommandLine,
3164         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3165         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3166         BOOL bInheritHandles,
3167         DWORD dwCreationFlags,
3168         LPVOID lpEnvironment,
3169         LPCSTR lpCurrentDirectory,
3170         LPSTARTUPINFOA lpStartupInfo,
3171         LPPROCESS_INFORMATION lpProcessInformation )
3172 {
3173     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
3174           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3175           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3176
3177     return FALSE;
3178 }
3179
3180 BOOL WINAPI CreateProcessAsUserW(
3181         HANDLE hToken,
3182         LPCWSTR lpApplicationName,
3183         LPWSTR lpCommandLine,
3184         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3185         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3186         BOOL bInheritHandles,
3187         DWORD dwCreationFlags,
3188         LPVOID lpEnvironment,
3189         LPCWSTR lpCurrentDirectory,
3190         LPSTARTUPINFOW lpStartupInfo,
3191         LPPROCESS_INFORMATION lpProcessInformation )
3192 {
3193     FIXME("%p %s %s %p %p %d 0x%08lx %p %s %p %p - semi- stub\n", hToken, 
3194           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
3195           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
3196           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3197
3198     /* We should create the process with a suspended main thread */
3199     if (!CreateProcessW (lpApplicationName,
3200                          lpCommandLine,
3201                          lpProcessAttributes,
3202                          lpThreadAttributes,
3203                          bInheritHandles,
3204                          dwCreationFlags, /* CREATE_SUSPENDED */
3205                          lpEnvironment,
3206                          lpCurrentDirectory,
3207                          lpStartupInfo,
3208                          lpProcessInformation))
3209     {
3210       return FALSE;
3211     }
3212
3213     return TRUE;
3214 }
3215
3216 /******************************************************************************
3217  * ComputeStringSidSize
3218  */
3219 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3220 {
3221     int ctok = 0;
3222     DWORD size = sizeof(SID);
3223
3224     while (*StringSid)
3225     {
3226         if (*StringSid == '-')
3227             ctok++;
3228         StringSid++;
3229     }
3230
3231     if (ctok > 3)
3232         size += (ctok - 3) * sizeof(DWORD);
3233
3234     return size;
3235 }
3236
3237 BOOL WINAPI DuplicateTokenEx(
3238         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
3239         LPSECURITY_ATTRIBUTES lpTokenAttributes,
3240         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3241         TOKEN_TYPE TokenType,
3242         PHANDLE DuplicateTokenHandle )
3243 {
3244     OBJECT_ATTRIBUTES ObjectAttributes;
3245
3246     TRACE("%p 0x%08lx 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3247           ImpersonationLevel, TokenType, DuplicateTokenHandle);
3248
3249     InitializeObjectAttributes(
3250         &ObjectAttributes,
3251         NULL,
3252         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
3253         NULL,
3254         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
3255
3256     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
3257                                            dwDesiredAccess,
3258                                            &ObjectAttributes,
3259                                            ImpersonationLevel,
3260                                            TokenType,
3261                                            DuplicateTokenHandle ) );
3262 }
3263
3264 BOOL WINAPI DuplicateToken(
3265         HANDLE ExistingTokenHandle,
3266         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3267         PHANDLE DuplicateTokenHandle )
3268 {
3269     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
3270                              NULL, ImpersonationLevel, TokenImpersonation,
3271                              DuplicateTokenHandle );
3272 }
3273
3274 BOOL WINAPI EnumDependentServicesA(
3275         SC_HANDLE hService,
3276         DWORD dwServiceState,
3277         LPENUM_SERVICE_STATUSA lpServices,
3278         DWORD cbBufSize,
3279         LPDWORD pcbBytesNeeded,
3280         LPDWORD lpServicesReturned )
3281 {
3282     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3283           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3284
3285     return FALSE;
3286 }
3287
3288 BOOL WINAPI EnumDependentServicesW(
3289         SC_HANDLE hService,
3290         DWORD dwServiceState,
3291         LPENUM_SERVICE_STATUSW lpServices,
3292         DWORD cbBufSize,
3293         LPDWORD pcbBytesNeeded,
3294         LPDWORD lpServicesReturned )
3295 {
3296     FIXME("%p 0x%08lx %p 0x%08lx %p %p - stub\n", hService, dwServiceState,
3297           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3298
3299     return FALSE;
3300 }
3301
3302 /******************************************************************************
3303  * ParseStringSidToSid
3304  */
3305 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3306 {
3307     BOOL bret = FALSE;
3308     SID* pisid=pSid;
3309
3310     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3311     if (!StringSid)
3312     {
3313         SetLastError(ERROR_INVALID_PARAMETER);
3314         TRACE("StringSid is NULL, returning FALSE\n");
3315         return FALSE;
3316     }
3317
3318     *cBytes = ComputeStringSidSize(StringSid);
3319     if (!pisid) /* Simply compute the size */
3320     {
3321         TRACE("only size requested, returning TRUE\n");
3322         return TRUE;
3323     }
3324
3325     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3326     {
3327         DWORD i = 0, identAuth;
3328         DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
3329
3330         StringSid += 2; /* Advance to Revision */
3331         pisid->Revision = atoiW(StringSid);
3332
3333         if (pisid->Revision != SDDL_REVISION)
3334         {
3335             TRACE("Revision %d is unknown\n", pisid->Revision);
3336             goto lend; /* ERROR_INVALID_SID */
3337         }
3338         if (csubauth == 0)
3339         {
3340             TRACE("SubAuthorityCount is 0\n");
3341             goto lend; /* ERROR_INVALID_SID */
3342         }
3343
3344         pisid->SubAuthorityCount = csubauth;
3345
3346         /* Advance to identifier authority */
3347         while (*StringSid && *StringSid != '-')
3348             StringSid++;
3349         if (*StringSid == '-')
3350             StringSid++;
3351
3352         /* MS' implementation can't handle values greater than 2^32 - 1, so
3353          * we don't either; assume most significant bytes are always 0
3354          */
3355         pisid->IdentifierAuthority.Value[0] = 0;
3356         pisid->IdentifierAuthority.Value[1] = 0;
3357         identAuth = atoiW(StringSid);
3358         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3359         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3360         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3361         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3362
3363         /* Advance to first sub authority */
3364         while (*StringSid && *StringSid != '-')
3365             StringSid++;
3366         if (*StringSid == '-')
3367             StringSid++;
3368
3369         while (*StringSid)
3370         {       
3371             while (*StringSid && *StringSid != '-')
3372                 StringSid++;
3373
3374             pisid->SubAuthority[i++] = atoiW(StringSid);
3375         }
3376
3377         if (i != pisid->SubAuthorityCount)
3378             goto lend; /* ERROR_INVALID_SID */
3379
3380         bret = TRUE;
3381     }
3382     else /* String constant format  - Only available in winxp and above */
3383     {
3384         pisid->Revision = SDDL_REVISION;
3385         pisid->SubAuthorityCount = 1;
3386
3387         FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3388
3389         /* TODO: Lookup string of well-known SIDs in table */
3390         pisid->IdentifierAuthority.Value[5] = 0;
3391         pisid->SubAuthority[0] = 0;
3392
3393         bret = TRUE;
3394     }
3395
3396 lend:
3397     if (!bret)
3398         SetLastError(ERROR_INVALID_SID);
3399
3400     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3401     return bret;
3402 }
3403
3404 /******************************************************************************
3405  * GetNamedSecurityInfoA [ADVAPI32.@]
3406  */
3407 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
3408         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3409         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3410         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3411 {
3412     DWORD len;
3413     LPWSTR wstr = NULL;
3414     DWORD r;
3415
3416     TRACE("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3417         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3418
3419     if( pObjectName )
3420     {
3421         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3422         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3423         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3424     }
3425
3426     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3427                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3428
3429     HeapFree( GetProcessHeap(), 0, wstr );
3430
3431     return r;
3432 }
3433
3434 /******************************************************************************
3435  * GetNamedSecurityInfoW [ADVAPI32.@]
3436  */
3437 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
3438     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
3439     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
3440 {
3441     DWORD needed, offset;
3442     SECURITY_DESCRIPTOR_RELATIVE *relative;
3443     BYTE *buffer;
3444
3445     TRACE( "%s %d %ld %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
3446            group, dacl, sacl, descriptor );
3447
3448     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
3449
3450     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3451     if (info & OWNER_SECURITY_INFORMATION)
3452         needed += sizeof(sidWorld);
3453     if (info & GROUP_SECURITY_INFORMATION)
3454         needed += sizeof(sidWorld);
3455     if (info & DACL_SECURITY_INFORMATION)
3456         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3457     if (info & SACL_SECURITY_INFORMATION)
3458         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3459
3460     /* must be freed by caller */
3461     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
3462     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
3463
3464     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
3465     {
3466         HeapFree( GetProcessHeap(), 0, *descriptor );
3467         return ERROR_INVALID_SECURITY_DESCR;
3468     }
3469
3470     relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
3471     relative->Control |= SE_SELF_RELATIVE;
3472     buffer = (BYTE *)relative;
3473     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3474
3475     if (owner && (info & OWNER_SECURITY_INFORMATION))
3476     {
3477         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3478         relative->Owner = offset;
3479         *owner = buffer + offset;
3480         offset += sizeof(sidWorld);
3481     }
3482     if (group && (info & GROUP_SECURITY_INFORMATION))
3483     {
3484         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3485         relative->Group = offset;
3486         *group = buffer + offset;
3487         offset += sizeof(sidWorld);
3488     }
3489     if (dacl && (info & DACL_SECURITY_INFORMATION))
3490     {
3491         GetWorldAccessACL( (PACL)(buffer + offset) );
3492         relative->Dacl = offset;
3493         *dacl = (PACL)(buffer + offset);
3494         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3495     }
3496     if (sacl && (info & SACL_SECURITY_INFORMATION))
3497     {
3498         GetWorldAccessACL( (PACL)(buffer + offset) );
3499         relative->Sacl = offset;
3500         *sacl = (PACL)(buffer + offset);
3501     }
3502     return ERROR_SUCCESS;
3503 }
3504
3505 /******************************************************************************
3506  * DecryptFileW [ADVAPI32.@]
3507  */
3508 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
3509 {
3510     FIXME("%s %08lx\n", debugstr_w(lpFileName), dwReserved);
3511     return TRUE;
3512 }
3513
3514 /******************************************************************************
3515  * DecryptFileA [ADVAPI32.@]
3516  */
3517 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
3518 {
3519     FIXME("%s %08lx\n", debugstr_a(lpFileName), dwReserved);
3520     return TRUE;
3521 }
3522
3523 /******************************************************************************
3524  * EncryptFileW [ADVAPI32.@]
3525  */
3526 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
3527 {
3528     FIXME("%s\n", debugstr_w(lpFileName));
3529     return TRUE;
3530 }
3531
3532 /******************************************************************************
3533  * EncryptFileA [ADVAPI32.@]
3534  */
3535 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
3536 {
3537     FIXME("%s\n", debugstr_a(lpFileName));
3538     return TRUE;
3539 }
3540
3541 /******************************************************************************
3542  * SetSecurityInfo [ADVAPI32.@]
3543  */
3544 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
3545                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
3546                       PSID psidGroup, PACL pDacl, PACL pSacl) {
3547     FIXME("stub\n");
3548     return ERROR_SUCCESS;
3549 }