setupapi: Implement SetupGetFileCompressionInfo on top of SetupGetFileCompressionInfoEx.
[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 }, { SECURITY_NULL_RID } } },
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     *NewAcl = NULL;
2925     return ERROR_SUCCESS;
2926 }
2927
2928 /******************************************************************************
2929  * SetNamedSecurityInfoA [ADVAPI32.@]
2930  */
2931 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
2932         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
2933         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
2934 {
2935     DWORD len;
2936     LPWSTR wstr = NULL;
2937     DWORD r;
2938
2939     TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
2940            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
2941
2942     if( pObjectName )
2943     {
2944         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
2945         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
2946         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
2947     }
2948
2949     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
2950                            psidGroup, pDacl, pSacl );
2951
2952     HeapFree( GetProcessHeap(), 0, wstr );
2953
2954     return r;
2955 }
2956
2957 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
2958     PSECURITY_DESCRIPTOR ModificationDescriptor,
2959     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
2960     PGENERIC_MAPPING GenericMapping,
2961     HANDLE Token )
2962 {
2963     FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
2964           ObjectsSecurityDescriptor, GenericMapping, Token);
2965
2966     return TRUE;
2967 }
2968
2969 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
2970   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
2971   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
2972 {
2973     FIXME("%p 0x%08x 0x%08x - stub\n", pSecurityDescriptor, ControlBitsOfInterest,
2974           ControlBitsToSet);
2975
2976     return TRUE;
2977 }
2978
2979 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
2980 {
2981     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
2982 }
2983
2984 /******************************************************************************
2985  * AreAnyAccessesGranted [ADVAPI32.@]
2986  *
2987  * Determines whether or not any of a set of specified access permissions have
2988  * been granted or not.
2989  *
2990  * PARAMS
2991  *   GrantedAccess [I] The permissions that have been granted.
2992  *   DesiredAccess [I] The permissions that you want to have.
2993  *
2994  * RETURNS
2995  *   Nonzero if any of the permissions have been granted, zero if none of the
2996  *   permissions have been granted.
2997  */
2998
2999 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3000 {
3001     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3002 }
3003
3004 /******************************************************************************
3005  * SetNamedSecurityInfoW [ADVAPI32.@]
3006  */
3007 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3008         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3009         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3010 {
3011     FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3012            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3013     return ERROR_SUCCESS;
3014 }
3015
3016 /******************************************************************************
3017  * GetExplicitEntriesFromAclA [ADVAPI32.@]
3018  */
3019 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3020         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3021 {
3022     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3023     return ERROR_CALL_NOT_IMPLEMENTED;
3024 }
3025
3026 /******************************************************************************
3027  * GetExplicitEntriesFromAclW [ADVAPI32.@]
3028  */
3029 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
3030         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
3031 {
3032     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
3033     return ERROR_CALL_NOT_IMPLEMENTED;
3034 }
3035
3036
3037 /******************************************************************************
3038  * ParseAclStringFlags
3039  */
3040 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
3041 {
3042     DWORD flags = 0;
3043     LPCWSTR szAcl = *StringAcl;
3044
3045     while (*szAcl != '(')
3046     {
3047         if (*szAcl == 'P')
3048         {
3049             flags |= SE_DACL_PROTECTED;
3050         }
3051         else if (*szAcl == 'A')
3052         {
3053             szAcl++;
3054             if (*szAcl == 'R')
3055                 flags |= SE_DACL_AUTO_INHERIT_REQ;
3056             else if (*szAcl == 'I')
3057                 flags |= SE_DACL_AUTO_INHERITED;
3058         }
3059         szAcl++;
3060     }
3061
3062     *StringAcl = szAcl;
3063     return flags;
3064 }
3065
3066 /******************************************************************************
3067  * ParseAceStringType
3068  */
3069 static const ACEFLAG AceType[] =
3070 {
3071     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
3072     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
3073     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
3074     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
3075     /*
3076     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
3077     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
3078     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
3079     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
3080     */
3081     { NULL, 0 },
3082 };
3083
3084 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
3085 {
3086     UINT len = 0;
3087     LPCWSTR szAcl = *StringAcl;
3088     const ACEFLAG *lpaf = AceType;
3089
3090     while (lpaf->wstr &&
3091         (len = strlenW(lpaf->wstr)) &&
3092         strncmpW(lpaf->wstr, szAcl, len))
3093         lpaf++;
3094
3095     if (!lpaf->wstr)
3096         return 0;
3097
3098     *StringAcl += len;
3099     return lpaf->value;
3100 }
3101
3102
3103 /******************************************************************************
3104  * ParseAceStringFlags
3105  */
3106 static const ACEFLAG AceFlags[] =
3107 {
3108     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
3109     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
3110     { SDDL_INHERITED,         INHERITED_ACE },
3111     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
3112     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
3113     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
3114     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
3115     { NULL, 0 },
3116 };
3117
3118 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
3119 {
3120     UINT len = 0;
3121     BYTE flags = 0;
3122     LPCWSTR szAcl = *StringAcl;
3123
3124     while (*szAcl != ';')
3125     {
3126         const ACEFLAG *lpaf = AceFlags;
3127
3128         while (lpaf->wstr &&
3129                (len = strlenW(lpaf->wstr)) &&
3130                strncmpW(lpaf->wstr, szAcl, len))
3131             lpaf++;
3132
3133         if (!lpaf->wstr)
3134             return 0;
3135
3136         flags |= lpaf->value;
3137         szAcl += len;
3138     }
3139
3140     *StringAcl = szAcl;
3141     return flags;
3142 }
3143
3144
3145 /******************************************************************************
3146  * ParseAceStringRights
3147  */
3148 static const ACEFLAG AceRights[] =
3149 {
3150     { SDDL_GENERIC_ALL,     GENERIC_ALL },
3151     { SDDL_GENERIC_READ,    GENERIC_READ },
3152     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
3153     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
3154     { SDDL_READ_CONTROL,    READ_CONTROL },
3155     { SDDL_STANDARD_DELETE, DELETE },
3156     { SDDL_WRITE_DAC,       WRITE_DAC },
3157     { SDDL_WRITE_OWNER,     WRITE_OWNER },
3158     { NULL, 0 },
3159 };
3160
3161 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
3162 {
3163     UINT len = 0;
3164     DWORD rights = 0;
3165     LPCWSTR szAcl = *StringAcl;
3166
3167     if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
3168     {
3169         LPCWSTR p = szAcl;
3170
3171         while (*p && *p != ';')
3172             p++;
3173
3174         if (p - szAcl <= 8)
3175         {
3176             rights = strtoulW(szAcl, NULL, 16);
3177             *StringAcl = p;
3178         }
3179         else
3180             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
3181     }
3182     else
3183     {
3184         while (*szAcl != ';')
3185         {
3186             const ACEFLAG *lpaf = AceRights;
3187
3188             while (lpaf->wstr &&
3189                (len = strlenW(lpaf->wstr)) &&
3190                strncmpW(lpaf->wstr, szAcl, len))
3191             {
3192                lpaf++;
3193             }
3194
3195             if (!lpaf->wstr)
3196                 return 0;
3197
3198             rights |= lpaf->value;
3199             szAcl += len;
3200         }
3201     }
3202
3203     *StringAcl = szAcl;
3204     return rights;
3205 }
3206
3207
3208 /******************************************************************************
3209  * ParseStringAclToAcl
3210  * 
3211  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
3212  */
3213 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
3214     PACL pAcl, LPDWORD cBytes)
3215 {
3216     DWORD val;
3217     DWORD sidlen;
3218     DWORD length = sizeof(ACL);
3219     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
3220
3221     TRACE("%s\n", debugstr_w(StringAcl));
3222
3223     if (!StringAcl)
3224         return FALSE;
3225
3226     if (pAcl) /* pAce is only useful if we're setting values */
3227         pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
3228
3229     /* Parse ACL flags */
3230     *lpdwFlags = ParseAclStringFlags(&StringAcl);
3231
3232     /* Parse ACE */
3233     while (*StringAcl == '(')
3234     {
3235         StringAcl++;
3236
3237         /* Parse ACE type */
3238         val = ParseAceStringType(&StringAcl);
3239         if (pAce)
3240             pAce->Header.AceType = (BYTE) val;
3241         if (*StringAcl != ';')
3242             goto lerr;
3243         StringAcl++;
3244
3245         /* Parse ACE flags */
3246         val = ParseAceStringFlags(&StringAcl);
3247         if (pAce)
3248             pAce->Header.AceFlags = (BYTE) val;
3249         if (*StringAcl != ';')
3250             goto lerr;
3251         StringAcl++;
3252
3253         /* Parse ACE rights */
3254         val = ParseAceStringRights(&StringAcl);
3255         if (pAce)
3256             pAce->Mask = val;
3257         if (*StringAcl != ';')
3258             goto lerr;
3259         StringAcl++;
3260
3261         /* Parse ACE object guid */
3262         if (*StringAcl != ';')
3263         {
3264             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3265             goto lerr;
3266         }
3267         StringAcl++;
3268
3269         /* Parse ACE inherit object guid */
3270         if (*StringAcl != ';')
3271         {
3272             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
3273             goto lerr;
3274         }
3275         StringAcl++;
3276
3277         /* Parse ACE account sid */
3278         if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
3279         {
3280             while (*StringAcl && *StringAcl != ')')
3281                 StringAcl++;
3282         }
3283
3284         if (*StringAcl != ')')
3285             goto lerr;
3286         StringAcl++;
3287
3288         length += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
3289     }
3290
3291     *cBytes = length;
3292     return TRUE;
3293
3294 lerr:
3295     WARN("Invalid ACE string format\n");
3296     return FALSE;
3297 }
3298
3299
3300 /******************************************************************************
3301  * ParseStringSecurityDescriptorToSecurityDescriptor
3302  */
3303 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
3304     LPCWSTR StringSecurityDescriptor,
3305     SECURITY_DESCRIPTOR* SecurityDescriptor,
3306     LPDWORD cBytes)
3307 {
3308     BOOL bret = FALSE;
3309     WCHAR toktype;
3310     WCHAR tok[MAX_PATH];
3311     LPCWSTR lptoken;
3312     LPBYTE lpNext = NULL;
3313     DWORD len;
3314
3315     *cBytes = 0;
3316
3317     if (SecurityDescriptor)
3318         lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
3319
3320     while (*StringSecurityDescriptor)
3321     {
3322         toktype = *StringSecurityDescriptor;
3323
3324         /* Expect char identifier followed by ':' */
3325         StringSecurityDescriptor++;
3326         if (*StringSecurityDescriptor != ':')
3327         {
3328             SetLastError(ERROR_INVALID_PARAMETER);
3329             goto lend;
3330         }
3331         StringSecurityDescriptor++;
3332
3333         /* Extract token */
3334         lptoken = StringSecurityDescriptor;
3335         while (*lptoken && *lptoken != ':')
3336             lptoken++;
3337
3338         if (*lptoken)
3339             lptoken--;
3340
3341         len = lptoken - StringSecurityDescriptor;
3342         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
3343         tok[len] = 0;
3344
3345         switch (toktype)
3346         {
3347             case 'O':
3348             {
3349                 DWORD bytes;
3350
3351                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3352                     goto lend;
3353
3354                 if (SecurityDescriptor)
3355                 {
3356                     SecurityDescriptor->Owner = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3357                     lpNext += bytes; /* Advance to next token */
3358                 }
3359
3360                 *cBytes += bytes;
3361
3362                 break;
3363             }
3364
3365             case 'G':
3366             {
3367                 DWORD bytes;
3368
3369                 if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
3370                     goto lend;
3371
3372                 if (SecurityDescriptor)
3373                 {
3374                     SecurityDescriptor->Group = (PSID)(lpNext - (LPBYTE)SecurityDescriptor);
3375                     lpNext += bytes; /* Advance to next token */
3376                 }
3377
3378                 *cBytes += bytes;
3379
3380                 break;
3381             }
3382
3383             case 'D':
3384             {
3385                 DWORD flags;
3386                 DWORD bytes;
3387
3388                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3389                     goto lend;
3390
3391                 if (SecurityDescriptor)
3392                 {
3393                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
3394                     SecurityDescriptor->Dacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3395                     lpNext += bytes; /* Advance to next token */
3396                 }
3397
3398                 *cBytes += bytes;
3399
3400                 break;
3401             }
3402
3403             case 'S':
3404             {
3405                 DWORD flags;
3406                 DWORD bytes;
3407
3408                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
3409                     goto lend;
3410
3411                 if (SecurityDescriptor)
3412                 {
3413                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
3414                     SecurityDescriptor->Sacl = (PACL)(lpNext - (LPBYTE)SecurityDescriptor);
3415                     lpNext += bytes; /* Advance to next token */
3416                 }
3417
3418                 *cBytes += bytes;
3419
3420                 break;
3421             }
3422
3423             default:
3424                 FIXME("Unknown token\n");
3425                 SetLastError(ERROR_INVALID_PARAMETER);
3426                 goto lend;
3427         }
3428
3429         StringSecurityDescriptor = lptoken;
3430     }
3431
3432     bret = TRUE;
3433
3434 lend:
3435     return bret;
3436 }
3437
3438 /******************************************************************************
3439  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
3440  */
3441 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
3442         LPCSTR StringSecurityDescriptor,
3443         DWORD StringSDRevision,
3444         PSECURITY_DESCRIPTOR* SecurityDescriptor,
3445         PULONG SecurityDescriptorSize)
3446 {
3447     UINT len;
3448     BOOL ret = FALSE;
3449     LPWSTR StringSecurityDescriptorW;
3450
3451     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
3452     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
3453
3454     if (StringSecurityDescriptorW)
3455     {
3456         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
3457
3458         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
3459                                                                    StringSDRevision, SecurityDescriptor,
3460                                                                    SecurityDescriptorSize);
3461         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
3462     }
3463
3464     return ret;
3465 }
3466
3467 /******************************************************************************
3468  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
3469  */
3470 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
3471         LPCWSTR StringSecurityDescriptor,
3472         DWORD StringSDRevision,
3473         PSECURITY_DESCRIPTOR* SecurityDescriptor,
3474         PULONG SecurityDescriptorSize)
3475 {
3476     DWORD cBytes;
3477     SECURITY_DESCRIPTOR* psd;
3478     BOOL bret = FALSE;
3479
3480     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
3481
3482     if (GetVersion() & 0x80000000)
3483     {
3484         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3485         goto lend;
3486     }
3487     else if (StringSDRevision != SID_REVISION)
3488     {
3489         SetLastError(ERROR_UNKNOWN_REVISION);
3490         goto lend;
3491     }
3492
3493     /* Compute security descriptor length */
3494     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3495         NULL, &cBytes))
3496         goto lend;
3497
3498     psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
3499         GMEM_ZEROINIT, cBytes);
3500
3501     psd->Revision = SID_REVISION;
3502     psd->Control |= SE_SELF_RELATIVE;
3503
3504     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
3505         psd, &cBytes))
3506     {
3507         LocalFree(psd);
3508         goto lend;
3509     }
3510
3511     if (SecurityDescriptorSize)
3512         *SecurityDescriptorSize = cBytes;
3513
3514     bret = TRUE;
3515  
3516 lend:
3517     TRACE(" ret=%d\n", bret);
3518     return bret;
3519 }
3520
3521 /******************************************************************************
3522  * ConvertStringSidToSidW [ADVAPI32.@]
3523  */
3524 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
3525 {
3526     BOOL bret = FALSE;
3527     DWORD cBytes;
3528
3529     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
3530     if (GetVersion() & 0x80000000)
3531         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3532     else if (!StringSid || !Sid)
3533         SetLastError(ERROR_INVALID_PARAMETER);
3534     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
3535     {
3536         PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
3537
3538         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
3539         if (!bret)
3540             LocalFree(*Sid); 
3541     }
3542     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3543     return bret;
3544 }
3545
3546 /******************************************************************************
3547  * ConvertStringSidToSidA [ADVAPI32.@]
3548  */
3549 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
3550 {
3551     BOOL bret = FALSE;
3552
3553     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
3554     if (GetVersion() & 0x80000000)
3555         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
3556     else if (!StringSid || !Sid)
3557         SetLastError(ERROR_INVALID_PARAMETER);
3558     else
3559     {
3560         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
3561         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
3562          len * sizeof(WCHAR));
3563
3564         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
3565         bret = ConvertStringSidToSidW(wStringSid, Sid);
3566         HeapFree(GetProcessHeap(), 0, wStringSid);
3567     }
3568     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3569     return bret;
3570 }
3571
3572 /******************************************************************************
3573  * ConvertSidToStringSidW [ADVAPI32.@]
3574  *
3575  *  format of SID string is:
3576  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
3577  *  where
3578  *    <rev> is the revision of the SID encoded as decimal
3579  *    <auth> is the identifier authority encoded as hex
3580  *    <subauthN> is the subauthority id encoded as decimal
3581  */
3582 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
3583 {
3584     DWORD sz, i;
3585     LPWSTR str;
3586     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
3587     WCHAR subauthfmt[] = { '-','%','u',0 };
3588     SID* pisid=pSid;
3589
3590     TRACE("%p %p\n", pSid, pstr );
3591
3592     if( !IsValidSid( pSid ) )
3593         return FALSE;
3594
3595     if (pisid->Revision != SDDL_REVISION)
3596         return FALSE;
3597     if (pisid->IdentifierAuthority.Value[0] ||
3598      pisid->IdentifierAuthority.Value[1])
3599     {
3600         FIXME("not matching MS' bugs\n");
3601         return FALSE;
3602     }
3603
3604     sz = 14 + pisid->SubAuthorityCount * 11;
3605     str = LocalAlloc( 0, sz*sizeof(WCHAR) );
3606     sprintfW( str, fmt, pisid->Revision, MAKELONG(
3607      MAKEWORD( pisid->IdentifierAuthority.Value[5],
3608      pisid->IdentifierAuthority.Value[4] ),
3609      MAKEWORD( pisid->IdentifierAuthority.Value[3],
3610      pisid->IdentifierAuthority.Value[2] ) ) );
3611     for( i=0; i<pisid->SubAuthorityCount; i++ )
3612         sprintfW( str + strlenW(str), subauthfmt, pisid->SubAuthority[i] );
3613     *pstr = str;
3614
3615     return TRUE;
3616 }
3617
3618 /******************************************************************************
3619  * ConvertSidToStringSidA [ADVAPI32.@]
3620  */
3621 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
3622 {
3623     LPWSTR wstr = NULL;
3624     LPSTR str;
3625     UINT len;
3626
3627     TRACE("%p %p\n", pSid, pstr );
3628
3629     if( !ConvertSidToStringSidW( pSid, &wstr ) )
3630         return FALSE;
3631
3632     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
3633     str = LocalAlloc( 0, len );
3634     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
3635     LocalFree( wstr );
3636
3637     *pstr = str;
3638
3639     return TRUE;
3640 }
3641
3642 BOOL WINAPI CreatePrivateObjectSecurity(
3643         PSECURITY_DESCRIPTOR ParentDescriptor,
3644         PSECURITY_DESCRIPTOR CreatorDescriptor,
3645         PSECURITY_DESCRIPTOR* NewDescriptor,
3646         BOOL IsDirectoryObject,
3647         HANDLE Token,
3648         PGENERIC_MAPPING GenericMapping )
3649 {
3650     FIXME("%p %p %p %d %p %p - stub\n", ParentDescriptor, CreatorDescriptor,
3651           NewDescriptor, IsDirectoryObject, Token, GenericMapping);
3652
3653     return FALSE;
3654 }
3655
3656 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
3657 {
3658     FIXME("%p - stub\n", ObjectDescriptor);
3659
3660     return TRUE;
3661 }
3662
3663 BOOL WINAPI CreateProcessAsUserA(
3664         HANDLE hToken,
3665         LPCSTR lpApplicationName,
3666         LPSTR lpCommandLine,
3667         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3668         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3669         BOOL bInheritHandles,
3670         DWORD dwCreationFlags,
3671         LPVOID lpEnvironment,
3672         LPCSTR lpCurrentDirectory,
3673         LPSTARTUPINFOA lpStartupInfo,
3674         LPPROCESS_INFORMATION lpProcessInformation )
3675 {
3676     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
3677           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
3678           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3679
3680     return FALSE;
3681 }
3682
3683 BOOL WINAPI CreateProcessAsUserW(
3684         HANDLE hToken,
3685         LPCWSTR lpApplicationName,
3686         LPWSTR lpCommandLine,
3687         LPSECURITY_ATTRIBUTES lpProcessAttributes,
3688         LPSECURITY_ATTRIBUTES lpThreadAttributes,
3689         BOOL bInheritHandles,
3690         DWORD dwCreationFlags,
3691         LPVOID lpEnvironment,
3692         LPCWSTR lpCurrentDirectory,
3693         LPSTARTUPINFOW lpStartupInfo,
3694         LPPROCESS_INFORMATION lpProcessInformation )
3695 {
3696     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken, 
3697           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
3698           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
3699           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
3700
3701     /* We should create the process with a suspended main thread */
3702     if (!CreateProcessW (lpApplicationName,
3703                          lpCommandLine,
3704                          lpProcessAttributes,
3705                          lpThreadAttributes,
3706                          bInheritHandles,
3707                          dwCreationFlags, /* CREATE_SUSPENDED */
3708                          lpEnvironment,
3709                          lpCurrentDirectory,
3710                          lpStartupInfo,
3711                          lpProcessInformation))
3712     {
3713       return FALSE;
3714     }
3715
3716     return TRUE;
3717 }
3718
3719 /******************************************************************************
3720  * DuplicateTokenEx [ADVAPI32.@]
3721  */
3722 BOOL WINAPI DuplicateTokenEx(
3723         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
3724         LPSECURITY_ATTRIBUTES lpTokenAttributes,
3725         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3726         TOKEN_TYPE TokenType,
3727         PHANDLE DuplicateTokenHandle )
3728 {
3729     OBJECT_ATTRIBUTES ObjectAttributes;
3730
3731     TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
3732           ImpersonationLevel, TokenType, DuplicateTokenHandle);
3733
3734     InitializeObjectAttributes(
3735         &ObjectAttributes,
3736         NULL,
3737         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
3738         NULL,
3739         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
3740
3741     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
3742                                            dwDesiredAccess,
3743                                            &ObjectAttributes,
3744                                            ImpersonationLevel,
3745                                            TokenType,
3746                                            DuplicateTokenHandle ) );
3747 }
3748
3749 BOOL WINAPI DuplicateToken(
3750         HANDLE ExistingTokenHandle,
3751         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
3752         PHANDLE DuplicateTokenHandle )
3753 {
3754     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
3755                              NULL, ImpersonationLevel, TokenImpersonation,
3756                              DuplicateTokenHandle );
3757 }
3758
3759 BOOL WINAPI EnumDependentServicesA(
3760         SC_HANDLE hService,
3761         DWORD dwServiceState,
3762         LPENUM_SERVICE_STATUSA lpServices,
3763         DWORD cbBufSize,
3764         LPDWORD pcbBytesNeeded,
3765         LPDWORD lpServicesReturned )
3766 {
3767     FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
3768           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3769
3770     return FALSE;
3771 }
3772
3773 BOOL WINAPI EnumDependentServicesW(
3774         SC_HANDLE hService,
3775         DWORD dwServiceState,
3776         LPENUM_SERVICE_STATUSW lpServices,
3777         DWORD cbBufSize,
3778         LPDWORD pcbBytesNeeded,
3779         LPDWORD lpServicesReturned )
3780 {
3781     FIXME("%p 0x%08x %p 0x%08x %p %p - stub\n", hService, dwServiceState,
3782           lpServices, cbBufSize, pcbBytesNeeded, lpServicesReturned);
3783
3784     return FALSE;
3785 }
3786
3787 /******************************************************************************
3788  * ComputeStringSidSize
3789  */
3790 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
3791 {
3792     DWORD size = sizeof(SID);
3793
3794     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3795     {
3796         int ctok = 0;
3797         while (*StringSid)
3798         {
3799             if (*StringSid == '-')
3800                 ctok++;
3801             StringSid++;
3802         }
3803
3804         if (ctok > 3)
3805             size += (ctok - 3) * sizeof(DWORD);
3806     }
3807     else /* String constant format  - Only available in winxp and above */
3808     {
3809         int i;
3810
3811         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3812             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3813                 size += (WellKnownSids[i].Sid.SubAuthorityCount - 1) * sizeof(DWORD);
3814     }
3815
3816     return size;
3817 }
3818
3819 /******************************************************************************
3820  * ParseStringSidToSid
3821  */
3822 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
3823 {
3824     BOOL bret = FALSE;
3825     SID* pisid=pSid;
3826
3827     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
3828     if (!StringSid)
3829     {
3830         SetLastError(ERROR_INVALID_PARAMETER);
3831         TRACE("StringSid is NULL, returning FALSE\n");
3832         return FALSE;
3833     }
3834
3835     *cBytes = ComputeStringSidSize(StringSid);
3836     if (!pisid) /* Simply compute the size */
3837     {
3838         TRACE("only size requested, returning TRUE\n");
3839         return TRUE;
3840     }
3841
3842     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
3843     {
3844         DWORD i = 0, identAuth;
3845         DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
3846
3847         StringSid += 2; /* Advance to Revision */
3848         pisid->Revision = atoiW(StringSid);
3849
3850         if (pisid->Revision != SDDL_REVISION)
3851         {
3852             TRACE("Revision %d is unknown\n", pisid->Revision);
3853             goto lend; /* ERROR_INVALID_SID */
3854         }
3855         if (csubauth == 0)
3856         {
3857             TRACE("SubAuthorityCount is 0\n");
3858             goto lend; /* ERROR_INVALID_SID */
3859         }
3860
3861         pisid->SubAuthorityCount = csubauth;
3862
3863         /* Advance to identifier authority */
3864         while (*StringSid && *StringSid != '-')
3865             StringSid++;
3866         if (*StringSid == '-')
3867             StringSid++;
3868
3869         /* MS' implementation can't handle values greater than 2^32 - 1, so
3870          * we don't either; assume most significant bytes are always 0
3871          */
3872         pisid->IdentifierAuthority.Value[0] = 0;
3873         pisid->IdentifierAuthority.Value[1] = 0;
3874         identAuth = atoiW(StringSid);
3875         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
3876         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
3877         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
3878         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
3879
3880         /* Advance to first sub authority */
3881         while (*StringSid && *StringSid != '-')
3882             StringSid++;
3883         if (*StringSid == '-')
3884             StringSid++;
3885
3886         while (*StringSid)
3887         {
3888             while (*StringSid && *StringSid != '-')
3889                 StringSid++;
3890             if (*StringSid == '-')
3891                 StringSid++;
3892
3893             pisid->SubAuthority[i++] = atoiW(StringSid);
3894         }
3895
3896         if (i != pisid->SubAuthorityCount)
3897             goto lend; /* ERROR_INVALID_SID */
3898
3899         bret = TRUE;
3900     }
3901     else /* String constant format  - Only available in winxp and above */
3902     {
3903         int i;
3904         pisid->Revision = SDDL_REVISION;
3905
3906         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
3907             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
3908             {
3909                 DWORD j;
3910                 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
3911                 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
3912                 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
3913                     pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
3914                 bret = TRUE;
3915             }
3916
3917         if (!bret)
3918             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
3919     }
3920
3921 lend:
3922     if (!bret)
3923         SetLastError(ERROR_INVALID_SID);
3924
3925     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
3926     return bret;
3927 }
3928
3929 /******************************************************************************
3930  * GetNamedSecurityInfoA [ADVAPI32.@]
3931  */
3932 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
3933         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3934         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
3935         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
3936 {
3937     DWORD len;
3938     LPWSTR wstr = NULL;
3939     DWORD r;
3940
3941     TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
3942         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
3943
3944     if( pObjectName )
3945     {
3946         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3947         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3948         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3949     }
3950
3951     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
3952                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
3953
3954     HeapFree( GetProcessHeap(), 0, wstr );
3955
3956     return r;
3957 }
3958
3959 /******************************************************************************
3960  * GetNamedSecurityInfoW [ADVAPI32.@]
3961  */
3962 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
3963     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
3964     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
3965 {
3966     DWORD needed, offset;
3967     SECURITY_DESCRIPTOR_RELATIVE *relative;
3968     BYTE *buffer;
3969
3970     TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
3971            group, dacl, sacl, descriptor );
3972
3973     if (!name || !descriptor) return ERROR_INVALID_PARAMETER;
3974
3975     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3976     if (info & OWNER_SECURITY_INFORMATION)
3977         needed += sizeof(sidWorld);
3978     if (info & GROUP_SECURITY_INFORMATION)
3979         needed += sizeof(sidWorld);
3980     if (info & DACL_SECURITY_INFORMATION)
3981         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3982     if (info & SACL_SECURITY_INFORMATION)
3983         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3984
3985     /* must be freed by caller */
3986     *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
3987     if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
3988
3989     if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
3990     {
3991         HeapFree( GetProcessHeap(), 0, *descriptor );
3992         return ERROR_INVALID_SECURITY_DESCR;
3993     }
3994
3995     relative = (SECURITY_DESCRIPTOR_RELATIVE *)*descriptor;
3996     relative->Control |= SE_SELF_RELATIVE;
3997     buffer = (BYTE *)relative;
3998     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
3999
4000     if (owner && (info & OWNER_SECURITY_INFORMATION))
4001     {
4002         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4003         relative->Owner = offset;
4004         *owner = buffer + offset;
4005         offset += sizeof(sidWorld);
4006     }
4007     if (group && (info & GROUP_SECURITY_INFORMATION))
4008     {
4009         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
4010         relative->Group = offset;
4011         *group = buffer + offset;
4012         offset += sizeof(sidWorld);
4013     }
4014     if (dacl && (info & DACL_SECURITY_INFORMATION))
4015     {
4016         GetWorldAccessACL( (PACL)(buffer + offset) );
4017         relative->Dacl = offset;
4018         *dacl = (PACL)(buffer + offset);
4019         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
4020     }
4021     if (sacl && (info & SACL_SECURITY_INFORMATION))
4022     {
4023         GetWorldAccessACL( (PACL)(buffer + offset) );
4024         relative->Sacl = offset;
4025         *sacl = (PACL)(buffer + offset);
4026     }
4027     return ERROR_SUCCESS;
4028 }
4029
4030 /******************************************************************************
4031  * DecryptFileW [ADVAPI32.@]
4032  */
4033 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
4034 {
4035     FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
4036     return TRUE;
4037 }
4038
4039 /******************************************************************************
4040  * DecryptFileA [ADVAPI32.@]
4041  */
4042 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
4043 {
4044     FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
4045     return TRUE;
4046 }
4047
4048 /******************************************************************************
4049  * EncryptFileW [ADVAPI32.@]
4050  */
4051 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4052 {
4053     FIXME("%s\n", debugstr_w(lpFileName));
4054     return TRUE;
4055 }
4056
4057 /******************************************************************************
4058  * EncryptFileA [ADVAPI32.@]
4059  */
4060 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4061 {
4062     FIXME("%s\n", debugstr_a(lpFileName));
4063     return TRUE;
4064 }
4065
4066 /******************************************************************************
4067  * FileEncryptionStatusW [ADVAPI32.@]
4068  */
4069 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4070 {
4071     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4072     if (!lpStatus)
4073         return FALSE;
4074     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4075     return TRUE;
4076 }
4077
4078 /******************************************************************************
4079  * FileEncryptionStatusA [ADVAPI32.@]
4080  */
4081 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4082 {
4083     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4084     if (!lpStatus)
4085         return FALSE;
4086     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4087     return TRUE;
4088 }
4089
4090 /******************************************************************************
4091  * SetSecurityInfo [ADVAPI32.@]
4092  */
4093 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
4094                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4095                       PSID psidGroup, PACL pDacl, PACL pSacl) {
4096     FIXME("stub\n");
4097     return ERROR_SUCCESS;
4098 }