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