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