You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
596 lines
24 KiB
596 lines
24 KiB
#include <fusenetincludes.h>
|
|
#include <assemblycache.h>
|
|
#include <msxml2.h>
|
|
#include <manifestimport.h>
|
|
#include <manifestdata.h>
|
|
#include <dbglog.h>
|
|
|
|
|
|
// fwd declaration
|
|
HRESULT CheckPlatform(LPMANIFEST_DATA pPlatformData);
|
|
|
|
|
|
// return: 0 for all satisfied
|
|
HRESULT CheckPlatformRequirementsEx(LPASSEMBLY_MANIFEST_IMPORT pManifestImport,
|
|
CDebugLog* pDbgLog, LPDWORD pdwNumMissingPlatforms, LPTPLATFORM_INFO* pptPlatform)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
MAKE_ERROR_MACROS_STATIC(hr);
|
|
DWORD dwCount = 0;
|
|
DWORD dwMissingCount = 0;
|
|
LPMANIFEST_DATA pPlatformList = NULL;
|
|
LPMANIFEST_DATA pPlatformData = NULL;
|
|
DWORD cbProperty = 0, dwType = 0;
|
|
LPASSEMBLY_IDENTITY pAsmId = NULL;
|
|
LPTPLATFORM_INFO ptPlatform = NULL;
|
|
LPWSTR pwzId = NULL;
|
|
DWORD dwCC = 0;
|
|
|
|
IF_NULL_EXIT(pManifestImport, E_INVALIDARG);
|
|
IF_NULL_EXIT(pdwNumMissingPlatforms, E_INVALIDARG);
|
|
IF_NULL_EXIT(pptPlatform, E_INVALIDARG);
|
|
|
|
*pdwNumMissingPlatforms = 0;
|
|
*pptPlatform = NULL;
|
|
|
|
IF_FAILED_EXIT(CreateManifestData(L"platform list", &pPlatformList));
|
|
|
|
IF_FAILED_EXIT(pManifestImport->GetNextPlatform(dwCount, &pPlatformData));
|
|
while (hr == S_OK)
|
|
{
|
|
if (pDbgLog)
|
|
{
|
|
SAFEDELETEARRAY(pwzId);
|
|
IF_FAILED_EXIT(pPlatformData->GetType(&pwzId));
|
|
IF_NULL_EXIT(pwzId, E_FAIL);
|
|
|
|
IF_FAILED_EXIT(FusionCompareString(pwzId, WZ_DATA_PLATFORM_MANAGED, 0));
|
|
if (hr == S_OK)
|
|
{
|
|
SAFEDELETEARRAY(pwzId);
|
|
IF_FAILED_EXIT(pPlatformData->Get(CAssemblyManifestImport::g_StringTable[CAssemblyManifestImport::AssemblyIdTag].pwz,
|
|
(LPVOID*) &pAsmId, &cbProperty, &dwType));
|
|
IF_NULL_EXIT(pAsmId, E_FAIL);
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_IUNKNOWN_PTR, E_FAIL);
|
|
|
|
IF_FAILED_EXIT(pAsmId->GetDisplayName(0, &pwzId, &dwCC));
|
|
SAFERELEASE(pAsmId);
|
|
}
|
|
}
|
|
|
|
IF_FAILED_EXIT(CheckPlatform(pPlatformData));
|
|
if (hr == S_FALSE)
|
|
{
|
|
IF_FALSE_EXIT(dwMissingCount < dwMissingCount+1, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
|
|
dwMissingCount++;
|
|
|
|
// ISSUE-06/07/02-felixybc use linked-list instead?
|
|
IF_FAILED_EXIT((static_cast<CManifestData*>(pPlatformList))->Set(dwMissingCount, (LPVOID) pPlatformData, sizeof(LPVOID), MAN_DATA_TYPE_IUNKNOWN_PTR));
|
|
|
|
if (pDbgLog)
|
|
{
|
|
DEBUGOUT1(pDbgLog, 1, L" LOG: Missing dependent platform, id: %s", pwzId);
|
|
}
|
|
}
|
|
else if (pDbgLog)
|
|
{
|
|
DEBUGOUT1(pDbgLog, 1, L" LOG: Found dependent platform, id: %s", pwzId);
|
|
}
|
|
|
|
SAFERELEASE(pPlatformData);
|
|
|
|
IF_FALSE_EXIT(dwCount < dwCount+1, HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW));
|
|
dwCount++;
|
|
// platform data is returned in order
|
|
IF_FAILED_EXIT(pManifestImport->GetNextPlatform(dwCount, &pPlatformData));
|
|
}
|
|
|
|
// assemble platform struct
|
|
if (dwMissingCount > 0)
|
|
{
|
|
IF_ALLOC_FAILED_EXIT(ptPlatform = new TPLATFORM_INFO[dwMissingCount]);
|
|
// ISSUE - zero out memory pointed by ptPlatform
|
|
for (DWORD dw = 0; dw < dwMissingCount; dw++)
|
|
{
|
|
IF_FAILED_EXIT((static_cast<CManifestData*>(pPlatformList))->Get(dw+1, (LPVOID *)&pPlatformData, &cbProperty, &dwType));
|
|
IF_NULL_EXIT(pPlatformData, E_FAIL);
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_IUNKNOWN_PTR, E_FAIL);
|
|
|
|
// allow missing friendly name??
|
|
IF_FAILED_EXIT(pPlatformData->Get(CAssemblyManifestImport::g_StringTable[CAssemblyManifestImport::FriendlyName].pwz,
|
|
(LPVOID *)&((ptPlatform[dw]).pwzName), &cbProperty, &dwType));
|
|
IF_NULL_EXIT(((ptPlatform[dw]).pwzName), E_FAIL);
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_LPWSTR, E_FAIL);
|
|
|
|
IF_FAILED_EXIT(pPlatformData->Get(CAssemblyManifestImport::g_StringTable[CAssemblyManifestImport::Href].pwz,
|
|
(LPVOID *)&((ptPlatform[dw]).pwzURL), &cbProperty, &dwType));
|
|
// allow missing URL
|
|
if ((ptPlatform[dw]).pwzURL != NULL)
|
|
{
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_LPWSTR, E_FAIL);
|
|
}
|
|
|
|
// ISSUE-06/07/02-felixybc for internal use, need a different way to return Codebase
|
|
|
|
SAFERELEASE(pPlatformData);
|
|
|
|
if (pDbgLog)
|
|
{
|
|
DEBUGOUT2(pDbgLog, 1, L" LOG: Missing dependent platform data, friendlyName: %s; codebase/URL: %s",
|
|
(ptPlatform[dw]).pwzName, (ptPlatform[dw]).pwzURL);
|
|
}
|
|
}
|
|
}
|
|
|
|
*pdwNumMissingPlatforms = dwMissingCount;
|
|
*pptPlatform = ptPlatform;
|
|
ptPlatform = NULL;
|
|
|
|
exit:
|
|
if (FAILED(hr) && ptPlatform)
|
|
{
|
|
for (DWORD dw = 0; dw < dwMissingCount; dw++)
|
|
{
|
|
SAFEDELETEARRAY((ptPlatform[dw]).pwzName);
|
|
SAFEDELETEARRAY((ptPlatform[dw]).pwzURL);
|
|
}
|
|
SAFEDELETEARRAY(ptPlatform);
|
|
}
|
|
|
|
SAFEDELETEARRAY(pwzId);
|
|
|
|
SAFERELEASE(pAsmId);
|
|
SAFERELEASE(pPlatformData);
|
|
SAFERELEASE(pPlatformList);
|
|
return hr;
|
|
}
|
|
|
|
|
|
// return: 0 for all satisfied
|
|
HRESULT CheckPlatformRequirements(LPASSEMBLY_MANIFEST_IMPORT pManifestImport,
|
|
LPDWORD pdwNumMissingPlatforms, LPTPLATFORM_INFO* pptPlatform)
|
|
{
|
|
return CheckPlatformRequirementsEx(pManifestImport, NULL, pdwNumMissingPlatforms, pptPlatform);
|
|
}
|
|
|
|
|
|
#define WZ_PLATFORM_OS_TYPE_WORKSTATION L"workstation"
|
|
#define WZ_PLATFORM_OS_TYPE_DOMAIN_CONTROLLER L"domainController"
|
|
#define WZ_PLATFORM_OS_TYPE_SERVER L"server"
|
|
#define WZ_PLATFORM_OS_SUITE_BACKOFFICE L"backoffice"
|
|
#define WZ_PLATFORM_OS_SUITE_BLADE L"blade"
|
|
#define WZ_PLATFORM_OS_SUITE_DATACENTER L"datacenter"
|
|
#define WZ_PLATFORM_OS_SUITE_ENTERPRISE L"enterprise"
|
|
#define WZ_PLATFORM_OS_SUITE_PERSONAL L"home" // note: different text
|
|
#define WZ_PLATFORM_OS_SUITE_SMALLBUSINESS L"smallbusiness"
|
|
#define WZ_PLATFORM_OS_SUITE_SMALLBUSINESS_RESTRICTED L"smallbusinessRestricted"
|
|
#define WZ_PLATFORM_OS_SUITE_TERMINAL L"terminal"
|
|
// our addition/definition:
|
|
#define WZ_PLATFORM_OS_SUITE_PROFESSIONAL L"professional"
|
|
// return: S_OK
|
|
// S_FALSE
|
|
// E_*
|
|
HRESULT CheckOSHelper(LPMANIFEST_DATA pOSData)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
MAKE_ERROR_MACROS_STATIC(hr);
|
|
LPWSTR pwzBuf = NULL;
|
|
LPDWORD pdwVal = NULL;
|
|
DWORD cbProperty = 0;
|
|
DWORD dwType = 0;
|
|
OSVERSIONINFOEX osvi;
|
|
DWORDLONG dwlConditionMask = 0;
|
|
DWORD dwTypeMask = 0;
|
|
BOOL bCheckProfessionalSuite = FALSE;
|
|
#define WORD_MAX 0xffff
|
|
|
|
// verify type
|
|
IF_FAILED_EXIT(pOSData->GetType(&pwzBuf));
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_DATA_OSVERSIONINFO, pwzBuf, 0));
|
|
IF_FALSE_EXIT(hr == S_OK, E_INVALIDARG);
|
|
SAFEDELETEARRAY(pwzBuf);
|
|
|
|
// Initialize the OSVERSIONINFOEX structure.
|
|
|
|
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
|
|
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
|
|
for (CAssemblyManifestImport::eStringTableId i = CAssemblyManifestImport::MajorVersion; i <= CAssemblyManifestImport::ProductType; i++)
|
|
{
|
|
if (i >= CAssemblyManifestImport::MajorVersion && i <= CAssemblyManifestImport::ServicePackMinor)
|
|
{
|
|
IF_FAILED_EXIT(pOSData->Get(CAssemblyManifestImport::g_StringTable[i].pwz,
|
|
(LPVOID*) &pdwVal, &cbProperty, &dwType));
|
|
if (pdwVal != NULL)
|
|
{
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_DWORD, E_FAIL);
|
|
|
|
switch (i)
|
|
{
|
|
case CAssemblyManifestImport::MajorVersion:
|
|
osvi.dwMajorVersion = *pdwVal;
|
|
|
|
// Initialize the condition mask.
|
|
VER_SET_CONDITION( dwlConditionMask, VER_MAJORVERSION,
|
|
VER_GREATER_EQUAL );
|
|
|
|
dwTypeMask |= VER_MAJORVERSION;
|
|
break;
|
|
case CAssemblyManifestImport::MinorVersion:
|
|
osvi.dwMinorVersion = *pdwVal;
|
|
VER_SET_CONDITION( dwlConditionMask, VER_MINORVERSION,
|
|
VER_GREATER_EQUAL );
|
|
dwTypeMask |= VER_MINORVERSION;
|
|
break;
|
|
case CAssemblyManifestImport::BuildNumber:
|
|
osvi.dwBuildNumber = *pdwVal;
|
|
VER_SET_CONDITION( dwlConditionMask, VER_BUILDNUMBER,
|
|
VER_GREATER_EQUAL );
|
|
dwTypeMask |= VER_BUILDNUMBER;
|
|
break;
|
|
case CAssemblyManifestImport::ServicePackMajor:
|
|
// WORD
|
|
osvi.wServicePackMajor = (WORD) ((*pdwVal) & WORD_MAX);
|
|
VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMAJOR,
|
|
VER_GREATER_EQUAL );
|
|
dwTypeMask |= VER_SERVICEPACKMAJOR;
|
|
break;
|
|
case CAssemblyManifestImport::ServicePackMinor:
|
|
// WORD
|
|
osvi.wServicePackMinor = (WORD) ((*pdwVal) & WORD_MAX);
|
|
VER_SET_CONDITION( dwlConditionMask, VER_SERVICEPACKMINOR,
|
|
VER_GREATER_EQUAL );
|
|
dwTypeMask |= VER_SERVICEPACKMINOR;
|
|
break;
|
|
//default: should not happen
|
|
}
|
|
SAFEDELETEARRAY(pdwVal);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(pOSData->Get(CAssemblyManifestImport::g_StringTable[i].pwz,
|
|
(LPVOID*) &pwzBuf, &cbProperty, &dwType));
|
|
if (pwzBuf != NULL)
|
|
{
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_LPWSTR, E_FAIL);
|
|
if (i == CAssemblyManifestImport::ProductType)
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_TYPE_WORKSTATION, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_NT_WORKSTATION The system is running Windows NT 4.0 Workstation,
|
|
// Windows 2000 Professional, Windows XP Home Edition, or Windows XP Professional.
|
|
osvi.wProductType = VER_NT_WORKSTATION;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_TYPE_DOMAIN_CONTROLLER, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_NT_DOMAIN_CONTROLLER The system is a domain controller.
|
|
osvi.wProductType = VER_NT_DOMAIN_CONTROLLER;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_TYPE_SERVER, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_NT_SERVER The system is a server.
|
|
osvi.wProductType = VER_NT_SERVER;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(E_FAIL);
|
|
}
|
|
}
|
|
}
|
|
|
|
VER_SET_CONDITION( dwlConditionMask, VER_PRODUCT_TYPE,
|
|
VER_EQUAL );
|
|
dwTypeMask |= VER_PRODUCT_TYPE;
|
|
}
|
|
else if (i == CAssemblyManifestImport::Suite)
|
|
{
|
|
// ISSUE-06/07/02-felixybc suite mask should allow specifying multiple with AND OR conditions
|
|
// use goto done to avoid indenting.
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_BACKOFFICE, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_BACKOFFICE Microsoft BackOffice components are installed.
|
|
osvi.wSuiteMask |= VER_SUITE_BACKOFFICE;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_BLADE, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_BLADE Windows Web Server is installed.
|
|
osvi.wSuiteMask |= VER_SUITE_BLADE;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_DATACENTER, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_DATACENTER Windows 2000 or Windows Datacenter Server is installed.
|
|
osvi.wSuiteMask |= VER_SUITE_DATACENTER;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_ENTERPRISE, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_ENTERPRISE Windows 2000 Advanced Server or Windows Enterprise Server is installed.
|
|
osvi.wSuiteMask |= VER_SUITE_ENTERPRISE;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_PERSONAL, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_PERSONAL Windows XP Home Edition is installed.
|
|
osvi.wSuiteMask |= VER_SUITE_PERSONAL;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_SMALLBUSINESS, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_SMALLBUSINESS Microsoft Small Business Server is installed.
|
|
osvi.wSuiteMask |= VER_SUITE_SMALLBUSINESS;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_SMALLBUSINESS_RESTRICTED, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_SMALLBUSINESS_RESTRICTED Microsoft Small Business Server is installed with the restrictive client license in force.
|
|
osvi.wSuiteMask |= VER_SUITE_SMALLBUSINESS_RESTRICTED;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_TERMINAL, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
//VER_SUITE_TERMINAL Terminal Services is installed.
|
|
osvi.wSuiteMask |= VER_SUITE_TERMINAL;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(FusionCompareString(WZ_PLATFORM_OS_SUITE_PROFESSIONAL, pwzBuf, 0));
|
|
if (hr == S_OK)
|
|
bCheckProfessionalSuite = TRUE;
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(E_FAIL);
|
|
}
|
|
}
|
|
// more from winnt.h..
|
|
//#define VER_SUITE_COMMUNICATIONS
|
|
//#define VER_SUITE_EMBEDDEDNT
|
|
//#define VER_SUITE_SINGLEUSERTS
|
|
//#define VER_SUITE_EMBEDDED_RESTRICTED
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// ISSUE-06/07/02-felixybc assume AND condition
|
|
VER_SET_CONDITION( dwlConditionMask, VER_SUITENAME,
|
|
VER_AND );
|
|
dwTypeMask |= VER_SUITENAME;
|
|
}
|
|
//else should not happen
|
|
//hr = E_FAIL;
|
|
|
|
SAFEDELETEARRAY(pwzBuf);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ISSUE-06/07/02-felixybc assume nt only
|
|
osvi.dwPlatformId = VER_PLATFORM_WIN32_NT;
|
|
VER_SET_CONDITION( dwlConditionMask, VER_PLATFORMID,
|
|
VER_EQUAL );
|
|
dwTypeMask |= VER_PLATFORMID;
|
|
|
|
// Perform the test
|
|
|
|
BOOL bResult = VerifyVersionInfo(
|
|
&osvi,
|
|
dwTypeMask,
|
|
dwlConditionMask);
|
|
|
|
if (!bResult)
|
|
{
|
|
DWORD dw = GetLastError();
|
|
if (dw != ERROR_OLD_WIN_VERSION)
|
|
hr = HRESULT_FROM_WIN32(dw);
|
|
else
|
|
hr = S_FALSE;
|
|
}
|
|
else
|
|
{
|
|
hr = S_OK;
|
|
if (bCheckProfessionalSuite)
|
|
{
|
|
// do "professional" - do a GetVersionEx after to check suite
|
|
|
|
// ISSUE-06/14/02-felixybc check 'professional'. API has no notion of professional
|
|
// assume "not home" == "professional"
|
|
// note: type==workstation for Home/Pro but suite==Home for Home
|
|
|
|
OSVERSIONINFOEX osvx;
|
|
ZeroMemory(&osvx, sizeof(OSVERSIONINFOEX));
|
|
osvx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
|
IF_WIN32_FALSE_EXIT(GetVersionEx((OSVERSIONINFO*) &osvx));
|
|
if ((osvx.wSuiteMask & VER_SUITE_PERSONAL) || (osvx.wProductType != VER_NT_WORKSTATION))
|
|
{
|
|
hr = S_FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
SAFEDELETEARRAY(pwzBuf);
|
|
SAFEDELETEARRAY(pdwVal);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CheckOS(LPMANIFEST_DATA pPlatformData)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
MAKE_ERROR_MACROS_STATIC(hr);
|
|
DWORD dwCount = 0;
|
|
LPMANIFEST_DATA pOSData = NULL;
|
|
DWORD cbProperty = 0;
|
|
DWORD dwType = 0;
|
|
BOOL bFound = FALSE;
|
|
|
|
while (TRUE)
|
|
{
|
|
// test a list of versions - as soon as 1 is satisfied, this check succeeds
|
|
|
|
IF_FAILED_EXIT((static_cast<CManifestData*>(pPlatformData))->Get(dwCount,
|
|
(LPVOID*) &pOSData, &cbProperty, &dwType));
|
|
if (pOSData == NULL)
|
|
break;
|
|
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_IUNKNOWN_PTR, HRESULT_FROM_WIN32(ERROR_BAD_FORMAT));
|
|
IF_FAILED_EXIT(CheckOSHelper(pOSData));
|
|
if (hr == S_OK)
|
|
{
|
|
bFound = TRUE;
|
|
break;
|
|
}
|
|
SAFERELEASE(pOSData);
|
|
dwCount++;
|
|
}
|
|
|
|
if (bFound)
|
|
hr = S_OK;
|
|
else
|
|
hr = S_FALSE;
|
|
|
|
exit:
|
|
SAFERELEASE(pOSData);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CheckDotNet(LPMANIFEST_DATA pPlatformData)
|
|
{
|
|
#define WZ_DOTNETREGPATH L"Software\\Microsoft\\.NetFramework\\Policy\\"
|
|
HRESULT hr = S_OK;
|
|
MAKE_ERROR_MACROS_STATIC(hr);
|
|
DWORD dwCount = 0;
|
|
LPWSTR pwzVersion = NULL;
|
|
DWORD cbProperty = 0;
|
|
DWORD dwType = 0;
|
|
CString sRegPath;
|
|
CString sVersion;
|
|
CString sBuildNum;
|
|
CRegImport *pRegImport = NULL;
|
|
BOOL bFound = FALSE;
|
|
|
|
while (TRUE)
|
|
{
|
|
// test a list of versions - as soon as 1 is found, this check succeeds
|
|
|
|
IF_FAILED_EXIT((static_cast<CManifestData*>(pPlatformData))->Get(dwCount,
|
|
(LPVOID*) &pwzVersion, &cbProperty, &dwType));
|
|
if (pwzVersion == NULL)
|
|
break;
|
|
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_LPWSTR, HRESULT_FROM_WIN32(ERROR_BAD_FORMAT));
|
|
IF_FAILED_EXIT(sVersion.TakeOwnership(pwzVersion, cbProperty/sizeof(WCHAR)));
|
|
pwzVersion = NULL;
|
|
|
|
// xml format: <supportedRuntime version="v1.0.4122" />
|
|
// registry layout: HKLM\software\microsoft\.netframework\policy\v1.0, value name=4122
|
|
IF_FAILED_EXIT(sVersion.SplitLastElement(L'.', sBuildNum));
|
|
|
|
IF_FAILED_EXIT(sRegPath.Assign(WZ_DOTNETREGPATH));
|
|
IF_FAILED_EXIT(sRegPath.Append(sVersion));
|
|
|
|
// note: require access to HKLM
|
|
IF_FAILED_EXIT(CRegImport::Create(&pRegImport, sRegPath._pwz, HKEY_LOCAL_MACHINE));
|
|
if (hr == S_OK)
|
|
{
|
|
IF_FAILED_EXIT(pRegImport->Check(sBuildNum._pwz, bFound));
|
|
if (bFound)
|
|
break;
|
|
SAFEDELETE(pRegImport);
|
|
}
|
|
dwCount++;
|
|
}
|
|
|
|
if (bFound)
|
|
hr = S_OK;
|
|
else
|
|
hr = S_FALSE;
|
|
|
|
exit:
|
|
SAFEDELETEARRAY(pwzVersion);
|
|
SAFEDELETE(pRegImport);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CheckManagedPlatform(LPMANIFEST_DATA pPlatformData)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
MAKE_ERROR_MACROS_STATIC(hr);
|
|
LPASSEMBLY_IDENTITY pAsmId = NULL;
|
|
DWORD cbProperty = 0;
|
|
DWORD dwType = 0;
|
|
CString sAsmPath;
|
|
|
|
// ISSUE-06/07/02-felixybc apply policy also; use Fusion's PreBind
|
|
|
|
IF_FAILED_EXIT(pPlatformData->Get(CAssemblyManifestImport::g_StringTable[CAssemblyManifestImport::AssemblyIdTag].pwz,
|
|
(LPVOID*) &pAsmId, &cbProperty, &dwType));
|
|
IF_NULL_EXIT(pAsmId, E_FAIL);
|
|
IF_FALSE_EXIT(dwType == MAN_DATA_TYPE_IUNKNOWN_PTR, E_FAIL);
|
|
|
|
IF_FAILED_EXIT(CAssemblyCache::GlobalCacheLookup(pAsmId, sAsmPath));
|
|
|
|
exit:
|
|
SAFERELEASE(pAsmId);
|
|
return hr;
|
|
}
|
|
|
|
|
|
HRESULT CheckPlatform(LPMANIFEST_DATA pPlatformData)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
MAKE_ERROR_MACROS_STATIC(hr);
|
|
CString sPlatformType;
|
|
LPWSTR pwzBuf = NULL;
|
|
|
|
// get the platform type
|
|
IF_FAILED_EXIT(pPlatformData->GetType(&pwzBuf));
|
|
IF_NULL_EXIT(pwzBuf, E_FAIL);
|
|
// use accessor.
|
|
IF_FAILED_EXIT(sPlatformType.TakeOwnership(pwzBuf));
|
|
pwzBuf = NULL;
|
|
|
|
IF_FAILED_EXIT(sPlatformType.CompareString(WZ_DATA_PLATFORM_OS));
|
|
if (hr == S_OK)
|
|
{
|
|
IF_FAILED_EXIT(CheckOS(pPlatformData));
|
|
}
|
|
else
|
|
{
|
|
IF_FAILED_EXIT(sPlatformType.CompareString(WZ_DATA_PLATFORM_DOTNET));
|
|
if (hr == S_OK)
|
|
{
|
|
IF_FAILED_EXIT(CheckDotNet(pPlatformData));
|
|
}
|
|
else
|
|
{
|
|
/*IF_FAILED_EXIT(sName.CompareString(DX));
|
|
if (hr == S_OK)
|
|
{
|
|
IF_FAILED_EXIT(CheckDirectX(pPlatformData));
|
|
}
|
|
else
|
|
{*/
|
|
IF_FAILED_EXIT(sPlatformType.CompareString(WZ_DATA_PLATFORM_MANAGED));
|
|
if (hr == S_OK)
|
|
{
|
|
IF_FAILED_EXIT(CheckManagedPlatform(pPlatformData));
|
|
}
|
|
else
|
|
hr = E_FAIL;
|
|
//}
|
|
}
|
|
}
|
|
|
|
exit:
|
|
SAFEDELETEARRAY(pwzBuf);
|
|
return hr;
|
|
}
|