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