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