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