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