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.

1158 lines
26 KiB

  1. /*++
  2. Copyright (c) 1993-2001 Microsoft Corporation
  3. Module Name:
  4. registry.cpp
  5. Abstract:
  6. This file implements the apis for DRWTSN32 to access the registry.
  7. All access to the registry are done in this file. If additional
  8. registry control is needed then a function should be added in this file
  9. and exposed to the other files in DRWTSN32.
  10. Author:
  11. Wesley Witt (wesw) 1-May-1993
  12. Environment:
  13. User Mode
  14. --*/
  15. #include "pch.cpp"
  16. //
  17. // string constants for accessing the registry
  18. // there is a string constant here for each key and each value
  19. // that is accessed in the registry.
  20. //
  21. #define DRWATSON_EXE_NAME _T("drwtsn32.exe")
  22. #define REGKEY_SOFTWARE _T("software\\microsoft")
  23. #define REGKEY_MESSAGEFILE _T("EventMessageFile")
  24. #define REGKEY_TYPESSUPP _T("TypesSupported")
  25. #define REGKEY_SYSTEMROOT _T("%SystemRoot%\\System32\\")
  26. #define REGKEY_EVENTLOG _T("SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\")
  27. #define REGKEY_APPNAME _T("ApplicationName")
  28. #define REGKEY_FUNCTION _T("FunctionName")
  29. #define REGKEY_EXCEPTIONCODE _T("ExceptionCode")
  30. #define REGKEY_ADDRESS _T("Address")
  31. #define REGKEY_LOG_PATH _T("LogFilePath")
  32. #define REGKEY_DUMPSYMBOLS _T("DumpSymbols")
  33. #define REGKEY_DUMPALLTHREADS _T("DumpAllThreads")
  34. #define REGKEY_APPENDTOLOGFILE _T("AppendToLogFile")
  35. #define REGKEY_INSTRUCTIONS _T("Instructions")
  36. #define REGKEY_VISUAL _T("VisualNotification")
  37. #define REGKEY_SOUND _T("SoundNotification")
  38. #define REGKEY_CRASH_DUMP _T("CreateCrashDump")
  39. #define REGKEY_CRASH_FILE _T("CrashDumpFile")
  40. #define REGKEY_CRASH_TYPE _T("CrashDumpType")
  41. #define REGKEY_WAVE_FILE _T("WaveFile")
  42. #define REGKEY_NUM_CRASHES _T("NumberOfCrashes")
  43. #define REGKEY_MAX_CRASHES _T("MaximumCrashes")
  44. #define REGKEY_CURRENTVERSION _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion")
  45. #define REGKEY_CONTROLWINDOWS _T("SYSTEM\\CurrentControlSet\\Control\\Windows")
  46. #define REGKEY_CSD_VERSION _T("CSDVersion")
  47. #define REGKEY_CURRENT_BUILD _T("CurrentBuildNumber")
  48. #define REGKEY_CURRENT_TYPE _T("CurrentType")
  49. #define REGKEY_REG_ORGANIZATION _T("RegisteredOrganization")
  50. #define REGKEY_REG_OWNER _T("RegisteredOwner")
  51. #define REGKEY_AEDEBUG _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug")
  52. #define REGKEY_AUTO _T("Auto")
  53. #define REGKEY_DEBUGGER _T("Debugger")
  54. #define REGKEY_PROCESSOR _T("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0")
  55. #define REGKEY_PROCESSOR_ID _T("Identifier")
  56. //
  57. // local prototypes
  58. //
  59. void
  60. RegSetDWORD(
  61. HKEY hkey,
  62. PTSTR pszSubKey,
  63. DWORD dwValue
  64. );
  65. void
  66. RegSetBOOL(
  67. HKEY hkey,
  68. PTSTR pszSubKey,
  69. BOOL dwValue
  70. );
  71. void
  72. RegSetSZ(
  73. HKEY hkey,
  74. PTSTR pszSubKey,
  75. PTSTR pszValue
  76. );
  77. void
  78. RegSetEXPANDSZ(
  79. HKEY hkey,
  80. PTSTR pszSubKey,
  81. PTSTR pszValue
  82. );
  83. BOOL
  84. RegQueryBOOL(
  85. HKEY hkey,
  86. PTSTR pszSubKey
  87. );
  88. DWORD
  89. RegQueryDWORD(
  90. HKEY hkey,
  91. PTSTR pszSubKey
  92. );
  93. void
  94. RegQuerySZ(
  95. HKEY hkey,
  96. PTSTR pszSubKey,
  97. PTSTR pszValue,
  98. DWORD dwSizeValue
  99. );
  100. BOOL
  101. RegSaveAllValues(
  102. HKEY hKeyDrWatson,
  103. POPTIONS o
  104. );
  105. BOOL
  106. RegGetAllValues(
  107. POPTIONS o,
  108. HKEY hKeyDrWatson
  109. );
  110. BOOL
  111. RegInitializeDefaults(
  112. HKEY hKeyDrWatson
  113. );
  114. HKEY
  115. RegGetAppKey(
  116. BOOL ReadOnly
  117. );
  118. BOOL
  119. RegCreateEventSource(
  120. void
  121. );
  122. void
  123. GetDrWatsonLogPath(
  124. LPTSTR szPath
  125. );
  126. void
  127. GetDrWatsonCrashDump(
  128. LPTSTR szPath
  129. );
  130. BOOL
  131. RegGetAllValues(
  132. POPTIONS o,
  133. HKEY hKeyDrWatson
  134. )
  135. /*++
  136. Routine Description:
  137. This functions retrieves all registry data for DRWTSN32 and puts
  138. the data in the OPTIONS structure passed in.
  139. Arguments:
  140. o - pointer to an OPTIONS structure
  141. hKeyDrWatson - handle to a registry key for DRWTSN32 registry data
  142. Return Value:
  143. TRUE - retrieved all data without error
  144. FALSE - errors occurred and did not get all data
  145. --*/
  146. {
  147. RegQuerySZ(hKeyDrWatson, REGKEY_LOG_PATH, o->szLogPath, sizeof(o->szLogPath) );
  148. RegQuerySZ(hKeyDrWatson, REGKEY_WAVE_FILE, o->szWaveFile, sizeof(o->szWaveFile) );
  149. RegQuerySZ(hKeyDrWatson, REGKEY_CRASH_FILE, o->szCrashDump, sizeof(o->szCrashDump) );
  150. o->fDumpSymbols = RegQueryBOOL( hKeyDrWatson, REGKEY_DUMPSYMBOLS );
  151. o->fDumpAllThreads = RegQueryBOOL( hKeyDrWatson, REGKEY_DUMPALLTHREADS );
  152. o->fAppendToLogFile = RegQueryBOOL( hKeyDrWatson, REGKEY_APPENDTOLOGFILE );
  153. o->fVisual = RegQueryBOOL( hKeyDrWatson, REGKEY_VISUAL );
  154. o->fSound = RegQueryBOOL( hKeyDrWatson, REGKEY_SOUND );
  155. o->fCrash = RegQueryBOOL( hKeyDrWatson, REGKEY_CRASH_DUMP );
  156. o->dwInstructions = RegQueryDWORD( hKeyDrWatson, REGKEY_INSTRUCTIONS );
  157. o->dwMaxCrashes = RegQueryDWORD( hKeyDrWatson, REGKEY_MAX_CRASHES );
  158. o->dwType = (CrashDumpType)RegQueryDWORD(hKeyDrWatson, REGKEY_CRASH_TYPE);
  159. return TRUE;
  160. }
  161. BOOL
  162. RegSaveAllValues(
  163. HKEY hKeyDrWatson,
  164. POPTIONS o
  165. )
  166. /*++
  167. Routine Description:
  168. This functions saves all registry data for DRWTSN32 that is passed
  169. in via the OPTIONS structure.
  170. Arguments:
  171. hKeyDrWatson - handle to a registry key for DRWTSN32 registry data
  172. o - pointer to an OPTIONS structure
  173. Return Value:
  174. TRUE - saved all data without error
  175. FALSE - errors occurred and did not save all data
  176. --*/
  177. {
  178. RegSetSZ( hKeyDrWatson, REGKEY_LOG_PATH, o->szLogPath );
  179. RegSetSZ( hKeyDrWatson, REGKEY_WAVE_FILE, o->szWaveFile );
  180. RegSetSZ( hKeyDrWatson, REGKEY_CRASH_FILE, o->szCrashDump );
  181. RegSetBOOL( hKeyDrWatson, REGKEY_DUMPSYMBOLS, o->fDumpSymbols );
  182. RegSetBOOL( hKeyDrWatson, REGKEY_DUMPALLTHREADS, o->fDumpAllThreads );
  183. RegSetBOOL( hKeyDrWatson, REGKEY_APPENDTOLOGFILE, o->fAppendToLogFile );
  184. RegSetBOOL( hKeyDrWatson, REGKEY_VISUAL, o->fVisual );
  185. RegSetBOOL( hKeyDrWatson, REGKEY_SOUND, o->fSound );
  186. RegSetBOOL( hKeyDrWatson, REGKEY_CRASH_DUMP, o->fCrash );
  187. RegSetDWORD( hKeyDrWatson, REGKEY_INSTRUCTIONS, o->dwInstructions );
  188. RegSetDWORD( hKeyDrWatson, REGKEY_MAX_CRASHES, o->dwMaxCrashes );
  189. RegSetDWORD( hKeyDrWatson, REGKEY_CRASH_TYPE, o->dwType);
  190. return TRUE;
  191. }
  192. BOOL
  193. RegInitializeDefaults(
  194. HKEY hKeyDrWatson
  195. )
  196. /*++
  197. Routine Description:
  198. This functions initializes the registry with the default values.
  199. Arguments:
  200. hKeyDrWatson - handle to a registry key for DRWTSN32 registry data
  201. Return Value:
  202. TRUE - saved all data without error
  203. FALSE - errors occurred and did not save all data
  204. --*/
  205. {
  206. OPTIONS o;
  207. GetDrWatsonLogPath(o.szLogPath);
  208. GetDrWatsonCrashDump(o.szCrashDump);
  209. o.szWaveFile[0] = _T('\0');
  210. o.fDumpSymbols = FALSE;
  211. o.fDumpAllThreads = TRUE;
  212. o.fAppendToLogFile = TRUE;
  213. o.fVisual = FALSE;
  214. o.fSound = FALSE;
  215. o.fCrash = TRUE;
  216. o.dwInstructions = 10;
  217. o.dwMaxCrashes = 10;
  218. o.dwType = MiniDump;
  219. RegSetNumCrashes( 0 );
  220. RegSaveAllValues( hKeyDrWatson, &o );
  221. RegCreateEventSource();
  222. return TRUE;
  223. }
  224. BOOL
  225. RegCreateEventSource(
  226. void
  227. )
  228. /*++
  229. Routine Description:
  230. This function creates an event source in the registry. The event
  231. source is used by the event viewer to display the data in a
  232. presentable manner.
  233. Arguments:
  234. None.
  235. Return Value:
  236. TRUE - saved all data without error
  237. FALSE - errors occurred and did not save all data
  238. --*/
  239. {
  240. HKEY hk;
  241. _TCHAR szBuf[1024];
  242. DWORD dwDisp;
  243. _TCHAR szAppName[MAX_PATH];
  244. GetAppName( szAppName, sizeof(szAppName) / sizeof(_TCHAR) );
  245. _tcscpy( szBuf, REGKEY_EVENTLOG );
  246. _tcscat( szBuf, szAppName );
  247. if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  248. szBuf,
  249. 0,
  250. NULL,
  251. REG_OPTION_NON_VOLATILE,
  252. KEY_QUERY_VALUE | KEY_SET_VALUE,
  253. NULL,
  254. &hk,
  255. &dwDisp
  256. )) {
  257. return FALSE;
  258. }
  259. if (dwDisp == REG_OPENED_EXISTING_KEY) {
  260. RegCloseKey(hk);
  261. return TRUE;
  262. }
  263. _tcscpy( szBuf, REGKEY_SYSTEMROOT );
  264. _tcscat( szBuf, DRWATSON_EXE_NAME );
  265. RegSetEXPANDSZ( hk, REGKEY_MESSAGEFILE, szBuf );
  266. RegSetDWORD( hk, REGKEY_TYPESSUPP, EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE );
  267. RegCloseKey(hk);
  268. return TRUE;
  269. }
  270. HKEY
  271. RegGetAppKey(
  272. BOOL ReadOnly
  273. )
  274. /*++
  275. Routine Description:
  276. This function gets a handle to the DRWTSN32 registry key.
  277. Arguments:
  278. ReadOnly - Caller needs this foe reading purposes only
  279. Although, we could need to create it if its not present
  280. Return Value:
  281. Valid handle - handle opened ok
  282. NULL - could not open the handle
  283. --*/
  284. {
  285. DWORD rc;
  286. DWORD dwDisp;
  287. HKEY hKeyDrWatson;
  288. HKEY hKeyMicrosoft;
  289. _TCHAR szAppName[MAX_PATH];
  290. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  291. REGKEY_SOFTWARE,
  292. 0,
  293. KEY_QUERY_VALUE | KEY_SET_VALUE |
  294. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  295. &hKeyMicrosoft
  296. );
  297. if (rc != ERROR_SUCCESS) {
  298. if (ReadOnly) {
  299. // Try oepning it for read only
  300. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  301. REGKEY_SOFTWARE,
  302. 0,
  303. KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
  304. &hKeyMicrosoft
  305. );
  306. }
  307. if (rc != ERROR_SUCCESS) {
  308. return NULL;
  309. }
  310. }
  311. szAppName[0] = 0;
  312. GetAppName( szAppName, sizeof(szAppName) / sizeof(_TCHAR) );
  313. rc = RegCreateKeyEx( hKeyMicrosoft,
  314. szAppName,
  315. 0,
  316. NULL,
  317. REG_OPTION_NON_VOLATILE,
  318. KEY_READ | KEY_WRITE,
  319. NULL,
  320. &hKeyDrWatson,
  321. &dwDisp
  322. );
  323. if (rc != ERROR_SUCCESS) {
  324. if (ReadOnly) {
  325. // Try oepning it for read only
  326. rc = RegCreateKeyEx( hKeyMicrosoft,
  327. szAppName,
  328. 0,
  329. NULL,
  330. REG_OPTION_NON_VOLATILE,
  331. KEY_READ,
  332. NULL,
  333. &hKeyDrWatson,
  334. &dwDisp
  335. );
  336. }
  337. if (rc != ERROR_SUCCESS) {
  338. RegCloseKey(hKeyMicrosoft);
  339. return NULL;
  340. }
  341. }
  342. if (dwDisp == REG_CREATED_NEW_KEY) {
  343. RegInitializeDefaults( hKeyDrWatson );
  344. }
  345. RegCloseKey(hKeyMicrosoft);
  346. return hKeyDrWatson;
  347. }
  348. BOOL
  349. RegInitialize(
  350. POPTIONS o
  351. )
  352. /*++
  353. Routine Description:
  354. This function is used to initialize the OPTIONS structure passed in
  355. with the current values in the registry. Note that if the registry
  356. is empty then the defaults are stored in the registry and also
  357. returned in the OPTIONS structure.
  358. Arguments:
  359. o - Returns an OPTIONS struct with initial values
  360. Return Value:
  361. TRUE - all data was retrieved ok
  362. NULL - could not get all data
  363. --*/
  364. {
  365. HKEY hKeyDrWatson;
  366. BOOL Succ = FALSE;
  367. ZeroMemory(o, sizeof(*o));
  368. hKeyDrWatson = RegGetAppKey( TRUE );
  369. if ( hKeyDrWatson != NULL ) {
  370. Succ = RegGetAllValues( o, hKeyDrWatson );
  371. RegCloseKey( hKeyDrWatson );
  372. }
  373. return Succ;
  374. }
  375. BOOL
  376. RegSave(
  377. POPTIONS o
  378. )
  379. /*++
  380. Routine Description:
  381. This function is used to save the data in the OPTIONS structure
  382. to the registry.
  383. Arguments:
  384. o - pointer to an OPTIONS structure
  385. Return Value:
  386. TRUE - all data was saved ok
  387. NULL - could not save all data
  388. --*/
  389. {
  390. HKEY hKeyDrWatson;
  391. hKeyDrWatson = RegGetAppKey( FALSE );
  392. if (hKeyDrWatson)
  393. {
  394. RegSaveAllValues( hKeyDrWatson, o );
  395. RegCloseKey( hKeyDrWatson );
  396. return TRUE;
  397. }
  398. return FALSE;
  399. }
  400. void
  401. RegSetNumCrashes(
  402. DWORD dwNumCrashes
  403. )
  404. /*++
  405. Routine Description:
  406. This function changes the value in the registry that contains the
  407. number of crashes that have occurred.
  408. Arguments:
  409. dwNumCrashes - the number of craches to save
  410. Return Value:
  411. None.
  412. --*/
  413. {
  414. HKEY hKeyDrWatson;
  415. hKeyDrWatson = RegGetAppKey( FALSE );
  416. if (hKeyDrWatson)
  417. {
  418. RegSetDWORD( hKeyDrWatson, REGKEY_NUM_CRASHES, dwNumCrashes );
  419. RegCloseKey( hKeyDrWatson );
  420. }
  421. return;
  422. }
  423. DWORD
  424. RegGetNumCrashes(
  425. void
  426. )
  427. /*++
  428. Routine Description:
  429. This function get the value in the registry that contains the
  430. number of crashes that have occurred.
  431. Arguments:
  432. None.
  433. Return Value:
  434. the number of craches that have occurred
  435. --*/
  436. {
  437. HKEY hKeyDrWatson;
  438. DWORD dwNumCrashes=0;
  439. hKeyDrWatson = RegGetAppKey( TRUE );
  440. if ( hKeyDrWatson != NULL ) {
  441. dwNumCrashes = RegQueryDWORD( hKeyDrWatson, REGKEY_NUM_CRASHES );
  442. RegCloseKey( hKeyDrWatson );
  443. }
  444. return dwNumCrashes;
  445. }
  446. BOOLEAN
  447. RegInstallDrWatson(
  448. BOOL fQuiet
  449. )
  450. /*++
  451. Routine Description:
  452. This function sets the AEDebug registry values to automatically
  453. invoke drwtsn32 when a crash occurs.
  454. Arguments:
  455. None.
  456. Return Value:
  457. Valid handle - handle opened ok
  458. NULL - could not open the handle
  459. --*/
  460. {
  461. DWORD rc;
  462. HKEY hKeyMicrosoft;
  463. OPTIONS o;
  464. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  465. REGKEY_AEDEBUG,
  466. 0,
  467. KEY_QUERY_VALUE | KEY_SET_VALUE,
  468. &hKeyMicrosoft
  469. );
  470. if (rc != ERROR_SUCCESS) {
  471. return FALSE;
  472. }
  473. RegSetSZ( hKeyMicrosoft, REGKEY_AUTO, _T("1") );
  474. RegSetSZ( hKeyMicrosoft, REGKEY_DEBUGGER, _T("drwtsn32 -p %ld -e %ld -g") );
  475. RegCloseKey( hKeyMicrosoft );
  476. RegInitialize( &o );
  477. if (fQuiet) {
  478. o.fVisual = FALSE;
  479. o.fSound = FALSE;
  480. RegSave( &o );
  481. }
  482. return TRUE;
  483. }
  484. void
  485. RegSetDWORD(
  486. HKEY hkey,
  487. PTSTR pszSubKey,
  488. DWORD dwValue
  489. )
  490. /*++
  491. Routine Description:
  492. This function changes a DWORD value in the registry using the
  493. hkey and pszSubKey as the registry key info.
  494. Arguments:
  495. hkey - handle to a registry key
  496. pszSubKey - pointer to a subkey string
  497. dwValue - new registry value
  498. Return Value:
  499. None.
  500. --*/
  501. {
  502. DWORD rc;
  503. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue) );
  504. Assert( rc == ERROR_SUCCESS );
  505. }
  506. void
  507. RegSetBOOL(
  508. HKEY hkey,
  509. PTSTR pszSubKey,
  510. BOOL dwValue
  511. )
  512. /*++
  513. Routine Description:
  514. This function changes a BOOL value in the registry using the
  515. hkey and pszSubKey as the registry key info.
  516. Arguments:
  517. hkey - handle to a registry key
  518. pszSubKey - pointer to a subkey string
  519. dwValue - new registry value
  520. Return Value:
  521. None.
  522. --*/
  523. {
  524. DWORD rc;
  525. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_DWORD, (LPBYTE)&dwValue, 4 );
  526. Assert( rc == ERROR_SUCCESS );
  527. }
  528. void
  529. RegSetSZ(
  530. HKEY hkey,
  531. PTSTR pszSubKey,
  532. PTSTR pszValue
  533. )
  534. /*++
  535. Routine Description:
  536. This function changes a SZ value in the registry using the
  537. hkey and pszSubKey as the registry key info.
  538. Arguments:
  539. hkey - handle to a registry key
  540. pszSubKey - pointer to a subkey string
  541. pszValue - new registry value
  542. Return Value:
  543. None.
  544. --*/
  545. {
  546. DWORD rc;
  547. TCHAR szPath[_MAX_PATH];
  548. // If Dr Watson registry key for log path or crash file are
  549. // the defaults, don't write them to the registry.
  550. // The defaults for these are obtained by querying.
  551. if ( _tcscmp( pszSubKey, REGKEY_LOG_PATH ) == 0 ) {
  552. GetDrWatsonLogPath( szPath );
  553. if (_tcscmp(szPath,pszValue) == 0 ) return;
  554. } else if ( _tcscmp( pszSubKey, REGKEY_CRASH_FILE) == 0 ) {
  555. RegQuerySZ(hkey, pszSubKey, szPath, _MAX_PATH * sizeof(_TCHAR));
  556. if ( _tcscmp(szPath, pszValue) == 0 ) return;
  557. }
  558. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_SZ, (PBYTE) pszValue, (_tcslen(pszValue) +1) * sizeof(_TCHAR) );
  559. Assert( rc == ERROR_SUCCESS );
  560. }
  561. void
  562. RegSetEXPANDSZ(
  563. HKEY hkey,
  564. PTSTR pszSubKey,
  565. PTSTR pszValue
  566. )
  567. /*++
  568. Routine Description:
  569. This function changes a SZ value in the registry using the
  570. hkey and pszSubKey as the registry key info.
  571. Arguments:
  572. hkey - handle to a registry key
  573. pszSubKey - pointer to a subkey string
  574. pszValue - new registry value
  575. Return Value:
  576. None.
  577. --*/
  578. {
  579. DWORD rc;
  580. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_EXPAND_SZ, (PBYTE) pszValue, (_tcslen(pszValue)+1) * sizeof(TCHAR) );
  581. Assert( rc == ERROR_SUCCESS );
  582. }
  583. BOOL
  584. RegQueryBOOL(
  585. HKEY hkey,
  586. PTSTR pszSubKey
  587. )
  588. /*++
  589. Routine Description:
  590. This function queries BOOL value in the registry using the
  591. hkey and pszSubKey as the registry key info. If the value is not
  592. found in the registry, it is added with a FALSE value.
  593. Arguments:
  594. hkey - handle to a registry key
  595. pszSubKey - pointer to a subkey string
  596. Return Value:
  597. TRUE or FALSE.
  598. --*/
  599. {
  600. DWORD rc;
  601. DWORD len;
  602. DWORD dwType;
  603. BOOL fValue = FALSE;
  604. len = 4;
  605. rc = RegQueryValueEx( hkey, pszSubKey, 0, &dwType, (LPBYTE)&fValue, &len );
  606. if (rc != ERROR_SUCCESS) {
  607. if (rc == ERROR_FILE_NOT_FOUND) {
  608. fValue = FALSE;
  609. RegSetBOOL( hkey, pszSubKey, fValue );
  610. }
  611. else {
  612. Assert( rc == ERROR_SUCCESS );
  613. }
  614. }
  615. else {
  616. Assert( dwType == REG_DWORD );
  617. }
  618. return fValue;
  619. }
  620. DWORD
  621. RegQueryDWORD(
  622. HKEY hkey,
  623. PTSTR pszSubKey
  624. )
  625. /*++
  626. Routine Description:
  627. This function queries BOOL value in the registry using the
  628. hkey and pszSubKey as the registry key info. If the value is not
  629. found in the registry, it is added with a zero value.
  630. Arguments:
  631. hkey - handle to a registry key
  632. pszSubKey - pointer to a subkey string
  633. Return Value:
  634. registry value
  635. --*/
  636. {
  637. DWORD rc;
  638. DWORD len;
  639. DWORD dwType;
  640. DWORD fValue = 0;
  641. len = 4;
  642. rc = RegQueryValueEx( hkey, pszSubKey, 0, &dwType, (LPBYTE)&fValue, &len );
  643. if (rc != ERROR_SUCCESS) {
  644. if (rc == ERROR_FILE_NOT_FOUND) {
  645. fValue = 0;
  646. RegSetDWORD( hkey, pszSubKey, fValue );
  647. }
  648. else {
  649. Assert( rc == ERROR_SUCCESS );
  650. }
  651. }
  652. else {
  653. Assert( dwType == REG_DWORD );
  654. }
  655. return fValue;
  656. }
  657. void
  658. RegQuerySZ(
  659. HKEY hkey,
  660. PTSTR pszSubKey,
  661. PTSTR pszValue,
  662. DWORD dwSizeValue
  663. )
  664. /*++
  665. Routine Description:
  666. This function queries BOOL value in the registry using the
  667. hkey and pszSubKey as the registry key info. If the value is not
  668. found in the registry, it is added with a zero value.
  669. Arguments:
  670. hkey - handle to a registry key
  671. pszSubKey - pointer to a subkey string
  672. Return Value:
  673. registry value
  674. --*/
  675. {
  676. LONG lRes;
  677. DWORD dwType;
  678. lRes = RegQueryValueEx( hkey, pszSubKey, 0, &dwType, (PBYTE) pszValue, &dwSizeValue );
  679. if (lRes == ERROR_FILE_NOT_FOUND) {
  680. // If these two SubKeys already exist in the registry, then use the registry values.
  681. // If they don't exist, query for the value.
  682. if ( _tcscmp( pszSubKey, REGKEY_LOG_PATH) == 0 ) {
  683. GetDrWatsonLogPath( pszValue );
  684. } else if ( _tcscmp( pszSubKey, REGKEY_CRASH_FILE) == 0 ) {
  685. GetDrWatsonCrashDump( pszValue );
  686. }
  687. } else {
  688. Assert( lRes == ERROR_SUCCESS );
  689. Assert( dwType == REG_SZ || dwType == REG_EXPAND_SZ );
  690. // If the old defaults for Beta 3 or NT4 log path and crash file
  691. // exist, then delete them and use the new and improved values
  692. if ( _tcscmp( pszSubKey, REGKEY_LOG_PATH) == 0 &&
  693. (_tcsicmp( pszValue, _T("%userprofile%")) == 0 ||
  694. _tcsicmp( pszValue, _T("%windir%")) == 0 ) ) {
  695. // Delete the key
  696. lRes = RegDeleteValue( hkey, pszSubKey);
  697. Assert ( lRes == ERROR_SUCCESS);
  698. GetDrWatsonLogPath( pszValue );
  699. } else if ( _tcscmp( pszSubKey, REGKEY_CRASH_FILE) == 0 &&
  700. _tcsicmp( pszValue, _T("%windir%\\user.dmp")) == 0 ) {
  701. // Delete the key
  702. lRes = RegDeleteValue( hkey, pszSubKey);
  703. Assert( lRes == ERROR_SUCCESS);
  704. GetDrWatsonCrashDump( pszValue );
  705. }
  706. }
  707. }
  708. void
  709. RegLogCurrentVersion(
  710. void
  711. )
  712. /*++
  713. Routine Description:
  714. This function writes system and user info. to the log file
  715. Arguments:
  716. None
  717. Return Value:
  718. registry value
  719. History:
  720. 8/21/97 a-paulbr fixed bug 658
  721. --*/
  722. {
  723. _TCHAR buf[1024];
  724. DWORD rc;
  725. HKEY hKeyCurrentVersion = NULL;
  726. HKEY hKeyControlWindows = NULL;
  727. DWORD dwSPNum = 0;
  728. DWORD dwType = REG_DWORD;
  729. DWORD dwSize = sizeof(DWORD);
  730. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  731. REGKEY_CURRENTVERSION,
  732. 0,
  733. KEY_QUERY_VALUE,
  734. &hKeyCurrentVersion
  735. );
  736. if (rc != ERROR_SUCCESS) {
  737. return;
  738. }
  739. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  740. REGKEY_CONTROLWINDOWS,
  741. 0,
  742. KEY_QUERY_VALUE,
  743. &hKeyControlWindows);
  744. if (hKeyControlWindows) {
  745. //
  746. // I'm using RegQueryValueEx() because there is an assertion in
  747. // RegQueryDWORD() if the key does not exist.
  748. //
  749. RegQueryValueEx(hKeyControlWindows,
  750. REGKEY_CSD_VERSION,
  751. NULL,
  752. &dwType,
  753. (BYTE*)&dwSPNum,
  754. &dwSize
  755. );
  756. }
  757. RegQuerySZ(hKeyCurrentVersion, REGKEY_CURRENT_BUILD, buf, sizeof(buf) );
  758. lprintf( MSG_CURRENT_BUILD, buf );
  759. if ((hKeyControlWindows) &&
  760. (dwType == REG_DWORD) &&
  761. (HIBYTE(LOWORD(dwSPNum)) != 0)) {
  762. _stprintf(buf, _T("%hu"), HIBYTE(LOWORD(dwSPNum)));
  763. lprintf( MSG_CSD_VERSION, buf );
  764. } else {
  765. _stprintf(buf, _T("None"));
  766. lprintf( MSG_CSD_VERSION, buf );
  767. }
  768. RegQuerySZ( hKeyCurrentVersion,REGKEY_CURRENT_TYPE, buf, sizeof(buf) );
  769. lprintf( MSG_CURRENT_TYPE, buf );
  770. RegQuerySZ( hKeyCurrentVersion,REGKEY_REG_ORGANIZATION, buf, sizeof(buf) );
  771. lprintf( MSG_REG_ORGANIZATION, buf );
  772. RegQuerySZ( hKeyCurrentVersion,REGKEY_REG_OWNER, buf, sizeof(buf) );
  773. lprintf( MSG_REG_OWNER, buf );
  774. //
  775. // Close the keys that we opened
  776. //
  777. RegCloseKey(hKeyCurrentVersion);
  778. RegCloseKey(hKeyControlWindows);
  779. return;
  780. }
  781. void
  782. RegLogProcessorType(
  783. void
  784. )
  785. {
  786. _TCHAR buf[1024];
  787. DWORD rc;
  788. HKEY hKey;
  789. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  790. REGKEY_PROCESSOR,
  791. 0,
  792. KEY_QUERY_VALUE,
  793. &hKey
  794. );
  795. if (rc != ERROR_SUCCESS) {
  796. return;
  797. }
  798. RegQuerySZ( hKey, REGKEY_PROCESSOR_ID, buf, sizeof(buf) );
  799. lprintf( MSG_SYSINFO_PROC_TYPE, buf );
  800. return;
  801. }
  802. void
  803. GetDrWatsonLogPath(
  804. LPTSTR szPath
  805. )
  806. {
  807. int rc;
  808. HRESULT Hr;
  809. Hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE,
  810. NULL, 0, szPath);
  811. if (Hr != S_OK) {
  812. ExitProcess(1);
  813. }
  814. if (_tcslen(szPath) > MAX_PATH - 32) {
  815. ExitProcess(1);
  816. }
  817. _tcscat(szPath,_T("\\Microsoft\\Dr Watson") );
  818. if ( !CreateDirectory(szPath, NULL) ) {
  819. if( GetLastError() != ERROR_ALREADY_EXISTS ) {
  820. rc = GetLastError();
  821. }
  822. }
  823. }
  824. void
  825. GetDrWatsonCrashDump(
  826. LPTSTR szPath
  827. )
  828. {
  829. int rc;
  830. HRESULT Hr;
  831. Hr = SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA | CSIDL_FLAG_CREATE,
  832. NULL, 0, szPath);
  833. if (Hr != S_OK) {
  834. ExitProcess(1);
  835. }
  836. if (_tcslen(szPath) > MAX_PATH - 40) {
  837. ExitProcess(1);
  838. }
  839. _tcscat(szPath,_T("\\Microsoft\\Dr Watson") );
  840. if ( !CreateDirectory(szPath, NULL) ) {
  841. if( GetLastError() != ERROR_ALREADY_EXISTS ) {
  842. rc = GetLastError();
  843. }
  844. }
  845. _tcscat(szPath, _T("\\user.dmp") );
  846. return;
  847. }
  848. void
  849. DeleteCrashDump()
  850. {
  851. HKEY hKeyDrWatson;
  852. TCHAR szCrashDump[MAX_PATH];
  853. hKeyDrWatson = RegGetAppKey( TRUE );
  854. if (hKeyDrWatson) {
  855. RegQuerySZ(hKeyDrWatson, REGKEY_CRASH_FILE, szCrashDump, sizeof(szCrashDump) );
  856. DeleteFile(szCrashDump);
  857. RegCloseKey( hKeyDrWatson );
  858. }
  859. }