#include "stdafx.h"
#include "IsVistaKB940105Required.h"


#ifdef _MANAGED
#pragma managed(push, off)
#endif


static bool IsRequired()
{
#if defined(WIN32) && !defined(WIN64)
	OSVERSIONINFO osv;
	memset(&osv, 0, sizeof(osv));
	osv.dwOSVersionInfoSize = sizeof(osv);
	GetVersionEx(&osv);

	if (osv.dwMajorVersion != 6 || osv.dwMinorVersion != 0 || (osv.dwBuildNumber > 6000))
	{
		// This QFE only ever applies to Windows Vista RTM. Windows Vista SP1 already has this fix,
		// and earlier versions of Windows do not implement WDDM
		return false;
	}

	//MEMORYSTATUSEX mex;
	//memset(&mex, 0, sizeof(mex));
	//mex.dwLength = sizeof(mex);
	//GlobalMemoryStatusEx(&mex);

	//if (mex.ullTotalVirtual >= 4294836224)
	//{
	//	// If there is 4 GB of VA space total for this process, then we are a
	//	// 32-bit Large Address Aware application running on a Windows 64-bit OS.

	//	// We could be a 32-bit Large Address Aware application running on a
	//	// Windows 32-bit OS and get up to 3 GB, but that has stability implications.
	//	// Therefore, we recommend the QFE for all 32-bit versions of the OS.

	//	// No need for the fix unless the game is pushing 4 GB of VA
	//	return false;
	//}

	const char* sysFile = "dxgkrnl.sys";

	// Ensure we are checking the system copy of the file
	char sysPath[MAX_PATH];
	GetSystemDirectory(sysPath, sizeof(sysPath));

	strncat(sysPath, "\\drivers\\", MAX_PATH);
	strncat(sysPath, sysFile, MAX_PATH);

	char buf[2048];
	if (!GetFileVersionInfo(sysPath, 0, sizeof(buf), buf))
	{
		// This should never happen, but we'll assume it's a newer .sys file since we've
		// narrowed the test to a Windows Vista RTM OS.
		return false;
	}

	VS_FIXEDFILEINFO* ver;
	UINT size;
	if (!VerQueryValue(buf, "\\", (void**) &ver, &size) || size != sizeof(VS_FIXEDFILEINFO) || ver->dwSignature != 0xFEEF04BD)
	{
		// This should never happen, but we'll assume it's a newer .sys file since we've
		// narrowed the test to a Windows Vista RTM OS.
		return false;
	}

	// File major.minor.build.qfe version comparison
	//   WORD major = HIWORD( ver->dwFileVersionMS ); WORD minor = LOWORD( ver->dwFileVersionMS );
	//   WORD build = HIWORD( ver->dwFileVersionLS ); WORD qfe = LOWORD( ver->dwFileVersionLS );

	if (ver->dwFileVersionMS > MAKELONG(0, 6) || (ver->dwFileVersionMS == MAKELONG(0, 6) && ver->dwFileVersionLS >= MAKELONG(20648, 6000)))
	{
		// QFE fix version of dxgkrnl.sys is 6.0.6000.20648
		return false;
	}

	return true;
#else
	return false; // The QFE is not required for a 64-bit native application as it has 8 TB of VA
#endif
}


ISVISTAKB940105REQUIRED_API BOOL IsVistaKB940105Required()
{
	return IsRequired() ? TRUE : FALSE;
}


BOOL APIENTRY DllMain(HMODULE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
{
	return TRUE;
}


#ifdef _MANAGED
#pragma managed(pop)
#endif

