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.

427 lines
10 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. All rights reserved.
  4. Module Name:
  5. dbgreg.cxx
  6. Abstract:
  7. Debug Registry class
  8. Author:
  9. Steve Kiraly (SteveKi) 18-Jun-1998
  10. Revision History:
  11. --*/
  12. #include "precomp.hxx"
  13. #pragma hdrstop
  14. #include "dbgloadl.hxx"
  15. #include "dbgreg.hxx"
  16. TDebugRegApis::
  17. TDebugRegApis(
  18. VOID
  19. ) : m_Lib( _T("advapi32.dll") ),
  20. m_bValid( FALSE ),
  21. m_CreateKeyEx (NULL ),
  22. m_OpenKeyEx( NULL ),
  23. m_CloseKey( NULL ),
  24. m_QueryValueEx( NULL ),
  25. m_SetValueEx( NULL ),
  26. m_EnumKeyEx( NULL ),
  27. m_DeleteKey( NULL )
  28. {
  29. if( m_Lib.bValid() )
  30. {
  31. m_CreateKeyEx = reinterpret_cast<pfRegCreateKeyEx> ( m_Lib.pfnGetProc( "RegCreateKeyEx" SUFFIX ) );
  32. m_OpenKeyEx = reinterpret_cast<pfRegOpenKeyEx> ( m_Lib.pfnGetProc( "RegOpenKeyEx" SUFFIX ) );
  33. m_CloseKey = reinterpret_cast<pfRegCloseKey> ( m_Lib.pfnGetProc( "RegCloseKey" ) );
  34. m_QueryValueEx = reinterpret_cast<pfRegQueryValueEx> ( m_Lib.pfnGetProc( "RegQueryValueEx" SUFFIX ) );
  35. m_SetValueEx = reinterpret_cast<pfRegSetValueEx> ( m_Lib.pfnGetProc( "RegSetValueEx" SUFFIX ) );
  36. m_EnumKeyEx = reinterpret_cast<pfRegEnumKeyEx> ( m_Lib.pfnGetProc( "RegEnumKeyEx" SUFFIX ) );
  37. m_DeleteKey = reinterpret_cast<pfRegDeleteKey> ( m_Lib.pfnGetProc( "RegDeleteKey" SUFFIX ) );
  38. m_DeleteValue = reinterpret_cast<pfRegDeleteValue> ( m_Lib.pfnGetProc( "RegDeleteValue" SUFFIX ) );
  39. if( m_CreateKeyEx &&
  40. m_OpenKeyEx &&
  41. m_CloseKey &&
  42. m_QueryValueEx &&
  43. m_SetValueEx &&
  44. m_EnumKeyEx &&
  45. m_DeleteKey &&
  46. m_DeleteValue )
  47. {
  48. m_bValid = TRUE;
  49. }
  50. }
  51. }
  52. BOOL
  53. TDebugRegApis::
  54. bValid(
  55. VOID
  56. ) const
  57. {
  58. return m_bValid;
  59. }
  60. TDebugRegistry::
  61. TDebugRegistry(
  62. IN LPCTSTR pszSection,
  63. IN UINT ioFlags,
  64. IN HKEY hOpenedKey
  65. ) : m_strSection( pszSection ),
  66. m_hKey( NULL ),
  67. m_Status( ERROR_SUCCESS )
  68. {
  69. DBG_ASSERT( pszSection );
  70. DBG_ASSERT( hOpenedKey );
  71. if( m_Reg.bValid() )
  72. {
  73. DWORD dwDisposition = 0;
  74. UINT uAccessIndex = 0;
  75. static DWORD adwAccess [] = { 0, KEY_READ, KEY_WRITE, KEY_ALL_ACCESS };
  76. uAccessIndex = ioFlags & ( kRead | kWrite );
  77. if( uAccessIndex )
  78. {
  79. if( ioFlags & kCreate )
  80. {
  81. m_Status = m_Reg.m_CreateKeyEx( hOpenedKey,
  82. m_strSection,
  83. 0,
  84. NULL,
  85. 0,
  86. adwAccess[ uAccessIndex ],
  87. NULL,
  88. &m_hKey,
  89. &dwDisposition );
  90. }
  91. if( ioFlags & kOpen )
  92. {
  93. m_Status = m_Reg.m_OpenKeyEx( hOpenedKey,
  94. m_strSection,
  95. 0,
  96. adwAccess[ uAccessIndex ],
  97. &m_hKey );
  98. }
  99. }
  100. }
  101. }
  102. TDebugRegistry::
  103. ~TDebugRegistry(
  104. VOID
  105. )
  106. {
  107. if( m_hKey )
  108. {
  109. m_Reg.m_CloseKey( m_hKey );
  110. }
  111. }
  112. BOOL
  113. TDebugRegistry::
  114. bValid(
  115. VOID
  116. ) const
  117. {
  118. //
  119. // A valid hKey and a valid section name is the class valid check.
  120. //
  121. return m_hKey != NULL && m_strSection.bValid() && m_Reg.bValid();
  122. }
  123. DWORD
  124. TDebugRegistry::
  125. LastError(
  126. VOID
  127. ) const
  128. {
  129. return m_Status;
  130. }
  131. BOOL
  132. TDebugRegistry::
  133. bRead(
  134. IN LPCTSTR pValueName,
  135. IN OUT DWORD &dwValue
  136. )
  137. {
  138. DBG_ASSERT( bValid() );
  139. DBG_ASSERT( pValueName );
  140. DWORD dwType = REG_DWORD;
  141. DWORD dwSize = sizeof( dwValue );
  142. m_Status = m_Reg.m_QueryValueEx( m_hKey,
  143. pValueName,
  144. NULL,
  145. &dwType,
  146. reinterpret_cast<LPBYTE>( &dwValue ),
  147. &dwSize );
  148. return m_Status == ERROR_SUCCESS && dwType == REG_DWORD;
  149. }
  150. BOOL
  151. TDebugRegistry::
  152. bRead(
  153. IN LPCTSTR pValueName,
  154. IN OUT BOOL &bValue
  155. )
  156. {
  157. DBG_ASSERT( bValid() );
  158. DBG_ASSERT( pValueName );
  159. DWORD dwType = REG_DWORD;
  160. DWORD dwSize = sizeof( bValue );
  161. m_Status = m_Reg.m_QueryValueEx( m_hKey,
  162. pValueName,
  163. NULL,
  164. &dwType,
  165. reinterpret_cast<LPBYTE>( &bValue ),
  166. &dwSize );
  167. return m_Status == ERROR_SUCCESS && dwType == REG_DWORD;
  168. }
  169. BOOL
  170. TDebugRegistry::
  171. bRead(
  172. IN LPCTSTR pValueName,
  173. IN OUT TDebugString &strValue
  174. )
  175. {
  176. DBG_ASSERT( bValid() );
  177. DBG_ASSERT( pValueName );
  178. TCHAR szBuffer[kHint];
  179. DWORD dwType = REG_SZ;
  180. BOOL bStatus = FALSE;
  181. DWORD dwSize = sizeof( szBuffer );
  182. m_Status = m_Reg.m_QueryValueEx( m_hKey,
  183. pValueName,
  184. NULL,
  185. &dwType,
  186. reinterpret_cast<LPBYTE>( szBuffer ),
  187. &dwSize );
  188. if( m_Status == ERROR_MORE_DATA && dwType == REG_SZ && dwSize )
  189. {
  190. LPTSTR pszBuff = INTERNAL_NEW TCHAR[ dwSize ];
  191. if( pszBuff )
  192. {
  193. m_Status = m_Reg.m_QueryValueEx( m_hKey,
  194. pValueName,
  195. NULL,
  196. &dwType,
  197. reinterpret_cast<LPBYTE>( pszBuff ),
  198. &dwSize );
  199. }
  200. else
  201. {
  202. m_Status = ERROR_NOT_ENOUGH_MEMORY;
  203. }
  204. if( m_Status == ERROR_SUCCESS )
  205. {
  206. bStatus = strValue.bUpdate( pszBuff );
  207. }
  208. INTERNAL_DELETE [] pszBuff;
  209. }
  210. else
  211. {
  212. if( m_Status == ERROR_SUCCESS && dwType == REG_SZ )
  213. {
  214. bStatus = strValue.bUpdate( szBuffer );
  215. }
  216. }
  217. return bStatus;
  218. }
  219. BOOL
  220. TDebugRegistry::
  221. bRead(
  222. IN LPCTSTR pValueName,
  223. IN OUT PVOID pValue,
  224. IN DWORD cbSize,
  225. IN LPDWORD pcbNeeded OPTIONAL
  226. )
  227. {
  228. DBG_ASSERT( bValid() );
  229. DBG_ASSERT( pValueName );
  230. DBG_ASSERT( pValue );
  231. DWORD dwType = REG_BINARY;
  232. BOOL bStatus = FALSE;
  233. DWORD dwSize = cbSize;
  234. m_Status = m_Reg.m_QueryValueEx( m_hKey,
  235. pValueName,
  236. NULL,
  237. &dwType,
  238. reinterpret_cast<LPBYTE>( pValue ),
  239. &dwSize );
  240. if( m_Status == ERROR_MORE_DATA && pcbNeeded )
  241. {
  242. *pcbNeeded = dwSize;
  243. }
  244. return m_Status == ERROR_SUCCESS && dwType == REG_BINARY && dwSize == cbSize;
  245. }
  246. BOOL
  247. TDebugRegistry::
  248. bWrite(
  249. IN LPCTSTR pValueName,
  250. IN const DWORD dwValue
  251. )
  252. {
  253. DBG_ASSERT( bValid() );
  254. DBG_ASSERT( pValueName );
  255. m_Status = m_Reg.m_SetValueEx( m_hKey,
  256. pValueName,
  257. 0,
  258. REG_DWORD,
  259. reinterpret_cast<const BYTE *>( &dwValue ),
  260. sizeof( dwValue ) );
  261. return m_Status == ERROR_SUCCESS;
  262. }
  263. BOOL
  264. TDebugRegistry::
  265. bWrite(
  266. IN LPCTSTR pValueName,
  267. IN LPCTSTR pszValue
  268. )
  269. {
  270. DBG_ASSERT( bValid() );
  271. DBG_ASSERT( pValueName );
  272. m_Status = m_Reg.m_SetValueEx( m_hKey,
  273. pValueName,
  274. 0,
  275. REG_SZ,
  276. reinterpret_cast<const BYTE *>( pszValue ),
  277. _tcslen( pszValue ) * sizeof( TCHAR ) + sizeof( TCHAR ) );
  278. return m_Status == ERROR_SUCCESS;
  279. }
  280. BOOL
  281. TDebugRegistry::
  282. bWrite(
  283. IN LPCTSTR pValueName,
  284. IN const PVOID pValue,
  285. IN DWORD cbSize
  286. )
  287. {
  288. DBG_ASSERT( bValid() );
  289. DBG_ASSERT( pValueName );
  290. DBG_ASSERT( pValue );
  291. m_Status = m_Reg.m_SetValueEx( m_hKey,
  292. pValueName,
  293. 0,
  294. REG_BINARY,
  295. reinterpret_cast<const BYTE *>( pValue ),
  296. cbSize );
  297. return m_Status == ERROR_SUCCESS;
  298. }
  299. BOOL
  300. TDebugRegistry::
  301. bRemove(
  302. IN LPCTSTR pValueName
  303. )
  304. {
  305. DBG_ASSERT( bValid() );
  306. DBG_ASSERT( pValueName );
  307. m_Status = m_Reg.m_DeleteValue( m_hKey, pValueName );
  308. return m_Status == ERROR_SUCCESS;
  309. }
  310. BOOL
  311. TDebugRegistry::
  312. bRemoveKey(
  313. IN LPCTSTR pKeyName
  314. )
  315. {
  316. DBG_ASSERT( bValid() );
  317. DBG_ASSERT( pKeyName );
  318. m_Status = dwRecursiveRegDeleteKey( m_hKey, pKeyName );
  319. return m_Status == ERROR_SUCCESS;
  320. }
  321. DWORD
  322. TDebugRegistry::
  323. dwRecursiveRegDeleteKey(
  324. IN HKEY hKey,
  325. IN LPCTSTR pszSubkey
  326. ) const
  327. {
  328. HKEY hSubkey = NULL;
  329. DWORD dwStatus = m_Reg.m_OpenKeyEx( hKey,
  330. pszSubkey,
  331. 0,
  332. KEY_ALL_ACCESS,
  333. &hSubkey );
  334. while ( dwStatus == ERROR_SUCCESS )
  335. {
  336. TCHAR szSubkey[ MAX_PATH ];
  337. DWORD cbSubkeySize = COUNTOF( szSubkey );
  338. dwStatus = m_Reg.m_EnumKeyEx( hSubkey,
  339. 0,
  340. szSubkey,
  341. &cbSubkeySize,
  342. 0,
  343. 0,
  344. 0,
  345. 0 );
  346. if( dwStatus == ERROR_NO_MORE_ITEMS )
  347. break;
  348. if( dwStatus != ERROR_SUCCESS )
  349. return dwStatus;
  350. dwStatus = dwRecursiveRegDeleteKey( hSubkey, szSubkey );
  351. }
  352. if( hSubkey )
  353. {
  354. m_Reg.m_CloseKey( hSubkey );
  355. }
  356. dwStatus = m_Reg.m_DeleteKey( hKey, pszSubkey );
  357. return dwStatus;
  358. }