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