windows-nt/Source/XPSP1/NT/windows/appcompat/shims/specific/nflfever2000.cpp
2020-09-26 16:20:57 +08:00

162 lines
3.3 KiB
C++

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
NFLFever2000.cpp
Abstract:
The app reads past the end of files that it's copied into memory.
The shim allocates additional memory for it
Note we included an in-memory patch for Win2k. On Whistler it's not
required, the rest of the shim does the work.
Notes:
This is an app specific shim.
History:
01/11/2000 linstev Created
10/03/2000 maonis Modified (the acm stuff is now in a general purpose shim)
--*/
#include "precomp.h"
IMPLEMENT_SHIM_BEGIN(NFLFever2000)
#include "ShimHookMacro.h"
APIHOOK_ENUM_BEGIN
APIHOOK_ENUM_ENTRY(GetFileSize)
APIHOOK_ENUM_ENTRY(RtlAllocateHeap)
APIHOOK_ENUM_ENTRY(mmioSetInfo)
APIHOOK_ENUM_END
DWORD g_dwFileSize = -1;
BOOL g_bPatched = FALSE;
/*++
Hook GetFileSize to make sure we get the correct heap allocations.
--*/
DWORD
APIHOOK(GetFileSize)(
HANDLE hFile,
LPDWORD lpFileSizeHigh
)
{
DWORD dwRet = ORIGINAL_API(GetFileSize)(hFile, lpFileSizeHigh);
g_dwFileSize = dwRet;
PBYTE p;
ULONG oldProtect;
if (!g_bPatched) {
p = (PBYTE)0x10995d0;
if (!IsBadReadPtr(p, 1) && (*p == 0x8b)) {
VirtualProtect(p, 3, PAGE_READWRITE, &oldProtect);
*p = 0xc2;
*(p + 1) = 0x8;
*(p + 2) = 0x0;
VirtualProtect(p, 3, oldProtect, &oldProtect);
g_bPatched = TRUE;
}
}
return dwRet;
}
/*++
Increase the heap allocation size.
--*/
PVOID
APIHOOK(RtlAllocateHeap) (
PVOID HeapHandle,
ULONG Flags,
SIZE_T Size
)
{
if (Size == g_dwFileSize) {
DPFN( eDbgLevelError, "Adjusted heap allocation from %d to %d\n", Size, Size+0x1000);
Size += 0x1000;
}
return ORIGINAL_API(RtlAllocateHeap)(HeapHandle, Flags, Size);
}
/*++
Make the buffer read/write.
--*/
MMRESULT
APIHOOK(mmioSetInfo)(
HMMIO hmmio,
LPMMIOINFO lpmmioinfo,
UINT wFlags
)
{
//
// BUGBUG: Not needed on XP, but still required on Win2k
// This fix causes sound to skip, see #304678.
//
// Win2k used to check if the buffer could be written to, instead of just
// read. We fixed this on XP. However, it's not enough to just copy the
// buffer, because it's used later.
// Not clear what the actual fix is though.
//
/*
HPSTR p = NULL;
if (lpmmioinfo && lpmmioinfo->pchBuffer &&
(IsBadWritePtr(lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer) &&
!IsBadReadPtr(lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer))) {
p = (HPSTR) malloc(lpmmioinfo->cchBuffer);
if (p) {
DPFN( eDbgLevelError, "Fixing mmioSetInfo buffer");
MoveMemory(p, lpmmioinfo->pchBuffer, lpmmioinfo->cchBuffer);
lpmmioinfo->pchBuffer = p;
}
}
MMRESULT mRet = ORIGINAL_API(mmioSetInfo)(hmmio, lpmmioinfo, wFlags);
if (p) {
free(p);
}
return mRet;
*/
return ORIGINAL_API(mmioSetInfo)(hmmio, lpmmioinfo, wFlags);
}
/*++
Register hooked functions
--*/
HOOK_BEGIN
APIHOOK_ENTRY(KERNEL32.DLL, GetFileSize)
APIHOOK_ENTRY(NTDLL.DLL, RtlAllocateHeap)
APIHOOK_ENTRY(WINMM.DLL, mmioSetInfo)
HOOK_END
IMPLEMENT_SHIM_END