~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/advapi32/security.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

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