Leaked source code of windows server 2003
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.

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