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