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.

527 lines
16 KiB

  1. // cfgdump.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #include "sapi.h"
  5. #include "..\..\..\common\include\assertwithstack.h"
  6. #include "..\..\..\common\include\assertwithstack.cpp"
  7. #define _SYMBOL(x) (Header.pszSymbols + (x))
  8. CComModule _Module;
  9. const WCHAR * Word(ULONG x, const SPCFGHEADER & Header)
  10. {
  11. const WCHAR * psz = Header.pszWords;
  12. if (x > Header.cchWords)
  13. {
  14. return(L"ERROR");
  15. }
  16. while (x)
  17. {
  18. for (; *psz; psz++) {}
  19. x--;
  20. psz++;
  21. }
  22. return psz;
  23. }
  24. void _PrintRuleName(const SPCFGHEADER & Header, ULONG ulIndex)
  25. {
  26. for (ULONG i = 0; i < Header.cRules; i++)
  27. {
  28. if (Header.pRules[i].FirstArcIndex == ulIndex)
  29. {
  30. wprintf(L"<%s>", _SYMBOL(Header.pRules[i].NameSymbolOffset));
  31. return;
  32. }
  33. }
  34. wprintf(L"<0x%.8x>", ulIndex);
  35. }
  36. void _RecurseDump(const SPCFGHEADER & Header, ULONG NodeIndex, BYTE * pFlags, long * pPathIndexList, ULONG ulPathLen)
  37. {
  38. if (NodeIndex == 0)
  39. {
  40. return;
  41. }
  42. SPCFGARC * pArc = Header.pArcs + NodeIndex;
  43. while (TRUE)
  44. {
  45. if ((pFlags[NodeIndex] & 0x40)== 0) // Don't allow 2 recursions
  46. {
  47. if (pFlags[NodeIndex] & 0x80)
  48. {
  49. pFlags[NodeIndex] |= 0x40;
  50. pPathIndexList[ulPathLen] = -((long)NodeIndex);
  51. }
  52. else
  53. {
  54. pFlags[NodeIndex] |= 0x80;
  55. pPathIndexList[ulPathLen] = NodeIndex;
  56. }
  57. if (pArc->NextStartArcIndex == 0) // Terminal -- Print the stuff out!
  58. {
  59. for (ULONG i = 0; i <= ulPathLen; i++)
  60. {
  61. ULONG ulIndex;
  62. if (pPathIndexList[i] < 0)
  63. {
  64. ulIndex = -pPathIndexList[i];
  65. }
  66. else
  67. {
  68. ulIndex = pPathIndexList[i];
  69. }
  70. SPCFGARC * pPrintNode = Header.pArcs + ulIndex;
  71. if (pPrintNode->fRuleRef)
  72. {
  73. SPCFGRULE * pRule = Header.pRules + pPrintNode->TransitionIndex;
  74. if (pRule->NameSymbolOffset)
  75. {
  76. wprintf(L"(%s) ", _SYMBOL(pRule->NameSymbolOffset));
  77. }
  78. else
  79. {
  80. wprintf(L"(ID=%d) ", pRule->RuleId);
  81. }
  82. }
  83. else
  84. {
  85. if (pPrintNode->TransitionIndex)
  86. {
  87. if (pPrintNode->TransitionIndex == SPTEXTBUFFERTRANSITION)
  88. {
  89. wprintf(L"[TEXTBUFFER] ");
  90. }
  91. else if (pPrintNode->TransitionIndex == SPWILDCARDTRANSITION)
  92. {
  93. wprintf(L"... ");
  94. }
  95. else if (pPrintNode->TransitionIndex == SPDICTATIONTRANSITION)
  96. {
  97. wprintf(L"* ");
  98. }
  99. else
  100. {
  101. const WCHAR *pszWord = Word(pPrintNode->TransitionIndex, Header);
  102. wprintf(L"%s%c ", pszWord, (pszWord && (*pszWord == L'/')) ? L';' : L'');
  103. }
  104. }
  105. }
  106. }
  107. //
  108. // Now the semantic info...
  109. //
  110. BOOL bHaveSemanticInfo = FALSE;
  111. wprintf(L"-- ");
  112. for (i = 0; i <= ulPathLen; i++)
  113. {
  114. ULONG ulVal;
  115. if (pPathIndexList[i] < 0)
  116. {
  117. ulVal = -pPathIndexList[i];
  118. }
  119. else
  120. {
  121. ulVal = pPathIndexList[i];
  122. }
  123. if (Header.pArcs[ulVal].fHasSemanticTag)
  124. {
  125. long lFirst = 0;
  126. long lLast = ((long)Header.cSemanticTags) - 1;
  127. while (lFirst <= lLast)
  128. {
  129. long lTest = (lFirst + lLast) / 2;
  130. SPCFGSEMANTICTAG * pTag = Header.pSemanticTags + lTest;
  131. ULONG ulTestVal = pTag->ArcIndex;
  132. if (ulTestVal == ulVal)
  133. {
  134. CComVariant cvVar;
  135. HRESULT hr = AssignSemanticValue(pTag, &cvVar);
  136. if (SUCCEEDED(hr))
  137. {
  138. hr = cvVar.ChangeType(VT_BSTR);
  139. }
  140. wprintf(L"%s=\"%s\" (%s)", _SYMBOL(pTag->PropNameSymbolOffset), _SYMBOL(pTag->PropValueSymbolOffset),
  141. cvVar.bstrVal);
  142. bHaveSemanticInfo = TRUE;
  143. break;
  144. }
  145. if (ulTestVal < ulVal)
  146. {
  147. lFirst = lTest + 1;
  148. }
  149. else
  150. {
  151. lLast = lTest - 1;
  152. }
  153. }
  154. _ASSERT(lFirst <= lLast);
  155. }
  156. }
  157. if (!bHaveSemanticInfo)
  158. {
  159. wprintf(L"(none)\n");
  160. }
  161. else
  162. {
  163. wprintf(L"\n");
  164. }
  165. }
  166. else
  167. {
  168. _RecurseDump(Header, pArc->NextStartArcIndex, pFlags, pPathIndexList, ulPathLen+1);
  169. }
  170. if (pFlags[NodeIndex] & 0x40)
  171. {
  172. pFlags[NodeIndex] &= ~(0x40);
  173. }
  174. else
  175. {
  176. pFlags[NodeIndex] &= ~(0x80);
  177. }
  178. }
  179. if (pArc->fLastArc)
  180. {
  181. break;
  182. }
  183. pArc++;
  184. NodeIndex++;
  185. }
  186. }
  187. void DumpContents(const SPCFGSERIALIZEDHEADER * pFileData)
  188. {
  189. CComPtr<ISpGramCompBackend> cpBackend;
  190. cpBackend.CoCreateInstance(CLSID_SpGramCompBackend);
  191. cpBackend->InitFromBinaryGrammar(pFileData);
  192. ULONG i;
  193. SPCFGHEADER Header;
  194. SpConvertCFGHeader(pFileData, &Header);
  195. SPCFGSERIALIZEDHEADER *pFH = (SPCFGSERIALIZEDHEADER *)pFileData;
  196. //
  197. // Raw dump here...
  198. //
  199. WCHAR guidstr[MAX_PATH];
  200. wprintf(L"HEADER:\n");
  201. ::StringFromGUID2(Header.FormatId, guidstr, MAX_PATH);
  202. wprintf(L"ForamtId = %s\n", guidstr);
  203. ::StringFromGUID2(Header.GrammarGUID, guidstr, MAX_PATH);
  204. wprintf(L"GrammarGUID = %s\n", guidstr);
  205. wprintf(L"LangID = %d\n", Header.LangID);
  206. wprintf(L"Largest State = %d\n", Header.cArcsInLargestState);
  207. wprintf(L"cchWords = %d\n",Header.cchWords);
  208. wprintf(L"cchSymbols = %d\n", Header.cchSymbols);
  209. wprintf(L"cRules = %d\n", Header.cRules);
  210. wprintf(L"cArcs = %d\n", Header.cArcs );
  211. wprintf(L"cSemanticTags = %d\n", Header.cSemanticTags);
  212. wprintf(L"cResources = %d\n", Header.cResources);
  213. wprintf(L"Words = 0x%.8x\n", pFH->pszWords);
  214. wprintf(L"Symbols = 0x%.8x\n", pFH->pszSymbols);
  215. wprintf(L"Rules = 0x%.8x\n", pFH->pRules);
  216. wprintf(L"Arcs = 0x%.8x\n", pFH->pArcs);
  217. wprintf(L"SemanticTags = 0x%.8x\n", pFH->pSemanticTags);
  218. wprintf(L"Resources = 0x%.8x\n", pFH->pResources);
  219. if (Header.cchWords < 1)
  220. {
  221. wprintf(L"\n\tERROR: Grammar contains no words!\n");
  222. }
  223. wprintf(L"\nWORDS:\n");
  224. i = 1;
  225. while (i < Header.cchWords)
  226. {
  227. wprintf(L"0x%.8x -->%s<--\n", i, Header.pszWords + i);
  228. i = i + wcslen(Header.pszWords + i) + 1;
  229. }
  230. wprintf(L"\nSYMBOLS:\n");
  231. i = 1;
  232. while (i < Header.cchSymbols)
  233. {
  234. wprintf(L"0x%.8x - %s\n", i, Header.pszSymbols + i);
  235. i = i + wcslen(Header.pszSymbols + i) + 1;
  236. }
  237. wprintf(L"\nSEMANTIC TAGS:\n");
  238. SPCFGSEMANTICTAG *pTag = Header.pSemanticTags;
  239. for(i=0;i < Header.cSemanticTags; i++)
  240. {
  241. CComVariant cvVar;
  242. HRESULT hr = AssignSemanticValue(pTag, &cvVar);
  243. if (SUCCEEDED(hr))
  244. {
  245. hr = cvVar.ChangeType(VT_BSTR);
  246. }
  247. wprintf(L"0x%.8x - [0x%.8x (%1d) - 0x%.8x (%1d)] Name (%d): %s Value (%d): \"%s\" %s\n",
  248. pTag->ArcIndex, pTag->StartArcIndex, pTag->fStartParallelEpsilonArc, pTag->EndArcIndex, pTag->fEndParallelEpsilonArc,
  249. pTag->PropId,(pTag->PropNameSymbolOffset) ? &Header.pszSymbols[pTag->PropNameSymbolOffset] : L" N/A ",
  250. pTag->PropValueSymbolOffset, (pTag->PropValueSymbolOffset) ? &Header.pszSymbols[pTag->PropValueSymbolOffset] : L"",
  251. cvVar.bstrVal);
  252. pTag++;
  253. }
  254. BYTE * aFlags = new BYTE[Header.cArcs];
  255. if (aFlags == NULL)
  256. {
  257. wprintf(L"Internal tool error -- Out of memory");
  258. return;
  259. }
  260. memset(aFlags, 0, Header.cArcs);
  261. wprintf(L"\nRULE-INDEX ID TOP ACT PROP IMP EXP RES DYN FIRST-ARC NAME-INDEX NAME\n");
  262. SPCFGRULE * pRule = Header.pRules;
  263. for (i = 0; i < Header.cRules; i++, pRule++)
  264. {
  265. wprintf(L"0x%.8x 0x%.8x %1.d %1.d %1.d %1.d %1.d %1.d %1.d 0x%.8x 0x%.8x \"%s\"\n",
  266. i, pRule->RuleId, pRule->fTopLevel, pRule->fDefaultActive, pRule->fPropRule, pRule->fImport, pRule->fExport, pRule->fHasResources, pRule->fDynamic,
  267. pRule->FirstArcIndex, pRule->NameSymbolOffset, _SYMBOL(pRule->NameSymbolOffset));
  268. aFlags[pRule->FirstArcIndex] = 1;
  269. }
  270. SPCFGARC * pArc = Header.pArcs;
  271. for (i = 0; i < Header.cArcs; i++, pArc++)
  272. {
  273. if (pArc->fRuleRef)
  274. {
  275. aFlags[pArc->TransitionIndex] |= 2;
  276. }
  277. }
  278. wprintf(L"\nNON-TOP-LEVEL RULES\n");
  279. for (i = 1; i < Header.cArcs; i++)
  280. {
  281. if (aFlags[i] == 2)
  282. {
  283. wprintf(L"0x%.8x\n", i);
  284. }
  285. }
  286. wprintf(L"\nARC-INDEX WEIGHT RULE LAST SEM-TAG TRANS-IDX NEXT-ARC CONF TRANSITION NAME\n");
  287. pArc = Header.pArcs;
  288. for (i = 0; i < Header.cArcs; i++, pArc++)
  289. {
  290. wprintf(L"0x%.8x %4.4f %1.d %1.d %1.d 0x%.8x 0x%.8x %2s ",
  291. i, (Header.pWeights) ? Header.pWeights[i] : 1.0f, pArc->fRuleRef, pArc->fLastArc, pArc->fHasSemanticTag, pArc->TransitionIndex,
  292. pArc->NextStartArcIndex, pArc->fLowConfRequired ? L"-1" : pArc->fHighConfRequired ? L"+1" : L" ");
  293. if (pArc->TransitionIndex == SPTEXTBUFFERTRANSITION)
  294. {
  295. wprintf(L"[TEXTBUFFER]\n");
  296. }
  297. else if (pArc->TransitionIndex == SPWILDCARDTRANSITION)
  298. {
  299. wprintf(L"[WILDCARD]\n");
  300. }
  301. else if (pArc->TransitionIndex == SPDICTATIONTRANSITION)
  302. {
  303. wprintf(L"[DICTATION]\n");
  304. }
  305. else if (pArc->fRuleRef)
  306. {
  307. SPCFGRULE * pRule = Header.pRules + pArc->TransitionIndex;
  308. if (pRule->fImport)
  309. {
  310. wprintf(L"(%s)\n", _SYMBOL(pRule->NameSymbolOffset));
  311. }
  312. else
  313. {
  314. if (pRule->NameSymbolOffset)
  315. {
  316. wprintf(L"<%s>\n", _SYMBOL(pRule->NameSymbolOffset));
  317. }
  318. else
  319. {
  320. wprintf(L"<0x%.8x>\n", pArc->TransitionIndex);
  321. }
  322. }
  323. }
  324. else
  325. {
  326. wprintf(L"%s\n", Word(pArc->TransitionIndex, Header));
  327. }
  328. }
  329. //
  330. // Resources
  331. //
  332. if (Header.cResources)
  333. {
  334. wprintf(L"\nRES-INDEX RULE-INDEX NAME = VAL\n");
  335. SPCFGRESOURCE * pRes = Header.pResources;
  336. for (i = 0; i < Header.cResources; i++, pRes++)
  337. {
  338. wprintf(L"0x%.8x 0x%.8x %s = %s\n", i, pRes->RuleIndex,
  339. _SYMBOL(pRes->ResourceNameSymbolOffset),
  340. _SYMBOL(pRes->ResourceValueSymbolOffset));
  341. }
  342. }
  343. else
  344. {
  345. wprintf(L"\nNO RESOURCES IN THIS GRAMMAR\n");
  346. }
  347. //
  348. // Now a formatted dump
  349. //
  350. pRule = Header.pRules;
  351. for (i = 0; i < Header.cRules; i++, pRule++)
  352. {
  353. if (!pRule->fImport)
  354. {
  355. if (pRule->NameSymbolOffset)
  356. {
  357. wprintf(L"\nRule %d - %s\n", i, _SYMBOL(pRule->NameSymbolOffset));
  358. }
  359. else
  360. {
  361. wprintf(L"\nRule %d - <NO NAME> (ID=%d)\n", i, pRule->RuleId);
  362. }
  363. }
  364. else
  365. {
  366. wprintf(L"\nRule <0x%.8x> %s\n", pRule->FirstArcIndex);
  367. }
  368. long Path[100];
  369. _RecurseDump(Header, pRule->FirstArcIndex, aFlags, Path, 0);
  370. }
  371. delete[] aFlags;
  372. }
  373. //
  374. // Compile an XML file, and dump it.
  375. //
  376. void LoadCompileDumpXML(char * pszFilename)
  377. {
  378. HRESULT hr = S_OK;
  379. CComPtr<ISpStream> cpSrcStream;
  380. CComPtr<IStream> cpDestMemStream;
  381. CComPtr<ISpGrammarCompiler> cpCompiler;
  382. hr = SPBindToFile(pszFilename, SPFM_OPEN_READONLY, &cpSrcStream);
  383. if( FAILED(hr) )
  384. {
  385. wprintf(L"\n\tERROR: could not open parse %S\n", pszFilename );
  386. wprintf(L"\tERROR: try using the complete name. i.e. C:\\blah\\%S\n\n", pszFilename );
  387. return;
  388. }
  389. if (SUCCEEDED(hr))
  390. {
  391. hr = ::CreateStreamOnHGlobal(NULL, TRUE, &cpDestMemStream);
  392. }
  393. if (SUCCEEDED(hr))
  394. {
  395. hr = cpCompiler.CoCreateInstance(CLSID_SpGrammarCompiler);
  396. }
  397. if (SUCCEEDED(hr))
  398. {
  399. hr = cpCompiler->CompileStream(cpSrcStream, cpDestMemStream, NULL, NULL, NULL, 0);
  400. if(FAILED(hr))
  401. {
  402. wprintf(L"\n\tERROR: Compile of %S failed.\n", pszFilename );
  403. return;
  404. }
  405. }
  406. if (SUCCEEDED(hr))
  407. {
  408. HGLOBAL hGlobal;
  409. hr = ::GetHGlobalFromStream(cpDestMemStream, &hGlobal);
  410. if (SUCCEEDED(hr))
  411. {
  412. SPCFGSERIALIZEDHEADER * pBinaryData = (SPCFGSERIALIZEDHEADER * )GlobalLock(hGlobal);
  413. DumpContents((SPCFGSERIALIZEDHEADER *)pBinaryData);
  414. GlobalUnlock(hGlobal);
  415. }
  416. }
  417. if(FAILED(hr))
  418. {
  419. wprintf(L"\n\tERROR: Could not dump %S.\n", pszFilename );
  420. return;
  421. }
  422. }
  423. //
  424. // Load a CFG file and dump it.
  425. //
  426. void LoadDumpCFG(char * pszFilename)
  427. {
  428. HANDLE hFile = ::CreateFile(pszFilename, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
  429. if (hFile != INVALID_HANDLE_VALUE)
  430. {
  431. HANDLE hMapFile;
  432. hMapFile = ::CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  433. if (hMapFile)
  434. {
  435. LPVOID lpMapAddress;
  436. lpMapAddress = ::MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 0);
  437. if (lpMapAddress)
  438. {
  439. DumpContents((SPCFGSERIALIZEDHEADER *)lpMapAddress);
  440. ::UnmapViewOfFile(lpMapAddress);
  441. }
  442. ::CloseHandle(hMapFile);
  443. }
  444. ::CloseHandle(hFile);
  445. }
  446. else
  447. {
  448. wprintf(L"\n\tERROR: could not open %S\n\n", pszFilename );
  449. }
  450. }
  451. int main(int argc, char* argv[])
  452. {
  453. USES_CONVERSION;
  454. ::CoInitialize(NULL);
  455. if (argc != 2)
  456. {
  457. wprintf(L"\n\tusage: %s <binary cfg file>\n\n", T2W(argv[0]));
  458. return 0;
  459. }
  460. //
  461. // Determine the file extension, or add .cfg
  462. //
  463. char * pszFilename = (char*)calloc( strlen(argv[1]) + 5,sizeof(char));
  464. strcat( pszFilename, argv[1] );
  465. if (stricmp(&pszFilename[strlen(pszFilename)-4],".xml") != 0 )
  466. {
  467. if (strcmp(&pszFilename[strlen(pszFilename)-4],".cfg"))
  468. {
  469. strcat(pszFilename,".cfg");
  470. }
  471. }
  472. //
  473. // Try and parse the file.
  474. //
  475. if (stricmp(&pszFilename[strlen(pszFilename)-4],".xml")==0)
  476. {
  477. LoadCompileDumpXML(pszFilename);
  478. }
  479. else
  480. {
  481. LoadDumpCFG(pszFilename);
  482. }
  483. return 0;
  484. }