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