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