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