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.

698 lines
22 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000.
  5. //
  6. // File: filtreg.cxx
  7. //
  8. // Contents: Filter registration utility
  9. //
  10. // History: 02 Dec 1997 KyleP Created
  11. //
  12. //--------------------------------------------------------------------------
  13. #include <stdio.h>
  14. extern "C"
  15. {
  16. #include <nt.h>
  17. #include <ntrtl.h>
  18. #include <nturtl.h>
  19. }
  20. #include <windows.h>
  21. //
  22. // From smart.hxx
  23. //
  24. class SRegKey
  25. {
  26. public:
  27. SRegKey( HKEY key ) : _key( key ) {}
  28. SRegKey() : _key( 0 ) {}
  29. ~SRegKey() { Free(); }
  30. void Set( HKEY key ) { _key = key; }
  31. HKEY Acquire() { HKEY tmp = _key; _key = 0; return tmp; }
  32. void Free() { if ( 0 != _key ) { RegCloseKey( _key ); _key = 0; } }
  33. private:
  34. HKEY _key;
  35. };
  36. void Usage();
  37. void PrintExtensions( HKEY hkeyCLSID, WCHAR const * wcsTargetCLSID );
  38. void LocateByExtension( HKEY hkeyCLSID );
  39. void LocateByCLSID( HKEY hkeyCLSID );
  40. BOOL LocateFilter( HKEY hkeyBase,
  41. HKEY hkeyCLSID,
  42. WCHAR const * wcsClassOrExt,
  43. WCHAR * wcsFilterName,
  44. WCHAR * wcsFilterDll );
  45. LONG Replicate( WCHAR const * wszDstExt, WCHAR const * wszSrcExt );
  46. extern "C" int __cdecl wmain( int argc, WCHAR * argv[] )
  47. {
  48. if ( argc > 1 )
  49. {
  50. if ( argc != 3 )
  51. Usage();
  52. else
  53. Replicate( argv[1], argv[2] );
  54. }
  55. else
  56. {
  57. //
  58. // Enumerate, looking for extensions and classes with a persistent handler.
  59. //
  60. HKEY hkeyCLSID;
  61. LONG dwError = RegOpenKeyEx( HKEY_CLASSES_ROOT,
  62. L"CLSID",
  63. 0,
  64. KEY_READ | KEY_ENUMERATE_SUB_KEYS,
  65. &hkeyCLSID );
  66. if ( ERROR_SUCCESS != dwError )
  67. {
  68. printf( "RegOpenKey( \"CLSID\" ) returned %d\n", dwError );
  69. }
  70. else
  71. {
  72. SRegKey xkeyCLSID( hkeyCLSID );
  73. printf( "Filters loaded by extension:\n" );
  74. LocateByExtension( hkeyCLSID );
  75. printf( "\n\nFilters loaded by class:\n" );
  76. LocateByCLSID( hkeyCLSID );
  77. }
  78. }
  79. return 0;
  80. }
  81. void Usage()
  82. {
  83. printf( "Usage: filtreg [dstExt] [srcExt]\n"
  84. " Displays IFilter registrations. If [dstExt] and [srcExt]\n"
  85. " are specified then [dstExt] is registered to act like [srcExt].\n" );
  86. }
  87. void LocateByExtension( HKEY hkeyCLSID )
  88. {
  89. DWORD dwExtIndex;
  90. DWORD dwError = RegQueryInfoKey ( HKEY_CLASSES_ROOT,
  91. 0,
  92. 0,
  93. 0,
  94. &dwExtIndex,
  95. 0,
  96. 0,
  97. 0,
  98. 0,
  99. 0,
  100. 0,
  101. 0 );
  102. if ( ERROR_SUCCESS != dwError )
  103. {
  104. printf( "RegQueryInfoKey( HKCR ) returned %d\n", dwError );
  105. }
  106. else
  107. {
  108. for ( DWORD dwIndex = 0; dwIndex < dwExtIndex; dwIndex++ )
  109. {
  110. WCHAR wcsExt[100];
  111. DWORD ccExt = sizeof(wcsExt)/sizeof(WCHAR);
  112. dwError = RegEnumKeyEx( HKEY_CLASSES_ROOT,
  113. dwIndex,
  114. wcsExt,
  115. &ccExt,
  116. 0,
  117. 0,
  118. 0,
  119. 0 );
  120. //
  121. // All the extensions come first.
  122. //
  123. if ( ERROR_SUCCESS != dwError || ( wcsExt[0] != L'.' && wcsExt[0] != L'*' ) )
  124. break;
  125. WCHAR wcsFilterName[MAX_PATH];
  126. WCHAR wcsFilterDll[MAX_PATH];
  127. if ( LocateFilter( HKEY_CLASSES_ROOT,
  128. hkeyCLSID,
  129. wcsExt,
  130. wcsFilterName,
  131. wcsFilterDll ) )
  132. {
  133. printf( "%ws --> %ws (%ws)\n", wcsExt, wcsFilterName, wcsFilterDll );
  134. }
  135. }
  136. }
  137. }
  138. void LocateByCLSID( HKEY hkeyCLSID )
  139. {
  140. DWORD dwClsidIndex;
  141. DWORD dwError = RegQueryInfoKey ( hkeyCLSID,
  142. 0,
  143. 0,
  144. 0,
  145. &dwClsidIndex,
  146. 0,
  147. 0,
  148. 0,
  149. 0,
  150. 0,
  151. 0,
  152. 0 );
  153. if ( ERROR_SUCCESS != dwError )
  154. {
  155. printf( "RegQueryInfoKey( \"CLSID\" ) returned %d\n", dwError );
  156. }
  157. else
  158. {
  159. for ( DWORD dwIndex = dwClsidIndex - 2; dwIndex != 0xFFFFFFFF; dwIndex-- )
  160. {
  161. WCHAR wcsCLSID[100];
  162. DWORD ccCLSID = sizeof(wcsCLSID)/sizeof(WCHAR);
  163. dwError = RegEnumKeyEx( hkeyCLSID,
  164. dwIndex,
  165. wcsCLSID,
  166. &ccCLSID,
  167. 0,
  168. 0,
  169. 0,
  170. 0 );
  171. if ( ERROR_SUCCESS == dwError )
  172. {
  173. //
  174. // Look for a filter.
  175. //
  176. WCHAR wcsFilterName[MAX_PATH];
  177. WCHAR wcsFilterDll[MAX_PATH];
  178. if ( LocateFilter( hkeyCLSID,
  179. hkeyCLSID,
  180. wcsCLSID,
  181. wcsFilterName,
  182. wcsFilterDll ) )
  183. {
  184. //
  185. // Find a decent name for the class.
  186. //
  187. HKEY hkeyClass;
  188. RegOpenKeyEx( hkeyCLSID,
  189. wcsCLSID,
  190. 0,
  191. KEY_READ,
  192. &hkeyClass );
  193. SRegKey xkeyClass( hkeyClass );
  194. WCHAR wcsClassName[500];
  195. DWORD dwType;
  196. DWORD cbClassName = sizeof(wcsClassName);
  197. dwError = RegQueryValueEx( hkeyClass,
  198. 0,
  199. 0,
  200. &dwType,
  201. (BYTE *)wcsClassName,
  202. &cbClassName );
  203. if ( ERROR_SUCCESS != dwError || dwType != REG_SZ || wcsClassName[0] == 0)
  204. {
  205. wcscpy( wcsClassName, wcsCLSID );
  206. }
  207. printf( "%ws\n\tFilter: %ws (%ws)\n", wcsClassName, wcsFilterName, wcsFilterDll );
  208. PrintExtensions( hkeyCLSID, wcsCLSID );
  209. printf( "\n\n" );
  210. }
  211. }
  212. }
  213. }
  214. }
  215. BOOL LocateFilter( HKEY hkeyBase,
  216. HKEY hkeyCLSID,
  217. WCHAR const * wcsClassOrExt,
  218. WCHAR * wcsFilterName,
  219. WCHAR * wcsFilterDll )
  220. {
  221. BOOL fOk = FALSE;
  222. do
  223. {
  224. //
  225. // Look for a persistent handler
  226. //
  227. unsigned cwc = wcslen( wcsClassOrExt ) + wcslen( L"\\PersistentHandler" );
  228. if ( cwc >= MAX_PATH )
  229. return FALSE;
  230. HKEY hkeyPH;
  231. WCHAR wcsTemp[MAX_PATH];
  232. wcscpy( wcsTemp, wcsClassOrExt );
  233. wcscat( wcsTemp, L"\\PersistentHandler" );
  234. DWORD dwError = RegOpenKeyEx( hkeyBase,
  235. wcsTemp,
  236. 0,
  237. KEY_READ | KEY_ENUMERATE_SUB_KEYS,
  238. &hkeyPH );
  239. if ( ERROR_SUCCESS != dwError )
  240. break;
  241. SRegKey xkeyPH( hkeyPH );
  242. //
  243. // Find the name of the persistent handler
  244. //
  245. wcscat( wcsFilterName, L"Unknown" );
  246. wcscat( wcsFilterDll, L"Unknown" );
  247. WCHAR wcsPHClass[1000];
  248. DWORD cbPHClass = sizeof(wcsPHClass);
  249. DWORD dwType;
  250. dwError = RegQueryValueEx( hkeyPH,
  251. 0,
  252. 0,
  253. &dwType,
  254. (BYTE *)wcsPHClass,
  255. &cbPHClass );
  256. if ( ERROR_SUCCESS != dwError )
  257. break;
  258. HKEY hkeyPHClass;
  259. wcscat( wcsPHClass, L"\\PersistentAddinsRegistered\\{89BCB740-6119-101A-BCB7-00DD010655AF}" );
  260. RegOpenKeyEx( hkeyCLSID,
  261. wcsPHClass,
  262. 0,
  263. KEY_READ,
  264. &hkeyPHClass );
  265. SRegKey xkeyPHClass( hkeyPHClass );
  266. //
  267. // Now open the filter class and look for a name.
  268. //
  269. if ( ERROR_SUCCESS != dwError )
  270. break;
  271. WCHAR wcsFilterClass[1000];
  272. DWORD cbFilterClass = sizeof(wcsFilterClass);
  273. dwError = RegQueryValueEx( hkeyPHClass,
  274. 0,
  275. 0,
  276. &dwType,
  277. (BYTE *)wcsFilterClass,
  278. &cbFilterClass );
  279. if ( ERROR_SUCCESS != dwError || dwType != REG_SZ )
  280. break;
  281. HKEY hkeyFilterClass;
  282. dwError = RegOpenKeyEx( hkeyCLSID,
  283. wcsFilterClass,
  284. 0,
  285. KEY_READ,
  286. &hkeyFilterClass );
  287. if ( ERROR_SUCCESS != dwError )
  288. break;
  289. SRegKey xkeyFilterClass( hkeyFilterClass );
  290. DWORD cbFilterName = MAX_PATH;
  291. dwError = RegQueryValueEx( hkeyFilterClass,
  292. 0,
  293. 0,
  294. &dwType,
  295. (BYTE *)wcsFilterName,
  296. &cbFilterName );
  297. //
  298. // Don't check for error, because "Unknown was already in wcsFiltername
  299. //
  300. HKEY hkeyFilterIPS;
  301. dwError = RegOpenKeyEx( hkeyFilterClass,
  302. L"InprocServer32",
  303. 0,
  304. KEY_READ,
  305. &hkeyFilterIPS );
  306. if ( ERROR_SUCCESS != dwError )
  307. break;
  308. DWORD cbFilterDll = MAX_PATH;
  309. dwError = RegQueryValueEx( hkeyFilterIPS,
  310. 0,
  311. 0,
  312. &dwType,
  313. (BYTE *)wcsFilterDll,
  314. &cbFilterDll );
  315. //
  316. // Don't check for error, because "Unknown was already in wcsFiltername
  317. //
  318. fOk = TRUE;
  319. } while( FALSE );
  320. return fOk;
  321. }
  322. void PrintExtensions( HKEY hkeyCLSID, WCHAR const * wcsTargetCLSID )
  323. {
  324. unsigned cExt = 0;
  325. //
  326. // Re-used vars
  327. //
  328. DWORD ccTemp; // Size for RegQueryValueEx
  329. DWORD dwType; // Type for RegQueryValueEx
  330. DWORD dwClassIndex;
  331. DWORD dwError = RegQueryInfoKey ( HKEY_CLASSES_ROOT,
  332. 0,
  333. 0,
  334. 0,
  335. &dwClassIndex,
  336. 0,
  337. 0,
  338. 0,
  339. 0,
  340. 0,
  341. 0,
  342. 0 );
  343. if ( ERROR_SUCCESS != dwError )
  344. {
  345. printf( "RegQueryInfoKey( \"CLSID\" ) returned %d\n", dwError );
  346. }
  347. else
  348. {
  349. //
  350. // Outer loop looks for items registered with this class id
  351. //
  352. WCHAR wcsShortName[100];
  353. WCHAR wcsShortName2[sizeof(wcsShortName)/sizeof(WCHAR)];
  354. wcsShortName2[0] = 0;
  355. for ( DWORD dwIndex = dwClassIndex - 2; dwIndex != 0xFFFFFFFF; dwIndex-- )
  356. {
  357. ccTemp = sizeof(wcsShortName)/sizeof(WCHAR);
  358. dwError = RegEnumKeyEx( HKEY_CLASSES_ROOT,
  359. dwIndex,
  360. wcsShortName,
  361. &ccTemp,
  362. 0,
  363. 0,
  364. 0,
  365. 0 );
  366. if ( ERROR_SUCCESS != dwError )
  367. continue;
  368. HKEY hkeyClsid;
  369. WCHAR wcsTemp[sizeof(wcsShortName)/sizeof(WCHAR) + 50];
  370. unsigned cwc = wcslen( wcsShortName ) + wcslen( L"\\CLSID" );
  371. if ( cwc >= ( sizeof wcsTemp / sizeof WCHAR ) )
  372. return;
  373. wcscpy( wcsTemp, wcsShortName );
  374. wcscat( wcsTemp, L"\\CLSID" );
  375. dwError = RegOpenKeyEx( HKEY_CLASSES_ROOT,
  376. wcsTemp,
  377. 0,
  378. KEY_READ | KEY_ENUMERATE_SUB_KEYS,
  379. &hkeyClsid );
  380. if ( ERROR_SUCCESS != dwError )
  381. continue;
  382. //
  383. // This is a short name. Now get the Class Id and see if
  384. // it matches.
  385. //
  386. SRegKey xkeyClsid( hkeyClsid );
  387. WCHAR wcsClsid[100];
  388. DWORD cbTemp = sizeof(wcsClsid);
  389. dwError = RegQueryValueEx( hkeyClsid,
  390. 0,
  391. 0,
  392. &dwType,
  393. (BYTE *)wcsClsid,
  394. &cbTemp );
  395. if ( ERROR_SUCCESS != dwError ||
  396. 0 != _wcsicmp( wcsClsid, wcsTargetCLSID ) )
  397. {
  398. continue;
  399. }
  400. //
  401. // This is a matching short name. Now, go back and look for
  402. // extensions.
  403. //
  404. for ( DWORD dwIndex2 = 0; dwIndex2 < dwClassIndex; dwIndex2++ )
  405. {
  406. WCHAR wcsExtension[100];
  407. DWORD ccExtension = sizeof(wcsExtension)/sizeof(WCHAR);
  408. dwError = RegEnumKeyEx( HKEY_CLASSES_ROOT,
  409. dwIndex2,
  410. wcsExtension,
  411. &ccExtension,
  412. 0,
  413. 0,
  414. 0,
  415. 0 );
  416. //
  417. // All the extensions come first.
  418. //
  419. if ( ERROR_SUCCESS != dwError || (wcsExtension[0] != L'.' && wcsExtension[0] != L'*') )
  420. break;
  421. //
  422. // Potential extension...
  423. //
  424. HKEY hkeyExtension;
  425. dwError = RegOpenKeyEx( HKEY_CLASSES_ROOT,
  426. wcsExtension,
  427. 0,
  428. KEY_READ | KEY_ENUMERATE_SUB_KEYS,
  429. &hkeyExtension );
  430. if ( ERROR_SUCCESS != dwError )
  431. continue;
  432. SRegKey xkeyExtension( hkeyExtension );
  433. WCHAR wcsShortName3[sizeof(wcsShortName)/sizeof(WCHAR)];
  434. cbTemp = sizeof(wcsShortName3);
  435. dwError = RegQueryValueEx( hkeyExtension,
  436. 0,
  437. 0,
  438. &dwType,
  439. (BYTE *)wcsShortName3,
  440. &cbTemp );
  441. if ( ERROR_SUCCESS == dwError && 0 == _wcsicmp( wcsShortName, wcsShortName3 ) )
  442. {
  443. //
  444. // Work around wierd anomalies in registry enumeration.
  445. //
  446. #if 0
  447. if ( 0 == _wcsicmp( wcsShortName2, wcsShortName3 ) )
  448. continue;
  449. else
  450. wcscpy( wcsShortName2, wcsShortName3 );
  451. #endif
  452. //
  453. // Is this extension covered by an override?
  454. //
  455. WCHAR wcsFilterName[MAX_PATH];
  456. WCHAR wcsFilterDll[MAX_PATH];
  457. if ( !LocateFilter( HKEY_CLASSES_ROOT,
  458. hkeyCLSID,
  459. wcsExtension,
  460. wcsFilterName,
  461. wcsFilterDll ) )
  462. {
  463. if ( cExt % 2 == 0 )
  464. {
  465. if ( 0 != cExt )
  466. printf( "\n" );
  467. printf( "\tExtensions: %ws (%ws) ", wcsExtension, wcsShortName );
  468. }
  469. else
  470. printf( "%ws (%ws) ", wcsExtension, wcsShortName );
  471. cExt++;
  472. }
  473. }
  474. }
  475. }
  476. }
  477. }
  478. LONG Replicate( WCHAR const * wszDstExt, WCHAR const * wszSrcExt )
  479. {
  480. DWORD dwError;
  481. do
  482. {
  483. //
  484. // First, look up the old one...
  485. //
  486. unsigned cwc = wcslen( wszSrcExt ) + wcslen( L"\\PersistentHandler" );
  487. if ( cwc >= MAX_PATH )
  488. return ERROR_INVALID_PARAMETER;
  489. HKEY hkeyPH;
  490. WCHAR wcsTemp[MAX_PATH];
  491. wcscpy( wcsTemp, wszSrcExt );
  492. wcscat( wcsTemp, L"\\PersistentHandler" );
  493. dwError = RegOpenKeyEx( HKEY_CLASSES_ROOT,
  494. wcsTemp,
  495. 0,
  496. KEY_READ | KEY_ENUMERATE_SUB_KEYS,
  497. &hkeyPH );
  498. if ( ERROR_SUCCESS != dwError )
  499. {
  500. printf( "Error %u opening HKCR\\%ws\n", dwError, wcsTemp );
  501. break;
  502. }
  503. SRegKey xkeyPH( hkeyPH );
  504. DWORD dwType;
  505. WCHAR wcsPH[100];
  506. DWORD cbTemp = sizeof(wcsPH);
  507. dwError = RegQueryValueEx( hkeyPH,
  508. 0,
  509. 0,
  510. &dwType,
  511. (BYTE *)wcsPH,
  512. &cbTemp );
  513. if ( ERROR_SUCCESS != dwError )
  514. {
  515. printf( "Error %u reading persistent handler class.\n", dwError );
  516. break;
  517. }
  518. //
  519. // Now append to new extension.
  520. //
  521. HKEY hkeyDstPH;
  522. DWORD dwDisposition;
  523. cwc = wcslen( wszDstExt ) + wcslen( L"\\PersistentHandler" );
  524. if ( cwc >= MAX_PATH )
  525. return ERROR_INVALID_PARAMETER;
  526. wcscpy( wcsTemp, wszDstExt );
  527. wcscat( wcsTemp, L"\\PersistentHandler" );
  528. dwError = RegCreateKeyExW( HKEY_CLASSES_ROOT, // Root
  529. wcsTemp, // Sub key
  530. 0, // Reserved
  531. 0, // Class
  532. 0, // Flags
  533. KEY_ALL_ACCESS, // Access
  534. 0, // Security
  535. &hkeyDstPH, // Handle
  536. &dwDisposition ); // Disposition
  537. if ( ERROR_SUCCESS != dwError )
  538. {
  539. printf( "Error %u creating persistent handler key HKCR\\%ws\n", dwError, wcsTemp );
  540. break;
  541. }
  542. SRegKey xkeyDstPH( hkeyDstPH );
  543. dwError = RegSetValueExW( hkeyDstPH, // Key
  544. 0, // Name
  545. 0, // Reserved
  546. REG_SZ, // Type
  547. (BYTE *)wcsPH, // Value
  548. (1 + wcslen(wcsPH)) * sizeof(WCHAR) );
  549. if ( ERROR_SUCCESS != dwError )
  550. {
  551. printf( "Error %u creating persistent handler key HKCR\\%ws\n", dwError, wcsTemp );
  552. break;
  553. }
  554. } while( FALSE );
  555. return dwError;
  556. }