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

1177 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. TCHAR szPATH[_MAX_PATH];
  179. RegSetSZ( hKeyDrWatson, REGKEY_LOG_PATH, o->szLogPath );
  180. RegSetSZ( hKeyDrWatson, REGKEY_WAVE_FILE, o->szWaveFile );
  181. RegSetSZ( hKeyDrWatson, REGKEY_CRASH_FILE, o->szCrashDump );
  182. RegSetBOOL( hKeyDrWatson, REGKEY_DUMPSYMBOLS, o->fDumpSymbols );
  183. RegSetBOOL( hKeyDrWatson, REGKEY_DUMPALLTHREADS, o->fDumpAllThreads );
  184. RegSetBOOL( hKeyDrWatson, REGKEY_APPENDTOLOGFILE, o->fAppendToLogFile );
  185. RegSetBOOL( hKeyDrWatson, REGKEY_VISUAL, o->fVisual );
  186. RegSetBOOL( hKeyDrWatson, REGKEY_SOUND, o->fSound );
  187. RegSetBOOL( hKeyDrWatson, REGKEY_CRASH_DUMP, o->fCrash );
  188. RegSetDWORD( hKeyDrWatson, REGKEY_INSTRUCTIONS, o->dwInstructions );
  189. RegSetDWORD( hKeyDrWatson, REGKEY_MAX_CRASHES, o->dwMaxCrashes );
  190. RegSetDWORD( hKeyDrWatson, REGKEY_CRASH_TYPE, o->dwType);
  191. return TRUE;
  192. }
  193. BOOL
  194. RegInitializeDefaults(
  195. HKEY hKeyDrWatson
  196. )
  197. /*++
  198. Routine Description:
  199. This functions initializes the registry with the default values.
  200. Arguments:
  201. hKeyDrWatson - handle to a registry key for DRWTSN32 registry data
  202. Return Value:
  203. TRUE - saved all data without error
  204. FALSE - errors occurred and did not save all data
  205. --*/
  206. {
  207. OPTIONS o;
  208. GetDrWatsonLogPath(o.szLogPath);
  209. GetDrWatsonCrashDump(o.szCrashDump);
  210. o.szWaveFile[0] = _T('\0');
  211. o.fDumpSymbols = FALSE;
  212. o.fDumpAllThreads = TRUE;
  213. o.fAppendToLogFile = TRUE;
  214. o.fVisual = FALSE;
  215. o.fSound = FALSE;
  216. o.fCrash = TRUE;
  217. o.dwInstructions = 10;
  218. o.dwMaxCrashes = 10;
  219. o.dwType = MiniDump;
  220. RegSetNumCrashes( 0 );
  221. RegSaveAllValues( hKeyDrWatson, &o );
  222. RegCreateEventSource();
  223. return TRUE;
  224. }
  225. BOOL
  226. RegCreateEventSource(
  227. void
  228. )
  229. /*++
  230. Routine Description:
  231. This function creates an event source in the registry. The event
  232. source is used by the event viewer to display the data in a
  233. presentable manner.
  234. Arguments:
  235. None.
  236. Return Value:
  237. TRUE - saved all data without error
  238. FALSE - errors occurred and did not save all data
  239. --*/
  240. {
  241. HKEY hk;
  242. _TCHAR szBuf[1024];
  243. DWORD dwDisp;
  244. _TCHAR szAppName[MAX_PATH];
  245. GetAppName( szAppName, sizeof(szAppName) / sizeof(_TCHAR) );
  246. _tcscpy( szBuf, REGKEY_EVENTLOG );
  247. _tcscat( szBuf, szAppName );
  248. if (RegCreateKeyEx( HKEY_LOCAL_MACHINE,
  249. szBuf,
  250. 0,
  251. NULL,
  252. REG_OPTION_NON_VOLATILE,
  253. KEY_QUERY_VALUE | KEY_SET_VALUE,
  254. NULL,
  255. &hk,
  256. &dwDisp
  257. )) {
  258. return FALSE;
  259. }
  260. if (dwDisp == REG_OPENED_EXISTING_KEY) {
  261. RegCloseKey(hk);
  262. return TRUE;
  263. }
  264. _tcscpy( szBuf, REGKEY_SYSTEMROOT );
  265. _tcscat( szBuf, DRWATSON_EXE_NAME );
  266. RegSetEXPANDSZ( hk, REGKEY_MESSAGEFILE, szBuf );
  267. RegSetDWORD( hk, REGKEY_TYPESSUPP, EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE );
  268. RegCloseKey(hk);
  269. return TRUE;
  270. }
  271. HKEY
  272. RegGetAppKey(
  273. BOOL ReadOnly
  274. )
  275. /*++
  276. Routine Description:
  277. This function gets a handle to the DRWTSN32 registry key.
  278. Arguments:
  279. ReadOnly - Caller needs this foe reading purposes only
  280. Although, we could need to create it if its not present
  281. Return Value:
  282. Valid handle - handle opened ok
  283. NULL - could not open the handle
  284. --*/
  285. {
  286. DWORD rc;
  287. DWORD dwDisp;
  288. HKEY hKeyDrWatson;
  289. HKEY hKeyMicrosoft;
  290. _TCHAR szAppName[MAX_PATH];
  291. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  292. REGKEY_SOFTWARE,
  293. 0,
  294. KEY_QUERY_VALUE | KEY_SET_VALUE |
  295. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  296. &hKeyMicrosoft
  297. );
  298. if (rc != ERROR_SUCCESS) {
  299. if (ReadOnly) {
  300. // Try oepning it for read only
  301. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  302. REGKEY_SOFTWARE,
  303. 0,
  304. KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
  305. &hKeyMicrosoft
  306. );
  307. }
  308. if (rc != ERROR_SUCCESS) {
  309. return NULL;
  310. }
  311. }
  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. return NULL;
  339. }
  340. }
  341. if (dwDisp == REG_CREATED_NEW_KEY) {
  342. RegInitializeDefaults( hKeyDrWatson );
  343. }
  344. return hKeyDrWatson;
  345. }
  346. BOOL
  347. RegInitialize(
  348. POPTIONS o
  349. )
  350. /*++
  351. Routine Description:
  352. This function is used to initialize the OPTIONS structure passed in
  353. with the current values in the registry. Note that if the registry
  354. is empty then the defaults are stored in the registry and also
  355. returned in the OPTIONS structure.
  356. Arguments:
  357. o - Returns an OPTIONS struct with initial values
  358. Return Value:
  359. TRUE - all data was retrieved ok
  360. NULL - could not get all data
  361. --*/
  362. {
  363. HKEY hKeyDrWatson;
  364. UINT u1 = sizeof(*o);
  365. UINT u2 = sizeof(OPTIONS);
  366. hKeyDrWatson = RegGetAppKey( TRUE );
  367. Assert( hKeyDrWatson != NULL );
  368. ZeroMemory(o, sizeof(*o));
  369. if (!RegGetAllValues( o, hKeyDrWatson )) {
  370. return FALSE;
  371. }
  372. RegCloseKey( hKeyDrWatson );
  373. return TRUE;
  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. Assert( hKeyDrWatson != NULL );
  393. if (hKeyDrWatson)
  394. {
  395. RegSaveAllValues( hKeyDrWatson, o );
  396. RegCloseKey( hKeyDrWatson );
  397. }
  398. return TRUE;
  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. Assert( hKeyDrWatson != NULL );
  417. if (hKeyDrWatson)
  418. {
  419. RegSetDWORD( hKeyDrWatson, REGKEY_NUM_CRASHES, dwNumCrashes );
  420. RegCloseKey( hKeyDrWatson );
  421. }
  422. return;
  423. }
  424. DWORD
  425. RegGetNumCrashes(
  426. void
  427. )
  428. /*++
  429. Routine Description:
  430. This function get the value in the registry that contains the
  431. number of crashes that have occurred.
  432. Arguments:
  433. None.
  434. Return Value:
  435. the number of craches that have occurred
  436. --*/
  437. {
  438. HKEY hKeyDrWatson;
  439. DWORD dwNumCrashes=0;
  440. hKeyDrWatson = RegGetAppKey( TRUE );
  441. Assert( hKeyDrWatson != NULL );
  442. if ( hKeyDrWatson != NULL ) {
  443. dwNumCrashes = RegQueryDWORD( hKeyDrWatson, REGKEY_NUM_CRASHES );
  444. RegCloseKey( hKeyDrWatson );
  445. }
  446. return dwNumCrashes;
  447. }
  448. BOOLEAN
  449. RegInstallDrWatson(
  450. BOOL fQuiet
  451. )
  452. /*++
  453. Routine Description:
  454. This function sets the AEDebug registry values to automatically
  455. invoke drwtsn32 when a crash occurs.
  456. Arguments:
  457. None.
  458. Return Value:
  459. Valid handle - handle opened ok
  460. NULL - could not open the handle
  461. --*/
  462. {
  463. DWORD rc;
  464. HKEY hKeyMicrosoft;
  465. OPTIONS o;
  466. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  467. REGKEY_AEDEBUG,
  468. 0,
  469. KEY_QUERY_VALUE | KEY_SET_VALUE,
  470. &hKeyMicrosoft
  471. );
  472. if (rc != ERROR_SUCCESS) {
  473. return FALSE;
  474. }
  475. RegSetSZ( hKeyMicrosoft, REGKEY_AUTO, _T("1") );
  476. RegSetSZ( hKeyMicrosoft, REGKEY_DEBUGGER, _T("drwtsn32 -p %ld -e %ld -g") );
  477. RegCloseKey( hKeyMicrosoft );
  478. RegInitialize( &o );
  479. if (fQuiet) {
  480. o.fVisual = FALSE;
  481. o.fSound = FALSE;
  482. RegSave( &o );
  483. }
  484. return TRUE;
  485. }
  486. void
  487. RegSetDWORD(
  488. HKEY hkey,
  489. PTSTR pszSubKey,
  490. DWORD dwValue
  491. )
  492. /*++
  493. Routine Description:
  494. This function changes a DWORD value in the registry using the
  495. hkey and pszSubKey as the registry key info.
  496. Arguments:
  497. hkey - handle to a registry key
  498. pszSubKey - pointer to a subkey string
  499. dwValue - new registry value
  500. Return Value:
  501. None.
  502. --*/
  503. {
  504. DWORD rc;
  505. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_DWORD, (LPBYTE)&dwValue, sizeof(dwValue) );
  506. Assert( rc == ERROR_SUCCESS );
  507. }
  508. void
  509. RegSetBOOL(
  510. HKEY hkey,
  511. PTSTR pszSubKey,
  512. BOOL dwValue
  513. )
  514. /*++
  515. Routine Description:
  516. This function changes a BOOL value in the registry using the
  517. hkey and pszSubKey as the registry key info.
  518. Arguments:
  519. hkey - handle to a registry key
  520. pszSubKey - pointer to a subkey string
  521. dwValue - new registry value
  522. Return Value:
  523. None.
  524. --*/
  525. {
  526. DWORD rc;
  527. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_DWORD, (LPBYTE)&dwValue, 4 );
  528. Assert( rc == ERROR_SUCCESS );
  529. }
  530. void
  531. RegSetSZ(
  532. HKEY hkey,
  533. PTSTR pszSubKey,
  534. PTSTR pszValue
  535. )
  536. /*++
  537. Routine Description:
  538. This function changes a SZ value in the registry using the
  539. hkey and pszSubKey as the registry key info.
  540. Arguments:
  541. hkey - handle to a registry key
  542. pszSubKey - pointer to a subkey string
  543. pszValue - new registry value
  544. Return Value:
  545. None.
  546. --*/
  547. {
  548. DWORD rc;
  549. TCHAR szPath[_MAX_PATH];
  550. // If Dr Watson registry key for log path or crash file are
  551. // the defaults, don't write them to the registry.
  552. // The defaults for these are obtained by querying.
  553. if ( _tcscmp( pszSubKey, REGKEY_LOG_PATH ) == 0 ) {
  554. GetDrWatsonLogPath( szPath );
  555. if (_tcscmp(szPath,pszValue) == 0 ) return;
  556. } else if ( _tcscmp( pszSubKey, REGKEY_CRASH_FILE) == 0 ) {
  557. RegQuerySZ(hkey, pszSubKey, szPath, _MAX_PATH);
  558. if ( _tcscmp(szPath, pszValue) == 0 ) return;
  559. }
  560. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_SZ, (PBYTE) pszValue, (_tcslen(pszValue) +1) * sizeof(_TCHAR) );
  561. Assert( rc == ERROR_SUCCESS );
  562. }
  563. void
  564. RegSetEXPANDSZ(
  565. HKEY hkey,
  566. PTSTR pszSubKey,
  567. PTSTR pszValue
  568. )
  569. /*++
  570. Routine Description:
  571. This function changes a SZ value in the registry using the
  572. hkey and pszSubKey as the registry key info.
  573. Arguments:
  574. hkey - handle to a registry key
  575. pszSubKey - pointer to a subkey string
  576. pszValue - new registry value
  577. Return Value:
  578. None.
  579. --*/
  580. {
  581. DWORD rc;
  582. rc = RegSetValueEx( hkey, pszSubKey, 0, REG_EXPAND_SZ, (PBYTE) pszValue, _tcslen(pszValue)+1 );
  583. Assert( rc == ERROR_SUCCESS );
  584. }
  585. BOOL
  586. RegQueryBOOL(
  587. HKEY hkey,
  588. PTSTR pszSubKey
  589. )
  590. /*++
  591. Routine Description:
  592. This function queries BOOL value in the registry using the
  593. hkey and pszSubKey as the registry key info. If the value is not
  594. found in the registry, it is added with a FALSE value.
  595. Arguments:
  596. hkey - handle to a registry key
  597. pszSubKey - pointer to a subkey string
  598. Return Value:
  599. TRUE or FALSE.
  600. --*/
  601. {
  602. DWORD rc;
  603. DWORD len;
  604. DWORD dwType;
  605. BOOL fValue = FALSE;
  606. len = 4;
  607. rc = RegQueryValueEx( hkey, pszSubKey, 0, &dwType, (LPBYTE)&fValue, &len );
  608. if (rc != ERROR_SUCCESS) {
  609. if (rc == ERROR_FILE_NOT_FOUND) {
  610. fValue = FALSE;
  611. RegSetBOOL( hkey, pszSubKey, fValue );
  612. }
  613. else {
  614. Assert( rc == ERROR_SUCCESS );
  615. }
  616. }
  617. else {
  618. Assert( dwType == REG_DWORD );
  619. }
  620. return fValue;
  621. }
  622. DWORD
  623. RegQueryDWORD(
  624. HKEY hkey,
  625. PTSTR pszSubKey
  626. )
  627. /*++
  628. Routine Description:
  629. This function queries BOOL value in the registry using the
  630. hkey and pszSubKey as the registry key info. If the value is not
  631. found in the registry, it is added with a zero value.
  632. Arguments:
  633. hkey - handle to a registry key
  634. pszSubKey - pointer to a subkey string
  635. Return Value:
  636. registry value
  637. --*/
  638. {
  639. DWORD rc;
  640. DWORD len;
  641. DWORD dwType;
  642. DWORD fValue = 0;
  643. len = 4;
  644. rc = RegQueryValueEx( hkey, pszSubKey, 0, &dwType, (LPBYTE)&fValue, &len );
  645. if (rc != ERROR_SUCCESS) {
  646. if (rc == ERROR_FILE_NOT_FOUND) {
  647. fValue = 0;
  648. RegSetDWORD( hkey, pszSubKey, fValue );
  649. }
  650. else {
  651. Assert( rc == ERROR_SUCCESS );
  652. }
  653. }
  654. else {
  655. Assert( dwType == REG_DWORD );
  656. }
  657. return fValue;
  658. }
  659. void
  660. RegQuerySZ(
  661. HKEY hkey,
  662. PTSTR pszSubKey,
  663. PTSTR pszValue,
  664. DWORD dwSizeValue
  665. )
  666. /*++
  667. Routine Description:
  668. This function queries BOOL value in the registry using the
  669. hkey and pszSubKey as the registry key info. If the value is not
  670. found in the registry, it is added with a zero value.
  671. Arguments:
  672. hkey - handle to a registry key
  673. pszSubKey - pointer to a subkey string
  674. Return Value:
  675. registry value
  676. --*/
  677. {
  678. LONG lRes;
  679. DWORD dwLen;
  680. DWORD dwType;
  681. lRes = RegQueryValueEx( hkey, pszSubKey, 0, &dwType, (PBYTE) pszValue, &dwSizeValue );
  682. if (lRes == ERROR_FILE_NOT_FOUND) {
  683. // If these two SubKeys already exist in the registry, then use the registry values.
  684. // If they don't exist, query for the value.
  685. if ( _tcscmp( pszSubKey, REGKEY_LOG_PATH) == 0 ) {
  686. GetDrWatsonLogPath( pszValue );
  687. } else if ( _tcscmp( pszSubKey, REGKEY_CRASH_FILE) == 0 ) {
  688. GetDrWatsonCrashDump( pszValue );
  689. }
  690. } else {
  691. Assert( lRes == ERROR_SUCCESS );
  692. Assert( dwType == REG_SZ || dwType == REG_EXPAND_SZ );
  693. // If the old defaults for Beta 3 or NT4 log path and crash file
  694. // exist, then delete them and use the new and improved values
  695. if ( _tcscmp( pszSubKey, REGKEY_LOG_PATH) == 0 &&
  696. (_tcsicmp( pszValue, _T("%userprofile%")) == 0 ||
  697. _tcsicmp( pszValue, _T("%windir%")) == 0 ) ) {
  698. // Delete the key
  699. lRes = RegDeleteValue( hkey, pszSubKey);
  700. Assert ( lRes == ERROR_SUCCESS);
  701. GetDrWatsonLogPath( pszValue );
  702. } else if ( _tcscmp( pszSubKey, REGKEY_CRASH_FILE) == 0 &&
  703. _tcsicmp( pszValue, _T("%windir%\\user.dmp")) == 0 ) {
  704. // Delete the key
  705. lRes = RegDeleteValue( hkey, pszSubKey);
  706. Assert( lRes == ERROR_SUCCESS);
  707. GetDrWatsonCrashDump( pszValue );
  708. }
  709. }
  710. }
  711. void
  712. RegLogCurrentVersion(
  713. void
  714. )
  715. /*++
  716. Routine Description:
  717. This function writes system and user info. to the log file
  718. Arguments:
  719. None
  720. Return Value:
  721. registry value
  722. History:
  723. 8/21/97 a-paulbr fixed bug 658
  724. --*/
  725. {
  726. _TCHAR buf[1024];
  727. DWORD rc;
  728. HKEY hKeyCurrentVersion = NULL;
  729. HKEY hKeyControlWindows = NULL;
  730. DWORD dwSPNum = 0;
  731. DWORD dwType = REG_DWORD;
  732. DWORD dwSize = sizeof(DWORD);
  733. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  734. REGKEY_CURRENTVERSION,
  735. 0,
  736. KEY_QUERY_VALUE,
  737. &hKeyCurrentVersion
  738. );
  739. if (rc != ERROR_SUCCESS) {
  740. return;
  741. }
  742. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  743. REGKEY_CONTROLWINDOWS,
  744. 0,
  745. KEY_QUERY_VALUE,
  746. &hKeyControlWindows);
  747. if (hKeyControlWindows) {
  748. //
  749. // I'm using RegQueryValueEx() because there is an assertion in
  750. // RegQueryDWORD() if the key does not exist.
  751. //
  752. RegQueryValueEx(hKeyControlWindows,
  753. REGKEY_CSD_VERSION,
  754. NULL,
  755. &dwType,
  756. (BYTE*)&dwSPNum,
  757. &dwSize
  758. );
  759. }
  760. RegQuerySZ(hKeyCurrentVersion, REGKEY_CURRENT_BUILD, buf, sizeof(buf) );
  761. lprintf( MSG_CURRENT_BUILD, buf );
  762. if ((hKeyControlWindows) &&
  763. (dwType == REG_DWORD) &&
  764. (HIBYTE(LOWORD(dwSPNum)) != 0)) {
  765. _stprintf(buf, _T("%hu"), HIBYTE(LOWORD(dwSPNum)));
  766. lprintf( MSG_CSD_VERSION, buf );
  767. } else {
  768. _stprintf(buf, _T("None"));
  769. lprintf( MSG_CSD_VERSION, buf );
  770. }
  771. RegQuerySZ( hKeyCurrentVersion,REGKEY_CURRENT_TYPE, buf, sizeof(buf) );
  772. lprintf( MSG_CURRENT_TYPE, buf );
  773. RegQuerySZ( hKeyCurrentVersion,REGKEY_REG_ORGANIZATION, buf, sizeof(buf) );
  774. lprintf( MSG_REG_ORGANIZATION, buf );
  775. RegQuerySZ( hKeyCurrentVersion,REGKEY_REG_OWNER, buf, sizeof(buf) );
  776. lprintf( MSG_REG_OWNER, buf );
  777. //
  778. // Close the keys that we opened
  779. //
  780. RegCloseKey(hKeyCurrentVersion);
  781. RegCloseKey(hKeyControlWindows);
  782. return;
  783. }
  784. void
  785. RegLogProcessorType(
  786. void
  787. )
  788. {
  789. _TCHAR buf[1024];
  790. DWORD rc;
  791. HKEY hKey;
  792. rc = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  793. REGKEY_PROCESSOR,
  794. 0,
  795. KEY_QUERY_VALUE,
  796. &hKey
  797. );
  798. if (rc != ERROR_SUCCESS) {
  799. return;
  800. }
  801. RegQuerySZ( hKey, REGKEY_PROCESSOR_ID, buf, sizeof(buf) );
  802. lprintf( MSG_SYSINFO_PROC_TYPE, buf );
  803. return;
  804. }
  805. void
  806. GetDrWatsonLogPath(
  807. LPTSTR szPath
  808. )
  809. {
  810. int rc;
  811. SECURITY_ATTRIBUTES SecAttrib;
  812. SECURITY_DESCRIPTOR SecDescript;
  813. SHGetFolderPath(NULL,
  814. CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szPath);
  815. Assert( _tcsicmp(szPath,_T("")) != 0 );
  816. _tcscat(szPath,_T("\\Microsoft\\Dr Watson") );
  817. // Create a DACL that allows all access to the directory
  818. SecAttrib.nLength=sizeof(SECURITY_ATTRIBUTES);
  819. SecAttrib.lpSecurityDescriptor=&SecDescript;
  820. SecAttrib.bInheritHandle=FALSE;
  821. InitializeSecurityDescriptor(&SecDescript, SECURITY_DESCRIPTOR_REVISION);
  822. SetSecurityDescriptorDacl(&SecDescript, TRUE, NULL, FALSE);
  823. if ( !CreateDirectory(szPath,&SecAttrib) ) {
  824. if( GetLastError() != ERROR_ALREADY_EXISTS ) {
  825. rc = GetLastError();
  826. }
  827. }
  828. return;
  829. }
  830. void
  831. GetDrWatsonCrashDump(
  832. LPTSTR szPath
  833. )
  834. {
  835. int rc;
  836. SECURITY_ATTRIBUTES SecAttrib;
  837. SECURITY_DESCRIPTOR SecDescript;
  838. SHGetFolderPath(NULL,
  839. CSIDL_COMMON_APPDATA | CSIDL_FLAG_CREATE, NULL, 0, szPath);
  840. Assert( _tcsicmp(szPath,_T("")) != 0 );
  841. _tcscat(szPath,_T("\\Microsoft\\Dr Watson") );
  842. // Create a DACL that allows all access to the directory
  843. SecAttrib.nLength=sizeof(SECURITY_ATTRIBUTES);
  844. SecAttrib.lpSecurityDescriptor=&SecDescript;
  845. SecAttrib.bInheritHandle=FALSE;
  846. InitializeSecurityDescriptor(&SecDescript, SECURITY_DESCRIPTOR_REVISION);
  847. SetSecurityDescriptorDacl(&SecDescript, TRUE, NULL, FALSE);
  848. if ( !CreateDirectory(szPath,&SecAttrib) ) {
  849. if( GetLastError() != ERROR_ALREADY_EXISTS ) {
  850. rc = GetLastError();
  851. }
  852. }
  853. _tcscat(szPath, _T("\\user.dmp") );
  854. return;
  855. }
  856. void
  857. DeleteCrashDump()
  858. {
  859. HKEY hKeyDrWatson;
  860. TCHAR szCrashDump[MAX_PATH];
  861. hKeyDrWatson = RegGetAppKey( TRUE );
  862. if (hKeyDrWatson) {
  863. RegQuerySZ(hKeyDrWatson, REGKEY_CRASH_FILE, szCrashDump, sizeof(szCrashDump) );
  864. DeleteFile(szCrashDump);
  865. RegCloseKey( hKeyDrWatson );
  866. }
  867. }