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