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