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.

640 lines
23 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997 - 2000.
  5. //
  6. // File: filtdump.cxx
  7. //
  8. // Contents: IFilter dump utility
  9. //
  10. // History: 30-Dec-97 KyleP Added header
  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. #include <filterr.h>
  22. #include <filter.h>
  23. #include <ntquery.h>
  24. #include <vquery.hxx>
  25. BOOL fContentOnly = FALSE;
  26. BOOL fOutputFile = FALSE;
  27. void * pProtectedStart;
  28. WCHAR * pwszProtectedBuf;
  29. unsigned ccProtectedBuf = 100;
  30. void Usage();
  31. int _cdecl main( int argc, char * argv[] )
  32. {
  33. if ( argc < 2 )
  34. {
  35. Usage();
  36. exit( 0 );
  37. }
  38. WCHAR wszBuffer[4096];
  39. WCHAR wszBuffer2[4096];
  40. char szBuffer[4096];
  41. char szOutputFile[MAX_PATH];
  42. ULONG cbWritten;
  43. char szDefault[] = "?";
  44. HRESULT hr = CoInitializeEx( 0, COINIT_MULTITHREADED );
  45. if ( FAILED( hr ) )
  46. return 1;
  47. HANDLE hFile = GetStdHandle( STD_OUTPUT_HANDLE );
  48. int iFile = 1;
  49. for ( int i = 1; i < argc; i++ )
  50. {
  51. if ( argv[i][0] == '-' )
  52. {
  53. switch ( argv[i][1] )
  54. {
  55. case 'b':
  56. case 'B':
  57. iFile = i+1;
  58. fContentOnly = 1;
  59. break;
  60. case 'o':
  61. case 'O':
  62. fOutputFile = 1;
  63. if ( strlen( argv[i+1] ) >= sizeof szOutputFile )
  64. {
  65. Usage();
  66. return 1;
  67. }
  68. strcpy(szOutputFile, argv[i+1]);
  69. iFile = i+2;
  70. break;
  71. case 's':
  72. case 'S':
  73. iFile = i+2;
  74. i++;
  75. ccProtectedBuf = atoi( argv[i] );
  76. break;
  77. default:
  78. Usage();
  79. return 0;
  80. }
  81. }
  82. }
  83. if ( fOutputFile )
  84. {
  85. hFile = CreateFileA( szOutputFile, // pointer to name of the file
  86. GENERIC_WRITE, // access (read-write) mode
  87. FILE_SHARE_READ, // share mode
  88. 0, // pointer to security attributes
  89. CREATE_ALWAYS, // how to create
  90. 0, // file attributes
  91. 0 ); // template
  92. if ( INVALID_HANDLE_VALUE == hFile )
  93. {
  94. sprintf( szBuffer, "Error %d opening %s\n", GetLastError(), argv[iFile] );
  95. WriteFile( GetStdHandle( STD_OUTPUT_HANDLE ), szBuffer, strlen(szBuffer), &cbWritten, 0 );
  96. exit( 1 );
  97. }
  98. wszBuffer[0] = 0xFEFF;
  99. if (!fContentOnly)
  100. WriteFile( hFile, wszBuffer, sizeof(WCHAR), &cbWritten, 0 );
  101. }
  102. //
  103. // Allocate protected buffer
  104. //
  105. int cbProtectedBuf = ccProtectedBuf * sizeof(WCHAR);
  106. pProtectedStart = VirtualAlloc( 0, cbProtectedBuf + 4096 + 1, MEM_RESERVE, PAGE_READWRITE );
  107. VirtualAlloc( pProtectedStart, ((cbProtectedBuf + 4095) / 4096) * 4096, MEM_COMMIT, PAGE_READWRITE );
  108. pwszProtectedBuf = (WCHAR *) ((BYTE *)pProtectedStart + ((cbProtectedBuf + 4095) / 4096) * 4096 - cbProtectedBuf);
  109. for ( ; iFile < argc; iFile++ )
  110. {
  111. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  112. {
  113. sprintf( szBuffer, "FILE: %s\n", argv[iFile] );
  114. if (!fContentOnly)
  115. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  116. }
  117. else
  118. {
  119. mbstowcs( wszBuffer2, argv[iFile], sizeof(wszBuffer2)/sizeof(WCHAR) );
  120. swprintf( wszBuffer, L"FILE: %s\r\n", wszBuffer2 );
  121. if (!fContentOnly)
  122. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  123. }
  124. WCHAR wcsPath[MAX_PATH];
  125. mbstowcs( wcsPath, argv[iFile], sizeof(wcsPath)/sizeof(WCHAR) );
  126. IFilter * pFilt = 0;
  127. SCODE sc = LoadIFilter( wcsPath, 0, (void **)&pFilt );
  128. if ( FAILED(sc) )
  129. {
  130. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  131. {
  132. sprintf( szBuffer, "Error 0x%x loading IFilter\n", sc );
  133. if (!fContentOnly)
  134. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  135. }
  136. else
  137. {
  138. swprintf( wszBuffer, L"Error 0x%x loading IFilter\r\n", sc );
  139. if (!fContentOnly)
  140. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  141. }
  142. CIShutdown();
  143. exit( 1 );
  144. }
  145. //
  146. // Initialize filter.
  147. //
  148. ULONG Flags = 0;
  149. sc = pFilt->Init( IFILTER_INIT_CANON_PARAGRAPHS |
  150. IFILTER_INIT_HARD_LINE_BREAKS |
  151. IFILTER_INIT_CANON_HYPHENS |
  152. IFILTER_INIT_CANON_SPACES |
  153. IFILTER_INIT_INDEXING_ONLY |
  154. IFILTER_INIT_APPLY_INDEX_ATTRIBUTES,
  155. 0,
  156. NULL,
  157. &Flags );
  158. if( FAILED(sc) )
  159. {
  160. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  161. {
  162. sprintf( szBuffer, "Error 0x%x from IFilter::Init.\n", sc );
  163. if (!fContentOnly)
  164. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  165. }
  166. else
  167. {
  168. swprintf( wszBuffer, L"Error 0x%x from IFilter::Init.\r\n", sc );
  169. if (!fContentOnly)
  170. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  171. }
  172. pFilt->Release();
  173. CIShutdown();
  174. exit( 1 );
  175. }
  176. if ( !fContentOnly && (Flags & IFILTER_FLAGS_OLE_PROPERTIES) )
  177. {
  178. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  179. {
  180. sprintf( szBuffer, "**Additional Properties available via IPropertyStorage.\n\n", sc );
  181. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  182. }
  183. else
  184. {
  185. swprintf( wszBuffer, L"**Additional Properties available via IPropertyStorage.\r\n\r\n", sc );
  186. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  187. }
  188. }
  189. //
  190. // Loop through the chunks.
  191. //
  192. BOOL fText;
  193. STAT_CHUNK StatChunk;
  194. StatChunk.attribute.psProperty.ulKind = PRSPEC_PROPID;
  195. while (1)
  196. {
  197. WCHAR wcsBuffer[2048];
  198. sc = pFilt->GetChunk( &StatChunk );
  199. if ( FILTER_E_EMBEDDING_UNAVAILABLE == sc || FILTER_E_LINK_UNAVAILABLE == sc )
  200. {
  201. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  202. {
  203. sprintf( szBuffer, "Encountered an embed/link for which filter is not available.\n" );
  204. if (!fContentOnly)
  205. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  206. }
  207. else
  208. {
  209. swprintf( wszBuffer, L"Encountered an embed/link for which filter is not available.\r\n" );
  210. if (!fContentOnly)
  211. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  212. }
  213. continue; //continue with other chunks.
  214. }
  215. if ( FAILED(sc) && sc != FILTER_E_END_OF_CHUNKS )
  216. {
  217. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  218. {
  219. sprintf( szBuffer, "IFilter::GetChunk returned 0x%x\n", sc );
  220. if (!fContentOnly)
  221. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  222. }
  223. else
  224. {
  225. swprintf( wszBuffer, L"IFilter::GetChunk returned 0x%x\r\n", sc );
  226. if (!fContentOnly)
  227. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  228. }
  229. break;
  230. }
  231. if ( sc == FILTER_E_END_OF_CHUNKS )
  232. break;
  233. if ( CHUNK_TEXT == StatChunk.flags )
  234. fText = TRUE;
  235. if ( CHUNK_VALUE == StatChunk.flags )
  236. fText = FALSE;
  237. //
  238. // Put in the struct of chunk into the file if requested
  239. //
  240. int cc = 0;
  241. cc += swprintf( wszBuffer + cc, L"\r\n----------------------------------------------------------------------\r\n" );
  242. cc += swprintf( wszBuffer + cc, L"\t\tAttribute = %08lX-%04X-%04X-%02X%02X%02X%02X%02X%02X%02X%02X\\",
  243. StatChunk.attribute.guidPropSet.Data1,
  244. StatChunk.attribute.guidPropSet.Data2,
  245. StatChunk.attribute.guidPropSet.Data3,
  246. StatChunk.attribute.guidPropSet.Data4[0], StatChunk.attribute.guidPropSet.Data4[1],
  247. StatChunk.attribute.guidPropSet.Data4[2], StatChunk.attribute.guidPropSet.Data4[3],
  248. StatChunk.attribute.guidPropSet.Data4[4], StatChunk.attribute.guidPropSet.Data4[5],
  249. StatChunk.attribute.guidPropSet.Data4[6], StatChunk.attribute.guidPropSet.Data4[7] );
  250. if ( StatChunk.attribute.psProperty.ulKind == PRSPEC_PROPID )
  251. cc += swprintf( wszBuffer + cc, L"%d\r\n", StatChunk.attribute.psProperty.propid );
  252. else
  253. cc += swprintf( wszBuffer + cc, L"%ws\r\n", StatChunk.attribute.psProperty.lpwstr );
  254. cc += swprintf( wszBuffer + cc, L"\t\tidChunk = %d\r\n", StatChunk.idChunk );
  255. cc += swprintf( wszBuffer + cc, L"\t\tBreakType = %d", StatChunk.breakType );
  256. switch ( StatChunk.breakType )
  257. {
  258. case CHUNK_NO_BREAK:
  259. cc += swprintf( wszBuffer + cc, L" (No Break)\r\n" );
  260. break;
  261. case CHUNK_EOW:
  262. cc += swprintf( wszBuffer + cc, L" (Word)\r\n" );
  263. break;
  264. case CHUNK_EOS:
  265. cc += swprintf( wszBuffer + cc, L" (Sentence)\r\n" );
  266. break;
  267. case CHUNK_EOP:
  268. cc += swprintf( wszBuffer + cc, L" (Paragraph)\r\n" );
  269. break;
  270. case CHUNK_EOC:
  271. cc += swprintf( wszBuffer + cc, L" (Chapter)\r\n" );
  272. break;
  273. }
  274. cc += swprintf( wszBuffer + cc, L"\t\tFlags(chunkstate) = 0x%x", StatChunk.flags );
  275. if ( CHUNK_TEXT & StatChunk.flags )
  276. cc += swprintf( wszBuffer + cc, L" (Text) " );
  277. if ( CHUNK_VALUE & StatChunk.flags )
  278. cc += swprintf( wszBuffer + cc, L" (Value) " );
  279. cc += swprintf( wszBuffer + cc, L"\r\n" );
  280. cc += swprintf( wszBuffer + cc, L"\t\tLocale = %d (0x%x)\r\n", StatChunk.locale, StatChunk.locale );
  281. cc += swprintf( wszBuffer + cc, L"\t\tIdChunkSource = %d\r\n", StatChunk.idChunkSource );
  282. cc += swprintf( wszBuffer + cc, L"\t\tcwcStartSource = %d\r\n", StatChunk.cwcStartSource );
  283. cc += swprintf( wszBuffer + cc, L"\t\tcwcLenSource = %d\r\n", StatChunk.cwcLenSource );
  284. cc += swprintf( wszBuffer + cc, L"----------------------------------------------------------------------\r\n" );
  285. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  286. {
  287. int cc2 = WideCharToMultiByte( CP_ACP,
  288. WC_COMPOSITECHECK | WC_DEFAULTCHAR,
  289. wszBuffer,
  290. cc,
  291. szBuffer,
  292. sizeof(szBuffer),
  293. szDefault,
  294. 0 );
  295. if (!fContentOnly)
  296. WriteFile( hFile, szBuffer, cc2, &cbWritten, 0 );
  297. }
  298. else
  299. {
  300. if (!fContentOnly)
  301. WriteFile( hFile, wszBuffer, cc*sizeof(WCHAR), &cbWritten, 0 );
  302. }
  303. PROPVARIANT * pPropValue;
  304. while ( TRUE )
  305. {
  306. if( fText )
  307. {
  308. ULONG ccBuffer = ccProtectedBuf;
  309. sc = pFilt->GetText( &ccBuffer, pwszProtectedBuf );
  310. //printf ("sc: %#x, ccBuffer: %d, buffer %#x\n", sc, ccBuffer, pwszProtectedBuf );
  311. //DebugBreak();
  312. if ( FAILED(sc) && (sc != FILTER_E_NO_MORE_TEXT) )
  313. {
  314. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  315. {
  316. sprintf( szBuffer, "Error 0x%x from IFilter::GetText.\n", sc );
  317. if (!fContentOnly)
  318. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  319. }
  320. else
  321. {
  322. swprintf( wszBuffer, L"Error 0x%x from IFilter::GetText.\r\n", sc );
  323. if (!fContentOnly)
  324. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  325. }
  326. break;
  327. }
  328. if ( sc == FILTER_E_NO_MORE_TEXT )
  329. break; //go, fetch another chunk
  330. //
  331. // write the buffer to file
  332. //
  333. #if 0
  334. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  335. {
  336. sprintf( szBuffer, "\n------\nGetText returned %d characters\n------\n", ccBuffer );
  337. if (!fContentOnly)
  338. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  339. }
  340. else
  341. {
  342. swprintf( wszBuffer, L"\n------\nGetText returned %d characters\n------\n", ccBuffer );
  343. if (!fContentOnly)
  344. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  345. }
  346. #endif
  347. if ( 0 == ccBuffer )
  348. {
  349. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  350. {
  351. sprintf( szBuffer, "<empty ::GetText>\r\n", ccBuffer );
  352. if (!fContentOnly)
  353. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  354. }
  355. else
  356. {
  357. swprintf( wszBuffer, L"<empty ::GetText>\r\n", ccBuffer );
  358. if (!fContentOnly)
  359. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  360. }
  361. }
  362. wcsBuffer[ccBuffer] = 0;
  363. //
  364. // Convert to MBCS
  365. //
  366. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  367. {
  368. //printf( "copy to %#x, from %#x, cc %d\n", wcsBuffer, pwszProtectedBuf, ccBuffer );
  369. //DebugBreak();
  370. for ( unsigned i = 0; i < ccBuffer; i++ )
  371. {
  372. if ( 0xd == pwszProtectedBuf[i] ||
  373. 0xb == pwszProtectedBuf[i] )
  374. WriteFile( hFile, "\r\n", 2, &cbWritten, 0 );
  375. else
  376. WriteFile( hFile, &pwszProtectedBuf[i], sizeof BYTE, &cbWritten, 0 );
  377. }
  378. // RtlCopyMemory( wcsBuffer, pwszProtectedBuf, ccBuffer * sizeof WCHAR );
  379. // printf( "%ws", wcsBuffer );
  380. }
  381. else
  382. {
  383. WriteFile( hFile, pwszProtectedBuf, ccBuffer * sizeof(WCHAR), &cbWritten, 0 );
  384. }
  385. }
  386. if( !fText )
  387. {
  388. sc = pFilt->GetValue( &pPropValue );
  389. if ( FAILED(sc) && (sc != FILTER_E_NO_MORE_VALUES) )
  390. {
  391. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  392. {
  393. sprintf( szBuffer, "IFilter::GetValue returned 0x%x\n", sc );
  394. if (!fContentOnly)
  395. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  396. }
  397. else
  398. {
  399. swprintf( wszBuffer, L"IFilter::GetValue returned 0x%x\r\n", sc );
  400. if (!fContentOnly)
  401. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  402. }
  403. break;
  404. }
  405. if ( sc == FILTER_E_NO_MORE_VALUES )
  406. break; //go, fetch another chunk
  407. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  408. {
  409. sprintf( szBuffer, "Type = %d (0x%x): ", pPropValue->vt, pPropValue->vt );
  410. if (!fContentOnly)
  411. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  412. }
  413. else
  414. {
  415. swprintf( wszBuffer, L"Type = %d (0x%x): ", pPropValue->vt, pPropValue->vt );
  416. if (!fContentOnly)
  417. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  418. }
  419. switch( pPropValue->vt )
  420. {
  421. case VT_LPWSTR:
  422. case VT_BSTR:
  423. {
  424. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  425. {
  426. int cc = WideCharToMultiByte( CP_ACP,
  427. WC_COMPOSITECHECK | WC_DEFAULTCHAR,
  428. pPropValue->pwszVal,
  429. wcslen( pPropValue->pwszVal ),
  430. szBuffer,
  431. sizeof(szBuffer),
  432. szDefault,
  433. 0 );
  434. WriteFile( hFile, szBuffer, cc, &cbWritten, 0 );
  435. }
  436. else
  437. {
  438. WriteFile( hFile, pPropValue->pwszVal, wcslen(pPropValue->pwszVal) * sizeof(WCHAR), &cbWritten, 0 );
  439. }
  440. break;
  441. }
  442. case VT_LPSTR:
  443. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  444. {
  445. WriteFile( hFile, pPropValue->pszVal, strlen(pPropValue->pszVal), &cbWritten, 0 );
  446. }
  447. else
  448. {
  449. wszBuffer[0] = 0;
  450. MultiByteToWideChar( CP_ACP,
  451. 0,
  452. pPropValue->pszVal,
  453. -1,
  454. wszBuffer,
  455. sizeof wszBuffer / sizeof wszBuffer[0] );
  456. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  457. }
  458. break;
  459. default:
  460. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  461. {
  462. sprintf( szBuffer, "Unprintable type" );
  463. if (!fContentOnly)
  464. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  465. }
  466. else
  467. {
  468. swprintf( wszBuffer, L"Unprintable type" );
  469. if (!fContentOnly)
  470. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  471. }
  472. break;
  473. }
  474. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  475. {
  476. sprintf( szBuffer, "\n" );
  477. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  478. }
  479. else
  480. {
  481. swprintf( wszBuffer, L"\r\n" );
  482. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  483. }
  484. if( pPropValue )
  485. {
  486. PropVariantClear( pPropValue );
  487. CoTaskMemFree( pPropValue );
  488. pPropValue = 0;
  489. }
  490. }
  491. }//while
  492. }//while
  493. pFilt->Release();
  494. if ( hFile == GetStdHandle( STD_OUTPUT_HANDLE ) )
  495. {
  496. sprintf( szBuffer, "\n\n" );
  497. WriteFile( hFile, szBuffer, strlen(szBuffer), &cbWritten, 0 );
  498. }
  499. else
  500. {
  501. swprintf( wszBuffer, L"\r\n\r\n" );
  502. WriteFile( hFile, wszBuffer, wcslen(wszBuffer)*sizeof(WCHAR), &cbWritten, 0 );
  503. }
  504. }
  505. CIShutdown();
  506. CoUninitialize();
  507. if ( hFile != GetStdHandle( STD_OUTPUT_HANDLE ) )
  508. {
  509. CloseHandle( hFile );
  510. }
  511. return 0;
  512. }
  513. void Usage()
  514. {
  515. printf( "Usage: FiltDump [-b] [-o Unicode output file] [-s buffer size] <file> <file> <file> ...\n" );
  516. printf( "Use -b to print only the contents of the file without additional commentary.\n");
  517. printf( "Use -s to control text buffer size (guard page at end)\n" );
  518. }