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