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