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

3313 lines
94 KiB
C++
Raw Permalink Blame History

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
Custom.cpp
Abstract:
Module to add custom behaviour to virtual registry.
Fixes:
VersionNumber string for Microsoft Playpack
Expanders for DevicePath, ProgramFilesPath and WallPaperDir
Redirectors for screen savers
Virtual HKEY_DYN_DATA structure
Add ProductName to all Network Cards
Locale has been moved
Wordpad filenames
NoDriveTypeAutorun has a different type
Notes:
This file should be used to add custom behavior to virtual registry.
History:
05/05/2000 linstev Created
09/01/2000 t-adams Added support for PCI devices to BuildDynData()
09/01/2000 robkenny Added Krondor
09/09/2000 robkenny Updated Wordpad to return a short path to the exe
09/21/2000 prashkud Added fix for SpellItDeluxe
10/25/2000 maonis Added CookieMaster
10/17/2000 robkenny Added HKEY_DYN_DATA\Display\Settings
11/27/2000 a-fwills Added display guid to redirectors
12/28/2000 a-brienw Added BuildTalkingDictionary for American Heritage
Talking Dictionary which is looking for a SharedDir key
01/15/2001 maonis Added PageKeepPro
02/06/2001 a-larrsh Added FileNet Web Server
02/27/2001 maonis Added PageMaker
02/27/2001 robkenny Converted to use tcs.h
03/01/2001 prashkud Added NetBT keys in BuildNetworkCards()
04/05/2001 mnikkel Added HKLM\Microsoft\Windows\CurrentVersion\App Paths\DXDIAG.EXE
04/27/2001 prashkud Added custom MiddleSchoolAdvantage 2001 entry
05/04/2001 prashkud Added custom entry for BOGUSCTRLID - Win2K layer
05/19/2001 hioh Added NOWROBLUE, BuildNowroBlue
06/13/2001 carlco Added Princeton ACT
08/10/2001 mikrause Added Airline Tycoon, DirectSound hacks.
11/06/2001 mikrause Added Delphi 5.0 Pro
01/02/2002 mamathas Added NortonAntiVirus2002, BuildNortonAntiVirus
04/23/2002 garyma Added Word Perfect Office 2002
--*/
#define SHIM_LIB_BUILD_FLAG
#include "precomp.h"
#include "secutils.h"
#include <stdio.h>
IMPLEMENT_SHIM_BEGIN(VirtualRegistry)
#include "ShimHookMacro.h"
#include "VRegistry.h"
#include "VRegistry_dsound.h"
//
// Functions that modify the behaviour of virtualregistry
//
void BuildWin98SE(char* szParam);
void BuildRedirectors(char* szParam);
void BuildCookiePath(char* szParam);
void BuildHasbro(char* szParam);
void BuildDynData(char* szParam);
void BuildCurrentConfig(char* szParam);
void BuildLocale(char* szParam);
void BuildWordPad(char* szParam);
void BuildAutoRun(char* szParam);
void BuildTalkingDictionary(char* szParam);
void BuildNetworkCards(char* szParam);
void BuildNT4SP5(char* szParam);
void BuildNT50(char* szParam);
void BuildNT51(char* szParam);
void BuildBogusCtrlID(char* szParam);
void BuildExpanders(char* szParam);
void BuildDX7A(char* szParam);
void BuildDXDiag(char* szParam);
void BuildFutureCop(char* szParam);
void BuildKrondor(char* szParam);
void BuildPageKeepProDirectory(char* szParam);
void BuildProfile(char* szParam);
void BuildSpellItDeluxe(char* szParam);
void BuildIE401(char* szParam);
void BuildIE55(char* szParam);
void BuildIE60(char* szParam);
void BuildJoystick(char* szParam);
void BuildIllustrator8(char* szParam);
void BuildModemWizard(char* szParam);
void BuildMSI(char* szParam);
void BuildFileNetWebServer(char* szParam);
void BuildPrinter(char* szParam);
void BuildPageMaker65(char* szParam);
void BuildStarTrekArmada(char* szParam);
void BuildMSA2001(char* szParam);
void BuildNowroBlue(char* szParam);
void BuildRegisteredOwner(char* szParam);
void BuildPrincetonACT(char* szParam);
void BuildHEDZ(char* szParam);
void BuildAirlineTycoon(char* szParam);
void BuildDSDevAccel(char* szParam);
void BuildDSPadCursors(char* szParam);
void BuildDSCachePositions(char* szParam);
void BuildDSReturnWritePos(char* szParam);
void BuildDSSmoothWritePos(char* szParam);
void BuildDSDisableDevice(char* szParam);
void BuildDelphi5Pro(char* szParam);
void BuildNortonAntiVirus(char* szParam);
void BuildWordPerfect2002(char* szParam);
// Table that contains all the fixes - note, must be terminated by a NULL entry.
VENTRY g_VList[] =
{
{L"WIN98SE", BuildWin98SE, eWin9x, FALSE, NULL },
{L"REDIRECT", BuildRedirectors, eWin9x, FALSE, NULL },
{L"COOKIEPATH", BuildCookiePath, eWin9x, FALSE, NULL },
{L"HASBRO", BuildHasbro, eWin9x, FALSE, NULL },
{L"DYN_DATA", BuildDynData, eWin9x, FALSE, NULL },
{L"CURRENT_CONFIG", BuildCurrentConfig, eWin9x, FALSE, NULL },
{L"LOCALE", BuildLocale, eWin9x, FALSE, NULL },
{L"WORDPAD", BuildWordPad, eWin9x, FALSE, NULL },
{L"AUTORUN", BuildAutoRun, eWin9x, FALSE, NULL },
{L"TALKINGDICTIONARY", BuildTalkingDictionary, eWin9x, FALSE, NULL },
{L"PRINTER", BuildPrinter, eWin9x, FALSE, NULL },
{L"REGISTEREDOWNER", BuildRegisteredOwner, eWin9x, FALSE, NULL },
{L"NETWORK_CARDS", BuildNetworkCards, eWinNT, FALSE, NULL },
{L"NT4SP5", BuildNT4SP5, eWinNT, FALSE, NULL },
{L"NT50", BuildNT50, eWin2K, FALSE, NULL },
{L"BOGUSCTRLID", BuildBogusCtrlID, eWin2K, FALSE, NULL },
{L"NT51", BuildNT51, eWinXP, FALSE, NULL },
{L"EXPAND", BuildExpanders, eCustom, FALSE, NULL },
{L"DX7A", BuildDX7A, eCustom, FALSE, NULL },
{L"DXDIAG", BuildDXDiag, eCustom, FALSE, NULL },
{L"FUTURECOP", BuildFutureCop, eCustom, FALSE, NULL },
{L"KRONDOR", BuildKrondor, eCustom, FALSE, NULL },
{L"PROFILE", BuildProfile, eCustom, FALSE, NULL },
{L"SPELLITDELUXE", BuildSpellItDeluxe, eCustom, FALSE, NULL },
{L"IE401", BuildIE401, eCustom, FALSE, NULL },
{L"IE55", BuildIE55, eCustom, FALSE, NULL },
{L"IE60", BuildIE60, eCustom, FALSE, NULL },
{L"JOYSTICK", BuildJoystick, eCustom, FALSE, NULL },
{L"ILLUSTRATOR8", BuildIllustrator8, eCustom, FALSE, NULL },
{L"PAGEKEEPPRO30", BuildPageKeepProDirectory, eCustom, FALSE, NULL },
{L"MODEMWIZARD", BuildModemWizard, eCustom, FALSE, NULL },
{L"MSI", BuildMSI, eCustom, FALSE, NULL },
{L"FILENETWEBSERVER", BuildFileNetWebServer, eCustom, FALSE, NULL },
{L"PAGEMAKER65", BuildPageMaker65, eCustom, FALSE, NULL },
{L"STARTREKARMADA", BuildStarTrekArmada, eCustom, FALSE, NULL },
{L"MSA2001", BuildMSA2001, eCustom, FALSE, NULL },
{L"NOWROBLUE", BuildNowroBlue, eCustom, FALSE, NULL },
{L"PRINCETONACT", BuildPrincetonACT, eCustom, FALSE, NULL },
{L"HEDZ", BuildHEDZ, eCustom, FALSE, NULL },
{L"AIRLINETYCOON", BuildAirlineTycoon, eCustom, FALSE, NULL },
{L"DSDEVACCEL", BuildDSDevAccel, eCustom, FALSE, NULL },
{L"DSPADCURSORS", BuildDSPadCursors, eCustom, FALSE, NULL },
{L"DSCACHEPOSITIONS", BuildDSCachePositions, eCustom, FALSE, NULL },
{L"DSRETURNWRITEPOS", BuildDSReturnWritePos, eCustom, FALSE, NULL },
{L"DSSMOOTHWRITEPOS", BuildDSSmoothWritePos, eCustom, FALSE, NULL },
{L"DSDISABLEDEVICE", BuildDSDisableDevice, eCustom, FALSE, NULL },
{L"DELPHI5PRO", BuildDelphi5Pro, eCustom, FALSE, NULL },
{L"NORTONANTIVIRUS", BuildNortonAntiVirus, eCustom, FALSE, NULL },
{L"WORDPERFECT2002", BuildWordPerfect2002, eCustom, FALSE, NULL },
// Must Be The Last Entry
{L"", NULL, eCustom, FALSE, NULL }
};
VENTRY *g_pVList = &g_VList[0];
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add Win98 SE registry value - so far we only know about the Play Pack that
needs it.
History:
05/04/2000 linstev Created
--*/
void
BuildWin98SE(char* /*szParam*/)
{
VIRTUALKEY *key;
// Add version number string for emulation of Win98 SE
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion");
if (key)
{
key->AddValue(L"VersionNumber", REG_SZ, (LPBYTE)L"4.10.2222");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Known moved locations for which we need redirectors
History:
05/04/2000 linstev Created
--*/
void
BuildRedirectors(char* /*szParam*/)
{
// Display property page add ons and controls have changed location.
VRegistry.AddRedirect(
L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\Display",
L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\Desk");
// this key moved somewhere around build 2200.
// System config scan type apps (ip.exe bundled in EA sports)
// starting failing again.
VRegistry.AddRedirect(
L"HKLM\\System\\CurrentControlSet\\Services\\Class",
L"HKLM\\System\\CurrentControlSet\\Control\\Class");
// Nightmare Ned wasn't finding display starting from Class.
// Directing it from Display to the GUID.
VRegistry.AddRedirect(
L"HKLM\\System\\CurrentControlSet\\Services\\Class\\Display",
L"HKLM\\System\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}");
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
CookieMaster gets the wrong path to cookies
because HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache\\Special Paths\\Cookies
contains bogus value (shell is going to fix this). We change this to the correct value %USERPROFILE%\Cookies.
History:
10/25/2000 maonis Created
--*/
void
BuildCookiePath(char* /*szParam*/)
{
WCHAR wCookiePath[] = L"%USERPROFILE%\\Cookies";
VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache\\Special Paths\\Cookies");
if (key)
{
key->AddValue(L"Directory", REG_EXPAND_SZ, (LPBYTE)wCookiePath, 0);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
During the Slingo installation, the program places a value in the registry
called 'PALFILE'. When you run the app, it checks this value to determine
where the CD-ROM is located. For example, if the CD-ROM drive is 'E', it
should put 'E:\Slingo.pal'. It fails to do this correctly on Win2K or Whistler,
as it puts the install path instead. When the app runs, if the value doesn't
refer to 'x:\Slingo.pal (where x is the CD-ROM drive)', the app immediately
starts to do a FindFirstFile->FindNextFile looking for the file on the hard
drive. Eventually it AVs during the search with no error message. This code
sets the value in the registry on behalf of the app.
History:
11/1/2000 rparsons Created
--*/
LONG
WINAPI
VR_Hasbro(
OPENKEY *key,
VIRTUALKEY * /* vkey */,
VIRTUALVAL *vvalue
)
{
DWORD dwType;
WCHAR wszPath[MAX_PATH];
DWORD dwSize = sizeof(wszPath);
DWORD dwAttributes;
//
// Query the original value
//
LONG lRet = RegQueryValueExW(
key->hkOpen,
vvalue->wName,
NULL,
&dwType,
(LPBYTE)wszPath,
&dwSize);
//
// Query failed - something went wrong
//
if (FAILURE(lRet))
{
DPFN( eDbgLevelError, "[Hasbro hack] Failed to query %S for expansion", vvalue->wName);
goto Exit;
}
//
// Not a string type!
//
if ((dwType != REG_SZ) || (dwSize > sizeof(wszPath)))
{
DPFN( eDbgLevelError, "[Hasbro hack] Failed to query %S", vvalue->wName);
lRet = ERROR_BAD_ARGUMENTS;
goto Exit;
}
// Check what's there
dwAttributes = GetFileAttributes(wszPath);
// If it's not a file, or it's a directory, then we have to find it ourselves
if ((dwAttributes == (DWORD)-1) || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
{
WCHAR *lpDrives = L"";
DWORD dwBufferLen = 0;
//
// The plan is to run all the drives and find one with a .PAL file on
// it. We also have the restriction that it must be a CDRom. It has
// been pointed out that if the user has multiple CD drives and has
// different HasBro titles in each drive, we could cause a failure,
// but we're considering that a pathological case for now. Especially
// considering we have no way of knowing what the palfile name is ahead
// of time.
//
dwBufferLen = GetLogicalDriveStringsW(0, lpDrives);
if (dwBufferLen)
{
lpDrives = (WCHAR *) malloc((dwBufferLen + 1) * sizeof(WCHAR));
if (lpDrives)
{
GetLogicalDriveStrings(dwBufferLen, lpDrives);
WCHAR *lpCurrent = lpDrives;
while (lpCurrent && lpCurrent[0])
{
if (GetDriveTypeW(lpCurrent) == DRIVE_CDROM)
{
//
// We've found a CD drive, now see if it has a .PAL
// file on it.
//
WCHAR wszFile[MAX_PATH];
WIN32_FIND_DATAW ffData;
HANDLE hFindFile;
if (SUCCEEDED(StringCchCopyW(wszFile, MAX_PATH, lpCurrent)) &&
SUCCEEDED(StringCchCatW(wszFile, MAX_PATH, L"*.PAL")))
{
hFindFile = FindFirstFileW(wszFile, &ffData);
if (hFindFile != INVALID_HANDLE_VALUE)
{
// A .PAL file exists, return that.
FindClose(hFindFile);
if (SUCCEEDED(StringCchCopyW(wszPath, MAX_PATH, lpCurrent)) &&
SUCCEEDED(StringCchCatW(wszPath, MAX_PATH, ffData.cFileName)))
{
LOGN( eDbgLevelInfo, "[Hasbro hack] Returning path %S", wszPath);
break;
}
}
}
}
// Advance to the next drive letter
lpCurrent += wcslen(lpCurrent) + 1;
}
free(lpDrives);
}
}
}
// Copy the result into the output of QueryValue
vvalue->cbData = (wcslen(wszPath) + 1) * sizeof(WCHAR);
vvalue->lpData = (LPBYTE) malloc(vvalue->cbData);
if (!vvalue->lpData)
{
DPFN( eDbgLevelError, szOutOfMemory);
lRet = ERROR_NOT_ENOUGH_MEMORY;
goto Exit;
}
MoveMemory(vvalue->lpData, wszPath, vvalue->cbData);
//
// Never call us again, since we've done the work to set this value up and
// stored it in our virtual value
//
vvalue->pfnQueryValue = NULL;
lRet = ERROR_SUCCESS;
Exit:
return lRet;
}
void
BuildHasbro(char* /*szParam*/)
{
HKEY hHasbroKey;
WCHAR wszKeyName[MAX_PATH];
DWORD dwIndex;
const WCHAR wszHasbroPath[] = L"SOFTWARE\\Hasbro Interactive";
if (FAILURE(RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszHasbroPath, 0, KEY_READ, &hHasbroKey)))
{
DPFN( eDbgLevelSpew, "[Hasbro hack] Ignoring fix - no titles found");
return;
}
//
// Enum the keys under Hasbro Interactive and add a virtual PALFILE value.
// Attach our callback to this value (see above)
//
dwIndex = 0;
while (SUCCESS(RegEnumKeyW(hHasbroKey, dwIndex, wszKeyName, MAX_PATH)))
{
WCHAR wszName[MAX_PATH] = L"HKLM\\";
if (SUCCEEDED(StringCchCatW(wszName, MAX_PATH, wszHasbroPath)) &&
SUCCEEDED(StringCchCatW(wszName, MAX_PATH, L"\\")) &&
SUCCEEDED(StringCchCatW(wszName, MAX_PATH, wszKeyName)))
{
VIRTUALKEY *key = VRegistry.AddKey(wszName);
if (key)
{
VIRTUALVAL *val = key->AddValue(L"PALFILE", REG_SZ, 0, 0);
if (val)
{
val->pfnQueryValue = VR_Hasbro;
}
DPFN( eDbgLevelInfo, "[Hasbro hack] Adding fix for %S", wszKeyName);
}
}
dwIndex++;
}
RegCloseKey(hHasbroKey);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
A simple DYN_DATA structure which emulates win9x.
History:
05/04/2000 linstev Created
09/01/2000 t-adams Added support for PCI devices so EA's 3dSetup.exe & others can
detect hardware.
--*/
#define ENUM_BASE 0xC29A28C0
void
BuildDynData(char* /*szParam*/)
{
VIRTUALKEY *key, *nkey;
HKEY hkPCI = 0;
DWORD i = 0;
DWORD dwNameLen = 0;
LPWSTR wstrName = NULL;
LPWSTR wstrVName = NULL;
FILETIME fileTime;
DWORD dwValue;
// Entries in HKDD\Config Manager\Enum were references to entries in HKLM\Enum\PCI that are now
// located at HKLM\SYSTEM\CurrentControlSet\Enum\PCI
VRegistry.AddRedirect(
L"HKLM\\Enum",
L"HKLM\\SYSTEM\\CurrentControlSet\\Enum");
// Construct HKDD\Config Manager\Enum so that it reflects the entries in HKLM\SYSTEM\CurrentControlSet\Enum\PCI
key = VRegistry.AddKey(L"HKDD\\Config Manager\\Enum");
if (!key)
{
goto exit;
}
if (SUCCESS(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Enum\\PCI",0, KEY_READ, &hkPCI)))
{
dwNameLen = MAX_PATH;
wstrName = (LPWSTR) malloc(dwNameLen * sizeof(WCHAR));
if (NULL == wstrName)
{
goto exit;
}
wstrVName = (LPWSTR) malloc(dwNameLen * sizeof(WCHAR));
if (NULL == wstrName)
{
goto exit;
}
i = 0;
while (ERROR_SUCCESS == RegEnumKeyExW(hkPCI, i, wstrName, &dwNameLen, NULL, NULL, NULL, &fileTime))
{
if (FAILED(StringCchPrintf(wstrVName, MAX_PATH, L"%x", ENUM_BASE+i)))
{
continue;
}
nkey = key->AddKey(wstrVName);
if (!nkey) continue;
if (SUCCEEDED(StringCchCopy(wstrVName, MAX_PATH, L"PCI\\")) &&
SUCCEEDED(StringCchCat(wstrVName, MAX_PATH, wstrName)))
{
nkey->AddValue(L"HardWareKey", REG_SZ, (LPBYTE)wstrVName);
}
nkey->AddValueDWORD(L"Problem", 0);
dwNameLen = MAX_PATH;
++i;
}
}
key = VRegistry.AddKey(L"HKDD\\Config Manager\\Global");
key = VRegistry.AddKey(L"HKDD\\PerfStats");
key = VRegistry.AddKey(L"HKDD\\PerfStats\\StartSrv");
if (key)
{
dwValue = 0x0000001;
key->AddValue(L"KERNEL", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM", REG_BINARY, (LPBYTE)&dwValue, 4);
}
key = VRegistry.AddKey(L"HKDD\\PerfStats\\StartStat");
if (key)
{
dwValue = 0x0000001;
key->AddValue(L"KERNEL\\CPUUsage", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"KERNEL\\Threads", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"KERNEL\\VMs", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cCurPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cMacPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cMinPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\FailedRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\Hits", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\LRUBuffers", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\LRURecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\Misses", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\RandomRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\BReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\BWritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\DirtyData", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\ReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\WritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cDiscards", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cInstanceFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageIns", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageOuts", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgCommit", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcache", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMac", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMid", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMin", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgFree", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgLocked", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgLockedNonCache", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgOther", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSharedPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwap", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFile", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFileDefective", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFileInUse", REG_BINARY, (LPBYTE)&dwValue, 4);
}
key = VRegistry.AddKey(L"HKDD\\PerfStats\\StatData");
if (key)
{
dwValue = 0x0000001;
key->AddValue(L"KERNEL\\CPUUsage", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"KERNEL\\Threads", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"KERNEL\\VMs", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cCurPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cMacPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cMinPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\FailedRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\Hits", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\LRUBuffers", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\LRURecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\Misses", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\RandomRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\BReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\BWritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\DirtyData", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\ReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\WritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cDiscards", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cInstanceFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageIns", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageOuts", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgCommit", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcache", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMac", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMid", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMin", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgFree", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgLocked", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgLockedNonCache", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgOther", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSharedPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwap", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFile", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFileDefective", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFileInUse", REG_BINARY, (LPBYTE)&dwValue, 4);
}
key = VRegistry.AddKey(L"HKDD\\PerfStats\\StopSrv");
if (key)
{
dwValue = 0x0000001;
key->AddValue(L"KERNEL", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM", REG_BINARY, (LPBYTE)&dwValue, 4);
}
key = VRegistry.AddKey(L"HKDD\\PerfStats\\StopStat");
if (key)
{
dwValue = 0x0000001;
key->AddValue(L"KERNEL\\CPUUsage", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"KERNEL\\Threads", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"KERNEL\\VMs", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cCurPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cMacPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\cMinPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\FailedRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\Hits", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\LRUBuffers", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\LRURecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\Misses", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VCACHE\\RandomRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\BReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\BWritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\DirtyData", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\ReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VFAT\\WritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cDiscards", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cInstanceFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageIns", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cPageOuts", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgCommit", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcache", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMac", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMid", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgDiskcacheMin", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgFree", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgLocked", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgLockedNonCache", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgOther", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSharedPages", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwap", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFile", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFileDefective", REG_BINARY, (LPBYTE)&dwValue, 4);
key->AddValue(L"VMM\\cpgSwapFileInUse", REG_BINARY, (LPBYTE)&dwValue, 4);
}
exit:
if (NULL != wstrName)
{
free(wstrName);
}
if (NULL != wstrVName)
{
free(wstrVName);
}
if (0 != hkPCI)
{
RegCloseKey(hkPCI);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
DisplaySettings
History:
10/17/2000 robkenny Added HKEY_CURRENT_CONFIG
--*/
void
BuildCurrentConfig(char* /*szParam*/)
{
DEVMODE devMode;
memset(&devMode, 0, sizeof(devMode));
devMode.dmSize = sizeof(devMode);
// Get the current display settings
BOOL bSuccessful = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
if (bSuccessful)
{
// Create fake registry keys with dmPelsWidth, dmPelsHeight, dmPelsWidth and dmBitsPerPel
VIRTUALKEY *key = VRegistry.AddKey(L"HKCC\\Display\\Settings");
if (key)
{
WCHAR lpValue[100];
if (SUCCEEDED(StringCchPrintf(lpValue, 100, L"%d",devMode.dmBitsPerPel)))
{
key->AddValue(L"BitsPerPixel", REG_SZ, (LPBYTE)lpValue, 0);
}
if (SUCCEEDED(StringCchPrintf(lpValue, 100,L"%d,%d", devMode.dmPelsWidth, devMode.dmPelsHeight)))
{
key->AddValue(L"Resolution", REG_SZ, (LPBYTE)lpValue, 0);
}
}
}
// Redirect the current desktop fonts
VRegistry.AddRedirect(
L"HKCC\\Display\\Fonts",
L"HKCC\\Software\\Fonts");
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Make RegQueryValue return the value that's in the "(Default)" value, rather
than the NULL which is in there now. Not sure why the Locale key has this
difference.
History:
06/29/2000 linstev Created
--*/
void
BuildLocale(char* /*szParam*/)
{
#define LOCALE_KEY HKEY_LOCAL_MACHINE
#define LOCALE_SUBKEY L"System\\CurrentControlSet\\Control\\Nls\\Locale"
HKEY hkBase;
if (FAILURE(RegOpenKeyExW(
LOCALE_KEY,
LOCALE_SUBKEY,
0,
KEY_READ,
&hkBase)))
{
return;
}
WCHAR wValue[MAX_PATH];
DWORD dwSize = MAX_PATH * sizeof(WCHAR);
if (SUCCESS(RegQueryValueExW(hkBase, L"(Default)", 0, 0, (LPBYTE)wValue, &dwSize)))
{
LPWSTR wzPath;
VIRTUALKEY *localekey;
// Convert the KEY and SUBKEY into a path we can use for the vregistry
wzPath = MakePath(LOCALE_KEY, 0, LOCALE_SUBKEY);
if (wzPath)
{
localekey = VRegistry.AddKey(wzPath);
if (localekey)
{
localekey->AddValue(L"", REG_SZ, (LPBYTE)wValue);
}
free(wzPath);
}
}
RegCloseKey(hkBase);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
On NT, the strings in these values are of the form:
C:\Program Files\Windows NT\Accessories\WORDPAD.EXE "%1"
Note that the entire string is NOT quoted. On win9x, the string was:
C:\Windows\wordpad.exe "%1"
This causes problems when apps parse the NT version, because they hit the
space between Program and Files.
The fix is to return a shortened pathname to wordpad.exe
History:
05/04/2000 linstev Created
05/04/2000 robkenny Updated to return a correct short pathname to wordpad.exe
--*/
void
BuildWordPad(char* /*szParam*/)
{
// Allocate memory so we don't use up lots of stack
WCHAR *lpwzWordpadOpen = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
WCHAR *lpwzWordpadPrint = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
WCHAR *lpwzWordpadPrintTo = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
WCHAR *lpwzWordpadLong = lpwzWordpadOpen; // borrow the buffer to save space
WCHAR *lpwzWordpadShort = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
DWORD lpType;
DWORD cbValue;
LONG result;
if (lpwzWordpadOpen == NULL ||
lpwzWordpadPrint == NULL ||
lpwzWordpadPrintTo == NULL ||
lpwzWordpadShort == NULL)
{
goto AllDone;
}
// Read the path to WORDPAD.EXE directly from the registry.
HKEY hKeyAppPaths;
result = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\WORDPAD.EXE",
0,
KEY_QUERY_VALUE,
&hKeyAppPaths
);
if (result != ERROR_SUCCESS)
{
goto AllDone;
}
cbValue = MAX_PATH * sizeof(DWORD);
result = RegQueryValueExW(
hKeyAppPaths,
NULL, // default value
NULL,
&lpType,
(LPBYTE)lpwzWordpadLong,
&cbValue);
RegCloseKey(hKeyAppPaths);
if (result != ERROR_SUCCESS)
{
goto AllDone;
}
// turn bytes into string length (includes EOS)
DWORD cchValue = cbValue /sizeof(WCHAR);
if (lpType == REG_EXPAND_SZ)
{
WCHAR * lpwzWordpadExpand = lpwzWordpadPrintTo; // borrow the lpwzWordpadPrintTo buffer for a moment.
cchValue = ExpandEnvironmentStringsW(lpwzWordpadLong, lpwzWordpadExpand, MAX_PATH);
if (cchValue == 0 || cchValue > MAX_PATH )
goto AllDone;
lpwzWordpadLong = lpwzWordpadExpand;
}
// Rip off the trailing Quote
lpwzWordpadLong[cchValue-2] = 0;
lpwzWordpadLong += 1;
// Build the short path to wordpad
cchValue = GetShortPathNameW(lpwzWordpadLong, lpwzWordpadShort, MAX_PATH);
if (cchValue == 0 || cchValue > MAX_PATH)
{
goto AllDone;
}
if (FAILED(StringCchPrintf(lpwzWordpadOpen, MAX_PATH,L"%s \"%%1\"", lpwzWordpadShort)) ||
FAILED(StringCchPrintf(lpwzWordpadPrint, MAX_PATH, L"%s /p \"%%1\"",lpwzWordpadShort)) ||
FAILED(StringCchPrintf(lpwzWordpadPrintTo, MAX_PATH,L"%s /pt \"%%1\" \"%%2\" \"%%3\" \"%%4\"", lpwzWordpadShort)))
{
goto AllDone;
}
#define WORDPAD_OPEN ((LPBYTE)lpwzWordpadOpen)
#define WORDPAD_PRINT ((LPBYTE)lpwzWordpadPrint)
#define WORDPAD_PRINTTO ((LPBYTE)lpwzWordpadPrintTo)
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKCR\\rtffile\\shell\\open\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
key = VRegistry.AddKey(L"HKCR\\rtffile\\shell\\print\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
key = VRegistry.AddKey(L"HKCR\\rtffile\\shell\\printto\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
key = VRegistry.AddKey(L"HKCR\\Wordpad.Document.1\\shell\\open\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
key = VRegistry.AddKey(L"HKCR\\Wordpad.Document.1\\shell\\print\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
key = VRegistry.AddKey(L"HKCR\\Wordpad.Document.1\\shell\\printto\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
key = VRegistry.AddKey(L"HKCR\\wrifile\\shell\\open\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
key = VRegistry.AddKey(L"HKCR\\wrifile\\shell\\print\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
key = VRegistry.AddKey(L"HKCR\\wrifile\\shell\\printto\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Applications\\wordpad.exe\\shell\\open\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Applications\\wordpad.exe\\shell\\print\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Applications\\wordpad.exe\\shell\\printto\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\rtffile\\shell\\open\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\rtffile\\shell\\print\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\rtffile\\shell\\printto\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Wordpad.Document.1\\shell\\open\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Wordpad.Document.1\\shell\\print\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Wordpad.Document.1\\shell\\printto\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\wrifile\\shell\\open\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\wrifile\\shell\\print\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\wrifile\\shell\\printto\\command");
if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
AllDone:
free(lpwzWordpadOpen);
free(lpwzWordpadPrint);
free(lpwzWordpadPrintTo);
free(lpwzWordpadShort);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
This is a REG_BINARY on win9x
History:
07/18/2000 linstev Created
--*/
void
BuildAutoRun(char* /*szParam*/)
{
#define AUTORUN_KEY HKEY_CURRENT_USER
#define AUTORUN_SUBKEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"
HKEY hkBase;
if (FAILURE(RegOpenKeyExW(
AUTORUN_KEY,
AUTORUN_SUBKEY,
0,
KEY_READ,
&hkBase)))
{
return;
}
DWORD dwValue;
DWORD dwSize = sizeof(DWORD);
if (SUCCESS(RegQueryValueExW(hkBase, L"NoDriveTypeAutoRun", 0, 0, (LPBYTE)&dwValue, &dwSize)))
{
LPWSTR wzPath;
VIRTUALKEY *vkey;
// Convert the KEY and SUBKEY into a path we can use for the vregistry
wzPath = MakePath(AUTORUN_KEY, 0, AUTORUN_SUBKEY);
if (wzPath)
{
vkey = VRegistry.AddKey(wzPath);
if (vkey)
{
vkey->AddValue(L"NoDriveTypeAutoRun", REG_BINARY, (LPBYTE)&dwValue, sizeof(DWORD));
}
free(wzPath);
}
}
RegCloseKey(hkBase);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add SharedDir value to HKLM\Software\Microsoft\Windows\CurrentVersion\Setup
The SharedDir in this case is just the windows directory (as it was on 9x).
History:
12/28/2000 a-brienw Created
--*/
void
BuildTalkingDictionary(char* /*szParam*/)
{
VIRTUALKEY *key;
WCHAR szWindowsDir[MAX_PATH];
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
if (key)
{
DWORD cchSize = GetWindowsDirectoryW( (LPWSTR)szWindowsDir, MAX_PATH);
if (cchSize != 0 && cchSize <= MAX_PATH)
key->AddValue(L"SharedDir", REG_SZ, (LPBYTE)szWindowsDir);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add a ProductName value to every network card description as on NT 4. The
product name in this case is just the first 8 characters of the
description.
History:
01/18/2000 linstev Created
03/01/2001 prashkud Added NetBT\Adapter key and the corresponding values
--*/
void
BuildNetworkCards(char* /*szParam*/)
{
#define NETCARD_KEY HKEY_LOCAL_MACHINE
#define NETCARD_SUBKEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"
#define NETBT_SUBKEY L"System\\CurrentControlSet\\Services\\NetBT"
// For NetBT
LPWSTR wzNetBTPath;
WCHAR wAdapter[MAX_PATH];
VIRTUALKEY *vkAdapter = NULL;
HKEY hkNetBT;
if (FAILURE(RegOpenKeyExW(
NETCARD_KEY,
NETBT_SUBKEY,
0,
KEY_READ,
&hkNetBT)))
{
DPFN( eDbgLevelError, "Failed to add NetBT settings");
return;
}
if (FAILED(StringCchCopy(wAdapter, MAX_PATH, NETBT_SUBKEY)))
{
RegCloseKey(hkNetBT);
return;
}
if (FAILED(StringCchCat(wAdapter, MAX_PATH, L"\\Adapters")))
{
RegCloseKey(hkNetBT);
return;
}
// Make this a Virtual path
wzNetBTPath = MakePath(NETCARD_KEY, 0, wAdapter);
if (!wzNetBTPath)
{
DPFN( eDbgLevelError, "Failed to make NetBT path");
RegCloseKey(hkNetBT);
return;
}
// Adding the Adapters subkey to NetBT
vkAdapter = VRegistry.AddKey(wzNetBTPath);
free(wzNetBTPath);
HKEY hkBase;
// Check for network cards
if (FAILURE(RegOpenKeyExW(
NETCARD_KEY,
NETCARD_SUBKEY,
0,
KEY_READ,
&hkBase)))
{
DPFN( eDbgLevelError, "Failed to add Network card registry settings");
return;
}
LPWSTR wzPath;
VIRTUALKEY *netkey;
// Convert the KEY and SUBKEY into a path we can use for the vregistry
wzPath = MakePath(NETCARD_KEY, 0, NETCARD_SUBKEY);
netkey = wzPath ? VRegistry.AddKey(wzPath) : NULL;
if (wzPath && netkey)
{
// Enumerate the keys and add them to the virtual registry
DWORD dwIndex = 0;
WCHAR wName[MAX_PATH];
while (SUCCESS(RegEnumKeyW(
hkBase,
dwIndex,
wName,
MAX_PATH)))
{
HKEY hKey;
VIRTUALKEY *keyn;
WCHAR wTemp[MAX_PATH];
keyn = netkey->AddKey(wName);
if (!keyn)
{
break;
}
if (SUCCEEDED(StringCchCopy(wTemp, MAX_PATH, NETCARD_SUBKEY)) &&
SUCCEEDED(StringCchCat(wTemp, MAX_PATH, L"\\")) &&
SUCCEEDED(StringCchCat(wTemp, MAX_PATH,wName)))
{
// Open the actual key
if (SUCCESS(RegOpenKeyExW(
NETCARD_KEY,
wTemp,
0,
KEY_READ,
&hKey)))
{
WCHAR wDesc[MAX_PATH];
WCHAR wServName[MAX_PATH];
DWORD dwSize = MAX_PATH;
// check for description
if (SUCCESS(RegQueryValueExW(
hKey,
L"Description",
0,
0,
(LPBYTE)wDesc,
&dwSize)))
{
// Max out at 8 characters
wDesc[8] = L'\0';
keyn->AddValue(L"ProductName", REG_SZ, (LPBYTE)wDesc);
}
// Query for the ServiceName Value
dwSize = MAX_PATH;
if (SUCCESS(RegQueryValueExW(
hKey,
L"ServiceName",
0,
0,
(LPBYTE)wServName,
&dwSize)))
{
if (vkAdapter)
{
if (!vkAdapter->AddKey(wServName))
{
DPFN( eDbgLevelError, "Error adding the Key to NetBT");
}
}
}
RegCloseKey(hKey);
}
}
dwIndex++;
}
}
free(wzPath);
RegCloseKey(hkBase);
RegCloseKey(hkNetBT);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add NT4 SP5 Credentials.
History:
05/23/2000 linstev Created
--*/
void
BuildNT4SP5(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
if (key)
{
key->AddValue(L"CSDVersion", REG_SZ, (LPBYTE)L"Service Pack 5");
}
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
if (key)
{
key->AddValue(L"CurrentVersion", REG_SZ, (LPBYTE)L"4.0");
}
key = VRegistry.AddKey(L"HKLM\\System\\CurrentControlSet\\Control\\Windows");
if (key)
{
key->AddValueDWORD(L"CSDVersion", 0x0500);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add Win2k version number
History:
05/22/2001 linstev Created
--*/
void
BuildNT50(char* /*szParam*/)
{
VIRTUALKEY *key;
// Add Win2k version number
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
if (key)
{
key->AddValue(L"CurrentVersion", REG_SZ, (LPBYTE)L"5.0");
key->AddValue(L"ProductName", REG_SZ, (LPBYTE)L"Microsoft Windows 2000");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add WinXP version number
History:
05/01/2002 linstev Created
--*/
void
BuildNT51(char* /*szParam*/)
{
VIRTUALKEY *key;
// Add Win2k version number
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
if (key)
{
key->AddValue(L"CurrentVersion", REG_SZ, (LPBYTE)L"5.1");
key->AddValue(L"ProductName", REG_SZ, (LPBYTE)L"Microsoft Windows XP");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
This function adds the Shell compatibility flag for apps that need the
bogus Ctrl ID of IDOK for ToolBarWindows32 class.
This also gets applied through the Win2K layer as this is a regression from
Win2K.
History:
05/04/2001 prashkud Created
--*/
void
BuildBogusCtrlID(char* /*szParam*/)
{
CSTRING_TRY
{
WCHAR wszFileName[MAX_PATH];
CString csFileName, csFileTitle;
CString csRegPath(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Applications");
VIRTUALKEY *Key;
if (GetModuleFileName(NULL, wszFileName, MAX_PATH))
{
csFileName = wszFileName;
csFileName.GetLastPathComponent(csFileTitle);
csRegPath.AppendPath(csFileTitle);
Key = VRegistry.AddKey(csRegPath.Get());
if (Key)
{
Key->AddValue(L"FILEOPENBOGUSCTRLID", REG_SZ, 0, 0);
LOGN(eDbgLevelInfo, "Added FILEOPENBOGUSCTRLID value for app %S", csFileTitle.Get());
}
}
}
CSTRING_CATCH
{
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Known different values from Win9x.
History:
05/04/2000 linstev Created
--*/
void
BuildExpanders(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion");
if (key)
{
// These are REG_EXPAND_SZ on NT and REG_SZ on Win9x
key->AddExpander(L"DevicePath");
key->AddExpander(L"ProgramFilesPath");
key->AddExpander(L"WallPaperDir");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add DX7a Credentials.
History:
05/23/2000 linstev Created
--*/
void
BuildDX7A(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\DirectX");
if (key)
{
key->AddValue(L"Version", REG_SZ, (LPBYTE)L"4.07.00.0716");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add DXDIAG path.
History:
04/05/2001 mnikkel Created
--*/
void
BuildDXDiag(char* /*szParam*/)
{
VIRTUALKEY *key;
WCHAR wszPathDir[MAX_PATH];
DWORD cchSize = GetSystemDirectoryW(wszPathDir, MAX_PATH);
if (cchSize == 0 || cchSize > MAX_PATH)
{
DPFN( eDbgLevelError, "BuildDXDiag: GetSystemDirectory Failed");
return;
}
if (FAILED(StringCchCat(wszPathDir, MAX_PATH, L"\\dxdiag.exe")))
{
return;
}
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\DXDIAG.EXE");
if (key)
{
key->AddValue(L"", REG_EXPAND_SZ, (LPBYTE)wszPathDir, 0);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Add FullScreen == 1 to fix bug in Future Cop that makes it not always run
in fullscreen mode.
History:
09/01/2000 linstev Created
--*/
void
BuildFutureCop(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKLM\\Software\\Electronic Arts\\Future Cop\\Settings");
if (key)
{
key->AddValueDWORD(L"FullScreen", 0x01);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Return to Krondor attempts to find ACM drivers, this key was moved and renamed.
Was: HKLM\System\CurrentControlSet\Control\MediaResources\ACM\MSACM.MSADPCM\drivers = msadp32.acm
Is: HKLM\Software\Microsoft\Windows NT\CurrentVersion\Drivers32\Msacm.Msadpcm = msadp32.acm
Grab the current value from the registry, and build a virtual key and value
History:
09/06/2000 robkenny Created
--*/
void
BuildKrondor(char* /*szParam*/)
{
HKEY msadpcmKey;
LONG error = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32",
0, KEY_READ, &msadpcmKey);
if (SUCCESS(error))
{
// Found the key, grab the name of the driver
WCHAR driverName[MAX_PATH];
DWORD driverNameSize = sizeof(driverName);
DWORD driverNameType = REG_SZ;
error = RegQueryValueExW(
msadpcmKey,
L"MSACM.MSADPCM",
0, &driverNameType,
(LPBYTE)driverName,
&driverNameSize);
if (SUCCESS(error))
{
// We got all the data, so we can now add the virtual key and value
VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\System\\CurrentControlSet\\Control\\MediaResources\\ACM\\MSACM.MSADPCM");
if (key)
{
key->AddValue(L"driver", REG_SZ, (LPBYTE)driverName, 0);
}
}
RegCloseKey(msadpcmKey);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Redirect changes from CURRENT_USER to LOCAL_MACHINE.
History:
09/17/2000 linstev Created
--*/
void
BuildProfile(char* /*szParam*/)
{
VRegistry.AddRedirect(
L"HKCU\\Software\\Microsoft\\Windows",
L"HKLM\\Software\\Microsoft\\Windows");
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
In Spell it Deluxe setup, the path for the SpeechFonts DLL ECN_1K8.DLL is
hardcoded to " C:\Voices32". If the installation is on a D: partition, the
LoadLibraryA( ) call fails and the App AV's.
Now the current partition drive will be taken and added to the path.
History:
09/21/2000 prashkud Created
--*/
void
BuildSpellItDeluxe(char* /*szParam*/)
{
HKEY hSpeechFonts;
WCHAR wszSystemDir[MAX_PATH], wszPathDir[MAX_PATH];
if (GetSystemDirectory(wszSystemDir, MAX_PATH))
{
*(wszSystemDir+3) = L'\0';
}
else
{
DPFN( eDbgLevelError, "SpellIt: GetSystemDirectory Failed");
return;
}
if (FAILED(StringCchCopy(wszPathDir, MAX_PATH, wszSystemDir)))
{
return;
}
if (FAILED(StringCchCat(wszPathDir, MAX_PATH, L"Voices32")))
{
return;
}
LONG error = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"Software\\FirstByte\\ProVoice\\SpeechFonts",
0, KEY_READ | KEY_WRITE, &hSpeechFonts);
if (SUCCESS(error))
{
if (FAILED(RegSetValueExW(
hSpeechFonts,
L"Path",
0,
REG_SZ,
(LPBYTE) wszPathDir,
wcslen(wszPathDir) * sizeof(WCHAR))))
{
DPFN( eDbgLevelError, "SpellIt: RegSetValueEx failed");
}
RegCloseKey(hSpeechFonts);
}
else
{
DPFN( eDbgLevelError, "SpellIt: RegOpenKeyExW failed");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Some applications need internet explorer for their functionality. The
applications try get the version of the internet explorer from the following
registry key : HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion. But
under WHISTLER environment, the key entry will not be created. So, the apps
fail to continue.
The app looks for the version info of the Internet Explorer in the registry
at HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion from the "Plus!
VersionNumber" Key. In WHISTLER the key will not be created in the registry.
To solve the problem we use Virtual Registry Keys. So, the app will assume
the key is existing in the registry.
WHISTLER, by default, will install I.E.6. So, I have created the key as
"IE 6 6.0.2404.0000" and this is the latest version of I.E. on WHISTLER as
on today.(11/22/2000).
History:
11/22/2000 v-rbabu Created
07/03/2001 linstev Added IE 5.5 from Win2k
--*/
void
BuildIE401(char* /*szParam*/)
{
VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Internet Explorer");
if (key)
{
key->AddValue(L"Version", REG_SZ, (LPBYTE)L"4.72.2106.9", 0);
}
}
void
BuildIE55(char* /*szParam*/)
{
VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Internet Explorer");
if (key)
{
key->AddValue(L"Version", REG_SZ, (LPBYTE)L"5.50.4522.1800", 0);
}
}
void
BuildIE60(char* /*szParam*/)
{
WCHAR wIE[] = L"IE 6 6.0.2404.0000";
// Now add the virtual key and value
VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
if (key)
{
key->AddValue(L"Plus! VersionNumber", REG_SZ, (LPBYTE)wIE, 0);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
The idea here is to fix apps that depend on short names for input devices.
We just trim the name to 32 characters (including terminator).
History:
12/06/2000 linstev Created
--*/
void
BuildJoystick(char* /*szParam*/)
{
HKEY hJoystickKey;
WCHAR wszKeyName[MAX_PATH];
DWORD dwIndex;
const WCHAR wszJoystickPath[] = L"System\\CurrentControlSet\\Control\\MediaProperties\\PrivateProperties\\Joystick\\OEM";
if (FAILURE(RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszJoystickPath, 0, KEY_READ, &hJoystickKey)))
{
DPFN( eDbgLevelSpew, "[Joystick hack] No joysticks found");
return;
}
//
// Enum the keys under Joystick and make virtual entries
//
dwIndex = 0;
while (SUCCESS(RegEnumKeyW(hJoystickKey, dwIndex, wszKeyName, MAX_PATH)))
{
WCHAR wszID[MAX_PATH] = L"HKLM\\";
if (SUCCEEDED(StringCchCat(wszID, MAX_PATH, wszJoystickPath)) &&
SUCCEEDED(StringCchCat(wszID, MAX_PATH, L"\\")) &&
SUCCEEDED(StringCchCat(wszID, MAX_PATH, wszKeyName)))
{
HKEY hkOEM;
if (SUCCESS(RegOpenKeyExW(hJoystickKey, wszKeyName, 0, KEY_READ, &hkOEM)))
{
WCHAR wszName[MAX_PATH + 1];
DWORD dwSize = MAX_PATH * sizeof(WCHAR);
if (SUCCESS(RegQueryValueExW(hkOEM, L"OEMName", 0, NULL, (LPBYTE) wszName, &dwSize)))
{
if (dwSize > 31 * sizeof(WCHAR))
{
VIRTUALKEY *key = VRegistry.AddKey(wszID);
if (key)
{
dwSize = 31 * sizeof(WCHAR);
wszName[31] = L'\0';
key->AddValue(L"OEMName", REG_SZ, (LPBYTE) wszName);
}
}
}
RegCloseKey(hkOEM);
}
}
dwIndex++;
}
RegCloseKey(hJoystickKey);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Hack for Adobe Illustrator 8
History:
12/18/2000 linstev Created
--*/
void
BuildIllustrator8(char* /*szParam*/)
{
if (ShouldApplyShim())
{
// Redirect everything
VRegistry.AddRedirect(
L"HKLM\\Software\\Adobe",
L"HKCU\\Software\\Adobe");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Hack for Adobe PageMaker 6.5
History:
02/27/2001 maonis Created
--*/
void BuildPageMaker65(char* /*szParam*/)
{
if (ShouldApplyShim())
{
VRegistry.AddRedirect(
L"HKCU\\Software\\Adobe\\PageMaker65",
L"HKLM\\Software\\Adobe\\PageMaker65");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Hack for PageKeepPro30.
History:
01/15/2000 maonis Created
--*/
void
BuildPageKeepProDirectory(char* /*szParam*/)
{
// We cannot call ShGetSpecialFolderPath since we are still in our DLL main,
// so we get the path to "My Documents" directly from the registry.
HKEY hkFolders;
if (SUCCESS(RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hkFolders)))
{
DWORD dwType;
WCHAR wszPath[MAX_PATH];
DWORD dwSize = MAX_PATH*sizeof(WCHAR);
if (SUCCESS(RegQueryValueExW( hkFolders, L"Personal", NULL, &dwType, (LPBYTE)wszPath, &dwSize)))
{
VIRTUALKEY *key = VRegistry.AddKey(L"HKCU\\Software\\Caere Corp\\PageKeepPro30\\Preference");
if (key)
{
key->AddValue(L"Directory", REG_EXPAND_SZ, (LPBYTE)wszPath, 0);
}
}
RegCloseKey(hkFolders);
}
// Secondly, since we don't support using UI-less mode for TWAIN layer
// we mandatorily set BASICMODE for scanners to 2 instead of 0 - 2 means
// to always use UI mode.
HKEY hkScanners;
WCHAR wszKeyName[MAX_PATH] = L"";
DWORD dwIndex;
const WCHAR wszScanner[] = L"Software\\Caere Corp\\Scan Manager\\4.02\\Scanners";
if (FAILURE(RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszScanner,0, KEY_READ, &hkScanners)))
{
DPFN( eDbgLevelSpew, "[PageKeepPro 3.0] No scanner found");
return;
}
dwIndex = 0;
while (SUCCESS(RegEnumKeyW(hkScanners, dwIndex, wszKeyName, MAX_PATH)))
{
WCHAR wszID[MAX_PATH] = L"HKLM\\";
if (SUCCEEDED(StringCchCat(wszID, MAX_PATH,wszScanner)) &&
SUCCEEDED(StringCchCat(wszID, MAX_PATH,L"\\")) &&
SUCCEEDED(StringCchCat(wszID, MAX_PATH,wszKeyName)))
{
HKEY hkScanner;
if (SUCCESS(RegOpenKeyExW(hkScanners, wszKeyName, 0, KEY_READ, &hkScanner)))
{
VIRTUALKEY *keyMode = VRegistry.AddKey(wszID);
if (keyMode)
{
keyMode->AddValueDWORD(L"BASICMODE", 2);
}
RegCloseKey(hkScanner);
}
}
dwIndex++;
}
RegCloseKey(hkScanners);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Hack for ModemWizard because the keys moved
History:
01/18/2001 linstev & a-leelat Created
--*/
void
BuildModemWizard(char* /*szParam*/)
{
// Redirect everything
VRegistry.AddRedirect(
L"HKLM\\SYSTEM\\CurrentControlSet\\Enum\\Root",
L"HKLM\\SYSTEM\\CurrentControlSet\\Enum");
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Hack for Office2000 Developer 1.5 which looks in the wrong place for
components.
From ChetanP:
Basically the redirect code would have to do something like this -
if HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\<user sid>\Components\359E92CC2CB71D119A12000A9CE1A22A
exists, redirect to that location
else if HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\359E92CC2CB71D119A12000A9CE1A22A
exists, redirect to that location
else, no redirection.
Whistler Bug #241596
History:
02/01/2001 linstev Created
--*/
#define SIZE_OF_TOKEN_INFORMATION \
sizeof(TOKEN_USER) + \
sizeof(SID) + \
sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES
#define SIZE_OF_SID_MAX \
sizeof(SID) + \
SID_MAX_SUB_AUTHORITIES * sizeof(DWORD)
#define cchMaxSID 256
//
// Get the current SID as text
//
BOOL
GetStringSID(
WCHAR *szSID
)
{
BOOL bRet = TRUE;
HANDLE hToken = NULL;
int i;
PISID pISID;
UCHAR rgSID[SIZE_OF_SID_MAX];
UCHAR TokenInformation[SIZE_OF_TOKEN_INFORMATION];
ULONG ReturnLength;
WCHAR Buffer[cchMaxSID];
//
// Get a token
//
if (!OpenThreadToken(
GetCurrentThread(),
TOKEN_IMPERSONATE | TOKEN_QUERY,
TRUE,
&hToken))
{
if (GetLastError() == ERROR_NO_TOKEN)
{
bRet = OpenProcessToken(
GetCurrentProcess(),
TOKEN_IMPERSONATE | TOKEN_QUERY,
&hToken);
}
else
{
bRet = FALSE;
}
}
if (!bRet)
{
DPFN( eDbgLevelError, "[GetStringSID] Failed to OpenProcessToken");
goto Exit;
}
//
// Get the binary form of the token
//
bRet = GetTokenInformation(
hToken,
TokenUser,
TokenInformation,
sizeof(TokenInformation),
&ReturnLength);
if (bRet)
{
bRet = FALSE;
pISID = (PISID)((PTOKEN_USER) TokenInformation)->User.Sid;
if (!CopySid(SIZE_OF_SID_MAX, rgSID, pISID))
{
DPFN( eDbgLevelError, "CopySID failed");
goto Exit;
}
//
// Get the text form of the token
//
HRESULT hr = StringCchPrintf(Buffer, cchMaxSID,L"S-%u-", (USHORT) pISID->Revision);
if (FAILED(hr))
{
goto Exit;
}
hr = StringCchCopy(szSID, 1024, Buffer);
if (FAILED(hr))
{
goto Exit;
}
if ((pISID->IdentifierAuthority.Value[0] != 0) ||
(pISID->IdentifierAuthority.Value[1] != 0))
{
hr = StringCchPrintf(Buffer, cchMaxSID,
L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
(USHORT) pISID->IdentifierAuthority.Value[0],
(USHORT) pISID->IdentifierAuthority.Value[1],
(USHORT) pISID->IdentifierAuthority.Value[2],
(USHORT) pISID->IdentifierAuthority.Value[3],
(USHORT) pISID->IdentifierAuthority.Value[4],
(USHORT) pISID->IdentifierAuthority.Value[5]);
if (FAILED(hr))
{
goto Exit;
}
hr = StringCchCat(szSID, 1024, Buffer);
if (FAILED(hr))
{
goto Exit;
}
}
else
{
ULONG Tmp =
(ULONG) pISID->IdentifierAuthority.Value[5] +
(ULONG)(pISID->IdentifierAuthority.Value[4] << 8) +
(ULONG)(pISID->IdentifierAuthority.Value[3] << 16) +
(ULONG)(pISID->IdentifierAuthority.Value[2] << 24);
hr = StringCchPrintf(Buffer, cchMaxSID, L"%lu", Tmp);
if (FAILED(hr))
{
goto Exit;
}
hr = StringCchCat(szSID, 1024, Buffer);
if (FAILED(hr))
{
goto Exit;
}
}
for (i=0; i < pISID->SubAuthorityCount; i++)
{
hr = StringCchPrintf(Buffer, cchMaxSID, L"-%lu", pISID->SubAuthority[i]);
if (FAILED(hr))
{
goto Exit;
}
hr = StringCchCat(szSID, 1024, Buffer);
if (FAILED(hr))
{
goto Exit;
}
}
}
else
{
DPFN( eDbgLevelError, "GetTokenInformation failed");
goto Exit;
}
bRet = TRUE;
Exit:
if (hToken)
{
CloseHandle(hToken);
}
return bRet;
}
void
BuildMSI(char* /*szParam*/)
{
WCHAR szSID[1024];
// Get the current users SID as a string
if (!GetStringSID(szSID))
{
DPFN( eDbgLevelError, "BuildMSI Failed");
return;
}
HKEY hKey;
WCHAR szTemp[1024];
const WCHAR szBase[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\";
const WCHAR szComp[] = L"\\Components\\359E92CC2CB71D119A12000A9CE1A22A";
HRESULT hr;
hr = StringCchCopy(szTemp, 1024, szBase);
if (FAILED(hr))
{
return;
}
hr = StringCchCat(szTemp, 1024, szSID);
if (FAILED(hr))
{
return;
}
hr = StringCchCat(szTemp, 1024, szComp);
if (FAILED(hr))
{
return;
}
// Attempt to open szBase + <user sid> + szComp
if (RegOpenKeyW(HKEY_LOCAL_MACHINE, szTemp, &hKey) != ERROR_SUCCESS)
{
RegCloseKey(hKey);
// Attempt to open szBase + S-1-5-18 + szComp
hr = StringCchCopy(szTemp, 1024, szBase);
if (FAILED(hr))
{
return;
}
hr = StringCchCat(szTemp, 1024, L"S-1-5-18");
if (FAILED(hr))
{
return;
}
hr = StringCchCat(szTemp, 1024, szComp);
if (FAILED(hr))
{
return;
}
if (RegOpenKeyW(HKEY_LOCAL_MACHINE, szTemp, &hKey) != ERROR_SUCCESS)
{
DPFN( eDbgLevelError, "BuildMSI Failed to find keys");
RegCloseKey(hKey);
return;
}
}
// Redirect as appropriate
WCHAR szTarget[1024] = L"HKLM\\";
hr = StringCchCat(szTarget,1024, szTemp);
if (FAILED(hr))
{
return;
}
VRegistry.AddRedirect(
L"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components\\359E92CC2CB71D119A12000A9CE1A22A",
szTarget);
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Added FileNet Web Server
History:
02/06/2001 a-larrsh Created
--*/
void
BuildFileNetWebServer(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKLM\\System\\CurrentControlSet\\Services\\W3SVC\\Parameters");
if (key)
{
key->AddValueDWORD(L"MajorVersion", 0x00000005);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Added default printer key. We have to effectively delay load this, because
we can't be guaranteed that winspool will have had it's init routine loaded
before us. Of course, we still can't guarentee that somebody won't try to
get at this key from their dllmain, so we wrap the whole thing in an
exception handler.
History:
02/06/2001 linstev & mnikkel Created
--*/
LONG
WINAPI
VR_Printer(
OPENKEY * /* key */,
VIRTUALKEY * /* vkey */,
VIRTUALVAL *vvalue
)
{
LOGN( eDbgLevelInfo, "[Printer] Query for legacy printer");
__try
{
DWORD dwSize;
// Get the default printer name
if (GetDefaultPrinterW(NULL, &dwSize) == 0)
{
// Now that we have the right size, allocate a buffer
if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
LPWSTR pszName = (LPWSTR) malloc(dwSize * sizeof(WCHAR));
if (pszName)
{
// Now get the default printer with the right buffer size.
if (GetDefaultPrinterW(pszName, &dwSize))
{
//
// Set up the virtual value. Note we don't have free the
// memory since it's a once off allocation that persists
// with the value
//
vvalue->cbData = dwSize * sizeof(WCHAR);
vvalue->lpData = (LPBYTE) pszName;
//
// Never call us again, since we've found the printer and
// stored it in our virtual value
//
vvalue->pfnQueryValue = NULL;
return ERROR_SUCCESS;
}
else
{
//
// We failed to get the default printer, may as well
// clean up gracefully.
//
free(pszName);
}
}
}
}
DPFN( eDbgLevelError, "[Printer] No printers found or out of memory");
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DPFN( eDbgLevelError, "[Printer] Exception encountered, winspool not initialized?");
}
//
// Going for the graceful exit: there's no default printer or we get an
// error trying to find it.
//
return ERROR_FILE_NOT_FOUND;
}
void
BuildPrinter(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKCC\\System\\CurrentControlSet\\Control\\Print\\Printers");
if (key)
{
VIRTUALVAL *val = key->AddValue(L"Default", REG_SZ, 0, 0);
if (val)
{
val->pfnQueryValue = VR_Printer;
}
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
The app is multi-threaded, but the app sets the DX DDSCL_MULTITHREADED flag
too late: after D3D is initialized. This hack basically turns on
multi-threaded locking for D3D.
History:
02/27/2001 rankala + ssteiner Created
--*/
void
BuildStarTrekArmada(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKLM\\SOFTWARE\\Microsoft\\Direct3D");
if (key)
{
key->AddValueDWORD(L"DisableST", 1);
}
}
/*++
Function Description:
This function gets called whenever the app queries for "Health" value.This
is not set properly by the app and this causes the app not to function
properly. We fix this issue by obtaining the right path which the app sets
in another registry key and sending that back as the value for "Health".
History:
05/04/2001 prashkud Created
--*/
LONG
WINAPI
VR_MSA2001(
OPENKEY * /* key */,
VIRTUALKEY * /* vkey */,
VIRTUALVAL *vvalue
)
{
HKEY hPath = NULL;
LONG lRet = ERROR_SUCCESS;
CSTRING_TRY
{
CString csBody5Reg(L"Software\\Classes\\Body5\\Open\\Shell\\Command");
WCHAR wPath[MAX_PATH];
DWORD dwSize = MAX_PATH*sizeof(WCHAR);
if (FAILURE(lRet = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
csBody5Reg.Get(),
0, KEY_READ, &hPath)))
{
DPFN(eDbgLevelError, "MSA2001: RegOpenKeyExW failed");
goto exit;
}
if (FAILURE( lRet = RegQueryValueExW(
hPath, L"", // Default value
0, NULL, (LPBYTE)wPath, &dwSize)))
{
DPFN(eDbgLevelError, "MSA2001: RegQueryValueEx failed");
goto exit;
}
CString csPath(wPath);
int len = csPath.Find(L" ");
// We get the space in the string
wPath[len] = L'\0';
csPath = wPath;
CString csPathName;
csPath.GetNotLastPathComponent(csPathName);
vvalue->cbData = (csPathName.GetLength()+1) * sizeof(WCHAR);
vvalue->lpData = (LPBYTE) malloc(vvalue->cbData);
if (!vvalue->lpData)
{
DPFN(eDbgLevelError, szOutOfMemory);
lRet = ERROR_NOT_ENOUGH_MEMORY;
goto exit;
}
MoveMemory(vvalue->lpData, csPathName.Get(), vvalue->cbData);
DPFN(eDbgLevelInfo, "MSA2001: The data value is %S",csPathName.Get());
lRet = ERROR_SUCCESS;
vvalue->dwType = REG_SZ;
return lRet;
}
CSTRING_CATCH
{
}
exit:
if (hPath)
{
RegCloseKey(hPath);
}
return lRet;
}
/*++
Function Description:
History:
04/27/2001 prashkud Created
--*/
void
BuildMSA2001(char* /*szParam*/)
{
VIRTUALKEY *Key = VRegistry.AddKey(L"HKLM\\Software\\Encore Software\\Middle School Advantage 2001\\1.0");
if (Key)
{
VIRTUALVAL *val = Key->AddValue(L"health", REG_SZ, 0, 0);
if (val)
{
val->pfnQueryValue = VR_MSA2001;
DPFN(eDbgLevelInfo, "[Middle School Advantage 2001] Added Health");
}
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Hack for Nowro Blue (Korean App)
History:
05/17/2001 hioh Created
--*/
void BuildNowroBlue(char* /*szParam*/)
{
// Below HKCU include location of files.
// Non install user could not locate files and could not run app properly.
// Redirect from HKCU to HKLM for commonly use.
VRegistry.AddRedirect(
L"HKCU\\Software\\nowcom",
L"HKLM\\Software\\nowcom");
VRegistry.AddRedirect(
L"HKCU\\Software\\nowirc",
L"HKLM\\Software\\nowirc");
VRegistry.AddRedirect(
L"HKCU\\Software\\nownuri",
L"HKLM\\Software\\nownuri");
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
To enable the trial version, WebWasher looks for RegisteredOrganization at:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
rather than:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
History:
05/31/2001 stevepro Created
--*/
void
BuildRegisteredOwner(char* /*szParam*/)
{
HKEY hkCurrentVersion;
if (FAILURE(RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"Software\\Microsoft\\Windows NT\\CurrentVersion",
0,
KEY_READ,
&hkCurrentVersion)))
{
return;
}
// Read the registered owner values from the old location
WCHAR szOrg[MAX_PATH];
*szOrg = L'\0';
DWORD dwSize = ARRAYSIZE(szOrg);
if (FAILURE(RegQueryValueExW(
hkCurrentVersion,
L"RegisteredOrganization",
NULL,
NULL,
(LPBYTE)szOrg,
&dwSize)))
{
RegCloseKey(hkCurrentVersion);
return;
}
WCHAR szOwner[MAX_PATH];
*szOwner = L'\0';
dwSize = ARRAYSIZE(szOwner);
if (FAILURE(RegQueryValueExW(
hkCurrentVersion,
L"RegisteredOwner",
NULL,
NULL,
(LPBYTE)szOwner,
&dwSize)))
{
RegCloseKey(hkCurrentVersion);
return;
}
RegCloseKey(hkCurrentVersion);
// Add them as virtual values to the new location
if (*szOrg || *szOwner)
{
VIRTUALKEY *pKey = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion");
if (pKey)
{
if (*szOrg)
{
pKey->AddValue(L"RegisteredOrganization", REG_SZ, (LPBYTE)szOrg);
}
if (*szOwner)
{
pKey->AddValue(L"RegisteredOwner", REG_SZ, (LPBYTE)szOwner);
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
The ACT CD of Princeton review looks for and, if not found, creates an "MSN"
key illegally in the root of HKLM. Win9x allows this, but Win2k does not.
This fix will redirect the program to look in the normal location for this
key.
History:
02/22/2001 a-noahy Created
--*/
void
BuildPrincetonACT(char* /*szParam*/)
{
VRegistry.AddRedirect(
L"HKLM\\MSN",
L"HKLM\\Software\\Microsoft\\MSN");
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Fix for HEDZ which uses the registry to determine the resolution
History:
06/28/2001 linstev Created
--*/
void
BuildHEDZ(char* /*szParam*/)
{
VIRTUALKEY *key;
//
// Add just what this app needs - don't bother with full emulation of this
// part of the registry
//
key = VRegistry.AddKey(L"HKLM\\Config\\0001\\Display\\Settings");
if (key)
{
WCHAR wzRes[10];
DWORD dwCX, dwCY;
key->AddValue(L"BitsPerPixel", REG_SZ, (LPBYTE)L"16");
dwCX = GetSystemMetrics(SM_CXSCREEN);
dwCY = GetSystemMetrics(SM_CYSCREEN);
if (FAILED(StringCchPrintfW(
wzRes, 10, L"%d,%d", dwCX, dwCY)))
{
return;
}
key->AddValue(L"Resolution", REG_SZ, (LPBYTE)wzRes);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Called by BuildAirlineTycoon to recursively search for the key describing a CDROM
History:
08/07/2001 mikrause Created
--*/
void FindCDROMKey(HKEY hKey, CString& csCurrentPath)
{
LONG lRet;
DWORD dwKeyNameSize = MAX_PATH;
WCHAR wszKeyName[MAX_PATH];
HKEY hSubKey;
DWORD dwIndex = 0;
// Recurse into all subkeys.
while( ORIGINAL_API(RegEnumKeyExW)(hKey, dwIndex, wszKeyName, &dwKeyNameSize,
NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
{
lRet = ORIGINAL_API(RegOpenKeyExW)(hKey, wszKeyName, 0, KEY_READ, &hSubKey);
if (lRet == ERROR_SUCCESS)
{
// Add this key to the path
csCurrentPath += L"\\";
csCurrentPath += wszKeyName;
// Check this key's subkeys.
FindCDROMKey(hSubKey, csCurrentPath);
ORIGINAL_API(RegCloseKey)(hSubKey);
// Trim the path back.
int index = csCurrentPath.ReverseFind(L'\\');
csCurrentPath.Truncate(index);
}
dwKeyNameSize = MAX_PATH;
dwIndex++;
}
// Check if this key has a Class value equal to "cdrom"
DWORD dwDataSize;
BYTE pData[MAX_PATH*sizeof(WCHAR)];
DWORD dwType;
dwDataSize = MAX_PATH * sizeof(WCHAR);
lRet = ORIGINAL_API(RegQueryValueExW)(hKey, L"CLASS", NULL, &dwType, pData,
&dwDataSize);
if ( (lRet == ERROR_SUCCESS) && (dwType == REG_SZ)
&& (_wcsicmp((LPWSTR)pData, L"CDROM")==0))
{
// Get location information on the device
WCHAR wszLocationInformation[MAX_PATH];
DWORD dwLocInfoSize = MAX_PATH * sizeof(WCHAR);
lRet = ORIGINAL_API(RegQueryValueExW)(hKey, L"LocationInformation",
NULL, &dwType, (BYTE*)wszLocationInformation, &dwLocInfoSize);
if ( (lRet == ERROR_SUCCESS) && (dwType == REG_SZ))
{
// Create the device name (like "\\?\cdrom0\".
CString csDevice = L"\\\\?\\cdrom";
csDevice += wszLocationInformation;
csDevice += L"\\";
// Find which volume name this is mapped to.
WCHAR wszCDRomMountPoint[50];
if (GetVolumeNameForVolumeMountPoint(csDevice.Get(),
wszCDRomMountPoint, 50))
{
// Find which drive this is mapped to.
WCHAR wszDriveMountPoint[50];
WCHAR wszDrive[] = L"A:\\";
// Find what drive has an identical volume mount point.
for(; wszDrive[0] <= L'Z'; wszDrive[0]++)
{
if (GetVolumeNameForVolumeMountPoint(wszDrive,
wszDriveMountPoint, 50))
{
// Check if the CD-ROM and this disk drive
// map to the same volume.
if (_wcsicmp(wszDriveMountPoint, wszCDRomMountPoint)==0)
{
// Add a value to the CD-ROM key.
VIRTUALKEY* key = VRegistry.AddKey(csCurrentPath);
if (key)
{
// Only use a single letter.
wszDrive[1] = L'\0';
VIRTUALVAL* val =
key->AddValue(L"CurrentDriveLetterAssignment",
REG_SZ, (BYTE*) wszDrive, sizeof(WCHAR));
if (val)
{
DPFN(eDbgLevelInfo,
"[Airline Tycoon]Added drive letter \
%S for %S to PNP data", wszDrive,
csDevice.Get());
}
}
break;
}
}
}
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Fix for Airline Tycoon which uses PNP registry entries to determine the
drive letter assignments for CD-ROM drives.
History:
08/07/2001 mikrause Created
--*/
void
BuildAirlineTycoon(char* /*szParam*/)
{
// Search for CD-ROM keys in the registry.
HKEY hKey;
LONG lRet;
lRet = ORIGINAL_API(RegOpenKeyExW)(HKEY_LOCAL_MACHINE,
L"System\\CurrentControlSet\\Enum", 0, KEY_READ, &hKey);
if (lRet != ERROR_SUCCESS)
{
DPFN(eDbgLevelError, "[AirlineTycoon] Cannot open ENUM key!");
return;
}
// Enumerate subkeys
CString csBasePath = L"HKLM\\System\\CurrentControlSet\\Enum";
FindCDROMKey(hKey, csBasePath);
ORIGINAL_API(RegCloseKey)(hKey);
// Set up so that PNP data is redirected.
BuildDynData("");
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Sets the DirectSound acceleration level the app will be allowed to use.
Arguments:
szParam - Command line of the form: accellevel | device1 | device2 | ...
Accellevel is the device acceleration level, and devices 1 through n
are the devices to apply to.
Accellevel can be: NONE, STANDARD, or FULL
Devices can be: EMULATEDRENDER, KSRENDER, EMULATEDCAPTURE, KSCAPTURE
History:
08/10/2001 mikrause Created
--*/
void
BuildDSDevAccel(
char* szParam)
{
// No Try/Catch needed, already in ParseCommandLine
CStringToken csParam(szParam, "|");
CString csTok;
DWORD dwAccelLevel;
DWORD dwDevices = 0;
if (csParam.GetToken(csTok))
{
if (csTok.CompareNoCase(L"NONE")==0)
{
dwAccelLevel = DSAPPHACK_ACCELNONE;
}
else if (csTok.CompareNoCase(L"STANDARD")==0)
{
dwAccelLevel = DSAPPHACK_ACCELSTANDARD;
}
else if (csTok.CompareNoCase(L"FULL")==0)
{
dwAccelLevel = DSAPPHACK_ACCELFULL;
}
else
{
DPFN(eDbgLevelError, "[DSDEVACCEL] Invalid Acceleration Level %s", csTok.GetAnsi());
return;
}
}
else
{
DPFN(eDbgLevelError, "[DSDEVACCEL] Invalid Parameters");
return;
}
while (csParam.GetToken(csTok))
{
if (csTok.CompareNoCase(L"EMULATEDRENDER")==0)
{
dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
}
else if (csTok.CompareNoCase(L"KSRENDER")==0)
{
dwDevices |= DSAPPHACK_DEV_KSRENDER;
}
else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
}
else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
}
else
{
DPFN(eDbgLevelError, "[DSDEVACCEL] Unknown device %s", csTok.GetAnsi());
}
}
if (dwDevices == 0)
{
DPFN(eDbgLevelError, "[DSDEVACCEL] No devices specified.");
return;
}
if (AddDSHackDeviceAcceleration(dwAccelLevel, dwDevices) == FALSE)
{
DPFN(eDbgLevelError, "[DSDEVACCEL] Unabled to add DirectSound hack");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Makes IDirectSoundBuffer::GetCurrentPosition() tell the app
that the play and write cursors are X milliseconds further
along than they really are.
Arguments:
szParam - Command line of the form: milliseconds
Where milliseconds is the number of milliseconds to pad the cursors.
History:
08/10/2001 mikrause Created
--*/
void
BuildDSPadCursors(
char* szParam)
{
// No Try/Catch needed, already in ParseCommandLine
CString csParam(szParam);
DWORD dwMilliseconds = 0;
dwMilliseconds = atol(csParam.GetAnsi());
if ( dwMilliseconds == 0)
{
DPFN(eDbgLevelWarning, "[DSPADCURSORS] Invalid number of milliseconds");
return;
}
if (AddDSHackPadCursors(dwMilliseconds) == FALSE)
{
DPFN(eDbgLevelError, "[DSPADCURSORS] Unabled to add DirectSound hack");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Caches the positions of the cursors for apps that abuse
IDirectSoundBuffer::GetCurrentPosition().
Arguments:
szParam - Command line of the form: Dev1 | Dev2 | . . .
Devices affected. See BuildDSDevAccel().
History:
08/10/2001 mikrause Created
--*/
void
BuildDSCachePositions(
char* szParam)
{
// No Try/Catch needed, already in ParseCommandLine
CStringToken csParam(szParam, "|");
CString csTok;
DWORD dwDevices = 0;
while (csParam.GetToken(csTok))
{
if (csTok.CompareNoCase(L"EMULATEDRENDER")==0)
{
dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
}
else if (csTok.CompareNoCase(L"KSRENDER")==0)
{
dwDevices |= DSAPPHACK_DEV_KSRENDER;
}
else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
}
else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
}
else
{
DPFN(eDbgLevelError, "[DSCACHEPOSITIONS] Unknown device %s", csTok.GetAnsi());
}
}
if (dwDevices == 0)
{
DPFN(eDbgLevelError, "[DSCACHEPOSITIONS] No devices specified.");
return;
}
if (AddDSHackCachePositions(dwDevices) == FALSE)
{
DPFN(eDbgLevelError, "[DSCACHEPOSITIONS] Unabled to add DirectSound hack");
}
}
/*++
Function Description:
When the app asks for the play cursor, we give it the
write cursor instead. The correct way to stream audio
into a looping dsound buffer is to key off the write cursor,
but some apps (e.g. QuickTime) use the play cursor instead.
This apphacks alleviates them.
Arguments:
szParam - Parameters of the form dev1 | dev2 | . . .
See BuildDSDevAccel() for valid devices.
History:
08/10/2001 mikrause Created
--*/
void
BuildDSReturnWritePos(
char* szParam)
{
// No Try/Catch needed, already in ParseCommandLine
CStringToken csParam(szParam, "|");
CString csTok;
DWORD dwDevices = 0;
while (csParam.GetToken(csTok))
{
if (csTok.CompareNoCase(L"EMULATEDRENDER")==0)
{
dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
}
else if (csTok.CompareNoCase(L"KSRENDER")==0)
{
dwDevices |= DSAPPHACK_DEV_KSRENDER;
}
else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
}
else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
}
else
{
DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] Unknown device %s", csTok.GetAnsi());
}
}
if (dwDevices == 0)
{
DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] No devices specified.");
return;
}
if (AddDSHackReturnWritePos(dwDevices) == FALSE)
{
DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] Unabled to add DirectSound hack");
}
}
/*++
Function Description:
Makes dsound always return a write position which is X
milliseconds ahead of the play position, rather than
the <20>real<61> write position.
Arguments:
szParam - Milliseconds of padding.
History:
08/10/2001 mikrause Created
--*/
void
BuildDSSmoothWritePos(
char* szParam)
{
// No Try/Catch needed, already in ParseCommandLine
CString csParam(szParam);
DWORD dwMilliseconds = 0;
dwMilliseconds = atol(csParam.GetAnsi());
if ( dwMilliseconds == 0)
{
DPFN(eDbgLevelWarning, "[DSSMOOTHWRITEPOS] Invalid number of milliseconds");
return;
}
if (AddDSHackSmoothWritePos(dwMilliseconds) == FALSE)
{
DPFN(eDbgLevelError, "[DSSMOOTHWRITEPOS] Unabled to add DirectSound hack");
}
else
{
DPFN(eDbgLevelInfo, "[DSSMOOTHWRITEPOS] Added DS Hack Smooth Write Pos, %d ms",
dwMilliseconds);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
NortonAntiVirus trys to set the registry value to hide the language bar.
Protecting the registry value.
History:
01/02/2002 mamathas Created
--*/
void BuildNortonAntiVirus(char* /*szParam*/)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKCU\\Software\\Microsoft\\CTF\\LangBar");
if (key)
{
// Block all writes to ShowStatus
key->AddProtector(L"ShowStatus");
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Disabled some category of devices altogether, forces
playback through emulated path.
Arguments:
szParam - Combination of device that this hack applies to, see BuildDSDevAccel().
History:
08/10/2001 mikrause Created
--*/
void
BuildDSDisableDevice(
char* szParam)
{
// No try/catch needed. Already done in ParseCommandLine
CStringToken csParam(szParam, "|");
CString csTok;
DWORD dwDevices = 0;
while (csParam.GetToken(csTok)==TRUE)
{
if (csTok.CompareNoCase(L"EMULATEDRENDER"))
{
dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
}
else if (csTok.CompareNoCase(L"KSRENDER")==0)
{
dwDevices |= DSAPPHACK_DEV_KSRENDER;
}
else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
}
else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
{
dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
}
else
{
DPFN(eDbgLevelError, "[DSDISABLEDEVICE] Unknown device %s", csTok.GetAnsi());
}
}
if (dwDevices == 0)
{
DPFN(eDbgLevelError, "[DSDISABLEDEVICE] No devices specified.");
return;
}
if (AddDSHackDisableDevice(dwDevices) == FALSE)
{
DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] Unabled to add DirectSound hack");
}
}
LONG WINAPI
Delphi5SetValue(
OPENKEY *key,
VIRTUALKEY * /* vkey */,
VIRTUALVAL *vvalue,
DWORD dwType,
const BYTE* pbData,
DWORD cbData)
{
// Only accept attempts to set a valid REG_SZ value.
if (dwType == REG_SZ && !IsBadStringPtrW((PWSTR)pbData, cbData/sizeof(WCHAR)))
{
CSTRING_TRY
{
CString csValue = (PWSTR)pbData;
int idx = csValue.Find(L"InstReg.exe");
if (idx != -1)
{
csValue.Insert(idx + lstrlenW(L"InstReg.exe"), L'\"');
csValue.Insert(0, L'\"');
return RegSetValueExW(key->hkOpen, vvalue->wName, 0, dwType, (BYTE*)csValue.Get(),
(csValue.GetLength()+1)*sizeof(WCHAR));
}
}
CSTRING_CATCH
{
DPFN(eDbgLevelError, "CString exception occured in Delphi5SetValue");
}
}
// Got here, something went wrong. Default o normal RegSetValue
return RegSetValueExW(key->hkOpen, vvalue->wName, 0, dwType, pbData, cbData);
}
void
BuildDelphi5Pro(
char* /* szParam */)
{
VIRTUALKEY *key;
key = VRegistry.AddKey(L"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce");
if (key)
{
key->AddCustomSet(L"BorlandReboot1", Delphi5SetValue);
}
}
///////////////////////////////////////////////////////////////////////////////
/*++
Function Description:
Word Perfect Office Suite 2002 attempts to delete ODBC key during uninstall.
Protecting the registry value.
History:
04/23/2002 garyma Created
--*/
void BuildWordPerfect2002(char* /*szParam*/)
{
VRegistry.AddKeyProtector(L"HKLM\\Software\\ODBC");
}
///////////////////////////////////////////////////////////////////////////////
IMPLEMENT_SHIM_END