msi: Create the _Property table as a temporary table so that the properties aren...
[wine] / dlls / advapi32 / security.c
1 /*
2  * Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
3  * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
4  * Copyright 2006 Robert Reif
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  *
20  */
21
22 #include <stdarg.h>
23 #include <string.h>
24
25 #include "ntstatus.h"
26 #define WIN32_NO_STATUS
27 #include "windef.h"
28 #include "winbase.h"
29 #include "winerror.h"
30 #include "rpcnterr.h"
31 #include "winreg.h"
32 #include "winternl.h"
33 #include "winioctl.h"
34 #include "ntsecapi.h"
35 #include "accctrl.h"
36 #include "sddl.h"
37 #include "winsvc.h"
38 #include "aclapi.h"
39 #include "advapi32_misc.h"
40
41 #include "wine/debug.h"
42 #include "wine/unicode.h"
43
44 WINE_DEFAULT_DEBUG_CHANNEL(advapi);
45
46 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
47 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
48     PACL pAcl, LPDWORD cBytes);
49 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
50 static BYTE ParseAceStringType(LPCWSTR* StringAcl);
51 static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
52 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
53     LPCWSTR StringSecurityDescriptor,
54     SECURITY_DESCRIPTOR* SecurityDescriptor,
55     LPDWORD cBytes);
56 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
57
58 typedef struct _ACEFLAG
59 {
60    LPCWSTR wstr;
61    DWORD value;
62 } ACEFLAG, *LPACEFLAG;
63
64 typedef struct _MAX_SID
65 {
66     /* same fields as struct _SID */
67     BYTE Revision;
68     BYTE SubAuthorityCount;
69     SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
70     DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
71 } MAX_SID;
72
73 typedef struct WELLKNOWNSID
74 {
75     WCHAR wstr[2];
76     WELL_KNOWN_SID_TYPE Type;
77     MAX_SID Sid;
78 } WELLKNOWNSID;
79
80 static const WELLKNOWNSID WellKnownSids[] =
81 {
82     { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } },
83     { {'W','D'}, WinWorldSid, { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY }, { SECURITY_WORLD_RID } } },
84     { {0,0}, WinLocalSid, { SID_REVISION, 1, { SECURITY_LOCAL_SID_AUTHORITY }, { SECURITY_LOCAL_RID } } },
85     { {'C','O'}, WinCreatorOwnerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_RID } } },
86     { {'C','G'}, WinCreatorGroupSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_RID } } },
87     { {0,0}, WinCreatorOwnerServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_OWNER_SERVER_RID } } },
88     { {0,0}, WinCreatorGroupServerSid, { SID_REVISION, 1, { SECURITY_CREATOR_SID_AUTHORITY }, { SECURITY_CREATOR_GROUP_SERVER_RID } } },
89     { {0,0}, WinNtAuthoritySid, { SID_REVISION, 0, { SECURITY_NT_AUTHORITY }, { SECURITY_NULL_RID } } },
90     { {0,0}, WinDialupSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_DIALUP_RID } } },
91     { {'N','U'}, WinNetworkSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_RID } } },
92     { {0,0}, WinBatchSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BATCH_RID } } },
93     { {'I','U'}, WinInteractiveSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_INTERACTIVE_RID } } },
94     { {'S','U'}, WinServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_SERVICE_RID } } },
95     { {'A','N'}, WinAnonymousSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } } },
96     { {0,0}, WinProxySid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PROXY_RID } } },
97     { {'E','D'}, WinEnterpriseControllersSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ENTERPRISE_CONTROLLERS_RID } } },
98     { {'P','S'}, WinSelfSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_PRINCIPAL_SELF_RID } } },
99     { {'A','U'}, WinAuthenticatedUserSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } } },
100     { {'R','C'}, WinRestrictedCodeSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_RESTRICTED_CODE_RID } } },
101     { {0,0}, WinTerminalServerSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_TERMINAL_SERVER_RID } } },
102     { {0,0}, WinRemoteLogonIdSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_REMOTE_LOGON_RID } } },
103     { {'S','Y'}, WinLocalSystemSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } } },
104     { {'L','S'}, WinLocalServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SERVICE_RID } } },
105     { {'N','S'}, WinNetworkServiceSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_NETWORK_SERVICE_RID } } },
106     { {0,0}, WinBuiltinDomainSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID } } },
107     { {'B','A'}, WinBuiltinAdministratorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } } },
108     { {'B','U'}, WinBuiltinUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } } },
109     { {'B','G'}, WinBuiltinGuestsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_GUESTS } } },
110     { {'P','U'}, WinBuiltinPowerUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_POWER_USERS } } },
111     { {'A','O'}, WinBuiltinAccountOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ACCOUNT_OPS } } },
112     { {'S','O'}, WinBuiltinSystemOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_SYSTEM_OPS } } },
113     { {'P','O'}, WinBuiltinPrintOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PRINT_OPS } } },
114     { {'B','O'}, WinBuiltinBackupOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_BACKUP_OPS } } },
115     { {'R','E'}, WinBuiltinReplicatorSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REPLICATOR } } },
116     { {'R','U'}, WinBuiltinPreWindows2000CompatibleAccessSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_PREW2KCOMPACCESS } } },
117     { {'R','D'}, WinBuiltinRemoteDesktopUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_REMOTE_DESKTOP_USERS } } },
118     { {'N','O'}, WinBuiltinNetworkConfigurationOperatorsSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_NETWORK_CONFIGURATION_OPS } } },
119     { {0,0}, WinNTLMAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_NTLM_RID } } },
120     { {0,0}, WinDigestAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_DIGEST_RID } } },
121     { {0,0}, WinSChannelAuthenticationSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_PACKAGE_BASE_RID, SECURITY_PACKAGE_SCHANNEL_RID } } },
122     { {0,0}, WinThisOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_THIS_ORGANIZATION_RID } } },
123     { {0,0}, WinOtherOrganizationSid, { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_OTHER_ORGANIZATION_RID } } },
124     { {0,0}, WinBuiltinPerfMonitoringUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_MONITORING_USERS } } },
125     { {0,0}, WinBuiltinPerfLoggingUsersSid, { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_LOGGING_USERS } } },
126 };
127
128 static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
129
130 typedef struct _AccountSid {
131     WELL_KNOWN_SID_TYPE type;
132     LPCWSTR account;
133     LPCWSTR domain;
134     SID_NAME_USE name_use;
135 } AccountSid;
136
137 static const WCHAR Account_Operators[] = { 'A','c','c','o','u','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
138 static const WCHAR Administrator[] = {'A','d','m','i','n','i','s','t','r','a','t','o','r',0 };
139 static const WCHAR Administrators[] = { 'A','d','m','i','n','i','s','t','r','a','t','o','r','s',0 };
140 static const WCHAR ANONYMOUS_LOGON[] = { 'A','N','O','N','Y','M','O','U','S',' ','L','O','G','O','N',0 };
141 static const WCHAR Authenticated_Users[] = { 'A','u','t','h','e','n','t','i','c','a','t','e','d',' ','U','s','e','r','s',0 };
142 static const WCHAR Backup_Operators[] = { 'B','a','c','k','u','p',' ','O','p','e','r','a','t','o','r','s',0 };
143 static const WCHAR BATCH[] = { 'B','A','T','C','H',0 };
144 static const WCHAR Blank[] = { 0 };
145 static const WCHAR BUILTIN[] = { 'B','U','I','L','T','I','N',0 };
146 static const WCHAR Cert_Publishers[] = { 'C','e','r','t',' ','P','u','b','l','i','s','h','e','r','s',0 };
147 static const WCHAR CREATOR_GROUP[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',0 };
148 static const WCHAR CREATOR_GROUP_SERVER[] = { 'C','R','E','A','T','O','R',' ','G','R','O','U','P',' ','S','E','R','V','E','R',0 };
149 static const WCHAR CREATOR_OWNER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',0 };
150 static const WCHAR CREATOR_OWNER_SERVER[] = { 'C','R','E','A','T','O','R',' ','O','W','N','E','R',' ','S','E','R','V','E','R',0 };
151 static const WCHAR DIALUP[] = { 'D','I','A','L','U','P',0 };
152 static const WCHAR Digest_Authentication[] = { 'D','i','g','e','s','t',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
153 static const WCHAR DOMAIN[] = {'D','O','M','A','I','N',0};
154 static const WCHAR Domain_Admins[] = { 'D','o','m','a','i','n',' ','A','d','m','i','n','s',0 };
155 static const WCHAR Domain_Computers[] = { 'D','o','m','a','i','n',' ','C','o','m','p','u','t','e','r','s',0 };
156 static const WCHAR Domain_Controllers[] = { 'D','o','m','a','i','n',' ','C','o','n','t','r','o','l','l','e','r','s',0 };
157 static const WCHAR Domain_Guests[] = { 'D','o','m','a','i','n',' ','G','u','e','s','t','s',0 };
158 static const WCHAR Domain_Users[] = { 'D','o','m','a','i','n',' ','U','s','e','r','s',0 };
159 static const WCHAR Enterprise_Admins[] = { 'E','n','t','e','r','p','r','i','s','e',' ','A','d','m','i','n','s',0 };
160 static const WCHAR ENTERPRISE_DOMAIN_CONTROLLERS[] = { 'E','N','T','E','R','P','R','I','S','E',' ','D','O','M','A','I','N',' ','C','O','N','T','R','O','L','L','E','R','S',0 };
161 static const WCHAR Everyone[] = { 'E','v','e','r','y','o','n','e',0 };
162 static const WCHAR Group_Policy_Creator_Owners[] = { 'G','r','o','u','p',' ','P','o','l','i','c','y',' ','C','r','e','a','t','o','r',' ','O','w','n','e','r','s',0 };
163 static const WCHAR Guest[] = { 'G','u','e','s','t',0 };
164 static const WCHAR Guests[] = { 'G','u','e','s','t','s',0 };
165 static const WCHAR INTERACTIVE[] = { 'I','N','T','E','R','A','C','T','I','V','E',0 };
166 static const WCHAR LOCAL[] = { 'L','O','C','A','L',0 };
167 static const WCHAR LOCAL_SERVICE[] = { 'L','O','C','A','L',' ','S','E','R','V','I','C','E',0 };
168 static const WCHAR NETWORK[] = { 'N','E','T','W','O','R','K',0 };
169 static const WCHAR Network_Configuration_Operators[] = { 'N','e','t','w','o','r','k',' ','C','o','n','f','i','g','u','r','a','t','i','o','n',' ','O','p','e','r','a','t','o','r','s',0 };
170 static const WCHAR NETWORK_SERVICE[] = { 'N','E','T','W','O','R','K',' ','S','E','R','V','I','C','E',0 };
171 static const WCHAR NT_AUTHORITY[] = { 'N','T',' ','A','U','T','H','O','R','I','T','Y',0 };
172 static const WCHAR NT_Pseudo_Domain[] = { 'N','T',' ','P','s','e','u','d','o',' ','D','o','m','a','i','n',0 };
173 static const WCHAR NTML_Authentication[] = { 'N','T','M','L',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
174 static const WCHAR NULL_SID[] = { 'N','U','L','L',' ','S','I','D',0 };
175 static const WCHAR Other_Organization[] = { 'O','t','h','e','r',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
176 static const WCHAR Performance_Log_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','L','o','g',' ','U','s','e','r','s',0 };
177 static const WCHAR Performance_Monitor_Users[] = { 'P','e','r','f','o','r','m','a','n','c','e',' ','M','o','n','i','t','o','r',' ','U','s','e','r','s',0 };
178 static const WCHAR Power_Users[] = { 'P','o','w','e','r',' ','U','s','e','r','s',0 };
179 static const WCHAR Pre_Windows_2000_Compatible_Access[] = { 'P','r','e','-','W','i','n','d','o','w','s',' ','2','0','0','0',' ','C','o','m','p','a','t','i','b','l','e',' ','A','c','c','e','s','s',0 };
180 static const WCHAR Print_Operators[] = { 'P','r','i','n','t',' ','O','p','e','r','a','t','o','r','s',0 };
181 static const WCHAR PROXY[] = { 'P','R','O','X','Y',0 };
182 static const WCHAR RAS_and_IAS_Servers[] = { 'R','A','S',' ','a','n','d',' ','I','A','S',' ','S','e','r','v','e','r','s',0 };
183 static const WCHAR Remote_Desktop_Users[] = { 'R','e','m','o','t','e',' ','D','e','s','k','t','o','p',' ','U','s','e','r','s',0 };
184 static const WCHAR REMOTE_INTERACTIVE_LOGON[] = { 'R','E','M','O','T','E',' ','I','N','T','E','R','A','C','T','I','V','E',' ','L','O','G','O','N',0 };
185 static const WCHAR Replicators[] = { 'R','e','p','l','i','c','a','t','o','r','s',0 };
186 static const WCHAR RESTRICTED[] = { 'R','E','S','T','R','I','C','T','E','D',0 };
187 static const WCHAR SChannel_Authentication[] = { 'S','C','h','a','n','n','e','l',' ','A','u','t','h','e','n','t','i','c','a','t','i','o','n',0 };
188 static const WCHAR Schema_Admins[] = { 'S','c','h','e','m','a',' ','A','d','m','i','n','s',0 };
189 static const WCHAR SELF[] = { 'S','E','L','F',0 };
190 static const WCHAR Server_Operators[] = { 'S','e','r','v','e','r',' ','O','p','e','r','a','t','o','r','s',0 };
191 static const WCHAR SERVICE[] = { 'S','E','R','V','I','C','E',0 };
192 static const WCHAR SYSTEM[] = { 'S','Y','S','T','E','M',0 };
193 static const WCHAR TERMINAL_SERVER_USER[] = { 'T','E','R','M','I','N','A','L',' ','S','E','R','V','E','R',' ','U','S','E','R',0 };
194 static const WCHAR This_Organization[] = { 'T','h','i','s',' ','O','r','g','a','n','i','z','a','t','i','o','n',0 };
195 static const WCHAR Users[] = { 'U','s','e','r','s',0 };
196
197 static const AccountSid ACCOUNT_SIDS[] = {
198     { WinNullSid, NULL_SID, Blank, SidTypeWellKnownGroup },
199     { WinWorldSid, Everyone, Blank, SidTypeWellKnownGroup },
200     { WinLocalSid, LOCAL, Blank, SidTypeWellKnownGroup },
201     { WinCreatorOwnerSid, CREATOR_OWNER, Blank, SidTypeWellKnownGroup },
202     { WinCreatorGroupSid, CREATOR_GROUP, Blank, SidTypeWellKnownGroup },
203     { WinCreatorOwnerServerSid, CREATOR_OWNER_SERVER, Blank, SidTypeWellKnownGroup },
204     { WinCreatorGroupServerSid, CREATOR_GROUP_SERVER, Blank, SidTypeWellKnownGroup },
205     { WinNtAuthoritySid, NT_Pseudo_Domain, NT_Pseudo_Domain, SidTypeDomain },
206     { WinDialupSid, DIALUP, NT_AUTHORITY, SidTypeWellKnownGroup },
207     { WinNetworkSid, NETWORK, NT_AUTHORITY, SidTypeWellKnownGroup },
208     { WinBatchSid, BATCH, NT_AUTHORITY, SidTypeWellKnownGroup },
209     { WinInteractiveSid, INTERACTIVE, NT_AUTHORITY, SidTypeWellKnownGroup },
210     { WinServiceSid, SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
211     { WinAnonymousSid, ANONYMOUS_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
212     { WinProxySid, PROXY, NT_AUTHORITY, SidTypeWellKnownGroup },
213     { WinEnterpriseControllersSid, ENTERPRISE_DOMAIN_CONTROLLERS, NT_AUTHORITY, SidTypeWellKnownGroup },
214     { WinSelfSid, SELF, NT_AUTHORITY, SidTypeWellKnownGroup },
215     { WinAuthenticatedUserSid, Authenticated_Users, NT_AUTHORITY, SidTypeWellKnownGroup },
216     { WinRestrictedCodeSid, RESTRICTED, NT_AUTHORITY, SidTypeWellKnownGroup },
217     { WinTerminalServerSid, TERMINAL_SERVER_USER, NT_AUTHORITY, SidTypeWellKnownGroup },
218     { WinRemoteLogonIdSid, REMOTE_INTERACTIVE_LOGON, NT_AUTHORITY, SidTypeWellKnownGroup },
219     { WinLocalSystemSid, SYSTEM, NT_AUTHORITY, SidTypeWellKnownGroup },
220     { WinLocalServiceSid, LOCAL_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
221     { WinNetworkServiceSid, NETWORK_SERVICE, NT_AUTHORITY, SidTypeWellKnownGroup },
222     { WinBuiltinDomainSid, BUILTIN, BUILTIN, SidTypeDomain },
223     { WinBuiltinAdministratorsSid, Administrators, BUILTIN, SidTypeAlias },
224     { WinBuiltinUsersSid, Users, BUILTIN, SidTypeAlias },
225     { WinBuiltinGuestsSid, Guests, BUILTIN, SidTypeAlias },
226     { WinBuiltinPowerUsersSid, Power_Users, BUILTIN, SidTypeAlias },
227     { WinBuiltinAccountOperatorsSid, Account_Operators, BUILTIN, SidTypeAlias },
228     { WinBuiltinSystemOperatorsSid, Server_Operators, BUILTIN, SidTypeAlias },
229     { WinBuiltinPrintOperatorsSid, Print_Operators, BUILTIN, SidTypeAlias },
230     { WinBuiltinBackupOperatorsSid, Backup_Operators, BUILTIN, SidTypeAlias },
231     { WinBuiltinReplicatorSid, Replicators, BUILTIN, SidTypeAlias },
232     { WinBuiltinPreWindows2000CompatibleAccessSid, Pre_Windows_2000_Compatible_Access, BUILTIN, SidTypeAlias },
233     { WinBuiltinRemoteDesktopUsersSid, Remote_Desktop_Users, BUILTIN, SidTypeAlias },
234     { WinBuiltinNetworkConfigurationOperatorsSid, Network_Configuration_Operators, BUILTIN, SidTypeAlias },
235     { WinNTLMAuthenticationSid, NTML_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
236     { WinDigestAuthenticationSid, Digest_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
237     { WinSChannelAuthenticationSid, SChannel_Authentication, NT_AUTHORITY, SidTypeWellKnownGroup },
238     { WinThisOrganizationSid, This_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
239     { WinOtherOrganizationSid, Other_Organization, NT_AUTHORITY, SidTypeWellKnownGroup },
240     { WinBuiltinPerfMonitoringUsersSid, Performance_Monitor_Users, BUILTIN, SidTypeAlias },
241     { WinBuiltinPerfLoggingUsersSid, Performance_Log_Users, BUILTIN, SidTypeAlias },
242 };
243 /*
244  * ACE access rights
245  */
246 static const WCHAR SDDL_READ_CONTROL[]     = {'R','C',0};
247 static const WCHAR SDDL_WRITE_DAC[]        = {'W','D',0};
248 static const WCHAR SDDL_WRITE_OWNER[]      = {'W','O',0};
249 static const WCHAR SDDL_STANDARD_DELETE[]  = {'S','D',0};
250 static const WCHAR SDDL_GENERIC_ALL[]      = {'G','A',0};
251 static const WCHAR SDDL_GENERIC_READ[]     = {'G','R',0};
252 static const WCHAR SDDL_GENERIC_WRITE[]    = {'G','W',0};
253 static const WCHAR SDDL_GENERIC_EXECUTE[]  = {'G','X',0};
254
255 /*
256  * ACE types
257  */
258 static const WCHAR SDDL_ACCESS_ALLOWED[]        = {'A',0};
259 static const WCHAR SDDL_ACCESS_DENIED[]         = {'D',0};
260 static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
261 static const WCHAR SDDL_OBJECT_ACCESS_DENIED[]  = {'O','D',0};
262 static const WCHAR SDDL_AUDIT[]                 = {'A','U',0};
263 static const WCHAR SDDL_ALARM[]                 = {'A','L',0};
264 static const WCHAR SDDL_OBJECT_AUDIT[]          = {'O','U',0};
265 static const WCHAR SDDL_OBJECT_ALARMp[]         = {'O','L',0};
266
267 /*
268  * ACE flags
269  */
270 static const WCHAR SDDL_CONTAINER_INHERIT[]  = {'C','I',0};
271 static const WCHAR SDDL_OBJECT_INHERIT[]     = {'O','I',0};
272 static const WCHAR SDDL_NO_PROPAGATE[]       = {'N','P',0};
273 static const WCHAR SDDL_INHERIT_ONLY[]       = {'I','O',0};
274 static const WCHAR SDDL_INHERITED[]          = {'I','D',0};
275 static const WCHAR SDDL_AUDIT_SUCCESS[]      = {'S','A',0};
276 static const WCHAR SDDL_AUDIT_FAILURE[]      = {'F','A',0};
277
278 const char * debugstr_sid(PSID sid)
279 {
280     int auth = 0;
281     SID * psid = (SID *)sid;
282
283     if (psid == NULL)
284         return "(null)";
285
286     auth = psid->IdentifierAuthority.Value[5] +
287            (psid->IdentifierAuthority.Value[4] << 8) +
288            (psid->IdentifierAuthority.Value[3] << 16) +
289            (psid->IdentifierAuthority.Value[2] << 24);
290
291     switch (psid->SubAuthorityCount) {
292     case 0:
293         return wine_dbg_sprintf("S-%d-%d", psid->Revision, auth);
294     case 1:
295         return wine_dbg_sprintf("S-%d-%d-%u", psid->Revision, auth,
296             psid->SubAuthority[0]);
297     case 2:
298         return wine_dbg_sprintf("S-%d-%d-%u-%u", psid->Revision, auth,
299             psid->SubAuthority[0], psid->SubAuthority[1]);
300     case 3:
301         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u", psid->Revision, auth,
302             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2]);
303     case 4:
304         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u", psid->Revision, auth,
305             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
306             psid->SubAuthority[3]);
307     case 5:
308         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u", psid->Revision, auth,
309             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
310             psid->SubAuthority[3], psid->SubAuthority[4]);
311     case 6:
312         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
313             psid->SubAuthority[3], psid->SubAuthority[1], psid->SubAuthority[2],
314             psid->SubAuthority[0], psid->SubAuthority[4], psid->SubAuthority[5]);
315     case 7:
316         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
317             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
318             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
319             psid->SubAuthority[6]);
320     case 8:
321         return wine_dbg_sprintf("S-%d-%d-%u-%u-%u-%u-%u-%u-%u-%u", psid->Revision, auth,
322             psid->SubAuthority[0], psid->SubAuthority[1], psid->SubAuthority[2],
323             psid->SubAuthority[3], psid->SubAuthority[4], psid->SubAuthority[5],
324             psid->SubAuthority[6], psid->SubAuthority[7]);
325     }
326     return "(too-big)";
327 }
328
329 /* set last error code from NT status and get the proper boolean return value */
330 /* used for functions that are a simple wrapper around the corresponding ntdll API */
331 static inline BOOL set_ntstatus( NTSTATUS status )
332 {
333     if (status) SetLastError( RtlNtStatusToDosError( status ));
334     return !status;
335 }
336
337 #define WINE_SIZE_OF_WORLD_ACCESS_ACL   (sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD))
338
339 static void GetWorldAccessACL(PACL pACL)
340 {
341     PACCESS_ALLOWED_ACE pACE = (PACCESS_ALLOWED_ACE) (pACL + 1);
342
343     pACL->AclRevision = ACL_REVISION;
344     pACL->Sbz1 = 0;
345     pACL->AclSize = WINE_SIZE_OF_WORLD_ACCESS_ACL;
346     pACL->AceCount = 1;
347     pACL->Sbz2 = 0;
348
349     pACE->Header.AceType = ACCESS_ALLOWED_ACE_TYPE;
350     pACE->Header.AceFlags = CONTAINER_INHERIT_ACE;
351     pACE->Header.AceSize = sizeof(ACCESS_ALLOWED_ACE) + sizeof(sidWorld) - sizeof(DWORD);
352     pACE->Mask = 0xf3ffffff; /* Everything except reserved bits */
353     memcpy(&pACE->SidStart, &sidWorld, sizeof(sidWorld));
354 }
355
356 /************************************************************
357  *                ADVAPI_IsLocalComputer
358  *
359  * Checks whether the server name indicates local machine.
360  */
361 BOOL ADVAPI_IsLocalComputer(LPCWSTR ServerName)
362 {
363     DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
364     BOOL Result;
365     LPWSTR buf;
366
367     if (!ServerName || !ServerName[0])
368         return TRUE;
369
370     buf = HeapAlloc(GetProcessHeap(), 0, dwSize * sizeof(WCHAR));
371     Result = GetComputerNameW(buf,  &dwSize);
372     if (Result && (ServerName[0] == '\\') && (ServerName[1] == '\\'))
373         ServerName += 2;
374     Result = Result && !lstrcmpW(ServerName, buf);
375     HeapFree(GetProcessHeap(), 0, buf);
376
377     return Result;
378 }
379
380 /************************************************************
381  *                ADVAPI_GetComputerSid
382  *
383  * Reads the computer SID from the registry.
384  */
385 BOOL ADVAPI_GetComputerSid(PSID sid)
386 {
387     HKEY key;
388     LONG ret;
389     BOOL retval = FALSE;
390     static const WCHAR Account[] = { 'S','E','C','U','R','I','T','Y','\\','S','A','M','\\','D','o','m','a','i','n','s','\\','A','c','c','o','u','n','t',0 };
391     static const WCHAR V[] = { 'V',0 };
392
393     if ((ret = RegOpenKeyExW(HKEY_LOCAL_MACHINE, Account, 0,
394         KEY_READ, &key)) == ERROR_SUCCESS)
395     {
396         DWORD size = 0;
397         ret = RegQueryValueExW(key, V, NULL, NULL, NULL, &size);
398         if (ret == ERROR_MORE_DATA || ret == ERROR_SUCCESS)
399         {
400             BYTE * data = HeapAlloc(GetProcessHeap(), 0, size);
401             if (data)
402             {
403                 if ((ret = RegQueryValueExW(key, V, NULL, NULL,
404                      data, &size)) == ERROR_SUCCESS)
405                 {
406                     /* the SID is in the last 24 bytes of the binary data */
407                     CopyMemory(sid, &data[size-24], 24);
408                     retval = TRUE;
409                 }
410                 HeapFree(GetProcessHeap(), 0, data);
411             }
412         }
413         RegCloseKey(key);
414     }
415
416     if(retval == TRUE) return retval;
417
418     /* create a new random SID */
419     if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, Account,
420         0, NULL, 0, KEY_ALL_ACCESS, NULL, &key, NULL) == ERROR_SUCCESS)
421     {
422         PSID new_sid;
423         SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
424         DWORD id[3];
425
426         if (RtlGenRandom(&id, sizeof(id)))
427         {
428             if (AllocateAndInitializeSid(&identifierAuthority, 4, SECURITY_NT_NON_UNIQUE, id[0], id[1], id[2], 0, 0, 0, 0, &new_sid))
429             {
430                 if (RegSetValueExW(key, V, 0, REG_BINARY, new_sid, GetLengthSid(new_sid)) == ERROR_SUCCESS)
431                     retval = CopySid(GetLengthSid(new_sid), sid, new_sid);
432
433                 FreeSid(new_sid);
434             }
435         }
436         RegCloseKey(key);
437     }
438
439     return retval;
440 }
441
442 /*      ##############################
443         ######  TOKEN FUNCTIONS ######
444         ##############################
445 */
446
447 /******************************************************************************
448  * OpenProcessToken                     [ADVAPI32.@]
449  * Opens the access token associated with a process handle.
450  *
451  * PARAMS
452  *   ProcessHandle [I] Handle to process
453  *   DesiredAccess [I] Desired access to process
454  *   TokenHandle   [O] Pointer to handle of open access token
455  *
456  * RETURNS
457  *  Success: TRUE. TokenHandle contains the access token.
458  *  Failure: FALSE.
459  *
460  * NOTES
461  *  See NtOpenProcessToken.
462  */
463 BOOL WINAPI
464 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
465                   HANDLE *TokenHandle )
466 {
467         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
468 }
469
470 /******************************************************************************
471  * OpenThreadToken [ADVAPI32.@]
472  *
473  * Opens the access token associated with a thread handle.
474  *
475  * PARAMS
476  *   ThreadHandle  [I] Handle to process
477  *   DesiredAccess [I] Desired access to the thread
478  *   OpenAsSelf    [I] ???
479  *   TokenHandle   [O] Destination for the token handle
480  *
481  * RETURNS
482  *  Success: TRUE. TokenHandle contains the access token.
483  *  Failure: FALSE.
484  *
485  * NOTES
486  *  See NtOpenThreadToken.
487  */
488 BOOL WINAPI
489 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
490                  BOOL OpenAsSelf, HANDLE *TokenHandle)
491 {
492         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
493 }
494
495 BOOL WINAPI
496 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
497                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
498 {
499     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
500                                              PreviousState, ReturnLength));
501 }
502
503 /******************************************************************************
504  * AdjustTokenPrivileges [ADVAPI32.@]
505  *
506  * Adjust the privileges of an open token handle.
507  * 
508  * PARAMS
509  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
510  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
511  *  NewState             [I]   Desired new privileges of the token
512  *  BufferLength         [I]   Length of NewState
513  *  PreviousState        [O]   Destination for the previous state
514  *  ReturnLength         [I/O] Size of PreviousState
515  *
516  *
517  * RETURNS
518  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
519  *  Failure: FALSE.
520  *
521  * NOTES
522  *  See NtAdjustPrivilegesToken.
523  */
524 BOOL WINAPI
525 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
526                        LPVOID NewState, DWORD BufferLength,
527                        LPVOID PreviousState, LPDWORD ReturnLength )
528 {
529     NTSTATUS status;
530
531     TRACE("\n");
532     
533     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
534                                                      NewState, BufferLength, PreviousState,
535                                                      ReturnLength);
536     SetLastError( RtlNtStatusToDosError( status ));
537     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
538         return TRUE;
539     else
540         return FALSE;
541 }
542
543 /******************************************************************************
544  * CheckTokenMembership [ADVAPI32.@]
545  *
546  * Determine if an access token is a member of a SID.
547  * 
548  * PARAMS
549  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
550  *   SidToCheck  [I] SID that possibly contains the token
551  *   IsMember    [O] Destination for result.
552  *
553  * RETURNS
554  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
555  *  Failure: FALSE.
556  */
557 BOOL WINAPI
558 CheckTokenMembership( HANDLE TokenHandle, PSID SidToCheck,
559                       PBOOL IsMember )
560 {
561   FIXME("(%p %p %p) stub!\n", TokenHandle, SidToCheck, IsMember);
562
563   *IsMember = TRUE;
564   return(TRUE);
565 }
566
567 /******************************************************************************
568  * GetTokenInformation [ADVAPI32.@]
569  *
570  * Get a type of information about an access token.
571  *
572  * PARAMS
573  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
574  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
575  *   tokeninfo       [O] Destination for token information
576  *   tokeninfolength [I] Length of tokeninfo
577  *   retlen          [O] Destination for returned token information length
578  *
579  * RETURNS
580  *  Success: TRUE. tokeninfo contains retlen bytes of token information
581  *  Failure: FALSE.
582  *
583  * NOTES
584  *  See NtQueryInformationToken.
585  */
586 BOOL WINAPI
587 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
588                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
589 {
590     TRACE("(%p, %s, %p, %d, %p):\n",
591           token,
592           (tokeninfoclass == TokenUser) ? "TokenUser" :
593           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
594           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
595           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
596           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
597           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
598           (tokeninfoclass == TokenSource) ? "TokenSource" :
599           (tokeninfoclass == TokenType) ? "TokenType" :
600           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
601           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
602           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
603           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
604           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
605           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
606           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
607           "Unknown",
608           tokeninfo, tokeninfolength, retlen);
609     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
610                                                   tokeninfolength, retlen));
611 }
612
613 /******************************************************************************
614  * SetTokenInformation [ADVAPI32.@]
615  *
616  * Set information for an access token.
617  *
618  * PARAMS
619  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
620  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
621  *   tokeninfo       [I] Token information to set
622  *   tokeninfolength [I] Length of tokeninfo
623  *
624  * RETURNS
625  *  Success: TRUE. The information for the token is set to tokeninfo.
626  *  Failure: FALSE.
627  */
628 BOOL WINAPI
629 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
630                      LPVOID tokeninfo, DWORD tokeninfolength )
631 {
632     TRACE("(%p, %s, %p, %d): stub\n",
633           token,
634           (tokeninfoclass == TokenUser) ? "TokenUser" :
635           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
636           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
637           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
638           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
639           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
640           (tokeninfoclass == TokenSource) ? "TokenSource" :
641           (tokeninfoclass == TokenType) ? "TokenType" :
642           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
643           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
644           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
645           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
646           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
647           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
648           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
649           "Unknown",
650           tokeninfo, tokeninfolength);
651
652     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
653 }
654
655 /*************************************************************************
656  * SetThreadToken [ADVAPI32.@]
657  *
658  * Assigns an 'impersonation token' to a thread so it can assume the
659  * security privileges of another thread or process.  Can also remove
660  * a previously assigned token. 
661  *
662  * PARAMS
663  *   thread          [O] Handle to thread to set the token for
664  *   token           [I] Token to set
665  *
666  * RETURNS
667  *  Success: TRUE. The threads access token is set to token
668  *  Failure: FALSE.
669  *
670  * NOTES
671  *  Only supported on NT or higher. On Win9X this function does nothing.
672  *  See SetTokenInformation.
673  */
674 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
675 {
676     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
677                                                  ThreadImpersonationToken, &token, sizeof token ));
678 }
679
680 /*      ##############################
681         ######  SID FUNCTIONS   ######
682         ##############################
683 */
684
685 /******************************************************************************
686  * AllocateAndInitializeSid [ADVAPI32.@]
687  *
688  * PARAMS
689  *   pIdentifierAuthority []
690  *   nSubAuthorityCount   []
691  *   nSubAuthority0       []
692  *   nSubAuthority1       []
693  *   nSubAuthority2       []
694  *   nSubAuthority3       []
695  *   nSubAuthority4       []
696  *   nSubAuthority5       []
697  *   nSubAuthority6       []
698  *   nSubAuthority7       []
699  *   pSid                 []
700  */
701 BOOL WINAPI
702 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
703                           BYTE nSubAuthorityCount,
704                           DWORD nSubAuthority0, DWORD nSubAuthority1,
705                           DWORD nSubAuthority2, DWORD nSubAuthority3,
706                           DWORD nSubAuthority4, DWORD nSubAuthority5,
707                           DWORD nSubAuthority6, DWORD nSubAuthority7,
708                           PSID *pSid )
709 {
710     return set_ntstatus( RtlAllocateAndInitializeSid(
711                              pIdentifierAuthority, nSubAuthorityCount,
712                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
713                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
714                              pSid ));
715 }
716
717 /******************************************************************************
718  * FreeSid [ADVAPI32.@]
719  *
720  * PARAMS
721  *   pSid []
722  */
723 PVOID WINAPI
724 FreeSid( PSID pSid )
725 {
726         RtlFreeSid(pSid);
727         return NULL; /* is documented like this */
728 }
729
730 /******************************************************************************
731  * CopySid [ADVAPI32.@]
732  *
733  * PARAMS
734  *   nDestinationSidLength []
735  *   pDestinationSid       []
736  *   pSourceSid            []
737  */
738 BOOL WINAPI
739 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
740 {
741         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
742 }
743
744 /******************************************************************************
745  * CreateWellKnownSid [ADVAPI32.@]
746  */
747 BOOL WINAPI
748 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
749                     PSID DomainSid,
750                     PSID pSid,
751                     DWORD* cbSid)
752 {
753     int i;
754     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
755
756     if (DomainSid != NULL) {
757         FIXME("Only local computer supported!\n");
758         SetLastError(ERROR_INVALID_PARAMETER);  /* FIXME */
759         return FALSE;
760     }
761
762     if (cbSid == NULL || pSid == NULL) {
763         SetLastError(ERROR_INVALID_PARAMETER);
764         return FALSE;
765     }
766
767     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
768         if (WellKnownSids[i].Type == WellKnownSidType) {
769             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
770
771             if (*cbSid < length) {
772                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
773                 return FALSE;
774             }
775
776             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
777             *cbSid = length;
778             return TRUE;
779         }
780     }
781
782     SetLastError(ERROR_INVALID_PARAMETER);
783     return FALSE;
784 }
785
786 /******************************************************************************
787  * IsWellKnownSid [ADVAPI32.@]
788  */
789 BOOL WINAPI
790 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
791 {
792     int i;
793     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
794
795     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
796         if (WellKnownSids[i].Type == WellKnownSidType)
797             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
798                 return TRUE;
799
800     return FALSE;
801 }
802
803 BOOL WINAPI
804 IsTokenRestricted( HANDLE TokenHandle )
805 {
806     TOKEN_GROUPS *groups;
807     DWORD size;
808     NTSTATUS status;
809     BOOL restricted;
810
811     TRACE("(%p)\n", TokenHandle);
812  
813     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
814     if (status != STATUS_BUFFER_TOO_SMALL)
815         return FALSE;
816  
817     groups = HeapAlloc(GetProcessHeap(), 0, size);
818     if (!groups)
819     {
820         SetLastError(ERROR_OUTOFMEMORY);
821         return FALSE;
822     }
823  
824     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
825     if (status != STATUS_SUCCESS)
826     {
827         HeapFree(GetProcessHeap(), 0, groups);
828         return set_ntstatus(status);
829     }
830  
831     if (groups->GroupCount)
832         restricted = TRUE;
833     else
834         restricted = FALSE;
835      
836     HeapFree(GetProcessHeap(), 0, groups);
837  
838     return restricted;
839 }
840
841 /******************************************************************************
842  * IsValidSid [ADVAPI32.@]
843  *
844  * PARAMS
845  *   pSid []
846  */
847 BOOL WINAPI
848 IsValidSid( PSID pSid )
849 {
850         return RtlValidSid( pSid );
851 }
852
853 /******************************************************************************
854  * EqualSid [ADVAPI32.@]
855  *
856  * PARAMS
857  *   pSid1 []
858  *   pSid2 []
859  */
860 BOOL WINAPI
861 EqualSid( PSID pSid1, PSID pSid2 )
862 {
863         return RtlEqualSid( pSid1, pSid2 );
864 }
865
866 /******************************************************************************
867  * EqualPrefixSid [ADVAPI32.@]
868  */
869 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
870 {
871         return RtlEqualPrefixSid(pSid1, pSid2);
872 }
873
874 /******************************************************************************
875  * GetSidLengthRequired [ADVAPI32.@]
876  *
877  * PARAMS
878  *   nSubAuthorityCount []
879  */
880 DWORD WINAPI
881 GetSidLengthRequired( BYTE nSubAuthorityCount )
882 {
883         return RtlLengthRequiredSid(nSubAuthorityCount);
884 }
885
886 /******************************************************************************
887  * InitializeSid [ADVAPI32.@]
888  *
889  * PARAMS
890  *   pIdentifierAuthority []
891  */
892 BOOL WINAPI
893 InitializeSid (
894         PSID pSid,
895         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
896         BYTE nSubAuthorityCount)
897 {
898         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
899 }
900
901 DWORD WINAPI
902 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
903 {
904     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
905
906     return 1;
907 }
908
909 DWORD WINAPI
910 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
911 {
912     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
913
914     return 1;
915 }
916
917 /******************************************************************************
918  * GetSidIdentifierAuthority [ADVAPI32.@]
919  *
920  * PARAMS
921  *   pSid []
922  */
923 PSID_IDENTIFIER_AUTHORITY WINAPI
924 GetSidIdentifierAuthority( PSID pSid )
925 {
926         return RtlIdentifierAuthoritySid(pSid);
927 }
928
929 /******************************************************************************
930  * GetSidSubAuthority [ADVAPI32.@]
931  *
932  * PARAMS
933  *   pSid          []
934  *   nSubAuthority []
935  */
936 PDWORD WINAPI
937 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
938 {
939         return RtlSubAuthoritySid(pSid, nSubAuthority);
940 }
941
942 /******************************************************************************
943  * GetSidSubAuthorityCount [ADVAPI32.@]
944  *
945  * PARAMS
946  *   pSid []
947  */
948 PUCHAR WINAPI
949 GetSidSubAuthorityCount (PSID pSid)
950 {
951         return RtlSubAuthorityCountSid(pSid);
952 }
953
954 /******************************************************************************
955  * GetLengthSid [ADVAPI32.@]
956  *
957  * PARAMS
958  *   pSid []
959  */
960 DWORD WINAPI
961 GetLengthSid (PSID pSid)
962 {
963         return RtlLengthSid(pSid);
964 }
965
966 /*      ##############################################
967         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
968         ##############################################
969 */
970
971  /****************************************************************************** 
972  * BuildSecurityDescriptorA [ADVAPI32.@]
973  *
974  * Builds a SD from 
975  *
976  * PARAMS
977  *  pOwner                [I]
978  *  pGroup                [I]
979  *  cCountOfAccessEntries [I]
980  *  pListOfAccessEntries  [I]
981  *  cCountOfAuditEntries  [I]
982  *  pListofAuditEntries   [I]
983  *  pOldSD                [I]
984  *  lpdwBufferLength      [I/O]
985  *  pNewSD                [O]
986  *
987  * RETURNS
988  *  Success: ERROR_SUCCESS
989  *  Failure: nonzero error code from Winerror.h
990  */
991 DWORD WINAPI BuildSecurityDescriptorA(
992     IN PTRUSTEEA pOwner,
993     IN PTRUSTEEA pGroup,
994     IN ULONG cCountOfAccessEntries,
995     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
996     IN ULONG cCountOfAuditEntries,
997     IN PEXPLICIT_ACCESSA pListofAuditEntries,
998     IN PSECURITY_DESCRIPTOR pOldSD,
999     IN OUT PULONG lpdwBufferLength,
1000     OUT PSECURITY_DESCRIPTOR* pNewSD)
1001
1002     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1003           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1004           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1005  
1006     return ERROR_CALL_NOT_IMPLEMENTED;
1007
1008  
1009 /******************************************************************************
1010  * BuildSecurityDescriptorW [ADVAPI32.@]
1011  *
1012  * See BuildSecurityDescriptorA.
1013  */
1014 DWORD WINAPI BuildSecurityDescriptorW(
1015     IN PTRUSTEEW pOwner,
1016     IN PTRUSTEEW pGroup,
1017     IN ULONG cCountOfAccessEntries,
1018     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1019     IN ULONG cCountOfAuditEntries,
1020     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1021     IN PSECURITY_DESCRIPTOR pOldSD,
1022     IN OUT PULONG lpdwBufferLength,
1023     OUT PSECURITY_DESCRIPTOR* pNewSD)
1024
1025     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1026           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1027           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1028  
1029     return ERROR_CALL_NOT_IMPLEMENTED;
1030
1031
1032 /******************************************************************************
1033  * InitializeSecurityDescriptor [ADVAPI32.@]
1034  *
1035  * PARAMS
1036  *   pDescr   []
1037  *   revision []
1038  */
1039 BOOL WINAPI
1040 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1041 {
1042         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1043 }
1044
1045
1046 /******************************************************************************
1047  * MakeAbsoluteSD [ADVAPI32.@]
1048  */
1049 BOOL WINAPI MakeAbsoluteSD (
1050         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1051         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1052         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1053         OUT PACL pDacl,
1054         OUT LPDWORD lpdwDaclSize,
1055         OUT PACL pSacl,
1056         OUT LPDWORD lpdwSaclSize,
1057         OUT PSID pOwner,
1058         OUT LPDWORD lpdwOwnerSize,
1059         OUT PSID pPrimaryGroup,
1060         OUT LPDWORD lpdwPrimaryGroupSize)
1061 {
1062     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1063                                                      pAbsoluteSecurityDescriptor,
1064                                                      lpdwAbsoluteSecurityDescriptorSize,
1065                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1066                                                      pOwner, lpdwOwnerSize,
1067                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1068 }
1069
1070 /******************************************************************************
1071  * GetKernelObjectSecurity [ADVAPI32.@]
1072  */
1073 BOOL WINAPI GetKernelObjectSecurity(
1074         HANDLE Handle,
1075         SECURITY_INFORMATION RequestedInformation,
1076         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1077         DWORD nLength,
1078         LPDWORD lpnLengthNeeded )
1079 {
1080     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1081           pSecurityDescriptor, nLength, lpnLengthNeeded);
1082
1083     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1084                                                nLength, lpnLengthNeeded ));
1085 }
1086
1087 /******************************************************************************
1088  * GetPrivateObjectSecurity [ADVAPI32.@]
1089  */
1090 BOOL WINAPI GetPrivateObjectSecurity(
1091         PSECURITY_DESCRIPTOR ObjectDescriptor,
1092         SECURITY_INFORMATION SecurityInformation,
1093         PSECURITY_DESCRIPTOR ResultantDescriptor,
1094         DWORD DescriptorLength,
1095         PDWORD ReturnLength )
1096 {
1097     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1098           ResultantDescriptor, DescriptorLength, ReturnLength);
1099
1100     return set_ntstatus( NtQuerySecurityObject(ObjectDescriptor, SecurityInformation,
1101                                                ResultantDescriptor, DescriptorLength, ReturnLength ));
1102 }
1103
1104 /******************************************************************************
1105  * GetSecurityDescriptorLength [ADVAPI32.@]
1106  */
1107 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1108 {
1109         return RtlLengthSecurityDescriptor(pDescr);
1110 }
1111
1112 /******************************************************************************
1113  * GetSecurityDescriptorOwner [ADVAPI32.@]
1114  *
1115  * PARAMS
1116  *   pOwner            []
1117  *   lpbOwnerDefaulted []
1118  */
1119 BOOL WINAPI
1120 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1121                             LPBOOL lpbOwnerDefaulted )
1122 {
1123     BOOLEAN defaulted;
1124     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1125     *lpbOwnerDefaulted = defaulted;
1126     return ret;
1127 }
1128
1129 /******************************************************************************
1130  * SetSecurityDescriptorOwner [ADVAPI32.@]
1131  *
1132  * PARAMS
1133  */
1134 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1135                                    PSID pOwner, BOOL bOwnerDefaulted)
1136 {
1137     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1138 }
1139 /******************************************************************************
1140  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1141  */
1142 BOOL WINAPI GetSecurityDescriptorGroup(
1143         PSECURITY_DESCRIPTOR SecurityDescriptor,
1144         PSID *Group,
1145         LPBOOL GroupDefaulted)
1146 {
1147     BOOLEAN defaulted;
1148     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1149     *GroupDefaulted = defaulted;
1150     return ret;
1151 }
1152 /******************************************************************************
1153  * SetSecurityDescriptorGroup [ADVAPI32.@]
1154  */
1155 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1156                                            PSID Group, BOOL GroupDefaulted)
1157 {
1158     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1159 }
1160
1161 /******************************************************************************
1162  * IsValidSecurityDescriptor [ADVAPI32.@]
1163  *
1164  * PARAMS
1165  *   lpsecdesc []
1166  */
1167 BOOL WINAPI
1168 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1169 {
1170     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1171 }
1172
1173 /******************************************************************************
1174  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1175  */
1176 BOOL WINAPI GetSecurityDescriptorDacl(
1177         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1178         OUT LPBOOL lpbDaclPresent,
1179         OUT PACL *pDacl,
1180         OUT LPBOOL lpbDaclDefaulted)
1181 {
1182     BOOLEAN present, defaulted;
1183     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1184     *lpbDaclPresent = present;
1185     *lpbDaclDefaulted = defaulted;
1186     return ret;
1187 }
1188
1189 /******************************************************************************
1190  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1191  */
1192 BOOL WINAPI
1193 SetSecurityDescriptorDacl (
1194         PSECURITY_DESCRIPTOR lpsd,
1195         BOOL daclpresent,
1196         PACL dacl,
1197         BOOL dacldefaulted )
1198 {
1199     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1200 }
1201 /******************************************************************************
1202  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1203  */
1204 BOOL WINAPI GetSecurityDescriptorSacl(
1205         IN PSECURITY_DESCRIPTOR lpsd,
1206         OUT LPBOOL lpbSaclPresent,
1207         OUT PACL *pSacl,
1208         OUT LPBOOL lpbSaclDefaulted)
1209 {
1210     BOOLEAN present, defaulted;
1211     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1212     *lpbSaclPresent = present;
1213     *lpbSaclDefaulted = defaulted;
1214     return ret;
1215 }
1216
1217 /**************************************************************************
1218  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1219  */
1220 BOOL WINAPI SetSecurityDescriptorSacl (
1221         PSECURITY_DESCRIPTOR lpsd,
1222         BOOL saclpresent,
1223         PACL lpsacl,
1224         BOOL sacldefaulted)
1225 {
1226     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1227 }
1228 /******************************************************************************
1229  * MakeSelfRelativeSD [ADVAPI32.@]
1230  *
1231  * PARAMS
1232  *   lpabssecdesc  []
1233  *   lpselfsecdesc []
1234  *   lpbuflen      []
1235  */
1236 BOOL WINAPI
1237 MakeSelfRelativeSD(
1238         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1239         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1240         IN OUT LPDWORD lpdwBufferLength)
1241 {
1242     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1243                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1244 }
1245
1246 /******************************************************************************
1247  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1248  */
1249
1250 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1251                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1252 {
1253     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1254 }
1255
1256 /*      ##############################
1257         ######  ACL FUNCTIONS   ######
1258         ##############################
1259 */
1260
1261 /*************************************************************************
1262  * InitializeAcl [ADVAPI32.@]
1263  */
1264 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1265 {
1266     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1267 }
1268
1269 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1270 {
1271     TRACE("(%p)\n", hNamedPipe);
1272
1273     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL, NULL,
1274                          FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1275 }
1276
1277 /******************************************************************************
1278  *  AddAccessAllowedAce [ADVAPI32.@]
1279  */
1280 BOOL WINAPI AddAccessAllowedAce(
1281         IN OUT PACL pAcl,
1282         IN DWORD dwAceRevision,
1283         IN DWORD AccessMask,
1284         IN PSID pSid)
1285 {
1286     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1287 }
1288
1289 /******************************************************************************
1290  *  AddAccessAllowedAceEx [ADVAPI32.@]
1291  */
1292 BOOL WINAPI AddAccessAllowedAceEx(
1293         IN OUT PACL pAcl,
1294         IN DWORD dwAceRevision,
1295         IN DWORD AceFlags,
1296         IN DWORD AccessMask,
1297         IN PSID pSid)
1298 {
1299     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1300 }
1301
1302 /******************************************************************************
1303  *  AddAccessDeniedAce [ADVAPI32.@]
1304  */
1305 BOOL WINAPI AddAccessDeniedAce(
1306         IN OUT PACL pAcl,
1307         IN DWORD dwAceRevision,
1308         IN DWORD AccessMask,
1309         IN PSID pSid)
1310 {
1311     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1312 }
1313
1314 /******************************************************************************
1315  *  AddAccessDeniedAceEx [ADVAPI32.@]
1316  */
1317 BOOL WINAPI AddAccessDeniedAceEx(
1318         IN OUT PACL pAcl,
1319         IN DWORD dwAceRevision,
1320         IN DWORD AceFlags,
1321         IN DWORD AccessMask,
1322         IN PSID pSid)
1323 {
1324     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1325 }
1326
1327 /******************************************************************************
1328  *  AddAce [ADVAPI32.@]
1329  */
1330 BOOL WINAPI AddAce(
1331         IN OUT PACL pAcl,
1332         IN DWORD dwAceRevision,
1333         IN DWORD dwStartingAceIndex,
1334         LPVOID pAceList,
1335         DWORD nAceListLength)
1336 {
1337     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1338 }
1339
1340 /******************************************************************************
1341  * DeleteAce [ADVAPI32.@]
1342  */
1343 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1344 {
1345     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1346 }
1347
1348 /******************************************************************************
1349  *  FindFirstFreeAce [ADVAPI32.@]
1350  */
1351 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1352 {
1353         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1354 }
1355
1356 /******************************************************************************
1357  * GetAce [ADVAPI32.@]
1358  */
1359 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1360 {
1361     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1362 }
1363
1364 /******************************************************************************
1365  * GetAclInformation [ADVAPI32.@]
1366  */
1367 BOOL WINAPI GetAclInformation(
1368   PACL pAcl,
1369   LPVOID pAclInformation,
1370   DWORD nAclInformationLength,
1371   ACL_INFORMATION_CLASS dwAclInformationClass)
1372 {
1373     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1374                                                nAclInformationLength, dwAclInformationClass));
1375 }
1376
1377 /******************************************************************************
1378  *  IsValidAcl [ADVAPI32.@]
1379  */
1380 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1381 {
1382         return RtlValidAcl(pAcl);
1383 }
1384
1385 /*      ##############################
1386         ######  MISC FUNCTIONS  ######
1387         ##############################
1388 */
1389
1390 /******************************************************************************
1391  * AllocateLocallyUniqueId [ADVAPI32.@]
1392  *
1393  * PARAMS
1394  *   lpLuid []
1395  */
1396 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1397 {
1398     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1399 }
1400
1401 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1402  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1403 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1404  { 'S','e','A','s','s','i','g','n','P','r','i','m','a','r','y','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1405 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1406  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1407 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1408  { 'S','e','I','n','c','r','e','a','s','e','Q','u','o','t','a','P','r','i','v','i','l','e','g','e',0 };
1409 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1410  { 'S','e','M','a','c','h','i','n','e','A','c','c','o','u','n','t','P','r','i','v','i','l','e','g','e',0 };
1411 static const WCHAR SE_TCB_NAME_W[] =
1412  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1413 static const WCHAR SE_SECURITY_NAME_W[] =
1414  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1415 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1416  { 'S','e','T','a','k','e','O','w','n','e','r','s','h','i','p','P','r','i','v','i','l','e','g','e',0 };
1417 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1418  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1419 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1420  { 'S','e','S','y','s','t','e','m','P','r','o','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1421 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1422  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1423 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1424  { 'S','e','P','r','o','f','i','l','e','S','i','n','g','l','e','P','r','o','c','e','s','s','P','r','i','v','i','l','e','g','e',0 };
1425 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1426  { 'S','e','I','n','c','r','e','a','s','e','B','a','s','e','P','r','i','o','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1427 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1428  { 'S','e','C','r','e','a','t','e','P','a','g','e','f','i','l','e','P','r','i','v','i','l','e','g','e',0 };
1429 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1430  { 'S','e','C','r','e','a','t','e','P','e','r','m','a','n','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1431 static const WCHAR SE_BACKUP_NAME_W[] =
1432  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1433 static const WCHAR SE_RESTORE_NAME_W[] =
1434  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1435 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1436  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1437 static const WCHAR SE_DEBUG_NAME_W[] =
1438  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1439 static const WCHAR SE_AUDIT_NAME_W[] =
1440  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1441 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1442  { 'S','e','S','y','s','t','e','m','E','n','v','i','r','o','n','m','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1443 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1444  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1445 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1446  { 'S','e','R','e','m','o','t','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1447 static const WCHAR SE_UNDOCK_NAME_W[] =
1448  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1449 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1450  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1451 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1452  { 'S','e','E','n','a','b','l','e','D','e','l','e','g','a','t','i','o','n','P','r','i','v','i','l','e','g','e',0 };
1453 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1454  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1455 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1456  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1457 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1458  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1459
1460 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1461 {
1462     NULL,
1463     NULL,
1464     SE_CREATE_TOKEN_NAME_W,
1465     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1466     SE_LOCK_MEMORY_NAME_W,
1467     SE_INCREASE_QUOTA_NAME_W,
1468     SE_MACHINE_ACCOUNT_NAME_W,
1469     SE_TCB_NAME_W,
1470     SE_SECURITY_NAME_W,
1471     SE_TAKE_OWNERSHIP_NAME_W,
1472     SE_LOAD_DRIVER_NAME_W,
1473     SE_SYSTEM_PROFILE_NAME_W,
1474     SE_SYSTEMTIME_NAME_W,
1475     SE_PROF_SINGLE_PROCESS_NAME_W,
1476     SE_INC_BASE_PRIORITY_NAME_W,
1477     SE_CREATE_PAGEFILE_NAME_W,
1478     SE_CREATE_PERMANENT_NAME_W,
1479     SE_BACKUP_NAME_W,
1480     SE_RESTORE_NAME_W,
1481     SE_SHUTDOWN_NAME_W,
1482     SE_DEBUG_NAME_W,
1483     SE_AUDIT_NAME_W,
1484     SE_SYSTEM_ENVIRONMENT_NAME_W,
1485     SE_CHANGE_NOTIFY_NAME_W,
1486     SE_REMOTE_SHUTDOWN_NAME_W,
1487     SE_UNDOCK_NAME_W,
1488     SE_SYNC_AGENT_NAME_W,
1489     SE_ENABLE_DELEGATION_NAME_W,
1490     SE_MANAGE_VOLUME_NAME_W,
1491     SE_IMPERSONATE_NAME_W,
1492     SE_CREATE_GLOBAL_NAME_W,
1493 };
1494
1495 /******************************************************************************
1496  * LookupPrivilegeValueW                        [ADVAPI32.@]
1497  *
1498  * See LookupPrivilegeValueA.
1499  */
1500 BOOL WINAPI
1501 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1502 {
1503     UINT i;
1504
1505     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1506
1507     if (!ADVAPI_IsLocalComputer(lpSystemName))
1508     {
1509         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1510         return FALSE;
1511     }
1512     if (!lpName)
1513     {
1514         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1515         return FALSE;
1516     }
1517     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1518     {
1519         if( !WellKnownPrivNames[i] )
1520             continue;
1521         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1522             continue;
1523         lpLuid->LowPart = i;
1524         lpLuid->HighPart = 0;
1525         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1526                lpLuid->HighPart, lpLuid->LowPart );
1527         return TRUE;
1528     }
1529     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1530     return FALSE;
1531 }
1532
1533 /******************************************************************************
1534  * LookupPrivilegeValueA                        [ADVAPI32.@]
1535  *
1536  * Retrieves LUID used on a system to represent the privilege name.
1537  *
1538  * PARAMS
1539  *  lpSystemName [I] Name of the system
1540  *  lpName       [I] Name of the privilege
1541  *  lpLuid       [O] Destination for the resulting LUID
1542  *
1543  * RETURNS
1544  *  Success: TRUE. lpLuid contains the requested LUID.
1545  *  Failure: FALSE.
1546  */
1547 BOOL WINAPI
1548 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1549 {
1550     UNICODE_STRING lpSystemNameW;
1551     UNICODE_STRING lpNameW;
1552     BOOL ret;
1553
1554     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1555     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1556     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1557     RtlFreeUnicodeString(&lpNameW);
1558     RtlFreeUnicodeString(&lpSystemNameW);
1559     return ret;
1560 }
1561
1562 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1563                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1564 {
1565     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1566           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1567
1568     return FALSE;
1569 }
1570
1571 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1572                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1573 {
1574     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1575           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1576
1577     return FALSE;
1578 }
1579
1580 /******************************************************************************
1581  * LookupPrivilegeNameA                 [ADVAPI32.@]
1582  *
1583  * See LookupPrivilegeNameW.
1584  */
1585 BOOL WINAPI
1586 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1587  LPDWORD cchName)
1588 {
1589     UNICODE_STRING lpSystemNameW;
1590     BOOL ret;
1591     DWORD wLen = 0;
1592
1593     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1594
1595     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1596     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1597     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1598     {
1599         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1600
1601         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1602          &wLen);
1603         if (ret)
1604         {
1605             /* Windows crashes if cchName is NULL, so will I */
1606             int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1607              *cchName, NULL, NULL);
1608
1609             if (len == 0)
1610             {
1611                 /* WideCharToMultiByte failed */
1612                 ret = FALSE;
1613             }
1614             else if (len > *cchName)
1615             {
1616                 *cchName = len;
1617                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1618                 ret = FALSE;
1619             }
1620             else
1621             {
1622                 /* WideCharToMultiByte succeeded, output length needs to be
1623                  * length not including NULL terminator
1624                  */
1625                 *cchName = len - 1;
1626             }
1627         }
1628         HeapFree(GetProcessHeap(), 0, lpNameW);
1629     }
1630     RtlFreeUnicodeString(&lpSystemNameW);
1631     return ret;
1632 }
1633
1634 /******************************************************************************
1635  * LookupPrivilegeNameW                 [ADVAPI32.@]
1636  *
1637  * Retrieves the privilege name referred to by the LUID lpLuid.
1638  *
1639  * PARAMS
1640  *  lpSystemName [I]   Name of the system
1641  *  lpLuid       [I]   Privilege value
1642  *  lpName       [O]   Name of the privilege
1643  *  cchName      [I/O] Number of characters in lpName.
1644  *
1645  * RETURNS
1646  *  Success: TRUE. lpName contains the name of the privilege whose value is
1647  *  *lpLuid.
1648  *  Failure: FALSE.
1649  *
1650  * REMARKS
1651  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1652  *  using this function.
1653  *  If the length of lpName is too small, on return *cchName will contain the
1654  *  number of WCHARs needed to contain the privilege, including the NULL
1655  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1656  *  On success, *cchName will contain the number of characters stored in
1657  *  lpName, NOT including the NULL terminator.
1658  */
1659 BOOL WINAPI
1660 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1661  LPDWORD cchName)
1662 {
1663     size_t privNameLen;
1664
1665     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1666
1667     if (!ADVAPI_IsLocalComputer(lpSystemName))
1668     {
1669         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1670         return FALSE;
1671     }
1672     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1673      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1674     {
1675         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1676         return FALSE;
1677     }
1678     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1679     /* Windows crashes if cchName is NULL, so will I */
1680     if (*cchName <= privNameLen)
1681     {
1682         *cchName = privNameLen + 1;
1683         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1684         return FALSE;
1685     }
1686     else
1687     {
1688         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1689         *cchName = privNameLen;
1690         return TRUE;
1691     }
1692 }
1693
1694 /******************************************************************************
1695  * GetFileSecurityA [ADVAPI32.@]
1696  *
1697  * Obtains Specified information about the security of a file or directory.
1698  *
1699  * PARAMS
1700  *  lpFileName           [I] Name of the file to get info for
1701  *  RequestedInformation [I] SE_ flags from "winnt.h"
1702  *  pSecurityDescriptor  [O] Destination for security information
1703  *  nLength              [I] Length of pSecurityDescriptor
1704  *  lpnLengthNeeded      [O] Destination for length of returned security information
1705  *
1706  * RETURNS
1707  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1708  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1709  *
1710  * NOTES
1711  *  The information returned is constrained by the callers access rights and
1712  *  privileges.
1713  */
1714 BOOL WINAPI
1715 GetFileSecurityA( LPCSTR lpFileName,
1716                     SECURITY_INFORMATION RequestedInformation,
1717                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1718                     DWORD nLength, LPDWORD lpnLengthNeeded )
1719 {
1720     DWORD len;
1721     BOOL r;
1722     LPWSTR name = NULL;
1723
1724     if( lpFileName )
1725     {
1726         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1727         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1728         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1729     }
1730
1731     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1732                           nLength, lpnLengthNeeded );
1733     HeapFree( GetProcessHeap(), 0, name );
1734
1735     return r;
1736 }
1737
1738 /******************************************************************************
1739  * GetFileSecurityW [ADVAPI32.@]
1740  *
1741  * See GetFileSecurityA.
1742  */
1743 BOOL WINAPI
1744 GetFileSecurityW( LPCWSTR lpFileName,
1745                     SECURITY_INFORMATION RequestedInformation,
1746                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1747                     DWORD nLength, LPDWORD lpnLengthNeeded )
1748 {
1749     HANDLE hfile;
1750     NTSTATUS status;
1751
1752     hfile = CreateFileW( lpFileName, GENERIC_READ, FILE_SHARE_READ,
1753                          NULL, OPEN_EXISTING, 0, 0 );
1754     if ( hfile == INVALID_HANDLE_VALUE )
1755         return FALSE;
1756
1757     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1758                                     nLength, lpnLengthNeeded );
1759     CloseHandle( hfile );
1760     return set_ntstatus( status );
1761 }
1762
1763
1764 /******************************************************************************
1765  * LookupAccountSidA [ADVAPI32.@]
1766  */
1767 BOOL WINAPI
1768 LookupAccountSidA(
1769         IN LPCSTR system,
1770         IN PSID sid,
1771         OUT LPSTR account,
1772         IN OUT LPDWORD accountSize,
1773         OUT LPSTR domain,
1774         IN OUT LPDWORD domainSize,
1775         OUT PSID_NAME_USE name_use )
1776 {
1777     DWORD len;
1778     BOOL r;
1779     LPWSTR systemW = NULL;
1780     LPWSTR accountW = NULL;
1781     LPWSTR domainW = NULL;
1782     DWORD accountSizeW = *accountSize;
1783     DWORD domainSizeW = *domainSize;
1784
1785     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1786           debugstr_a(system),debugstr_sid(sid),
1787           account,accountSize,accountSize?*accountSize:0,
1788           domain,domainSize,domainSize?*domainSize:0,
1789           name_use);
1790
1791     if (system) {
1792         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
1793         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
1794         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
1795     }
1796     if (account)
1797         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
1798     if (domain)
1799         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
1800
1801     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
1802
1803     if (r) {
1804         if (accountW && *accountSize) {
1805             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
1806             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
1807             *accountSize = len;
1808         } else
1809             *accountSize = accountSizeW + 1;
1810
1811         if (domainW && *domainSize) {
1812             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
1813             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
1814             *domainSize = len;
1815         } else
1816             *domainSize = domainSizeW + 1;
1817     }
1818
1819     HeapFree( GetProcessHeap(), 0, systemW );
1820     HeapFree( GetProcessHeap(), 0, accountW );
1821     HeapFree( GetProcessHeap(), 0, domainW );
1822
1823     return r;
1824 }
1825
1826 /******************************************************************************
1827  * LookupAccountSidW [ADVAPI32.@]
1828  *
1829  * PARAMS
1830  *   system      []
1831  *   sid         []
1832  *   account     []
1833  *   accountSize []
1834  *   domain      []
1835  *   domainSize  []
1836  *   name_use    []
1837  */
1838
1839 BOOL WINAPI
1840 LookupAccountSidW(
1841         IN LPCWSTR system,
1842         IN PSID sid,
1843         OUT LPWSTR account,
1844         IN OUT LPDWORD accountSize,
1845         OUT LPWSTR domain,
1846         IN OUT LPDWORD domainSize,
1847         OUT PSID_NAME_USE name_use )
1848 {
1849     int i, j;
1850     const WCHAR * ac = NULL;
1851     const WCHAR * dm = NULL;
1852     SID_NAME_USE use = 0;
1853     LPWSTR computer_name = NULL;
1854
1855     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
1856           debugstr_w(system),debugstr_sid(sid),
1857           account,accountSize,accountSize?*accountSize:0,
1858           domain,domainSize,domainSize?*domainSize:0,
1859           name_use);
1860
1861     if (!ADVAPI_IsLocalComputer(system)) {
1862         FIXME("Only local computer supported!\n");
1863         SetLastError(ERROR_NONE_MAPPED);
1864         return FALSE;
1865     }
1866
1867     /* check the well known SIDs first */
1868     for (i = 0; i <= 60; i++) {
1869         if (IsWellKnownSid(sid, i)) {
1870             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
1871                 if (ACCOUNT_SIDS[j].type == i) {
1872                     ac = ACCOUNT_SIDS[j].account;
1873                     dm = ACCOUNT_SIDS[j].domain;
1874                     use = ACCOUNT_SIDS[j].name_use;
1875                 }
1876             }
1877             break;
1878         }
1879     }
1880
1881     if (dm == NULL) {
1882         MAX_SID local;
1883
1884         /* check for the local computer next */
1885         if (ADVAPI_GetComputerSid(&local)) {
1886             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
1887             BOOL result;
1888
1889             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
1890             result = GetComputerNameW(computer_name,  &size);
1891
1892             if (result) {
1893                 if (EqualSid(sid, &local)) {
1894                     dm = computer_name;
1895                     ac = Blank;
1896                     use = 3;
1897                 } else {
1898                     local.SubAuthorityCount++;
1899
1900                     if (EqualPrefixSid(sid, &local)) {
1901                         dm = computer_name;
1902                         use = 1;
1903                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
1904                         case DOMAIN_USER_RID_ADMIN:
1905                             ac = Administrator;
1906                             break;
1907                         case DOMAIN_USER_RID_GUEST:
1908                             ac = Guest;
1909                             break;
1910                         case DOMAIN_GROUP_RID_ADMINS:
1911                             ac = Domain_Admins;
1912                             break;
1913                         case DOMAIN_GROUP_RID_USERS:
1914                             ac = Domain_Users;
1915                             break;
1916                         case DOMAIN_GROUP_RID_GUESTS:
1917                             ac = Domain_Guests;
1918                             break;
1919                         case DOMAIN_GROUP_RID_COMPUTERS:
1920                             ac = Domain_Computers;
1921                             break;
1922                         case DOMAIN_GROUP_RID_CONTROLLERS:
1923                             ac = Domain_Controllers;
1924                             break;
1925                         case DOMAIN_GROUP_RID_CERT_ADMINS:
1926                             ac = Cert_Publishers;
1927                             break;
1928                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
1929                             ac = Schema_Admins;
1930                             break;
1931                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
1932                             ac = Enterprise_Admins;
1933                             break;
1934                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
1935                             ac = Group_Policy_Creator_Owners;
1936                             break;
1937                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
1938                             ac = RAS_and_IAS_Servers;
1939                             break;
1940                         default:
1941                             dm = NULL;
1942                             break;
1943                         }
1944                     }
1945                 }
1946             }
1947         }
1948     }
1949
1950     if (dm) {
1951         BOOL status = TRUE;
1952         if (*accountSize > lstrlenW(ac)) {
1953             if (account)
1954                 lstrcpyW(account, ac);
1955         }
1956         if (*domainSize > lstrlenW(dm)) {
1957             if (domain)
1958                 lstrcpyW(domain, dm);
1959         }
1960         if (((*accountSize != 0) && (*accountSize < strlenW(ac))) ||
1961             ((*domainSize != 0) && (*domainSize < strlenW(dm)))) {
1962             SetLastError(ERROR_INSUFFICIENT_BUFFER);
1963             status = FALSE;
1964         }
1965         if (*domainSize)
1966             *domainSize = strlenW(dm);
1967         else
1968             *domainSize = strlenW(dm) + 1;
1969         if (*accountSize)
1970             *accountSize = strlenW(ac);
1971         else
1972             *accountSize = strlenW(ac) + 1;
1973         *name_use = use;
1974         HeapFree(GetProcessHeap(), 0, computer_name);
1975         return status;
1976     }
1977
1978     HeapFree(GetProcessHeap(), 0, computer_name);
1979     SetLastError(ERROR_NONE_MAPPED);
1980     return FALSE;
1981 }
1982
1983 /******************************************************************************
1984  * SetFileSecurityA [ADVAPI32.@]
1985  *
1986  * See SetFileSecurityW.
1987  */
1988 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
1989                                 SECURITY_INFORMATION RequestedInformation,
1990                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
1991 {
1992     DWORD len;
1993     BOOL r;
1994     LPWSTR name = NULL;
1995
1996     if( lpFileName )
1997     {
1998         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1999         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2000         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2001     }
2002
2003     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2004     HeapFree( GetProcessHeap(), 0, name );
2005
2006     return r;
2007 }
2008
2009 /******************************************************************************
2010  * SetFileSecurityW [ADVAPI32.@]
2011  *
2012  * Sets the security of a file or directory.
2013  *
2014  * PARAMS
2015  *   lpFileName           []
2016  *   RequestedInformation []
2017  *   pSecurityDescriptor  []
2018  *
2019  * RETURNS
2020  *  Success: TRUE.
2021  *  Failure: FALSE.
2022  */
2023 BOOL WINAPI
2024 SetFileSecurityW( LPCWSTR lpFileName,
2025                     SECURITY_INFORMATION RequestedInformation,
2026                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2027 {
2028   FIXME("(%s) : stub\n", debugstr_w(lpFileName) );
2029   return TRUE;
2030 }
2031
2032 /******************************************************************************
2033  * QueryWindows31FilesMigration [ADVAPI32.@]
2034  *
2035  * PARAMS
2036  *   x1 []
2037  */
2038 BOOL WINAPI
2039 QueryWindows31FilesMigration( DWORD x1 )
2040 {
2041         FIXME("(%d):stub\n",x1);
2042         return TRUE;
2043 }
2044
2045 /******************************************************************************
2046  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2047  *
2048  * PARAMS
2049  *   x1 []
2050  *   x2 []
2051  *   x3 []
2052  *   x4 []
2053  */
2054 BOOL WINAPI
2055 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2056                                                DWORD x4 )
2057 {
2058         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2059         return TRUE;
2060 }
2061
2062 /******************************************************************************
2063  * NotifyBootConfigStatus [ADVAPI32.@]
2064  *
2065  * PARAMS
2066  *   x1 []
2067  */
2068 BOOL WINAPI
2069 NotifyBootConfigStatus( BOOL x1 )
2070 {
2071         FIXME("(0x%08d):stub\n",x1);
2072         return 1;
2073 }
2074
2075 /******************************************************************************
2076  * RevertToSelf [ADVAPI32.@]
2077  *
2078  * Ends the impersonation of a user.
2079  *
2080  * PARAMS
2081  *   void []
2082  *
2083  * RETURNS
2084  *  Success: TRUE.
2085  *  Failure: FALSE.
2086  */
2087 BOOL WINAPI
2088 RevertToSelf( void )
2089 {
2090     HANDLE Token = NULL;
2091     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2092         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2093 }
2094
2095 /******************************************************************************
2096  * ImpersonateSelf [ADVAPI32.@]
2097  *
2098  * Makes an impersonation token that represents the process user and assigns
2099  * to the current thread.
2100  *
2101  * PARAMS
2102  *  ImpersonationLevel [I] Level at which to impersonate.
2103  *
2104  * RETURNS
2105  *  Success: TRUE.
2106  *  Failure: FALSE.
2107  */
2108 BOOL WINAPI
2109 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2110 {
2111     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2112 }
2113
2114 /******************************************************************************
2115  * ImpersonateLoggedOnUser [ADVAPI32.@]
2116  */
2117 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2118 {
2119     DWORD size;
2120     NTSTATUS Status;
2121     HANDLE ImpersonationToken;
2122     TOKEN_TYPE Type;
2123
2124     FIXME( "(%p)\n", hToken );
2125
2126     if (!GetTokenInformation( hToken, TokenType, &Type,
2127                               sizeof(TOKEN_TYPE), &size ))
2128         return FALSE;
2129
2130     if (Type == TokenPrimary)
2131     {
2132         OBJECT_ATTRIBUTES ObjectAttributes;
2133
2134         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2135
2136         Status = NtDuplicateToken( hToken,
2137                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2138                                    &ObjectAttributes,
2139                                    SecurityImpersonation,
2140                                    TokenImpersonation,
2141                                    &ImpersonationToken );
2142         if (Status != STATUS_SUCCESS)
2143         {
2144             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2145             SetLastError( RtlNtStatusToDosError( Status ) );
2146             return FALSE;
2147         }
2148     }
2149     else
2150         ImpersonationToken = hToken;
2151
2152     Status = NtSetInformationThread( GetCurrentThread(),
2153                                      ThreadImpersonationToken,
2154                                      &ImpersonationToken,
2155                                      sizeof(ImpersonationToken) );
2156
2157     if (Type == TokenPrimary)
2158         NtClose( ImpersonationToken );
2159
2160     if (Status != STATUS_SUCCESS)
2161     {
2162         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2163         SetLastError( RtlNtStatusToDosError( Status ) );
2164         return FALSE;
2165     }
2166
2167     return TRUE;
2168 }
2169
2170 /******************************************************************************
2171  * AccessCheck [ADVAPI32.@]
2172  */
2173 BOOL WINAPI
2174 AccessCheck(
2175         PSECURITY_DESCRIPTOR SecurityDescriptor,
2176         HANDLE ClientToken,
2177         DWORD DesiredAccess,
2178         PGENERIC_MAPPING GenericMapping,
2179         PPRIVILEGE_SET PrivilegeSet,
2180         LPDWORD PrivilegeSetLength,
2181         LPDWORD GrantedAccess,
2182         LPBOOL AccessStatus)
2183 {
2184     NTSTATUS access_status;
2185     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2186                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2187                                            GrantedAccess, &access_status) );
2188     if (ret) *AccessStatus = set_ntstatus( access_status );
2189     return ret;
2190 }
2191
2192
2193 /******************************************************************************
2194  * AccessCheckByType [ADVAPI32.@]
2195  */
2196 BOOL WINAPI AccessCheckByType(
2197     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2198     PSID PrincipalSelfSid,
2199     HANDLE ClientToken, 
2200     DWORD DesiredAccess, 
2201     POBJECT_TYPE_LIST ObjectTypeList,
2202     DWORD ObjectTypeListLength,
2203     PGENERIC_MAPPING GenericMapping,
2204     PPRIVILEGE_SET PrivilegeSet,
2205     LPDWORD PrivilegeSetLength, 
2206     LPDWORD GrantedAccess,
2207     LPBOOL AccessStatus)
2208 {
2209         FIXME("stub\n");
2210
2211         *AccessStatus = TRUE;
2212
2213         return !*AccessStatus;
2214 }
2215
2216 /******************************************************************************
2217  * MapGenericMask [ADVAPI32.@]
2218  *
2219  * Maps generic access rights into specific access rights according to the
2220  * supplied mapping.
2221  *
2222  * PARAMS
2223  *  AccessMask     [I/O] Access rights.
2224  *  GenericMapping [I] The mapping between generic and specific rights.
2225  *
2226  * RETURNS
2227  *  Nothing.
2228  */
2229 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2230 {
2231     RtlMapGenericMask( AccessMask, GenericMapping );
2232 }
2233
2234 /*************************************************************************
2235  * SetKernelObjectSecurity [ADVAPI32.@]
2236  */
2237 BOOL WINAPI SetKernelObjectSecurity (
2238         IN HANDLE Handle,
2239         IN SECURITY_INFORMATION SecurityInformation,
2240         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2241 {
2242     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2243 }
2244
2245
2246 /******************************************************************************
2247  *  AddAuditAccessAce [ADVAPI32.@]
2248  */
2249 BOOL WINAPI AddAuditAccessAce(
2250     IN OUT PACL pAcl, 
2251     IN DWORD dwAceRevision, 
2252     IN DWORD dwAccessMask, 
2253     IN PSID pSid, 
2254     IN BOOL bAuditSuccess, 
2255     IN BOOL bAuditFailure) 
2256 {
2257     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2258                                               bAuditSuccess, bAuditFailure) ); 
2259 }
2260
2261 /******************************************************************************
2262  * LookupAccountNameA [ADVAPI32.@]
2263  */
2264 BOOL WINAPI
2265 LookupAccountNameA(
2266         IN LPCSTR system,
2267         IN LPCSTR account,
2268         OUT PSID sid,
2269         OUT LPDWORD cbSid,
2270         LPSTR ReferencedDomainName,
2271         IN OUT LPDWORD cbReferencedDomainName,
2272         OUT PSID_NAME_USE name_use )
2273 {
2274     BOOL ret;
2275     UNICODE_STRING lpSystemW;
2276     UNICODE_STRING lpAccountW;
2277     LPWSTR lpReferencedDomainNameW = NULL;
2278
2279     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2280     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2281
2282     if (ReferencedDomainName)
2283         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2284
2285     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2286         cbReferencedDomainName, name_use);
2287
2288     if (ret && lpReferencedDomainNameW)
2289     {
2290         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, *cbReferencedDomainName,
2291             ReferencedDomainName, *cbReferencedDomainName, NULL, NULL);
2292     }
2293
2294     RtlFreeUnicodeString(&lpSystemW);
2295     RtlFreeUnicodeString(&lpAccountW);
2296     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2297
2298     return ret;
2299 }
2300
2301 /******************************************************************************
2302  * LookupAccountNameW [ADVAPI32.@]
2303  */
2304 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2305                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2306                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2307 {
2308     /* Default implementation: Always return a default SID */
2309     SID_IDENTIFIER_AUTHORITY identifierAuthority = {SECURITY_NT_AUTHORITY};
2310     BOOL ret;
2311     PSID pSid;
2312     static const WCHAR dm[] = {'D','O','M','A','I','N',0};
2313
2314     FIXME("%s %s %p %p %p %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2315           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2316
2317     ret = AllocateAndInitializeSid(&identifierAuthority,
2318         2,
2319         SECURITY_BUILTIN_DOMAIN_RID,
2320         DOMAIN_ALIAS_RID_ADMINS,
2321         0, 0, 0, 0, 0, 0,
2322         &pSid);
2323
2324     if (!ret)
2325        return FALSE;
2326
2327     if (!RtlValidSid(pSid))
2328     {
2329        FreeSid(pSid);
2330        return FALSE;
2331     }
2332
2333     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2334        CopySid(*cbSid, Sid, pSid);
2335     if (*cbSid < GetLengthSid(pSid))
2336     {
2337        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2338        ret = FALSE;
2339     }
2340     *cbSid = GetLengthSid(pSid);
2341     
2342     if (ReferencedDomainName != NULL && (*cchReferencedDomainName > strlenW(dm)))
2343       strcpyW(ReferencedDomainName, dm);
2344
2345     if (*cchReferencedDomainName <= strlenW(dm))
2346     {
2347        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2348        ret = FALSE;
2349     }
2350
2351     *cchReferencedDomainName = strlenW(dm)+1;
2352
2353     FreeSid(pSid);
2354
2355     return ret;
2356 }
2357
2358 /******************************************************************************
2359  * PrivilegeCheck [ADVAPI32.@]
2360  */
2361 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2362 {
2363     BOOL ret;
2364     BOOLEAN Result;
2365
2366     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2367
2368     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2369     if (ret)
2370         *pfResult = Result;
2371     return ret;
2372 }
2373
2374 /******************************************************************************
2375  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2376  */
2377 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2378   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2379   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2380   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2381 {
2382         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2383                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2384                 SecurityDescriptor, DesiredAccess, GenericMapping,
2385                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2386         return TRUE;
2387 }
2388
2389 /******************************************************************************
2390  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2391  */
2392 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2393   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2394   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2395   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2396 {
2397         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2398                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2399                 SecurityDescriptor, DesiredAccess, GenericMapping,
2400                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2401         return TRUE;
2402 }
2403
2404 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2405 {
2406     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2407
2408     return TRUE;
2409 }
2410
2411 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2412 {
2413     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2414
2415     return TRUE;
2416 }
2417
2418 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2419 {
2420     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2421
2422     return TRUE;
2423 }
2424
2425 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2426   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2427   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2428   LPBOOL GenerateOnClose)
2429 {
2430         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2431                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2432         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2433         GenerateOnClose);
2434
2435     return TRUE;
2436 }
2437
2438 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2439   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2440   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2441   LPBOOL GenerateOnClose)
2442 {
2443     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2444         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2445         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2446         GenerateOnClose);
2447
2448     return TRUE;
2449 }
2450
2451 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2452   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2453 {
2454     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
2455           DesiredAccess, Privileges, AccessGranted);
2456
2457     return TRUE;
2458 }
2459
2460 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
2461   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2462 {
2463     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
2464           DesiredAccess, Privileges, AccessGranted);
2465
2466     return TRUE;
2467 }
2468
2469 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
2470                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2471 {
2472     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
2473           ClientToken, Privileges, AccessGranted);
2474
2475     return TRUE;
2476 }
2477
2478 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
2479                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
2480 {
2481     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
2482           ClientToken, Privileges, AccessGranted);
2483
2484     return TRUE;
2485 }
2486
2487 /******************************************************************************
2488  * GetSecurityInfo [ADVAPI32.@]
2489  */
2490 DWORD WINAPI GetSecurityInfo(
2491     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
2492     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
2493     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
2494     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
2495 )
2496 {
2497   FIXME("stub!\n");
2498   return ERROR_BAD_PROVIDER;
2499 }
2500
2501 /******************************************************************************
2502  * GetSecurityInfoExW [ADVAPI32.@]
2503  */
2504 DWORD WINAPI GetSecurityInfoExW(
2505         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
2506         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
2507         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
2508         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
2509 )
2510 {
2511   FIXME("stub!\n");
2512   return ERROR_BAD_PROVIDER; 
2513 }
2514
2515 /******************************************************************************
2516  * BuildExplicitAccessWithNameA [ADVAPI32.@]
2517  */
2518 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
2519                                           LPSTR pTrusteeName, DWORD AccessPermissions,
2520                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2521 {
2522     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
2523           AccessPermissions, AccessMode, Inheritance);
2524
2525     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2526     pExplicitAccess->grfAccessMode = AccessMode;
2527     pExplicitAccess->grfInheritance = Inheritance;
2528
2529     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2530     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2531     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2532     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2533     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2534 }
2535
2536 /******************************************************************************
2537  * BuildExplicitAccessWithNameW [ADVAPI32.@]
2538  */
2539 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
2540                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
2541                                           ACCESS_MODE AccessMode, DWORD Inheritance )
2542 {
2543     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
2544           AccessPermissions, AccessMode, Inheritance);
2545
2546     pExplicitAccess->grfAccessPermissions = AccessPermissions;
2547     pExplicitAccess->grfAccessMode = AccessMode;
2548     pExplicitAccess->grfInheritance = Inheritance;
2549
2550     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
2551     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2552     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
2553     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
2554     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
2555 }
2556
2557 /******************************************************************************
2558  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
2559  */
2560 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
2561                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
2562                                              LPSTR InheritedObjectTypeName, LPSTR Name )
2563 {
2564     DWORD ObjectsPresent = 0;
2565
2566     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2567           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
2568
2569     /* Fill the OBJECTS_AND_NAME structure */
2570     pObjName->ObjectType = ObjectType;
2571     if (ObjectTypeName != NULL)
2572     {
2573         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2574     }
2575
2576     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2577     if (InheritedObjectTypeName != NULL)
2578     {
2579         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2580     }
2581
2582     pObjName->ObjectsPresent = ObjectsPresent;
2583     pObjName->ptstrName = Name;
2584
2585     /* Fill the TRUSTEE structure */
2586     pTrustee->pMultipleTrustee = NULL;
2587     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2588     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2589     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2590     pTrustee->ptstrName = (LPSTR)pObjName;
2591 }
2592
2593 /******************************************************************************
2594  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
2595  */
2596 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
2597                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
2598                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
2599 {
2600     DWORD ObjectsPresent = 0;
2601
2602     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
2603           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
2604
2605     /* Fill the OBJECTS_AND_NAME structure */
2606     pObjName->ObjectType = ObjectType;
2607     if (ObjectTypeName != NULL)
2608     {
2609         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2610     }
2611
2612     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
2613     if (InheritedObjectTypeName != NULL)
2614     {
2615         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2616     }
2617
2618     pObjName->ObjectsPresent = ObjectsPresent;
2619     pObjName->ptstrName = Name;
2620
2621     /* Fill the TRUSTEE structure */
2622     pTrustee->pMultipleTrustee = NULL;
2623     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2624     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
2625     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2626     pTrustee->ptstrName = (LPWSTR)pObjName;
2627 }
2628
2629 /******************************************************************************
2630  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
2631  */
2632 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
2633                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2634 {
2635     DWORD ObjectsPresent = 0;
2636
2637     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2638
2639     /* Fill the OBJECTS_AND_SID structure */
2640     if (pObjectGuid != NULL)
2641     {
2642         pObjSid->ObjectTypeGuid = *pObjectGuid;
2643         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2644     }
2645     else
2646     {
2647         ZeroMemory(&pObjSid->ObjectTypeGuid,
2648                    sizeof(GUID));
2649     }
2650
2651     if (pInheritedObjectGuid != NULL)
2652     {
2653         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2654         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2655     }
2656     else
2657     {
2658         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2659                    sizeof(GUID));
2660     }
2661
2662     pObjSid->ObjectsPresent = ObjectsPresent;
2663     pObjSid->pSid = pSid;
2664
2665     /* Fill the TRUSTEE structure */
2666     pTrustee->pMultipleTrustee = NULL;
2667     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2668     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2669     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2670     pTrustee->ptstrName = (LPSTR) pObjSid;
2671 }
2672
2673 /******************************************************************************
2674  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
2675  */
2676 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
2677                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
2678 {
2679     DWORD ObjectsPresent = 0;
2680
2681     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
2682
2683     /* Fill the OBJECTS_AND_SID structure */
2684     if (pObjectGuid != NULL)
2685     {
2686         pObjSid->ObjectTypeGuid = *pObjectGuid;
2687         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
2688     }
2689     else
2690     {
2691         ZeroMemory(&pObjSid->ObjectTypeGuid,
2692                    sizeof(GUID));
2693     }
2694
2695     if (pInheritedObjectGuid != NULL)
2696     {
2697         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
2698         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
2699     }
2700     else
2701     {
2702         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
2703                    sizeof(GUID));
2704     }
2705
2706     pObjSid->ObjectsPresent = ObjectsPresent;
2707     pObjSid->pSid = pSid;
2708
2709     /* Fill the TRUSTEE structure */
2710     pTrustee->pMultipleTrustee = NULL;
2711     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2712     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
2713     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2714     pTrustee->ptstrName = (LPWSTR) pObjSid;
2715 }
2716
2717 /******************************************************************************
2718  * BuildTrusteeWithSidA [ADVAPI32.@]
2719  */
2720 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
2721 {
2722     TRACE("%p %p\n", pTrustee, pSid);
2723
2724     pTrustee->pMultipleTrustee = NULL;
2725     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2726     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2727     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2728     pTrustee->ptstrName = (LPSTR) pSid;
2729 }
2730
2731 /******************************************************************************
2732  * BuildTrusteeWithSidW [ADVAPI32.@]
2733  */
2734 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
2735 {
2736     TRACE("%p %p\n", pTrustee, pSid);
2737
2738     pTrustee->pMultipleTrustee = NULL;
2739     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2740     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
2741     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2742     pTrustee->ptstrName = (LPWSTR) pSid;
2743 }
2744
2745 /******************************************************************************
2746  * BuildTrusteeWithNameA [ADVAPI32.@]
2747  */
2748 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
2749 {
2750     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
2751
2752     pTrustee->pMultipleTrustee = NULL;
2753     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2754     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2755     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2756     pTrustee->ptstrName = name;
2757 }
2758
2759 /******************************************************************************
2760  * BuildTrusteeWithNameW [ADVAPI32.@]
2761  */
2762 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
2763 {
2764     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
2765
2766     pTrustee->pMultipleTrustee = NULL;
2767     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
2768     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
2769     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
2770     pTrustee->ptstrName = name;
2771 }
2772
2773 /****************************************************************************** 
2774  * GetTrusteeFormA [ADVAPI32.@] 
2775  */ 
2776 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
2777 {  
2778     TRACE("(%p)\n", pTrustee); 
2779   
2780     if (!pTrustee) 
2781         return TRUSTEE_BAD_FORM; 
2782   
2783     return pTrustee->TrusteeForm; 
2784 }  
2785   
2786 /****************************************************************************** 
2787  * GetTrusteeFormW [ADVAPI32.@] 
2788  */ 
2789 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
2790 {  
2791     TRACE("(%p)\n", pTrustee); 
2792   
2793     if (!pTrustee) 
2794         return TRUSTEE_BAD_FORM; 
2795   
2796     return pTrustee->TrusteeForm; 
2797 }  
2798   
2799 /****************************************************************************** 
2800  * GetTrusteeNameA [ADVAPI32.@] 
2801  */ 
2802 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
2803 {  
2804     TRACE("(%p)\n", pTrustee); 
2805   
2806     if (!pTrustee) 
2807         return NULL; 
2808   
2809     return pTrustee->ptstrName; 
2810 }  
2811   
2812 /****************************************************************************** 
2813  * GetTrusteeNameW [ADVAPI32.@] 
2814  */ 
2815 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
2816 {  
2817     TRACE("(%p)\n", pTrustee); 
2818   
2819     if (!pTrustee) 
2820         return NULL; 
2821   
2822     return pTrustee->ptstrName; 
2823 }  
2824   
2825 /****************************************************************************** 
2826  * GetTrusteeTypeA [ADVAPI32.@] 
2827  */ 
2828 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
2829 {  
2830     TRACE("(%p)\n", pTrustee); 
2831   
2832     if (!pTrustee) 
2833         return TRUSTEE_IS_UNKNOWN; 
2834   
2835     return pTrustee->TrusteeType; 
2836 }  
2837   
2838 /****************************************************************************** 
2839  * GetTrusteeTypeW [ADVAPI32.@] 
2840  */ 
2841 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
2842 {  
2843     TRACE("(%p)\n", pTrustee); 
2844   
2845     if (!pTrustee) 
2846         return TRUSTEE_IS_UNKNOWN; 
2847   
2848     return pTrustee->TrusteeType; 
2849
2850  
2851 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
2852                                DWORD nAclInformationLength,
2853                                ACL_INFORMATION_CLASS dwAclInformationClass )
2854 {
2855     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
2856           nAclInformationLength, dwAclInformationClass);
2857
2858     return TRUE;
2859 }
2860
2861 /******************************************************************************
2862  * SetEntriesInAclA [ADVAPI32.@]
2863  */
2864 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
2865                                PACL OldAcl, PACL* NewAcl )
2866 {
2867     FIXME("%d %p %p %p\n",count,pEntries,OldAcl,NewAcl);
2868     return ERROR_CALL_NOT_IMPLEMENTED;
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 (owner && (info & OWNER_SECURITY_INFORMATION))
3955     {
3956         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3957         relative->Owner = offset;
3958         *owner = buffer + offset;
3959         offset += sizeof(sidWorld);
3960     }
3961     if (group && (info & GROUP_SECURITY_INFORMATION))
3962     {
3963         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
3964         relative->Group = offset;
3965         *group = buffer + offset;
3966         offset += sizeof(sidWorld);
3967     }
3968     if (dacl && (info & DACL_SECURITY_INFORMATION))
3969     {
3970         GetWorldAccessACL( (PACL)(buffer + offset) );
3971         relative->Dacl = offset;
3972         *dacl = (PACL)(buffer + offset);
3973         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
3974     }
3975     if (sacl && (info & SACL_SECURITY_INFORMATION))
3976     {
3977         GetWorldAccessACL( (PACL)(buffer + offset) );
3978         relative->Sacl = offset;
3979         *sacl = (PACL)(buffer + offset);
3980     }
3981     return ERROR_SUCCESS;
3982 }
3983
3984 /******************************************************************************
3985  * DecryptFileW [ADVAPI32.@]
3986  */
3987 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
3988 {
3989     FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
3990     return TRUE;
3991 }
3992
3993 /******************************************************************************
3994  * DecryptFileA [ADVAPI32.@]
3995  */
3996 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
3997 {
3998     FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
3999     return TRUE;
4000 }
4001
4002 /******************************************************************************
4003  * EncryptFileW [ADVAPI32.@]
4004  */
4005 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
4006 {
4007     FIXME("%s\n", debugstr_w(lpFileName));
4008     return TRUE;
4009 }
4010
4011 /******************************************************************************
4012  * EncryptFileA [ADVAPI32.@]
4013  */
4014 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
4015 {
4016     FIXME("%s\n", debugstr_a(lpFileName));
4017     return TRUE;
4018 }
4019
4020 /******************************************************************************
4021  * FileEncryptionStatusW [ADVAPI32.@]
4022  */
4023 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
4024 {
4025     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
4026     if (!lpStatus)
4027         return FALSE;
4028     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4029     return TRUE;
4030 }
4031
4032 /******************************************************************************
4033  * FileEncryptionStatusA [ADVAPI32.@]
4034  */
4035 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
4036 {
4037     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
4038     if (!lpStatus)
4039         return FALSE;
4040     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
4041     return TRUE;
4042 }
4043
4044 /******************************************************************************
4045  * SetSecurityInfo [ADVAPI32.@]
4046  */
4047 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
4048                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
4049                       PSID psidGroup, PACL pDacl, PACL pSacl) {
4050     FIXME("stub\n");
4051     return ERROR_SUCCESS;
4052 }