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

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

Version: ~ [ wine-1.5.4 ] ~ [ wine-1.5.3 ] ~ [ wine-1.5.2 ] ~ [ wine-1.5.1 ] ~ [ wine-1.5.0 ] ~ [ wine-1.4 ] ~ [ wine-1.4-rc6 ] ~ [ wine-1.4-rc5 ] ~ [ wine-1.4-rc4 ] ~ [ wine-1.4-rc3 ] ~ [ wine-1.4-rc2 ] ~ [ wine-1.4-rc1 ] ~ [ wine-1.3.37 ] ~ [ wine-1.3.36 ] ~ [ wine-1.3.35 ] ~ [ wine-1.3.34 ] ~ [ wine-1.3.33 ] ~ [ wine-1.3.32 ] ~ [ wine-1.3.31 ] ~ [ wine-1.3.30 ] ~ [ wine-1.3.29 ] ~ [ wine-1.3.28 ] ~ [ wine-1.3.27 ] ~ [ wine-1.3.26 ] ~ [ wine-1.3.25 ] ~ [ wine-1.3.24 ] ~ [ wine-1.3.23 ] ~ [ wine-1.3.22 ] ~ [ wine-1.3.21 ] ~ [ wine-1.3.20 ] ~ [ wine-1.3.19 ] ~ [ wine-1.3.18 ] ~ [ wine-1.2.3 ] ~ [ wine-1.3.17 ] ~ [ wine-1.3.16 ] ~ [ wine-1.3.15 ] ~ [ wine-1.3.14 ] ~ [ wine-1.3.13 ] ~ [ wine-1.3.12 ] ~ [ wine-1.3.11 ] ~ [ wine-1.3.10 ] ~ [ wine-1.3.9 ] ~ [ wine-1.2.2 ] ~ [ wine-1.3.8 ] ~ [ wine-1.3.7 ] ~ [ wine-1.3.6 ] ~ [ wine-1.3.5 ] ~ [ wine-1.2.1 ] ~ [ wine-1.3.4 ] ~ [ wine-1.3.3 ] ~ [ wine-1.3.2 ] ~ [ wine-1.3.1 ] ~ [ wine-1.3.0 ] ~ [ wine-1.2 ] ~ [ wine-1.2-rc7 ] ~ [ wine-1.2-rc6 ] ~ [ wine-1.2-rc5 ] ~ [ wine-1.2-rc4 ] ~ [ wine-1.2-rc3 ] ~ [ wine-1.2-rc2 ] ~ [ wine-1.2-rc1 ] ~ [ wine-1.1.44 ] ~ [ wine-1.1.43 ] ~ [ wine-1.1.42 ] ~ [ wine-1.1.41 ] ~ [ wine-1.1.40 ] ~ [ wine-1.1.39 ] ~ [ wine-1.1.38 ] ~ [ wine-1.1.37 ] ~ [ wine-1.1.36 ] ~ [ wine-1.1.35 ] ~ [ wine-1.1.34 ] ~ [ 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 BOOL ADVAPI_GetComputerSid(PSID sid)
451 {
452     static const struct /* same fields as struct SID */
453     {
454         BYTE Revision;
455         BYTE SubAuthorityCount;
456         SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
457         DWORD SubAuthority[4];
458     } computer_sid =
459     { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } };
460 
461     memcpy( sid, &computer_sid, sizeof(computer_sid) );
462     return TRUE;
463 }
464 
465 /*      ##############################
466         ######  TOKEN FUNCTIONS ######
467         ##############################
468 */
469 
470 /******************************************************************************
471  * OpenProcessToken                     [ADVAPI32.@]
472  * Opens the access token associated with a process handle.
473  *
474  * PARAMS
475  *   ProcessHandle [I] Handle to process
476  *   DesiredAccess [I] Desired access to process
477  *   TokenHandle   [O] Pointer to handle of open access token
478  *
479  * RETURNS
480  *  Success: TRUE. TokenHandle contains the access token.
481  *  Failure: FALSE.
482  *
483  * NOTES
484  *  See NtOpenProcessToken.
485  */
486 BOOL WINAPI
487 OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
488                   HANDLE *TokenHandle )
489 {
490         return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
491 }
492 
493 /******************************************************************************
494  * OpenThreadToken [ADVAPI32.@]
495  *
496  * Opens the access token associated with a thread handle.
497  *
498  * PARAMS
499  *   ThreadHandle  [I] Handle to process
500  *   DesiredAccess [I] Desired access to the thread
501  *   OpenAsSelf    [I] ???
502  *   TokenHandle   [O] Destination for the token handle
503  *
504  * RETURNS
505  *  Success: TRUE. TokenHandle contains the access token.
506  *  Failure: FALSE.
507  *
508  * NOTES
509  *  See NtOpenThreadToken.
510  */
511 BOOL WINAPI
512 OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
513                  BOOL OpenAsSelf, HANDLE *TokenHandle)
514 {
515         return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
516 }
517 
518 BOOL WINAPI
519 AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
520                    DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
521 {
522     return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
523                                              PreviousState, ReturnLength));
524 }
525 
526 /******************************************************************************
527  * AdjustTokenPrivileges [ADVAPI32.@]
528  *
529  * Adjust the privileges of an open token handle.
530  * 
531  * PARAMS
532  *  TokenHandle          [I]   Handle from OpenProcessToken() or OpenThreadToken() 
533  *  DisableAllPrivileges [I]   TRUE=Remove all privileges, FALSE=Use NewState
534  *  NewState             [I]   Desired new privileges of the token
535  *  BufferLength         [I]   Length of NewState
536  *  PreviousState        [O]   Destination for the previous state
537  *  ReturnLength         [I/O] Size of PreviousState
538  *
539  *
540  * RETURNS
541  *  Success: TRUE. Privileges are set to NewState and PreviousState is updated.
542  *  Failure: FALSE.
543  *
544  * NOTES
545  *  See NtAdjustPrivilegesToken.
546  */
547 BOOL WINAPI
548 AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
549                        PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
550                        PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
551 {
552     NTSTATUS status;
553 
554     TRACE("\n");
555     
556     status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
557                                                      NewState, BufferLength, PreviousState,
558                                                      ReturnLength);
559     SetLastError( RtlNtStatusToDosError( status ));
560     if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
561         return TRUE;
562     else
563         return FALSE;
564 }
565 
566 /******************************************************************************
567  * CheckTokenMembership [ADVAPI32.@]
568  *
569  * Determine if an access token is a member of a SID.
570  * 
571  * PARAMS
572  *   TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
573  *   SidToCheck  [I] SID that possibly contains the token
574  *   IsMember    [O] Destination for result.
575  *
576  * RETURNS
577  *  Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
578  *  Failure: FALSE.
579  */
580 BOOL WINAPI
581 CheckTokenMembership( HANDLE token, PSID sid_to_check,
582                       PBOOL is_member )
583 {
584     PTOKEN_GROUPS token_groups = NULL;
585     HANDLE thread_token = NULL;
586     DWORD size, i;
587     BOOL ret;
588 
589     TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
590 
591     *is_member = FALSE;
592 
593     if (!token)
594     {
595         if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
596         {
597             HANDLE process_token;
598             ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
599             if (!ret)
600                 goto exit;
601             ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
602                 NULL, SecurityImpersonation, TokenImpersonation,
603                 &thread_token);
604             CloseHandle(process_token);
605             if (!ret)
606                 goto exit;
607         }
608         token = thread_token;
609     }
610     else
611     {
612         TOKEN_TYPE type;
613 
614         ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
615         if (!ret) goto exit;
616 
617         if (type == TokenPrimary)
618         {
619             SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
620             return FALSE;
621         }
622     }
623 
624     ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
625     if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
626         goto exit;
627 
628     token_groups = HeapAlloc(GetProcessHeap(), 0, size);
629     if (!token_groups)
630     {
631         ret = FALSE;
632         goto exit;
633     }
634 
635     ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
636     if (!ret)
637         goto exit;
638 
639     for (i = 0; i < token_groups->GroupCount; i++)
640     {
641         TRACE("Groups[%d]: {0x%x, %s}\n", i,
642             token_groups->Groups[i].Attributes,
643             debugstr_sid(token_groups->Groups[i].Sid));
644         if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
645             EqualSid(sid_to_check, token_groups->Groups[i].Sid))
646         {
647             *is_member = TRUE;
648             TRACE("sid enabled and found in token\n");
649             break;
650         }
651     }
652 
653 exit:
654     HeapFree(GetProcessHeap(), 0, token_groups);
655     if (thread_token != NULL) CloseHandle(thread_token);
656 
657     return ret;
658 }
659 
660 /******************************************************************************
661  * GetTokenInformation [ADVAPI32.@]
662  *
663  * Get a type of information about an access token.
664  *
665  * PARAMS
666  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
667  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
668  *   tokeninfo       [O] Destination for token information
669  *   tokeninfolength [I] Length of tokeninfo
670  *   retlen          [O] Destination for returned token information length
671  *
672  * RETURNS
673  *  Success: TRUE. tokeninfo contains retlen bytes of token information
674  *  Failure: FALSE.
675  *
676  * NOTES
677  *  See NtQueryInformationToken.
678  */
679 BOOL WINAPI
680 GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
681                      LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
682 {
683     TRACE("(%p, %s, %p, %d, %p):\n",
684           token,
685           (tokeninfoclass == TokenUser) ? "TokenUser" :
686           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
687           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
688           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
689           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
690           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
691           (tokeninfoclass == TokenSource) ? "TokenSource" :
692           (tokeninfoclass == TokenType) ? "TokenType" :
693           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
694           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
695           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
696           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
697           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
698           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
699           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
700           "Unknown",
701           tokeninfo, tokeninfolength, retlen);
702     return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
703                                                   tokeninfolength, retlen));
704 }
705 
706 /******************************************************************************
707  * SetTokenInformation [ADVAPI32.@]
708  *
709  * Set information for an access token.
710  *
711  * PARAMS
712  *   token           [I] Handle from OpenProcessToken() or OpenThreadToken()
713  *   tokeninfoclass  [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
714  *   tokeninfo       [I] Token information to set
715  *   tokeninfolength [I] Length of tokeninfo
716  *
717  * RETURNS
718  *  Success: TRUE. The information for the token is set to tokeninfo.
719  *  Failure: FALSE.
720  */
721 BOOL WINAPI
722 SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
723                      LPVOID tokeninfo, DWORD tokeninfolength )
724 {
725     TRACE("(%p, %s, %p, %d): stub\n",
726           token,
727           (tokeninfoclass == TokenUser) ? "TokenUser" :
728           (tokeninfoclass == TokenGroups) ? "TokenGroups" :
729           (tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
730           (tokeninfoclass == TokenOwner) ? "TokenOwner" :
731           (tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
732           (tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
733           (tokeninfoclass == TokenSource) ? "TokenSource" :
734           (tokeninfoclass == TokenType) ? "TokenType" :
735           (tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
736           (tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
737           (tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
738           (tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
739           (tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
740           (tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
741           (tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
742           "Unknown",
743           tokeninfo, tokeninfolength);
744 
745     return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
746 }
747 
748 /*************************************************************************
749  * SetThreadToken [ADVAPI32.@]
750  *
751  * Assigns an 'impersonation token' to a thread so it can assume the
752  * security privileges of another thread or process.  Can also remove
753  * a previously assigned token. 
754  *
755  * PARAMS
756  *   thread          [O] Handle to thread to set the token for
757  *   token           [I] Token to set
758  *
759  * RETURNS
760  *  Success: TRUE. The threads access token is set to token
761  *  Failure: FALSE.
762  *
763  * NOTES
764  *  Only supported on NT or higher. On Win9X this function does nothing.
765  *  See SetTokenInformation.
766  */
767 BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
768 {
769     return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
770                                                  ThreadImpersonationToken, &token, sizeof token ));
771 }
772 
773 /*************************************************************************
774  * CreateRestrictedToken [ADVAPI32.@]
775  *
776  * Create a new more restricted token from an existing token.
777  *
778  * PARAMS
779  *   baseToken       [I] Token to base the new restricted token on
780  *   flags           [I] Options
781  *   nDisableSids    [I] Length of disableSids array
782  *   disableSids     [I] Array of SIDs to disable in the new token
783  *   nDeletePrivs    [I] Length of deletePrivs array
784  *   deletePrivs     [I] Array of privileges to delete in the new token
785  *   nRestrictSids   [I] Length of restrictSids array
786  *   restrictSids    [I] Array of SIDs to restrict in the new token
787  *   newToken        [O] Address where the new token is stored
788  *
789  * RETURNS
790  *  Success: TRUE
791  *  Failure: FALSE
792  */
793 BOOL WINAPI CreateRestrictedToken(
794     HANDLE baseToken,
795     DWORD flags,
796     DWORD nDisableSids,
797     PSID_AND_ATTRIBUTES disableSids,
798     DWORD nDeletePrivs,
799     PLUID_AND_ATTRIBUTES deletePrivs,
800     DWORD nRestrictSids,
801     PSID_AND_ATTRIBUTES restrictSids,
802     PHANDLE newToken)
803 {
804     FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
805           baseToken, flags, nDisableSids, disableSids,
806           nDeletePrivs, deletePrivs,
807           nRestrictSids, restrictSids,
808           newToken);
809     SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
810     return FALSE;
811 }
812 
813 /*      ##############################
814         ######  SID FUNCTIONS   ######
815         ##############################
816 */
817 
818 /******************************************************************************
819  * AllocateAndInitializeSid [ADVAPI32.@]
820  *
821  * PARAMS
822  *   pIdentifierAuthority []
823  *   nSubAuthorityCount   []
824  *   nSubAuthority0       []
825  *   nSubAuthority1       []
826  *   nSubAuthority2       []
827  *   nSubAuthority3       []
828  *   nSubAuthority4       []
829  *   nSubAuthority5       []
830  *   nSubAuthority6       []
831  *   nSubAuthority7       []
832  *   pSid                 []
833  */
834 BOOL WINAPI
835 AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
836                           BYTE nSubAuthorityCount,
837                           DWORD nSubAuthority0, DWORD nSubAuthority1,
838                           DWORD nSubAuthority2, DWORD nSubAuthority3,
839                           DWORD nSubAuthority4, DWORD nSubAuthority5,
840                           DWORD nSubAuthority6, DWORD nSubAuthority7,
841                           PSID *pSid )
842 {
843     return set_ntstatus( RtlAllocateAndInitializeSid(
844                              pIdentifierAuthority, nSubAuthorityCount,
845                              nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3,
846                              nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7,
847                              pSid ));
848 }
849 
850 /******************************************************************************
851  * FreeSid [ADVAPI32.@]
852  *
853  * PARAMS
854  *   pSid []
855  */
856 PVOID WINAPI
857 FreeSid( PSID pSid )
858 {
859         RtlFreeSid(pSid);
860         return NULL; /* is documented like this */
861 }
862 
863 /******************************************************************************
864  * CopySid [ADVAPI32.@]
865  *
866  * PARAMS
867  *   nDestinationSidLength []
868  *   pDestinationSid       []
869  *   pSourceSid            []
870  */
871 BOOL WINAPI
872 CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid )
873 {
874         return RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid);
875 }
876 
877 /******************************************************************************
878  * CreateWellKnownSid [ADVAPI32.@]
879  */
880 BOOL WINAPI
881 CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType,
882                     PSID DomainSid,
883                     PSID pSid,
884                     DWORD* cbSid)
885 {
886     unsigned int i;
887     TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
888 
889     if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
890     {
891         SetLastError(ERROR_INVALID_PARAMETER);
892         return FALSE;
893     }
894 
895     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
896         if (WellKnownSids[i].Type == WellKnownSidType) {
897             DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
898 
899             if (*cbSid < length)
900             {
901                 *cbSid = length;
902                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
903                 return FALSE;
904             }
905             if (!pSid)
906             {
907                 SetLastError(ERROR_INVALID_PARAMETER);
908                 return FALSE;
909             }
910             CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
911             *cbSid = length;
912             return TRUE;
913         }
914     }
915 
916     if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
917     {
918         SetLastError(ERROR_INVALID_PARAMETER);
919         return FALSE;
920     }
921 
922     for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
923         if (WellKnownRids[i].Type == WellKnownSidType) {
924             UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
925             DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
926             DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
927 
928             if (*cbSid < output_sid_length)
929             {
930                 *cbSid = output_sid_length;
931                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
932                 return FALSE;
933             }
934             if (!pSid)
935             {
936                 SetLastError(ERROR_INVALID_PARAMETER);
937                 return FALSE;
938             }
939             CopyMemory(pSid, DomainSid, domain_sid_length);
940             (*GetSidSubAuthorityCount(pSid))++;
941             (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
942             *cbSid = output_sid_length;
943             return TRUE;
944         }
945 
946     SetLastError(ERROR_INVALID_PARAMETER);
947     return FALSE;
948 }
949 
950 /******************************************************************************
951  * IsWellKnownSid [ADVAPI32.@]
952  */
953 BOOL WINAPI
954 IsWellKnownSid( PSID pSid, WELL_KNOWN_SID_TYPE WellKnownSidType )
955 {
956     unsigned int i;
957     TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
958 
959     for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
960         if (WellKnownSids[i].Type == WellKnownSidType)
961             if (EqualSid(pSid, (PSID)&(WellKnownSids[i].Sid.Revision)))
962                 return TRUE;
963 
964     return FALSE;
965 }
966 
967 BOOL WINAPI
968 IsTokenRestricted( HANDLE TokenHandle )
969 {
970     TOKEN_GROUPS *groups;
971     DWORD size;
972     NTSTATUS status;
973     BOOL restricted;
974 
975     TRACE("(%p)\n", TokenHandle);
976  
977     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
978     if (status != STATUS_BUFFER_TOO_SMALL)
979         return FALSE;
980  
981     groups = HeapAlloc(GetProcessHeap(), 0, size);
982     if (!groups)
983     {
984         SetLastError(ERROR_OUTOFMEMORY);
985         return FALSE;
986     }
987  
988     status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
989     if (status != STATUS_SUCCESS)
990     {
991         HeapFree(GetProcessHeap(), 0, groups);
992         return set_ntstatus(status);
993     }
994  
995     if (groups->GroupCount)
996         restricted = TRUE;
997     else
998         restricted = FALSE;
999      
1000     HeapFree(GetProcessHeap(), 0, groups);
1001  
1002     return restricted;
1003 }
1004 
1005 /******************************************************************************
1006  * IsValidSid [ADVAPI32.@]
1007  *
1008  * PARAMS
1009  *   pSid []
1010  */
1011 BOOL WINAPI
1012 IsValidSid( PSID pSid )
1013 {
1014         return RtlValidSid( pSid );
1015 }
1016 
1017 /******************************************************************************
1018  * EqualSid [ADVAPI32.@]
1019  *
1020  * PARAMS
1021  *   pSid1 []
1022  *   pSid2 []
1023  */
1024 BOOL WINAPI
1025 EqualSid( PSID pSid1, PSID pSid2 )
1026 {
1027         BOOL ret = RtlEqualSid( pSid1, pSid2 );
1028         SetLastError(ERROR_SUCCESS);
1029         return ret;
1030 }
1031 
1032 /******************************************************************************
1033  * EqualPrefixSid [ADVAPI32.@]
1034  */
1035 BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2)
1036 {
1037         return RtlEqualPrefixSid(pSid1, pSid2);
1038 }
1039 
1040 /******************************************************************************
1041  * GetSidLengthRequired [ADVAPI32.@]
1042  *
1043  * PARAMS
1044  *   nSubAuthorityCount []
1045  */
1046 DWORD WINAPI
1047 GetSidLengthRequired( BYTE nSubAuthorityCount )
1048 {
1049         return RtlLengthRequiredSid(nSubAuthorityCount);
1050 }
1051 
1052 /******************************************************************************
1053  * InitializeSid [ADVAPI32.@]
1054  *
1055  * PARAMS
1056  *   pIdentifierAuthority []
1057  */
1058 BOOL WINAPI
1059 InitializeSid (
1060         PSID pSid,
1061         PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
1062         BYTE nSubAuthorityCount)
1063 {
1064         return RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount);
1065 }
1066 
1067 DWORD WINAPI
1068 GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
1069 {
1070     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1071 
1072     *pAccessRights = STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL;
1073     return 0;
1074 }
1075 
1076 DWORD WINAPI
1077 GetEffectiveRightsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pAccessRights )
1078 {
1079     FIXME("%p %p %p - stub\n", pacl, pTrustee, pAccessRights);
1080 
1081     return 1;
1082 }
1083 
1084 /******************************************************************************
1085  * GetSidIdentifierAuthority [ADVAPI32.@]
1086  *
1087  * PARAMS
1088  *   pSid []
1089  */
1090 PSID_IDENTIFIER_AUTHORITY WINAPI
1091 GetSidIdentifierAuthority( PSID pSid )
1092 {
1093         return RtlIdentifierAuthoritySid(pSid);
1094 }
1095 
1096 /******************************************************************************
1097  * GetSidSubAuthority [ADVAPI32.@]
1098  *
1099  * PARAMS
1100  *   pSid          []
1101  *   nSubAuthority []
1102  */
1103 PDWORD WINAPI
1104 GetSidSubAuthority( PSID pSid, DWORD nSubAuthority )
1105 {
1106         SetLastError(ERROR_SUCCESS);
1107         return RtlSubAuthoritySid(pSid, nSubAuthority);
1108 }
1109 
1110 /******************************************************************************
1111  * GetSidSubAuthorityCount [ADVAPI32.@]
1112  *
1113  * PARAMS
1114  *   pSid []
1115  */
1116 PUCHAR WINAPI
1117 GetSidSubAuthorityCount (PSID pSid)
1118 {
1119         SetLastError(ERROR_SUCCESS);
1120         return RtlSubAuthorityCountSid(pSid);
1121 }
1122 
1123 /******************************************************************************
1124  * GetLengthSid [ADVAPI32.@]
1125  *
1126  * PARAMS
1127  *   pSid []
1128  */
1129 DWORD WINAPI
1130 GetLengthSid (PSID pSid)
1131 {
1132         return RtlLengthSid(pSid);
1133 }
1134 
1135 /*      ##############################################
1136         ######  SECURITY DESCRIPTOR FUNCTIONS   ######
1137         ##############################################
1138 */
1139 
1140  /****************************************************************************** 
1141  * BuildSecurityDescriptorA [ADVAPI32.@]
1142  *
1143  * Builds a SD from 
1144  *
1145  * PARAMS
1146  *  pOwner                [I]
1147  *  pGroup                [I]
1148  *  cCountOfAccessEntries [I]
1149  *  pListOfAccessEntries  [I]
1150  *  cCountOfAuditEntries  [I]
1151  *  pListofAuditEntries   [I]
1152  *  pOldSD                [I]
1153  *  lpdwBufferLength      [I/O]
1154  *  pNewSD                [O]
1155  *
1156  * RETURNS
1157  *  Success: ERROR_SUCCESS
1158  *  Failure: nonzero error code from Winerror.h
1159  */
1160 DWORD WINAPI BuildSecurityDescriptorA(
1161     IN PTRUSTEEA pOwner,
1162     IN PTRUSTEEA pGroup,
1163     IN ULONG cCountOfAccessEntries,
1164     IN PEXPLICIT_ACCESSA pListOfAccessEntries,
1165     IN ULONG cCountOfAuditEntries,
1166     IN PEXPLICIT_ACCESSA pListofAuditEntries,
1167     IN PSECURITY_DESCRIPTOR pOldSD,
1168     IN OUT PULONG lpdwBufferLength,
1169     OUT PSECURITY_DESCRIPTOR* pNewSD)
1170 { 
1171     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1172           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1173           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1174  
1175     return ERROR_CALL_NOT_IMPLEMENTED;
1176 } 
1177  
1178 /******************************************************************************
1179  * BuildSecurityDescriptorW [ADVAPI32.@]
1180  *
1181  * See BuildSecurityDescriptorA.
1182  */
1183 DWORD WINAPI BuildSecurityDescriptorW(
1184     IN PTRUSTEEW pOwner,
1185     IN PTRUSTEEW pGroup,
1186     IN ULONG cCountOfAccessEntries,
1187     IN PEXPLICIT_ACCESSW pListOfAccessEntries,
1188     IN ULONG cCountOfAuditEntries,
1189     IN PEXPLICIT_ACCESSW pListofAuditEntries,
1190     IN PSECURITY_DESCRIPTOR pOldSD,
1191     IN OUT PULONG lpdwBufferLength,
1192     OUT PSECURITY_DESCRIPTOR* pNewSD)
1193 { 
1194     FIXME("(%p,%p,%d,%p,%d,%p,%p,%p,%p) stub!\n",pOwner,pGroup,
1195           cCountOfAccessEntries,pListOfAccessEntries,cCountOfAuditEntries,
1196           pListofAuditEntries,pOldSD,lpdwBufferLength,pNewSD);
1197  
1198     return ERROR_CALL_NOT_IMPLEMENTED;
1199 } 
1200 
1201 /******************************************************************************
1202  * InitializeSecurityDescriptor [ADVAPI32.@]
1203  *
1204  * PARAMS
1205  *   pDescr   []
1206  *   revision []
1207  */
1208 BOOL WINAPI
1209 InitializeSecurityDescriptor( PSECURITY_DESCRIPTOR pDescr, DWORD revision )
1210 {
1211         return set_ntstatus( RtlCreateSecurityDescriptor(pDescr, revision ));
1212 }
1213 
1214 
1215 /******************************************************************************
1216  * MakeAbsoluteSD [ADVAPI32.@]
1217  */
1218 BOOL WINAPI MakeAbsoluteSD (
1219         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1220         OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1221         OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
1222         OUT PACL pDacl,
1223         OUT LPDWORD lpdwDaclSize,
1224         OUT PACL pSacl,
1225         OUT LPDWORD lpdwSaclSize,
1226         OUT PSID pOwner,
1227         OUT LPDWORD lpdwOwnerSize,
1228         OUT PSID pPrimaryGroup,
1229         OUT LPDWORD lpdwPrimaryGroupSize)
1230 {
1231     return set_ntstatus( RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
1232                                                      pAbsoluteSecurityDescriptor,
1233                                                      lpdwAbsoluteSecurityDescriptorSize,
1234                                                      pDacl, lpdwDaclSize, pSacl, lpdwSaclSize,
1235                                                      pOwner, lpdwOwnerSize,
1236                                                      pPrimaryGroup, lpdwPrimaryGroupSize));
1237 }
1238 
1239 /******************************************************************************
1240  * GetKernelObjectSecurity [ADVAPI32.@]
1241  */
1242 BOOL WINAPI GetKernelObjectSecurity(
1243         HANDLE Handle,
1244         SECURITY_INFORMATION RequestedInformation,
1245         PSECURITY_DESCRIPTOR pSecurityDescriptor,
1246         DWORD nLength,
1247         LPDWORD lpnLengthNeeded )
1248 {
1249     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", Handle, RequestedInformation,
1250           pSecurityDescriptor, nLength, lpnLengthNeeded);
1251 
1252     return set_ntstatus( NtQuerySecurityObject(Handle, RequestedInformation, pSecurityDescriptor,
1253                                                nLength, lpnLengthNeeded ));
1254 }
1255 
1256 /******************************************************************************
1257  * GetPrivateObjectSecurity [ADVAPI32.@]
1258  */
1259 BOOL WINAPI GetPrivateObjectSecurity(
1260         PSECURITY_DESCRIPTOR ObjectDescriptor,
1261         SECURITY_INFORMATION SecurityInformation,
1262         PSECURITY_DESCRIPTOR ResultantDescriptor,
1263         DWORD DescriptorLength,
1264         PDWORD ReturnLength )
1265 {
1266     SECURITY_DESCRIPTOR desc;
1267     BOOL defaulted, present;
1268     PACL pacl;
1269     PSID psid;
1270 
1271     TRACE("(%p,0x%08x,%p,0x%08x,%p)\n", ObjectDescriptor, SecurityInformation,
1272           ResultantDescriptor, DescriptorLength, ReturnLength);
1273 
1274     if (!InitializeSecurityDescriptor(&desc, SECURITY_DESCRIPTOR_REVISION))
1275         return FALSE;
1276 
1277     if (SecurityInformation & OWNER_SECURITY_INFORMATION)
1278     {
1279         if (!GetSecurityDescriptorOwner(ObjectDescriptor, &psid, &defaulted))
1280             return FALSE;
1281         SetSecurityDescriptorOwner(&desc, psid, defaulted);
1282     }
1283 
1284     if (SecurityInformation & GROUP_SECURITY_INFORMATION)
1285     {
1286         if (!GetSecurityDescriptorGroup(ObjectDescriptor, &psid, &defaulted))
1287             return FALSE;
1288         SetSecurityDescriptorGroup(&desc, psid, defaulted);
1289     }
1290 
1291     if (SecurityInformation & DACL_SECURITY_INFORMATION)
1292     {
1293         if (!GetSecurityDescriptorDacl(ObjectDescriptor, &present, &pacl, &defaulted))
1294             return FALSE;
1295         SetSecurityDescriptorDacl(&desc, present, pacl, defaulted);
1296     }
1297 
1298     if (SecurityInformation & SACL_SECURITY_INFORMATION)
1299     {
1300         if (!GetSecurityDescriptorSacl(ObjectDescriptor, &present, &pacl, &defaulted))
1301             return FALSE;
1302         SetSecurityDescriptorSacl(&desc, present, pacl, defaulted);
1303     }
1304 
1305     *ReturnLength = DescriptorLength;
1306     return MakeSelfRelativeSD(&desc, ResultantDescriptor, ReturnLength);
1307 }
1308 
1309 /******************************************************************************
1310  * GetSecurityDescriptorLength [ADVAPI32.@]
1311  */
1312 DWORD WINAPI GetSecurityDescriptorLength( PSECURITY_DESCRIPTOR pDescr)
1313 {
1314         return RtlLengthSecurityDescriptor(pDescr);
1315 }
1316 
1317 /******************************************************************************
1318  * GetSecurityDescriptorOwner [ADVAPI32.@]
1319  *
1320  * PARAMS
1321  *   pOwner            []
1322  *   lpbOwnerDefaulted []
1323  */
1324 BOOL WINAPI
1325 GetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pDescr, PSID *pOwner,
1326                             LPBOOL lpbOwnerDefaulted )
1327 {
1328     BOOLEAN defaulted;
1329     BOOL ret = set_ntstatus( RtlGetOwnerSecurityDescriptor( pDescr, pOwner, &defaulted ));
1330     *lpbOwnerDefaulted = defaulted;
1331     return ret;
1332 }
1333 
1334 /******************************************************************************
1335  * SetSecurityDescriptorOwner [ADVAPI32.@]
1336  *
1337  * PARAMS
1338  */
1339 BOOL WINAPI SetSecurityDescriptorOwner( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1340                                    PSID pOwner, BOOL bOwnerDefaulted)
1341 {
1342     return set_ntstatus( RtlSetOwnerSecurityDescriptor(pSecurityDescriptor, pOwner, bOwnerDefaulted));
1343 }
1344 /******************************************************************************
1345  * GetSecurityDescriptorGroup                   [ADVAPI32.@]
1346  */
1347 BOOL WINAPI GetSecurityDescriptorGroup(
1348         PSECURITY_DESCRIPTOR SecurityDescriptor,
1349         PSID *Group,
1350         LPBOOL GroupDefaulted)
1351 {
1352     BOOLEAN defaulted;
1353     BOOL ret = set_ntstatus( RtlGetGroupSecurityDescriptor(SecurityDescriptor, Group, &defaulted ));
1354     *GroupDefaulted = defaulted;
1355     return ret;
1356 }
1357 /******************************************************************************
1358  * SetSecurityDescriptorGroup [ADVAPI32.@]
1359  */
1360 BOOL WINAPI SetSecurityDescriptorGroup ( PSECURITY_DESCRIPTOR SecurityDescriptor,
1361                                            PSID Group, BOOL GroupDefaulted)
1362 {
1363     return set_ntstatus( RtlSetGroupSecurityDescriptor( SecurityDescriptor, Group, GroupDefaulted));
1364 }
1365 
1366 /******************************************************************************
1367  * IsValidSecurityDescriptor [ADVAPI32.@]
1368  *
1369  * PARAMS
1370  *   lpsecdesc []
1371  */
1372 BOOL WINAPI
1373 IsValidSecurityDescriptor( PSECURITY_DESCRIPTOR SecurityDescriptor )
1374 {
1375     return set_ntstatus( RtlValidSecurityDescriptor(SecurityDescriptor));
1376 }
1377 
1378 /******************************************************************************
1379  *  GetSecurityDescriptorDacl                   [ADVAPI32.@]
1380  */
1381 BOOL WINAPI GetSecurityDescriptorDacl(
1382         IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
1383         OUT LPBOOL lpbDaclPresent,
1384         OUT PACL *pDacl,
1385         OUT LPBOOL lpbDaclDefaulted)
1386 {
1387     BOOLEAN present, defaulted;
1388     BOOL ret = set_ntstatus( RtlGetDaclSecurityDescriptor(pSecurityDescriptor, &present, pDacl, &defaulted));
1389     *lpbDaclPresent = present;
1390     *lpbDaclDefaulted = defaulted;
1391     return ret;
1392 }
1393 
1394 /******************************************************************************
1395  *  SetSecurityDescriptorDacl                   [ADVAPI32.@]
1396  */
1397 BOOL WINAPI
1398 SetSecurityDescriptorDacl (
1399         PSECURITY_DESCRIPTOR lpsd,
1400         BOOL daclpresent,
1401         PACL dacl,
1402         BOOL dacldefaulted )
1403 {
1404     return set_ntstatus( RtlSetDaclSecurityDescriptor (lpsd, daclpresent, dacl, dacldefaulted ) );
1405 }
1406 /******************************************************************************
1407  *  GetSecurityDescriptorSacl                   [ADVAPI32.@]
1408  */
1409 BOOL WINAPI GetSecurityDescriptorSacl(
1410         IN PSECURITY_DESCRIPTOR lpsd,
1411         OUT LPBOOL lpbSaclPresent,
1412         OUT PACL *pSacl,
1413         OUT LPBOOL lpbSaclDefaulted)
1414 {
1415     BOOLEAN present, defaulted;
1416     BOOL ret = set_ntstatus( RtlGetSaclSecurityDescriptor(lpsd, &present, pSacl, &defaulted) );
1417     *lpbSaclPresent = present;
1418     *lpbSaclDefaulted = defaulted;
1419     return ret;
1420 }
1421 
1422 /**************************************************************************
1423  * SetSecurityDescriptorSacl                    [ADVAPI32.@]
1424  */
1425 BOOL WINAPI SetSecurityDescriptorSacl (
1426         PSECURITY_DESCRIPTOR lpsd,
1427         BOOL saclpresent,
1428         PACL lpsacl,
1429         BOOL sacldefaulted)
1430 {
1431     return set_ntstatus (RtlSetSaclSecurityDescriptor(lpsd, saclpresent, lpsacl, sacldefaulted));
1432 }
1433 /******************************************************************************
1434  * MakeSelfRelativeSD [ADVAPI32.@]
1435  *
1436  * PARAMS
1437  *   lpabssecdesc  []
1438  *   lpselfsecdesc []
1439  *   lpbuflen      []
1440  */
1441 BOOL WINAPI
1442 MakeSelfRelativeSD(
1443         IN PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
1444         IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
1445         IN OUT LPDWORD lpdwBufferLength)
1446 {
1447     return set_ntstatus( RtlMakeSelfRelativeSD( pAbsoluteSecurityDescriptor,
1448                                                 pSelfRelativeSecurityDescriptor, lpdwBufferLength));
1449 }
1450 
1451 /******************************************************************************
1452  * GetSecurityDescriptorControl                 [ADVAPI32.@]
1453  */
1454 
1455 BOOL WINAPI GetSecurityDescriptorControl ( PSECURITY_DESCRIPTOR  pSecurityDescriptor,
1456                  PSECURITY_DESCRIPTOR_CONTROL pControl, LPDWORD lpdwRevision)
1457 {
1458     return set_ntstatus( RtlGetControlSecurityDescriptor(pSecurityDescriptor,pControl,lpdwRevision));
1459 }
1460 
1461 /******************************************************************************
1462  * SetSecurityDescriptorControl                 [ADVAPI32.@]
1463  */
1464 BOOL WINAPI SetSecurityDescriptorControl( PSECURITY_DESCRIPTOR pSecurityDescriptor,
1465   SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
1466   SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet )
1467 {
1468     return set_ntstatus( RtlSetControlSecurityDescriptor(
1469         pSecurityDescriptor, ControlBitsOfInterest, ControlBitsToSet ) );
1470 }
1471 
1472 /*      ##############################
1473         ######  ACL FUNCTIONS   ######
1474         ##############################
1475 */
1476 
1477 /*************************************************************************
1478  * InitializeAcl [ADVAPI32.@]
1479  */
1480 BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
1481 {
1482     return set_ntstatus( RtlCreateAcl(acl, size, rev));
1483 }
1484 
1485 BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
1486 {
1487     IO_STATUS_BLOCK io_block;
1488 
1489     TRACE("(%p)\n", hNamedPipe);
1490 
1491     return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
1492                          &io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
1493 }
1494 
1495 /******************************************************************************
1496  *  AddAccessAllowedAce [ADVAPI32.@]
1497  */
1498 BOOL WINAPI AddAccessAllowedAce(
1499         IN OUT PACL pAcl,
1500         IN DWORD dwAceRevision,
1501         IN DWORD AccessMask,
1502         IN PSID pSid)
1503 {
1504     return set_ntstatus(RtlAddAccessAllowedAce(pAcl, dwAceRevision, AccessMask, pSid));
1505 }
1506 
1507 /******************************************************************************
1508  *  AddAccessAllowedAceEx [ADVAPI32.@]
1509  */
1510 BOOL WINAPI AddAccessAllowedAceEx(
1511         IN OUT PACL pAcl,
1512         IN DWORD dwAceRevision,
1513         IN DWORD AceFlags,
1514         IN DWORD AccessMask,
1515         IN PSID pSid)
1516 {
1517     return set_ntstatus(RtlAddAccessAllowedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1518 }
1519 
1520 /******************************************************************************
1521  *  AddAccessDeniedAce [ADVAPI32.@]
1522  */
1523 BOOL WINAPI AddAccessDeniedAce(
1524         IN OUT PACL pAcl,
1525         IN DWORD dwAceRevision,
1526         IN DWORD AccessMask,
1527         IN PSID pSid)
1528 {
1529     return set_ntstatus(RtlAddAccessDeniedAce(pAcl, dwAceRevision, AccessMask, pSid));
1530 }
1531 
1532 /******************************************************************************
1533  *  AddAccessDeniedAceEx [ADVAPI32.@]
1534  */
1535 BOOL WINAPI AddAccessDeniedAceEx(
1536         IN OUT PACL pAcl,
1537         IN DWORD dwAceRevision,
1538         IN DWORD AceFlags,
1539         IN DWORD AccessMask,
1540         IN PSID pSid)
1541 {
1542     return set_ntstatus(RtlAddAccessDeniedAceEx(pAcl, dwAceRevision, AceFlags, AccessMask, pSid));
1543 }
1544 
1545 /******************************************************************************
1546  *  AddAce [ADVAPI32.@]
1547  */
1548 BOOL WINAPI AddAce(
1549         IN OUT PACL pAcl,
1550         IN DWORD dwAceRevision,
1551         IN DWORD dwStartingAceIndex,
1552         LPVOID pAceList,
1553         DWORD nAceListLength)
1554 {
1555     return set_ntstatus(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength));
1556 }
1557 
1558 /******************************************************************************
1559  * DeleteAce [ADVAPI32.@]
1560  */
1561 BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
1562 {
1563     return set_ntstatus(RtlDeleteAce(pAcl, dwAceIndex));
1564 }
1565 
1566 /******************************************************************************
1567  *  FindFirstFreeAce [ADVAPI32.@]
1568  */
1569 BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
1570 {
1571         return RtlFirstFreeAce(pAcl, (PACE_HEADER *)pAce);
1572 }
1573 
1574 /******************************************************************************
1575  * GetAce [ADVAPI32.@]
1576  */
1577 BOOL WINAPI GetAce(PACL pAcl,DWORD dwAceIndex,LPVOID *pAce )
1578 {
1579     return set_ntstatus(RtlGetAce(pAcl, dwAceIndex, pAce));
1580 }
1581 
1582 /******************************************************************************
1583  * GetAclInformation [ADVAPI32.@]
1584  */
1585 BOOL WINAPI GetAclInformation(
1586   PACL pAcl,
1587   LPVOID pAclInformation,
1588   DWORD nAclInformationLength,
1589   ACL_INFORMATION_CLASS dwAclInformationClass)
1590 {
1591     return set_ntstatus(RtlQueryInformationAcl(pAcl, pAclInformation,
1592                                                nAclInformationLength, dwAclInformationClass));
1593 }
1594 
1595 /******************************************************************************
1596  *  IsValidAcl [ADVAPI32.@]
1597  */
1598 BOOL WINAPI IsValidAcl(IN PACL pAcl)
1599 {
1600         return RtlValidAcl(pAcl);
1601 }
1602 
1603 /*      ##############################
1604         ######  MISC FUNCTIONS  ######
1605         ##############################
1606 */
1607 
1608 /******************************************************************************
1609  * AllocateLocallyUniqueId [ADVAPI32.@]
1610  *
1611  * PARAMS
1612  *   lpLuid []
1613  */
1614 BOOL WINAPI AllocateLocallyUniqueId( PLUID lpLuid )
1615 {
1616     return set_ntstatus(NtAllocateLocallyUniqueId(lpLuid));
1617 }
1618 
1619 static const WCHAR SE_CREATE_TOKEN_NAME_W[] =
1620  { 'S','e','C','r','e','a','t','e','T','o','k','e','n','P','r','i','v','i','l','e','g','e',0 };
1621 static const WCHAR SE_ASSIGNPRIMARYTOKEN_NAME_W[] =
1622  { '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 };
1623 static const WCHAR SE_LOCK_MEMORY_NAME_W[] =
1624  { 'S','e','L','o','c','k','M','e','m','o','r','y','P','r','i','v','i','l','e','g','e',0 };
1625 static const WCHAR SE_INCREASE_QUOTA_NAME_W[] =
1626  { '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 };
1627 static const WCHAR SE_MACHINE_ACCOUNT_NAME_W[] =
1628  { '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 };
1629 static const WCHAR SE_TCB_NAME_W[] =
1630  { 'S','e','T','c','b','P','r','i','v','i','l','e','g','e',0 };
1631 static const WCHAR SE_SECURITY_NAME_W[] =
1632  { 'S','e','S','e','c','u','r','i','t','y','P','r','i','v','i','l','e','g','e',0 };
1633 static const WCHAR SE_TAKE_OWNERSHIP_NAME_W[] =
1634  { '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 };
1635 static const WCHAR SE_LOAD_DRIVER_NAME_W[] =
1636  { 'S','e','L','o','a','d','D','r','i','v','e','r','P','r','i','v','i','l','e','g','e',0 };
1637 static const WCHAR SE_SYSTEM_PROFILE_NAME_W[] =
1638  { '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 };
1639 static const WCHAR SE_SYSTEMTIME_NAME_W[] =
1640  { 'S','e','S','y','s','t','e','m','t','i','m','e','P','r','i','v','i','l','e','g','e',0 };
1641 static const WCHAR SE_PROF_SINGLE_PROCESS_NAME_W[] =
1642  { '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 };
1643 static const WCHAR SE_INC_BASE_PRIORITY_NAME_W[] =
1644  { '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 };
1645 static const WCHAR SE_CREATE_PAGEFILE_NAME_W[] =
1646  { '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 };
1647 static const WCHAR SE_CREATE_PERMANENT_NAME_W[] =
1648  { '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 };
1649 static const WCHAR SE_BACKUP_NAME_W[] =
1650  { 'S','e','B','a','c','k','u','p','P','r','i','v','i','l','e','g','e',0 };
1651 static const WCHAR SE_RESTORE_NAME_W[] =
1652  { 'S','e','R','e','s','t','o','r','e','P','r','i','v','i','l','e','g','e',0 };
1653 static const WCHAR SE_SHUTDOWN_NAME_W[] =
1654  { 'S','e','S','h','u','t','d','o','w','n','P','r','i','v','i','l','e','g','e',0 };
1655 static const WCHAR SE_DEBUG_NAME_W[] =
1656  { 'S','e','D','e','b','u','g','P','r','i','v','i','l','e','g','e',0 };
1657 static const WCHAR SE_AUDIT_NAME_W[] =
1658  { 'S','e','A','u','d','i','t','P','r','i','v','i','l','e','g','e',0 };
1659 static const WCHAR SE_SYSTEM_ENVIRONMENT_NAME_W[] =
1660  { '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 };
1661 static const WCHAR SE_CHANGE_NOTIFY_NAME_W[] =
1662  { 'S','e','C','h','a','n','g','e','N','o','t','i','f','y','P','r','i','v','i','l','e','g','e',0 };
1663 static const WCHAR SE_REMOTE_SHUTDOWN_NAME_W[] =
1664  { '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 };
1665 static const WCHAR SE_UNDOCK_NAME_W[] =
1666  { 'S','e','U','n','d','o','c','k','P','r','i','v','i','l','e','g','e',0 };
1667 static const WCHAR SE_SYNC_AGENT_NAME_W[] =
1668  { 'S','e','S','y','n','c','A','g','e','n','t','P','r','i','v','i','l','e','g','e',0 };
1669 static const WCHAR SE_ENABLE_DELEGATION_NAME_W[] =
1670  { '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 };
1671 static const WCHAR SE_MANAGE_VOLUME_NAME_W[] =
1672  { 'S','e','M','a','n','a','g','e','V','o','l','u','m','e','P','r','i','v','i','l','e','g','e',0 };
1673 static const WCHAR SE_IMPERSONATE_NAME_W[] =
1674  { 'S','e','I','m','p','e','r','s','o','n','a','t','e','P','r','i','v','i','l','e','g','e',0 };
1675 static const WCHAR SE_CREATE_GLOBAL_NAME_W[] =
1676  { 'S','e','C','r','e','a','t','e','G','l','o','b','a','l','P','r','i','v','i','l','e','g','e',0 };
1677 
1678 static const WCHAR * const WellKnownPrivNames[SE_MAX_WELL_KNOWN_PRIVILEGE + 1] =
1679 {
1680     NULL,
1681     NULL,
1682     SE_CREATE_TOKEN_NAME_W,
1683     SE_ASSIGNPRIMARYTOKEN_NAME_W,
1684     SE_LOCK_MEMORY_NAME_W,
1685     SE_INCREASE_QUOTA_NAME_W,
1686     SE_MACHINE_ACCOUNT_NAME_W,
1687     SE_TCB_NAME_W,
1688     SE_SECURITY_NAME_W,
1689     SE_TAKE_OWNERSHIP_NAME_W,
1690     SE_LOAD_DRIVER_NAME_W,
1691     SE_SYSTEM_PROFILE_NAME_W,
1692     SE_SYSTEMTIME_NAME_W,
1693     SE_PROF_SINGLE_PROCESS_NAME_W,
1694     SE_INC_BASE_PRIORITY_NAME_W,
1695     SE_CREATE_PAGEFILE_NAME_W,
1696     SE_CREATE_PERMANENT_NAME_W,
1697     SE_BACKUP_NAME_W,
1698     SE_RESTORE_NAME_W,
1699     SE_SHUTDOWN_NAME_W,
1700     SE_DEBUG_NAME_W,
1701     SE_AUDIT_NAME_W,
1702     SE_SYSTEM_ENVIRONMENT_NAME_W,
1703     SE_CHANGE_NOTIFY_NAME_W,
1704     SE_REMOTE_SHUTDOWN_NAME_W,
1705     SE_UNDOCK_NAME_W,
1706     SE_SYNC_AGENT_NAME_W,
1707     SE_ENABLE_DELEGATION_NAME_W,
1708     SE_MANAGE_VOLUME_NAME_W,
1709     SE_IMPERSONATE_NAME_W,
1710     SE_CREATE_GLOBAL_NAME_W,
1711 };
1712 
1713 /******************************************************************************
1714  * LookupPrivilegeValueW                        [ADVAPI32.@]
1715  *
1716  * See LookupPrivilegeValueA.
1717  */
1718 BOOL WINAPI
1719 LookupPrivilegeValueW( LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid )
1720 {
1721     UINT i;
1722 
1723     TRACE("%s,%s,%p\n",debugstr_w(lpSystemName), debugstr_w(lpName), lpLuid);
1724 
1725     if (!ADVAPI_IsLocalComputer(lpSystemName))
1726     {
1727         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1728         return FALSE;
1729     }
1730     if (!lpName)
1731     {
1732         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1733         return FALSE;
1734     }
1735     for( i=SE_MIN_WELL_KNOWN_PRIVILEGE; i<=SE_MAX_WELL_KNOWN_PRIVILEGE; i++ )
1736     {
1737         if( !WellKnownPrivNames[i] )
1738             continue;
1739         if( strcmpiW( WellKnownPrivNames[i], lpName) )
1740             continue;
1741         lpLuid->LowPart = i;
1742         lpLuid->HighPart = 0;
1743         TRACE( "%s -> %08x-%08x\n",debugstr_w( lpSystemName ),
1744                lpLuid->HighPart, lpLuid->LowPart );
1745         return TRUE;
1746     }
1747     SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1748     return FALSE;
1749 }
1750 
1751 /******************************************************************************
1752  * LookupPrivilegeValueA                        [ADVAPI32.@]
1753  *
1754  * Retrieves LUID used on a system to represent the privilege name.
1755  *
1756  * PARAMS
1757  *  lpSystemName [I] Name of the system
1758  *  lpName       [I] Name of the privilege
1759  *  lpLuid       [O] Destination for the resulting LUID
1760  *
1761  * RETURNS
1762  *  Success: TRUE. lpLuid contains the requested LUID.
1763  *  Failure: FALSE.
1764  */
1765 BOOL WINAPI
1766 LookupPrivilegeValueA( LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid )
1767 {
1768     UNICODE_STRING lpSystemNameW;
1769     UNICODE_STRING lpNameW;
1770     BOOL ret;
1771 
1772     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1773     RtlCreateUnicodeStringFromAsciiz(&lpNameW,lpName);
1774     ret = LookupPrivilegeValueW(lpSystemNameW.Buffer, lpNameW.Buffer, lpLuid);
1775     RtlFreeUnicodeString(&lpNameW);
1776     RtlFreeUnicodeString(&lpSystemNameW);
1777     return ret;
1778 }
1779 
1780 BOOL WINAPI LookupPrivilegeDisplayNameA( LPCSTR lpSystemName, LPCSTR lpName, LPSTR lpDisplayName,
1781                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1782 {
1783     FIXME("%s %s %s %p %p - stub\n", debugstr_a(lpSystemName), debugstr_a(lpName),
1784           debugstr_a(lpDisplayName), cchDisplayName, lpLanguageId);
1785 
1786     return FALSE;
1787 }
1788 
1789 BOOL WINAPI LookupPrivilegeDisplayNameW( LPCWSTR lpSystemName, LPCWSTR lpName, LPWSTR lpDisplayName,
1790                                          LPDWORD cchDisplayName, LPDWORD lpLanguageId )
1791 {
1792     FIXME("%s %s %s %p %p - stub\n", debugstr_w(lpSystemName), debugstr_w(lpName),
1793           debugstr_w(lpDisplayName), cchDisplayName, lpLanguageId);
1794 
1795     return FALSE;
1796 }
1797 
1798 /******************************************************************************
1799  * LookupPrivilegeNameA                 [ADVAPI32.@]
1800  *
1801  * See LookupPrivilegeNameW.
1802  */
1803 BOOL WINAPI
1804 LookupPrivilegeNameA( LPCSTR lpSystemName, PLUID lpLuid, LPSTR lpName,
1805  LPDWORD cchName)
1806 {
1807     UNICODE_STRING lpSystemNameW;
1808     BOOL ret;
1809     DWORD wLen = 0;
1810 
1811     TRACE("%s %p %p %p\n", debugstr_a(lpSystemName), lpLuid, lpName, cchName);
1812 
1813     RtlCreateUnicodeStringFromAsciiz(&lpSystemNameW, lpSystemName);
1814     ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, NULL, &wLen);
1815     if (!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER)
1816     {
1817         LPWSTR lpNameW = HeapAlloc(GetProcessHeap(), 0, wLen * sizeof(WCHAR));
1818 
1819         ret = LookupPrivilegeNameW(lpSystemNameW.Buffer, lpLuid, lpNameW,
1820          &wLen);
1821         if (ret)
1822         {
1823             /* Windows crashes if cchName is NULL, so will I */
1824             unsigned int len = WideCharToMultiByte(CP_ACP, 0, lpNameW, -1, lpName,
1825              *cchName, NULL, NULL);
1826 
1827             if (len == 0)
1828             {
1829                 /* WideCharToMultiByte failed */
1830                 ret = FALSE;
1831             }
1832             else if (len > *cchName)
1833             {
1834                 *cchName = len;
1835                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
1836                 ret = FALSE;
1837             }
1838             else
1839             {
1840                 /* WideCharToMultiByte succeeded, output length needs to be
1841                  * length not including NULL terminator
1842                  */
1843                 *cchName = len - 1;
1844             }
1845         }
1846         HeapFree(GetProcessHeap(), 0, lpNameW);
1847     }
1848     RtlFreeUnicodeString(&lpSystemNameW);
1849     return ret;
1850 }
1851 
1852 /******************************************************************************
1853  * LookupPrivilegeNameW                 [ADVAPI32.@]
1854  *
1855  * Retrieves the privilege name referred to by the LUID lpLuid.
1856  *
1857  * PARAMS
1858  *  lpSystemName [I]   Name of the system
1859  *  lpLuid       [I]   Privilege value
1860  *  lpName       [O]   Name of the privilege
1861  *  cchName      [I/O] Number of characters in lpName.
1862  *
1863  * RETURNS
1864  *  Success: TRUE. lpName contains the name of the privilege whose value is
1865  *  *lpLuid.
1866  *  Failure: FALSE.
1867  *
1868  * REMARKS
1869  *  Only well-known privilege names (those defined in winnt.h) can be retrieved
1870  *  using this function.
1871  *  If the length of lpName is too small, on return *cchName will contain the
1872  *  number of WCHARs needed to contain the privilege, including the NULL
1873  *  terminator, and GetLastError will return ERROR_INSUFFICIENT_BUFFER.
1874  *  On success, *cchName will contain the number of characters stored in
1875  *  lpName, NOT including the NULL terminator.
1876  */
1877 BOOL WINAPI
1878 LookupPrivilegeNameW( LPCWSTR lpSystemName, PLUID lpLuid, LPWSTR lpName,
1879  LPDWORD cchName)
1880 {
1881     size_t privNameLen;
1882 
1883     TRACE("%s,%p,%p,%p\n",debugstr_w(lpSystemName), lpLuid, lpName, cchName);
1884 
1885     if (!ADVAPI_IsLocalComputer(lpSystemName))
1886     {
1887         SetLastError(RPC_S_SERVER_UNAVAILABLE);
1888         return FALSE;
1889     }
1890     if (lpLuid->HighPart || (lpLuid->LowPart < SE_MIN_WELL_KNOWN_PRIVILEGE ||
1891      lpLuid->LowPart > SE_MAX_WELL_KNOWN_PRIVILEGE))
1892     {
1893         SetLastError(ERROR_NO_SUCH_PRIVILEGE);
1894         return FALSE;
1895     }
1896     privNameLen = strlenW(WellKnownPrivNames[lpLuid->LowPart]);
1897     /* Windows crashes if cchName is NULL, so will I */
1898     if (*cchName <= privNameLen)
1899     {
1900         *cchName = privNameLen + 1;
1901         SetLastError(ERROR_INSUFFICIENT_BUFFER);
1902         return FALSE;
1903     }
1904     else
1905     {
1906         strcpyW(lpName, WellKnownPrivNames[lpLuid->LowPart]);
1907         *cchName = privNameLen;
1908         return TRUE;
1909     }
1910 }
1911 
1912 /******************************************************************************
1913  * GetFileSecurityA [ADVAPI32.@]
1914  *
1915  * Obtains Specified information about the security of a file or directory.
1916  *
1917  * PARAMS
1918  *  lpFileName           [I] Name of the file to get info for
1919  *  RequestedInformation [I] SE_ flags from "winnt.h"
1920  *  pSecurityDescriptor  [O] Destination for security information
1921  *  nLength              [I] Length of pSecurityDescriptor
1922  *  lpnLengthNeeded      [O] Destination for length of returned security information
1923  *
1924  * RETURNS
1925  *  Success: TRUE. pSecurityDescriptor contains the requested information.
1926  *  Failure: FALSE. lpnLengthNeeded contains the required space to return the info. 
1927  *
1928  * NOTES
1929  *  The information returned is constrained by the callers access rights and
1930  *  privileges.
1931  */
1932 BOOL WINAPI
1933 GetFileSecurityA( LPCSTR lpFileName,
1934                     SECURITY_INFORMATION RequestedInformation,
1935                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1936                     DWORD nLength, LPDWORD lpnLengthNeeded )
1937 {
1938     DWORD len;
1939     BOOL r;
1940     LPWSTR name = NULL;
1941 
1942     if( lpFileName )
1943     {
1944         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
1945         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
1946         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
1947     }
1948 
1949     r = GetFileSecurityW( name, RequestedInformation, pSecurityDescriptor,
1950                           nLength, lpnLengthNeeded );
1951     HeapFree( GetProcessHeap(), 0, name );
1952 
1953     return r;
1954 }
1955 
1956 /******************************************************************************
1957  * GetFileSecurityW [ADVAPI32.@]
1958  *
1959  * See GetFileSecurityA.
1960  */
1961 BOOL WINAPI
1962 GetFileSecurityW( LPCWSTR lpFileName,
1963                     SECURITY_INFORMATION RequestedInformation,
1964                     PSECURITY_DESCRIPTOR pSecurityDescriptor,
1965                     DWORD nLength, LPDWORD lpnLengthNeeded )
1966 {
1967     HANDLE hfile;
1968     NTSTATUS status;
1969     DWORD access = 0;
1970 
1971     TRACE("(%s,%d,%p,%d,%p)\n", debugstr_w(lpFileName),
1972           RequestedInformation, pSecurityDescriptor,
1973           nLength, lpnLengthNeeded);
1974 
1975     if (RequestedInformation & (OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|
1976                                 DACL_SECURITY_INFORMATION))
1977         access |= READ_CONTROL;
1978     if (RequestedInformation & SACL_SECURITY_INFORMATION)
1979         access |= ACCESS_SYSTEM_SECURITY;
1980 
1981     hfile = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
1982                          NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0 );
1983     if ( hfile == INVALID_HANDLE_VALUE )
1984         return FALSE;
1985 
1986     status = NtQuerySecurityObject( hfile, RequestedInformation, pSecurityDescriptor,
1987                                     nLength, lpnLengthNeeded );
1988     CloseHandle( hfile );
1989     return set_ntstatus( status );
1990 }
1991 
1992 
1993 /******************************************************************************
1994  * LookupAccountSidA [ADVAPI32.@]
1995  */
1996 BOOL WINAPI
1997 LookupAccountSidA(
1998         IN LPCSTR system,
1999         IN PSID sid,
2000         OUT LPSTR account,
2001         IN OUT LPDWORD accountSize,
2002         OUT LPSTR domain,
2003         IN OUT LPDWORD domainSize,
2004         OUT PSID_NAME_USE name_use )
2005 {
2006     DWORD len;
2007     BOOL r;
2008     LPWSTR systemW = NULL;
2009     LPWSTR accountW = NULL;
2010     LPWSTR domainW = NULL;
2011     DWORD accountSizeW = *accountSize;
2012     DWORD domainSizeW = *domainSize;
2013 
2014     if (system) {
2015         len = MultiByteToWideChar( CP_ACP, 0, system, -1, NULL, 0 );
2016         systemW = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
2017         MultiByteToWideChar( CP_ACP, 0, system, -1, systemW, len );
2018     }
2019     if (account)
2020         accountW = HeapAlloc( GetProcessHeap(), 0, accountSizeW * sizeof(WCHAR) );
2021     if (domain)
2022         domainW = HeapAlloc( GetProcessHeap(), 0, domainSizeW * sizeof(WCHAR) );
2023 
2024     r = LookupAccountSidW( systemW, sid, accountW, &accountSizeW, domainW, &domainSizeW, name_use );
2025 
2026     if (r) {
2027         if (accountW && *accountSize) {
2028             len = WideCharToMultiByte( CP_ACP, 0, accountW, -1, NULL, 0, NULL, NULL );
2029             WideCharToMultiByte( CP_ACP, 0, accountW, -1, account, len, NULL, NULL );
2030             *accountSize = len;
2031         } else
2032             *accountSize = accountSizeW + 1;
2033 
2034         if (domainW && *domainSize) {
2035             len = WideCharToMultiByte( CP_ACP, 0, domainW, -1, NULL, 0, NULL, NULL );
2036             WideCharToMultiByte( CP_ACP, 0, domainW, -1, domain, len, NULL, NULL );
2037             *domainSize = len;
2038         } else
2039             *domainSize = domainSizeW + 1;
2040     }
2041     else
2042     {
2043         *accountSize = accountSizeW + 1;
2044         *domainSize = domainSizeW + 1;
2045     }
2046 
2047     HeapFree( GetProcessHeap(), 0, systemW );
2048     HeapFree( GetProcessHeap(), 0, accountW );
2049     HeapFree( GetProcessHeap(), 0, domainW );
2050 
2051     return r;
2052 }
2053 
2054 /******************************************************************************
2055  * LookupAccountSidW [ADVAPI32.@]
2056  *
2057  * PARAMS
2058  *   system      []
2059  *   sid         []
2060  *   account     []
2061  *   accountSize []
2062  *   domain      []
2063  *   domainSize  []
2064  *   name_use    []
2065  */
2066 
2067 BOOL WINAPI
2068 LookupAccountSidW(
2069         IN LPCWSTR system,
2070         IN PSID sid,
2071         OUT LPWSTR account,
2072         IN OUT LPDWORD accountSize,
2073         OUT LPWSTR domain,
2074         IN OUT LPDWORD domainSize,
2075         OUT PSID_NAME_USE name_use )
2076 {
2077     unsigned int i, j;
2078     const WCHAR * ac = NULL;
2079     const WCHAR * dm = NULL;
2080     SID_NAME_USE use = 0;
2081     LPWSTR computer_name = NULL;
2082     LPWSTR account_name = NULL;
2083 
2084     TRACE("(%s,sid=%s,%p,%p(%u),%p,%p(%u),%p)\n",
2085           debugstr_w(system),debugstr_sid(sid),
2086           account,accountSize,accountSize?*accountSize:0,
2087           domain,domainSize,domainSize?*domainSize:0,
2088           name_use);
2089 
2090     if (!ADVAPI_IsLocalComputer(system)) {
2091         FIXME("Only local computer supported!\n");
2092         SetLastError(RPC_S_SERVER_UNAVAILABLE);
2093         return FALSE;
2094     }
2095 
2096     /* check the well known SIDs first */
2097     for (i = 0; i <= 60; i++) {
2098         if (IsWellKnownSid(sid, i)) {
2099             for (j = 0; j < (sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0])); j++) {
2100                 if (ACCOUNT_SIDS[j].type == i) {
2101                     ac = ACCOUNT_SIDS[j].account;
2102                     dm = ACCOUNT_SIDS[j].domain;
2103                     use = ACCOUNT_SIDS[j].name_use;
2104                 }
2105             }
2106             break;
2107         }
2108     }
2109 
2110     if (dm == NULL) {
2111         MAX_SID local;
2112 
2113         /* check for the local computer next */
2114         if (ADVAPI_GetComputerSid(&local)) {
2115             DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
2116             BOOL result;
2117 
2118             computer_name = HeapAlloc(GetProcessHeap(), 0, size * sizeof(WCHAR));
2119             result = GetComputerNameW(computer_name,  &size);
2120 
2121             if (result) {
2122                 if (EqualSid(sid, &local)) {
2123                     dm = computer_name;
2124                     ac = Blank;
2125                     use = 3;
2126                 } else {
2127                     local.SubAuthorityCount++;
2128 
2129                     if (EqualPrefixSid(sid, &local)) {
2130                         dm = computer_name;
2131                         use = 1;
2132                         switch (((MAX_SID *)sid)->SubAuthority[4]) {
2133                         case DOMAIN_USER_RID_ADMIN:
2134                             ac = Administrator;
2135                             break;
2136                         case DOMAIN_USER_RID_GUEST:
2137                             ac = Guest;
2138                             break;
2139                         case DOMAIN_GROUP_RID_ADMINS:
2140                             ac = Domain_Admins;
2141                             break;
2142                         case DOMAIN_GROUP_RID_USERS:
2143                             ac = Domain_Users;
2144                             break;
2145                         case DOMAIN_GROUP_RID_GUESTS:
2146                             ac = Domain_Guests;
2147                             break;
2148                         case DOMAIN_GROUP_RID_COMPUTERS:
2149                             ac = Domain_Computers;
2150                             break;
2151                         case DOMAIN_GROUP_RID_CONTROLLERS:
2152                             ac = Domain_Controllers;
2153                             break;
2154                         case DOMAIN_GROUP_RID_CERT_ADMINS:
2155                             ac = Cert_Publishers;
2156                             break;
2157                         case DOMAIN_GROUP_RID_SCHEMA_ADMINS:
2158                             ac = Schema_Admins;
2159                             break;
2160                         case DOMAIN_GROUP_RID_ENTERPRISE_ADMINS:
2161                             ac = Enterprise_Admins;
2162                             break;
2163                         case DOMAIN_GROUP_RID_POLICY_ADMINS:
2164                             ac = Group_Policy_Creator_Owners;
2165                             break;
2166                         case DOMAIN_ALIAS_RID_RAS_SERVERS:
2167                             ac = RAS_and_IAS_Servers;
2168                             break;
2169                         case 1000:      /* first user account */
2170                             size = UNLEN + 1;
2171                             account_name = HeapAlloc(
2172                                 GetProcessHeap(), 0, size * sizeof(WCHAR));
2173                             if (GetUserNameW(account_name, &size))
2174                                 ac = account_name;
2175                             else
2176                                 dm = NULL;
2177 
2178                             break;
2179                         default:
2180                             dm = NULL;
2181                             break;
2182                         }
2183                     }
2184                 }
2185             }
2186         }
2187     }
2188 
2189     if (dm) {
2190         DWORD ac_len = lstrlenW(ac);
2191         DWORD dm_len = lstrlenW(dm);
2192         BOOL status = TRUE;
2193 
2194         if (*accountSize > ac_len) {
2195             if (account)
2196                 lstrcpyW(account, ac);
2197         }
2198         if (*domainSize > dm_len) {
2199             if (domain)
2200                 lstrcpyW(domain, dm);
2201         }
2202         if ((*accountSize && *accountSize < ac_len) ||
2203             (!account && !*accountSize && ac_len)   ||
2204             (*domainSize && *domainSize < dm_len)   ||
2205             (!domain && !*domainSize && dm_len))
2206         {
2207             SetLastError(ERROR_INSUFFICIENT_BUFFER);
2208             status = FALSE;
2209         }
2210         if (*domainSize)
2211             *domainSize = dm_len;
2212         else
2213             *domainSize = dm_len + 1;
2214         if (*accountSize)
2215             *accountSize = ac_len;
2216         else
2217             *accountSize = ac_len + 1;
2218 
2219         HeapFree(GetProcessHeap(), 0, account_name);
2220         HeapFree(GetProcessHeap(), 0, computer_name);
2221         if (status) *name_use = use;
2222         return status;
2223     }
2224 
2225     HeapFree(GetProcessHeap(), 0, account_name);
2226     HeapFree(GetProcessHeap(), 0, computer_name);
2227     SetLastError(ERROR_NONE_MAPPED);
2228     return FALSE;
2229 }
2230 
2231 /******************************************************************************
2232  * SetFileSecurityA [ADVAPI32.@]
2233  *
2234  * See SetFileSecurityW.
2235  */
2236 BOOL WINAPI SetFileSecurityA( LPCSTR lpFileName,
2237                                 SECURITY_INFORMATION RequestedInformation,
2238                                 PSECURITY_DESCRIPTOR pSecurityDescriptor)
2239 {
2240     DWORD len;
2241     BOOL r;
2242     LPWSTR name = NULL;
2243 
2244     if( lpFileName )
2245     {
2246         len = MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, NULL, 0 );
2247         name = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) );
2248         MultiByteToWideChar( CP_ACP, 0, lpFileName, -1, name, len );
2249     }
2250 
2251     r = SetFileSecurityW( name, RequestedInformation, pSecurityDescriptor );
2252     HeapFree( GetProcessHeap(), 0, name );
2253 
2254     return r;
2255 }
2256 
2257 /******************************************************************************
2258  * SetFileSecurityW [ADVAPI32.@]
2259  *
2260  * Sets the security of a file or directory.
2261  *
2262  * PARAMS
2263  *   lpFileName           []
2264  *   RequestedInformation []
2265  *   pSecurityDescriptor  []
2266  *
2267  * RETURNS
2268  *  Success: TRUE.
2269  *  Failure: FALSE.
2270  */
2271 BOOL WINAPI
2272 SetFileSecurityW( LPCWSTR lpFileName,
2273                     SECURITY_INFORMATION RequestedInformation,
2274                     PSECURITY_DESCRIPTOR pSecurityDescriptor )
2275 {
2276     HANDLE file;
2277     DWORD access = 0;
2278     NTSTATUS status;
2279 
2280     TRACE("(%s, 0x%x, %p)\n", debugstr_w(lpFileName), RequestedInformation,
2281           pSecurityDescriptor );
2282 
2283     if (RequestedInformation & OWNER_SECURITY_INFORMATION ||
2284         RequestedInformation & GROUP_SECURITY_INFORMATION)
2285         access |= WRITE_OWNER;
2286     if (RequestedInformation & SACL_SECURITY_INFORMATION)
2287         access |= ACCESS_SYSTEM_SECURITY;
2288     if (RequestedInformation & DACL_SECURITY_INFORMATION)
2289         access |= WRITE_DAC;
2290 
2291     file = CreateFileW( lpFileName, access, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
2292                         NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
2293     if (file == INVALID_HANDLE_VALUE)
2294         return FALSE;
2295 
2296     status = NtSetSecurityObject( file, RequestedInformation, pSecurityDescriptor );
2297     CloseHandle( file );
2298     return set_ntstatus( status );
2299 }
2300 
2301 /******************************************************************************
2302  * QueryWindows31FilesMigration [ADVAPI32.@]
2303  *
2304  * PARAMS
2305  *   x1 []
2306  */
2307 BOOL WINAPI
2308 QueryWindows31FilesMigration( DWORD x1 )
2309 {
2310         FIXME("(%d):stub\n",x1);
2311         return TRUE;
2312 }
2313 
2314 /******************************************************************************
2315  * SynchronizeWindows31FilesAndWindowsNTRegistry [ADVAPI32.@]
2316  *
2317  * PARAMS
2318  *   x1 []
2319  *   x2 []
2320  *   x3 []
2321  *   x4 []
2322  */
2323 BOOL WINAPI
2324 SynchronizeWindows31FilesAndWindowsNTRegistry( DWORD x1, DWORD x2, DWORD x3,
2325                                                DWORD x4 )
2326 {
2327         FIXME("(0x%08x,0x%08x,0x%08x,0x%08x):stub\n",x1,x2,x3,x4);
2328         return TRUE;
2329 }
2330 
2331 /******************************************************************************
2332  * NotifyBootConfigStatus [ADVAPI32.@]
2333  *
2334  * PARAMS
2335  *   x1 []
2336  */
2337 BOOL WINAPI
2338 NotifyBootConfigStatus( BOOL x1 )
2339 {
2340         FIXME("(0x%08d):stub\n",x1);
2341         return 1;
2342 }
2343 
2344 /******************************************************************************
2345  * RevertToSelf [ADVAPI32.@]
2346  *
2347  * Ends the impersonation of a user.
2348  *
2349  * PARAMS
2350  *   void []
2351  *
2352  * RETURNS
2353  *  Success: TRUE.
2354  *  Failure: FALSE.
2355  */
2356 BOOL WINAPI
2357 RevertToSelf( void )
2358 {
2359     HANDLE Token = NULL;
2360     return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
2361         ThreadImpersonationToken, &Token, sizeof(Token) ) );
2362 }
2363 
2364 /******************************************************************************
2365  * ImpersonateSelf [ADVAPI32.@]
2366  *
2367  * Makes an impersonation token that represents the process user and assigns
2368  * to the current thread.
2369  *
2370  * PARAMS
2371  *  ImpersonationLevel [I] Level at which to impersonate.
2372  *
2373  * RETURNS
2374  *  Success: TRUE.
2375  *  Failure: FALSE.
2376  */
2377 BOOL WINAPI
2378 ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
2379 {
2380     return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
2381 }
2382 
2383 /******************************************************************************
2384  * ImpersonateLoggedOnUser [ADVAPI32.@]
2385  */
2386 BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
2387 {
2388     DWORD size;
2389     NTSTATUS Status;
2390     HANDLE ImpersonationToken;
2391     TOKEN_TYPE Type;
2392     static BOOL warn = TRUE;
2393 
2394     if (warn)
2395     {
2396         FIXME( "(%p)\n", hToken );
2397         warn = FALSE;
2398     }
2399     if (!GetTokenInformation( hToken, TokenType, &Type,
2400                               sizeof(TOKEN_TYPE), &size ))
2401         return FALSE;
2402 
2403     if (Type == TokenPrimary)
2404     {
2405         OBJECT_ATTRIBUTES ObjectAttributes;
2406 
2407         InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
2408 
2409         Status = NtDuplicateToken( hToken,
2410                                    TOKEN_IMPERSONATE | TOKEN_QUERY,
2411                                    &ObjectAttributes,
2412                                    SecurityImpersonation,
2413                                    TokenImpersonation,
2414                                    &ImpersonationToken );
2415         if (Status != STATUS_SUCCESS)
2416         {
2417             ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
2418             SetLastError( RtlNtStatusToDosError( Status ) );
2419             return FALSE;
2420         }
2421     }
2422     else
2423         ImpersonationToken = hToken;
2424 
2425     Status = NtSetInformationThread( GetCurrentThread(),
2426                                      ThreadImpersonationToken,
2427                                      &ImpersonationToken,
2428                                      sizeof(ImpersonationToken) );
2429 
2430     if (Type == TokenPrimary)
2431         NtClose( ImpersonationToken );
2432 
2433     if (Status != STATUS_SUCCESS)
2434     {
2435         ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
2436         SetLastError( RtlNtStatusToDosError( Status ) );
2437         return FALSE;
2438     }
2439 
2440     return TRUE;
2441 }
2442 
2443 /******************************************************************************
2444  * AccessCheck [ADVAPI32.@]
2445  */
2446 BOOL WINAPI
2447 AccessCheck(
2448         PSECURITY_DESCRIPTOR SecurityDescriptor,
2449         HANDLE ClientToken,
2450         DWORD DesiredAccess,
2451         PGENERIC_MAPPING GenericMapping,
2452         PPRIVILEGE_SET PrivilegeSet,
2453         LPDWORD PrivilegeSetLength,
2454         LPDWORD GrantedAccess,
2455         LPBOOL AccessStatus)
2456 {
2457     NTSTATUS access_status;
2458     BOOL ret = set_ntstatus( NtAccessCheck(SecurityDescriptor, ClientToken, DesiredAccess,
2459                                            GenericMapping, PrivilegeSet, PrivilegeSetLength,
2460                                            GrantedAccess, &access_status) );
2461     if (ret) *AccessStatus = set_ntstatus( access_status );
2462     return ret;
2463 }
2464 
2465 
2466 /******************************************************************************
2467  * AccessCheckByType [ADVAPI32.@]
2468  */
2469 BOOL WINAPI AccessCheckByType(
2470     PSECURITY_DESCRIPTOR pSecurityDescriptor, 
2471     PSID PrincipalSelfSid,
2472     HANDLE ClientToken, 
2473     DWORD DesiredAccess, 
2474     POBJECT_TYPE_LIST ObjectTypeList,
2475     DWORD ObjectTypeListLength,
2476     PGENERIC_MAPPING GenericMapping,
2477     PPRIVILEGE_SET PrivilegeSet,
2478     LPDWORD PrivilegeSetLength, 
2479     LPDWORD GrantedAccess,
2480     LPBOOL AccessStatus)
2481 {
2482         FIXME("stub\n");
2483 
2484         *AccessStatus = TRUE;
2485 
2486         return !*AccessStatus;
2487 }
2488 
2489 /******************************************************************************
2490  * MapGenericMask [ADVAPI32.@]
2491  *
2492  * Maps generic access rights into specific access rights according to the
2493  * supplied mapping.
2494  *
2495  * PARAMS
2496  *  AccessMask     [I/O] Access rights.
2497  *  GenericMapping [I] The mapping between generic and specific rights.
2498  *
2499  * RETURNS
2500  *  Nothing.
2501  */
2502 VOID WINAPI MapGenericMask( PDWORD AccessMask, PGENERIC_MAPPING GenericMapping )
2503 {
2504     RtlMapGenericMask( AccessMask, GenericMapping );
2505 }
2506 
2507 /*************************************************************************
2508  * SetKernelObjectSecurity [ADVAPI32.@]
2509  */
2510 BOOL WINAPI SetKernelObjectSecurity (
2511         IN HANDLE Handle,
2512         IN SECURITY_INFORMATION SecurityInformation,
2513         IN PSECURITY_DESCRIPTOR SecurityDescriptor )
2514 {
2515     return set_ntstatus (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
2516 }
2517 
2518 
2519 /******************************************************************************
2520  *  AddAuditAccessAce [ADVAPI32.@]
2521  */
2522 BOOL WINAPI AddAuditAccessAce(
2523     IN OUT PACL pAcl, 
2524     IN DWORD dwAceRevision, 
2525     IN DWORD dwAccessMask, 
2526     IN PSID pSid, 
2527     IN BOOL bAuditSuccess, 
2528     IN BOOL bAuditFailure) 
2529 {
2530     return set_ntstatus( RtlAddAuditAccessAce(pAcl, dwAceRevision, dwAccessMask, pSid, 
2531                                               bAuditSuccess, bAuditFailure) ); 
2532 }
2533 
2534 /******************************************************************************
2535  *  AddAuditAccessAce [ADVAPI32.@]
2536  */
2537 BOOL WINAPI AddAuditAccessAceEx(
2538     IN OUT PACL pAcl,
2539     IN DWORD dwAceRevision,
2540     IN DWORD dwAceFlags,
2541     IN DWORD dwAccessMask,
2542     IN PSID pSid,
2543     IN BOOL bAuditSuccess,
2544     IN BOOL bAuditFailure)
2545 {
2546     return set_ntstatus( RtlAddAuditAccessAceEx(pAcl, dwAceRevision, dwAceFlags, dwAccessMask, pSid,
2547                                               bAuditSuccess, bAuditFailure) );
2548 }
2549 
2550 /******************************************************************************
2551  * LookupAccountNameA [ADVAPI32.@]
2552  */
2553 BOOL WINAPI
2554 LookupAccountNameA(
2555         IN LPCSTR system,
2556         IN LPCSTR account,
2557         OUT PSID sid,
2558         OUT LPDWORD cbSid,
2559         LPSTR ReferencedDomainName,
2560         IN OUT LPDWORD cbReferencedDomainName,
2561         OUT PSID_NAME_USE name_use )
2562 {
2563     BOOL ret;
2564     UNICODE_STRING lpSystemW;
2565     UNICODE_STRING lpAccountW;
2566     LPWSTR lpReferencedDomainNameW = NULL;
2567 
2568     RtlCreateUnicodeStringFromAsciiz(&lpSystemW, system);
2569     RtlCreateUnicodeStringFromAsciiz(&lpAccountW, account);
2570 
2571     if (ReferencedDomainName)
2572         lpReferencedDomainNameW = HeapAlloc(GetProcessHeap(), 0, *cbReferencedDomainName * sizeof(WCHAR));
2573 
2574     ret = LookupAccountNameW(lpSystemW.Buffer, lpAccountW.Buffer, sid, cbSid, lpReferencedDomainNameW,
2575         cbReferencedDomainName, name_use);
2576 
2577     if (ret && lpReferencedDomainNameW)
2578     {
2579         WideCharToMultiByte(CP_ACP, 0, lpReferencedDomainNameW, -1,
2580             ReferencedDomainName, *cbReferencedDomainName+1, NULL, NULL);
2581     }
2582 
2583     RtlFreeUnicodeString(&lpSystemW);
2584     RtlFreeUnicodeString(&lpAccountW);
2585     HeapFree(GetProcessHeap(), 0, lpReferencedDomainNameW);
2586 
2587     return ret;
2588 }
2589 
2590 /******************************************************************************
2591  * lookup_user_account_name
2592  */
2593 static BOOL lookup_user_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2594                                      LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2595 {
2596     char buffer[sizeof(TOKEN_USER) + sizeof(SID) + sizeof(DWORD)*SID_MAX_SUB_AUTHORITIES];
2597     DWORD len = sizeof(buffer);
2598     HANDLE token;
2599     BOOL ret;
2600     PSID pSid;
2601     WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2602     DWORD nameLen;
2603 
2604     if (!OpenThreadToken(GetCurrentThread(), TOKEN_READ, TRUE, &token))
2605     {
2606         if (GetLastError() != ERROR_NO_TOKEN) return FALSE;
2607         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token)) return FALSE;
2608     }
2609 
2610     ret = GetTokenInformation(token, TokenUser, buffer, len, &len);
2611     CloseHandle( token );
2612 
2613     if (!ret) return FALSE;
2614 
2615     pSid = ((TOKEN_USER *)buffer)->User.Sid;
2616 
2617     if (Sid != NULL && (*cbSid >= GetLengthSid(pSid)))
2618        CopySid(*cbSid, Sid, pSid);
2619     if (*cbSid < GetLengthSid(pSid))
2620     {
2621        SetLastError(ERROR_INSUFFICIENT_BUFFER);
2622        ret = FALSE;
2623     }
2624     *cbSid = GetLengthSid(pSid);
2625 
2626     nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2627     if (!GetComputerNameW(domainName, &nameLen))
2628     {
2629         domainName[0] = 0;
2630         nameLen = 0;
2631     }
2632     if (*cchReferencedDomainName <= nameLen || !ret)
2633     {
2634         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2635         nameLen += 1;
2636         ret = FALSE;
2637     }
2638     else if (ReferencedDomainName)
2639         strcpyW(ReferencedDomainName, domainName);
2640 
2641     *cchReferencedDomainName = nameLen;
2642 
2643     if (ret)
2644         *peUse = SidTypeUser;
2645 
2646     return ret;
2647 }
2648 
2649 /******************************************************************************
2650  * lookup_computer_account_name
2651  */
2652 static BOOL lookup_computer_account_name(PSID Sid, PDWORD cbSid, LPWSTR ReferencedDomainName,
2653                                          LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2654 {
2655     MAX_SID local;
2656     BOOL ret;
2657     WCHAR domainName[MAX_COMPUTERNAME_LENGTH + 1];
2658     DWORD nameLen;
2659 
2660     if ((ret = ADVAPI_GetComputerSid(&local)))
2661     {
2662         if (Sid != NULL && (*cbSid >= GetLengthSid(&local)))
2663            CopySid(*cbSid, Sid, &local);
2664         if (*cbSid < GetLengthSid(&local))
2665         {
2666            SetLastError(ERROR_INSUFFICIENT_BUFFER);
2667            ret = FALSE;
2668         }
2669         *cbSid = GetLengthSid(&local);
2670     }
2671 
2672     nameLen = MAX_COMPUTERNAME_LENGTH + 1;
2673     if (!GetComputerNameW(domainName, &nameLen))
2674     {
2675         domainName[0] = 0;
2676         nameLen = 0;
2677     }
2678     if (*cchReferencedDomainName <= nameLen || !ret)
2679     {
2680         SetLastError(ERROR_INSUFFICIENT_BUFFER);
2681         nameLen += 1;
2682         ret = FALSE;
2683     }
2684     else if (ReferencedDomainName)
2685         strcpyW(ReferencedDomainName, domainName);
2686 
2687     *cchReferencedDomainName = nameLen;
2688 
2689     if (ret)
2690         *peUse = SidTypeDomain;
2691 
2692     return ret;
2693 }
2694 
2695 static void split_domain_account( const LSA_UNICODE_STRING *str, LSA_UNICODE_STRING *account,
2696                                   LSA_UNICODE_STRING *domain )
2697 {
2698     WCHAR *p = str->Buffer + str->Length / sizeof(WCHAR) - 1;
2699 
2700     while (p > str->Buffer && *p != '\\') p--;
2701 
2702     if (*p == '\\')
2703     {
2704         domain->Buffer = str->Buffer;
2705         domain->Length = (p - str->Buffer) * sizeof(WCHAR);
2706 
2707         account->Buffer = p + 1;
2708         account->Length = str->Length - ((p - str->Buffer + 1) * sizeof(WCHAR));
2709     }
2710     else
2711     {
2712         domain->Buffer = NULL;
2713         domain->Length = 0;
2714 
2715         account->Buffer = str->Buffer;
2716         account->Length = str->Length;
2717     }
2718 }
2719 
2720 static BOOL match_domain( ULONG idx, const LSA_UNICODE_STRING *domain )
2721 {
2722     ULONG len = strlenW( ACCOUNT_SIDS[idx].domain );
2723 
2724     if (len == domain->Length / sizeof(WCHAR) && !strncmpiW( domain->Buffer, ACCOUNT_SIDS[idx].domain, len ))
2725         return TRUE;
2726 
2727     return FALSE;
2728 }
2729 
2730 static BOOL match_account( ULONG idx, const LSA_UNICODE_STRING *account )
2731 {
2732     ULONG len = strlenW( ACCOUNT_SIDS[idx].account );
2733 
2734     if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].account, len ))
2735         return TRUE;
2736 
2737     if (ACCOUNT_SIDS[idx].alias)
2738     {
2739         len = strlenW( ACCOUNT_SIDS[idx].alias );
2740         if (len == account->Length / sizeof(WCHAR) && !strncmpiW( account->Buffer, ACCOUNT_SIDS[idx].alias, len ))
2741             return TRUE;
2742     }
2743     return FALSE;
2744 }
2745 
2746 /*
2747  * Helper function for LookupAccountNameW
2748  */
2749 BOOL lookup_local_wellknown_name( const LSA_UNICODE_STRING *account_and_domain,
2750                                   PSID Sid, LPDWORD cbSid,
2751                                   LPWSTR ReferencedDomainName,
2752                                   LPDWORD cchReferencedDomainName,
2753                                   PSID_NAME_USE peUse, BOOL *handled )
2754 {
2755     PSID pSid;
2756     LSA_UNICODE_STRING account, domain;
2757     BOOL ret = TRUE;
2758     ULONG i;
2759 
2760     *handled = FALSE;
2761     split_domain_account( account_and_domain, &account, &domain );
2762 
2763     for (i = 0; i < sizeof(ACCOUNT_SIDS) / sizeof(ACCOUNT_SIDS[0]); i++)
2764     {
2765         /* check domain first */
2766         if (domain.Buffer && !match_domain( i, &domain )) continue;
2767 
2768         if (match_account( i, &account ))
2769         {
2770             DWORD len, sidLen = SECURITY_MAX_SID_SIZE;
2771 
2772             if (!(pSid = HeapAlloc( GetProcessHeap(), 0, sidLen ))) return FALSE;
2773 
2774             if ((ret = CreateWellKnownSid( ACCOUNT_SIDS[i].type, NULL, pSid, &sidLen )))
2775             {
2776                 if (*cbSid < sidLen)
2777                 {
2778                     SetLastError(ERROR_INSUFFICIENT_BUFFER);
2779                     ret = FALSE;
2780                 }
2781                 else if (Sid)
2782                 {
2783                     CopySid(*cbSid, Sid, pSid);
2784                 }
2785                 *cbSid = sidLen;
2786             }
2787 
2788             len = strlenW( ACCOUNT_SIDS[i].domain );
2789             if (*cchReferencedDomainName <= len || !ret)
2790             {
2791                 SetLastError(ERROR_INSUFFICIENT_BUFFER);
2792                 len++;
2793                 ret = FALSE;
2794             }
2795             else if (ReferencedDomainName)
2796             {
2797                 strcpyW( ReferencedDomainName, ACCOUNT_SIDS[i].domain );
2798             }
2799 
2800             *cchReferencedDomainName = len;
2801             if (ret)
2802                 *peUse = ACCOUNT_SIDS[i].name_use;
2803 
2804             HeapFree(GetProcessHeap(), 0, pSid);
2805             *handled = TRUE;
2806             return ret;
2807         }
2808     }
2809     return ret;
2810 }
2811 
2812 BOOL lookup_local_user_name( const LSA_UNICODE_STRING *account_and_domain,
2813                              PSID Sid, LPDWORD cbSid,
2814                              LPWSTR ReferencedDomainName,
2815                              LPDWORD cchReferencedDomainName,
2816                              PSID_NAME_USE peUse, BOOL *handled )
2817 {
2818     DWORD nameLen;
2819     LPWSTR userName = NULL;
2820     LSA_UNICODE_STRING account, domain;
2821     BOOL ret = TRUE;
2822 
2823     *handled = FALSE;
2824     split_domain_account( account_and_domain, &account, &domain );
2825 
2826     /* Let the current Unix user id masquerade as first Windows user account */
2827 
2828     nameLen = UNLEN + 1;
2829     if (!(userName = HeapAlloc( GetProcessHeap(), 0, nameLen * sizeof(WCHAR) ))) return FALSE;
2830 
2831     if (domain.Buffer)
2832     {
2833         /* check to make sure this account is on this computer */
2834         if (GetComputerNameW( userName, &nameLen ) &&
2835             (domain.Length / sizeof(WCHAR) != nameLen || strncmpW( domain.Buffer, userName, nameLen )))
2836         {
2837             SetLastError(ERROR_NONE_MAPPED);
2838             ret = FALSE;
2839         }
2840         nameLen = UNLEN + 1;
2841     }
2842 
2843     if (GetUserNameW( userName, &nameLen ) &&
2844         account.Length / sizeof(WCHAR) == nameLen - 1 && !strncmpW( account.Buffer, userName, nameLen - 1 ))
2845     {
2846             ret = lookup_user_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2847             *handled = TRUE;
2848     }
2849     else
2850     {
2851         nameLen = UNLEN + 1;
2852         if (GetComputerNameW( userName, &nameLen ) &&
2853             account.Length / sizeof(WCHAR) == nameLen && !strncmpW( account.Buffer, userName , nameLen ))
2854         {
2855             ret = lookup_computer_account_name( Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse );
2856             *handled = TRUE;
2857         }
2858     }
2859 
2860     HeapFree(GetProcessHeap(), 0, userName);
2861     return ret;
2862 }
2863 
2864 /******************************************************************************
2865  * LookupAccountNameW [ADVAPI32.@]
2866  */
2867 BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSID Sid,
2868                                 LPDWORD cbSid, LPWSTR ReferencedDomainName,
2869                                 LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse )
2870 {
2871     BOOL ret, handled;
2872     LSA_UNICODE_STRING account;
2873 
2874     TRACE("%s %s %p %p %p %p %p\n", debugstr_w(lpSystemName), debugstr_w(lpAccountName),
2875           Sid, cbSid, ReferencedDomainName, cchReferencedDomainName, peUse);
2876 
2877     if (!ADVAPI_IsLocalComputer( lpSystemName ))
2878     {
2879         FIXME("remote computer not supported\n");
2880         SetLastError( RPC_S_SERVER_UNAVAILABLE );
2881         return FALSE;
2882     }
2883 
2884     if (!lpAccountName || !strcmpW( lpAccountName, Blank ))
2885     {
2886         lpAccountName = BUILTIN;
2887     }
2888 
2889     RtlInitUnicodeString( &account, lpAccountName );
2890 
2891     /* Check well known SIDs first */
2892     ret = lookup_local_wellknown_name( &account, Sid, cbSid, ReferencedDomainName,
2893                                        cchReferencedDomainName, peUse, &handled );
2894     if (handled)
2895         return ret;
2896 
2897     /* Check user names */
2898     ret = lookup_local_user_name( &account, Sid, cbSid, ReferencedDomainName,
2899                                   cchReferencedDomainName, peUse, &handled);
2900     if (handled)
2901         return ret;
2902 
2903     SetLastError( ERROR_NONE_MAPPED );
2904     return FALSE;
2905 }
2906 
2907 /******************************************************************************
2908  * PrivilegeCheck [ADVAPI32.@]
2909  */
2910 BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
2911 {
2912     BOOL ret;
2913     BOOLEAN Result;
2914 
2915     TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
2916 
2917     ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
2918     if (ret)
2919         *pfResult = Result;
2920     return ret;
2921 }
2922 
2923 /******************************************************************************
2924  * AccessCheckAndAuditAlarmA [ADVAPI32.@]
2925  */
2926 BOOL WINAPI AccessCheckAndAuditAlarmA(LPCSTR Subsystem, LPVOID HandleId, LPSTR ObjectTypeName,
2927   LPSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2928   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2929   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2930 {
2931         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_a(Subsystem),
2932                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName),
2933                 SecurityDescriptor, DesiredAccess, GenericMapping,
2934                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2935         return TRUE;
2936 }
2937 
2938 /******************************************************************************
2939  * AccessCheckAndAuditAlarmW [ADVAPI32.@]
2940  */
2941 BOOL WINAPI AccessCheckAndAuditAlarmW(LPCWSTR Subsystem, LPVOID HandleId, LPWSTR ObjectTypeName,
2942   LPWSTR ObjectName, PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD DesiredAccess,
2943   PGENERIC_MAPPING GenericMapping, BOOL ObjectCreation, LPDWORD GrantedAccess,
2944   LPBOOL AccessStatus, LPBOOL pfGenerateOnClose)
2945 {
2946         FIXME("stub (%s,%p,%s,%s,%p,%08x,%p,%x,%p,%p,%p)\n", debugstr_w(Subsystem),
2947                 HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName),
2948                 SecurityDescriptor, DesiredAccess, GenericMapping,
2949                 ObjectCreation, GrantedAccess, AccessStatus, pfGenerateOnClose);
2950         return TRUE;
2951 }
2952 
2953 BOOL WINAPI ObjectCloseAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2954 {
2955     FIXME("stub (%s,%p,%x)\n", debugstr_a(SubsystemName), HandleId, GenerateOnClose);
2956 
2957     return TRUE;
2958 }
2959 
2960 BOOL WINAPI ObjectCloseAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2961 {
2962     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2963 
2964     return TRUE;
2965 }
2966 
2967 BOOL WINAPI ObjectDeleteAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, BOOL GenerateOnClose)
2968 {
2969     FIXME("stub (%s,%p,%x)\n", debugstr_w(SubsystemName), HandleId, GenerateOnClose);
2970 
2971     return TRUE;
2972 }
2973 
2974 BOOL WINAPI ObjectOpenAuditAlarmA(LPCSTR SubsystemName, LPVOID HandleId, LPSTR ObjectTypeName,
2975   LPSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2976   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2977   LPBOOL GenerateOnClose)
2978 {
2979         FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_a(SubsystemName),
2980                 HandleId, debugstr_a(ObjectTypeName), debugstr_a(ObjectName), pSecurityDescriptor,
2981         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2982         GenerateOnClose);
2983 
2984     return TRUE;
2985 }
2986 
2987 BOOL WINAPI ObjectOpenAuditAlarmW(LPCWSTR SubsystemName, LPVOID HandleId, LPWSTR ObjectTypeName,
2988   LPWSTR ObjectName, PSECURITY_DESCRIPTOR pSecurityDescriptor, HANDLE ClientToken, DWORD DesiredAccess,
2989   DWORD GrantedAccess, PPRIVILEGE_SET Privileges, BOOL ObjectCreation, BOOL AccessGranted,
2990   LPBOOL GenerateOnClose)
2991 {
2992     FIXME("stub (%s,%p,%s,%s,%p,%p,0x%08x,0x%08x,%p,%x,%x,%p)\n", debugstr_w(SubsystemName),
2993         HandleId, debugstr_w(ObjectTypeName), debugstr_w(ObjectName), pSecurityDescriptor,
2994         ClientToken, DesiredAccess, GrantedAccess, Privileges, ObjectCreation, AccessGranted,
2995         GenerateOnClose);
2996 
2997     return TRUE;
2998 }
2999 
3000 BOOL WINAPI ObjectPrivilegeAuditAlarmA( LPCSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3001   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3002 {
3003     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_a(SubsystemName), HandleId, ClientToken,
3004           DesiredAccess, Privileges, AccessGranted);
3005 
3006     return TRUE;
3007 }
3008 
3009 BOOL WINAPI ObjectPrivilegeAuditAlarmW( LPCWSTR SubsystemName, LPVOID HandleId, HANDLE ClientToken,
3010   DWORD DesiredAccess, PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3011 {
3012     FIXME("stub (%s,%p,%p,0x%08x,%p,%x)\n", debugstr_w(SubsystemName), HandleId, ClientToken,
3013           DesiredAccess, Privileges, AccessGranted);
3014 
3015     return TRUE;
3016 }
3017 
3018 BOOL WINAPI PrivilegedServiceAuditAlarmA( LPCSTR SubsystemName, LPCSTR ServiceName, HANDLE ClientToken,
3019                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3020 {
3021     FIXME("stub (%s,%s,%p,%p,%x)\n", debugstr_a(SubsystemName), debugstr_a(ServiceName),
3022           ClientToken, Privileges, AccessGranted);
3023 
3024     return TRUE;
3025 }
3026 
3027 BOOL WINAPI PrivilegedServiceAuditAlarmW( LPCWSTR SubsystemName, LPCWSTR ServiceName, HANDLE ClientToken,
3028                                    PPRIVILEGE_SET Privileges, BOOL AccessGranted)
3029 {
3030     FIXME("stub %s,%s,%p,%p,%x)\n", debugstr_w(SubsystemName), debugstr_w(ServiceName),
3031           ClientToken, Privileges, AccessGranted);
3032 
3033     return TRUE;
3034 }
3035 
3036 /******************************************************************************
3037  * GetSecurityInfo [ADVAPI32.@]
3038  *
3039  * Retrieves a copy of the security descriptor associated with an object.
3040  *
3041  * PARAMS
3042  *  hObject              [I] A handle for the object.
3043  *  ObjectType           [I] The type of object.
3044  *  SecurityInfo         [I] A bitmask indicating what info to retrieve.
3045  *  ppsidOwner           [O] If non-null, receives a pointer to the owner SID.
3046  *  ppsidGroup           [O] If non-null, receives a pointer to the group SID.
3047  *  ppDacl               [O] If non-null, receives a pointer to the DACL.
3048  *  ppSacl               [O] If non-null, receives a pointer to the SACL.
3049  *  ppSecurityDescriptor [O] Receives a pointer to the security descriptor,
3050  *                           which must be freed with LocalFree.
3051  *
3052  * RETURNS
3053  *  ERROR_SUCCESS if all's well, and a WIN32 error code otherwise.
3054  */
3055 DWORD WINAPI GetSecurityInfo(
3056     HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3057     SECURITY_INFORMATION SecurityInfo, PSID *ppsidOwner,
3058     PSID *ppsidGroup, PACL *ppDacl, PACL *ppSacl,
3059     PSECURITY_DESCRIPTOR *ppSecurityDescriptor
3060 )
3061 {
3062     PSECURITY_DESCRIPTOR sd;
3063     NTSTATUS status;
3064     ULONG n1, n2;
3065     BOOL present, defaulted;
3066 
3067     status = NtQuerySecurityObject(hObject, SecurityInfo, NULL, 0, &n1);
3068     if (status != STATUS_BUFFER_TOO_SMALL && status != STATUS_SUCCESS)
3069         return RtlNtStatusToDosError(status);
3070 
3071     sd = LocalAlloc(0, n1);
3072     if (!sd)
3073         return ERROR_NOT_ENOUGH_MEMORY;
3074 
3075     status = NtQuerySecurityObject(hObject, SecurityInfo, sd, n1, &n2);
3076     if (status != STATUS_SUCCESS)
3077     {
3078         LocalFree(sd);
3079         return RtlNtStatusToDosError(status);
3080     }
3081 
3082     if (ppsidOwner)
3083     {
3084         *ppsidOwner = NULL;
3085         GetSecurityDescriptorOwner(sd, ppsidOwner, &defaulted);
3086     }
3087     if (ppsidGroup)
3088     {
3089         *ppsidGroup = NULL;
3090         GetSecurityDescriptorGroup(sd, ppsidGroup, &defaulted);
3091     }
3092     if (ppDacl)
3093     {
3094         *ppDacl = NULL;
3095         GetSecurityDescriptorDacl(sd, &present, ppDacl, &defaulted);
3096     }
3097     if (ppSacl)
3098     {
3099         *ppSacl = NULL;
3100         GetSecurityDescriptorSacl(sd, &present, ppSacl, &defaulted);
3101     }
3102     if (ppSecurityDescriptor)
3103         *ppSecurityDescriptor = sd;
3104 
3105     /* The security descriptor (sd) cannot be freed if ppSecurityDescriptor is
3106      * NULL, because native happily returns the SIDs and ACLs that are requested
3107      * in this case.
3108      */
3109 
3110     return ERROR_SUCCESS;
3111 }
3112 
3113 /******************************************************************************
3114  * GetSecurityInfoExA [ADVAPI32.@]
3115  */
3116 DWORD WINAPI GetSecurityInfoExA(
3117         HANDLE hObject, SE_OBJECT_TYPE ObjectType,
3118         SECURITY_INFORMATION SecurityInfo, LPCSTR lpProvider,
3119         LPCSTR lpProperty, PACTRL_ACCESSA *ppAccessList,
3120         PACTRL_AUDITA *ppAuditList, LPSTR *lppOwner, LPSTR *lppGroup
3121 )
3122 {
3123   FIXME("stub!\n");
3124   return ERROR_BAD_PROVIDER;
3125 }
3126 
3127 /******************************************************************************
3128  * GetSecurityInfoExW [ADVAPI32.@]
3129  */
3130 DWORD WINAPI GetSecurityInfoExW(
3131         HANDLE hObject, SE_OBJECT_TYPE ObjectType, 
3132         SECURITY_INFORMATION SecurityInfo, LPCWSTR lpProvider,
3133         LPCWSTR lpProperty, PACTRL_ACCESSW *ppAccessList, 
3134         PACTRL_AUDITW *ppAuditList, LPWSTR *lppOwner, LPWSTR *lppGroup
3135 )
3136 {
3137   FIXME("stub!\n");
3138   return ERROR_BAD_PROVIDER; 
3139 }
3140 
3141 /******************************************************************************
3142  * BuildExplicitAccessWithNameA [ADVAPI32.@]
3143  */
3144 VOID WINAPI BuildExplicitAccessWithNameA( PEXPLICIT_ACCESSA pExplicitAccess,
3145                                           LPSTR pTrusteeName, DWORD AccessPermissions,
3146                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3147 {
3148     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_a(pTrusteeName),
3149           AccessPermissions, AccessMode, Inheritance);
3150 
3151     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3152     pExplicitAccess->grfAccessMode = AccessMode;
3153     pExplicitAccess->grfInheritance = Inheritance;
3154 
3155     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3156     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3157     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3158     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3159     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3160 }
3161 
3162 /******************************************************************************
3163  * BuildExplicitAccessWithNameW [ADVAPI32.@]
3164  */
3165 VOID WINAPI BuildExplicitAccessWithNameW( PEXPLICIT_ACCESSW pExplicitAccess,
3166                                           LPWSTR pTrusteeName, DWORD AccessPermissions,
3167                                           ACCESS_MODE AccessMode, DWORD Inheritance )
3168 {
3169     TRACE("%p %s 0x%08x 0x%08x 0x%08x\n", pExplicitAccess, debugstr_w(pTrusteeName),
3170           AccessPermissions, AccessMode, Inheritance);
3171 
3172     pExplicitAccess->grfAccessPermissions = AccessPermissions;
3173     pExplicitAccess->grfAccessMode = AccessMode;
3174     pExplicitAccess->grfInheritance = Inheritance;
3175 
3176     pExplicitAccess->Trustee.pMultipleTrustee = NULL;
3177     pExplicitAccess->Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3178     pExplicitAccess->Trustee.TrusteeForm = TRUSTEE_IS_NAME;
3179     pExplicitAccess->Trustee.TrusteeType = TRUSTEE_IS_UNKNOWN;
3180     pExplicitAccess->Trustee.ptstrName = pTrusteeName;
3181 }
3182 
3183 /******************************************************************************
3184  * BuildTrusteeWithObjectsAndNameA [ADVAPI32.@]
3185  */
3186 VOID WINAPI BuildTrusteeWithObjectsAndNameA( PTRUSTEEA pTrustee, POBJECTS_AND_NAME_A pObjName,
3187                                              SE_OBJECT_TYPE ObjectType, LPSTR ObjectTypeName,
3188                                              LPSTR InheritedObjectTypeName, LPSTR Name )
3189 {
3190     DWORD ObjectsPresent = 0;
3191 
3192     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3193           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_a(Name));
3194 
3195     /* Fill the OBJECTS_AND_NAME structure */
3196     pObjName->ObjectType = ObjectType;
3197     if (ObjectTypeName != NULL)
3198     {
3199         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3200     }
3201 
3202     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3203     if (InheritedObjectTypeName != NULL)
3204     {
3205         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3206     }
3207 
3208     pObjName->ObjectsPresent = ObjectsPresent;
3209     pObjName->ptstrName = Name;
3210 
3211     /* Fill the TRUSTEE structure */
3212     pTrustee->pMultipleTrustee = NULL;
3213     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3214     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3215     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3216     pTrustee->ptstrName = (LPSTR)pObjName;
3217 }
3218 
3219 /******************************************************************************
3220  * BuildTrusteeWithObjectsAndNameW [ADVAPI32.@]
3221  */
3222 VOID WINAPI BuildTrusteeWithObjectsAndNameW( PTRUSTEEW pTrustee, POBJECTS_AND_NAME_W pObjName,
3223                                              SE_OBJECT_TYPE ObjectType, LPWSTR ObjectTypeName,
3224                                              LPWSTR InheritedObjectTypeName, LPWSTR Name )
3225 {
3226     DWORD ObjectsPresent = 0;
3227 
3228     TRACE("%p %p 0x%08x %p %p %s\n", pTrustee, pObjName,
3229           ObjectType, ObjectTypeName, InheritedObjectTypeName, debugstr_w(Name));
3230 
3231     /* Fill the OBJECTS_AND_NAME structure */
3232     pObjName->ObjectType = ObjectType;
3233     if (ObjectTypeName != NULL)
3234     {
3235         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3236     }
3237 
3238     pObjName->InheritedObjectTypeName = InheritedObjectTypeName;
3239     if (InheritedObjectTypeName != NULL)
3240     {
3241         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3242     }
3243 
3244     pObjName->ObjectsPresent = ObjectsPresent;
3245     pObjName->ptstrName = Name;
3246 
3247     /* Fill the TRUSTEE structure */
3248     pTrustee->pMultipleTrustee = NULL;
3249     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3250     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_NAME;
3251     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3252     pTrustee->ptstrName = (LPWSTR)pObjName;
3253 }
3254 
3255 /******************************************************************************
3256  * BuildTrusteeWithObjectsAndSidA [ADVAPI32.@]
3257  */
3258 VOID WINAPI BuildTrusteeWithObjectsAndSidA( PTRUSTEEA pTrustee, POBJECTS_AND_SID pObjSid,
3259                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3260 {
3261     DWORD ObjectsPresent = 0;
3262 
3263     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3264 
3265     /* Fill the OBJECTS_AND_SID structure */
3266     if (pObjectGuid != NULL)
3267     {
3268         pObjSid->ObjectTypeGuid = *pObjectGuid;
3269         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3270     }
3271     else
3272     {
3273         ZeroMemory(&pObjSid->ObjectTypeGuid,
3274                    sizeof(GUID));
3275     }
3276 
3277     if (pInheritedObjectGuid != NULL)
3278     {
3279         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3280         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3281     }
3282     else
3283     {
3284         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3285                    sizeof(GUID));
3286     }
3287 
3288     pObjSid->ObjectsPresent = ObjectsPresent;
3289     pObjSid->pSid = pSid;
3290 
3291     /* Fill the TRUSTEE structure */
3292     pTrustee->pMultipleTrustee = NULL;
3293     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3294     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3295     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3296     pTrustee->ptstrName = (LPSTR) pObjSid;
3297 }
3298 
3299 /******************************************************************************
3300  * BuildTrusteeWithObjectsAndSidW [ADVAPI32.@]
3301  */
3302 VOID WINAPI BuildTrusteeWithObjectsAndSidW( PTRUSTEEW pTrustee, POBJECTS_AND_SID pObjSid,
3303                                             GUID* pObjectGuid, GUID* pInheritedObjectGuid, PSID pSid )
3304 {
3305     DWORD ObjectsPresent = 0;
3306 
3307     TRACE("%p %p %p %p %p\n", pTrustee, pObjSid, pObjectGuid, pInheritedObjectGuid, pSid);
3308 
3309     /* Fill the OBJECTS_AND_SID structure */
3310     if (pObjectGuid != NULL)
3311     {
3312         pObjSid->ObjectTypeGuid = *pObjectGuid;
3313         ObjectsPresent |= ACE_OBJECT_TYPE_PRESENT;
3314     }
3315     else
3316     {
3317         ZeroMemory(&pObjSid->ObjectTypeGuid,
3318                    sizeof(GUID));
3319     }
3320 
3321     if (pInheritedObjectGuid != NULL)
3322     {
3323         pObjSid->InheritedObjectTypeGuid = *pInheritedObjectGuid;
3324         ObjectsPresent |= ACE_INHERITED_OBJECT_TYPE_PRESENT;
3325     }
3326     else
3327     {
3328         ZeroMemory(&pObjSid->InheritedObjectTypeGuid,
3329                    sizeof(GUID));
3330     }
3331 
3332     pObjSid->ObjectsPresent = ObjectsPresent;
3333     pObjSid->pSid = pSid;
3334 
3335     /* Fill the TRUSTEE structure */
3336     pTrustee->pMultipleTrustee = NULL;
3337     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3338     pTrustee->TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
3339     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3340     pTrustee->ptstrName = (LPWSTR) pObjSid;
3341 }
3342 
3343 /******************************************************************************
3344  * BuildTrusteeWithSidA [ADVAPI32.@]
3345  */
3346 VOID WINAPI BuildTrusteeWithSidA(PTRUSTEEA pTrustee, PSID pSid)
3347 {
3348     TRACE("%p %p\n", pTrustee, pSid);
3349 
3350     pTrustee->pMultipleTrustee = NULL;
3351     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3352     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3353     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3354     pTrustee->ptstrName = pSid;
3355 }
3356 
3357 /******************************************************************************
3358  * BuildTrusteeWithSidW [ADVAPI32.@]
3359  */
3360 VOID WINAPI BuildTrusteeWithSidW(PTRUSTEEW pTrustee, PSID pSid)
3361 {
3362     TRACE("%p %p\n", pTrustee, pSid);
3363 
3364     pTrustee->pMultipleTrustee = NULL;
3365     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3366     pTrustee->TrusteeForm = TRUSTEE_IS_SID;
3367     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3368     pTrustee->ptstrName = pSid;
3369 }
3370 
3371 /******************************************************************************
3372  * BuildTrusteeWithNameA [ADVAPI32.@]
3373  */
3374 VOID WINAPI BuildTrusteeWithNameA(PTRUSTEEA pTrustee, LPSTR name)
3375 {
3376     TRACE("%p %s\n", pTrustee, debugstr_a(name) );
3377 
3378     pTrustee->pMultipleTrustee = NULL;
3379     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3380     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3381     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3382     pTrustee->ptstrName = name;
3383 }
3384 
3385 /******************************************************************************
3386  * BuildTrusteeWithNameW [ADVAPI32.@]
3387  */
3388 VOID WINAPI BuildTrusteeWithNameW(PTRUSTEEW pTrustee, LPWSTR name)
3389 {
3390     TRACE("%p %s\n", pTrustee, debugstr_w(name) );
3391 
3392     pTrustee->pMultipleTrustee = NULL;
3393     pTrustee->MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
3394     pTrustee->TrusteeForm = TRUSTEE_IS_NAME;
3395     pTrustee->TrusteeType = TRUSTEE_IS_UNKNOWN;
3396     pTrustee->ptstrName = name;
3397 }
3398 
3399 /****************************************************************************** 
3400  * GetTrusteeFormA [ADVAPI32.@] 
3401  */ 
3402 TRUSTEE_FORM WINAPI GetTrusteeFormA(PTRUSTEEA pTrustee) 
3403 {  
3404     TRACE("(%p)\n", pTrustee); 
3405   
3406     if (!pTrustee) 
3407         return TRUSTEE_BAD_FORM; 
3408   
3409     return pTrustee->TrusteeForm; 
3410 }  
3411   
3412 /****************************************************************************** 
3413  * GetTrusteeFormW [ADVAPI32.@] 
3414  */ 
3415 TRUSTEE_FORM WINAPI GetTrusteeFormW(PTRUSTEEW pTrustee) 
3416 {  
3417     TRACE("(%p)\n", pTrustee); 
3418   
3419     if (!pTrustee) 
3420         return TRUSTEE_BAD_FORM; 
3421   
3422     return pTrustee->TrusteeForm; 
3423 }  
3424   
3425 /****************************************************************************** 
3426  * GetTrusteeNameA [ADVAPI32.@] 
3427  */ 
3428 LPSTR WINAPI GetTrusteeNameA(PTRUSTEEA pTrustee) 
3429 {  
3430     TRACE("(%p)\n", pTrustee); 
3431   
3432     if (!pTrustee) 
3433         return NULL; 
3434   
3435     return pTrustee->ptstrName; 
3436 }  
3437   
3438 /****************************************************************************** 
3439  * GetTrusteeNameW [ADVAPI32.@] 
3440  */ 
3441 LPWSTR WINAPI GetTrusteeNameW(PTRUSTEEW pTrustee) 
3442 {  
3443     TRACE("(%p)\n", pTrustee); 
3444   
3445     if (!pTrustee) 
3446         return NULL; 
3447   
3448     return pTrustee->ptstrName; 
3449 }  
3450   
3451 /****************************************************************************** 
3452  * GetTrusteeTypeA [ADVAPI32.@] 
3453  */ 
3454 TRUSTEE_TYPE WINAPI GetTrusteeTypeA(PTRUSTEEA pTrustee) 
3455 {  
3456     TRACE("(%p)\n", pTrustee); 
3457   
3458     if (!pTrustee) 
3459         return TRUSTEE_IS_UNKNOWN; 
3460   
3461     return pTrustee->TrusteeType; 
3462 }  
3463   
3464 /****************************************************************************** 
3465  * GetTrusteeTypeW [ADVAPI32.@] 
3466  */ 
3467 TRUSTEE_TYPE WINAPI GetTrusteeTypeW(PTRUSTEEW pTrustee) 
3468 {  
3469     TRACE("(%p)\n", pTrustee); 
3470   
3471     if (!pTrustee) 
3472         return TRUSTEE_IS_UNKNOWN; 
3473   
3474     return pTrustee->TrusteeType; 
3475 } 
3476  
3477 BOOL WINAPI SetAclInformation( PACL pAcl, LPVOID pAclInformation,
3478                                DWORD nAclInformationLength,
3479                                ACL_INFORMATION_CLASS dwAclInformationClass )
3480 {
3481     FIXME("%p %p 0x%08x 0x%08x - stub\n", pAcl, pAclInformation,
3482           nAclInformationLength, dwAclInformationClass);
3483 
3484     return TRUE;
3485 }
3486 
3487 static DWORD trustee_name_A_to_W(TRUSTEE_FORM form, char *trustee_nameA, WCHAR **ptrustee_nameW)
3488 {
3489     DWORD len;
3490 
3491     switch (form)
3492     {
3493     case TRUSTEE_IS_NAME:
3494     {
3495         WCHAR *wstr = NULL;
3496 
3497         if (trustee_nameA)
3498         {
3499             len = MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, NULL, 0 );
3500             if (!(wstr = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3501                 return ERROR_NOT_ENOUGH_MEMORY;
3502 
3503             MultiByteToWideChar( CP_ACP, 0, trustee_nameA, -1, wstr, len );
3504         }
3505 
3506         *ptrustee_nameW = wstr;
3507         return ERROR_SUCCESS;
3508     }
3509     case TRUSTEE_IS_OBJECTS_AND_NAME:
3510     {
3511         OBJECTS_AND_NAME_A *objA = (OBJECTS_AND_NAME_A *)trustee_nameA;
3512         OBJECTS_AND_NAME_W *objW = NULL;
3513 
3514         if (objA)
3515         {
3516             if (!(objW = HeapAlloc( GetProcessHeap(), 0, sizeof(OBJECTS_AND_NAME_W) )))
3517                 return ERROR_NOT_ENOUGH_MEMORY;
3518 
3519             objW->ObjectsPresent = objA->ObjectsPresent;
3520             objW->ObjectType = objA->ObjectType;
3521             objW->ObjectTypeName = NULL;
3522             objW->InheritedObjectTypeName = NULL;
3523             objW->ptstrName = NULL;
3524 
3525             if (objA->ObjectTypeName)
3526             {
3527                 len = MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, NULL, 0 );
3528                 if (!(objW->ObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3529                     goto error;
3530                 MultiByteToWideChar( CP_ACP, 0, objA->ObjectTypeName, -1, objW->ObjectTypeName, len );
3531             }
3532 
3533             if (objA->InheritedObjectTypeName)
3534             {
3535                 len = MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, NULL, 0 );
3536                 if (!(objW->InheritedObjectTypeName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3537                     goto error;
3538                 MultiByteToWideChar( CP_ACP, 0, objA->InheritedObjectTypeName, -1, objW->InheritedObjectTypeName, len );
3539             }
3540 
3541             if (objA->ptstrName)
3542             {
3543                 len = MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, NULL, 0 );
3544                 if (!(objW->ptstrName = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) )))
3545                     goto error;
3546                 MultiByteToWideChar( CP_ACP, 0, objA->ptstrName, -1, objW->ptstrName, len );
3547             }
3548         }
3549 
3550         *ptrustee_nameW = (WCHAR *)objW;
3551         return ERROR_SUCCESS;
3552 error:
3553         HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3554         HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3555         HeapFree( GetProcessHeap(), 0, objW );
3556         return ERROR_NOT_ENOUGH_MEMORY;
3557     }
3558     /* These forms do not require conversion. */
3559     case TRUSTEE_IS_SID:
3560     case TRUSTEE_IS_OBJECTS_AND_SID:
3561         *ptrustee_nameW = (WCHAR *)trustee_nameA;
3562         return ERROR_SUCCESS;
3563     default:
3564         return ERROR_INVALID_PARAMETER;
3565     }
3566 }
3567 
3568 static void free_trustee_name(TRUSTEE_FORM form, WCHAR *trustee_nameW)
3569 {
3570     switch (form)
3571     {
3572     case TRUSTEE_IS_NAME:
3573         HeapFree( GetProcessHeap(), 0, trustee_nameW );
3574         break;
3575     case TRUSTEE_IS_OBJECTS_AND_NAME:
3576     {
3577         OBJECTS_AND_NAME_W *objW = (OBJECTS_AND_NAME_W *)trustee_nameW;
3578 
3579         if (objW)
3580         {
3581             HeapFree( GetProcessHeap(), 0, objW->ptstrName );
3582             HeapFree( GetProcessHeap(), 0, objW->InheritedObjectTypeName );
3583             HeapFree( GetProcessHeap(), 0, objW->ObjectTypeName );
3584             HeapFree( GetProcessHeap(), 0, objW );
3585         }
3586 
3587         break;
3588     }
3589     /* Other forms did not require allocation, so no freeing is necessary. */
3590     default:
3591         break;
3592     }
3593 }
3594 
3595 /******************************************************************************
3596  * SetEntriesInAclA [ADVAPI32.@]
3597  */
3598 DWORD WINAPI SetEntriesInAclA( ULONG count, PEXPLICIT_ACCESSA pEntries,
3599                                PACL OldAcl, PACL* NewAcl )
3600 {
3601     DWORD err = ERROR_SUCCESS;
3602     EXPLICIT_ACCESSW *pEntriesW;
3603     UINT alloc_index, free_index;
3604 
3605     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3606 
3607     if (NewAcl)
3608         *NewAcl = NULL;
3609 
3610     if (!count && !OldAcl)
3611         return ERROR_SUCCESS;
3612 
3613     pEntriesW = HeapAlloc( GetProcessHeap(), 0, count * sizeof(EXPLICIT_ACCESSW) );
3614     if (!pEntriesW)
3615         return ERROR_NOT_ENOUGH_MEMORY;
3616 
3617     for (alloc_index = 0; alloc_index < count; ++alloc_index)
3618     {
3619         pEntriesW[alloc_index].grfAccessPermissions = pEntries[alloc_index].grfAccessPermissions;
3620         pEntriesW[alloc_index].grfAccessMode = pEntries[alloc_index].grfAccessMode;
3621         pEntriesW[alloc_index].grfInheritance = pEntries[alloc_index].grfInheritance;
3622         pEntriesW[alloc_index].Trustee.pMultipleTrustee = NULL; /* currently not supported */
3623         pEntriesW[alloc_index].Trustee.MultipleTrusteeOperation = pEntries[alloc_index].Trustee.MultipleTrusteeOperation;
3624         pEntriesW[alloc_index].Trustee.TrusteeForm = pEntries[alloc_index].Trustee.TrusteeForm;
3625         pEntriesW[alloc_index].Trustee.TrusteeType = pEntries[alloc_index].Trustee.TrusteeType;
3626 
3627         err = trustee_name_A_to_W( pEntries[alloc_index].Trustee.TrusteeForm,
3628                                    pEntries[alloc_index].Trustee.ptstrName,
3629                                    &pEntriesW[alloc_index].Trustee.ptstrName );
3630         if (err != ERROR_SUCCESS)
3631         {
3632             if (err == ERROR_INVALID_PARAMETER)
3633                 WARN("bad trustee form %d for trustee %d\n",
3634                      pEntries[alloc_index].Trustee.TrusteeForm, alloc_index);
3635 
3636             goto cleanup;
3637         }
3638     }
3639 
3640     err = SetEntriesInAclW( count, pEntriesW, OldAcl, NewAcl );
3641 
3642 cleanup:
3643     /* Free any previously allocated trustee name buffers, taking into account
3644      * a possible out-of-memory condition while building the EXPLICIT_ACCESSW
3645      * list. */
3646     for (free_index = 0; free_index < alloc_index; ++free_index)
3647         free_trustee_name( pEntriesW[free_index].Trustee.TrusteeForm, pEntriesW[free_index].Trustee.ptstrName );
3648 
3649     HeapFree( GetProcessHeap(), 0, pEntriesW );
3650     return err;
3651 }
3652 
3653 /******************************************************************************
3654  * SetEntriesInAclW [ADVAPI32.@]
3655  */
3656 DWORD WINAPI SetEntriesInAclW( ULONG count, PEXPLICIT_ACCESSW pEntries,
3657                                PACL OldAcl, PACL* NewAcl )
3658 {
3659     ULONG i;
3660     PSID *ppsid;
3661     DWORD ret = ERROR_SUCCESS;
3662     DWORD acl_size = sizeof(ACL);
3663     NTSTATUS status;
3664 
3665     TRACE("%d %p %p %p\n", count, pEntries, OldAcl, NewAcl);
3666 
3667     if (NewAcl)
3668         *NewAcl = NULL;
3669 
3670     if (!count && !OldAcl)
3671         return ERROR_SUCCESS;
3672 
3673     /* allocate array of maximum sized sids allowed */
3674     ppsid = HeapAlloc(GetProcessHeap(), 0, count * (sizeof(SID *) + FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES])));
3675     if (!ppsid)
3676         return ERROR_OUTOFMEMORY;
3677 
3678     for (i = 0; i < count; i++)
3679     {
3680         ppsid[i] = (char *)&ppsid[count] + i * FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3681 
3682         TRACE("[%d]:\n\tgrfAccessPermissions = 0x%x\n\tgrfAccessMode = %d\n\tgrfInheritance = 0x%x\n\t"
3683               "Trustee.pMultipleTrustee = %p\n\tMultipleTrusteeOperation = %d\n\tTrusteeForm = %d\n\t"
3684               "Trustee.TrusteeType = %d\n\tptstrName = %p\n", i,
3685               pEntries[i].grfAccessPermissions, pEntries[i].grfAccessMode, pEntries[i].grfInheritance,
3686               pEntries[i].Trustee.pMultipleTrustee, pEntries[i].Trustee.MultipleTrusteeOperation,
3687               pEntries[i].Trustee.TrusteeForm, pEntries[i].Trustee.TrusteeType,
3688               pEntries[i].Trustee.ptstrName);
3689 
3690         if (pEntries[i].Trustee.MultipleTrusteeOperation == TRUSTEE_IS_IMPERSONATE)
3691         {
3692             WARN("bad multiple trustee operation %d for trustee %d\n", pEntries[i].Trustee.MultipleTrusteeOperation, i);
3693             ret = ERROR_INVALID_PARAMETER;
3694             goto exit;
3695         }
3696 
3697         switch (pEntries[i].Trustee.TrusteeForm)
3698         {
3699         case TRUSTEE_IS_SID:
3700             if (!CopySid(FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]),
3701                          ppsid[i], pEntries[i].Trustee.ptstrName))
3702             {
3703                 WARN("bad sid %p for trustee %d\n", pEntries[i].Trustee.ptstrName, i);
3704                 ret = ERROR_INVALID_PARAMETER;
3705                 goto exit;
3706             }
3707             break;
3708         case TRUSTEE_IS_NAME:
3709         {
3710             DWORD sid_size = FIELD_OFFSET(SID, SubAuthority[SID_MAX_SUB_AUTHORITIES]);
3711             DWORD domain_size = MAX_COMPUTERNAME_LENGTH + 1;
3712             SID_NAME_USE use;
3713             if (!strcmpW( pEntries[i].Trustee.ptstrName, CURRENT_USER ))
3714             {
3715                 if (!lookup_user_account_name( ppsid[i], &sid_size, NULL, &domain_size, &use ))
3716                 {
3717                     ret = GetLastError();
3718                     goto exit;
3719                 }
3720             }
3721             else if (!LookupAccountNameW(NULL, pEntries[i].Trustee.ptstrName, ppsid[i], &sid_size, NULL, &domain_size, &use))
3722             {
3723                 WARN("bad user name %s for trustee %d\n", debugstr_w(pEntries[i].Trustee.ptstrName), i);
3724                 ret = ERROR_INVALID_PARAMETER;
3725                 goto exit;
3726             }
3727             break;
3728         }
3729         case TRUSTEE_IS_OBJECTS_AND_SID:
3730             FIXME("TRUSTEE_IS_OBJECTS_AND_SID unimplemented\n");
3731             break;
3732         case TRUSTEE_IS_OBJECTS_AND_NAME:
3733             FIXME("TRUSTEE_IS_OBJECTS_AND_NAME unimplemented\n");
3734             break;
3735         default:
3736             WARN("bad trustee form %d for trustee %d\n", pEntries[i].Trustee.TrusteeForm, i);
3737             ret = ERROR_INVALID_PARAMETER;
3738             goto exit;
3739         }
3740 
3741         /* Note: we overestimate the ACL size here as a tradeoff between
3742          * instructions (simplicity) and memory */
3743         switch (pEntries[i].grfAccessMode)
3744         {
3745         case GRANT_ACCESS:
3746         case SET_ACCESS:
3747             acl_size += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3748             break;
3749         case DENY_ACCESS:
3750             acl_size += FIELD_OFFSET(ACCESS_DENIED_ACE, SidStart) + GetLengthSid(ppsid[i]);
3751             break;
3752         case SET_AUDIT_SUCCESS:
3753         case SET_AUDIT_FAILURE:
3754             acl_size += FIELD_OFFSET(SYSTEM_AUDIT_ACE, SidStart) + GetLengthSid(ppsid[i]);
3755             break;
3756         case REVOKE_ACCESS:
3757             break;
3758         default:
3759             WARN("bad access mode %d for trustee %d\n", pEntries[i].grfAccessMode, i);
3760             ret = ERROR_INVALID_PARAMETER;
3761             goto exit;
3762         }
3763     }
3764 
3765     if (OldAcl)
3766     {
3767         ACL_SIZE_INFORMATION size_info;
3768 
3769         status = RtlQueryInformationAcl(OldAcl, &size_info, sizeof(size_info), AclSizeInformation);
3770         if (status != STATUS_SUCCESS)
3771         {
3772             ret = RtlNtStatusToDosError(status);
3773             goto exit;
3774         }
3775         acl_size += size_info.AclBytesInUse - sizeof(ACL);
3776     }
3777 
3778     *NewAcl = LocalAlloc(0, acl_size);
3779     if (!*NewAcl)
3780     {
3781         ret = ERROR_OUTOFMEMORY;
3782         goto exit;
3783     }
3784 
3785     status = RtlCreateAcl( *NewAcl, acl_size, ACL_REVISION );
3786     if (status != STATUS_SUCCESS)
3787     {
3788         ret = RtlNtStatusToDosError(status);
3789         goto exit;
3790     }
3791 
3792     for (i = 0; i < count; i++)
3793     {
3794         switch (pEntries[i].grfAccessMode)
3795         {
3796         case GRANT_ACCESS:
3797             status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3798                                               pEntries[i].grfInheritance,
3799                                               pEntries[i].grfAccessPermissions,
3800                                               ppsid[i]);
3801             break;
3802         case SET_ACCESS:
3803         {
3804             ULONG j;
3805             BOOL add = TRUE;
3806             if (OldAcl)
3807             {
3808                 for (j = 0; ; j++)
3809                 {
3810                     const ACE_HEADER *existing_ace_header;
3811                     status = RtlGetAce(OldAcl, j, (LPVOID *)&existing_ace_header);
3812                     if (status != STATUS_SUCCESS)
3813                         break;
3814                     if (pEntries[i].grfAccessMode == SET_ACCESS &&
3815                         existing_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3816                         EqualSid(ppsid[i], &((ACCESS_ALLOWED_ACE *)existing_ace_header)->SidStart))
3817                     {
3818                         add = FALSE;
3819                         break;
3820                     }
3821                 }
3822             }
3823             if (add)
3824                 status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION,
3825                                                   pEntries[i].grfInheritance,
3826                                                   pEntries[i].grfAccessPermissions,
3827                                                   ppsid[i]);
3828             break;
3829         }
3830         case DENY_ACCESS:
3831             status = RtlAddAccessDeniedAceEx(*NewAcl, ACL_REVISION,
3832                                              pEntries[i].grfInheritance,
3833                                              pEntries[i].grfAccessPermissions,
3834                                              ppsid[i]);
3835             break;
3836         case SET_AUDIT_SUCCESS:
3837             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3838                                             pEntries[i].grfInheritance,
3839                                             pEntries[i].grfAccessPermissions,
3840                                             ppsid[i], TRUE, FALSE);
3841             break;
3842         case SET_AUDIT_FAILURE:
3843             status = RtlAddAuditAccessAceEx(*NewAcl, ACL_REVISION,
3844                                             pEntries[i].grfInheritance,
3845                                             pEntries[i].grfAccessPermissions,
3846                                             ppsid[i], FALSE, TRUE);
3847             break;
3848         default:
3849             FIXME("unhandled access mode %d\n", pEntries[i].grfAccessMode);
3850         }
3851     }
3852 
3853     if (OldAcl)
3854     {
3855         for (i = 0; ; i++)
3856         {
3857             BOOL add = TRUE;
3858             ULONG j;
3859             const ACE_HEADER *old_ace_header;
3860             status = RtlGetAce(OldAcl, i, (LPVOID *)&old_ace_header);
3861             if (status != STATUS_SUCCESS) break;
3862             for (j = 0; j < count; j++)
3863             {
3864                 if (pEntries[j].grfAccessMode == SET_ACCESS &&
3865                     old_ace_header->AceType == ACCESS_ALLOWED_ACE_TYPE &&
3866                     EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3867                 {
3868                     status = RtlAddAccessAllowedAceEx(*NewAcl, ACL_REVISION, pEntries[j].grfInheritance, pEntries[j].grfAccessPermissions, ppsid[j]);
3869                     add = FALSE;
3870                     break;
3871                 }
3872                 else if (pEntries[j].grfAccessMode == REVOKE_ACCESS)
3873                 {
3874                     switch (old_ace_header->AceType)
3875                     {
3876                     case ACCESS_ALLOWED_ACE_TYPE:
3877                         if (EqualSid(ppsid[j], &((ACCESS_ALLOWED_ACE *)old_ace_header)->SidStart))
3878                             add = FALSE;
3879                         break;
3880                     case ACCESS_DENIED_ACE_TYPE:
3881                         if (EqualSid(ppsid[j], &((ACCESS_DENIED_ACE *)old_ace_header)->SidStart))
3882                             add = FALSE;
3883                         break;
3884                     case SYSTEM_AUDIT_ACE_TYPE:
3885                         if (EqualSid(ppsid[j], &((SYSTEM_AUDIT_ACE *)old_ace_header)->SidStart))
3886                             add = FALSE;
3887                         break;
3888                     case SYSTEM_ALARM_ACE_TYPE:
3889                         if (EqualSid(ppsid[j], &((SYSTEM_ALARM_ACE *)old_ace_header)->SidStart))
3890                             add = FALSE;
3891                         break;
3892                     default:
3893                         FIXME("unhandled ace type %d\n", old_ace_header->AceType);
3894                     }
3895 
3896                     if (!add)
3897                         break;
3898                 }
3899             }
3900             if (add)
3901                 status = RtlAddAce(*NewAcl, ACL_REVISION, 1, (PACE_HEADER)old_ace_header, old_ace_header->AceSize);
3902             if (status != STATUS_SUCCESS)
3903             {
3904                 WARN("RtlAddAce failed with error 0x%08x\n", status);
3905                 ret = RtlNtStatusToDosError(status);
3906                 break;
3907             }
3908         }
3909     }
3910 
3911 exit:
3912     HeapFree(GetProcessHeap(), 0, ppsid);
3913     return ret;
3914 }
3915 
3916 /******************************************************************************
3917  * SetNamedSecurityInfoA [ADVAPI32.@]
3918  */
3919 DWORD WINAPI SetNamedSecurityInfoA(LPSTR pObjectName,
3920         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3921         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3922 {
3923     DWORD len;
3924     LPWSTR wstr = NULL;
3925     DWORD r;
3926 
3927     TRACE("%s %d %d %p %p %p %p\n", debugstr_a(pObjectName), ObjectType,
3928            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3929 
3930     if( pObjectName )
3931     {
3932         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
3933         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
3934         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
3935     }
3936 
3937     r = SetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, psidOwner,
3938                            psidGroup, pDacl, pSacl );
3939 
3940     HeapFree( GetProcessHeap(), 0, wstr );
3941 
3942     return r;
3943 }
3944 
3945 BOOL WINAPI SetPrivateObjectSecurity( SECURITY_INFORMATION SecurityInformation,
3946     PSECURITY_DESCRIPTOR ModificationDescriptor,
3947     PSECURITY_DESCRIPTOR* ObjectsSecurityDescriptor,
3948     PGENERIC_MAPPING GenericMapping,
3949     HANDLE Token )
3950 {
3951     FIXME("0x%08x %p %p %p %p - stub\n", SecurityInformation, ModificationDescriptor,
3952           ObjectsSecurityDescriptor, GenericMapping, Token);
3953 
3954     return TRUE;
3955 }
3956 
3957 BOOL WINAPI AreAllAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3958 {
3959     return RtlAreAllAccessesGranted( GrantedAccess, DesiredAccess );
3960 }
3961 
3962 /******************************************************************************
3963  * AreAnyAccessesGranted [ADVAPI32.@]
3964  *
3965  * Determines whether or not any of a set of specified access permissions have
3966  * been granted or not.
3967  *
3968  * PARAMS
3969  *   GrantedAccess [I] The permissions that have been granted.
3970  *   DesiredAccess [I] The permissions that you want to have.
3971  *
3972  * RETURNS
3973  *   Nonzero if any of the permissions have been granted, zero if none of the
3974  *   permissions have been granted.
3975  */
3976 
3977 BOOL WINAPI AreAnyAccessesGranted( DWORD GrantedAccess, DWORD DesiredAccess )
3978 {
3979     return RtlAreAnyAccessesGranted( GrantedAccess, DesiredAccess );
3980 }
3981 
3982 /******************************************************************************
3983  * SetNamedSecurityInfoW [ADVAPI32.@]
3984  */
3985 DWORD WINAPI SetNamedSecurityInfoW(LPWSTR pObjectName,
3986         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
3987         PSID psidOwner, PSID psidGroup, PACL pDacl, PACL pSacl)
3988 {
3989     FIXME("%s %d %d %p %p %p %p\n", debugstr_w(pObjectName), ObjectType,
3990            SecurityInfo, psidOwner, psidGroup, pDacl, pSacl);
3991     return ERROR_SUCCESS;
3992 }
3993 
3994 /******************************************************************************
3995  * GetExplicitEntriesFromAclA [ADVAPI32.@]
3996  */
3997 DWORD WINAPI GetExplicitEntriesFromAclA( PACL pacl, PULONG pcCountOfExplicitEntries,
3998         PEXPLICIT_ACCESSA* pListOfExplicitEntries)
3999 {
4000     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4001     return ERROR_CALL_NOT_IMPLEMENTED;
4002 }
4003 
4004 /******************************************************************************
4005  * GetExplicitEntriesFromAclW [ADVAPI32.@]
4006  */
4007 DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntries,
4008         PEXPLICIT_ACCESSW* pListOfExplicitEntries)
4009 {
4010     FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
4011     return ERROR_CALL_NOT_IMPLEMENTED;
4012 }
4013 
4014 /******************************************************************************
4015  * GetAuditedPermissionsFromAclA [ADVAPI32.@]
4016  */
4017 DWORD WINAPI GetAuditedPermissionsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4018         PACCESS_MASK pFailedAuditRights)
4019 {
4020     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4021     return ERROR_CALL_NOT_IMPLEMENTED;
4022 
4023 }
4024 
4025 /******************************************************************************
4026  * GetAuditedPermissionsFromAclW [ADVAPI32.@]
4027  */
4028 DWORD WINAPI GetAuditedPermissionsFromAclW( PACL pacl, PTRUSTEEW pTrustee, PACCESS_MASK pSuccessfulAuditedRights,
4029         PACCESS_MASK pFailedAuditRights)
4030 {
4031     FIXME("%p %p %p %p\n",pacl, pTrustee, pSuccessfulAuditedRights, pFailedAuditRights);
4032     return ERROR_CALL_NOT_IMPLEMENTED;
4033 
4034 }
4035 
4036 /******************************************************************************
4037  * ParseAclStringFlags
4038  */
4039 static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
4040 {
4041     DWORD flags = 0;
4042     LPCWSTR szAcl = *StringAcl;
4043 
4044     while (*szAcl != '(')
4045     {
4046         if (*szAcl == 'P')
4047         {
4048             flags |= SE_DACL_PROTECTED;
4049         }
4050         else if (*szAcl == 'A')
4051         {
4052             szAcl++;
4053             if (*szAcl == 'R')
4054                 flags |= SE_DACL_AUTO_INHERIT_REQ;
4055             else if (*szAcl == 'I')
4056                 flags |= SE_DACL_AUTO_INHERITED;
4057         }
4058         szAcl++;
4059     }
4060 
4061     *StringAcl = szAcl;
4062     return flags;
4063 }
4064 
4065 /******************************************************************************
4066  * ParseAceStringType
4067  */
4068 static const ACEFLAG AceType[] =
4069 {
4070     { SDDL_ALARM,          SYSTEM_ALARM_ACE_TYPE },
4071     { SDDL_AUDIT,          SYSTEM_AUDIT_ACE_TYPE },
4072     { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
4073     { SDDL_ACCESS_DENIED,  ACCESS_DENIED_ACE_TYPE },
4074     /*
4075     { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
4076     { SDDL_OBJECT_ACCESS_DENIED,  ACCESS_DENIED_OBJECT_ACE_TYPE },
4077     { SDDL_OBJECT_ALARM,          SYSTEM_ALARM_OBJECT_ACE_TYPE },
4078     { SDDL_OBJECT_AUDIT,          SYSTEM_AUDIT_OBJECT_ACE_TYPE },
4079     */
4080     { NULL, 0 },
4081 };
4082 
4083 static BYTE ParseAceStringType(LPCWSTR* StringAcl)
4084 {
4085     UINT len = 0;
4086     LPCWSTR szAcl = *StringAcl;
4087     const ACEFLAG *lpaf = AceType;
4088 
4089     while (*szAcl == ' ')
4090         szAcl++;
4091 
4092     while (lpaf->wstr &&
4093         (len = strlenW(lpaf->wstr)) &&
4094         strncmpW(lpaf->wstr, szAcl, len))
4095         lpaf++;
4096 
4097     if (!lpaf->wstr)
4098         return 0;
4099 
4100     *StringAcl = szAcl + len;
4101     return lpaf->value;
4102 }
4103 
4104 
4105 /******************************************************************************
4106  * ParseAceStringFlags
4107  */
4108 static const ACEFLAG AceFlags[] =
4109 {
4110     { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
4111     { SDDL_AUDIT_FAILURE,     FAILED_ACCESS_ACE_FLAG },
4112     { SDDL_INHERITED,         INHERITED_ACE },
4113     { SDDL_INHERIT_ONLY,      INHERIT_ONLY_ACE },
4114     { SDDL_NO_PROPAGATE,      NO_PROPAGATE_INHERIT_ACE },
4115     { SDDL_OBJECT_INHERIT,    OBJECT_INHERIT_ACE },
4116     { SDDL_AUDIT_SUCCESS,     SUCCESSFUL_ACCESS_ACE_FLAG },
4117     { NULL, 0 },
4118 };
4119 
4120 static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
4121 {
4122     UINT len = 0;
4123     BYTE flags = 0;
4124     LPCWSTR szAcl = *StringAcl;
4125 
4126     while (*szAcl == ' ')
4127         szAcl++;
4128 
4129     while (*szAcl != ';')
4130     {
4131         const ACEFLAG *lpaf = AceFlags;
4132 
4133         while (lpaf->wstr &&
4134                (len = strlenW(lpaf->wstr)) &&
4135                strncmpW(lpaf->wstr, szAcl, len))
4136             lpaf++;
4137 
4138         if (!lpaf->wstr)
4139             return 0;
4140 
4141         flags |= lpaf->value;
4142         szAcl += len;
4143     }
4144 
4145     *StringAcl = szAcl;
4146     return flags;
4147 }
4148 
4149 
4150 /******************************************************************************
4151  * ParseAceStringRights
4152  */
4153 static const ACEFLAG AceRights[] =
4154 {
4155     { SDDL_GENERIC_ALL,     GENERIC_ALL },
4156     { SDDL_GENERIC_READ,    GENERIC_READ },
4157     { SDDL_GENERIC_WRITE,   GENERIC_WRITE },
4158     { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
4159 
4160     { SDDL_READ_CONTROL,    READ_CONTROL },
4161     { SDDL_STANDARD_DELETE, DELETE },
4162     { SDDL_WRITE_DAC,       WRITE_DAC },
4163     { SDDL_WRITE_OWNER,     WRITE_OWNER },
4164 
4165     { SDDL_READ_PROPERTY,   ADS_RIGHT_DS_READ_PROP},
4166     { SDDL_WRITE_PROPERTY,  ADS_RIGHT_DS_WRITE_PROP},
4167     { SDDL_CREATE_CHILD,    ADS_RIGHT_DS_CREATE_CHILD},
4168     { SDDL_DELETE_CHILD,    ADS_RIGHT_DS_DELETE_CHILD},
4169     { SDDL_LIST_CHILDREN,   ADS_RIGHT_ACTRL_DS_LIST},
4170     { SDDL_SELF_WRITE,      ADS_RIGHT_DS_SELF},
4171     { SDDL_LIST_OBJECT,     ADS_RIGHT_DS_LIST_OBJECT},
4172     { SDDL_DELETE_TREE,     ADS_RIGHT_DS_DELETE_TREE},
4173     { SDDL_CONTROL_ACCESS,  ADS_RIGHT_DS_CONTROL_ACCESS},
4174 
4175     { SDDL_FILE_ALL,        FILE_ALL_ACCESS },
4176     { SDDL_FILE_READ,       FILE_GENERIC_READ },
4177     { SDDL_FILE_WRITE,      FILE_GENERIC_WRITE },
4178     { SDDL_FILE_EXECUTE,    FILE_GENERIC_EXECUTE },
4179 
4180     { SDDL_KEY_ALL,         KEY_ALL_ACCESS },
4181     { SDDL_KEY_READ,        KEY_READ },
4182     { SDDL_KEY_WRITE,       KEY_WRITE },
4183     { SDDL_KEY_EXECUTE,     KEY_EXECUTE },
4184     { NULL, 0 },
4185 };
4186 
4187 static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
4188 {
4189     UINT len = 0;
4190     DWORD rights = 0;
4191     LPCWSTR szAcl = *StringAcl;
4192 
4193     while (*szAcl == ' ')
4194         szAcl++;
4195 
4196     if ((*szAcl == '') && (*(szAcl + 1) == 'x'))
4197     {
4198         LPCWSTR p = szAcl;
4199 
4200         while (*p && *p != ';')
4201             p++;
4202 
4203         if (p - szAcl <= 10 /* 8 hex digits + "0x" */ )
4204         {
4205             rights = strtoulW(szAcl, NULL, 16);
4206             szAcl = p;
4207         }
4208         else
4209             WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
4210     }
4211     else
4212     {
4213         while (*szAcl != ';')
4214         {
4215             const ACEFLAG *lpaf = AceRights;
4216 
4217             while (lpaf->wstr &&
4218                (len = strlenW(lpaf->wstr)) &&
4219                strncmpW(lpaf->wstr, szAcl, len))
4220             {
4221                lpaf++;
4222             }
4223 
4224             if (!lpaf->wstr)
4225                 return 0;
4226 
4227             rights |= lpaf->value;
4228             szAcl += len;
4229         }
4230     }
4231 
4232     *StringAcl = szAcl;
4233     return rights;
4234 }
4235 
4236 
4237 /******************************************************************************
4238  * ParseStringAclToAcl
4239  * 
4240  * dacl_flags(string_ace1)(string_ace2)... (string_acen) 
4241  */
4242 static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, 
4243     PACL pAcl, LPDWORD cBytes)
4244 {
4245     DWORD val;
4246     DWORD sidlen;
4247     DWORD length = sizeof(ACL);
4248     DWORD acesize = 0;
4249     DWORD acecount = 0;
4250     PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
4251     DWORD error = ERROR_INVALID_ACL;
4252 
4253     TRACE("%s\n", debugstr_w(StringAcl));
4254 
4255     if (!StringAcl)
4256         return FALSE;
4257 
4258     if (pAcl) /* pAce is only useful if we're setting values */
4259         pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1);
4260 
4261     /* Parse ACL flags */
4262     *lpdwFlags = ParseAclStringFlags(&StringAcl);
4263 
4264     /* Parse ACE */
4265     while (*StringAcl == '(')
4266     {
4267         StringAcl++;
4268 
4269         /* Parse ACE type */
4270         val = ParseAceStringType(&StringAcl);
4271         if (pAce)
4272             pAce->Header.AceType = (BYTE) val;
4273         if (*StringAcl != ';')
4274         {
4275             error = RPC_S_INVALID_STRING_UUID;
4276             goto lerr;
4277         }
4278         StringAcl++;
4279 
4280         /* Parse ACE flags */
4281         val = ParseAceStringFlags(&StringAcl);
4282         if (pAce)
4283             pAce->Header.AceFlags = (BYTE) val;
4284         if (*StringAcl != ';')
4285             goto lerr;
4286         StringAcl++;
4287 
4288         /* Parse ACE rights */
4289         val = ParseAceStringRights(&StringAcl);
4290         if (pAce)
4291             pAce->Mask = val;
4292         if (*StringAcl != ';')
4293             goto lerr;
4294         StringAcl++;
4295 
4296         /* Parse ACE object guid */
4297         while (*StringAcl == ' ')
4298             StringAcl++;
4299         if (*StringAcl != ';')
4300         {
4301             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4302             goto lerr;
4303         }
4304         StringAcl++;
4305 
4306         /* Parse ACE inherit object guid */
4307         while (*StringAcl == ' ')
4308             StringAcl++;
4309         if (*StringAcl != ';')
4310         {
4311             FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
4312             goto lerr;
4313         }
4314         StringAcl++;
4315 
4316         /* Parse ACE account sid */
4317         if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen))
4318         {
4319             while (*StringAcl && *StringAcl != ')')
4320                 StringAcl++;
4321         }
4322 
4323         if (*StringAcl != ')')
4324             goto lerr;
4325         StringAcl++;
4326 
4327         acesize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
4328         length += acesize;
4329         if (pAce)
4330         {
4331             pAce->Header.AceSize = acesize;
4332             pAce = (PACCESS_ALLOWED_ACE)((LPBYTE)pAce + acesize);
4333         }
4334         acecount++;
4335     }
4336 
4337     *cBytes = length;
4338 
4339     if (length > 0xffff)
4340     {
4341         ERR("ACL too large\n");
4342         goto lerr;
4343     }
4344 
4345     if (pAcl)
4346     {
4347         pAcl->AclRevision = ACL_REVISION;
4348         pAcl->Sbz1 = 0;
4349         pAcl->AclSize = length;
4350         pAcl->AceCount = acecount++;
4351         pAcl->Sbz2 = 0;
4352     }
4353     return TRUE;
4354 
4355 lerr:
4356     SetLastError(error);
4357     WARN("Invalid ACE string format\n");
4358     return FALSE;
4359 }
4360 
4361 
4362 /******************************************************************************
4363  * ParseStringSecurityDescriptorToSecurityDescriptor
4364  */
4365 static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
4366     LPCWSTR StringSecurityDescriptor,
4367     SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor,
4368     LPDWORD cBytes)
4369 {
4370     BOOL bret = FALSE;
4371     WCHAR toktype;
4372     WCHAR tok[MAX_PATH];
4373     LPCWSTR lptoken;
4374     LPBYTE lpNext = NULL;
4375     DWORD len;
4376 
4377     *cBytes = sizeof(SECURITY_DESCRIPTOR);
4378 
4379     if (SecurityDescriptor)
4380         lpNext = (LPBYTE)(SecurityDescriptor + 1);
4381 
4382     while (*StringSecurityDescriptor == ' ')
4383         StringSecurityDescriptor++;
4384 
4385     while (*StringSecurityDescriptor)
4386     {
4387         toktype = *StringSecurityDescriptor;
4388 
4389         /* Expect char identifier followed by ':' */
4390         StringSecurityDescriptor++;
4391         if (*StringSecurityDescriptor != ':')
4392         {
4393             SetLastError(ERROR_INVALID_PARAMETER);
4394             goto lend;
4395         }
4396         StringSecurityDescriptor++;
4397 
4398         /* Extract token */
4399         lptoken = StringSecurityDescriptor;
4400         while (*lptoken && *lptoken != ':')
4401             lptoken++;
4402 
4403         if (*lptoken)
4404             lptoken--;
4405 
4406         len = lptoken - StringSecurityDescriptor;
4407         memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
4408         tok[len] = 0;
4409 
4410         switch (toktype)
4411         {
4412             case 'O':
4413             {
4414                 DWORD bytes;
4415 
4416                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4417                     goto lend;
4418 
4419                 if (SecurityDescriptor)
4420                 {
4421                     SecurityDescriptor->Owner = lpNext - (LPBYTE)SecurityDescriptor;
4422                     lpNext += bytes; /* Advance to next token */
4423                 }
4424 
4425                 *cBytes += bytes;
4426 
4427                 break;
4428             }
4429 
4430             case 'G':
4431             {
4432                 DWORD bytes;
4433 
4434                 if (!ParseStringSidToSid(tok, lpNext, &bytes))
4435                     goto lend;
4436 
4437                 if (SecurityDescriptor)
4438                 {
4439                     SecurityDescriptor->Group = lpNext - (LPBYTE)SecurityDescriptor;
4440                     lpNext += bytes; /* Advance to next token */
4441                 }
4442 
4443                 *cBytes += bytes;
4444 
4445                 break;
4446             }
4447 
4448             case 'D':
4449             {
4450                 DWORD flags;
4451                 DWORD bytes;
4452 
4453                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4454                     goto lend;
4455 
4456                 if (SecurityDescriptor)
4457                 {
4458                     SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
4459                     SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor;
4460                     lpNext += bytes; /* Advance to next token */
4461                 }
4462 
4463                 *cBytes += bytes;
4464 
4465                 break;
4466             }
4467 
4468             case 'S':
4469             {
4470                 DWORD flags;
4471                 DWORD bytes;
4472 
4473                 if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
4474                     goto lend;
4475 
4476                 if (SecurityDescriptor)
4477                 {
4478                     SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
4479                     SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor;
4480                     lpNext += bytes; /* Advance to next token */
4481                 }
4482 
4483                 *cBytes += bytes;
4484 
4485                 break;
4486             }
4487 
4488             default:
4489                 FIXME("Unknown token\n");
4490                 SetLastError(ERROR_INVALID_PARAMETER);
4491                 goto lend;
4492         }
4493 
4494         StringSecurityDescriptor = lptoken;
4495     }
4496 
4497     bret = TRUE;
4498 
4499 lend:
4500     return bret;
4501 }
4502 
4503 /******************************************************************************
4504  * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
4505  */
4506 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
4507         LPCSTR StringSecurityDescriptor,
4508         DWORD StringSDRevision,
4509         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4510         PULONG SecurityDescriptorSize)
4511 {
4512     UINT len;
4513     BOOL ret = FALSE;
4514     LPWSTR StringSecurityDescriptorW;
4515 
4516     len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
4517     StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
4518 
4519     if (StringSecurityDescriptorW)
4520     {
4521         MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
4522 
4523         ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
4524                                                                    StringSDRevision, SecurityDescriptor,
4525                                                                    SecurityDescriptorSize);
4526         HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
4527     }
4528 
4529     return ret;
4530 }
4531 
4532 /******************************************************************************
4533  * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
4534  */
4535 BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
4536         LPCWSTR StringSecurityDescriptor,
4537         DWORD StringSDRevision,
4538         PSECURITY_DESCRIPTOR* SecurityDescriptor,
4539         PULONG SecurityDescriptorSize)
4540 {
4541     DWORD cBytes;
4542     SECURITY_DESCRIPTOR* psd;
4543     BOOL bret = FALSE;
4544 
4545     TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
4546 
4547     if (GetVersion() & 0x80000000)
4548     {
4549         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4550         goto lend;
4551     }
4552     else if (!StringSecurityDescriptor || !SecurityDescriptor)
4553     {
4554         SetLastError(ERROR_INVALID_PARAMETER);
4555         goto lend;
4556     }
4557     else if (StringSDRevision != SID_REVISION)
4558     {
4559         SetLastError(ERROR_UNKNOWN_REVISION);
4560         goto lend;
4561     }
4562 
4563     /* Compute security descriptor length */
4564     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4565         NULL, &cBytes))
4566         goto lend;
4567 
4568     psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes);
4569     if (!psd) goto lend;
4570 
4571     psd->Revision = SID_REVISION;
4572     psd->Control |= SE_SELF_RELATIVE;
4573 
4574     if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
4575              (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes))
4576     {
4577         LocalFree(psd);
4578         goto lend;
4579     }
4580 
4581     if (SecurityDescriptorSize)
4582         *SecurityDescriptorSize = cBytes;
4583 
4584     bret = TRUE;
4585  
4586 lend:
4587     TRACE(" ret=%d\n", bret);
4588     return bret;
4589 }
4590 
4591 static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
4592 {
4593     if (cch == -1)
4594         cch = strlenW(string);
4595 
4596     if (plen)
4597         *plen += cch;
4598 
4599     if (pwptr)
4600     {
4601         memcpy(*pwptr, string, sizeof(WCHAR)*cch);
4602         *pwptr += cch;
4603     }
4604 }
4605 
4606 static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
4607 {
4608     DWORD i;
4609     WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
4610     WCHAR subauthfmt[] = { '-','%','u',0 };
4611     WCHAR buf[26];
4612     SID *pisid = psid;
4613 
4614     if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
4615     {
4616         SetLastError(ERROR_INVALID_SID);
4617         return FALSE;
4618     }
4619 
4620     if (pisid->IdentifierAuthority.Value[0] ||
4621      pisid->IdentifierAuthority.Value[1])
4622     {
4623         FIXME("not matching MS' bugs\n");
4624         SetLastError(ERROR_INVALID_SID);
4625         return FALSE;
4626     }
4627 
4628     sprintfW( buf, fmt, pisid->Revision,
4629         MAKELONG(
4630             MAKEWORD( pisid->IdentifierAuthority.Value[5],
4631                     pisid->IdentifierAuthority.Value[4] ),
4632             MAKEWORD( pisid->IdentifierAuthority.Value[3],
4633                     pisid->IdentifierAuthority.Value[2] )
4634         ) );
4635     DumpString(buf, -1, pwptr, plen);
4636 
4637     for( i=0; i<pisid->SubAuthorityCount; i++ )
4638     {
4639         sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
4640         DumpString(buf, -1, pwptr, plen);
4641     }
4642     return TRUE;
4643 }
4644 
4645 static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
4646 {
4647     size_t i;
4648     for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
4649     {
4650         if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
4651         {
4652             DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
4653             return TRUE;
4654         }
4655     }
4656 
4657     return DumpSidNumeric(psid, pwptr, plen);
4658 }
4659 
4660 static const LPCWSTR AceRightBitNames[32] = {
4661         SDDL_CREATE_CHILD,        /*  0 */
4662         SDDL_DELETE_CHILD,
4663         SDDL_LIST_CHILDREN,
4664         SDDL_SELF_WRITE,
4665         SDDL_READ_PROPERTY,       /*  4 */
4666         SDDL_WRITE_PROPERTY,
4667         SDDL_DELETE_TREE,
4668         SDDL_LIST_OBJECT,
4669         SDDL_CONTROL_ACCESS,      /*  8 */
4670         NULL,
4671         NULL,
4672         NULL,
4673         NULL,                     /* 12 */
4674         NULL,
4675         NULL,
4676         NULL,
4677         SDDL_STANDARD_DELETE,     /* 16 */
4678         SDDL_READ_CONTROL,
4679         SDDL_WRITE_DAC,
4680         SDDL_WRITE_OWNER,
4681         NULL,                     /* 20 */
4682         NULL,
4683         NULL,
4684         NULL,
4685         NULL,                     /* 24 */
4686         NULL,
4687         NULL,
4688         NULL,
4689         SDDL_GENERIC_ALL,         /* 28 */
4690         SDDL_GENERIC_EXECUTE,
4691         SDDL_GENERIC_WRITE,
4692         SDDL_GENERIC_READ
4693 };
4694 
4695 static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
4696 {
4697     static const WCHAR fmtW[] = {'','x','%','x',0};
4698     WCHAR buf[15];
4699     size_t i;
4700 
4701     if (mask == 0)
4702         return;
4703 
4704     /* first check if the right have name */
4705     for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
4706     {
4707         if (AceRights[i].wstr == NULL)
4708             break;
4709         if (mask == AceRights[i].value)
4710         {
4711             DumpString(AceRights[i].wstr, -1, pwptr, plen);
4712             return;
4713         }
4714     }
4715 
4716     /* then check if it can be built from bit names */
4717     for (i = 0; i < 32; i++)
4718     {
4719         if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
4720         {
4721             /* can't be built from bit names */
4722             sprintfW(buf, fmtW, mask);
4723             DumpString(buf, -1, pwptr, plen);
4724             return;
4725         }
4726     }
4727 
4728     /* build from bit names */
4729     for (i = 0; i < 32; i++)
4730         if (mask & (1 << i))
4731             DumpString(AceRightBitNames[i], -1, pwptr, plen);
4732 }
4733 
4734 static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
4735 {
4736     ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
4737     static const WCHAR openbr = '(';
4738     static const WCHAR closebr = ')';
4739     static const WCHAR semicolon = ';';
4740 
4741     if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
4742     {
4743         SetLastError(ERROR_INVALID_ACL);
4744         return FALSE;
4745     }
4746 
4747     piace = pace;
4748     DumpString(&openbr, 1, pwptr, plen);
4749     switch (piace->Header.AceType)
4750     {
4751         case ACCESS_ALLOWED_ACE_TYPE:
4752             DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
4753             break;
4754         case ACCESS_DENIED_ACE_TYPE:
4755             DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
4756             break;
4757         case SYSTEM_AUDIT_ACE_TYPE:
4758             DumpString(SDDL_AUDIT, -1, pwptr, plen);
4759             break;
4760         case SYSTEM_ALARM_ACE_TYPE:
4761             DumpString(SDDL_ALARM, -1, pwptr, plen);
4762             break;
4763     }
4764     DumpString(&semicolon, 1, pwptr, plen);
4765 
4766     if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
4767         DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
4768     if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
4769         DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
4770     if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
4771         DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
4772     if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
4773         DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
4774     if (piace->Header.AceFlags & INHERITED_ACE)
4775         DumpString(SDDL_INHERITED, -1, pwptr, plen);
4776     if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
4777         DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
4778     if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
4779         DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
4780     DumpString(&semicolon, 1, pwptr, plen);
4781     DumpRights(piace->Mask, pwptr, plen);
4782     DumpString(&semicolon, 1, pwptr, plen);
4783     /* objects not supported */
4784     DumpString(&semicolon, 1, pwptr, plen);
4785     /* objects not supported */
4786     DumpString(&semicolon, 1, pwptr, plen);
4787     if (!DumpSid(&piace->SidStart, pwptr, plen))
4788         return FALSE;
4789     DumpString(&closebr, 1, pwptr, plen);
4790     return TRUE;
4791 }
4792 
4793 static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
4794 {
4795     WORD count;
4796     int i;
4797 
4798     if (protected)
4799         DumpString(SDDL_PROTECTED, -1, pwptr, plen);
4800     if (autoInheritReq)
4801         DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
4802     if (autoInherited)
4803         DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
4804 
4805     if (pacl == NULL)
4806         return TRUE;
4807 
4808     if (!IsValidAcl(pacl))
4809         return FALSE;
4810 
4811     count = pacl->AceCount;
4812     for (i = 0; i < count; i++)
4813     {
4814         LPVOID ace;
4815         if (!GetAce(pacl, i, &ace))
4816             return FALSE;
4817         if (!DumpAce(ace, pwptr, plen))
4818             return FALSE;
4819     }
4820 
4821     return TRUE;
4822 }
4823 
4824 static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4825 {
4826     static const WCHAR prefix[] = {'O',':',0};
4827     BOOL bDefaulted;
4828     PSID psid;
4829 
4830     if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
4831         return FALSE;
4832 
4833     if (psid == NULL)
4834         return TRUE;
4835 
4836     DumpString(prefix, -1, pwptr, plen);
4837     if (!DumpSid(psid, pwptr, plen))
4838         return FALSE;
4839     return TRUE;
4840 }
4841 
4842 static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4843 {
4844     static const WCHAR prefix[] = {'G',':',0};
4845     BOOL bDefaulted;
4846     PSID psid;
4847 
4848     if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
4849         return FALSE;
4850 
4851     if (psid == NULL)
4852         return TRUE;
4853 
4854     DumpString(prefix, -1, pwptr, plen);
4855     if (!DumpSid(psid, pwptr, plen))
4856         return FALSE;
4857     return TRUE;
4858 }
4859 
4860 static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4861 {
4862     static const WCHAR dacl[] = {'D',':',0};
4863     SECURITY_DESCRIPTOR_CONTROL control;
4864     BOOL present, defaulted;
4865     DWORD revision;
4866     PACL pacl;
4867 
4868     if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
4869         return FALSE;
4870 
4871     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4872         return FALSE;
4873 
4874     if (!present)
4875         return TRUE;
4876 
4877     DumpString(dacl, 2, pwptr, plen);
4878     if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
4879         return FALSE;
4880     return TRUE;
4881 }
4882 
4883 static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
4884 {
4885     static const WCHAR sacl[] = {'S',':',0};
4886     SECURITY_DESCRIPTOR_CONTROL control;
4887     BOOL present, defaulted;
4888     DWORD revision;
4889     PACL pacl;
4890 
4891     if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
4892         return FALSE;
4893 
4894     if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
4895         return FALSE;
4896 
4897     if (!present)
4898         return TRUE;
4899 
4900     DumpString(sacl, 2, pwptr, plen);
4901     if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
4902         return FALSE;
4903     return TRUE;
4904 }
4905 
4906 /******************************************************************************
4907  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4908  */
4909 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen)
4910 {
4911     ULONG len;
4912     WCHAR *wptr, *wstr;
4913 
4914     if (SDRevision != SDDL_REVISION_1)
4915     {
4916         ERR("Pogram requested unknown SDDL revision %d\n", SDRevision);
4917         SetLastError(ERROR_UNKNOWN_REVISION);
4918         return FALSE;
4919     }
4920 
4921     len = 0;
4922     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4923         if (!DumpOwner(SecurityDescriptor, NULL, &len))
4924             return FALSE;
4925     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4926         if (!DumpGroup(SecurityDescriptor, NULL, &len))
4927             return FALSE;
4928     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4929         if (!DumpDacl(SecurityDescriptor, NULL, &len))
4930             return FALSE;
4931     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4932         if (!DumpSacl(SecurityDescriptor, NULL, &len))
4933             return FALSE;
4934 
4935     wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
4936     if (RequestedInformation & OWNER_SECURITY_INFORMATION)
4937         if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
4938             return FALSE;
4939     if (RequestedInformation & GROUP_SECURITY_INFORMATION)
4940         if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
4941             return FALSE;
4942     if (RequestedInformation & DACL_SECURITY_INFORMATION)
4943         if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
4944             return FALSE;
4945     if (RequestedInformation & SACL_SECURITY_INFORMATION)
4946         if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
4947             return FALSE;
4948     *wptr = 0;
4949 
4950     TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
4951     *OutputString = wstr;
4952     if (OutputLen)
4953         *OutputLen = strlenW(*OutputString)+1;
4954     return TRUE;
4955 }
4956 
4957 /******************************************************************************
4958  * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
4959  */
4960 BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen)
4961 {
4962     LPWSTR wstr;
4963     ULONG len;
4964     if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
4965     {
4966         int lenA;
4967 
4968         lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
4969         *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
4970         WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
4971         LocalFree(wstr);
4972 
4973         if (OutputLen != NULL)
4974             *OutputLen = lenA;
4975         return TRUE;
4976     }
4977     else
4978     {
4979         *OutputString = NULL;
4980         if (OutputLen)
4981             *OutputLen = 0;
4982         return FALSE;
4983     }
4984 }
4985 
4986 /******************************************************************************
4987  * ConvertStringSidToSidW [ADVAPI32.@]
4988  */
4989 BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
4990 {
4991     BOOL bret = FALSE;
4992     DWORD cBytes;
4993 
4994     TRACE("%s, %p\n", debugstr_w(StringSid), Sid);
4995     if (GetVersion() & 0x80000000)
4996         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
4997     else if (!StringSid || !Sid)
4998         SetLastError(ERROR_INVALID_PARAMETER);
4999     else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
5000     {
5001         PSID pSid = *Sid = LocalAlloc(0, cBytes);
5002 
5003         bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
5004         if (!bret)
5005             LocalFree(*Sid); 
5006     }
5007     return bret;
5008 }
5009 
5010 /******************************************************************************
5011  * ConvertStringSidToSidA [ADVAPI32.@]
5012  */
5013 BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid)
5014 {
5015     BOOL bret = FALSE;
5016 
5017     TRACE("%s, %p\n", debugstr_a(StringSid), Sid);
5018     if (GetVersion() & 0x80000000)
5019         SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
5020     else if (!StringSid || !Sid)
5021         SetLastError(ERROR_INVALID_PARAMETER);
5022     else
5023     {
5024         UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
5025         LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0,
5026          len * sizeof(WCHAR));
5027 
5028         MultiByteToWideChar(CP_ACP, 0, StringSid, -1, wStringSid, len);
5029         bret = ConvertStringSidToSidW(wStringSid, Sid);
5030         HeapFree(GetProcessHeap(), 0, wStringSid);
5031     }
5032     return bret;
5033 }
5034 
5035 /******************************************************************************
5036  * ConvertSidToStringSidW [ADVAPI32.@]
5037  *
5038  *  format of SID string is:
5039  *    S-<count>-<auth>-<subauth1>-<subauth2>-<subauth3>...
5040  *  where
5041  *    <rev> is the revision of the SID encoded as decimal
5042  *    <auth> is the identifier authority encoded as hex
5043  *    <subauthN> is the subauthority id encoded as decimal
5044  */
5045 BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr )
5046 {
5047     DWORD len = 0;
5048     LPWSTR wstr, wptr;
5049 
5050     TRACE("%p %p\n", pSid, pstr );
5051 
5052     len = 0;
5053     if (!DumpSidNumeric(pSid, NULL, &len))
5054         return FALSE;
5055     wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR));
5056     DumpSidNumeric(pSid, &wptr, NULL);
5057     *wptr = 0;
5058 
5059     *pstr = wstr;
5060     return TRUE;
5061 }
5062 
5063 /******************************************************************************
5064  * ConvertSidToStringSidA [ADVAPI32.@]
5065  */
5066 BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr)
5067 {
5068     LPWSTR wstr = NULL;
5069     LPSTR str;
5070     UINT len;
5071 
5072     TRACE("%p %p\n", pSid, pstr );
5073 
5074     if( !ConvertSidToStringSidW( pSid, &wstr ) )
5075         return FALSE;
5076 
5077     len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL );
5078     str = LocalAlloc( 0, len );
5079     WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL );
5080     LocalFree( wstr );
5081 
5082     *pstr = str;
5083 
5084     return TRUE;
5085 }
5086 
5087 BOOL WINAPI ConvertToAutoInheritPrivateObjectSecurity(
5088         PSECURITY_DESCRIPTOR pdesc,
5089         PSECURITY_DESCRIPTOR cdesc,
5090         PSECURITY_DESCRIPTOR* ndesc,
5091         GUID* objtype,
5092         BOOL isdir,
5093         PGENERIC_MAPPING genmap )
5094 {
5095     FIXME("%p %p %p %p %d %p - stub\n", pdesc, cdesc, ndesc, objtype, isdir, genmap);
5096 
5097     return FALSE;
5098 }
5099 
5100 BOOL WINAPI CreatePrivateObjectSecurity(
5101         PSECURITY_DESCRIPTOR ParentDescriptor,
5102         PSECURITY_DESCRIPTOR CreatorDescriptor,
5103         PSECURITY_DESCRIPTOR* NewDescriptor,
5104         BOOL IsDirectoryObject,
5105         HANDLE Token,
5106         PGENERIC_MAPPING GenericMapping )
5107 {
5108     SECURITY_DESCRIPTOR_RELATIVE *relative;
5109     DWORD needed, offset;
5110     BYTE *buffer;
5111 
5112     FIXME("%p %p %p %d %p %p - returns fake SECURITY_DESCRIPTOR\n", ParentDescriptor,
5113           CreatorDescriptor, NewDescriptor, IsDirectoryObject, Token, GenericMapping);
5114 
5115     needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5116     needed += sizeof(sidWorld);
5117     needed += sizeof(sidWorld);
5118     needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5119     needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5120 
5121     if (!(buffer = HeapAlloc( GetProcessHeap(), 0, needed ))) return FALSE;
5122     relative = (SECURITY_DESCRIPTOR_RELATIVE *)buffer;
5123     if (!InitializeSecurityDescriptor( relative, SECURITY_DESCRIPTOR_REVISION ))
5124     {
5125         HeapFree( GetProcessHeap(), 0, buffer );
5126         return FALSE;
5127     }
5128     relative->Control |= SE_SELF_RELATIVE;
5129     offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5130 
5131     memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5132     relative->Owner = offset;
5133     offset += sizeof(sidWorld);
5134 
5135     memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5136     relative->Group = offset;
5137     offset += sizeof(sidWorld);
5138 
5139     GetWorldAccessACL( (ACL *)(buffer + offset) );
5140     relative->Dacl = offset;
5141     offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5142 
5143     GetWorldAccessACL( (ACL *)(buffer + offset) );
5144     relative->Sacl = offset;
5145 
5146     *NewDescriptor = relative;
5147     return TRUE;
5148 }
5149 
5150 BOOL WINAPI DestroyPrivateObjectSecurity( PSECURITY_DESCRIPTOR* ObjectDescriptor )
5151 {
5152     FIXME("%p - stub\n", ObjectDescriptor);
5153 
5154     HeapFree( GetProcessHeap(), 0, *ObjectDescriptor );
5155     return TRUE;
5156 }
5157 
5158 BOOL WINAPI CreateProcessAsUserA(
5159         HANDLE hToken,
5160         LPCSTR lpApplicationName,
5161         LPSTR lpCommandLine,
5162         LPSECURITY_ATTRIBUTES lpProcessAttributes,
5163         LPSECURITY_ATTRIBUTES lpThreadAttributes,
5164         BOOL bInheritHandles,
5165         DWORD dwCreationFlags,
5166         LPVOID lpEnvironment,
5167         LPCSTR lpCurrentDirectory,
5168         LPSTARTUPINFOA lpStartupInfo,
5169         LPPROCESS_INFORMATION lpProcessInformation )
5170 {
5171     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - stub\n", hToken, debugstr_a(lpApplicationName),
5172           debugstr_a(lpCommandLine), lpProcessAttributes, lpThreadAttributes, bInheritHandles,
5173           dwCreationFlags, lpEnvironment, debugstr_a(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5174 
5175     return FALSE;
5176 }
5177 
5178 BOOL WINAPI CreateProcessAsUserW(
5179         HANDLE hToken,
5180         LPCWSTR lpApplicationName,
5181         LPWSTR lpCommandLine,
5182         LPSECURITY_ATTRIBUTES lpProcessAttributes,
5183         LPSECURITY_ATTRIBUTES lpThreadAttributes,
5184         BOOL bInheritHandles,
5185         DWORD dwCreationFlags,
5186         LPVOID lpEnvironment,
5187         LPCWSTR lpCurrentDirectory,
5188         LPSTARTUPINFOW lpStartupInfo,
5189         LPPROCESS_INFORMATION lpProcessInformation )
5190 {
5191     FIXME("%p %s %s %p %p %d 0x%08x %p %s %p %p - semi- stub\n", hToken, 
5192           debugstr_w(lpApplicationName), debugstr_w(lpCommandLine), lpProcessAttributes,
5193           lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, 
5194           debugstr_w(lpCurrentDirectory), lpStartupInfo, lpProcessInformation);
5195 
5196     /* We should create the process with a suspended main thread */
5197     if (!CreateProcessW (lpApplicationName,
5198                          lpCommandLine,
5199                          lpProcessAttributes,
5200                          lpThreadAttributes,
5201                          bInheritHandles,
5202                          dwCreationFlags, /* CREATE_SUSPENDED */
5203                          lpEnvironment,
5204                          lpCurrentDirectory,
5205                          lpStartupInfo,
5206                          lpProcessInformation))
5207     {
5208       return FALSE;
5209     }
5210 
5211     return TRUE;
5212 }
5213 
5214 /******************************************************************************
5215  * CreateProcessWithLogonW
5216  */
5217 BOOL WINAPI CreateProcessWithLogonW( LPCWSTR lpUsername, LPCWSTR lpDomain, LPCWSTR lpPassword, DWORD dwLogonFlags,
5218     LPCWSTR lpApplicationName, LPWSTR lpCommandLine, DWORD dwCreationFlags, LPVOID lpEnvironment,
5219     LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation )
5220 {
5221     FIXME("%s %s %s 0x%08x %s %s 0x%08x %p %s %p %p stub\n", debugstr_w(lpUsername), debugstr_w(lpDomain),
5222     debugstr_w(lpPassword), dwLogonFlags, debugstr_w(lpApplicationName),
5223     debugstr_w(lpCommandLine), dwCreationFlags, lpEnvironment, debugstr_w(lpCurrentDirectory),
5224     lpStartupInfo, lpProcessInformation);
5225 
5226     return FALSE;
5227 }
5228 
5229 /******************************************************************************
5230  * DuplicateTokenEx [ADVAPI32.@]
5231  */
5232 BOOL WINAPI DuplicateTokenEx(
5233         HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
5234         LPSECURITY_ATTRIBUTES lpTokenAttributes,
5235         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5236         TOKEN_TYPE TokenType,
5237         PHANDLE DuplicateTokenHandle )
5238 {
5239     OBJECT_ATTRIBUTES ObjectAttributes;
5240 
5241     TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
5242           ImpersonationLevel, TokenType, DuplicateTokenHandle);
5243 
5244     InitializeObjectAttributes(
5245         &ObjectAttributes,
5246         NULL,
5247         (lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
5248         NULL,
5249         lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
5250 
5251     return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
5252                                            dwDesiredAccess,
5253                                            &ObjectAttributes,
5254                                            ImpersonationLevel,
5255                                            TokenType,
5256                                            DuplicateTokenHandle ) );
5257 }
5258 
5259 BOOL WINAPI DuplicateToken(
5260         HANDLE ExistingTokenHandle,
5261         SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
5262         PHANDLE DuplicateTokenHandle )
5263 {
5264     return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
5265                              NULL, ImpersonationLevel, TokenImpersonation,
5266                              DuplicateTokenHandle );
5267 }
5268 
5269 /******************************************************************************
5270  * ComputeStringSidSize
5271  */
5272 static DWORD ComputeStringSidSize(LPCWSTR StringSid)
5273 {
5274     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
5275     {
5276         int ctok = 0;
5277         while (*StringSid)
5278         {
5279             if (*StringSid == '-')
5280                 ctok++;
5281             StringSid++;
5282         }
5283 
5284         if (ctok >= 3)
5285             return GetSidLengthRequired(ctok - 2);
5286     }
5287     else /* String constant format  - Only available in winxp and above */
5288     {
5289         unsigned int i;
5290 
5291         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5292             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5293                 return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
5294     }
5295 
5296     return GetSidLengthRequired(0);
5297 }
5298 
5299 /******************************************************************************
5300  * ParseStringSidToSid
5301  */
5302 static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
5303 {
5304     BOOL bret = FALSE;
5305     SID* pisid=pSid;
5306 
5307     TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
5308     if (!StringSid)
5309     {
5310         SetLastError(ERROR_INVALID_PARAMETER);
5311         TRACE("StringSid is NULL, returning FALSE\n");
5312         return FALSE;
5313     }
5314 
5315     while (*StringSid == ' ')
5316         StringSid++;
5317 
5318     *cBytes = ComputeStringSidSize(StringSid);
5319     if (!pisid) /* Simply compute the size */
5320     {
5321         TRACE("only size requested, returning TRUE\n");
5322         return TRUE;
5323     }
5324 
5325     if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
5326     {
5327         DWORD i = 0, identAuth;
5328         DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
5329 
5330         StringSid += 2; /* Advance to Revision */
5331         pisid->Revision = atoiW(StringSid);
5332 
5333         if (pisid->Revision != SDDL_REVISION)
5334         {
5335             TRACE("Revision %d is unknown\n", pisid->Revision);
5336             goto lend; /* ERROR_INVALID_SID */
5337         }
5338         if (csubauth == 0)
5339         {
5340             TRACE("SubAuthorityCount is 0\n");
5341             goto lend; /* ERROR_INVALID_SID */
5342         }
5343 
5344         pisid->SubAuthorityCount = csubauth;
5345 
5346         /* Advance to identifier authority */
5347         while (*StringSid && *StringSid != '-')
5348             StringSid++;
5349         if (*StringSid == '-')
5350             StringSid++;
5351 
5352         /* MS' implementation can't handle values greater than 2^32 - 1, so
5353          * we don't either; assume most significant bytes are always 0
5354          */
5355         pisid->IdentifierAuthority.Value[0] = 0;
5356         pisid->IdentifierAuthority.Value[1] = 0;
5357         identAuth = atoiW(StringSid);
5358         pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
5359         pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
5360         pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
5361         pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
5362 
5363         /* Advance to first sub authority */
5364         while (*StringSid && *StringSid != '-')
5365             StringSid++;
5366         if (*StringSid == '-')
5367             StringSid++;
5368 
5369         while (*StringSid)
5370         {
5371             pisid->SubAuthority[i++] = atoiW(StringSid);
5372 
5373             while (*StringSid && *StringSid != '-')
5374                 StringSid++;
5375             if (*StringSid == '-')
5376                 StringSid++;
5377         }
5378 
5379         if (i != pisid->SubAuthorityCount)
5380             goto lend; /* ERROR_INVALID_SID */
5381 
5382         bret = TRUE;
5383     }
5384     else /* String constant format  - Only available in winxp and above */
5385     {
5386         unsigned int i;
5387         pisid->Revision = SDDL_REVISION;
5388 
5389         for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
5390             if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
5391             {
5392                 DWORD j;
5393                 pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
5394                 pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
5395                 for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
5396                     pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
5397                 bret = TRUE;
5398             }
5399 
5400         if (!bret)
5401             FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
5402     }
5403 
5404 lend:
5405     if (!bret)
5406         SetLastError(ERROR_INVALID_SID);
5407 
5408     TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
5409     return bret;
5410 }
5411 
5412 /******************************************************************************
5413  * GetNamedSecurityInfoA [ADVAPI32.@]
5414  */
5415 DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
5416         SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5417         PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
5418         PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
5419 {
5420     DWORD len;
5421     LPWSTR wstr = NULL;
5422     DWORD r;
5423 
5424     TRACE("%s %d %d %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
5425         ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
5426 
5427     if( pObjectName )
5428     {
5429         len = MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, NULL, 0 );
5430         wstr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR));
5431         MultiByteToWideChar( CP_ACP, 0, pObjectName, -1, wstr, len );
5432     }
5433 
5434     r = GetNamedSecurityInfoW( wstr, ObjectType, SecurityInfo, ppsidOwner,
5435                            ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor );
5436 
5437     HeapFree( GetProcessHeap(), 0, wstr );
5438 
5439     return r;
5440 }
5441 
5442 /******************************************************************************
5443  * GetNamedSecurityInfoW [ADVAPI32.@]
5444  */
5445 DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
5446     SECURITY_INFORMATION info, PSID* owner, PSID* group, PACL* dacl,
5447     PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
5448 {
5449     DWORD needed, offset;
5450     SECURITY_DESCRIPTOR_RELATIVE *relative = NULL;
5451     BYTE *buffer;
5452 
5453     TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
5454            group, dacl, sacl, descriptor );
5455 
5456     /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
5457     if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
5458 
5459     /* If no descriptor, we have to check that there's a pointer for the requested information */
5460     if( !descriptor && (
5461         ((info & OWNER_SECURITY_INFORMATION) && !owner)
5462     ||  ((info & GROUP_SECURITY_INFORMATION) && !group)
5463     ||  ((info & DACL_SECURITY_INFORMATION)  && !dacl)
5464     ||  ((info & SACL_SECURITY_INFORMATION)  && !sacl)  ))
5465         return ERROR_INVALID_PARAMETER;
5466 
5467     needed = !descriptor ? 0 : sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5468     if (info & OWNER_SECURITY_INFORMATION)
5469         needed += sizeof(sidWorld);
5470     if (info & GROUP_SECURITY_INFORMATION)
5471         needed += sizeof(sidWorld);
5472     if (info & DACL_SECURITY_INFORMATION)
5473         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5474     if (info & SACL_SECURITY_INFORMATION)
5475         needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5476 
5477     if(descriptor)
5478     {
5479         /* must be freed by caller */
5480         *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
5481         if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
5482 
5483         if (!InitializeSecurityDescriptor( *descriptor, SECURITY_DESCRIPTOR_REVISION ))
5484         {
5485             HeapFree( GetProcessHeap(), 0, *descriptor );
5486             return ERROR_INVALID_SECURITY_DESCR;
5487         }
5488 
5489         relative = *descriptor;
5490         relative->Control |= SE_SELF_RELATIVE;
5491 
5492         buffer = (BYTE *)relative;
5493         offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
5494     }
5495     else
5496     {
5497         buffer = HeapAlloc( GetProcessHeap(), 0, needed );
5498         if (!buffer) return ERROR_NOT_ENOUGH_MEMORY;
5499         offset = 0;
5500     }
5501 
5502     if (info & OWNER_SECURITY_INFORMATION)
5503     {
5504         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5505         if(relative)
5506             relative->Owner = offset;
5507         if (owner)
5508             *owner = buffer + offset;
5509         offset += sizeof(sidWorld);
5510     }
5511     if (info & GROUP_SECURITY_INFORMATION)
5512     {
5513         memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
5514         if(relative)
5515             relative->Group = offset;
5516         if (group)
5517             *group = buffer + offset;
5518         offset += sizeof(sidWorld);
5519     }
5520     if (info & DACL_SECURITY_INFORMATION)
5521     {
5522         GetWorldAccessACL( (PACL)(buffer + offset) );
5523         if(relative)
5524         {
5525             relative->Control |= SE_DACL_PRESENT;
5526             relative->Dacl = offset;
5527         }
5528         if (dacl)
5529             *dacl = (PACL)(buffer + offset);
5530         offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
5531     }
5532     if (info & SACL_SECURITY_INFORMATION)
5533     {
5534         GetWorldAccessACL( (PACL)(buffer + offset) );
5535         if(relative)
5536         {
5537             relative->Control |= SE_SACL_PRESENT;
5538             relative->Sacl = offset;
5539         }
5540         if (sacl)
5541             *sacl = (PACL)(buffer + offset);
5542     }
5543 
5544     return ERROR_SUCCESS;
5545 }
5546 
5547 /******************************************************************************
5548  * GetNamedSecurityInfoExW [ADVAPI32.@]
5549  */
5550 DWORD WINAPI GetNamedSecurityInfoExW( LPCWSTR object, SE_OBJECT_TYPE type,
5551     SECURITY_INFORMATION info, LPCWSTR provider, LPCWSTR property,
5552     PACTRL_ACCESSW* access_list, PACTRL_AUDITW* audit_list, LPWSTR* owner, LPWSTR* group )
5553 {
5554     FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_w(object), type, info,
5555         debugstr_w(provider), debugstr_w(property), access_list, audit_list, owner, group);
5556     return ERROR_CALL_NOT_IMPLEMENTED;
5557 }
5558 
5559 /******************************************************************************
5560  * GetNamedSecurityInfoExA [ADVAPI32.@]
5561  */
5562 DWORD WINAPI GetNamedSecurityInfoExA( LPCSTR object, SE_OBJECT_TYPE type,
5563     SECURITY_INFORMATION info, LPCSTR provider, LPCSTR property,
5564     PACTRL_ACCESSA* access_list, PACTRL_AUDITA* audit_list, LPSTR* owner, LPSTR* group )
5565 {
5566     FIXME("(%s, %d, %d, %s, %s, %p, %p, %p, %p) stub\n", debugstr_a(object), type, info,
5567         debugstr_a(provider), debugstr_a(property), access_list, audit_list, owner, group);
5568     return ERROR_CALL_NOT_IMPLEMENTED;
5569 }
5570 
5571 /******************************************************************************
5572  * DecryptFileW [ADVAPI32.@]
5573  */
5574 BOOL WINAPI DecryptFileW(LPCWSTR lpFileName, DWORD dwReserved)
5575 {
5576     FIXME("%s %08x\n", debugstr_w(lpFileName), dwReserved);
5577     return TRUE;
5578 }
5579 
5580 /******************************************************************************
5581  * DecryptFileA [ADVAPI32.@]
5582  */
5583 BOOL WINAPI DecryptFileA(LPCSTR lpFileName, DWORD dwReserved)
5584 {
5585     FIXME("%s %08x\n", debugstr_a(lpFileName), dwReserved);
5586     return TRUE;
5587 }
5588 
5589 /******************************************************************************
5590  * EncryptFileW [ADVAPI32.@]
5591  */
5592 BOOL WINAPI EncryptFileW(LPCWSTR lpFileName)
5593 {
5594     FIXME("%s\n", debugstr_w(lpFileName));
5595     return TRUE;
5596 }
5597 
5598 /******************************************************************************
5599  * EncryptFileA [ADVAPI32.@]
5600  */
5601 BOOL WINAPI EncryptFileA(LPCSTR lpFileName)
5602 {
5603     FIXME("%s\n", debugstr_a(lpFileName));
5604     return TRUE;
5605 }
5606 
5607 /******************************************************************************
5608  * FileEncryptionStatusW [ADVAPI32.@]
5609  */
5610 BOOL WINAPI FileEncryptionStatusW(LPCWSTR lpFileName, LPDWORD lpStatus)
5611 {
5612     FIXME("(%s %p): stub\n", debugstr_w(lpFileName), lpStatus);
5613     if (!lpStatus)
5614         return FALSE;
5615     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5616     return TRUE;
5617 }
5618 
5619 /******************************************************************************
5620  * FileEncryptionStatusA [ADVAPI32.@]
5621  */
5622 BOOL WINAPI FileEncryptionStatusA(LPCSTR lpFileName, LPDWORD lpStatus)
5623 {
5624     FIXME("(%s %p): stub\n", debugstr_a(lpFileName), lpStatus);
5625     if (!lpStatus)
5626         return FALSE;
5627     *lpStatus = FILE_SYSTEM_NOT_SUPPORT;
5628     return TRUE;
5629 }
5630 
5631 /******************************************************************************
5632  * SetSecurityInfo [ADVAPI32.@]
5633  */
5634 DWORD WINAPI SetSecurityInfo(HANDLE handle, SE_OBJECT_TYPE ObjectType, 
5635                       SECURITY_INFORMATION SecurityInfo, PSID psidOwner,
5636                       PSID psidGroup, PACL pDacl, PACL pSacl) {
5637     FIXME("stub\n");
5638     return ERROR_SUCCESS;
5639 }
5640 
5641 /******************************************************************************
5642  * SaferCreateLevel   [ADVAPI32.@]
5643  */
5644 BOOL WINAPI SaferCreateLevel(DWORD ScopeId, DWORD LevelId, DWORD OpenFlags,
5645                              SAFER_LEVEL_HANDLE* LevelHandle, LPVOID lpReserved)
5646 {
5647     FIXME("(%u, %x, %u, %p, %p) stub\n", ScopeId, LevelId, OpenFlags, LevelHandle, lpReserved);
5648 
5649     *LevelHandle = (SAFER_LEVEL_HANDLE)0xdeadbeef;
5650     return TRUE;
5651 }
5652 
5653 /******************************************************************************
5654  * SaferComputeTokenFromLevel   [ADVAPI32.@]
5655  */
5656 BOOL WINAPI SaferComputeTokenFromLevel(SAFER_LEVEL_HANDLE handle, HANDLE token, PHANDLE access_token,
5657                                        DWORD flags, LPVOID reserved)
5658 {
5659     FIXME("(%p, %p, %p, %x, %p) stub\n", handle, token, access_token, flags, reserved);
5660 
5661     *access_token = (HANDLE)0xdeadbeef;
5662     return TRUE;
5663 }
5664 
5665 /******************************************************************************
5666  * SaferCloseLevel   [ADVAPI32.@]
5667  */
5668 BOOL WINAPI SaferCloseLevel(SAFER_LEVEL_HANDLE handle)
5669 {
5670     FIXME("(%p) stub\n", handle);
5671     return TRUE;
5672 }
5673 
5674 DWORD WINAPI TreeResetNamedSecurityInfoW( LPWSTR pObjectName,
5675                 SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
5676                 PSID pOwner, PSID pGroup, PACL pDacl, PACL pSacl,
5677                 BOOL KeepExplicit, FN_PROGRESS fnProgress,
5678                 PROG_INVOKE_SETTING ProgressInvokeSetting, PVOID Args)
5679 {
5680     FIXME("(%s, %i, %i, %p, %p, %p, %p, %i, %p, %i, %p  Stub\n",
5681         debugstr_w(pObjectName), ObjectType, SecurityInfo, pOwner, pGroup,
5682         pDacl, pSacl, KeepExplicit, fnProgress, ProgressInvokeSetting, Args);
5683 
5684     return ERROR_SUCCESS;
5685 }
5686 
5687 /******************************************************************************
5688  * SaferGetPolicyInformation   [ADVAPI32.@]
5689  */
5690 BOOL WINAPI SaferGetPolicyInformation(DWORD scope, SAFER_POLICY_INFO_CLASS class, DWORD size,
5691                                       PVOID buffer, PDWORD required, LPVOID lpReserved)
5692 {
5693     FIXME("(%u %u %u %p %p %p) stub\n", scope, class, size, buffer, required, lpReserved);
5694     return FALSE;
5695 }
5696 
5697 /******************************************************************************
5698  * SaferSetLevelInformation   [ADVAPI32.@]
5699  */
5700 BOOL WINAPI SaferSetLevelInformation(SAFER_LEVEL_HANDLE handle, SAFER_OBJECT_INFO_CLASS infotype,
5701                                      LPVOID buffer, DWORD size)
5702 {
5703     FIXME("(%p %u %p %u) stub\n", handle, infotype, buffer, size);
5704     return FALSE;
5705 }
5706 

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

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.