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