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