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