3497 lines
102 KiB
C++
3497 lines
102 KiB
C++
/*++
|
||
|
||
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
|
||
08/20/2002 mnikkel Added BuildIBMDirector
|
||
11/13/2002 astritz Added WebSphereSetup
|
||
|
||
--*/
|
||
|
||
#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);
|
||
void BuildIBMDirector(char* szParam);
|
||
void BuildXpLie(char* szParam);
|
||
void BuildXpSp1Lie(char* szParam);
|
||
void BuildWin2kSp2Lie(char* szParam);
|
||
void BuildWin2kSp3Lie(char* szParam);
|
||
void BuildWebSphereSetup(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 },
|
||
{L"IBMDIRECTOR", BuildIBMDirector, eCustom, FALSE, NULL },
|
||
{L"XPLIE", BuildXpLie, eCustom, FALSE, NULL },
|
||
{L"XPSP1LIE", BuildXpSp1Lie, eCustom, FALSE, NULL },
|
||
{L"WIN2KSP2LIE", BuildWin2kSp2Lie, eCustom, FALSE, NULL },
|
||
{L"WIN2KSP3LIE", BuildWin2kSp3Lie, eCustom, FALSE, NULL },
|
||
{L"WEBSPHERESETUP", BuildWebSphereSetup, 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 we found "InstReg.exe" and the string does not begin w/ a quote, then
|
||
// add quotes around the executable name
|
||
if ((idx != -1) && (csValue[0] != L'\"'))
|
||
{
|
||
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 to 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");
|
||
}
|
||
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
/*++
|
||
|
||
Function Description:
|
||
|
||
IBM Director installs twgproc.dll in AppInit_DLLs. This causes a hang
|
||
in login for .net . Protecting the registry value.
|
||
|
||
History:
|
||
|
||
08/20/2002 nikkel Created
|
||
|
||
--*/
|
||
|
||
void BuildIBMDirector(char* /*szParam*/)
|
||
{
|
||
VIRTUALKEY *key;
|
||
|
||
key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows");
|
||
if (key)
|
||
{
|
||
// Block all writes to AppInit_DLLs
|
||
key->AddProtector(L"AppInit_DLLs");
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
/*++
|
||
|
||
Function Description:
|
||
|
||
Change the usual suspects for version lies
|
||
|
||
History:
|
||
|
||
09/05/2002 robkenny Created
|
||
|
||
--*/
|
||
|
||
void
|
||
BuildVersionLie(
|
||
LPCWSTR productName,
|
||
LPCWSTR currentVersion,
|
||
LPCWSTR currentBuildNumber,
|
||
LPCWSTR csdVersion)
|
||
{
|
||
VIRTUALKEY * key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
|
||
if (key)
|
||
{
|
||
key->AddValue(L"ProductName", REG_SZ, (LPBYTE)productName);
|
||
key->AddValue(L"CurrentVersion", REG_SZ, (LPBYTE)currentVersion);
|
||
key->AddValue(L"CurrentBuildNumber", REG_SZ, (LPBYTE)currentBuildNumber);
|
||
key->AddValue(L"CSDVersion", REG_SZ, (LPBYTE)csdVersion);
|
||
}
|
||
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
/*++
|
||
|
||
Function Description:
|
||
|
||
Add WinXP version number
|
||
|
||
History:
|
||
|
||
09/05/2002 robkenny Created
|
||
|
||
--*/
|
||
|
||
void
|
||
BuildXpLie(char* /*szParam*/)
|
||
{
|
||
BuildVersionLie(L"Microsoft Windows XP",
|
||
L"5.1",
|
||
L"2600",
|
||
L"");
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
/*++
|
||
|
||
Function Description:
|
||
|
||
Add WinXP SP1 version number
|
||
|
||
History:
|
||
|
||
09/05/2002 robkenny Created
|
||
|
||
--*/
|
||
|
||
void
|
||
BuildXpSp1Lie(char* /*szParam*/)
|
||
{
|
||
BuildVersionLie(L"Microsoft Windows XP",
|
||
L"5.1",
|
||
L"2600",
|
||
L"Service Pack 1");
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
/*++
|
||
|
||
Function Description:
|
||
|
||
Add Win2K Sp2 version number
|
||
|
||
History:
|
||
|
||
09/05/2002 robkenny Created
|
||
|
||
--*/
|
||
|
||
void
|
||
BuildWin2kSp2Lie(char* szParam)
|
||
{
|
||
BuildVersionLie(L"Microsoft Windows 2000",
|
||
L"5.0",
|
||
L"2165",
|
||
L"Service Pack 2");
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
/*++
|
||
|
||
Function Description:
|
||
|
||
Add Win2K Sp3 version number
|
||
|
||
History:
|
||
|
||
09/05/2002 robkenny Created
|
||
|
||
--*/
|
||
|
||
void
|
||
BuildWin2kSp3Lie(char* szParam)
|
||
{
|
||
BuildVersionLie(L"Microsoft Windows 2000",
|
||
L"5.0",
|
||
L"2165",
|
||
L"Service Pack 3");
|
||
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
/*++
|
||
|
||
Function Description:
|
||
|
||
Add redirector for WebSphere's Setup.
|
||
|
||
History:
|
||
|
||
11/13/2002 astritz Created
|
||
|
||
--*/
|
||
|
||
void
|
||
BuildWebSphereSetup(char* szParam)
|
||
{
|
||
VIRTUALKEY *key;
|
||
|
||
key = VRegistry.AddKey(L"HKLM\\System\\CurrentControlSet\\services\\W3svc\\Parameters");
|
||
if (key)
|
||
{
|
||
DWORD dwValue = 0x5;
|
||
key->AddValueDWORD(L"MajorVersion", 0x5);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////////
|
||
|
||
IMPLEMENT_SHIM_END
|