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