Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3312 lines
94 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. Custom.cpp
  5. Abstract:
  6. Module to add custom behaviour to virtual registry.
  7. Fixes:
  8. VersionNumber string for Microsoft Playpack
  9. Expanders for DevicePath, ProgramFilesPath and WallPaperDir
  10. Redirectors for screen savers
  11. Virtual HKEY_DYN_DATA structure
  12. Add ProductName to all Network Cards
  13. Locale has been moved
  14. Wordpad filenames
  15. NoDriveTypeAutorun has a different type
  16. Notes:
  17. This file should be used to add custom behavior to virtual registry.
  18. History:
  19. 05/05/2000 linstev Created
  20. 09/01/2000 t-adams Added support for PCI devices to BuildDynData()
  21. 09/01/2000 robkenny Added Krondor
  22. 09/09/2000 robkenny Updated Wordpad to return a short path to the exe
  23. 09/21/2000 prashkud Added fix for SpellItDeluxe
  24. 10/25/2000 maonis Added CookieMaster
  25. 10/17/2000 robkenny Added HKEY_DYN_DATA\Display\Settings
  26. 11/27/2000 a-fwills Added display guid to redirectors
  27. 12/28/2000 a-brienw Added BuildTalkingDictionary for American Heritage
  28. Talking Dictionary which is looking for a SharedDir key
  29. 01/15/2001 maonis Added PageKeepPro
  30. 02/06/2001 a-larrsh Added FileNet Web Server
  31. 02/27/2001 maonis Added PageMaker
  32. 02/27/2001 robkenny Converted to use tcs.h
  33. 03/01/2001 prashkud Added NetBT keys in BuildNetworkCards()
  34. 04/05/2001 mnikkel Added HKLM\Microsoft\Windows\CurrentVersion\App Paths\DXDIAG.EXE
  35. 04/27/2001 prashkud Added custom MiddleSchoolAdvantage 2001 entry
  36. 05/04/2001 prashkud Added custom entry for BOGUSCTRLID - Win2K layer
  37. 05/19/2001 hioh Added NOWROBLUE, BuildNowroBlue
  38. 06/13/2001 carlco Added Princeton ACT
  39. 08/10/2001 mikrause Added Airline Tycoon, DirectSound hacks.
  40. 11/06/2001 mikrause Added Delphi 5.0 Pro
  41. 01/02/2002 mamathas Added NortonAntiVirus2002, BuildNortonAntiVirus
  42. 04/23/2002 garyma Added Word Perfect Office 2002
  43. --*/
  44. #define SHIM_LIB_BUILD_FLAG
  45. #include "precomp.h"
  46. #include "secutils.h"
  47. #include <stdio.h>
  48. IMPLEMENT_SHIM_BEGIN(VirtualRegistry)
  49. #include "ShimHookMacro.h"
  50. #include "VRegistry.h"
  51. #include "VRegistry_dsound.h"
  52. //
  53. // Functions that modify the behaviour of virtualregistry
  54. //
  55. void BuildWin98SE(char* szParam);
  56. void BuildRedirectors(char* szParam);
  57. void BuildCookiePath(char* szParam);
  58. void BuildHasbro(char* szParam);
  59. void BuildDynData(char* szParam);
  60. void BuildCurrentConfig(char* szParam);
  61. void BuildLocale(char* szParam);
  62. void BuildWordPad(char* szParam);
  63. void BuildAutoRun(char* szParam);
  64. void BuildTalkingDictionary(char* szParam);
  65. void BuildNetworkCards(char* szParam);
  66. void BuildNT4SP5(char* szParam);
  67. void BuildNT50(char* szParam);
  68. void BuildNT51(char* szParam);
  69. void BuildBogusCtrlID(char* szParam);
  70. void BuildExpanders(char* szParam);
  71. void BuildDX7A(char* szParam);
  72. void BuildDXDiag(char* szParam);
  73. void BuildFutureCop(char* szParam);
  74. void BuildKrondor(char* szParam);
  75. void BuildPageKeepProDirectory(char* szParam);
  76. void BuildProfile(char* szParam);
  77. void BuildSpellItDeluxe(char* szParam);
  78. void BuildIE401(char* szParam);
  79. void BuildIE55(char* szParam);
  80. void BuildIE60(char* szParam);
  81. void BuildJoystick(char* szParam);
  82. void BuildIllustrator8(char* szParam);
  83. void BuildModemWizard(char* szParam);
  84. void BuildMSI(char* szParam);
  85. void BuildFileNetWebServer(char* szParam);
  86. void BuildPrinter(char* szParam);
  87. void BuildPageMaker65(char* szParam);
  88. void BuildStarTrekArmada(char* szParam);
  89. void BuildMSA2001(char* szParam);
  90. void BuildNowroBlue(char* szParam);
  91. void BuildRegisteredOwner(char* szParam);
  92. void BuildPrincetonACT(char* szParam);
  93. void BuildHEDZ(char* szParam);
  94. void BuildAirlineTycoon(char* szParam);
  95. void BuildDSDevAccel(char* szParam);
  96. void BuildDSPadCursors(char* szParam);
  97. void BuildDSCachePositions(char* szParam);
  98. void BuildDSReturnWritePos(char* szParam);
  99. void BuildDSSmoothWritePos(char* szParam);
  100. void BuildDSDisableDevice(char* szParam);
  101. void BuildDelphi5Pro(char* szParam);
  102. void BuildNortonAntiVirus(char* szParam);
  103. void BuildWordPerfect2002(char* szParam);
  104. // Table that contains all the fixes - note, must be terminated by a NULL entry.
  105. VENTRY g_VList[] =
  106. {
  107. {L"WIN98SE", BuildWin98SE, eWin9x, FALSE, NULL },
  108. {L"REDIRECT", BuildRedirectors, eWin9x, FALSE, NULL },
  109. {L"COOKIEPATH", BuildCookiePath, eWin9x, FALSE, NULL },
  110. {L"HASBRO", BuildHasbro, eWin9x, FALSE, NULL },
  111. {L"DYN_DATA", BuildDynData, eWin9x, FALSE, NULL },
  112. {L"CURRENT_CONFIG", BuildCurrentConfig, eWin9x, FALSE, NULL },
  113. {L"LOCALE", BuildLocale, eWin9x, FALSE, NULL },
  114. {L"WORDPAD", BuildWordPad, eWin9x, FALSE, NULL },
  115. {L"AUTORUN", BuildAutoRun, eWin9x, FALSE, NULL },
  116. {L"TALKINGDICTIONARY", BuildTalkingDictionary, eWin9x, FALSE, NULL },
  117. {L"PRINTER", BuildPrinter, eWin9x, FALSE, NULL },
  118. {L"REGISTEREDOWNER", BuildRegisteredOwner, eWin9x, FALSE, NULL },
  119. {L"NETWORK_CARDS", BuildNetworkCards, eWinNT, FALSE, NULL },
  120. {L"NT4SP5", BuildNT4SP5, eWinNT, FALSE, NULL },
  121. {L"NT50", BuildNT50, eWin2K, FALSE, NULL },
  122. {L"BOGUSCTRLID", BuildBogusCtrlID, eWin2K, FALSE, NULL },
  123. {L"NT51", BuildNT51, eWinXP, FALSE, NULL },
  124. {L"EXPAND", BuildExpanders, eCustom, FALSE, NULL },
  125. {L"DX7A", BuildDX7A, eCustom, FALSE, NULL },
  126. {L"DXDIAG", BuildDXDiag, eCustom, FALSE, NULL },
  127. {L"FUTURECOP", BuildFutureCop, eCustom, FALSE, NULL },
  128. {L"KRONDOR", BuildKrondor, eCustom, FALSE, NULL },
  129. {L"PROFILE", BuildProfile, eCustom, FALSE, NULL },
  130. {L"SPELLITDELUXE", BuildSpellItDeluxe, eCustom, FALSE, NULL },
  131. {L"IE401", BuildIE401, eCustom, FALSE, NULL },
  132. {L"IE55", BuildIE55, eCustom, FALSE, NULL },
  133. {L"IE60", BuildIE60, eCustom, FALSE, NULL },
  134. {L"JOYSTICK", BuildJoystick, eCustom, FALSE, NULL },
  135. {L"ILLUSTRATOR8", BuildIllustrator8, eCustom, FALSE, NULL },
  136. {L"PAGEKEEPPRO30", BuildPageKeepProDirectory, eCustom, FALSE, NULL },
  137. {L"MODEMWIZARD", BuildModemWizard, eCustom, FALSE, NULL },
  138. {L"MSI", BuildMSI, eCustom, FALSE, NULL },
  139. {L"FILENETWEBSERVER", BuildFileNetWebServer, eCustom, FALSE, NULL },
  140. {L"PAGEMAKER65", BuildPageMaker65, eCustom, FALSE, NULL },
  141. {L"STARTREKARMADA", BuildStarTrekArmada, eCustom, FALSE, NULL },
  142. {L"MSA2001", BuildMSA2001, eCustom, FALSE, NULL },
  143. {L"NOWROBLUE", BuildNowroBlue, eCustom, FALSE, NULL },
  144. {L"PRINCETONACT", BuildPrincetonACT, eCustom, FALSE, NULL },
  145. {L"HEDZ", BuildHEDZ, eCustom, FALSE, NULL },
  146. {L"AIRLINETYCOON", BuildAirlineTycoon, eCustom, FALSE, NULL },
  147. {L"DSDEVACCEL", BuildDSDevAccel, eCustom, FALSE, NULL },
  148. {L"DSPADCURSORS", BuildDSPadCursors, eCustom, FALSE, NULL },
  149. {L"DSCACHEPOSITIONS", BuildDSCachePositions, eCustom, FALSE, NULL },
  150. {L"DSRETURNWRITEPOS", BuildDSReturnWritePos, eCustom, FALSE, NULL },
  151. {L"DSSMOOTHWRITEPOS", BuildDSSmoothWritePos, eCustom, FALSE, NULL },
  152. {L"DSDISABLEDEVICE", BuildDSDisableDevice, eCustom, FALSE, NULL },
  153. {L"DELPHI5PRO", BuildDelphi5Pro, eCustom, FALSE, NULL },
  154. {L"NORTONANTIVIRUS", BuildNortonAntiVirus, eCustom, FALSE, NULL },
  155. {L"WORDPERFECT2002", BuildWordPerfect2002, eCustom, FALSE, NULL },
  156. // Must Be The Last Entry
  157. {L"", NULL, eCustom, FALSE, NULL }
  158. };
  159. VENTRY *g_pVList = &g_VList[0];
  160. ///////////////////////////////////////////////////////////////////////////////
  161. /*++
  162. Function Description:
  163. Add Win98 SE registry value - so far we only know about the Play Pack that
  164. needs it.
  165. History:
  166. 05/04/2000 linstev Created
  167. --*/
  168. void
  169. BuildWin98SE(char* /*szParam*/)
  170. {
  171. VIRTUALKEY *key;
  172. // Add version number string for emulation of Win98 SE
  173. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion");
  174. if (key)
  175. {
  176. key->AddValue(L"VersionNumber", REG_SZ, (LPBYTE)L"4.10.2222");
  177. }
  178. }
  179. ///////////////////////////////////////////////////////////////////////////////
  180. /*++
  181. Function Description:
  182. Known moved locations for which we need redirectors
  183. History:
  184. 05/04/2000 linstev Created
  185. --*/
  186. void
  187. BuildRedirectors(char* /*szParam*/)
  188. {
  189. // Display property page add ons and controls have changed location.
  190. VRegistry.AddRedirect(
  191. L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\Display",
  192. L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Controls Folder\\Desk");
  193. // this key moved somewhere around build 2200.
  194. // System config scan type apps (ip.exe bundled in EA sports)
  195. // starting failing again.
  196. VRegistry.AddRedirect(
  197. L"HKLM\\System\\CurrentControlSet\\Services\\Class",
  198. L"HKLM\\System\\CurrentControlSet\\Control\\Class");
  199. // Nightmare Ned wasn't finding display starting from Class.
  200. // Directing it from Display to the GUID.
  201. VRegistry.AddRedirect(
  202. L"HKLM\\System\\CurrentControlSet\\Services\\Class\\Display",
  203. L"HKLM\\System\\CurrentControlSet\\Control\\Class\\{4D36E968-E325-11CE-BFC1-08002BE10318}");
  204. }
  205. ///////////////////////////////////////////////////////////////////////////////
  206. /*++
  207. Function Description:
  208. CookieMaster gets the wrong path to cookies
  209. because HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache\\Special Paths\\Cookies
  210. contains bogus value (shell is going to fix this). We change this to the correct value %USERPROFILE%\Cookies.
  211. History:
  212. 10/25/2000 maonis Created
  213. --*/
  214. void
  215. BuildCookiePath(char* /*szParam*/)
  216. {
  217. WCHAR wCookiePath[] = L"%USERPROFILE%\\Cookies";
  218. VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Cache\\Special Paths\\Cookies");
  219. if (key)
  220. {
  221. key->AddValue(L"Directory", REG_EXPAND_SZ, (LPBYTE)wCookiePath, 0);
  222. }
  223. }
  224. ///////////////////////////////////////////////////////////////////////////////
  225. /*++
  226. Function Description:
  227. During the Slingo installation, the program places a value in the registry
  228. called 'PALFILE'. When you run the app, it checks this value to determine
  229. where the CD-ROM is located. For example, if the CD-ROM drive is 'E', it
  230. should put 'E:\Slingo.pal'. It fails to do this correctly on Win2K or Whistler,
  231. as it puts the install path instead. When the app runs, if the value doesn't
  232. refer to 'x:\Slingo.pal (where x is the CD-ROM drive)', the app immediately
  233. starts to do a FindFirstFile->FindNextFile looking for the file on the hard
  234. drive. Eventually it AVs during the search with no error message. This code
  235. sets the value in the registry on behalf of the app.
  236. History:
  237. 11/1/2000 rparsons Created
  238. --*/
  239. LONG
  240. WINAPI
  241. VR_Hasbro(
  242. OPENKEY *key,
  243. VIRTUALKEY * /* vkey */,
  244. VIRTUALVAL *vvalue
  245. )
  246. {
  247. DWORD dwType;
  248. WCHAR wszPath[MAX_PATH];
  249. DWORD dwSize = sizeof(wszPath);
  250. DWORD dwAttributes;
  251. //
  252. // Query the original value
  253. //
  254. LONG lRet = RegQueryValueExW(
  255. key->hkOpen,
  256. vvalue->wName,
  257. NULL,
  258. &dwType,
  259. (LPBYTE)wszPath,
  260. &dwSize);
  261. //
  262. // Query failed - something went wrong
  263. //
  264. if (FAILURE(lRet))
  265. {
  266. DPFN( eDbgLevelError, "[Hasbro hack] Failed to query %S for expansion", vvalue->wName);
  267. goto Exit;
  268. }
  269. //
  270. // Not a string type!
  271. //
  272. if ((dwType != REG_SZ) || (dwSize > sizeof(wszPath)))
  273. {
  274. DPFN( eDbgLevelError, "[Hasbro hack] Failed to query %S", vvalue->wName);
  275. lRet = ERROR_BAD_ARGUMENTS;
  276. goto Exit;
  277. }
  278. // Check what's there
  279. dwAttributes = GetFileAttributes(wszPath);
  280. // If it's not a file, or it's a directory, then we have to find it ourselves
  281. if ((dwAttributes == (DWORD)-1) || (dwAttributes & FILE_ATTRIBUTE_DIRECTORY))
  282. {
  283. WCHAR *lpDrives = L"";
  284. DWORD dwBufferLen = 0;
  285. //
  286. // The plan is to run all the drives and find one with a .PAL file on
  287. // it. We also have the restriction that it must be a CDRom. It has
  288. // been pointed out that if the user has multiple CD drives and has
  289. // different HasBro titles in each drive, we could cause a failure,
  290. // but we're considering that a pathological case for now. Especially
  291. // considering we have no way of knowing what the palfile name is ahead
  292. // of time.
  293. //
  294. dwBufferLen = GetLogicalDriveStringsW(0, lpDrives);
  295. if (dwBufferLen)
  296. {
  297. lpDrives = (WCHAR *) malloc((dwBufferLen + 1) * sizeof(WCHAR));
  298. if (lpDrives)
  299. {
  300. GetLogicalDriveStrings(dwBufferLen, lpDrives);
  301. WCHAR *lpCurrent = lpDrives;
  302. while (lpCurrent && lpCurrent[0])
  303. {
  304. if (GetDriveTypeW(lpCurrent) == DRIVE_CDROM)
  305. {
  306. //
  307. // We've found a CD drive, now see if it has a .PAL
  308. // file on it.
  309. //
  310. WCHAR wszFile[MAX_PATH];
  311. WIN32_FIND_DATAW ffData;
  312. HANDLE hFindFile;
  313. if (SUCCEEDED(StringCchCopyW(wszFile, MAX_PATH, lpCurrent)) &&
  314. SUCCEEDED(StringCchCatW(wszFile, MAX_PATH, L"*.PAL")))
  315. {
  316. hFindFile = FindFirstFileW(wszFile, &ffData);
  317. if (hFindFile != INVALID_HANDLE_VALUE)
  318. {
  319. // A .PAL file exists, return that.
  320. FindClose(hFindFile);
  321. if (SUCCEEDED(StringCchCopyW(wszPath, MAX_PATH, lpCurrent)) &&
  322. SUCCEEDED(StringCchCatW(wszPath, MAX_PATH, ffData.cFileName)))
  323. {
  324. LOGN( eDbgLevelInfo, "[Hasbro hack] Returning path %S", wszPath);
  325. break;
  326. }
  327. }
  328. }
  329. }
  330. // Advance to the next drive letter
  331. lpCurrent += wcslen(lpCurrent) + 1;
  332. }
  333. free(lpDrives);
  334. }
  335. }
  336. }
  337. // Copy the result into the output of QueryValue
  338. vvalue->cbData = (wcslen(wszPath) + 1) * sizeof(WCHAR);
  339. vvalue->lpData = (LPBYTE) malloc(vvalue->cbData);
  340. if (!vvalue->lpData)
  341. {
  342. DPFN( eDbgLevelError, szOutOfMemory);
  343. lRet = ERROR_NOT_ENOUGH_MEMORY;
  344. goto Exit;
  345. }
  346. MoveMemory(vvalue->lpData, wszPath, vvalue->cbData);
  347. //
  348. // Never call us again, since we've done the work to set this value up and
  349. // stored it in our virtual value
  350. //
  351. vvalue->pfnQueryValue = NULL;
  352. lRet = ERROR_SUCCESS;
  353. Exit:
  354. return lRet;
  355. }
  356. void
  357. BuildHasbro(char* /*szParam*/)
  358. {
  359. HKEY hHasbroKey;
  360. WCHAR wszKeyName[MAX_PATH];
  361. DWORD dwIndex;
  362. const WCHAR wszHasbroPath[] = L"SOFTWARE\\Hasbro Interactive";
  363. if (FAILURE(RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszHasbroPath, 0, KEY_READ, &hHasbroKey)))
  364. {
  365. DPFN( eDbgLevelSpew, "[Hasbro hack] Ignoring fix - no titles found");
  366. return;
  367. }
  368. //
  369. // Enum the keys under Hasbro Interactive and add a virtual PALFILE value.
  370. // Attach our callback to this value (see above)
  371. //
  372. dwIndex = 0;
  373. while (SUCCESS(RegEnumKeyW(hHasbroKey, dwIndex, wszKeyName, MAX_PATH)))
  374. {
  375. WCHAR wszName[MAX_PATH] = L"HKLM\\";
  376. if (SUCCEEDED(StringCchCatW(wszName, MAX_PATH, wszHasbroPath)) &&
  377. SUCCEEDED(StringCchCatW(wszName, MAX_PATH, L"\\")) &&
  378. SUCCEEDED(StringCchCatW(wszName, MAX_PATH, wszKeyName)))
  379. {
  380. VIRTUALKEY *key = VRegistry.AddKey(wszName);
  381. if (key)
  382. {
  383. VIRTUALVAL *val = key->AddValue(L"PALFILE", REG_SZ, 0, 0);
  384. if (val)
  385. {
  386. val->pfnQueryValue = VR_Hasbro;
  387. }
  388. DPFN( eDbgLevelInfo, "[Hasbro hack] Adding fix for %S", wszKeyName);
  389. }
  390. }
  391. dwIndex++;
  392. }
  393. RegCloseKey(hHasbroKey);
  394. }
  395. ///////////////////////////////////////////////////////////////////////////////
  396. /*++
  397. Function Description:
  398. A simple DYN_DATA structure which emulates win9x.
  399. History:
  400. 05/04/2000 linstev Created
  401. 09/01/2000 t-adams Added support for PCI devices so EA's 3dSetup.exe & others can
  402. detect hardware.
  403. --*/
  404. #define ENUM_BASE 0xC29A28C0
  405. void
  406. BuildDynData(char* /*szParam*/)
  407. {
  408. VIRTUALKEY *key, *nkey;
  409. HKEY hkPCI = 0;
  410. DWORD i = 0;
  411. DWORD dwNameLen = 0;
  412. LPWSTR wstrName = NULL;
  413. LPWSTR wstrVName = NULL;
  414. FILETIME fileTime;
  415. DWORD dwValue;
  416. // Entries in HKDD\Config Manager\Enum were references to entries in HKLM\Enum\PCI that are now
  417. // located at HKLM\SYSTEM\CurrentControlSet\Enum\PCI
  418. VRegistry.AddRedirect(
  419. L"HKLM\\Enum",
  420. L"HKLM\\SYSTEM\\CurrentControlSet\\Enum");
  421. // Construct HKDD\Config Manager\Enum so that it reflects the entries in HKLM\SYSTEM\CurrentControlSet\Enum\PCI
  422. key = VRegistry.AddKey(L"HKDD\\Config Manager\\Enum");
  423. if (!key)
  424. {
  425. goto exit;
  426. }
  427. if (SUCCESS(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Enum\\PCI",0, KEY_READ, &hkPCI)))
  428. {
  429. dwNameLen = MAX_PATH;
  430. wstrName = (LPWSTR) malloc(dwNameLen * sizeof(WCHAR));
  431. if (NULL == wstrName)
  432. {
  433. goto exit;
  434. }
  435. wstrVName = (LPWSTR) malloc(dwNameLen * sizeof(WCHAR));
  436. if (NULL == wstrName)
  437. {
  438. goto exit;
  439. }
  440. i = 0;
  441. while (ERROR_SUCCESS == RegEnumKeyExW(hkPCI, i, wstrName, &dwNameLen, NULL, NULL, NULL, &fileTime))
  442. {
  443. if (FAILED(StringCchPrintf(wstrVName, MAX_PATH, L"%x", ENUM_BASE+i)))
  444. {
  445. continue;
  446. }
  447. nkey = key->AddKey(wstrVName);
  448. if (!nkey) continue;
  449. if (SUCCEEDED(StringCchCopy(wstrVName, MAX_PATH, L"PCI\\")) &&
  450. SUCCEEDED(StringCchCat(wstrVName, MAX_PATH, wstrName)))
  451. {
  452. nkey->AddValue(L"HardWareKey", REG_SZ, (LPBYTE)wstrVName);
  453. }
  454. nkey->AddValueDWORD(L"Problem", 0);
  455. dwNameLen = MAX_PATH;
  456. ++i;
  457. }
  458. }
  459. key = VRegistry.AddKey(L"HKDD\\Config Manager\\Global");
  460. key = VRegistry.AddKey(L"HKDD\\PerfStats");
  461. key = VRegistry.AddKey(L"HKDD\\PerfStats\\StartSrv");
  462. if (key)
  463. {
  464. dwValue = 0x0000001;
  465. key->AddValue(L"KERNEL", REG_BINARY, (LPBYTE)&dwValue, 4);
  466. key->AddValue(L"VCACHE", REG_BINARY, (LPBYTE)&dwValue, 4);
  467. key->AddValue(L"VFAT", REG_BINARY, (LPBYTE)&dwValue, 4);
  468. key->AddValue(L"VMM", REG_BINARY, (LPBYTE)&dwValue, 4);
  469. }
  470. key = VRegistry.AddKey(L"HKDD\\PerfStats\\StartStat");
  471. if (key)
  472. {
  473. dwValue = 0x0000001;
  474. key->AddValue(L"KERNEL\\CPUUsage", REG_BINARY, (LPBYTE)&dwValue, 4);
  475. key->AddValue(L"KERNEL\\Threads", REG_BINARY, (LPBYTE)&dwValue, 4);
  476. key->AddValue(L"KERNEL\\VMs", REG_BINARY, (LPBYTE)&dwValue, 4);
  477. key->AddValue(L"VCACHE\\cCurPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  478. key->AddValue(L"VCACHE\\cMacPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  479. key->AddValue(L"VCACHE\\cMinPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  480. key->AddValue(L"VCACHE\\FailedRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  481. key->AddValue(L"VCACHE\\Hits", REG_BINARY, (LPBYTE)&dwValue, 4);
  482. key->AddValue(L"VCACHE\\LRUBuffers", REG_BINARY, (LPBYTE)&dwValue, 4);
  483. key->AddValue(L"VCACHE\\LRURecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  484. key->AddValue(L"VCACHE\\Misses", REG_BINARY, (LPBYTE)&dwValue, 4);
  485. key->AddValue(L"VCACHE\\RandomRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  486. key->AddValue(L"VFAT\\BReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  487. key->AddValue(L"VFAT\\BWritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  488. key->AddValue(L"VFAT\\DirtyData", REG_BINARY, (LPBYTE)&dwValue, 4);
  489. key->AddValue(L"VFAT\\ReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  490. key->AddValue(L"VFAT\\WritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  491. key->AddValue(L"VMM\\cDiscards", REG_BINARY, (LPBYTE)&dwValue, 4);
  492. key->AddValue(L"VMM\\cInstanceFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
  493. key->AddValue(L"VMM\\cPageFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
  494. key->AddValue(L"VMM\\cPageIns", REG_BINARY, (LPBYTE)&dwValue, 4);
  495. key->AddValue(L"VMM\\cPageOuts", REG_BINARY, (LPBYTE)&dwValue, 4);
  496. key->AddValue(L"VMM\\cpgCommit", REG_BINARY, (LPBYTE)&dwValue, 4);
  497. key->AddValue(L"VMM\\cpgDiskcache", REG_BINARY, (LPBYTE)&dwValue, 4);
  498. key->AddValue(L"VMM\\cpgDiskcacheMac", REG_BINARY, (LPBYTE)&dwValue, 4);
  499. key->AddValue(L"VMM\\cpgDiskcacheMid", REG_BINARY, (LPBYTE)&dwValue, 4);
  500. key->AddValue(L"VMM\\cpgDiskcacheMin", REG_BINARY, (LPBYTE)&dwValue, 4);
  501. key->AddValue(L"VMM\\cpgFree", REG_BINARY, (LPBYTE)&dwValue, 4);
  502. key->AddValue(L"VMM\\cpgLocked", REG_BINARY, (LPBYTE)&dwValue, 4);
  503. key->AddValue(L"VMM\\cpgLockedNonCache", REG_BINARY, (LPBYTE)&dwValue, 4);
  504. key->AddValue(L"VMM\\cpgOther", REG_BINARY, (LPBYTE)&dwValue, 4);
  505. key->AddValue(L"VMM\\cpgSharedPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  506. key->AddValue(L"VMM\\cpgSwap", REG_BINARY, (LPBYTE)&dwValue, 4);
  507. key->AddValue(L"VMM\\cpgSwapFile", REG_BINARY, (LPBYTE)&dwValue, 4);
  508. key->AddValue(L"VMM\\cpgSwapFileDefective", REG_BINARY, (LPBYTE)&dwValue, 4);
  509. key->AddValue(L"VMM\\cpgSwapFileInUse", REG_BINARY, (LPBYTE)&dwValue, 4);
  510. }
  511. key = VRegistry.AddKey(L"HKDD\\PerfStats\\StatData");
  512. if (key)
  513. {
  514. dwValue = 0x0000001;
  515. key->AddValue(L"KERNEL\\CPUUsage", REG_BINARY, (LPBYTE)&dwValue, 4);
  516. key->AddValue(L"KERNEL\\Threads", REG_BINARY, (LPBYTE)&dwValue, 4);
  517. key->AddValue(L"KERNEL\\VMs", REG_BINARY, (LPBYTE)&dwValue, 4);
  518. key->AddValue(L"VCACHE\\cCurPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  519. key->AddValue(L"VCACHE\\cMacPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  520. key->AddValue(L"VCACHE\\cMinPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  521. key->AddValue(L"VCACHE\\FailedRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  522. key->AddValue(L"VCACHE\\Hits", REG_BINARY, (LPBYTE)&dwValue, 4);
  523. key->AddValue(L"VCACHE\\LRUBuffers", REG_BINARY, (LPBYTE)&dwValue, 4);
  524. key->AddValue(L"VCACHE\\LRURecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  525. key->AddValue(L"VCACHE\\Misses", REG_BINARY, (LPBYTE)&dwValue, 4);
  526. key->AddValue(L"VCACHE\\RandomRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  527. key->AddValue(L"VFAT\\BReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  528. key->AddValue(L"VFAT\\BWritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  529. key->AddValue(L"VFAT\\DirtyData", REG_BINARY, (LPBYTE)&dwValue, 4);
  530. key->AddValue(L"VFAT\\ReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  531. key->AddValue(L"VFAT\\WritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  532. key->AddValue(L"VMM\\cDiscards", REG_BINARY, (LPBYTE)&dwValue, 4);
  533. key->AddValue(L"VMM\\cInstanceFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
  534. key->AddValue(L"VMM\\cPageFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
  535. key->AddValue(L"VMM\\cPageIns", REG_BINARY, (LPBYTE)&dwValue, 4);
  536. key->AddValue(L"VMM\\cPageOuts", REG_BINARY, (LPBYTE)&dwValue, 4);
  537. key->AddValue(L"VMM\\cpgCommit", REG_BINARY, (LPBYTE)&dwValue, 4);
  538. key->AddValue(L"VMM\\cpgDiskcache", REG_BINARY, (LPBYTE)&dwValue, 4);
  539. key->AddValue(L"VMM\\cpgDiskcacheMac", REG_BINARY, (LPBYTE)&dwValue, 4);
  540. key->AddValue(L"VMM\\cpgDiskcacheMid", REG_BINARY, (LPBYTE)&dwValue, 4);
  541. key->AddValue(L"VMM\\cpgDiskcacheMin", REG_BINARY, (LPBYTE)&dwValue, 4);
  542. key->AddValue(L"VMM\\cpgFree", REG_BINARY, (LPBYTE)&dwValue, 4);
  543. key->AddValue(L"VMM\\cpgLocked", REG_BINARY, (LPBYTE)&dwValue, 4);
  544. key->AddValue(L"VMM\\cpgLockedNonCache", REG_BINARY, (LPBYTE)&dwValue, 4);
  545. key->AddValue(L"VMM\\cpgOther", REG_BINARY, (LPBYTE)&dwValue, 4);
  546. key->AddValue(L"VMM\\cpgSharedPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  547. key->AddValue(L"VMM\\cpgSwap", REG_BINARY, (LPBYTE)&dwValue, 4);
  548. key->AddValue(L"VMM\\cpgSwapFile", REG_BINARY, (LPBYTE)&dwValue, 4);
  549. key->AddValue(L"VMM\\cpgSwapFileDefective", REG_BINARY, (LPBYTE)&dwValue, 4);
  550. key->AddValue(L"VMM\\cpgSwapFileInUse", REG_BINARY, (LPBYTE)&dwValue, 4);
  551. }
  552. key = VRegistry.AddKey(L"HKDD\\PerfStats\\StopSrv");
  553. if (key)
  554. {
  555. dwValue = 0x0000001;
  556. key->AddValue(L"KERNEL", REG_BINARY, (LPBYTE)&dwValue, 4);
  557. key->AddValue(L"VCACHE", REG_BINARY, (LPBYTE)&dwValue, 4);
  558. key->AddValue(L"VFAT", REG_BINARY, (LPBYTE)&dwValue, 4);
  559. key->AddValue(L"VMM", REG_BINARY, (LPBYTE)&dwValue, 4);
  560. }
  561. key = VRegistry.AddKey(L"HKDD\\PerfStats\\StopStat");
  562. if (key)
  563. {
  564. dwValue = 0x0000001;
  565. key->AddValue(L"KERNEL\\CPUUsage", REG_BINARY, (LPBYTE)&dwValue, 4);
  566. key->AddValue(L"KERNEL\\Threads", REG_BINARY, (LPBYTE)&dwValue, 4);
  567. key->AddValue(L"KERNEL\\VMs", REG_BINARY, (LPBYTE)&dwValue, 4);
  568. key->AddValue(L"VCACHE\\cCurPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  569. key->AddValue(L"VCACHE\\cMacPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  570. key->AddValue(L"VCACHE\\cMinPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  571. key->AddValue(L"VCACHE\\FailedRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  572. key->AddValue(L"VCACHE\\Hits", REG_BINARY, (LPBYTE)&dwValue, 4);
  573. key->AddValue(L"VCACHE\\LRUBuffers", REG_BINARY, (LPBYTE)&dwValue, 4);
  574. key->AddValue(L"VCACHE\\LRURecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  575. key->AddValue(L"VCACHE\\Misses", REG_BINARY, (LPBYTE)&dwValue, 4);
  576. key->AddValue(L"VCACHE\\RandomRecycles", REG_BINARY, (LPBYTE)&dwValue, 4);
  577. key->AddValue(L"VFAT\\BReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  578. key->AddValue(L"VFAT\\BWritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  579. key->AddValue(L"VFAT\\DirtyData", REG_BINARY, (LPBYTE)&dwValue, 4);
  580. key->AddValue(L"VFAT\\ReadsSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  581. key->AddValue(L"VFAT\\WritesSec", REG_BINARY, (LPBYTE)&dwValue, 4);
  582. key->AddValue(L"VMM\\cDiscards", REG_BINARY, (LPBYTE)&dwValue, 4);
  583. key->AddValue(L"VMM\\cInstanceFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
  584. key->AddValue(L"VMM\\cPageFaults", REG_BINARY, (LPBYTE)&dwValue, 4);
  585. key->AddValue(L"VMM\\cPageIns", REG_BINARY, (LPBYTE)&dwValue, 4);
  586. key->AddValue(L"VMM\\cPageOuts", REG_BINARY, (LPBYTE)&dwValue, 4);
  587. key->AddValue(L"VMM\\cpgCommit", REG_BINARY, (LPBYTE)&dwValue, 4);
  588. key->AddValue(L"VMM\\cpgDiskcache", REG_BINARY, (LPBYTE)&dwValue, 4);
  589. key->AddValue(L"VMM\\cpgDiskcacheMac", REG_BINARY, (LPBYTE)&dwValue, 4);
  590. key->AddValue(L"VMM\\cpgDiskcacheMid", REG_BINARY, (LPBYTE)&dwValue, 4);
  591. key->AddValue(L"VMM\\cpgDiskcacheMin", REG_BINARY, (LPBYTE)&dwValue, 4);
  592. key->AddValue(L"VMM\\cpgFree", REG_BINARY, (LPBYTE)&dwValue, 4);
  593. key->AddValue(L"VMM\\cpgLocked", REG_BINARY, (LPBYTE)&dwValue, 4);
  594. key->AddValue(L"VMM\\cpgLockedNonCache", REG_BINARY, (LPBYTE)&dwValue, 4);
  595. key->AddValue(L"VMM\\cpgOther", REG_BINARY, (LPBYTE)&dwValue, 4);
  596. key->AddValue(L"VMM\\cpgSharedPages", REG_BINARY, (LPBYTE)&dwValue, 4);
  597. key->AddValue(L"VMM\\cpgSwap", REG_BINARY, (LPBYTE)&dwValue, 4);
  598. key->AddValue(L"VMM\\cpgSwapFile", REG_BINARY, (LPBYTE)&dwValue, 4);
  599. key->AddValue(L"VMM\\cpgSwapFileDefective", REG_BINARY, (LPBYTE)&dwValue, 4);
  600. key->AddValue(L"VMM\\cpgSwapFileInUse", REG_BINARY, (LPBYTE)&dwValue, 4);
  601. }
  602. exit:
  603. if (NULL != wstrName)
  604. {
  605. free(wstrName);
  606. }
  607. if (NULL != wstrVName)
  608. {
  609. free(wstrVName);
  610. }
  611. if (0 != hkPCI)
  612. {
  613. RegCloseKey(hkPCI);
  614. }
  615. }
  616. ///////////////////////////////////////////////////////////////////////////////
  617. /*++
  618. Function Description:
  619. DisplaySettings
  620. History:
  621. 10/17/2000 robkenny Added HKEY_CURRENT_CONFIG
  622. --*/
  623. void
  624. BuildCurrentConfig(char* /*szParam*/)
  625. {
  626. DEVMODE devMode;
  627. memset(&devMode, 0, sizeof(devMode));
  628. devMode.dmSize = sizeof(devMode);
  629. // Get the current display settings
  630. BOOL bSuccessful = EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &devMode);
  631. if (bSuccessful)
  632. {
  633. // Create fake registry keys with dmPelsWidth, dmPelsHeight, dmPelsWidth and dmBitsPerPel
  634. VIRTUALKEY *key = VRegistry.AddKey(L"HKCC\\Display\\Settings");
  635. if (key)
  636. {
  637. WCHAR lpValue[100];
  638. if (SUCCEEDED(StringCchPrintf(lpValue, 100, L"%d",devMode.dmBitsPerPel)))
  639. {
  640. key->AddValue(L"BitsPerPixel", REG_SZ, (LPBYTE)lpValue, 0);
  641. }
  642. if (SUCCEEDED(StringCchPrintf(lpValue, 100,L"%d,%d", devMode.dmPelsWidth, devMode.dmPelsHeight)))
  643. {
  644. key->AddValue(L"Resolution", REG_SZ, (LPBYTE)lpValue, 0);
  645. }
  646. }
  647. }
  648. // Redirect the current desktop fonts
  649. VRegistry.AddRedirect(
  650. L"HKCC\\Display\\Fonts",
  651. L"HKCC\\Software\\Fonts");
  652. }
  653. ///////////////////////////////////////////////////////////////////////////////
  654. /*++
  655. Function Description:
  656. Make RegQueryValue return the value that's in the "(Default)" value, rather
  657. than the NULL which is in there now. Not sure why the Locale key has this
  658. difference.
  659. History:
  660. 06/29/2000 linstev Created
  661. --*/
  662. void
  663. BuildLocale(char* /*szParam*/)
  664. {
  665. #define LOCALE_KEY HKEY_LOCAL_MACHINE
  666. #define LOCALE_SUBKEY L"System\\CurrentControlSet\\Control\\Nls\\Locale"
  667. HKEY hkBase;
  668. if (FAILURE(RegOpenKeyExW(
  669. LOCALE_KEY,
  670. LOCALE_SUBKEY,
  671. 0,
  672. KEY_READ,
  673. &hkBase)))
  674. {
  675. return;
  676. }
  677. WCHAR wValue[MAX_PATH];
  678. DWORD dwSize = MAX_PATH * sizeof(WCHAR);
  679. if (SUCCESS(RegQueryValueExW(hkBase, L"(Default)", 0, 0, (LPBYTE)wValue, &dwSize)))
  680. {
  681. LPWSTR wzPath;
  682. VIRTUALKEY *localekey;
  683. // Convert the KEY and SUBKEY into a path we can use for the vregistry
  684. wzPath = MakePath(LOCALE_KEY, 0, LOCALE_SUBKEY);
  685. if (wzPath)
  686. {
  687. localekey = VRegistry.AddKey(wzPath);
  688. if (localekey)
  689. {
  690. localekey->AddValue(L"", REG_SZ, (LPBYTE)wValue);
  691. }
  692. free(wzPath);
  693. }
  694. }
  695. RegCloseKey(hkBase);
  696. }
  697. ///////////////////////////////////////////////////////////////////////////////
  698. /*++
  699. Function Description:
  700. On NT, the strings in these values are of the form:
  701. C:\Program Files\Windows NT\Accessories\WORDPAD.EXE "%1"
  702. Note that the entire string is NOT quoted. On win9x, the string was:
  703. C:\Windows\wordpad.exe "%1"
  704. This causes problems when apps parse the NT version, because they hit the
  705. space between Program and Files.
  706. The fix is to return a shortened pathname to wordpad.exe
  707. History:
  708. 05/04/2000 linstev Created
  709. 05/04/2000 robkenny Updated to return a correct short pathname to wordpad.exe
  710. --*/
  711. void
  712. BuildWordPad(char* /*szParam*/)
  713. {
  714. // Allocate memory so we don't use up lots of stack
  715. WCHAR *lpwzWordpadOpen = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
  716. WCHAR *lpwzWordpadPrint = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
  717. WCHAR *lpwzWordpadPrintTo = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
  718. WCHAR *lpwzWordpadLong = lpwzWordpadOpen; // borrow the buffer to save space
  719. WCHAR *lpwzWordpadShort = (WCHAR *)malloc(MAX_PATH * sizeof(WCHAR));
  720. DWORD lpType;
  721. DWORD cbValue;
  722. LONG result;
  723. if (lpwzWordpadOpen == NULL ||
  724. lpwzWordpadPrint == NULL ||
  725. lpwzWordpadPrintTo == NULL ||
  726. lpwzWordpadShort == NULL)
  727. {
  728. goto AllDone;
  729. }
  730. // Read the path to WORDPAD.EXE directly from the registry.
  731. HKEY hKeyAppPaths;
  732. result = RegOpenKeyExW(
  733. HKEY_LOCAL_MACHINE,
  734. L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\WORDPAD.EXE",
  735. 0,
  736. KEY_QUERY_VALUE,
  737. &hKeyAppPaths
  738. );
  739. if (result != ERROR_SUCCESS)
  740. {
  741. goto AllDone;
  742. }
  743. cbValue = MAX_PATH * sizeof(DWORD);
  744. result = RegQueryValueExW(
  745. hKeyAppPaths,
  746. NULL, // default value
  747. NULL,
  748. &lpType,
  749. (LPBYTE)lpwzWordpadLong,
  750. &cbValue);
  751. RegCloseKey(hKeyAppPaths);
  752. if (result != ERROR_SUCCESS)
  753. {
  754. goto AllDone;
  755. }
  756. // turn bytes into string length (includes EOS)
  757. DWORD cchValue = cbValue /sizeof(WCHAR);
  758. if (lpType == REG_EXPAND_SZ)
  759. {
  760. WCHAR * lpwzWordpadExpand = lpwzWordpadPrintTo; // borrow the lpwzWordpadPrintTo buffer for a moment.
  761. cchValue = ExpandEnvironmentStringsW(lpwzWordpadLong, lpwzWordpadExpand, MAX_PATH);
  762. if (cchValue == 0 || cchValue > MAX_PATH )
  763. goto AllDone;
  764. lpwzWordpadLong = lpwzWordpadExpand;
  765. }
  766. // Rip off the trailing Quote
  767. lpwzWordpadLong[cchValue-2] = 0;
  768. lpwzWordpadLong += 1;
  769. // Build the short path to wordpad
  770. cchValue = GetShortPathNameW(lpwzWordpadLong, lpwzWordpadShort, MAX_PATH);
  771. if (cchValue == 0 || cchValue > MAX_PATH)
  772. {
  773. goto AllDone;
  774. }
  775. if (FAILED(StringCchPrintf(lpwzWordpadOpen, MAX_PATH,L"%s \"%%1\"", lpwzWordpadShort)) ||
  776. FAILED(StringCchPrintf(lpwzWordpadPrint, MAX_PATH, L"%s /p \"%%1\"",lpwzWordpadShort)) ||
  777. FAILED(StringCchPrintf(lpwzWordpadPrintTo, MAX_PATH,L"%s /pt \"%%1\" \"%%2\" \"%%3\" \"%%4\"", lpwzWordpadShort)))
  778. {
  779. goto AllDone;
  780. }
  781. #define WORDPAD_OPEN ((LPBYTE)lpwzWordpadOpen)
  782. #define WORDPAD_PRINT ((LPBYTE)lpwzWordpadPrint)
  783. #define WORDPAD_PRINTTO ((LPBYTE)lpwzWordpadPrintTo)
  784. VIRTUALKEY *key;
  785. key = VRegistry.AddKey(L"HKCR\\rtffile\\shell\\open\\command");
  786. if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
  787. key = VRegistry.AddKey(L"HKCR\\rtffile\\shell\\print\\command");
  788. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
  789. key = VRegistry.AddKey(L"HKCR\\rtffile\\shell\\printto\\command");
  790. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
  791. key = VRegistry.AddKey(L"HKCR\\Wordpad.Document.1\\shell\\open\\command");
  792. if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
  793. key = VRegistry.AddKey(L"HKCR\\Wordpad.Document.1\\shell\\print\\command");
  794. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
  795. key = VRegistry.AddKey(L"HKCR\\Wordpad.Document.1\\shell\\printto\\command");
  796. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
  797. key = VRegistry.AddKey(L"HKCR\\wrifile\\shell\\open\\command");
  798. if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
  799. key = VRegistry.AddKey(L"HKCR\\wrifile\\shell\\print\\command");
  800. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
  801. key = VRegistry.AddKey(L"HKCR\\wrifile\\shell\\printto\\command");
  802. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
  803. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Applications\\wordpad.exe\\shell\\open\\command");
  804. if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
  805. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Applications\\wordpad.exe\\shell\\print\\command");
  806. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
  807. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Applications\\wordpad.exe\\shell\\printto\\command");
  808. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
  809. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\rtffile\\shell\\open\\command");
  810. if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
  811. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\rtffile\\shell\\print\\command");
  812. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
  813. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\rtffile\\shell\\printto\\command");
  814. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
  815. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Wordpad.Document.1\\shell\\open\\command");
  816. if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
  817. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Wordpad.Document.1\\shell\\print\\command");
  818. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
  819. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\Wordpad.Document.1\\shell\\printto\\command");
  820. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
  821. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\wrifile\\shell\\open\\command");
  822. if (key) key->AddValue(0, REG_SZ, WORDPAD_OPEN);
  823. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\wrifile\\shell\\print\\command");
  824. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINT);
  825. key = VRegistry.AddKey(L"HKLM\\Software\\Classes\\wrifile\\shell\\printto\\command");
  826. if (key) key->AddValue(0, REG_SZ, WORDPAD_PRINTTO);
  827. AllDone:
  828. free(lpwzWordpadOpen);
  829. free(lpwzWordpadPrint);
  830. free(lpwzWordpadPrintTo);
  831. free(lpwzWordpadShort);
  832. }
  833. ///////////////////////////////////////////////////////////////////////////////
  834. /*++
  835. Function Description:
  836. This is a REG_BINARY on win9x
  837. History:
  838. 07/18/2000 linstev Created
  839. --*/
  840. void
  841. BuildAutoRun(char* /*szParam*/)
  842. {
  843. #define AUTORUN_KEY HKEY_CURRENT_USER
  844. #define AUTORUN_SUBKEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer"
  845. HKEY hkBase;
  846. if (FAILURE(RegOpenKeyExW(
  847. AUTORUN_KEY,
  848. AUTORUN_SUBKEY,
  849. 0,
  850. KEY_READ,
  851. &hkBase)))
  852. {
  853. return;
  854. }
  855. DWORD dwValue;
  856. DWORD dwSize = sizeof(DWORD);
  857. if (SUCCESS(RegQueryValueExW(hkBase, L"NoDriveTypeAutoRun", 0, 0, (LPBYTE)&dwValue, &dwSize)))
  858. {
  859. LPWSTR wzPath;
  860. VIRTUALKEY *vkey;
  861. // Convert the KEY and SUBKEY into a path we can use for the vregistry
  862. wzPath = MakePath(AUTORUN_KEY, 0, AUTORUN_SUBKEY);
  863. if (wzPath)
  864. {
  865. vkey = VRegistry.AddKey(wzPath);
  866. if (vkey)
  867. {
  868. vkey->AddValue(L"NoDriveTypeAutoRun", REG_BINARY, (LPBYTE)&dwValue, sizeof(DWORD));
  869. }
  870. free(wzPath);
  871. }
  872. }
  873. RegCloseKey(hkBase);
  874. }
  875. ///////////////////////////////////////////////////////////////////////////////
  876. /*++
  877. Function Description:
  878. Add SharedDir value to HKLM\Software\Microsoft\Windows\CurrentVersion\Setup
  879. The SharedDir in this case is just the windows directory (as it was on 9x).
  880. History:
  881. 12/28/2000 a-brienw Created
  882. --*/
  883. void
  884. BuildTalkingDictionary(char* /*szParam*/)
  885. {
  886. VIRTUALKEY *key;
  887. WCHAR szWindowsDir[MAX_PATH];
  888. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Setup");
  889. if (key)
  890. {
  891. DWORD cchSize = GetWindowsDirectoryW( (LPWSTR)szWindowsDir, MAX_PATH);
  892. if (cchSize != 0 && cchSize <= MAX_PATH)
  893. key->AddValue(L"SharedDir", REG_SZ, (LPBYTE)szWindowsDir);
  894. }
  895. }
  896. ///////////////////////////////////////////////////////////////////////////////
  897. /*++
  898. Function Description:
  899. Add a ProductName value to every network card description as on NT 4. The
  900. product name in this case is just the first 8 characters of the
  901. description.
  902. History:
  903. 01/18/2000 linstev Created
  904. 03/01/2001 prashkud Added NetBT\Adapter key and the corresponding values
  905. --*/
  906. void
  907. BuildNetworkCards(char* /*szParam*/)
  908. {
  909. #define NETCARD_KEY HKEY_LOCAL_MACHINE
  910. #define NETCARD_SUBKEY L"Software\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"
  911. #define NETBT_SUBKEY L"System\\CurrentControlSet\\Services\\NetBT"
  912. // For NetBT
  913. LPWSTR wzNetBTPath;
  914. WCHAR wAdapter[MAX_PATH];
  915. VIRTUALKEY *vkAdapter = NULL;
  916. HKEY hkNetBT;
  917. if (FAILURE(RegOpenKeyExW(
  918. NETCARD_KEY,
  919. NETBT_SUBKEY,
  920. 0,
  921. KEY_READ,
  922. &hkNetBT)))
  923. {
  924. DPFN( eDbgLevelError, "Failed to add NetBT settings");
  925. return;
  926. }
  927. if (FAILED(StringCchCopy(wAdapter, MAX_PATH, NETBT_SUBKEY)))
  928. {
  929. RegCloseKey(hkNetBT);
  930. return;
  931. }
  932. if (FAILED(StringCchCat(wAdapter, MAX_PATH, L"\\Adapters")))
  933. {
  934. RegCloseKey(hkNetBT);
  935. return;
  936. }
  937. // Make this a Virtual path
  938. wzNetBTPath = MakePath(NETCARD_KEY, 0, wAdapter);
  939. if (!wzNetBTPath)
  940. {
  941. DPFN( eDbgLevelError, "Failed to make NetBT path");
  942. RegCloseKey(hkNetBT);
  943. return;
  944. }
  945. // Adding the Adapters subkey to NetBT
  946. vkAdapter = VRegistry.AddKey(wzNetBTPath);
  947. free(wzNetBTPath);
  948. HKEY hkBase;
  949. // Check for network cards
  950. if (FAILURE(RegOpenKeyExW(
  951. NETCARD_KEY,
  952. NETCARD_SUBKEY,
  953. 0,
  954. KEY_READ,
  955. &hkBase)))
  956. {
  957. DPFN( eDbgLevelError, "Failed to add Network card registry settings");
  958. return;
  959. }
  960. LPWSTR wzPath;
  961. VIRTUALKEY *netkey;
  962. // Convert the KEY and SUBKEY into a path we can use for the vregistry
  963. wzPath = MakePath(NETCARD_KEY, 0, NETCARD_SUBKEY);
  964. netkey = wzPath ? VRegistry.AddKey(wzPath) : NULL;
  965. if (wzPath && netkey)
  966. {
  967. // Enumerate the keys and add them to the virtual registry
  968. DWORD dwIndex = 0;
  969. WCHAR wName[MAX_PATH];
  970. while (SUCCESS(RegEnumKeyW(
  971. hkBase,
  972. dwIndex,
  973. wName,
  974. MAX_PATH)))
  975. {
  976. HKEY hKey;
  977. VIRTUALKEY *keyn;
  978. WCHAR wTemp[MAX_PATH];
  979. keyn = netkey->AddKey(wName);
  980. if (!keyn)
  981. {
  982. break;
  983. }
  984. if (SUCCEEDED(StringCchCopy(wTemp, MAX_PATH, NETCARD_SUBKEY)) &&
  985. SUCCEEDED(StringCchCat(wTemp, MAX_PATH, L"\\")) &&
  986. SUCCEEDED(StringCchCat(wTemp, MAX_PATH,wName)))
  987. {
  988. // Open the actual key
  989. if (SUCCESS(RegOpenKeyExW(
  990. NETCARD_KEY,
  991. wTemp,
  992. 0,
  993. KEY_READ,
  994. &hKey)))
  995. {
  996. WCHAR wDesc[MAX_PATH];
  997. WCHAR wServName[MAX_PATH];
  998. DWORD dwSize = MAX_PATH;
  999. // check for description
  1000. if (SUCCESS(RegQueryValueExW(
  1001. hKey,
  1002. L"Description",
  1003. 0,
  1004. 0,
  1005. (LPBYTE)wDesc,
  1006. &dwSize)))
  1007. {
  1008. // Max out at 8 characters
  1009. wDesc[8] = L'\0';
  1010. keyn->AddValue(L"ProductName", REG_SZ, (LPBYTE)wDesc);
  1011. }
  1012. // Query for the ServiceName Value
  1013. dwSize = MAX_PATH;
  1014. if (SUCCESS(RegQueryValueExW(
  1015. hKey,
  1016. L"ServiceName",
  1017. 0,
  1018. 0,
  1019. (LPBYTE)wServName,
  1020. &dwSize)))
  1021. {
  1022. if (vkAdapter)
  1023. {
  1024. if (!vkAdapter->AddKey(wServName))
  1025. {
  1026. DPFN( eDbgLevelError, "Error adding the Key to NetBT");
  1027. }
  1028. }
  1029. }
  1030. RegCloseKey(hKey);
  1031. }
  1032. }
  1033. dwIndex++;
  1034. }
  1035. }
  1036. free(wzPath);
  1037. RegCloseKey(hkBase);
  1038. RegCloseKey(hkNetBT);
  1039. }
  1040. ///////////////////////////////////////////////////////////////////////////////
  1041. /*++
  1042. Function Description:
  1043. Add NT4 SP5 Credentials.
  1044. History:
  1045. 05/23/2000 linstev Created
  1046. --*/
  1047. void
  1048. BuildNT4SP5(char* /*szParam*/)
  1049. {
  1050. VIRTUALKEY *key;
  1051. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
  1052. if (key)
  1053. {
  1054. key->AddValue(L"CSDVersion", REG_SZ, (LPBYTE)L"Service Pack 5");
  1055. }
  1056. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
  1057. if (key)
  1058. {
  1059. key->AddValue(L"CurrentVersion", REG_SZ, (LPBYTE)L"4.0");
  1060. }
  1061. key = VRegistry.AddKey(L"HKLM\\System\\CurrentControlSet\\Control\\Windows");
  1062. if (key)
  1063. {
  1064. key->AddValueDWORD(L"CSDVersion", 0x0500);
  1065. }
  1066. }
  1067. ///////////////////////////////////////////////////////////////////////////////
  1068. /*++
  1069. Function Description:
  1070. Add Win2k version number
  1071. History:
  1072. 05/22/2001 linstev Created
  1073. --*/
  1074. void
  1075. BuildNT50(char* /*szParam*/)
  1076. {
  1077. VIRTUALKEY *key;
  1078. // Add Win2k version number
  1079. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
  1080. if (key)
  1081. {
  1082. key->AddValue(L"CurrentVersion", REG_SZ, (LPBYTE)L"5.0");
  1083. key->AddValue(L"ProductName", REG_SZ, (LPBYTE)L"Microsoft Windows 2000");
  1084. }
  1085. }
  1086. ///////////////////////////////////////////////////////////////////////////////
  1087. /*++
  1088. Function Description:
  1089. Add WinXP version number
  1090. History:
  1091. 05/01/2002 linstev Created
  1092. --*/
  1093. void
  1094. BuildNT51(char* /*szParam*/)
  1095. {
  1096. VIRTUALKEY *key;
  1097. // Add Win2k version number
  1098. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
  1099. if (key)
  1100. {
  1101. key->AddValue(L"CurrentVersion", REG_SZ, (LPBYTE)L"5.1");
  1102. key->AddValue(L"ProductName", REG_SZ, (LPBYTE)L"Microsoft Windows XP");
  1103. }
  1104. }
  1105. ///////////////////////////////////////////////////////////////////////////////
  1106. /*++
  1107. Function Description:
  1108. This function adds the Shell compatibility flag for apps that need the
  1109. bogus Ctrl ID of IDOK for ToolBarWindows32 class.
  1110. This also gets applied through the Win2K layer as this is a regression from
  1111. Win2K.
  1112. History:
  1113. 05/04/2001 prashkud Created
  1114. --*/
  1115. void
  1116. BuildBogusCtrlID(char* /*szParam*/)
  1117. {
  1118. CSTRING_TRY
  1119. {
  1120. WCHAR wszFileName[MAX_PATH];
  1121. CString csFileName, csFileTitle;
  1122. CString csRegPath(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\ShellCompatibility\\Applications");
  1123. VIRTUALKEY *Key;
  1124. if (GetModuleFileName(NULL, wszFileName, MAX_PATH))
  1125. {
  1126. csFileName = wszFileName;
  1127. csFileName.GetLastPathComponent(csFileTitle);
  1128. csRegPath.AppendPath(csFileTitle);
  1129. Key = VRegistry.AddKey(csRegPath.Get());
  1130. if (Key)
  1131. {
  1132. Key->AddValue(L"FILEOPENBOGUSCTRLID", REG_SZ, 0, 0);
  1133. LOGN(eDbgLevelInfo, "Added FILEOPENBOGUSCTRLID value for app %S", csFileTitle.Get());
  1134. }
  1135. }
  1136. }
  1137. CSTRING_CATCH
  1138. {
  1139. }
  1140. }
  1141. ///////////////////////////////////////////////////////////////////////////////
  1142. /*++
  1143. Function Description:
  1144. Known different values from Win9x.
  1145. History:
  1146. 05/04/2000 linstev Created
  1147. --*/
  1148. void
  1149. BuildExpanders(char* /*szParam*/)
  1150. {
  1151. VIRTUALKEY *key;
  1152. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion");
  1153. if (key)
  1154. {
  1155. // These are REG_EXPAND_SZ on NT and REG_SZ on Win9x
  1156. key->AddExpander(L"DevicePath");
  1157. key->AddExpander(L"ProgramFilesPath");
  1158. key->AddExpander(L"WallPaperDir");
  1159. }
  1160. }
  1161. ///////////////////////////////////////////////////////////////////////////////
  1162. /*++
  1163. Function Description:
  1164. Add DX7a Credentials.
  1165. History:
  1166. 05/23/2000 linstev Created
  1167. --*/
  1168. void
  1169. BuildDX7A(char* /*szParam*/)
  1170. {
  1171. VIRTUALKEY *key;
  1172. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\DirectX");
  1173. if (key)
  1174. {
  1175. key->AddValue(L"Version", REG_SZ, (LPBYTE)L"4.07.00.0716");
  1176. }
  1177. }
  1178. ///////////////////////////////////////////////////////////////////////////////
  1179. /*++
  1180. Function Description:
  1181. Add DXDIAG path.
  1182. History:
  1183. 04/05/2001 mnikkel Created
  1184. --*/
  1185. void
  1186. BuildDXDiag(char* /*szParam*/)
  1187. {
  1188. VIRTUALKEY *key;
  1189. WCHAR wszPathDir[MAX_PATH];
  1190. DWORD cchSize = GetSystemDirectoryW(wszPathDir, MAX_PATH);
  1191. if (cchSize == 0 || cchSize > MAX_PATH)
  1192. {
  1193. DPFN( eDbgLevelError, "BuildDXDiag: GetSystemDirectory Failed");
  1194. return;
  1195. }
  1196. if (FAILED(StringCchCat(wszPathDir, MAX_PATH, L"\\dxdiag.exe")))
  1197. {
  1198. return;
  1199. }
  1200. key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\DXDIAG.EXE");
  1201. if (key)
  1202. {
  1203. key->AddValue(L"", REG_EXPAND_SZ, (LPBYTE)wszPathDir, 0);
  1204. }
  1205. }
  1206. ///////////////////////////////////////////////////////////////////////////////
  1207. /*++
  1208. Function Description:
  1209. Add FullScreen == 1 to fix bug in Future Cop that makes it not always run
  1210. in fullscreen mode.
  1211. History:
  1212. 09/01/2000 linstev Created
  1213. --*/
  1214. void
  1215. BuildFutureCop(char* /*szParam*/)
  1216. {
  1217. VIRTUALKEY *key;
  1218. key = VRegistry.AddKey(L"HKLM\\Software\\Electronic Arts\\Future Cop\\Settings");
  1219. if (key)
  1220. {
  1221. key->AddValueDWORD(L"FullScreen", 0x01);
  1222. }
  1223. }
  1224. ///////////////////////////////////////////////////////////////////////////////
  1225. /*++
  1226. Function Description:
  1227. Return to Krondor attempts to find ACM drivers, this key was moved and renamed.
  1228. Was: HKLM\System\CurrentControlSet\Control\MediaResources\ACM\MSACM.MSADPCM\drivers = msadp32.acm
  1229. Is: HKLM\Software\Microsoft\Windows NT\CurrentVersion\Drivers32\Msacm.Msadpcm = msadp32.acm
  1230. Grab the current value from the registry, and build a virtual key and value
  1231. History:
  1232. 09/06/2000 robkenny Created
  1233. --*/
  1234. void
  1235. BuildKrondor(char* /*szParam*/)
  1236. {
  1237. HKEY msadpcmKey;
  1238. LONG error = RegOpenKeyExW(
  1239. HKEY_LOCAL_MACHINE,
  1240. L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32",
  1241. 0, KEY_READ, &msadpcmKey);
  1242. if (SUCCESS(error))
  1243. {
  1244. // Found the key, grab the name of the driver
  1245. WCHAR driverName[MAX_PATH];
  1246. DWORD driverNameSize = sizeof(driverName);
  1247. DWORD driverNameType = REG_SZ;
  1248. error = RegQueryValueExW(
  1249. msadpcmKey,
  1250. L"MSACM.MSADPCM",
  1251. 0, &driverNameType,
  1252. (LPBYTE)driverName,
  1253. &driverNameSize);
  1254. if (SUCCESS(error))
  1255. {
  1256. // We got all the data, so we can now add the virtual key and value
  1257. VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\System\\CurrentControlSet\\Control\\MediaResources\\ACM\\MSACM.MSADPCM");
  1258. if (key)
  1259. {
  1260. key->AddValue(L"driver", REG_SZ, (LPBYTE)driverName, 0);
  1261. }
  1262. }
  1263. RegCloseKey(msadpcmKey);
  1264. }
  1265. }
  1266. ///////////////////////////////////////////////////////////////////////////////
  1267. /*++
  1268. Function Description:
  1269. Redirect changes from CURRENT_USER to LOCAL_MACHINE.
  1270. History:
  1271. 09/17/2000 linstev Created
  1272. --*/
  1273. void
  1274. BuildProfile(char* /*szParam*/)
  1275. {
  1276. VRegistry.AddRedirect(
  1277. L"HKCU\\Software\\Microsoft\\Windows",
  1278. L"HKLM\\Software\\Microsoft\\Windows");
  1279. }
  1280. ///////////////////////////////////////////////////////////////////////////////
  1281. /*++
  1282. Function Description:
  1283. In Spell it Deluxe setup, the path for the SpeechFonts DLL ECN_1K8.DLL is
  1284. hardcoded to " C:\Voices32". If the installation is on a D: partition, the
  1285. LoadLibraryA( ) call fails and the App AV's.
  1286. Now the current partition drive will be taken and added to the path.
  1287. History:
  1288. 09/21/2000 prashkud Created
  1289. --*/
  1290. void
  1291. BuildSpellItDeluxe(char* /*szParam*/)
  1292. {
  1293. HKEY hSpeechFonts;
  1294. WCHAR wszSystemDir[MAX_PATH], wszPathDir[MAX_PATH];
  1295. if (GetSystemDirectory(wszSystemDir, MAX_PATH))
  1296. {
  1297. *(wszSystemDir+3) = L'\0';
  1298. }
  1299. else
  1300. {
  1301. DPFN( eDbgLevelError, "SpellIt: GetSystemDirectory Failed");
  1302. return;
  1303. }
  1304. if (FAILED(StringCchCopy(wszPathDir, MAX_PATH, wszSystemDir)))
  1305. {
  1306. return;
  1307. }
  1308. if (FAILED(StringCchCat(wszPathDir, MAX_PATH, L"Voices32")))
  1309. {
  1310. return;
  1311. }
  1312. LONG error = RegOpenKeyExW(
  1313. HKEY_LOCAL_MACHINE,
  1314. L"Software\\FirstByte\\ProVoice\\SpeechFonts",
  1315. 0, KEY_READ | KEY_WRITE, &hSpeechFonts);
  1316. if (SUCCESS(error))
  1317. {
  1318. if (FAILED(RegSetValueExW(
  1319. hSpeechFonts,
  1320. L"Path",
  1321. 0,
  1322. REG_SZ,
  1323. (LPBYTE) wszPathDir,
  1324. wcslen(wszPathDir) * sizeof(WCHAR))))
  1325. {
  1326. DPFN( eDbgLevelError, "SpellIt: RegSetValueEx failed");
  1327. }
  1328. RegCloseKey(hSpeechFonts);
  1329. }
  1330. else
  1331. {
  1332. DPFN( eDbgLevelError, "SpellIt: RegOpenKeyExW failed");
  1333. }
  1334. }
  1335. ///////////////////////////////////////////////////////////////////////////////
  1336. /*++
  1337. Function Description:
  1338. Some applications need internet explorer for their functionality. The
  1339. applications try get the version of the internet explorer from the following
  1340. registry key : HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion. But
  1341. under WHISTLER environment, the key entry will not be created. So, the apps
  1342. fail to continue.
  1343. The app looks for the version info of the Internet Explorer in the registry
  1344. at HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion from the "Plus!
  1345. VersionNumber" Key. In WHISTLER the key will not be created in the registry.
  1346. To solve the problem we use Virtual Registry Keys. So, the app will assume
  1347. the key is existing in the registry.
  1348. WHISTLER, by default, will install I.E.6. So, I have created the key as
  1349. "IE 6 6.0.2404.0000" and this is the latest version of I.E. on WHISTLER as
  1350. on today.(11/22/2000).
  1351. History:
  1352. 11/22/2000 v-rbabu Created
  1353. 07/03/2001 linstev Added IE 5.5 from Win2k
  1354. --*/
  1355. void
  1356. BuildIE401(char* /*szParam*/)
  1357. {
  1358. VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Internet Explorer");
  1359. if (key)
  1360. {
  1361. key->AddValue(L"Version", REG_SZ, (LPBYTE)L"4.72.2106.9", 0);
  1362. }
  1363. }
  1364. void
  1365. BuildIE55(char* /*szParam*/)
  1366. {
  1367. VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Internet Explorer");
  1368. if (key)
  1369. {
  1370. key->AddValue(L"Version", REG_SZ, (LPBYTE)L"5.50.4522.1800", 0);
  1371. }
  1372. }
  1373. void
  1374. BuildIE60(char* /*szParam*/)
  1375. {
  1376. WCHAR wIE[] = L"IE 6 6.0.2404.0000";
  1377. // Now add the virtual key and value
  1378. VIRTUALKEY *key = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion");
  1379. if (key)
  1380. {
  1381. key->AddValue(L"Plus! VersionNumber", REG_SZ, (LPBYTE)wIE, 0);
  1382. }
  1383. }
  1384. ///////////////////////////////////////////////////////////////////////////////
  1385. /*++
  1386. Function Description:
  1387. The idea here is to fix apps that depend on short names for input devices.
  1388. We just trim the name to 32 characters (including terminator).
  1389. History:
  1390. 12/06/2000 linstev Created
  1391. --*/
  1392. void
  1393. BuildJoystick(char* /*szParam*/)
  1394. {
  1395. HKEY hJoystickKey;
  1396. WCHAR wszKeyName[MAX_PATH];
  1397. DWORD dwIndex;
  1398. const WCHAR wszJoystickPath[] = L"System\\CurrentControlSet\\Control\\MediaProperties\\PrivateProperties\\Joystick\\OEM";
  1399. if (FAILURE(RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszJoystickPath, 0, KEY_READ, &hJoystickKey)))
  1400. {
  1401. DPFN( eDbgLevelSpew, "[Joystick hack] No joysticks found");
  1402. return;
  1403. }
  1404. //
  1405. // Enum the keys under Joystick and make virtual entries
  1406. //
  1407. dwIndex = 0;
  1408. while (SUCCESS(RegEnumKeyW(hJoystickKey, dwIndex, wszKeyName, MAX_PATH)))
  1409. {
  1410. WCHAR wszID[MAX_PATH] = L"HKLM\\";
  1411. if (SUCCEEDED(StringCchCat(wszID, MAX_PATH, wszJoystickPath)) &&
  1412. SUCCEEDED(StringCchCat(wszID, MAX_PATH, L"\\")) &&
  1413. SUCCEEDED(StringCchCat(wszID, MAX_PATH, wszKeyName)))
  1414. {
  1415. HKEY hkOEM;
  1416. if (SUCCESS(RegOpenKeyExW(hJoystickKey, wszKeyName, 0, KEY_READ, &hkOEM)))
  1417. {
  1418. WCHAR wszName[MAX_PATH + 1];
  1419. DWORD dwSize = MAX_PATH * sizeof(WCHAR);
  1420. if (SUCCESS(RegQueryValueExW(hkOEM, L"OEMName", 0, NULL, (LPBYTE) wszName, &dwSize)))
  1421. {
  1422. if (dwSize > 31 * sizeof(WCHAR))
  1423. {
  1424. VIRTUALKEY *key = VRegistry.AddKey(wszID);
  1425. if (key)
  1426. {
  1427. dwSize = 31 * sizeof(WCHAR);
  1428. wszName[31] = L'\0';
  1429. key->AddValue(L"OEMName", REG_SZ, (LPBYTE) wszName);
  1430. }
  1431. }
  1432. }
  1433. RegCloseKey(hkOEM);
  1434. }
  1435. }
  1436. dwIndex++;
  1437. }
  1438. RegCloseKey(hJoystickKey);
  1439. }
  1440. ///////////////////////////////////////////////////////////////////////////////
  1441. /*++
  1442. Function Description:
  1443. Hack for Adobe Illustrator 8
  1444. History:
  1445. 12/18/2000 linstev Created
  1446. --*/
  1447. void
  1448. BuildIllustrator8(char* /*szParam*/)
  1449. {
  1450. if (ShouldApplyShim())
  1451. {
  1452. // Redirect everything
  1453. VRegistry.AddRedirect(
  1454. L"HKLM\\Software\\Adobe",
  1455. L"HKCU\\Software\\Adobe");
  1456. }
  1457. }
  1458. ///////////////////////////////////////////////////////////////////////////////
  1459. /*++
  1460. Function Description:
  1461. Hack for Adobe PageMaker 6.5
  1462. History:
  1463. 02/27/2001 maonis Created
  1464. --*/
  1465. void BuildPageMaker65(char* /*szParam*/)
  1466. {
  1467. if (ShouldApplyShim())
  1468. {
  1469. VRegistry.AddRedirect(
  1470. L"HKCU\\Software\\Adobe\\PageMaker65",
  1471. L"HKLM\\Software\\Adobe\\PageMaker65");
  1472. }
  1473. }
  1474. ///////////////////////////////////////////////////////////////////////////////
  1475. /*++
  1476. Function Description:
  1477. Hack for PageKeepPro30.
  1478. History:
  1479. 01/15/2000 maonis Created
  1480. --*/
  1481. void
  1482. BuildPageKeepProDirectory(char* /*szParam*/)
  1483. {
  1484. // We cannot call ShGetSpecialFolderPath since we are still in our DLL main,
  1485. // so we get the path to "My Documents" directly from the registry.
  1486. HKEY hkFolders;
  1487. if (SUCCESS(RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", 0, KEY_READ, &hkFolders)))
  1488. {
  1489. DWORD dwType;
  1490. WCHAR wszPath[MAX_PATH];
  1491. DWORD dwSize = MAX_PATH*sizeof(WCHAR);
  1492. if (SUCCESS(RegQueryValueExW( hkFolders, L"Personal", NULL, &dwType, (LPBYTE)wszPath, &dwSize)))
  1493. {
  1494. VIRTUALKEY *key = VRegistry.AddKey(L"HKCU\\Software\\Caere Corp\\PageKeepPro30\\Preference");
  1495. if (key)
  1496. {
  1497. key->AddValue(L"Directory", REG_EXPAND_SZ, (LPBYTE)wszPath, 0);
  1498. }
  1499. }
  1500. RegCloseKey(hkFolders);
  1501. }
  1502. // Secondly, since we don't support using UI-less mode for TWAIN layer
  1503. // we mandatorily set BASICMODE for scanners to 2 instead of 0 - 2 means
  1504. // to always use UI mode.
  1505. HKEY hkScanners;
  1506. WCHAR wszKeyName[MAX_PATH] = L"";
  1507. DWORD dwIndex;
  1508. const WCHAR wszScanner[] = L"Software\\Caere Corp\\Scan Manager\\4.02\\Scanners";
  1509. if (FAILURE(RegOpenKeyExW(HKEY_LOCAL_MACHINE, wszScanner,0, KEY_READ, &hkScanners)))
  1510. {
  1511. DPFN( eDbgLevelSpew, "[PageKeepPro 3.0] No scanner found");
  1512. return;
  1513. }
  1514. dwIndex = 0;
  1515. while (SUCCESS(RegEnumKeyW(hkScanners, dwIndex, wszKeyName, MAX_PATH)))
  1516. {
  1517. WCHAR wszID[MAX_PATH] = L"HKLM\\";
  1518. if (SUCCEEDED(StringCchCat(wszID, MAX_PATH,wszScanner)) &&
  1519. SUCCEEDED(StringCchCat(wszID, MAX_PATH,L"\\")) &&
  1520. SUCCEEDED(StringCchCat(wszID, MAX_PATH,wszKeyName)))
  1521. {
  1522. HKEY hkScanner;
  1523. if (SUCCESS(RegOpenKeyExW(hkScanners, wszKeyName, 0, KEY_READ, &hkScanner)))
  1524. {
  1525. VIRTUALKEY *keyMode = VRegistry.AddKey(wszID);
  1526. if (keyMode)
  1527. {
  1528. keyMode->AddValueDWORD(L"BASICMODE", 2);
  1529. }
  1530. RegCloseKey(hkScanner);
  1531. }
  1532. }
  1533. dwIndex++;
  1534. }
  1535. RegCloseKey(hkScanners);
  1536. }
  1537. ///////////////////////////////////////////////////////////////////////////////
  1538. /*++
  1539. Function Description:
  1540. Hack for ModemWizard because the keys moved
  1541. History:
  1542. 01/18/2001 linstev & a-leelat Created
  1543. --*/
  1544. void
  1545. BuildModemWizard(char* /*szParam*/)
  1546. {
  1547. // Redirect everything
  1548. VRegistry.AddRedirect(
  1549. L"HKLM\\SYSTEM\\CurrentControlSet\\Enum\\Root",
  1550. L"HKLM\\SYSTEM\\CurrentControlSet\\Enum");
  1551. }
  1552. ///////////////////////////////////////////////////////////////////////////////
  1553. /*++
  1554. Function Description:
  1555. Hack for Office2000 Developer 1.5 which looks in the wrong place for
  1556. components.
  1557. From ChetanP:
  1558. Basically the redirect code would have to do something like this -
  1559. if HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\<user sid>\Components\359E92CC2CB71D119A12000A9CE1A22A
  1560. exists, redirect to that location
  1561. else if HKLM\Software\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\359E92CC2CB71D119A12000A9CE1A22A
  1562. exists, redirect to that location
  1563. else, no redirection.
  1564. Whistler Bug #241596
  1565. History:
  1566. 02/01/2001 linstev Created
  1567. --*/
  1568. #define SIZE_OF_TOKEN_INFORMATION \
  1569. sizeof(TOKEN_USER) + \
  1570. sizeof(SID) + \
  1571. sizeof(ULONG) * SID_MAX_SUB_AUTHORITIES
  1572. #define SIZE_OF_SID_MAX \
  1573. sizeof(SID) + \
  1574. SID_MAX_SUB_AUTHORITIES * sizeof(DWORD)
  1575. #define cchMaxSID 256
  1576. //
  1577. // Get the current SID as text
  1578. //
  1579. BOOL
  1580. GetStringSID(
  1581. WCHAR *szSID
  1582. )
  1583. {
  1584. BOOL bRet = TRUE;
  1585. HANDLE hToken = NULL;
  1586. int i;
  1587. PISID pISID;
  1588. UCHAR rgSID[SIZE_OF_SID_MAX];
  1589. UCHAR TokenInformation[SIZE_OF_TOKEN_INFORMATION];
  1590. ULONG ReturnLength;
  1591. WCHAR Buffer[cchMaxSID];
  1592. //
  1593. // Get a token
  1594. //
  1595. if (!OpenThreadToken(
  1596. GetCurrentThread(),
  1597. TOKEN_IMPERSONATE | TOKEN_QUERY,
  1598. TRUE,
  1599. &hToken))
  1600. {
  1601. if (GetLastError() == ERROR_NO_TOKEN)
  1602. {
  1603. bRet = OpenProcessToken(
  1604. GetCurrentProcess(),
  1605. TOKEN_IMPERSONATE | TOKEN_QUERY,
  1606. &hToken);
  1607. }
  1608. else
  1609. {
  1610. bRet = FALSE;
  1611. }
  1612. }
  1613. if (!bRet)
  1614. {
  1615. DPFN( eDbgLevelError, "[GetStringSID] Failed to OpenProcessToken");
  1616. goto Exit;
  1617. }
  1618. //
  1619. // Get the binary form of the token
  1620. //
  1621. bRet = GetTokenInformation(
  1622. hToken,
  1623. TokenUser,
  1624. TokenInformation,
  1625. sizeof(TokenInformation),
  1626. &ReturnLength);
  1627. if (bRet)
  1628. {
  1629. bRet = FALSE;
  1630. pISID = (PISID)((PTOKEN_USER) TokenInformation)->User.Sid;
  1631. if (!CopySid(SIZE_OF_SID_MAX, rgSID, pISID))
  1632. {
  1633. DPFN( eDbgLevelError, "CopySID failed");
  1634. goto Exit;
  1635. }
  1636. //
  1637. // Get the text form of the token
  1638. //
  1639. HRESULT hr = StringCchPrintf(Buffer, cchMaxSID,L"S-%u-", (USHORT) pISID->Revision);
  1640. if (FAILED(hr))
  1641. {
  1642. goto Exit;
  1643. }
  1644. hr = StringCchCopy(szSID, 1024, Buffer);
  1645. if (FAILED(hr))
  1646. {
  1647. goto Exit;
  1648. }
  1649. if ((pISID->IdentifierAuthority.Value[0] != 0) ||
  1650. (pISID->IdentifierAuthority.Value[1] != 0))
  1651. {
  1652. hr = StringCchPrintf(Buffer, cchMaxSID,
  1653. L"0x%02hx%02hx%02hx%02hx%02hx%02hx",
  1654. (USHORT) pISID->IdentifierAuthority.Value[0],
  1655. (USHORT) pISID->IdentifierAuthority.Value[1],
  1656. (USHORT) pISID->IdentifierAuthority.Value[2],
  1657. (USHORT) pISID->IdentifierAuthority.Value[3],
  1658. (USHORT) pISID->IdentifierAuthority.Value[4],
  1659. (USHORT) pISID->IdentifierAuthority.Value[5]);
  1660. if (FAILED(hr))
  1661. {
  1662. goto Exit;
  1663. }
  1664. hr = StringCchCat(szSID, 1024, Buffer);
  1665. if (FAILED(hr))
  1666. {
  1667. goto Exit;
  1668. }
  1669. }
  1670. else
  1671. {
  1672. ULONG Tmp =
  1673. (ULONG) pISID->IdentifierAuthority.Value[5] +
  1674. (ULONG)(pISID->IdentifierAuthority.Value[4] << 8) +
  1675. (ULONG)(pISID->IdentifierAuthority.Value[3] << 16) +
  1676. (ULONG)(pISID->IdentifierAuthority.Value[2] << 24);
  1677. hr = StringCchPrintf(Buffer, cchMaxSID, L"%lu", Tmp);
  1678. if (FAILED(hr))
  1679. {
  1680. goto Exit;
  1681. }
  1682. hr = StringCchCat(szSID, 1024, Buffer);
  1683. if (FAILED(hr))
  1684. {
  1685. goto Exit;
  1686. }
  1687. }
  1688. for (i=0; i < pISID->SubAuthorityCount; i++)
  1689. {
  1690. hr = StringCchPrintf(Buffer, cchMaxSID, L"-%lu", pISID->SubAuthority[i]);
  1691. if (FAILED(hr))
  1692. {
  1693. goto Exit;
  1694. }
  1695. hr = StringCchCat(szSID, 1024, Buffer);
  1696. if (FAILED(hr))
  1697. {
  1698. goto Exit;
  1699. }
  1700. }
  1701. }
  1702. else
  1703. {
  1704. DPFN( eDbgLevelError, "GetTokenInformation failed");
  1705. goto Exit;
  1706. }
  1707. bRet = TRUE;
  1708. Exit:
  1709. if (hToken)
  1710. {
  1711. CloseHandle(hToken);
  1712. }
  1713. return bRet;
  1714. }
  1715. void
  1716. BuildMSI(char* /*szParam*/)
  1717. {
  1718. WCHAR szSID[1024];
  1719. // Get the current users SID as a string
  1720. if (!GetStringSID(szSID))
  1721. {
  1722. DPFN( eDbgLevelError, "BuildMSI Failed");
  1723. return;
  1724. }
  1725. HKEY hKey;
  1726. WCHAR szTemp[1024];
  1727. const WCHAR szBase[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Installer\\UserData\\";
  1728. const WCHAR szComp[] = L"\\Components\\359E92CC2CB71D119A12000A9CE1A22A";
  1729. HRESULT hr;
  1730. hr = StringCchCopy(szTemp, 1024, szBase);
  1731. if (FAILED(hr))
  1732. {
  1733. return;
  1734. }
  1735. hr = StringCchCat(szTemp, 1024, szSID);
  1736. if (FAILED(hr))
  1737. {
  1738. return;
  1739. }
  1740. hr = StringCchCat(szTemp, 1024, szComp);
  1741. if (FAILED(hr))
  1742. {
  1743. return;
  1744. }
  1745. // Attempt to open szBase + <user sid> + szComp
  1746. if (RegOpenKeyW(HKEY_LOCAL_MACHINE, szTemp, &hKey) != ERROR_SUCCESS)
  1747. {
  1748. RegCloseKey(hKey);
  1749. // Attempt to open szBase + S-1-5-18 + szComp
  1750. hr = StringCchCopy(szTemp, 1024, szBase);
  1751. if (FAILED(hr))
  1752. {
  1753. return;
  1754. }
  1755. hr = StringCchCat(szTemp, 1024, L"S-1-5-18");
  1756. if (FAILED(hr))
  1757. {
  1758. return;
  1759. }
  1760. hr = StringCchCat(szTemp, 1024, szComp);
  1761. if (FAILED(hr))
  1762. {
  1763. return;
  1764. }
  1765. if (RegOpenKeyW(HKEY_LOCAL_MACHINE, szTemp, &hKey) != ERROR_SUCCESS)
  1766. {
  1767. DPFN( eDbgLevelError, "BuildMSI Failed to find keys");
  1768. RegCloseKey(hKey);
  1769. return;
  1770. }
  1771. }
  1772. // Redirect as appropriate
  1773. WCHAR szTarget[1024] = L"HKLM\\";
  1774. hr = StringCchCat(szTarget,1024, szTemp);
  1775. if (FAILED(hr))
  1776. {
  1777. return;
  1778. }
  1779. VRegistry.AddRedirect(
  1780. L"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Installer\\Components\\359E92CC2CB71D119A12000A9CE1A22A",
  1781. szTarget);
  1782. }
  1783. ///////////////////////////////////////////////////////////////////////////////
  1784. /*++
  1785. Function Description:
  1786. Added FileNet Web Server
  1787. History:
  1788. 02/06/2001 a-larrsh Created
  1789. --*/
  1790. void
  1791. BuildFileNetWebServer(char* /*szParam*/)
  1792. {
  1793. VIRTUALKEY *key;
  1794. key = VRegistry.AddKey(L"HKLM\\System\\CurrentControlSet\\Services\\W3SVC\\Parameters");
  1795. if (key)
  1796. {
  1797. key->AddValueDWORD(L"MajorVersion", 0x00000005);
  1798. }
  1799. }
  1800. ///////////////////////////////////////////////////////////////////////////////
  1801. /*++
  1802. Function Description:
  1803. Added default printer key. We have to effectively delay load this, because
  1804. we can't be guaranteed that winspool will have had it's init routine loaded
  1805. before us. Of course, we still can't guarentee that somebody won't try to
  1806. get at this key from their dllmain, so we wrap the whole thing in an
  1807. exception handler.
  1808. History:
  1809. 02/06/2001 linstev & mnikkel Created
  1810. --*/
  1811. LONG
  1812. WINAPI
  1813. VR_Printer(
  1814. OPENKEY * /* key */,
  1815. VIRTUALKEY * /* vkey */,
  1816. VIRTUALVAL *vvalue
  1817. )
  1818. {
  1819. LOGN( eDbgLevelInfo, "[Printer] Query for legacy printer");
  1820. __try
  1821. {
  1822. DWORD dwSize;
  1823. // Get the default printer name
  1824. if (GetDefaultPrinterW(NULL, &dwSize) == 0)
  1825. {
  1826. // Now that we have the right size, allocate a buffer
  1827. if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
  1828. {
  1829. LPWSTR pszName = (LPWSTR) malloc(dwSize * sizeof(WCHAR));
  1830. if (pszName)
  1831. {
  1832. // Now get the default printer with the right buffer size.
  1833. if (GetDefaultPrinterW(pszName, &dwSize))
  1834. {
  1835. //
  1836. // Set up the virtual value. Note we don't have free the
  1837. // memory since it's a once off allocation that persists
  1838. // with the value
  1839. //
  1840. vvalue->cbData = dwSize * sizeof(WCHAR);
  1841. vvalue->lpData = (LPBYTE) pszName;
  1842. //
  1843. // Never call us again, since we've found the printer and
  1844. // stored it in our virtual value
  1845. //
  1846. vvalue->pfnQueryValue = NULL;
  1847. return ERROR_SUCCESS;
  1848. }
  1849. else
  1850. {
  1851. //
  1852. // We failed to get the default printer, may as well
  1853. // clean up gracefully.
  1854. //
  1855. free(pszName);
  1856. }
  1857. }
  1858. }
  1859. }
  1860. DPFN( eDbgLevelError, "[Printer] No printers found or out of memory");
  1861. }
  1862. __except(EXCEPTION_EXECUTE_HANDLER)
  1863. {
  1864. DPFN( eDbgLevelError, "[Printer] Exception encountered, winspool not initialized?");
  1865. }
  1866. //
  1867. // Going for the graceful exit: there's no default printer or we get an
  1868. // error trying to find it.
  1869. //
  1870. return ERROR_FILE_NOT_FOUND;
  1871. }
  1872. void
  1873. BuildPrinter(char* /*szParam*/)
  1874. {
  1875. VIRTUALKEY *key;
  1876. key = VRegistry.AddKey(L"HKCC\\System\\CurrentControlSet\\Control\\Print\\Printers");
  1877. if (key)
  1878. {
  1879. VIRTUALVAL *val = key->AddValue(L"Default", REG_SZ, 0, 0);
  1880. if (val)
  1881. {
  1882. val->pfnQueryValue = VR_Printer;
  1883. }
  1884. }
  1885. }
  1886. ///////////////////////////////////////////////////////////////////////////////
  1887. /*++
  1888. Function Description:
  1889. The app is multi-threaded, but the app sets the DX DDSCL_MULTITHREADED flag
  1890. too late: after D3D is initialized. This hack basically turns on
  1891. multi-threaded locking for D3D.
  1892. History:
  1893. 02/27/2001 rankala + ssteiner Created
  1894. --*/
  1895. void
  1896. BuildStarTrekArmada(char* /*szParam*/)
  1897. {
  1898. VIRTUALKEY *key;
  1899. key = VRegistry.AddKey(L"HKLM\\SOFTWARE\\Microsoft\\Direct3D");
  1900. if (key)
  1901. {
  1902. key->AddValueDWORD(L"DisableST", 1);
  1903. }
  1904. }
  1905. /*++
  1906. Function Description:
  1907. This function gets called whenever the app queries for "Health" value.This
  1908. is not set properly by the app and this causes the app not to function
  1909. properly. We fix this issue by obtaining the right path which the app sets
  1910. in another registry key and sending that back as the value for "Health".
  1911. History:
  1912. 05/04/2001 prashkud Created
  1913. --*/
  1914. LONG
  1915. WINAPI
  1916. VR_MSA2001(
  1917. OPENKEY * /* key */,
  1918. VIRTUALKEY * /* vkey */,
  1919. VIRTUALVAL *vvalue
  1920. )
  1921. {
  1922. HKEY hPath = NULL;
  1923. LONG lRet = ERROR_SUCCESS;
  1924. CSTRING_TRY
  1925. {
  1926. CString csBody5Reg(L"Software\\Classes\\Body5\\Open\\Shell\\Command");
  1927. WCHAR wPath[MAX_PATH];
  1928. DWORD dwSize = MAX_PATH*sizeof(WCHAR);
  1929. if (FAILURE(lRet = RegOpenKeyExW(
  1930. HKEY_LOCAL_MACHINE,
  1931. csBody5Reg.Get(),
  1932. 0, KEY_READ, &hPath)))
  1933. {
  1934. DPFN(eDbgLevelError, "MSA2001: RegOpenKeyExW failed");
  1935. goto exit;
  1936. }
  1937. if (FAILURE( lRet = RegQueryValueExW(
  1938. hPath, L"", // Default value
  1939. 0, NULL, (LPBYTE)wPath, &dwSize)))
  1940. {
  1941. DPFN(eDbgLevelError, "MSA2001: RegQueryValueEx failed");
  1942. goto exit;
  1943. }
  1944. CString csPath(wPath);
  1945. int len = csPath.Find(L" ");
  1946. // We get the space in the string
  1947. wPath[len] = L'\0';
  1948. csPath = wPath;
  1949. CString csPathName;
  1950. csPath.GetNotLastPathComponent(csPathName);
  1951. vvalue->cbData = (csPathName.GetLength()+1) * sizeof(WCHAR);
  1952. vvalue->lpData = (LPBYTE) malloc(vvalue->cbData);
  1953. if (!vvalue->lpData)
  1954. {
  1955. DPFN(eDbgLevelError, szOutOfMemory);
  1956. lRet = ERROR_NOT_ENOUGH_MEMORY;
  1957. goto exit;
  1958. }
  1959. MoveMemory(vvalue->lpData, csPathName.Get(), vvalue->cbData);
  1960. DPFN(eDbgLevelInfo, "MSA2001: The data value is %S",csPathName.Get());
  1961. lRet = ERROR_SUCCESS;
  1962. vvalue->dwType = REG_SZ;
  1963. return lRet;
  1964. }
  1965. CSTRING_CATCH
  1966. {
  1967. }
  1968. exit:
  1969. if (hPath)
  1970. {
  1971. RegCloseKey(hPath);
  1972. }
  1973. return lRet;
  1974. }
  1975. /*++
  1976. Function Description:
  1977. History:
  1978. 04/27/2001 prashkud Created
  1979. --*/
  1980. void
  1981. BuildMSA2001(char* /*szParam*/)
  1982. {
  1983. VIRTUALKEY *Key = VRegistry.AddKey(L"HKLM\\Software\\Encore Software\\Middle School Advantage 2001\\1.0");
  1984. if (Key)
  1985. {
  1986. VIRTUALVAL *val = Key->AddValue(L"health", REG_SZ, 0, 0);
  1987. if (val)
  1988. {
  1989. val->pfnQueryValue = VR_MSA2001;
  1990. DPFN(eDbgLevelInfo, "[Middle School Advantage 2001] Added Health");
  1991. }
  1992. }
  1993. }
  1994. ///////////////////////////////////////////////////////////////////////////////
  1995. /*++
  1996. Function Description:
  1997. Hack for Nowro Blue (Korean App)
  1998. History:
  1999. 05/17/2001 hioh Created
  2000. --*/
  2001. void BuildNowroBlue(char* /*szParam*/)
  2002. {
  2003. // Below HKCU include location of files.
  2004. // Non install user could not locate files and could not run app properly.
  2005. // Redirect from HKCU to HKLM for commonly use.
  2006. VRegistry.AddRedirect(
  2007. L"HKCU\\Software\\nowcom",
  2008. L"HKLM\\Software\\nowcom");
  2009. VRegistry.AddRedirect(
  2010. L"HKCU\\Software\\nowirc",
  2011. L"HKLM\\Software\\nowirc");
  2012. VRegistry.AddRedirect(
  2013. L"HKCU\\Software\\nownuri",
  2014. L"HKLM\\Software\\nownuri");
  2015. }
  2016. ///////////////////////////////////////////////////////////////////////////////
  2017. /*++
  2018. Function Description:
  2019. To enable the trial version, WebWasher looks for RegisteredOrganization at:
  2020. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion
  2021. rather than:
  2022. HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion
  2023. History:
  2024. 05/31/2001 stevepro Created
  2025. --*/
  2026. void
  2027. BuildRegisteredOwner(char* /*szParam*/)
  2028. {
  2029. HKEY hkCurrentVersion;
  2030. if (FAILURE(RegOpenKeyExW(
  2031. HKEY_LOCAL_MACHINE,
  2032. L"Software\\Microsoft\\Windows NT\\CurrentVersion",
  2033. 0,
  2034. KEY_READ,
  2035. &hkCurrentVersion)))
  2036. {
  2037. return;
  2038. }
  2039. // Read the registered owner values from the old location
  2040. WCHAR szOrg[MAX_PATH];
  2041. *szOrg = L'\0';
  2042. DWORD dwSize = ARRAYSIZE(szOrg);
  2043. if (FAILURE(RegQueryValueExW(
  2044. hkCurrentVersion,
  2045. L"RegisteredOrganization",
  2046. NULL,
  2047. NULL,
  2048. (LPBYTE)szOrg,
  2049. &dwSize)))
  2050. {
  2051. RegCloseKey(hkCurrentVersion);
  2052. return;
  2053. }
  2054. WCHAR szOwner[MAX_PATH];
  2055. *szOwner = L'\0';
  2056. dwSize = ARRAYSIZE(szOwner);
  2057. if (FAILURE(RegQueryValueExW(
  2058. hkCurrentVersion,
  2059. L"RegisteredOwner",
  2060. NULL,
  2061. NULL,
  2062. (LPBYTE)szOwner,
  2063. &dwSize)))
  2064. {
  2065. RegCloseKey(hkCurrentVersion);
  2066. return;
  2067. }
  2068. RegCloseKey(hkCurrentVersion);
  2069. // Add them as virtual values to the new location
  2070. if (*szOrg || *szOwner)
  2071. {
  2072. VIRTUALKEY *pKey = VRegistry.AddKey(L"HKLM\\Software\\Microsoft\\Windows\\CurrentVersion");
  2073. if (pKey)
  2074. {
  2075. if (*szOrg)
  2076. {
  2077. pKey->AddValue(L"RegisteredOrganization", REG_SZ, (LPBYTE)szOrg);
  2078. }
  2079. if (*szOwner)
  2080. {
  2081. pKey->AddValue(L"RegisteredOwner", REG_SZ, (LPBYTE)szOwner);
  2082. }
  2083. }
  2084. }
  2085. }
  2086. ///////////////////////////////////////////////////////////////////////////////
  2087. /*++
  2088. Function Description:
  2089. The ACT CD of Princeton review looks for and, if not found, creates an "MSN"
  2090. key illegally in the root of HKLM. Win9x allows this, but Win2k does not.
  2091. This fix will redirect the program to look in the normal location for this
  2092. key.
  2093. History:
  2094. 02/22/2001 a-noahy Created
  2095. --*/
  2096. void
  2097. BuildPrincetonACT(char* /*szParam*/)
  2098. {
  2099. VRegistry.AddRedirect(
  2100. L"HKLM\\MSN",
  2101. L"HKLM\\Software\\Microsoft\\MSN");
  2102. }
  2103. ///////////////////////////////////////////////////////////////////////////////
  2104. /*++
  2105. Function Description:
  2106. Fix for HEDZ which uses the registry to determine the resolution
  2107. History:
  2108. 06/28/2001 linstev Created
  2109. --*/
  2110. void
  2111. BuildHEDZ(char* /*szParam*/)
  2112. {
  2113. VIRTUALKEY *key;
  2114. //
  2115. // Add just what this app needs - don't bother with full emulation of this
  2116. // part of the registry
  2117. //
  2118. key = VRegistry.AddKey(L"HKLM\\Config\\0001\\Display\\Settings");
  2119. if (key)
  2120. {
  2121. WCHAR wzRes[10];
  2122. DWORD dwCX, dwCY;
  2123. key->AddValue(L"BitsPerPixel", REG_SZ, (LPBYTE)L"16");
  2124. dwCX = GetSystemMetrics(SM_CXSCREEN);
  2125. dwCY = GetSystemMetrics(SM_CYSCREEN);
  2126. if (FAILED(StringCchPrintfW(
  2127. wzRes, 10, L"%d,%d", dwCX, dwCY)))
  2128. {
  2129. return;
  2130. }
  2131. key->AddValue(L"Resolution", REG_SZ, (LPBYTE)wzRes);
  2132. }
  2133. }
  2134. ///////////////////////////////////////////////////////////////////////////////
  2135. /*++
  2136. Function Description:
  2137. Called by BuildAirlineTycoon to recursively search for the key describing a CDROM
  2138. History:
  2139. 08/07/2001 mikrause Created
  2140. --*/
  2141. void FindCDROMKey(HKEY hKey, CString& csCurrentPath)
  2142. {
  2143. LONG lRet;
  2144. DWORD dwKeyNameSize = MAX_PATH;
  2145. WCHAR wszKeyName[MAX_PATH];
  2146. HKEY hSubKey;
  2147. DWORD dwIndex = 0;
  2148. // Recurse into all subkeys.
  2149. while( ORIGINAL_API(RegEnumKeyExW)(hKey, dwIndex, wszKeyName, &dwKeyNameSize,
  2150. NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
  2151. {
  2152. lRet = ORIGINAL_API(RegOpenKeyExW)(hKey, wszKeyName, 0, KEY_READ, &hSubKey);
  2153. if (lRet == ERROR_SUCCESS)
  2154. {
  2155. // Add this key to the path
  2156. csCurrentPath += L"\\";
  2157. csCurrentPath += wszKeyName;
  2158. // Check this key's subkeys.
  2159. FindCDROMKey(hSubKey, csCurrentPath);
  2160. ORIGINAL_API(RegCloseKey)(hSubKey);
  2161. // Trim the path back.
  2162. int index = csCurrentPath.ReverseFind(L'\\');
  2163. csCurrentPath.Truncate(index);
  2164. }
  2165. dwKeyNameSize = MAX_PATH;
  2166. dwIndex++;
  2167. }
  2168. // Check if this key has a Class value equal to "cdrom"
  2169. DWORD dwDataSize;
  2170. BYTE pData[MAX_PATH*sizeof(WCHAR)];
  2171. DWORD dwType;
  2172. dwDataSize = MAX_PATH * sizeof(WCHAR);
  2173. lRet = ORIGINAL_API(RegQueryValueExW)(hKey, L"CLASS", NULL, &dwType, pData,
  2174. &dwDataSize);
  2175. if ( (lRet == ERROR_SUCCESS) && (dwType == REG_SZ)
  2176. && (_wcsicmp((LPWSTR)pData, L"CDROM")==0))
  2177. {
  2178. // Get location information on the device
  2179. WCHAR wszLocationInformation[MAX_PATH];
  2180. DWORD dwLocInfoSize = MAX_PATH * sizeof(WCHAR);
  2181. lRet = ORIGINAL_API(RegQueryValueExW)(hKey, L"LocationInformation",
  2182. NULL, &dwType, (BYTE*)wszLocationInformation, &dwLocInfoSize);
  2183. if ( (lRet == ERROR_SUCCESS) && (dwType == REG_SZ))
  2184. {
  2185. // Create the device name (like "\\?\cdrom0\".
  2186. CString csDevice = L"\\\\?\\cdrom";
  2187. csDevice += wszLocationInformation;
  2188. csDevice += L"\\";
  2189. // Find which volume name this is mapped to.
  2190. WCHAR wszCDRomMountPoint[50];
  2191. if (GetVolumeNameForVolumeMountPoint(csDevice.Get(),
  2192. wszCDRomMountPoint, 50))
  2193. {
  2194. // Find which drive this is mapped to.
  2195. WCHAR wszDriveMountPoint[50];
  2196. WCHAR wszDrive[] = L"A:\\";
  2197. // Find what drive has an identical volume mount point.
  2198. for(; wszDrive[0] <= L'Z'; wszDrive[0]++)
  2199. {
  2200. if (GetVolumeNameForVolumeMountPoint(wszDrive,
  2201. wszDriveMountPoint, 50))
  2202. {
  2203. // Check if the CD-ROM and this disk drive
  2204. // map to the same volume.
  2205. if (_wcsicmp(wszDriveMountPoint, wszCDRomMountPoint)==0)
  2206. {
  2207. // Add a value to the CD-ROM key.
  2208. VIRTUALKEY* key = VRegistry.AddKey(csCurrentPath);
  2209. if (key)
  2210. {
  2211. // Only use a single letter.
  2212. wszDrive[1] = L'\0';
  2213. VIRTUALVAL* val =
  2214. key->AddValue(L"CurrentDriveLetterAssignment",
  2215. REG_SZ, (BYTE*) wszDrive, sizeof(WCHAR));
  2216. if (val)
  2217. {
  2218. DPFN(eDbgLevelInfo,
  2219. "[Airline Tycoon]Added drive letter \
  2220. %S for %S to PNP data", wszDrive,
  2221. csDevice.Get());
  2222. }
  2223. }
  2224. break;
  2225. }
  2226. }
  2227. }
  2228. }
  2229. }
  2230. }
  2231. }
  2232. ///////////////////////////////////////////////////////////////////////////////
  2233. /*++
  2234. Function Description:
  2235. Fix for Airline Tycoon which uses PNP registry entries to determine the
  2236. drive letter assignments for CD-ROM drives.
  2237. History:
  2238. 08/07/2001 mikrause Created
  2239. --*/
  2240. void
  2241. BuildAirlineTycoon(char* /*szParam*/)
  2242. {
  2243. // Search for CD-ROM keys in the registry.
  2244. HKEY hKey;
  2245. LONG lRet;
  2246. lRet = ORIGINAL_API(RegOpenKeyExW)(HKEY_LOCAL_MACHINE,
  2247. L"System\\CurrentControlSet\\Enum", 0, KEY_READ, &hKey);
  2248. if (lRet != ERROR_SUCCESS)
  2249. {
  2250. DPFN(eDbgLevelError, "[AirlineTycoon] Cannot open ENUM key!");
  2251. return;
  2252. }
  2253. // Enumerate subkeys
  2254. CString csBasePath = L"HKLM\\System\\CurrentControlSet\\Enum";
  2255. FindCDROMKey(hKey, csBasePath);
  2256. ORIGINAL_API(RegCloseKey)(hKey);
  2257. // Set up so that PNP data is redirected.
  2258. BuildDynData("");
  2259. }
  2260. ///////////////////////////////////////////////////////////////////////////////
  2261. /*++
  2262. Function Description:
  2263. Sets the DirectSound acceleration level the app will be allowed to use.
  2264. Arguments:
  2265. szParam - Command line of the form: accellevel | device1 | device2 | ...
  2266. Accellevel is the device acceleration level, and devices 1 through n
  2267. are the devices to apply to.
  2268. Accellevel can be: NONE, STANDARD, or FULL
  2269. Devices can be: EMULATEDRENDER, KSRENDER, EMULATEDCAPTURE, KSCAPTURE
  2270. History:
  2271. 08/10/2001 mikrause Created
  2272. --*/
  2273. void
  2274. BuildDSDevAccel(
  2275. char* szParam)
  2276. {
  2277. // No Try/Catch needed, already in ParseCommandLine
  2278. CStringToken csParam(szParam, "|");
  2279. CString csTok;
  2280. DWORD dwAccelLevel;
  2281. DWORD dwDevices = 0;
  2282. if (csParam.GetToken(csTok))
  2283. {
  2284. if (csTok.CompareNoCase(L"NONE")==0)
  2285. {
  2286. dwAccelLevel = DSAPPHACK_ACCELNONE;
  2287. }
  2288. else if (csTok.CompareNoCase(L"STANDARD")==0)
  2289. {
  2290. dwAccelLevel = DSAPPHACK_ACCELSTANDARD;
  2291. }
  2292. else if (csTok.CompareNoCase(L"FULL")==0)
  2293. {
  2294. dwAccelLevel = DSAPPHACK_ACCELFULL;
  2295. }
  2296. else
  2297. {
  2298. DPFN(eDbgLevelError, "[DSDEVACCEL] Invalid Acceleration Level %s", csTok.GetAnsi());
  2299. return;
  2300. }
  2301. }
  2302. else
  2303. {
  2304. DPFN(eDbgLevelError, "[DSDEVACCEL] Invalid Parameters");
  2305. return;
  2306. }
  2307. while (csParam.GetToken(csTok))
  2308. {
  2309. if (csTok.CompareNoCase(L"EMULATEDRENDER")==0)
  2310. {
  2311. dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
  2312. }
  2313. else if (csTok.CompareNoCase(L"KSRENDER")==0)
  2314. {
  2315. dwDevices |= DSAPPHACK_DEV_KSRENDER;
  2316. }
  2317. else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
  2318. {
  2319. dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
  2320. }
  2321. else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
  2322. {
  2323. dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
  2324. }
  2325. else
  2326. {
  2327. DPFN(eDbgLevelError, "[DSDEVACCEL] Unknown device %s", csTok.GetAnsi());
  2328. }
  2329. }
  2330. if (dwDevices == 0)
  2331. {
  2332. DPFN(eDbgLevelError, "[DSDEVACCEL] No devices specified.");
  2333. return;
  2334. }
  2335. if (AddDSHackDeviceAcceleration(dwAccelLevel, dwDevices) == FALSE)
  2336. {
  2337. DPFN(eDbgLevelError, "[DSDEVACCEL] Unabled to add DirectSound hack");
  2338. }
  2339. }
  2340. ///////////////////////////////////////////////////////////////////////////////
  2341. /*++
  2342. Function Description:
  2343. Makes IDirectSoundBuffer::GetCurrentPosition() tell the app
  2344. that the play and write cursors are X milliseconds further
  2345. along than they really are.
  2346. Arguments:
  2347. szParam - Command line of the form: milliseconds
  2348. Where milliseconds is the number of milliseconds to pad the cursors.
  2349. History:
  2350. 08/10/2001 mikrause Created
  2351. --*/
  2352. void
  2353. BuildDSPadCursors(
  2354. char* szParam)
  2355. {
  2356. // No Try/Catch needed, already in ParseCommandLine
  2357. CString csParam(szParam);
  2358. DWORD dwMilliseconds = 0;
  2359. dwMilliseconds = atol(csParam.GetAnsi());
  2360. if ( dwMilliseconds == 0)
  2361. {
  2362. DPFN(eDbgLevelWarning, "[DSPADCURSORS] Invalid number of milliseconds");
  2363. return;
  2364. }
  2365. if (AddDSHackPadCursors(dwMilliseconds) == FALSE)
  2366. {
  2367. DPFN(eDbgLevelError, "[DSPADCURSORS] Unabled to add DirectSound hack");
  2368. }
  2369. }
  2370. ///////////////////////////////////////////////////////////////////////////////
  2371. /*++
  2372. Function Description:
  2373. Caches the positions of the cursors for apps that abuse
  2374. IDirectSoundBuffer::GetCurrentPosition().
  2375. Arguments:
  2376. szParam - Command line of the form: Dev1 | Dev2 | . . .
  2377. Devices affected. See BuildDSDevAccel().
  2378. History:
  2379. 08/10/2001 mikrause Created
  2380. --*/
  2381. void
  2382. BuildDSCachePositions(
  2383. char* szParam)
  2384. {
  2385. // No Try/Catch needed, already in ParseCommandLine
  2386. CStringToken csParam(szParam, "|");
  2387. CString csTok;
  2388. DWORD dwDevices = 0;
  2389. while (csParam.GetToken(csTok))
  2390. {
  2391. if (csTok.CompareNoCase(L"EMULATEDRENDER")==0)
  2392. {
  2393. dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
  2394. }
  2395. else if (csTok.CompareNoCase(L"KSRENDER")==0)
  2396. {
  2397. dwDevices |= DSAPPHACK_DEV_KSRENDER;
  2398. }
  2399. else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
  2400. {
  2401. dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
  2402. }
  2403. else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
  2404. {
  2405. dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
  2406. }
  2407. else
  2408. {
  2409. DPFN(eDbgLevelError, "[DSCACHEPOSITIONS] Unknown device %s", csTok.GetAnsi());
  2410. }
  2411. }
  2412. if (dwDevices == 0)
  2413. {
  2414. DPFN(eDbgLevelError, "[DSCACHEPOSITIONS] No devices specified.");
  2415. return;
  2416. }
  2417. if (AddDSHackCachePositions(dwDevices) == FALSE)
  2418. {
  2419. DPFN(eDbgLevelError, "[DSCACHEPOSITIONS] Unabled to add DirectSound hack");
  2420. }
  2421. }
  2422. /*++
  2423. Function Description:
  2424. When the app asks for the play cursor, we give it the
  2425. write cursor instead. The correct way to stream audio
  2426. into a looping dsound buffer is to key off the write cursor,
  2427. but some apps (e.g. QuickTime) use the play cursor instead.
  2428. This apphacks alleviates them.
  2429. Arguments:
  2430. szParam - Parameters of the form dev1 | dev2 | . . .
  2431. See BuildDSDevAccel() for valid devices.
  2432. History:
  2433. 08/10/2001 mikrause Created
  2434. --*/
  2435. void
  2436. BuildDSReturnWritePos(
  2437. char* szParam)
  2438. {
  2439. // No Try/Catch needed, already in ParseCommandLine
  2440. CStringToken csParam(szParam, "|");
  2441. CString csTok;
  2442. DWORD dwDevices = 0;
  2443. while (csParam.GetToken(csTok))
  2444. {
  2445. if (csTok.CompareNoCase(L"EMULATEDRENDER")==0)
  2446. {
  2447. dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
  2448. }
  2449. else if (csTok.CompareNoCase(L"KSRENDER")==0)
  2450. {
  2451. dwDevices |= DSAPPHACK_DEV_KSRENDER;
  2452. }
  2453. else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
  2454. {
  2455. dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
  2456. }
  2457. else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
  2458. {
  2459. dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
  2460. }
  2461. else
  2462. {
  2463. DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] Unknown device %s", csTok.GetAnsi());
  2464. }
  2465. }
  2466. if (dwDevices == 0)
  2467. {
  2468. DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] No devices specified.");
  2469. return;
  2470. }
  2471. if (AddDSHackReturnWritePos(dwDevices) == FALSE)
  2472. {
  2473. DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] Unabled to add DirectSound hack");
  2474. }
  2475. }
  2476. /*++
  2477. Function Description:
  2478. Makes dsound always return a write position which is X
  2479. milliseconds ahead of the play position, rather than
  2480. the real write position.
  2481. Arguments:
  2482. szParam - Milliseconds of padding.
  2483. History:
  2484. 08/10/2001 mikrause Created
  2485. --*/
  2486. void
  2487. BuildDSSmoothWritePos(
  2488. char* szParam)
  2489. {
  2490. // No Try/Catch needed, already in ParseCommandLine
  2491. CString csParam(szParam);
  2492. DWORD dwMilliseconds = 0;
  2493. dwMilliseconds = atol(csParam.GetAnsi());
  2494. if ( dwMilliseconds == 0)
  2495. {
  2496. DPFN(eDbgLevelWarning, "[DSSMOOTHWRITEPOS] Invalid number of milliseconds");
  2497. return;
  2498. }
  2499. if (AddDSHackSmoothWritePos(dwMilliseconds) == FALSE)
  2500. {
  2501. DPFN(eDbgLevelError, "[DSSMOOTHWRITEPOS] Unabled to add DirectSound hack");
  2502. }
  2503. else
  2504. {
  2505. DPFN(eDbgLevelInfo, "[DSSMOOTHWRITEPOS] Added DS Hack Smooth Write Pos, %d ms",
  2506. dwMilliseconds);
  2507. }
  2508. }
  2509. ///////////////////////////////////////////////////////////////////////////////
  2510. /*++
  2511. Function Description:
  2512. NortonAntiVirus trys to set the registry value to hide the language bar.
  2513. Protecting the registry value.
  2514. History:
  2515. 01/02/2002 mamathas Created
  2516. --*/
  2517. void BuildNortonAntiVirus(char* /*szParam*/)
  2518. {
  2519. VIRTUALKEY *key;
  2520. key = VRegistry.AddKey(L"HKCU\\Software\\Microsoft\\CTF\\LangBar");
  2521. if (key)
  2522. {
  2523. // Block all writes to ShowStatus
  2524. key->AddProtector(L"ShowStatus");
  2525. }
  2526. }
  2527. ///////////////////////////////////////////////////////////////////////////////
  2528. /*++
  2529. Function Description:
  2530. Disabled some category of devices altogether, forces
  2531. playback through emulated path.
  2532. Arguments:
  2533. szParam - Combination of device that this hack applies to, see BuildDSDevAccel().
  2534. History:
  2535. 08/10/2001 mikrause Created
  2536. --*/
  2537. void
  2538. BuildDSDisableDevice(
  2539. char* szParam)
  2540. {
  2541. // No try/catch needed. Already done in ParseCommandLine
  2542. CStringToken csParam(szParam, "|");
  2543. CString csTok;
  2544. DWORD dwDevices = 0;
  2545. while (csParam.GetToken(csTok)==TRUE)
  2546. {
  2547. if (csTok.CompareNoCase(L"EMULATEDRENDER"))
  2548. {
  2549. dwDevices |= DSAPPHACK_DEV_EMULATEDRENDER;
  2550. }
  2551. else if (csTok.CompareNoCase(L"KSRENDER")==0)
  2552. {
  2553. dwDevices |= DSAPPHACK_DEV_KSRENDER;
  2554. }
  2555. else if (csTok.CompareNoCase(L"EMULATEDCAPTURE")==0)
  2556. {
  2557. dwDevices |= DSAPPHACK_DEV_EMULATEDCAPTURE;
  2558. }
  2559. else if (csTok.CompareNoCase(L"KSCAPTURE")==0)
  2560. {
  2561. dwDevices |= DSAPPHACK_DEV_KSCAPTURE;
  2562. }
  2563. else
  2564. {
  2565. DPFN(eDbgLevelError, "[DSDISABLEDEVICE] Unknown device %s", csTok.GetAnsi());
  2566. }
  2567. }
  2568. if (dwDevices == 0)
  2569. {
  2570. DPFN(eDbgLevelError, "[DSDISABLEDEVICE] No devices specified.");
  2571. return;
  2572. }
  2573. if (AddDSHackDisableDevice(dwDevices) == FALSE)
  2574. {
  2575. DPFN(eDbgLevelError, "[DSRETURNWRITEPOSITION] Unabled to add DirectSound hack");
  2576. }
  2577. }
  2578. LONG WINAPI
  2579. Delphi5SetValue(
  2580. OPENKEY *key,
  2581. VIRTUALKEY * /* vkey */,
  2582. VIRTUALVAL *vvalue,
  2583. DWORD dwType,
  2584. const BYTE* pbData,
  2585. DWORD cbData)
  2586. {
  2587. // Only accept attempts to set a valid REG_SZ value.
  2588. if (dwType == REG_SZ && !IsBadStringPtrW((PWSTR)pbData, cbData/sizeof(WCHAR)))
  2589. {
  2590. CSTRING_TRY
  2591. {
  2592. CString csValue = (PWSTR)pbData;
  2593. int idx = csValue.Find(L"InstReg.exe");
  2594. if (idx != -1)
  2595. {
  2596. csValue.Insert(idx + lstrlenW(L"InstReg.exe"), L'\"');
  2597. csValue.Insert(0, L'\"');
  2598. return RegSetValueExW(key->hkOpen, vvalue->wName, 0, dwType, (BYTE*)csValue.Get(),
  2599. (csValue.GetLength()+1)*sizeof(WCHAR));
  2600. }
  2601. }
  2602. CSTRING_CATCH
  2603. {
  2604. DPFN(eDbgLevelError, "CString exception occured in Delphi5SetValue");
  2605. }
  2606. }
  2607. // Got here, something went wrong. Default o normal RegSetValue
  2608. return RegSetValueExW(key->hkOpen, vvalue->wName, 0, dwType, pbData, cbData);
  2609. }
  2610. void
  2611. BuildDelphi5Pro(
  2612. char* /* szParam */)
  2613. {
  2614. VIRTUALKEY *key;
  2615. key = VRegistry.AddKey(L"HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce");
  2616. if (key)
  2617. {
  2618. key->AddCustomSet(L"BorlandReboot1", Delphi5SetValue);
  2619. }
  2620. }
  2621. ///////////////////////////////////////////////////////////////////////////////
  2622. /*++
  2623. Function Description:
  2624. Word Perfect Office Suite 2002 attempts to delete ODBC key during uninstall.
  2625. Protecting the registry value.
  2626. History:
  2627. 04/23/2002 garyma Created
  2628. --*/
  2629. void BuildWordPerfect2002(char* /*szParam*/)
  2630. {
  2631. VRegistry.AddKeyProtector(L"HKLM\\Software\\ODBC");
  2632. }
  2633. ///////////////////////////////////////////////////////////////////////////////
  2634. IMPLEMENT_SHIM_END