Windows2003-3790/windows/appcompat/shims/layer/fileversioninfolie.cpp
2020-09-30 16:53:55 +02:00

359 lines
12 KiB
C++

/*++
Copyright (c) 2000-2002 Microsoft Corporation
Module Name:
FileVersionInfoLie.cpp
Abstract:
This shim replaces the info returned from calls to GetFileVersionInfoSize and
GetFileVersionInfo with information stored in resource files. The default
is to replace file info with stored info obtained from DirectX ver 7a.
This can be overridden with command line input. For example:
COMMAND_LINE("D3drgbxf.dll,IDR_D3DRGBXFINFO;dsound.vxd,IDR_DSOUNDVXDINFO")
this would intercept the info calls for D3drgbxf.dll and dsounc.vxd and replace
their info with the info stored in the resources named. Note: All spaces within
the command line are considered part of the filename or resource name, only the
commas and semicolons are delimeters.
Notes:
This is a general purpose shim.
History:
01/03/2000 a-jamd Created
03/28/2000 a-jamd Added resource for ddraw16.dll
04/04/2000 a-michni Added resource for D3drgbxf.dll
04/07/2000 linstev Added resource for dsound.vxd
04/10/2000 markder Removed GetModuleHandle("_DDRAW6V") calls -- use g_hinstDll
04/18/2000 a-michni Modified DDraw6Versionlie to be command line input driven and
renamed to FileVersionInfoLie
04/26/2000 a-batjar GetFileVersionInfo should return truncated result if passed
in buffer size is smaller than infosize
07/19/2000 andyseti Added resource for shdocvw.bin
08/11/2000 a-brienw changed g_nNumDirectX6 to 7 and added entry for dsound.dll
made it the same as dsound.vxd
08/15/2000 a-vales Added resource for dsound.dll
11/08/2000 a-brienw changed dsound.dll entry to return dsound.vxd version info.
a-vales changed it from my previous entry which caused MAX2
to no longer work. I changed it back and checked it with
MAX2 and his app Golden Nugget and it is fine with both.
12/06/2000 mnikkel Added resources for all directx7a dlls and also for any
dlls that existed in previous versions of directx but
were deleted. NOTE: the resources for these files are
in win98 format so that apps which directly read the version
info will receive them in the way they are expecting.
02/18/2002 mnikkel Added check to make sure a null pointer was not passed into GetFileVersionInfoSizeA.
Added check to make sure a null pointer was not passed into GetFileVersionInfoA.
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(FileVersionInfoLie)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(GetFileVersionInfoA)
APIHOOK_ENUM_ENTRY(GetFileVersionInfoSizeA)
APIHOOK_ENUM_END
// Keep a list of files to version lie.
struct LIELIST
{
struct LIELIST * next;
CString szFileName;
CString szResource;
};
LIELIST *g_pLieList = NULL;
// DirectX 7a default files go here.
const INT g_nNumDirectX7a = 67;
WCHAR *g_szDirectX7aFiles[g_nNumDirectX7a] =
{ L"dplay.dll", L"d3dim.dll", L"d3dim700.dll",
L"d3dpmesh.dll", L"d3dramp.dll", L"d3drampf.dll",
L"d3dref.dll", L"d3drg16f.dll", L"d3drg24f.dll",
L"d3drg24x.dll", L"d3dhalf.dll", L"d3drg32f.dll",
L"d3drg32x.dll", L"d3drg55x.dll", L"d3drg56x.dll",
L"d3drg8f.dll", L"d3drg8x.dll", L"d3drgbf.dll",
L"d3drgbxf.dll", L"d3drm.dll", L"d3drm16f.dll",
L"d3drm24f.dll", L"d3drm32f.dll", L"d3drm8f.dll",
L"d3dxof.dll", L"ddhelp.exe", L"ddraw.dll",
L"ddraw16.dll", L"ddrawex.dll", L"devnode1.dll",
L"devnode2.dll", L"dinput.dll", L"dmband.dll",
L"dmcompos.dll", L"dmime.dll", L"dmloader.dll",
L"dmstyle.dll", L"dmsynth.dll", L"dmusic.dll",
L"dmusic16.dll", L"dmusic32.dll", L"dplayx.dll",
L"dpmodemx.dll", L"dpserial.dll", L"dpwsock.dll",
L"dpwsockx.dll", L"dsetup.dll", L"dsetup16.dll",
L"dsetup32.dll", L"dsetup6e.dll", L"dsetup6j.dll",
L"dsetupe.dll", L"dsetupj.dll", L"dsound.dll",
L"dsound3d.dll", L"dx7vb.dll", L"dxmigr.dll",
L"gcdef.dll", L"gchand.dll", L"msvcrt.dll",
L"pid.dll", L"vjoyd.vxd", L"dinput.vxd",
L"dsound.vxd", L"joyhid.vxd", L"mtrr.vxd",
L"ddraw.vxd"
};
// NOTE: These are 16 bit resources!!! This is necessary in case
// they index into the data themselves. If they do a verqueryvalue
// the data is converted before its returned by verqueryvalue.
WCHAR * g_szDirectX7aResource[g_nNumDirectX7a] =
{ L"IDR_dplay", L"IDR_d3dim", L"IDR_d3dim700",
L"IDR_d3dpmesh", L"IDR_d3dramp", L"IDR_d3drampf",
L"IDR_d3dref", L"IDR_d3drg16f", L"IDR_d3drg24f",
L"IDR_d3drg24x", L"IDR_d3dhalf", L"IDR_d3drg32f",
L"IDR_d3drg32x", L"IDR_d3drg55x", L"IDR_d3drg56x",
L"IDR_d3drg8f", L"IDR_d3drg8x", L"IDR_d3drgbf",
L"IDR_d3drgbxf", L"IDR_d3drm", L"IDR_d3drm16f",
L"IDR_d3drm24f", L"IDR_d3drm32f", L"IDR_d3drm8f",
L"IDR_d3dxof", L"IDR_ddhelp", L"IDR_ddraw",
L"IDR_ddraw16", L"IDR_ddrawex", L"IDR_devnode1",
L"IDR_devnode2", L"IDR_dinput", L"IDR_dmband",
L"IDR_dmcompos", L"IDR_dmime", L"IDR_dmloader",
L"IDR_dmstyle", L"IDR_dmsynth", L"IDR_dmusic",
L"IDR_dmusic16", L"IDR_dmusic32", L"IDR_dplayx",
L"IDR_dpmodemx", L"IDR_dpserial", L"IDR_dpwsock",
L"IDR_dpwsockx", L"IDR_dsetup", L"IDR_dsetup16",
L"IDR_dsetup32", L"IDR_dsetup6e", L"IDR_dsetup6j",
L"IDR_dsetupe", L"IDR_dsetupj", L"IDR_dsound",
L"IDR_dsound3d", L"IDR_dx7vb", L"IDR_dxmigr",
L"IDR_gcdef", L"IDR_gchand", L"IDR_msvcrt",
L"IDR_pid", L"IDR_vjoydvxd", L"IDR_dinputvxd",
L"IDR_dsoundvxd", L"IDR_joyhidvxd", L"IDR_mtrrvxd",
L"IDR_ddrawvxd"
};
/*++
return the size from the resource.
--*/
DWORD
APIHOOK(GetFileVersionInfoSizeA)(
LPSTR lpstrFilename,
LPDWORD lpdwHandle
)
{
DWORD dwRet = 0;
CSTRING_TRY
{
HRSRC hrsrcManifest = NULL;
LIELIST *pLiePtr = g_pLieList;
DPFN( eDbgLevelSpew, "[GetFileVersionInfoSizeA] size requested for %s\n", lpstrFilename );
CString csFileName(lpstrFilename);
CString csFilePart;
csFileName.GetLastPathComponent(csFilePart);
// Search through the list of files with their matching IDR's
while( pLiePtr )
{
if (csFilePart.CompareNoCase(pLiePtr->szFileName) == 0)
{
hrsrcManifest = FindResourceW( g_hinstDll, pLiePtr->szResource, L"FILES");
break;
}
pLiePtr = pLiePtr->next;
}
// If a match was found, get the resource size
if( hrsrcManifest )
{
dwRet = SizeofResource(g_hinstDll, hrsrcManifest);
if (lpdwHandle)
{
*lpdwHandle = 0;
}
}
}
CSTRING_CATCH
{
// Do nothing
}
if (dwRet == 0)
{
dwRet = ORIGINAL_API(GetFileVersionInfoSizeA)(lpstrFilename, lpdwHandle);
}
return dwRet;
}
/*++
Return the version for the modules that shipped with Win98SE.
--*/
BOOL
APIHOOK(GetFileVersionInfoA)(
LPSTR lpstrFilename,
DWORD dwHandle,
DWORD dwLen,
LPVOID lpData
)
{
BOOL bRet = FALSE;
CSTRING_TRY
{
HRSRC hrsrcManifest = NULL;
LIELIST *pLiePtr = g_pLieList;
DPFN( eDbgLevelSpew, "[GetFileVersionInfoA] info requested for %s\n", lpstrFilename );
CString csFileName(lpstrFilename);
CString csFilePart;
csFileName.GetLastPathComponent(csFilePart);
// Search through the list of files with their matching IDR's
while( pLiePtr )
{
if (csFilePart.CompareNoCase(pLiePtr->szFileName) == 0)
{
hrsrcManifest = FindResourceW( g_hinstDll, pLiePtr->szResource, L"FILES");
break;
}
pLiePtr = pLiePtr->next;
}
// If a match was found, get the resource size
if( hrsrcManifest )
{
LOGN( eDbgLevelError, "[GetFileVersionInfoA] Getting legacy version for %s.", lpstrFilename);
DWORD dwManifestSize = SizeofResource(g_hinstDll, hrsrcManifest);
HGLOBAL hManifestMem = LoadResource (g_hinstDll, hrsrcManifest);
PVOID lpManifestMem = LockResource (hManifestMem);
if (lpManifestMem)
{
memcpy(lpData, lpManifestMem, dwLen >= dwManifestSize ? dwManifestSize:dwLen );
bRet = TRUE;
}
}
}
CSTRING_CATCH
{
// Do nothing
}
if (!bRet)
{
bRet = ORIGINAL_API(GetFileVersionInfoA)(
lpstrFilename,
dwHandle,
dwLen,
lpData);
}
return bRet;
}
/*++
Parse the command line inputs.
--*/
BOOL ParseCommandLine(const char * commandLine)
{
CSTRING_TRY
{
CString csCmdLine(commandLine);
// if there are no command line inputs then default to
// the DirectX 7a files needed.
if (csCmdLine.IsEmpty())
{
DPFN( eDbgLevelSpew, "Defaulting to DirectX7a\n" );
for(int i = 0; i < g_nNumDirectX7a; i++)
{
LIELIST * pLiePtr = new LIELIST;
if (pLiePtr == NULL)
{
DPFN( eDbgLevelSpew, "Out of Memory when trying to allocate list." );
return FALSE;
}
pLiePtr->szFileName = g_szDirectX7aFiles[i];
pLiePtr->szResource = g_szDirectX7aResource[i];
pLiePtr->next = g_pLieList;
g_pLieList = pLiePtr;
}
}
else
{
CStringToken csTokenList(csCmdLine, L";");
CString csEntryTok;
while (csTokenList.GetToken(csEntryTok))
{
CStringToken csEntry(csEntryTok, L",");
CString csLeft;
CString csRight;
csEntry.GetToken(csLeft);
csEntry.GetToken(csRight);
if (!csLeft.IsEmpty() && !csRight.IsEmpty())
{
LIELIST * pLiePtr = new LIELIST;
pLiePtr->szFileName = csLeft;
pLiePtr->szResource = csRight;
pLiePtr->next = g_pLieList;
g_pLieList = pLiePtr;
}
}
}
}
CSTRING_CATCH
{
return FALSE;
}
return TRUE;
}
/*++
Register hooked functions
--*/
BOOL
NOTIFY_FUNCTION(
DWORD fdwReason
)
{
if (fdwReason == DLL_PROCESS_ATTACH)
{
return ParseCommandLine(COMMAND_LINE);
}
return TRUE;
}
HOOK_BEGIN
CALL_NOTIFY_FUNCTION
APIHOOK_ENTRY(VERSION.DLL, GetFileVersionInfoA)
APIHOOK_ENTRY(VERSION.DLL, GetFileVersionInfoSizeA)
HOOK_END
IMPLEMENT_SHIM_END