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