crypt32: Add missing ok calls.
[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     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1919                                 DACL_SECURITY_INFORMATION))
1920         access |= READ_CONTROL;
1921     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1922         access |= ACCESS_SYSTEM_SECURITY;
1923
1924     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1925                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1926     if ( hfile == INVALID_HANDLE_VALUE )
1927         return FALSE;
1928
1929     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1930                                     nLength, lpnLengthNeeded );
1931     CloseHandle( hfile );
1932     return set_ntstatus( status );
1933 }
1934
1935
1936 /******************************************************************************
1937  * LookupAccountSidA [ADVAPI32.@]
1938  */
1939 BOOL WINAPI
1940 LookupAccountSidA(
1941         IN LPCSTR system,
1942         IN PSID sid,
1943         OUT LPSTR account,
1944         IN OUT LPDWORD accountSize,
1945         OUT LPSTR domain,
1946         IN OUT LPDWORD domainSize,
1947         OUT PSID_NAME_USE name_use )
1948 {
1949     DWORD len;
1950     BOOL r;
1951     LPWSTR systemW = NULL;
1952     LPWSTR accountW = NULL;
1953     LPWSTR domainW = NULL;
1954     DWORD accountSizeW = *accountSize;
1955     DWORD domainSizeW = *domainSize;
1956
1957     if (system) {
1958         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1959         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1960         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1961     }
1962     if (account)
1963         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1964     if (domain)
1965         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1966
1967     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1968
1969     if (r) {
1970         if (accountW && *accountSize) {
1971             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1972             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1973             *accountSize = len;
1974         } else
1975             *accountSize = accountSizeW + 1;
1976
1977         if (domainW && *domainSize) {
1978             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1979             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1980             *domainSize = len;
1981         } else
1982             *domainSize = domainSizeW + 1;
1983     }
1984
1985     HeapFree( GetProcessHeap(), 0, systemW );
1986     HeapFree( GetProcessHeap(), 0, accountW );
1987     HeapFree( GetProcessHeap(), 0, domainW );
1988
1989     return r;
1990 }
1991
1992 /******************************************************************************
1993  * LookupAccountSidW [ADVAPI32.@]
1994  *
1995  * PARAMS
1996  *   system      []
1997  *   sid         []
1998  *   account     []
1999  *   accountSize []
2000  *   domain      []
2001  *   domainSize  []
2002  *   name_use    []
2003  */
2004
2005 BOOL WINAPI
2006 LookupAccountSidW(
2007         IN LPCWSTR system,
2008         IN PSID sid,
2009         OUT LPWSTR account,
2010         IN OUT LPDWORD accountSize,
2011         OUT LPWSTR domain,
2012         IN OUT LPDWORD domainSize,
2013         OUT PSID_NAME_USE name_use )
2014 {
2015     unsigned int i, j;
2016     const WCHAR * ac = NULL;
2017     const WCHAR * dm = NULL;
2018     SID_NAME_USE use = 0;
2019     LPWSTR computer_name = NULL;
2020     LPWSTR account_name = NULL;
2021
2022     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2023           debugstr_w(system),debugstr_sid(sid),
2024           account,accountSize,accountSize?*accountSize:0,
2025           domain,domainSize,domainSize?*domainSize:0,
2026           name_use);
2027
2028     if (!ADVAPI_IsLocalComputer(system)) {
2029         FIXME("Only local computer supported!\n");
2030         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2031         return FALSE;
2032     }
2033
2034     /* check the well known SIDs first */
2035     for (i = 0; i <= 60; i++) {
2036         if (IsWellKnownSid(sid, i)) {
2037             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2038                 if (ACCOUNT_SIDS[j].type == i) {
2039                     ac = ACCOUNT_SIDS[j].account;
2040                     dm = ACCOUNT_SIDS[j].domain;
2041                     use = ACCOUNT_SIDS[j].name_use;
2042                 }
2043             }
2044             break;
2045         }
2046     }
2047
2048     if (dm == NULL) {
2049         MAX_SID local;
2050
2051         /* check for the local computer next */
2052         if (ADVAPI_GetComputerSid(&local)) {
2053             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2054             BOOL result;
2055
2056             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2057             result = GetComputerNameW(computer_name,  &size);
2058
2059             if (result) {
2060                 if (EqualSid(sid, &local)) {
2061                     dm = computer_name;
2062                     ac = Blank;
2063                     use = 3;
2064                 } else {
2065                     local.SubAuthorityCount++;
2066
2067                     if (EqualPrefixSid(sid, &local)) {
2068                         dm = computer_name;
2069                         use = 1;
2070                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2071                         case DOMAIN_USER_RID_ADMIN:
2072                             ac = Administrator;
2073                             break;
2074                         case DOMAIN_USER_RID_GUEST:
2075                             ac = Guest;
2076                             break;
2077                         case DOMAIN_GROUP_RID_ADMINS:
2078                             ac = Domain_Admins;
2079                             break;
2080                         case DOMAIN_GROUP_RID_USERS:
2081                             ac = Domain_Users;
2082                             break;
2083                         case DOMAIN_GROUP_RID_GUESTS:
2084                             ac = Domain_Guests;
2085                             break;
2086                         case DOMAIN_GROUP_RID_COMPUTERS:
2087                             ac = Domain_Computers;
2088                             break;
2089                         case DOMAIN_GROUP_RID_CONTROLLERS:
2090                             ac = Domain_Controllers;
2091                             break;
2092                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2093                             ac = Cert_Publishers;
2094                             break;
2095                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2096                             ac = Schema_Admins;
2097                             break;
2098                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2099                             ac = Enterprise_Admins;
2100                             break;
2101                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2102                             ac = Group_Policy_Creator_Owners;
2103                             break;
2104                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2105                             ac = RAS_and_IAS_Servers;
2106                             break;
2107                         case 1000:      /* first user account */
2108                             size = UNLEN + 1;
2109                             account_name = HeapAlloc(
2110                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2111                             if (GetUserNameW(account_name, &size))
2112                                 ac = account_name;
2113                             else
2114                                 dm = NULL;
2115
2116                             break;
2117                         default:
2118                             dm = NULL;
2119                             break;
2120                         }
2121                     }
2122                 }
2123             }
2124         }
2125     }
2126
2127     if (dm) {
2128         DWORD ac_len = lstrlenW(ac);
2129         DWORD dm_len = lstrlenW(dm);
2130         BOOL status = TRUE;
2131
2132         if (*accountSize > ac_len) {
2133             if (account)
2134                 lstrcpyW(account, ac);
2135         }
2136         if (*domainSize > dm_len) {
2137             if (domain)
2138                 lstrcpyW(domain, dm);
2139         }
2140         if (((*accountSize != 0) && (*accountSize < ac_len)) ||
2141             ((*domainSize != 0) && (*domainSize < dm_len))) {
2142             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2143             status = FALSE;
2144         }
2145         if (*domainSize)
2146             *domainSize = dm_len;
2147         else
2148             *domainSize = dm_len + 1;
2149         if (*accountSize)
2150             *accountSize = ac_len;
2151         else
2152             *accountSize = ac_len + 1;
2153         *name_use = use;
2154         HeapFree(GetProcessHeap(), 0, account_name);
2155         HeapFree(GetProcessHeap(), 0, computer_name);
2156         return status;
2157     }
2158
2159     HeapFree(GetProcessHeap(), 0, account_name);
2160     HeapFree(GetProcessHeap(), 0, computer_name);
2161     SetLastError(ERROR_NONE_MAPPED);
2162     return FALSE;
2163 }
2164
2165 /******************************************************************************
2166  * SetFileSecurityA [ADVAPI32.@]
2167  *
2168  * See SetFileSecurityW.
2169  */
2170 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2171                                 SECURITY_INFORMATION RequestedInformation,
2172                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2173 {
2174     DWORD len;
2175     BOOL r;
2176     LPWSTR name = NULL;
2177
2178     if( lpFileName )
2179     {
2180         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2181         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2182         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2183     }
2184
2185     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2186     HeapFree( GetProcessHeap(), 0, name );
2187
2188     return r;
2189 }
2190
2191 /******************************************************************************
2192  * SetFileSecurityW [ADVAPI32.@]
2193  *
2194  * Sets the security of a file or directory.
2195  *
2196  * PARAMS
2197  *   lpFileName           []
2198  *   RequestedInformation []
2199  *   pSecurityDescriptor  []
2200  *
2201  * RETURNS
2202  *  Success: TRUE.
2203  *  Failure: FALSE.
2204  */
2205 BOOL WINAPI
2206 SetFileSecurityW( LPCWSTR lpFileName,
2207                     SECURITY_INFORMATION RequestedInformation,
2208                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2209 {
2210     HANDLE file;
2211     DWORD access = 0;
2212     NTSTATUS status;
2213
2214     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2215           pSecurityDescriptor );
2216
2217     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2218         RequestedInformation & GROUP_SECURITY_INFORMATION)
2219         access |= WRITE_OWNER;
2220     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2221         access |= ACCESS_SYSTEM_SECURITY;
2222     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2223         access |= WRITE_DAC;
2224
2225     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2226                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2227     if (file == INVALID_HANDLE_VALUE)
2228         return FALSE;
2229
2230     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2231     CloseHandle( file );
2232     return set_ntstatus( status );
2233 }
2234
2235 /******************************************************************************
2236  * QueryWindows31FilesMigration [ADVAPI32.@]
2237  *
2238  * PARAMS
2239  *   x1 []
2240  */
2241 BOOL WINAPI
2242 QueryWindows31FilesMigration( DWORD x1 )
2243 {
2244         FIXME("(%d):stub\n",x1);
2245         return TRUE;
2246 }
2247
2248 /******************************************************************************
2249  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2250  *
2251  * PARAMS
2252  *   x1 []
2253  *   x2 []
2254  *   x3 []
2255  *   x4 []
2256  */
2257 BOOL WINAPI
2258 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2259                                                DWORD x4 )
2260 {
2261         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2262         return TRUE;
2263 }
2264
2265 /******************************************************************************
2266  * NotifyBootConfigStatus [ADVAPI32.@]
2267  *
2268  * PARAMS
2269  *   x1 []
2270  */
2271 BOOL WINAPI
2272 NotifyBootConfigStatus( BOOL x1 )
2273 {
2274         FIXME("(0x%08d):stub\n",x1);
2275         return 1;
2276 }
2277
2278 /******************************************************************************
2279  * RevertToSelf [ADVAPI32.@]
2280  *
2281  * Ends the impersonation of a user.
2282  *
2283  * PARAMS
2284  *   void []
2285  *
2286  * RETURNS
2287  *  Success: TRUE.
2288  *  Failure: FALSE.
2289  */
2290 BOOL WINAPI
2291 RevertToSelf( void )
2292 {
2293     HANDLE Token = NULL;
2294     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2295         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2296 }
2297
2298 /******************************************************************************
2299  * ImpersonateSelf [ADVAPI32.@]
2300  *
2301  * Makes an impersonation token that represents the process user and assigns
2302  * to the current thread.
2303  *
2304  * PARAMS
2305  *  ImpersonationLevel [I] Level at which to impersonate.
2306  *
2307  * RETURNS
2308  *  Success: TRUE.
2309  *  Failure: FALSE.
2310  */
2311 BOOL WINAPI
2312 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2313 {
2314     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2315 }
2316
2317 /******************************************************************************
2318  * ImpersonateLoggedOnUser [ADVAPI32.@]
2319  */
2320 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2321 {
2322     DWORD size;
2323     NTSTATUS Status;
2324     HANDLE ImpersonationToken;
2325     TOKEN_TYPE Type;
2326     static BOOL warn = TRUE;
2327
2328     if (warn)
2329     {
2330         FIXME( "(%p)\n", hToken );
2331         warn = FALSE;
2332     }
2333     if (!GetTokenInformation( hToken, TokenType, &Type,
2334                               sizeof(TOKEN_TYPE), &size ))
2335         return FALSE;
2336
2337     if (Type == TokenPrimary)
2338     {
2339         OBJECT_ATTRIBUTES ObjectAttributes;
2340
2341         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2342
2343         Status = NtDuplicateToken( hToken,
2344                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2345                                    &ObjectAttributes,
2346                                    SecurityImpersonation,
2347                                    TokenImpersonation,
2348                                    &ImpersonationToken );
2349         if (Status != STATUS_SUCCESS)
2350         {
2351             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2352             SetLastError( RtlNtStatusToDosError( Status ) );
2353             return FALSE;
2354         }
2355     }
2356     else
2357         ImpersonationToken = hToken;
2358
2359     Status = NtSetInformationThread( GetCurrentThread(),
2360                                      ThreadImpersonationToken,
2361                                      &ImpersonationToken,
2362                                      sizeof(ImpersonationToken) );
2363
2364     if (Type == TokenPrimary)
2365         NtClose( ImpersonationToken );
2366
2367     if (Status != STATUS_SUCCESS)
2368     {
2369         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2370         SetLastError( RtlNtStatusToDosError( Status ) );
2371         return FALSE;
2372     }
2373
2374     return TRUE;
2375 }
2376
2377 /******************************************************************************
2378  * AccessCheck [ADVAPI32.@]
2379  */
2380 BOOL WINAPI
2381 AccessCheck(
2382         PSECURITY_DESCRIPTOR SecurityDescriptor,
2383         HANDLE ClientToken,
2384         DWORD DesiredAccess,
2385         PGENERIC_MAPPING GenericMapping,
2386         PPRIVILEGE_SET PrivilegeSet,
2387         LPDWORD PrivilegeSetLength,
2388         LPDWORD GrantedAccess,
2389         LPBOOL AccessStatus)
2390 {
2391     NTSTATUS access_status;
2392     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2393                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2394                                            GrantedAccess, &access_status) );
2395     if (ret) *AccessStatus = set_ntstatus( access_status );
2396     return ret;
2397 }
2398
2399
2400 /******************************************************************************
2401  * AccessCheckByType [ADVAPI32.@]
2402  */
2403 BOOL WINAPI AccessCheckByType(
2404     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2405     PSID PrincipalSelfSid,
2406     HANDLE ClientToken, 
2407     DWORD DesiredAccess, 
2408     POBJECT_TYPE_LIST ObjectTypeList,
2409     DWORD ObjectTypeListLength,
2410     PGENERIC_MAPPING GenericMapping,
2411     PPRIVILEGE_SET PrivilegeSet,
2412     LPDWORD PrivilegeSetLength, 
2413     LPDWORD GrantedAccess,
2414     LPBOOL AccessStatus)
2415 {
2416         FIXME("stub\n");
2417
2418         *AccessStatus = TRUE;
2419
2420         return !*AccessStatus;
2421 }
2422
2423 /******************************************************************************
2424  * MapGenericMask [ADVAPI32.@]
2425  *
2426  * Maps generic access rights into specific access rights according to the
2427  * supplied mapping.
2428  *
2429  * PARAMS
2430  *  AccessMask     [I/O] Access rights.
2431  *  GenericMapping [I] The mapping between generic and specific rights.
2432  *
2433  * RETURNS
2434  *  Nothing.
2435  */
2436 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2437 {
2438     RtlMapGenericMask( AccessMask, GenericMapping );
2439 }
2440
2441 /*************************************************************************
2442  * SetKernelObjectSecurity [ADVAPI32.@]
2443  */
2444 BOOL WINAPI SetKernelObjectSecurity (
2445         IN HANDLE Handle,
2446         IN SECURITY_INFORMATION SecurityInformation,
2447         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2448 {
2449     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2450 }
2451
2452
2453 /******************************************************************************
2454  *  AddAuditAccessAce [ADVAPI32.@]
2455  */
2456 BOOL WINAPI AddAuditAccessAce(
2457     IN OUT PACL pAcl, 
2458     IN DWORD dwAceRevision, 
2459     IN DWORD dwAccessMask, 
2460     IN PSID pSid, 
2461     IN BOOL bAuditSuccess, 
2462     IN BOOL bAuditFailure) 
2463 {
2464     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2465                                               bAuditSuccess, bAuditFailure) ); 
2466 }
2467
2468 /******************************************************************************
2469  *  AddAuditAccessAce [ADVAPI32.@]
2470  */
2471 BOOL WINAPI AddAuditAccessAceEx(
2472     IN OUT PACL pAcl,
2473     IN DWORD dwAceRevision,
2474     IN DWORD dwAceFlags,
2475     IN DWORD dwAccessMask,
2476     IN PSID pSid,
2477     IN BOOL bAuditSuccess,
2478     IN BOOL bAuditFailure)
2479 {
2480     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2481                                               bAuditSuccess, bAuditFailure) );
2482 }
2483
2484 /******************************************************************************
2485  * LookupAccountNameA [ADVAPI32.@]
2486  */
2487 BOOL WINAPI
2488 LookupAccountNameA(
2489         IN LPCSTR system,
2490         IN LPCSTR account,
2491         OUT PSID sid,
2492         OUT LPDWORD cbSid,
2493         LPSTR ReferencedDomainName,
2494         IN OUT LPDWORD cbReferencedDomainName,
2495         OUT PSID_NAME_USE name_use )
2496 {
2497     BOOL ret;
2498     UNICODE_STRING lpSystemW;
2499     UNICODE_STRING lpAccountW;
2500     LPWSTR lpReferencedDomainNameW = NULL;
2501
2502     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2503     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2504
2505     if (ReferencedDomainName)
2506         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2507
2508     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2509         cbReferencedDomainName, name_use);
2510
2511     if (ret && lpReferencedDomainNameW)
2512     {
2513         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2514             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2515     }
2516
2517     RtlFreeUnicodeString(&lpSystemW);
2518     RtlFreeUnicodeString(&lpAccountW);
2519     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2520
2521     return ret;
2522 }
2523
2524 /******************************************************************************
2525  * LookupAccountNameW [ADVAPI32.@]
2526  */
2527 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2528                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2529                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2530 {
2531     /* Default implementation: Always return a default SID */
2532     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2533     BOOL ret;
2534     PSID pSid;
2535     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2536     unsigned int i;
2537     DWORD nameLen;
2538     LPWSTR userName = NULL;
2539     LPCWSTR domainName;
2540
2541     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2542           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2543
2544     if (!ADVAPI_IsLocalComputer(lpSystemName))
2545     {
2546         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2547         return FALSE;
2548     }
2549
2550     if (!lpAccountName || !strcmpW(lpAccountName, Blank))
2551     {
2552         lpAccountName = BUILTIN;
2553     }
2554
2555     /* Check well known SIDs first */
2556
2557     for (i = 0; i < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); i++)
2558     {
2559         if (!strcmpW(lpAccountName, ACCOUNT_SIDS[i].account))
2560         {
2561             DWORD sidLen = SECURITY_MAX_SID_SIZE;
2562
2563             pSid = HeapAlloc(GetProcessHeap(), 0, sidLen);
2564
2565             ret = CreateWellKnownSid(ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen);
2566
2567             if (ret)
2568             {
2569                 if (*cbSid < sidLen)
2570                 {
2571                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2572                     ret = FALSE;
2573                 }
2574                 else if (Sid)
2575                 {
2576                     CopySid(*cbSid, Sid, pSid);
2577                 }
2578
2579                 *cbSid = sidLen;
2580             }
2581
2582             domainName = ACCOUNT_SIDS[i].domain;
2583             nameLen = strlenW(domainName);
2584
2585             if (*cchReferencedDomainName <= nameLen || !ret)
2586             {
2587                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2588                 nameLen += 1;
2589                 ret = FALSE;
2590             }
2591             else if (ReferencedDomainName && domainName)
2592             {
2593                 strcpyW(ReferencedDomainName, domainName);
2594             }
2595
2596             *cchReferencedDomainName = nameLen;
2597
2598             if (ret)
2599             {
2600                 *peUse = ACCOUNT_SIDS[i].name_use;
2601             }
2602
2603             HeapFree(GetProcessHeap(), 0, pSid);
2604
2605             return ret;
2606         }
2607     }
2608
2609     /* Let the current Unix user id masquerade as first Windows user account */
2610
2611     nameLen = UNLEN + 1;
2612
2613     userName = HeapAlloc(GetProcessHeap(), 0, nameLen);
2614
2615     ret = GetUserNameW(userName, &nameLen);
2616
2617     if (ret && strcmpW(lpAccountName, userName) != 0)
2618     {
2619         SetLastError(ERROR_NONE_MAPPED);
2620         ret = FALSE;
2621     }
2622
2623     HeapFree(GetProcessHeap(), 0, userName);
2624
2625     if (!ret)
2626     {
2627         return ret;
2628     }
2629
2630     ret = AllocateAndInitializeSid(&identifierAuthority,
2631         2,
2632         SECURITY_BUILTIN_DOMAIN_RID,
2633         DOMAIN_ALIAS_RID_ADMINS,
2634         0, 0, 0, 0, 0, 0,
2635         &pSid);
2636
2637     if (!ret)
2638        return FALSE;
2639
2640     if (!RtlValidSid(pSid))
2641     {
2642        FreeSid(pSid);
2643        return FALSE;
2644     }
2645
2646     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2647        CopySid(*cbSid, Sid, pSid);
2648     if (*cbSid < GetLengthSid(pSid))
2649     {
2650        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2651        ret = FALSE;
2652     }
2653     *cbSid = GetLengthSid(pSid);
2654
2655     domainName = dm;
2656     nameLen = strlenW(domainName);
2657
2658     if (*cchReferencedDomainName <= nameLen || !ret)
2659     {
2660         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2661         nameLen += 1;
2662         ret = FALSE;
2663     }
2664     else if (ReferencedDomainName)
2665     {
2666         strcpyW(ReferencedDomainName, domainName);
2667     }
2668
2669     *cchReferencedDomainName = nameLen;
2670
2671     if (ret)
2672     {
2673         *peUse = SidTypeUser;
2674     }
2675
2676     FreeSid(pSid);
2677
2678     return ret;
2679 }
2680
2681 /******************************************************************************
2682  * PrivilegeCheck [ADVAPI32.@]
2683  */
2684 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2685 {
2686     BOOL ret;
2687     BOOLEAN Result;
2688
2689     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2690
2691     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2692     if (ret)
2693         *pfResult = Result;
2694     return ret;
2695 }
2696
2697 /******************************************************************************
2698  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2699  */
2700 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2701   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2702   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2703   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2704 {
2705         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2706                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2707                 SecurityDescriptor, DesiredAccess, GenericMapping,
2708                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2709         return TRUE;
2710 }
2711
2712 /******************************************************************************
2713  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2714  */
2715 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2716   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2717   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2718   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2719 {
2720         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2721                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2722                 SecurityDescriptor, DesiredAccess, GenericMapping,
2723                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2724         return TRUE;
2725 }
2726
2727 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2728 {
2729     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2730
2731     return TRUE;
2732 }
2733
2734 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2735 {
2736     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2737
2738     return TRUE;
2739 }
2740
2741 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2742 {
2743     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2744
2745     return TRUE;
2746 }
2747
2748 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2749   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2750   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2751   LPBOOL GenerateOnClose)
2752 {
2753         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2754                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2755         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2756         GenerateOnClose);
2757
2758     return TRUE;
2759 }
2760
2761 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2762   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2763   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2764   LPBOOL GenerateOnClose)
2765 {
2766     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2767         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2768         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2769         GenerateOnClose);
2770
2771     return TRUE;
2772 }
2773
2774 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2775   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2776 {
2777     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2778           DesiredAccess, Privileges, AccessGranted);
2779
2780     return TRUE;
2781 }
2782
2783 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2784   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2785 {
2786     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2787           DesiredAccess, Privileges, AccessGranted);
2788
2789     return TRUE;
2790 }
2791
2792 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2793                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2794 {
2795     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2796           ClientToken, Privileges, AccessGranted);
2797
2798     return TRUE;
2799 }
2800
2801 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2802                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2803 {
2804     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2805           ClientToken, Privileges, AccessGranted);
2806
2807     return TRUE;
2808 }
2809
2810 /******************************************************************************
2811  * GetSecurityInfo [ADVAPI32.@]
2812  *
2813  * Retrieves a copy of the security descriptor associated with an object.
2814  *
2815  * PARAMS
2816  *  hObject              [I] A handle for the object.
2817  *  ObjectType           [I] The type of object.
2818  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
2819  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
2820  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
2821  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
2822  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
2823  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
2824  *                           which must be freed with LocalFree.
2825  *
2826  * RETURNS
2827  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
2828  */
2829 DWORD WINAPI GetSecurityInfo(
2830     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2831     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2832     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2833     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2834 )
2835 {
2836     PSECURITY_DESCRIPTOR sd;
2837     NTSTATUS status;
2838     ULONG n1, n2;
2839     BOOL present, defaulted;
2840
2841     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
2842     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
2843         return RtlNtStatusToDosError(status);
2844
2845     sd = LocalAlloc(0, n1);
2846     if (!sd)
2847         return ERROR_NOT_ENOUGH_MEMORY;
2848
2849     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
2850     if (status != STATUS_SUCCESS)
2851     {
2852         LocalFree(sd);
2853         return RtlNtStatusToDosError(status);
2854     }
2855
2856     if (ppsidOwner)
2857     {
2858         *ppsidOwner = NULL;
2859         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
2860     }
2861     if (ppsidGroup)
2862     {
2863         *ppsidGroup = NULL;
2864         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
2865     }
2866     if (ppDacl)
2867     {
2868         *ppDacl = NULL;
2869         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
2870     }
2871     if (ppSacl)
2872     {
2873         *ppSacl = NULL;
2874         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
2875     }
2876     if (ppSecurityDescriptor)
2877         *ppSecurityDescriptor = sd;
2878
2879     return ERROR_SUCCESS;
2880 }
2881
2882 /******************************************************************************
2883  * GetSecurityInfoExW [ADVAPI32.@]
2884  */
2885 DWORD WINAPI GetSecurityInfoExW(
2886         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2887         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2888         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2889         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2890 )
2891 {
2892   FIXME("stub!\n");
2893   return ERROR_BAD_PROVIDER; 
2894 }
2895
2896 /******************************************************************************
2897  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2898  */
2899 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2900                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2901                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2902 {
2903     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2904           AccessPermissions, AccessMode, Inheritance);
2905
2906     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2907     pExplicitAccess->grfAccessMode = AccessMode;
2908     pExplicitAccess->grfInheritance = Inheritance;
2909
2910     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2911     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2912     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2913     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2914     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2915 }
2916
2917 /******************************************************************************
2918  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2919  */
2920 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2921                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2922                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2923 {
2924     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2925           AccessPermissions, AccessMode, Inheritance);
2926
2927     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2928     pExplicitAccess->grfAccessMode = AccessMode;
2929     pExplicitAccess->grfInheritance = Inheritance;
2930
2931     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2932     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2933     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2934     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2935     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2936 }
2937
2938 /******************************************************************************
2939  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2940  */
2941 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2942                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2943                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2944 {
2945     DWORD ObjectsPresent = 0;
2946
2947     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2948           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2949
2950     /* Fill the OBJECTS_AND_NAME structure */
2951     pObjName->ObjectType = ObjectType;
2952     if (ObjectTypeName != NULL)
2953     {
2954         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2955     }
2956
2957     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2958     if (InheritedObjectTypeName != NULL)
2959     {
2960         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2961     }
2962
2963     pObjName->ObjectsPresent = ObjectsPresent;
2964     pObjName->ptstrName = Name;
2965
2966     /* Fill the TRUSTEE structure */
2967     pTrustee->pMultipleTrustee = NULL;
2968     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2969     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2970     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2971     pTrustee->ptstrName = (LPSTR)pObjName;
2972 }
2973
2974 /******************************************************************************
2975  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2976  */
2977 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2978                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2979                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2980 {
2981     DWORD ObjectsPresent = 0;
2982
2983     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2984           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2985
2986     /* Fill the OBJECTS_AND_NAME structure */
2987     pObjName->ObjectType = ObjectType;
2988     if (ObjectTypeName != NULL)
2989     {
2990         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2991     }
2992
2993     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2994     if (InheritedObjectTypeName != NULL)
2995     {
2996         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2997     }
2998
2999     pObjName->ObjectsPresent = ObjectsPresent;
3000     pObjName->ptstrName = Name;
3001
3002     /* Fill the TRUSTEE structure */
3003     pTrustee->pMultipleTrustee = NULL;
3004     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3005     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3006     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3007     pTrustee->ptstrName = (LPWSTR)pObjName;
3008 }
3009
3010 /******************************************************************************
3011  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3012  */
3013 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3014                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3015 {
3016     DWORD ObjectsPresent = 0;
3017
3018     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3019
3020     /* Fill the OBJECTS_AND_SID structure */
3021     if (pObjectGuid != NULL)
3022     {
3023         pObjSid->ObjectTypeGuid = *pObjectGuid;
3024         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3025     }
3026     else
3027     {
3028         ZeroMemory(&pObjSid->ObjectTypeGuid,
3029                    sizeof(GUID));
3030     }
3031
3032     if (pInheritedObjectGuid != NULL)
3033     {
3034         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3035         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3036     }
3037     else
3038     {
3039         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3040                    sizeof(GUID));
3041     }
3042
3043     pObjSid->ObjectsPresent = ObjectsPresent;
3044     pObjSid->pSid = pSid;
3045
3046     /* Fill the TRUSTEE structure */
3047     pTrustee->pMultipleTrustee = NULL;
3048     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3049     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3050     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3051     pTrustee->ptstrName = (LPSTR) pObjSid;
3052 }
3053
3054 /******************************************************************************
3055  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3056  */
3057 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3058                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3059 {
3060     DWORD ObjectsPresent = 0;
3061
3062     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3063
3064     /* Fill the OBJECTS_AND_SID structure */
3065     if (pObjectGuid != NULL)
3066     {
3067         pObjSid->ObjectTypeGuid = *pObjectGuid;
3068         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3069     }
3070     else
3071     {
3072         ZeroMemory(&pObjSid->ObjectTypeGuid,
3073                    sizeof(GUID));
3074     }
3075
3076     if (pInheritedObjectGuid != NULL)
3077     {
3078         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3079         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3080     }
3081     else
3082     {
3083         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3084                    sizeof(GUID));
3085     }
3086
3087     pObjSid->ObjectsPresent = ObjectsPresent;
3088     pObjSid->pSid = pSid;
3089
3090     /* Fill the TRUSTEE structure */
3091     pTrustee->pMultipleTrustee = NULL;
3092     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3093     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3094     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3095     pTrustee->ptstrName = (LPWSTR) pObjSid;
3096 }
3097
3098 /******************************************************************************
3099  * BuildTrusteeWithSidA [ADVAPI32.@]
3100  */
3101 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3102 {
3103     TRACE("%p %p\n", pTrustee, pSid);
3104
3105     pTrustee->pMultipleTrustee = NULL;
3106     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3107     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3108     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3109     pTrustee->ptstrName = (LPSTR) pSid;
3110 }
3111
3112 /******************************************************************************
3113  * BuildTrusteeWithSidW [ADVAPI32.@]
3114  */
3115 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3116 {
3117     TRACE("%p %p\n", pTrustee, pSid);
3118
3119     pTrustee->pMultipleTrustee = NULL;
3120     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3121     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3122     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3123     pTrustee->ptstrName = (LPWSTR) pSid;
3124 }
3125
3126 /******************************************************************************
3127  * BuildTrusteeWithNameA [ADVAPI32.@]
3128  */
3129 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3130 {
3131     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3132
3133     pTrustee->pMultipleTrustee = NULL;
3134     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3135     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3136     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3137     pTrustee->ptstrName = name;
3138 }
3139
3140 /******************************************************************************
3141  * BuildTrusteeWithNameW [ADVAPI32.@]
3142  */
3143 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3144 {
3145     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3146
3147     pTrustee->pMultipleTrustee = NULL;
3148     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3149     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3150     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3151     pTrustee->ptstrName = name;
3152 }
3153
3154 /****************************************************************************** 
3155  * GetTrusteeFormA [ADVAPI32.@] 
3156  */ 
3157 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
3158 {  
3159     TRACE("(%p)\n", pTrustee); 
3160   
3161     if (!pTrustee) 
3162         return TRUSTEE_BAD_FORM; 
3163   
3164     return pTrustee->TrusteeForm; 
3165 }  
3166   
3167 /****************************************************************************** 
3168  * GetTrusteeFormW [ADVAPI32.@] 
3169  */ 
3170 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
3171 {  
3172     TRACE("(%p)\n", pTrustee); 
3173   
3174     if (!pTrustee) 
3175         return TRUSTEE_BAD_FORM; 
3176   
3177     return pTrustee->TrusteeForm; 
3178 }  
3179   
3180 /****************************************************************************** 
3181  * GetTrusteeNameA [ADVAPI32.@] 
3182  */ 
3183 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
3184 {  
3185     TRACE("(%p)\n", pTrustee); 
3186   
3187     if (!pTrustee) 
3188         return NULL; 
3189   
3190     return pTrustee->ptstrName; 
3191 }  
3192   
3193 /****************************************************************************** 
3194  * GetTrusteeNameW [ADVAPI32.@] 
3195  */ 
3196 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
3197 {  
3198     TRACE("(%p)\n", pTrustee); 
3199   
3200     if (!pTrustee) 
3201         return NULL; 
3202   
3203     return pTrustee->ptstrName; 
3204 }  
3205   
3206 /****************************************************************************** 
3207  * GetTrusteeTypeA [ADVAPI32.@] 
3208  */ 
3209 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
3210 {  
3211     TRACE("(%p)\n", pTrustee); 
3212   
3213     if (!pTrustee) 
3214         return TRUSTEE_IS_UNKNOWN; 
3215   
3216     return pTrustee->TrusteeType; 
3217 }  
3218   
3219 /****************************************************************************** 
3220  * GetTrusteeTypeW [ADVAPI32.@] 
3221  */ 
3222 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
3223 {  
3224     TRACE("(%p)\n", pTrustee); 
3225   
3226     if (!pTrustee) 
3227         return TRUSTEE_IS_UNKNOWN; 
3228   
3229     return pTrustee->TrusteeType; 
3230
3231  
3232 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3233                                DWORD nAclInformationLength,
3234                                ACL_INFORMATION_CLASS dwAclInformationClass )
3235 {
3236     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3237           nAclInformationLength, dwAclInformationClass);
3238
3239     return TRUE;
3240 }
3241
3242 /******************************************************************************
3243  * SetEntriesInAclA [ADVAPI32.@]
3244  */
3245 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3246                                PACL OldAcl, PACL* NewAcl )
3247 {
3248     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
3249     if (NewAcl)
3250          *NewAcl = NULL;
3251     return ERROR_SUCCESS;
3252 }
3253
3254 /******************************************************************************
3255  * SetEntriesInAclW [ADVAPI32.@]
3256  */
3257 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3258                                PACL OldAcl, PACL* NewAcl )
3259 {
3260     ULONG i;
3261     PSID *ppsid;
3262     DWORD ret = ERROR_SUCCESS;
3263     DWORD acl_size = sizeof(ACL);
3264     NTSTATUS status;
3265
3266     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3267
3268     *NewAcl = NULL;
3269
3270     if (!count && !OldAcl)
3271         return ERROR_SUCCESS;
3272
3273     /* allocate array of maximum sized sids allowed */
3274     ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3275     if (!ppsid)
3276         return ERROR_OUTOFMEMORY;
3277
3278     for (i = 0; i < count; i++)
3279     {
3280         ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3281
3282         TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3283               "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3284               "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3285               pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3286               pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3287               pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3288               pEntries[i].Trustee.ptstrName);
3289
3290         if (pEntries[i].Trustee.MultipleTrusteeOperation != NO_MULTIPLE_TRUSTEE)
3291         {
3292             WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3293             ret = ERROR_INVALID_PARAMETER;
3294             goto exit;
3295         }
3296
3297         switch (pEntries[i].Trustee.TrusteeForm)
3298         {
3299         case TRUSTEE_IS_SID:
3300             if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3301                          ppsid[i], pEntries[i].Trustee.ptstrName))
3302             {
3303                 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3304                 ret = ERROR_INVALID_PARAMETER;
3305                 goto exit;
3306             }
3307             break;
3308         case TRUSTEE_IS_NAME:
3309         {
3310             DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3311             DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3312             SID_NAME_USE use;
3313             if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3314             {
3315                 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3316                 ret = ERROR_INVALID_PARAMETER;
3317                 goto exit;
3318             }
3319             break;
3320         }
3321         case TRUSTEE_IS_OBJECTS_AND_SID:
3322             FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3323             break;
3324         case TRUSTEE_IS_OBJECTS_AND_NAME:
3325             FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3326             break;
3327         default:
3328             WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3329             ret = ERROR_INVALID_PARAMETER;
3330             goto exit;
3331         }
3332
3333         /* Note: we overestimate the ACL size here as a tradeoff between
3334          * instructions (simplicity) and memory */
3335         switch (pEntries[i].grfAccessMode)
3336         {
3337         case GRANT_ACCESS:
3338         case SET_ACCESS:
3339             acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3340             break;
3341         case DENY_ACCESS:
3342             acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3343             break;
3344         case SET_AUDIT_SUCCESS:
3345         case SET_AUDIT_FAILURE:
3346             acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3347             break;
3348         case REVOKE_ACCESS:
3349             break;
3350         default:
3351             WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3352             ret = ERROR_INVALID_PARAMETER;
3353             goto exit;
3354         }
3355     }
3356
3357     if (OldAcl)
3358     {
3359         ACL_SIZE_INFORMATION size_info;
3360
3361         status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3362         if (status != STATUS_SUCCESS)
3363         {
3364             ret = RtlNtStatusToDosError(status);
3365             goto exit;
3366         }
3367         acl_size += size_info.AclBytesInUse - sizeof(ACL);
3368     }
3369
3370     *NewAcl = LocalAlloc(0, acl_size);
3371     if (!*NewAcl)
3372     {
3373         ret = ERROR_OUTOFMEMORY;
3374         goto exit;
3375     }
3376
3377     status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3378     if (status != STATUS_SUCCESS)
3379     {
3380         ret = RtlNtStatusToDosError(status);
3381         goto exit;
3382     }
3383
3384     for (i = 0; i < count; i++)
3385     {
3386         switch (pEntries[i].grfAccessMode)
3387         {
3388         case GRANT_ACCESS:
3389             status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3390                                               pEntries[i].grfInheritance,
3391                                               pEntries[i].grfAccessPermissions,
3392                                               ppsid[i]);
3393             break;
3394         case SET_ACCESS:
3395         {
3396             ULONG j;
3397             BOOL add = TRUE;
3398             if (OldAcl)
3399             {
3400                 for (j = 0; ; j++)
3401                 {
3402                     const ACE_HEADER *existing_ace_header;
3403                     status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3404                     if (status != STATUS_SUCCESS)
3405                         break;
3406                     if (pEntries[i].grfAccessMode == SET_ACCESS &&
3407                         existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3408                         EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3409                     {
3410                         add = FALSE;
3411                         break;
3412                     }
3413                 }
3414             }
3415             if (add)
3416                 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3417                                                   pEntries[i].grfInheritance,
3418                                                   pEntries[i].grfAccessPermissions,
3419                                                   ppsid[i]);
3420             break;
3421         }
3422         case DENY_ACCESS:
3423             status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3424                                              pEntries[i].grfInheritance,
3425                                              pEntries[i].grfAccessPermissions,
3426                                              ppsid[i]);
3427             break;
3428         case SET_AUDIT_SUCCESS:
3429             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3430                                             pEntries[i].grfInheritance,
3431                                             pEntries[i].grfAccessPermissions,
3432                                             ppsid[i], TRUE, FALSE);
3433             break;
3434         case SET_AUDIT_FAILURE:
3435             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3436                                             pEntries[i].grfInheritance,
3437                                             pEntries[i].grfAccessPermissions,
3438                                             ppsid[i], FALSE, TRUE);
3439             break;
3440         default:
3441             FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3442         }
3443     }
3444
3445     if (OldAcl)
3446     {
3447         for (i = 0; ; i++)
3448         {
3449             BOOL add = TRUE;
3450             ULONG j;
3451             const ACE_HEADER *old_ace_header;
3452             status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3453             if (status != STATUS_SUCCESS) break;
3454             for (j = 0; j < count; j++)
3455             {
3456                 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3457                     old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3458                     EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3459                 {
3460                     status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3461                     add = FALSE;
3462                     break;
3463                 }
3464                 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3465                 {
3466                     switch (old_ace_header->AceType)
3467                     {
3468                     case ACCESS_ALLOWED_ACE_TYPE:
3469                         if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3470                             add = FALSE;
3471                         break;
3472                     case ACCESS_DENIED_ACE_TYPE:
3473                         if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3474                             add = FALSE;
3475                         break;
3476                     case SYSTEM_AUDIT_ACE_TYPE:
3477                         if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3478                             add = FALSE;
3479                         break;
3480                     case SYSTEM_ALARM_ACE_TYPE:
3481                         if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3482                             add = FALSE;
3483                         break;
3484                     default:
3485                         FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3486                     }
3487
3488                     if (!add)
3489                         break;
3490                 }
3491             }
3492             if (add)
3493                 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3494             if (status != STATUS_SUCCESS)
3495             {
3496                 WARN("RtlAddAce failed with error 0x%08x\n", status);
3497                 ret = RtlNtStatusToDosError(status);
3498                 break;
3499             }
3500         }
3501     }
3502
3503 exit:
3504     HeapFree(GetProcessHeap(), 0, ppsid);
3505     return ret;
3506 }
3507
3508 /******************************************************************************
3509  * SetNamedSecurityInfoA [ADVAPI32.@]
3510  */
3511 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3512         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3513         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3514 {
3515     DWORD len;
3516     LPWSTR wstr = NULL;
3517     DWORD r;
3518
3519     TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3520            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3521
3522     if( pObjectName )
3523     {
3524         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3525         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3526         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3527     }
3528
3529     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3530                            psidGroup, pDacl, pSacl );
3531
3532     HeapFree( GetProcessHeap(), 0, wstr );
3533
3534     return r;
3535 }
3536
3537 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3538     PSECURITY_DESCRIPTOR ModificationDescriptor,
3539     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3540     PGENERIC_MAPPING GenericMapping,
3541     HANDLE Token )
3542 {
3543     FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3544           ObjectsSecurityDescriptor, GenericMapping, Token);
3545
3546     return TRUE;
3547 }
3548
3549 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3550 {
3551     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3552 }
3553
3554 /******************************************************************************
3555  * AreAnyAccessesGranted [ADVAPI32.@]
3556  *
3557  * Determines whether or not any of a set of specified access permissions have
3558  * been granted or not.
3559  *
3560  * PARAMS
3561  *   GrantedAccess [I] The permissions that have been granted.
3562  *   DesiredAccess [I] The permissions that you want to have.
3563  *
3564  * RETURNS
3565  *   Nonzero if any of the permissions have been granted, zero if none of the
3566  *   permissions have been granted.
3567  */
3568
3569 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3570 {
3571     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3572 }
3573
3574 /******************************************************************************
3575  * SetNamedSecurityInfoW [ADVAPI32.@]
3576  */
3577 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3578         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3579         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3580 {
3581     FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3582            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3583     return ERROR_SUCCESS;
3584 }
3585
3586 /******************************************************************************
3587  * GetExplicitEntriesFromAclA [ADVAPI32.@]
3588  */
3589 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3590         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3591 {
3592     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3593     return ERROR_CALL_NOT_IMPLEMENTED;
3594 }
3595
3596 /******************************************************************************
3597  * GetExplicitEntriesFromAclW [ADVAPI32.@]
3598  */
3599 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3600         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3601 {
3602     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3603     return ERROR_CALL_NOT_IMPLEMENTED;
3604 }
3605
3606 /******************************************************************************
3607  * GetAuditedPermissionsFromAclA [ADVAPI32.@]
3608  */
3609 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3610         PACCESS_MASK pFailedAuditRights)
3611 {
3612     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3613     return ERROR_CALL_NOT_IMPLEMENTED;
3614
3615 }
3616
3617 /******************************************************************************
3618  * GetAuditedPermissionsFromAclW [ADVAPI32.@]
3619  */
3620 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
3621         PACCESS_MASK pFailedAuditRights)
3622 {
3623     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
3624     return ERROR_CALL_NOT_IMPLEMENTED;
3625
3626 }
3627
3628 /******************************************************************************
3629  * ParseAclStringFlags
3630  */
3631 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3632 {
3633     DWORD flags = 0;
3634     LPCWSTR szAcl = *StringAcl;
3635
3636     while (*szAcl != '(')
3637     {
3638         if (*szAcl == 'P')
3639         {
3640             flags |= SE_DACL_PROTECTED;
3641         }
3642         else if (*szAcl == 'A')
3643         {
3644             szAcl++;
3645             if (*szAcl == 'R')
3646                 flags |= SE_DACL_AUTO_INHERIT_REQ;
3647             else if (*szAcl == 'I')
3648                 flags |= SE_DACL_AUTO_INHERITED;
3649         }
3650         szAcl++;
3651     }
3652
3653     *StringAcl = szAcl;
3654     return flags;
3655 }
3656
3657 /******************************************************************************
3658  * ParseAceStringType
3659  */
3660 static const ACEFLAG AceType[] =
3661 {
3662     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
3663     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
3664     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3665     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
3666     /*
3667     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3668     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
3669     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
3670     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3671     */
3672     { NULL, 0 },
3673 };
3674
3675 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3676 {
3677     UINT len = 0;
3678     LPCWSTR szAcl = *StringAcl;
3679     const ACEFLAG *lpaf = AceType;
3680
3681     while (lpaf->wstr &&
3682         (len = strlenW(lpaf->wstr)) &&
3683         strncmpW(lpaf->wstr, szAcl, len))
3684         lpaf++;
3685
3686     if (!lpaf->wstr)
3687         return 0;
3688
3689     *StringAcl += len;
3690     return lpaf->value;
3691 }
3692
3693
3694 /******************************************************************************
3695  * ParseAceStringFlags
3696  */
3697 static const ACEFLAG AceFlags[] =
3698 {
3699     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3700     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
3701     { SDDL_INHERITED,         INHERITED_ACE },
3702     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
3703     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
3704     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
3705     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
3706     { NULL, 0 },
3707 };
3708
3709 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3710 {
3711     UINT len = 0;
3712     BYTE flags = 0;
3713     LPCWSTR szAcl = *StringAcl;
3714
3715     while (*szAcl != ';')
3716     {
3717         const ACEFLAG *lpaf = AceFlags;
3718
3719         while (lpaf->wstr &&
3720                (len = strlenW(lpaf->wstr)) &&
3721                strncmpW(lpaf->wstr, szAcl, len))
3722             lpaf++;
3723
3724         if (!lpaf->wstr)
3725             return 0;
3726
3727         flags |= lpaf->value;
3728         szAcl += len;
3729     }
3730
3731     *StringAcl = szAcl;
3732     return flags;
3733 }
3734
3735
3736 /******************************************************************************
3737  * ParseAceStringRights
3738  */
3739 static const ACEFLAG AceRights[] =
3740 {
3741     { SDDL_GENERIC_ALL,     GENERIC_ALL },
3742     { SDDL_GENERIC_READ,    GENERIC_READ },
3743     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
3744     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3745
3746     { SDDL_READ_CONTROL,    READ_CONTROL },
3747     { SDDL_STANDARD_DELETE, DELETE },
3748     { SDDL_WRITE_DAC,       WRITE_DAC },
3749     { SDDL_WRITE_OWNER,     WRITE_OWNER },
3750
3751     { SDDL_READ_PROPERTY,   ADS_RIGHT_DS_READ_PROP},
3752     { SDDL_WRITE_PROPERTY,  ADS_RIGHT_DS_WRITE_PROP},
3753     { SDDL_CREATE_CHILD,    ADS_RIGHT_DS_CREATE_CHILD},
3754     { SDDL_DELETE_CHILD,    ADS_RIGHT_DS_DELETE_CHILD},
3755     { SDDL_LIST_CHILDREN,   ADS_RIGHT_ACTRL_DS_LIST},
3756     { SDDL_SELF_WRITE,      ADS_RIGHT_DS_SELF},
3757     { SDDL_LIST_OBJECT,     ADS_RIGHT_DS_LIST_OBJECT},
3758     { SDDL_DELETE_TREE,     ADS_RIGHT_DS_DELETE_TREE},
3759     { SDDL_CONTROL_ACCESS,  ADS_RIGHT_DS_CONTROL_ACCESS},
3760
3761     { SDDL_FILE_ALL,        FILE_ALL_ACCESS },
3762     { SDDL_FILE_READ,       FILE_GENERIC_READ },
3763     { SDDL_FILE_WRITE,      FILE_GENERIC_WRITE },
3764     { SDDL_FILE_EXECUTE,    FILE_GENERIC_EXECUTE },
3765
3766     { SDDL_KEY_ALL,         KEY_ALL_ACCESS },
3767     { SDDL_KEY_READ,        KEY_READ },
3768     { SDDL_KEY_WRITE,       KEY_WRITE },
3769     { SDDL_KEY_EXECUTE,     KEY_EXECUTE },
3770     { NULL, 0 },
3771 };
3772
3773 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3774 {
3775     UINT len = 0;
3776     DWORD rights = 0;
3777     LPCWSTR szAcl = *StringAcl;
3778
3779     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3780     {
3781         LPCWSTR p = szAcl;
3782
3783         while (*p && *p != ';')
3784             p++;
3785
3786         if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
3787         {
3788             rights = strtoulW(szAcl, NULL, 16);
3789             szAcl = p;
3790         }
3791         else
3792             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3793     }
3794     else
3795     {
3796         while (*szAcl != ';')
3797         {
3798             const ACEFLAG *lpaf = AceRights;
3799
3800             while (lpaf->wstr &&
3801                (len = strlenW(lpaf->wstr)) &&
3802                strncmpW(lpaf->wstr, szAcl, len))
3803             {
3804                lpaf++;
3805             }
3806
3807             if (!lpaf->wstr)
3808                 return 0;
3809
3810             rights |= lpaf->value;
3811             szAcl += len;
3812         }
3813     }
3814
3815     *StringAcl = szAcl;
3816     return rights;
3817 }
3818
3819
3820 /******************************************************************************
3821  * ParseStringAclToAcl
3822  * 
3823  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
3824  */
3825 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
3826     PACL pAcl, LPDWORD cBytes)
3827 {
3828     DWORD val;
3829     DWORD sidlen;
3830     DWORD length = sizeof(ACL);
3831     DWORD acesize = 0;
3832     DWORD acecount = 0;
3833     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3834
3835     TRACE("%s\n", debugstr_w(StringAcl));
3836
3837     if (!StringAcl)
3838         return FALSE;
3839
3840     if (pAcl) /* pAce is only useful if we're setting values */
3841         pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
3842
3843     /* Parse ACL flags */
3844     *lpdwFlags = ParseAclStringFlags(&StringAcl);
3845
3846     /* Parse ACE */
3847     while (*StringAcl == '(')
3848     {
3849         StringAcl++;
3850
3851         /* Parse ACE type */
3852         val = ParseAceStringType(&StringAcl);
3853         if (pAce)
3854             pAce->Header.AceType = (BYTE) val;
3855         if (*StringAcl != ';')
3856             goto lerr;
3857         StringAcl++;
3858
3859         /* Parse ACE flags */
3860         val = ParseAceStringFlags(&StringAcl);
3861         if (pAce)
3862             pAce->Header.AceFlags = (BYTE) val;
3863         if (*StringAcl != ';')
3864             goto lerr;
3865         StringAcl++;
3866
3867         /* Parse ACE rights */
3868         val = ParseAceStringRights(&StringAcl);
3869         if (pAce)
3870             pAce->Mask = val;
3871         if (*StringAcl != ';')
3872             goto lerr;
3873         StringAcl++;
3874
3875         /* Parse ACE object guid */
3876         if (*StringAcl != ';')
3877         {
3878             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3879             goto lerr;
3880         }
3881         StringAcl++;
3882
3883         /* Parse ACE inherit object guid */
3884         if (*StringAcl != ';')
3885         {
3886             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3887             goto lerr;
3888         }
3889         StringAcl++;
3890
3891         /* Parse ACE account sid */
3892         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3893         {
3894             while (*StringAcl && *StringAcl != ')')
3895                 StringAcl++;
3896         }
3897
3898         if (*StringAcl != ')')
3899             goto lerr;
3900         StringAcl++;
3901
3902         acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3903         length += acesize;
3904         if (pAce)
3905         {
3906             pAce->Header.AceSize = acesize;
3907             pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
3908         }
3909         acecount++;
3910     }
3911
3912     *cBytes = length;
3913
3914     if (length > 0xffff)
3915     {
3916         ERR("ACL too large\n");
3917         goto lerr;
3918     }
3919
3920     if (pAcl)
3921     {
3922         pAcl->AclRevision = ACL_REVISION;
3923         pAcl->Sbz1 = 0;
3924         pAcl->AclSize = length;
3925         pAcl->AceCount = acecount++;
3926         pAcl->Sbz2 = 0;
3927     }
3928     return TRUE;
3929
3930 lerr:
3931     SetLastError(ERROR_INVALID_ACL);
3932     WARN("Invalid ACE string format\n");
3933     return FALSE;
3934 }
3935
3936
3937 /******************************************************************************
3938  * ParseStringSecurityDescriptorToSecurityDescriptor
3939  */
3940 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3941     LPCWSTR StringSecurityDescriptor,
3942     SECURITY_DESCRIPTOR* SecurityDescriptor,
3943     LPDWORD cBytes)
3944 {
3945     BOOL bret = FALSE;
3946     WCHAR toktype;
3947     WCHAR tok[MAX_PATH];
3948     LPCWSTR lptoken;
3949     LPBYTE lpNext = NULL;
3950     DWORD len;
3951
3952     *cBytes = sizeof(SECURITY_DESCRIPTOR);
3953
3954     if (SecurityDescriptor)
3955         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3956
3957     while (*StringSecurityDescriptor)
3958     {
3959         toktype = *StringSecurityDescriptor;
3960
3961         /* Expect char identifier followed by ':' */
3962         StringSecurityDescriptor++;
3963         if (*StringSecurityDescriptor != ':')
3964         {
3965             SetLastError(ERROR_INVALID_PARAMETER);
3966             goto lend;
3967         }
3968         StringSecurityDescriptor++;
3969
3970         /* Extract token */
3971         lptoken = StringSecurityDescriptor;
3972         while (*lptoken && *lptoken != ':')
3973             lptoken++;
3974
3975         if (*lptoken)
3976             lptoken--;
3977
3978         len = lptoken - StringSecurityDescriptor;
3979         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3980         tok[len] = 0;
3981
3982         switch (toktype)
3983         {
3984             case 'O':
3985             {
3986                 DWORD bytes;
3987
3988                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3989                     goto lend;
3990
3991                 if (SecurityDescriptor)
3992                 {
3993                     SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3994                     lpNext += bytes; /* Advance to next token */
3995                 }
3996
3997                 *cBytes += bytes;
3998
3999                 break;
4000             }
4001
4002             case 'G':
4003             {
4004                 DWORD bytes;
4005
4006                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
4007                     goto lend;
4008
4009                 if (SecurityDescriptor)
4010                 {
4011                     SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
4012                     lpNext += bytes; /* Advance to next token */
4013                 }
4014
4015                 *cBytes += bytes;
4016
4017                 break;
4018             }
4019
4020             case 'D':
4021             {
4022                 DWORD flags;
4023                 DWORD bytes;
4024
4025                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4026                     goto lend;
4027
4028                 if (SecurityDescriptor)
4029                 {
4030                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4031                     SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4032                     lpNext += bytes; /* Advance to next token */
4033                 }
4034
4035                 *cBytes += bytes;
4036
4037                 break;
4038             }
4039
4040             case 'S':
4041             {
4042                 DWORD flags;
4043                 DWORD bytes;
4044
4045                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4046                     goto lend;
4047
4048                 if (SecurityDescriptor)
4049                 {
4050                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4051                     SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
4052                     lpNext += bytes; /* Advance to next token */
4053                 }
4054
4055                 *cBytes += bytes;
4056
4057                 break;
4058             }
4059
4060             default:
4061                 FIXME("Unknown token\n");
4062                 SetLastError(ERROR_INVALID_PARAMETER);
4063                 goto lend;
4064         }
4065
4066         StringSecurityDescriptor = lptoken;
4067     }
4068
4069     bret = TRUE;
4070
4071 lend:
4072     return bret;
4073 }
4074
4075 /******************************************************************************
4076  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4077  */
4078 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4079         LPCSTR StringSecurityDescriptor,
4080         DWORD StringSDRevision,
4081         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4082         PULONG SecurityDescriptorSize)
4083 {
4084     UINT len;
4085     BOOL ret = FALSE;
4086     LPWSTR StringSecurityDescriptorW;
4087
4088     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4089     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4090
4091     if (StringSecurityDescriptorW)
4092     {
4093         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4094
4095         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4096                                                                    StringSDRevision, SecurityDescriptor,
4097                                                                    SecurityDescriptorSize);
4098         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4099     }
4100
4101     return ret;
4102 }
4103
4104 /******************************************************************************
4105  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4106  */
4107 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4108         LPCWSTR StringSecurityDescriptor,
4109         DWORD StringSDRevision,
4110         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4111         PULONG SecurityDescriptorSize)
4112 {
4113     DWORD cBytes;
4114     SECURITY_DESCRIPTOR* psd;
4115     BOOL bret = FALSE;
4116
4117     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4118
4119     if (GetVersion() & 0x80000000)
4120     {
4121         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4122         goto lend;
4123     }
4124     else if (!StringSecurityDescriptor || !SecurityDescriptor)
4125     {
4126         SetLastError(ERROR_INVALID_PARAMETER);
4127         goto lend;
4128     }
4129     else if (StringSDRevision != SID_REVISION)
4130     {
4131         SetLastError(ERROR_UNKNOWN_REVISION);
4132         goto lend;
4133     }
4134
4135     /* Compute security descriptor length */
4136     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4137         NULL, &cBytes))
4138         goto lend;
4139
4140     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
4141         GMEM_ZEROINIT, cBytes);
4142     if (!psd) goto lend;
4143
4144     psd->Revision = SID_REVISION;
4145     psd->Control |= SE_SELF_RELATIVE;
4146
4147     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4148         psd, &cBytes))
4149     {
4150         LocalFree(psd);
4151         goto lend;
4152     }
4153
4154     if (SecurityDescriptorSize)
4155         *SecurityDescriptorSize = cBytes;
4156
4157     bret = TRUE;
4158  
4159 lend:
4160     TRACE(" ret=%d\n", bret);
4161     return bret;
4162 }
4163
4164 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4165 {
4166     if (cch == -1)
4167         cch = strlenW(string);
4168
4169     if (plen)
4170         *plen += cch;
4171
4172     if (pwptr)
4173     {
4174         memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4175         *pwptr += cch;
4176     }
4177 }
4178
4179 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4180 {
4181     DWORD i;
4182     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4183     WCHAR subauthfmt[] = { '-','%','u',0 };
4184     WCHAR buf[26];
4185     SID *pisid = psid;
4186
4187     if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4188     {
4189         SetLastError(ERROR_INVALID_SID);
4190         return FALSE;
4191     }
4192
4193     if (pisid->IdentifierAuthority.Value[0] ||
4194      pisid->IdentifierAuthority.Value[1])
4195     {
4196         FIXME("not matching MS' bugs\n");
4197         SetLastError(ERROR_INVALID_SID);
4198         return FALSE;
4199     }
4200
4201     sprintfW( buf, fmt, pisid->Revision,
4202         MAKELONG(
4203             MAKEWORD( pisid->IdentifierAuthority.Value[5],
4204                     pisid->IdentifierAuthority.Value[4] ),
4205             MAKEWORD( pisid->IdentifierAuthority.Value[3],
4206                     pisid->IdentifierAuthority.Value[2] )
4207         ) );
4208     DumpString(buf, -1, pwptr, plen);
4209
4210     for( i=0; i<pisid->SubAuthorityCount; i++ )
4211     {
4212         sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4213         DumpString(buf, -1, pwptr, plen);
4214     }
4215     return TRUE;
4216 }
4217
4218 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4219 {
4220     size_t i;
4221     for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4222     {
4223         if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4224         {
4225             DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4226             return TRUE;
4227         }
4228     }
4229
4230     return DumpSidNumeric(psid, pwptr, plen);
4231 }
4232
4233 static const LPCWSTR AceRightBitNames[32] = {
4234         SDDL_CREATE_CHILD,        /*  0 */
4235         SDDL_DELETE_CHILD,
4236         SDDL_LIST_CHILDREN,
4237         SDDL_SELF_WRITE,
4238         SDDL_READ_PROPERTY,       /*  4 */
4239         SDDL_WRITE_PROPERTY,
4240         SDDL_DELETE_TREE,
4241         SDDL_LIST_OBJECT,
4242         SDDL_CONTROL_ACCESS,      /*  8 */
4243         NULL,
4244         NULL,
4245         NULL,
4246         NULL,                     /* 12 */
4247         NULL,
4248         NULL,
4249         NULL,
4250         SDDL_STANDARD_DELETE,     /* 16 */
4251         SDDL_READ_CONTROL,
4252         SDDL_WRITE_DAC,
4253         SDDL_WRITE_OWNER,
4254         NULL,                     /* 20 */
4255         NULL,
4256         NULL,
4257         NULL,
4258         NULL,                     /* 24 */
4259         NULL,
4260         NULL,
4261         NULL,
4262         SDDL_GENERIC_ALL,         /* 28 */
4263         SDDL_GENERIC_EXECUTE,
4264         SDDL_GENERIC_WRITE,
4265         SDDL_GENERIC_READ
4266 };
4267
4268 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4269 {
4270     static const WCHAR fmtW[] = {'0','x','%','x',0};
4271     WCHAR buf[15];
4272     size_t i;
4273
4274     if (mask == 0)
4275         return;
4276
4277     /* first check if the right have name */
4278     for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4279     {
4280         if (AceRights[i].wstr == NULL)
4281             break;
4282         if (mask == AceRights[i].value)
4283         {
4284             DumpString(AceRights[i].wstr, -1, pwptr, plen);
4285             return;
4286         }
4287     }
4288
4289     /* then check if it can be built from bit names */
4290     for (i = 0; i < 32; i++)
4291     {
4292         if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4293         {
4294             /* can't be built from bit names */
4295             sprintfW(buf, fmtW, mask);
4296             DumpString(buf, -1, pwptr, plen);
4297             return;
4298         }
4299     }
4300
4301     /* build from bit names */
4302     for (i = 0; i < 32; i++)
4303         if (mask & (1 << i))
4304             DumpString(AceRightBitNames[i], -1, pwptr, plen);
4305 }
4306
4307 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4308 {
4309     ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4310     static const WCHAR openbr = '(';
4311     static const WCHAR closebr = ')';
4312     static const WCHAR semicolon = ';';
4313
4314     if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4315     {
4316         SetLastError(ERROR_INVALID_ACL);
4317         return FALSE;
4318     }
4319
4320     piace = (ACCESS_ALLOWED_ACE *)pace;
4321     DumpString(&openbr, 1, pwptr, plen);
4322     switch (piace->Header.AceType)
4323     {
4324         case ACCESS_ALLOWED_ACE_TYPE:
4325             DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4326             break;
4327         case ACCESS_DENIED_ACE_TYPE:
4328             DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4329             break;
4330         case SYSTEM_AUDIT_ACE_TYPE:
4331             DumpString(SDDL_AUDIT, -1, pwptr, plen);
4332             break;
4333         case SYSTEM_ALARM_ACE_TYPE:
4334             DumpString(SDDL_ALARM, -1, pwptr, plen);
4335             break;
4336     }
4337     DumpString(&semicolon, 1, pwptr, plen);
4338
4339     if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4340         DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4341     if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4342         DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4343     if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4344         DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4345     if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4346         DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4347     if (piace->Header.AceFlags & INHERITED_ACE)
4348         DumpString(SDDL_INHERITED, -1, pwptr, plen);
4349     if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4350         DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4351     if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4352         DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4353     DumpString(&semicolon, 1, pwptr, plen);
4354     DumpRights(piace->Mask, pwptr, plen);
4355     DumpString(&semicolon, 1, pwptr, plen);
4356     /* objects not supported */
4357     DumpString(&semicolon, 1, pwptr, plen);
4358     /* objects not supported */
4359     DumpString(&semicolon, 1, pwptr, plen);
4360     if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
4361         return FALSE;
4362     DumpString(&closebr, 1, pwptr, plen);
4363     return TRUE;
4364 }
4365
4366 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4367 {
4368     WORD count;
4369     int i;
4370
4371     if (protected)
4372         DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4373     if (autoInheritReq)
4374         DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4375     if (autoInherited)
4376         DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4377
4378     if (pacl == NULL)
4379         return TRUE;
4380
4381     if (!IsValidAcl(pacl))
4382         return FALSE;
4383
4384     count = pacl->AceCount;
4385     for (i = 0; i < count; i++)
4386     {
4387         LPVOID ace;
4388         if (!GetAce(pacl, i, &ace))
4389             return FALSE;
4390         if (!DumpAce(ace, pwptr, plen))
4391             return FALSE;
4392     }
4393
4394     return TRUE;
4395 }
4396
4397 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4398 {
4399     static const WCHAR prefix[] = {'O',':',0};
4400     BOOL bDefaulted;
4401     PSID psid;
4402
4403     if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4404         return FALSE;
4405
4406     if (psid == NULL)
4407         return TRUE;
4408
4409     DumpString(prefix, -1, pwptr, plen);
4410     if (!DumpSid(psid, pwptr, plen))
4411         return FALSE;
4412     return TRUE;
4413 }
4414
4415 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4416 {
4417     static const WCHAR prefix[] = {'G',':',0};
4418     BOOL bDefaulted;
4419     PSID psid;
4420
4421     if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4422         return FALSE;
4423
4424     if (psid == NULL)
4425         return TRUE;
4426
4427     DumpString(prefix, -1, pwptr, plen);
4428     if (!DumpSid(psid, pwptr, plen))
4429         return FALSE;
4430     return TRUE;
4431 }
4432
4433 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4434 {
4435     static const WCHAR dacl[] = {'D',':',0};
4436     SECURITY_DESCRIPTOR_CONTROL control;
4437     BOOL present, defaulted;
4438     DWORD revision;
4439     PACL pacl;
4440
4441     if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4442         return FALSE;
4443
4444     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4445         return FALSE;
4446
4447     if (!present)
4448         return TRUE;
4449
4450     DumpString(dacl, 2, pwptr, plen);
4451     if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4452         return FALSE;
4453     return TRUE;
4454 }
4455
4456 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4457 {
4458     static const WCHAR sacl[] = {'S',':',0};
4459     SECURITY_DESCRIPTOR_CONTROL control;
4460     BOOL present, defaulted;
4461     DWORD revision;
4462     PACL pacl;
4463
4464     if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4465         return FALSE;
4466
4467     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4468         return FALSE;
4469
4470     if (!present)
4471         return TRUE;
4472
4473     DumpString(sacl, 2, pwptr, plen);
4474     if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4475         return FALSE;
4476     return TRUE;
4477 }
4478
4479 /******************************************************************************
4480  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4481  */
4482 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4483 {
4484     ULONG len;
4485     WCHAR *wptr, *wstr;
4486
4487     if (SDRevision != SDDL_REVISION_1)
4488     {
4489         ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4490         SetLastError(ERROR_UNKNOWN_REVISION);
4491         return FALSE;
4492     }
4493
4494     len = 0;
4495     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4496         if (!DumpOwner(SecurityDescriptor, NULL, &len))
4497             return FALSE;
4498     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4499         if (!DumpGroup(SecurityDescriptor, NULL, &len))
4500             return FALSE;
4501     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4502         if (!DumpDacl(SecurityDescriptor, NULL, &len))
4503             return FALSE;
4504     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4505         if (!DumpSacl(SecurityDescriptor, NULL, &len))
4506             return FALSE;
4507
4508     wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4509     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4510         if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4511             return FALSE;
4512     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4513         if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4514             return FALSE;
4515     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4516         if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4517             return FALSE;
4518     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4519         if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4520             return FALSE;
4521     *wptr = 0;
4522
4523     TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4524     *OutputString = wstr;
4525     if (OutputLen)
4526         *OutputLen = strlenW(*OutputString)+1;
4527     return TRUE;
4528 }
4529
4530 /******************************************************************************
4531  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4532  */
4533 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4534 {
4535     LPWSTR wstr;
4536     ULONG len;
4537     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4538     {
4539         int lenA;
4540
4541         lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4542         *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4543         WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4544         LocalFree(wstr);
4545
4546         if (OutputLen != NULL)
4547             *OutputLen = lenA;
4548         return TRUE;
4549     }
4550     else
4551     {
4552         *OutputString = NULL;
4553         if (OutputLen)
4554             *OutputLen = 0;
4555         return FALSE;
4556     }
4557 }
4558
4559 /******************************************************************************
4560  * ConvertStringSidToSidW [ADVAPI32.@]
4561  */
4562 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4563 {
4564     BOOL bret = FALSE;
4565     DWORD cBytes;
4566
4567     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4568     if (GetVersion() & 0x80000000)
4569         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4570     else if (!StringSid || !Sid)
4571         SetLastError(ERROR_INVALID_PARAMETER);
4572     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
4573     {
4574         PSID pSid = *Sid = LocalAlloc(0, cBytes);
4575
4576         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
4577         if (!bret)
4578             LocalFree(*Sid); 
4579     }
4580     return bret;
4581 }
4582
4583 /******************************************************************************
4584  * ConvertStringSidToSidA [ADVAPI32.@]
4585  */
4586 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
4587 {
4588     BOOL bret = FALSE;
4589
4590     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
4591     if (GetVersion() & 0x80000000)
4592         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4593     else if (!StringSid || !Sid)
4594         SetLastError(ERROR_INVALID_PARAMETER);
4595     else
4596     {
4597         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
4598         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
4599          len * sizeof(WCHAR));
4600
4601         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
4602         bret = ConvertStringSidToSidW(wStringSid, Sid);
4603         HeapFree(GetProcessHeap(), 0, wStringSid);
4604     }
4605     return bret;
4606 }
4607
4608 /******************************************************************************
4609  * ConvertSidToStringSidW [ADVAPI32.@]
4610  *
4611  *  format of SID string is:
4612  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
4613  *  where
4614  *    <rev> is the revision of the SID encoded as decimal
4615  *    <auth> is the identifier authority encoded as hex
4616  *    <subauthN> is the subauthority id encoded as decimal
4617  */
4618 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
4619 {
4620     DWORD len = 0;
4621     LPWSTR wstr, wptr;
4622
4623     TRACE("%p %p\n", pSid, pstr );
4624
4625     len = 0;
4626     if (!DumpSidNumeric(pSid, NULL, &len))
4627         return FALSE;
4628     wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
4629     DumpSidNumeric(pSid, &wptr, NULL);
4630     *wptr = 0;
4631
4632     *pstr = wstr;
4633     return TRUE;
4634 }
4635
4636 /******************************************************************************
4637  * ConvertSidToStringSidA [ADVAPI32.@]
4638  */
4639 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
4640 {
4641     LPWSTR wstr = NULL;
4642     LPSTR str;
4643     UINT len;
4644
4645     TRACE("%p %p\n", pSid, pstr );
4646
4647     if( !ConvertSidToStringSidW( pSid, &wstr ) )
4648         return FALSE;
4649
4650     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
4651     str = LocalAlloc( 0, len );
4652     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
4653     LocalFree( wstr );
4654
4655     *pstr = str;
4656
4657     return TRUE;
4658 }
4659
4660 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
4661         PSECURITY_DESCRIPTOR pdesc,
4662         PSECURITY_DESCRIPTOR cdesc,
4663         PSECURITY_DESCRIPTOR* ndesc,
4664         GUID* objtype,
4665         BOOL isdir,
4666         PGENERIC_MAPPING genmap )
4667 {
4668     FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
4669
4670     return FALSE;
4671 }
4672
4673 BOOL WINAPI CreatePrivateObjectSecurity(
4674         PSECURITY_DESCRIPTOR ParentDescriptor,
4675         PSECURITY_DESCRIPTOR CreatorDescriptor,
4676         PSECURITY_DESCRIPTOR* NewDescriptor,
4677         BOOL IsDirectoryObject,
4678         HANDLE Token,
4679         PGENERIC_MAPPING GenericMapping )
4680 {
4681     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
4682           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
4683
4684     return FALSE;
4685 }
4686
4687 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
4688 {
4689     FIXME("%p - stub\n", ObjectDescriptor);
4690
4691     return TRUE;
4692 }
4693
4694 BOOL WINAPI CreateProcessAsUserA(
4695         HANDLE hToken,
4696         LPCSTR lpApplicationName,
4697         LPSTR lpCommandLine,
4698         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4699         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4700         BOOL bInheritHandles,
4701         DWORD dwCreationFlags,
4702         LPVOID lpEnvironment,
4703         LPCSTR lpCurrentDirectory,
4704         LPSTARTUPINFOA lpStartupInfo,
4705         LPPROCESS_INFORMATION lpProcessInformation )
4706 {
4707     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
4708           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
4709           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4710
4711     return FALSE;
4712 }
4713
4714 BOOL WINAPI CreateProcessAsUserW(
4715         HANDLE hToken,
4716         LPCWSTR lpApplicationName,
4717         LPWSTR lpCommandLine,
4718         LPSECURITY_ATTRIBUTES lpProcessAttributes,
4719         LPSECURITY_ATTRIBUTES lpThreadAttributes,
4720         BOOL bInheritHandles,
4721         DWORD dwCreationFlags,
4722         LPVOID lpEnvironment,
4723         LPCWSTR lpCurrentDirectory,
4724         LPSTARTUPINFOW lpStartupInfo,
4725         LPPROCESS_INFORMATION lpProcessInformation )
4726 {
4727     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken, 
4728           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
4729           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
4730           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
4731
4732     /* We should create the process with a suspended main thread */
4733     if (!CreateProcessW (lpApplicationName,
4734                          lpCommandLine,
4735                          lpProcessAttributes,
4736                          lpThreadAttributes,
4737                          bInheritHandles,
4738                          dwCreationFlags, /* CREATE_SUSPENDED */
4739                          lpEnvironment,
4740                          lpCurrentDirectory,
4741                          lpStartupInfo,
4742                          lpProcessInformation))
4743     {
4744       return FALSE;
4745     }
4746
4747     return TRUE;
4748 }
4749
4750 /******************************************************************************
4751  * CreateProcessWithLogonW
4752  */
4753 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
4754     LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
4755     LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
4756 {
4757     FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
4758     debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
4759     debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
4760     lpStartupInfo, lpProcessInformation);
4761
4762     return FALSE;
4763 }
4764
4765 /******************************************************************************
4766  * DuplicateTokenEx [ADVAPI32.@]
4767  */
4768 BOOL WINAPI DuplicateTokenEx(
4769         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
4770         LPSECURITY_ATTRIBUTES lpTokenAttributes,
4771         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4772         TOKEN_TYPE TokenType,
4773         PHANDLE DuplicateTokenHandle )
4774 {
4775     OBJECT_ATTRIBUTES ObjectAttributes;
4776
4777     TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
4778           ImpersonationLevel, TokenType, DuplicateTokenHandle);
4779
4780     InitializeObjectAttributes(
4781         &ObjectAttributes,
4782         NULL,
4783         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
4784         NULL,
4785         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
4786
4787     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
4788                                            dwDesiredAccess,
4789                                            &ObjectAttributes,
4790                                            ImpersonationLevel,
4791                                            TokenType,
4792                                            DuplicateTokenHandle ) );
4793 }
4794
4795 BOOL WINAPI DuplicateToken(
4796         HANDLE ExistingTokenHandle,
4797         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
4798         PHANDLE DuplicateTokenHandle )
4799 {
4800     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
4801                              NULL, ImpersonationLevel, TokenImpersonation,
4802                              DuplicateTokenHandle );
4803 }
4804
4805 /******************************************************************************
4806  * ComputeStringSidSize
4807  */
4808 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
4809 {
4810     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
4811     {
4812         int ctok = 0;
4813         while (*StringSid)
4814         {
4815             if (*StringSid == '-')
4816                 ctok++;
4817             StringSid++;
4818         }
4819
4820         if (ctok >= 3)
4821             return GetSidLengthRequired(ctok - 2);
4822     }
4823     else /* String constant format  - Only available in winxp and above */
4824     {
4825         unsigned int i;
4826
4827         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4828             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4829                 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
4830     }
4831
4832     return GetSidLengthRequired(0);
4833 }
4834
4835 /******************************************************************************
4836  * ParseStringSidToSid
4837  */
4838 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
4839 {
4840     BOOL bret = FALSE;
4841     SID* pisid=pSid;
4842
4843     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
4844     if (!StringSid)
4845     {
4846         SetLastError(ERROR_INVALID_PARAMETER);
4847         TRACE("StringSid is NULL, returning FALSE\n");
4848         return FALSE;
4849     }
4850
4851     *cBytes = ComputeStringSidSize(StringSid);
4852     if (!pisid) /* Simply compute the size */
4853     {
4854         TRACE("only size requested, returning TRUE\n");
4855         return TRUE;
4856     }
4857
4858     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
4859     {
4860         DWORD i = 0, identAuth;
4861         DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
4862
4863         StringSid += 2; /* Advance to Revision */
4864         pisid->Revision = atoiW(StringSid);
4865
4866         if (pisid->Revision != SDDL_REVISION)
4867         {
4868             TRACE("Revision %d is unknown\n", pisid->Revision);
4869             goto lend; /* ERROR_INVALID_SID */
4870         }
4871         if (csubauth == 0)
4872         {
4873             TRACE("SubAuthorityCount is 0\n");
4874             goto lend; /* ERROR_INVALID_SID */
4875         }
4876
4877         pisid->SubAuthorityCount = csubauth;
4878
4879         /* Advance to identifier authority */
4880         while (*StringSid && *StringSid != '-')
4881             StringSid++;
4882         if (*StringSid == '-')
4883             StringSid++;
4884
4885         /* MS' implementation can't handle values greater than 2^32 - 1, so
4886          * we don't either; assume most significant bytes are always 0
4887          */
4888         pisid->IdentifierAuthority.Value[0] = 0;
4889         pisid->IdentifierAuthority.Value[1] = 0;
4890         identAuth = atoiW(StringSid);
4891         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
4892         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
4893         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
4894         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
4895
4896         /* Advance to first sub authority */
4897         while (*StringSid && *StringSid != '-')
4898             StringSid++;
4899         if (*StringSid == '-')
4900             StringSid++;
4901
4902         while (*StringSid)
4903         {
4904             pisid->SubAuthority[i++] = atoiW(StringSid);
4905
4906             while (*StringSid && *StringSid != '-')
4907                 StringSid++;
4908             if (*StringSid == '-')
4909                 StringSid++;
4910         }
4911
4912         if (i != pisid->SubAuthorityCount)
4913             goto lend; /* ERROR_INVALID_SID */
4914
4915         bret = TRUE;
4916     }
4917     else /* String constant format  - Only available in winxp and above */
4918     {
4919         unsigned int i;
4920         pisid->Revision = SDDL_REVISION;
4921
4922         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
4923             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
4924             {
4925                 DWORD j;
4926                 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
4927                 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
4928                 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
4929                     pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
4930                 bret = TRUE;
4931             }
4932
4933         if (!bret)
4934             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
4935     }
4936
4937 lend:
4938     if (!bret)
4939         SetLastError(ERROR_INVALID_SID);
4940
4941     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
4942     return bret;
4943 }
4944
4945 /******************************************************************************
4946  * GetNamedSecurityInfoA [ADVAPI32.@]
4947  */
4948 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
4949         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
4950         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
4951         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
4952 {
4953     DWORD len;
4954     LPWSTR wstr = NULL;
4955     DWORD r;
4956
4957     TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
4958         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
4959
4960     if( pObjectName )
4961     {
4962         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
4963         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
4964         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
4965     }
4966
4967     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
4968                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
4969
4970     HeapFree( GetProcessHeap(), 0, wstr );
4971
4972     return r;
4973 }
4974
4975 /******************************************************************************
4976  * GetNamedSecurityInfoW [ADVAPI32.@]
4977  */
4978 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
4979     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
4980     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
4981 {
4982     DWORD needed, offset;
4983     SECURITY_DESCRIPTOR_RELATIVE *relative;
4984     BYTE *buffer;
4985
4986     TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
4987            group, dacl, sacl, descriptor );
4988
4989     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
4990
4991     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
4992     if (info & OWNER_SECURITY_INFORMATION)
4993         needed += sizeof(sidWorld);
4994     if (info & GROUP_SECURITY_INFORMATION)
4995         needed += sizeof(sidWorld);
4996     if (info & DACL_SECURITY_INFORMATION)
4997         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4998     if (info & SACL_SECURITY_INFORMATION)
4999         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5000
5001     /* must be freed by caller */
5002     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5003     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5004
5005     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5006     {
5007         HeapFree( GetProcessHeap(), 0, *descriptor );
5008         return ERROR_INVALID_SECURITY_DESCR;
5009     }
5010
5011     relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
5012     relative->Control |= SE_SELF_RELATIVE;
5013     buffer = (BYTE *)relative;
5014     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5015
5016     if (info & OWNER_SECURITY_INFORMATION)
5017     {
5018         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5019         relative->Owner = offset;
5020         if (owner)
5021             *owner = buffer + offset;
5022         offset += sizeof(sidWorld);
5023     }
5024     if (info & GROUP_SECURITY_INFORMATION)
5025     {
5026         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5027         relative->Group = offset;
5028         if (group)
5029             *group = buffer + offset;
5030         offset += sizeof(sidWorld);
5031     }
5032     if (info & DACL_SECURITY_INFORMATION)
5033     {
5034         relative->Control |= SE_DACL_PRESENT;
5035         GetWorldAccessACL( (PACL)(buffer + offset) );
5036         relative->Dacl = offset;
5037         if (dacl)
5038             *dacl = (PACL)(buffer + offset);
5039         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5040     }
5041     if (info & SACL_SECURITY_INFORMATION)
5042     {
5043         relative->Control |= SE_SACL_PRESENT;
5044         GetWorldAccessACL( (PACL)(buffer + offset) );
5045         relative->Sacl = offset;
5046         if (sacl)
5047             *sacl = (PACL)(buffer + offset);
5048     }
5049     return ERROR_SUCCESS;
5050 }
5051
5052 /******************************************************************************
5053  * DecryptFileW [ADVAPI32.@]
5054  */
5055 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5056 {
5057     FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5058     return TRUE;
5059 }
5060
5061 /******************************************************************************
5062  * DecryptFileA [ADVAPI32.@]
5063  */
5064 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5065 {
5066     FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5067     return TRUE;
5068 }
5069
5070 /******************************************************************************
5071  * EncryptFileW [ADVAPI32.@]
5072  */
5073 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5074 {
5075     FIXME("%s\n", debugstr_w(lpFileName));
5076     return TRUE;
5077 }
5078
5079 /******************************************************************************
5080  * EncryptFileA [ADVAPI32.@]
5081  */
5082 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5083 {
5084     FIXME("%s\n", debugstr_a(lpFileName));
5085     return TRUE;
5086 }
5087
5088 /******************************************************************************
5089  * FileEncryptionStatusW [ADVAPI32.@]
5090  */
5091 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5092 {
5093     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5094     if (!lpStatus)
5095         return FALSE;
5096     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5097     return TRUE;
5098 }
5099
5100 /******************************************************************************
5101  * FileEncryptionStatusA [ADVAPI32.@]
5102  */
5103 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5104 {
5105     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5106     if (!lpStatus)
5107         return FALSE;
5108     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5109     return TRUE;
5110 }
5111
5112 /******************************************************************************
5113  * SetSecurityInfo [ADVAPI32.@]
5114  */
5115 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
5116                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5117                       PSID psidGroup, PACL pDacl, PACL pSacl) {
5118     FIXME("stub\n");
5119     return ERROR_SUCCESS;
5120 }