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