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.

518 lines
16 KiB

  1. #include "nt.h"
  2. #include "ntdef.h"
  3. #include "ntrtl.h"
  4. #include "nturtl.h"
  5. #include "fci.h"
  6. #include "stdio.h"
  7. #include "sxs-rtl.h"
  8. #include "fasterxml.h"
  9. #include "skiplist.h"
  10. #include "namespacemanager.h"
  11. #include "xmlstructure.h"
  12. #ifdef INVALID_HANDLE_VALUE
  13. #undef INVALID_HANDLE_VALUE
  14. #endif
  15. #include "windows.h"
  16. #include "stdlib.h"
  17. NTSTATUS FASTCALL
  18. MyAllocator(SIZE_T cb, PVOID* pvOutput, PVOID pvAllocContext) {
  19. ASSERT(pvAllocContext == NULL);
  20. *pvOutput = RtlAllocateHeap(RtlProcessHeap(), 0, cb);
  21. return *pvOutput ? STATUS_SUCCESS : STATUS_NO_MEMORY;
  22. }
  23. NTSTATUS FASTCALL
  24. MyFreer(PVOID pv, PVOID pvAllocContext) {
  25. ASSERT(pvAllocContext == NULL);
  26. return RtlFreeHeap(RtlProcessHeap(), 0, pv) ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
  27. }
  28. EXTERN_C RTL_ALLOCATOR g_DefaultAllocator = {MyAllocator, MyFreer, NULL};
  29. void GetFormattedStateName(
  30. XML_TOKENIZATION_SPECIFIC_STATE State,
  31. CHAR *rgszBuffer,
  32. SIZE_T cchBuffer
  33. )
  34. {
  35. CHAR *pszSpecific = NULL;
  36. SIZE_T cchSpecific = 0;
  37. #define STRINGIFY(str, sz, cch) case str: sz = #str; cch = NUMBER_OF(#str) - 1; break
  38. switch(State) {
  39. STRINGIFY(XTSS_ERRONEOUS, pszSpecific, cchSpecific);
  40. STRINGIFY(XTSS_ELEMENT_OPEN, pszSpecific, cchSpecific);
  41. STRINGIFY(XTSS_ELEMENT_NAME, pszSpecific, cchSpecific);
  42. STRINGIFY(XTSS_ELEMENT_CLOSE, pszSpecific, cchSpecific);
  43. STRINGIFY(XTSS_ELEMENT_CLOSE_EMPTY, pszSpecific, cchSpecific);
  44. STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_NAME, pszSpecific, cchSpecific);
  45. STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_EQUALS, pszSpecific, cchSpecific);
  46. STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_OPEN, pszSpecific, cchSpecific);
  47. STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_CLOSE, pszSpecific, cchSpecific);
  48. STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_VALUE, pszSpecific, cchSpecific);
  49. STRINGIFY(XTSS_ELEMENT_WHITESPACE, pszSpecific, cchSpecific);
  50. STRINGIFY(XTSS_ELEMENT_XMLNS, pszSpecific, cchSpecific);
  51. STRINGIFY(XTSS_ELEMENT_XMLNS_DEFAULT, pszSpecific, cchSpecific);
  52. STRINGIFY(XTSS_ELEMENT_XMLNS_ALIAS, pszSpecific, cchSpecific);
  53. STRINGIFY(XTSS_ELEMENT_XMLNS_COLON, pszSpecific, cchSpecific);
  54. STRINGIFY(XTSS_ELEMENT_XMLNS_EQUALS, pszSpecific, cchSpecific);
  55. STRINGIFY(XTSS_ELEMENT_XMLNS_VALUE_OPEN, pszSpecific, cchSpecific);
  56. STRINGIFY(XTSS_ELEMENT_XMLNS_VALUE_CLOSE, pszSpecific, cchSpecific);
  57. STRINGIFY(XTSS_ELEMENT_XMLNS_VALUE, pszSpecific, cchSpecific);
  58. STRINGIFY(XTSS_ELEMENT_NAME_NS_PREFIX, pszSpecific, cchSpecific);
  59. STRINGIFY(XTSS_ELEMENT_NAME_NS_COLON, pszSpecific, cchSpecific);
  60. STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_NAME_NS_PREFIX, pszSpecific, cchSpecific);
  61. STRINGIFY(XTSS_ELEMENT_ATTRIBUTE_NAME_NS_COLON, pszSpecific, cchSpecific);
  62. STRINGIFY(XTSS_ENDELEMENT_OPEN, pszSpecific, cchSpecific);
  63. STRINGIFY(XTSS_ENDELEMENT_NAME, pszSpecific, cchSpecific);
  64. STRINGIFY(XTSS_ENDELEMENT_WHITESPACE, pszSpecific, cchSpecific);
  65. STRINGIFY(XTSS_ENDELEMENT_CLOSE, pszSpecific, cchSpecific);
  66. STRINGIFY(XTSS_XMLDECL_OPEN, pszSpecific, cchSpecific);
  67. STRINGIFY(XTSS_XMLDECL_CLOSE, pszSpecific, cchSpecific);
  68. STRINGIFY(XTSS_XMLDECL_WHITESPACE, pszSpecific, cchSpecific);
  69. STRINGIFY(XTSS_XMLDECL_VALUE, pszSpecific, cchSpecific);
  70. STRINGIFY(XTSS_XMLDECL_VALUE_OPEN, pszSpecific, cchSpecific);
  71. STRINGIFY(XTSS_XMLDECL_VALUE_CLOSE, pszSpecific, cchSpecific);
  72. STRINGIFY(XTSS_XMLDECL_EQUALS, pszSpecific, cchSpecific);
  73. STRINGIFY(XTSS_XMLDECL_ENCODING, pszSpecific, cchSpecific);
  74. STRINGIFY(XTSS_XMLDECL_STANDALONE, pszSpecific, cchSpecific);
  75. STRINGIFY(XTSS_XMLDECL_VERSION, pszSpecific, cchSpecific);
  76. STRINGIFY(XTSS_PI_OPEN, pszSpecific, cchSpecific);
  77. STRINGIFY(XTSS_PI_CLOSE, pszSpecific, cchSpecific);
  78. STRINGIFY(XTSS_PI_TARGET, pszSpecific, cchSpecific);
  79. STRINGIFY(XTSS_PI_VALUE, pszSpecific, cchSpecific);
  80. STRINGIFY(XTSS_PI_WHITESPACE, pszSpecific, cchSpecific);
  81. STRINGIFY(XTSS_CDATA_OPEN, pszSpecific, cchSpecific);
  82. STRINGIFY(XTSS_CDATA_CDATA, pszSpecific, cchSpecific);
  83. STRINGIFY(XTSS_CDATA_CLOSE, pszSpecific, cchSpecific);
  84. STRINGIFY(XTSS_COMMENT_OPEN, pszSpecific, cchSpecific);
  85. STRINGIFY(XTSS_COMMENT_COMMENTARY, pszSpecific, cchSpecific);
  86. STRINGIFY(XTSS_COMMENT_CLOSE, pszSpecific, cchSpecific);
  87. STRINGIFY(XTSS_STREAM_START, pszSpecific, cchSpecific);
  88. STRINGIFY(XTSS_STREAM_END, pszSpecific, cchSpecific);
  89. STRINGIFY(XTSS_STREAM_HYPERSPACE, pszSpecific, cchSpecific);
  90. default:
  91. pszSpecific = "bad specific state"; cchSpecific = strlen(pszSpecific);
  92. break;
  93. }
  94. _snprintf(rgszBuffer, cchBuffer, "%s", pszSpecific);
  95. }
  96. void DisplayToken(PXML_TOKEN pToken, FILE* pFile)
  97. {
  98. static char Formatter[4096];
  99. SIZE_T i;
  100. GetFormattedStateName(pToken->State, Formatter, NUMBER_OF(Formatter));
  101. fprintf(pFile, "%s, %d {%.*s}\n",
  102. Formatter,
  103. pToken->Run.cbData,
  104. pToken->Run.cbData,
  105. pToken->Run.pvData);
  106. }
  107. NTSTATUS
  108. DisplayLogicalThing(
  109. PXMLDOC_THING pThing,
  110. PRTL_GROWING_LIST pAttributeList
  111. )
  112. {
  113. printf("Extent {0x%p, %d} (depth %d):\n",
  114. pThing->TotalExtent.pvData,
  115. pThing->TotalExtent.cbData,
  116. pThing->ulDocumentDepth);
  117. switch (pThing->ulThingType) {
  118. case XMLDOC_THING_HYPERSPACE:
  119. {
  120. printf("\tHyperspace: {%.*s}\n", pThing->Hyperspace.cbData, pThing->Hyperspace.pvData);
  121. }
  122. break;
  123. case XMLDOC_THING_ELEMENT:
  124. {
  125. PXMLDOC_ATTRIBUTE pAttribute = NULL;
  126. ULONG ul = 0;
  127. NTSTATUS status;
  128. printf("\tElement {%.*s:%.*s} %d attributes %s\n",
  129. pThing->Element.NsPrefix.cbData,
  130. pThing->Element.NsPrefix.pvData,
  131. pThing->Element.Name.cbData,
  132. pThing->Element.Name.pvData,
  133. pThing->Element.ulAttributeCount,
  134. (pThing->Element.fElementEmpty ? "(empty)" : ""));
  135. for (ul = 0; ul < pThing->Element.ulAttributeCount; ul++) {
  136. status = RtlIndexIntoGrowingList(
  137. pAttributeList,
  138. ul,
  139. (PVOID*)&pAttribute,
  140. FALSE);
  141. if (NT_SUCCESS(status)) {
  142. printf("\t\tAttribute {%.*s:%.*s}={%.*s}\n",
  143. pAttribute->NsPrefix.cbData,
  144. pAttribute->NsPrefix.pvData,
  145. pAttribute->Name.cbData,
  146. pAttribute->Name.pvData,
  147. pAttribute->Value.cbData,
  148. pAttribute->Value.pvData);
  149. }
  150. else {
  151. printf("\t\t(Can't get attribute, error 0x%08lx)\n", status);
  152. }
  153. }
  154. }
  155. break;
  156. case XMLDOC_THING_XMLDECL:
  157. {
  158. PXMLDOC_XMLDECL pDecl = &pThing->XmlDecl;
  159. printf("\tXML Declaration: encoding {%.*s} version {%.*s} standalone {%.*s}\n",
  160. pDecl->Encoding.cbData,
  161. pDecl->Encoding.pvData,
  162. pDecl->Version.cbData,
  163. pDecl->Version.pvData,
  164. pDecl->Standalone.cbData,
  165. pDecl->Standalone.pvData);
  166. }
  167. break;
  168. case XMLDOC_THING_END_ELEMENT:
  169. {
  170. PXMLDOC_ENDELEMENT pElement = &pThing->EndElement;
  171. printf("\tClosing element {%.*s:%.*s} for tag {%.*s:%.*s}\n",
  172. pElement->NsPrefix.cbData,
  173. pElement->NsPrefix.pvData,
  174. pElement->Name.cbData,
  175. pElement->Name.pvData,
  176. pElement->OpeningElement.NsPrefix.cbData,
  177. pElement->OpeningElement.NsPrefix.pvData,
  178. pElement->OpeningElement.Name.cbData,
  179. pElement->OpeningElement.Name.pvData);
  180. }
  181. break;
  182. case XMLDOC_THING_END_OF_STREAM:
  183. printf("End of stream\n");
  184. break;
  185. case XMLDOC_THING_ERROR:
  186. {
  187. PXMLDOC_ERROR pError = &pThing->Error;
  188. printf("\tError in XML (or parser) found at {%.*s}, code %08lx\n",
  189. pError->BadExtent.cbData,
  190. pError->BadExtent.pvData,
  191. pError->Code);
  192. }
  193. break;
  194. }
  195. return STATUS_SUCCESS;
  196. }
  197. BOOL s_fDisplay = FALSE;
  198. NTSTATUS
  199. RunThroughFile(
  200. PVOID pvData,
  201. SIZE_T cbData
  202. )
  203. {
  204. XML_LOGICAL_STATE MasterParseState;
  205. XMLDOC_THING DocumentPiece;
  206. RTL_GROWING_LIST AttributeList;
  207. NTSTATUS status;
  208. LARGE_INTEGER liStart, liEnd;
  209. QueryPerformanceCounter(&liStart);
  210. status = RtlInitializeGrowingList(
  211. &AttributeList,
  212. sizeof(XMLDOC_ATTRIBUTE),
  213. 20,
  214. NULL,
  215. 0,
  216. &g_DefaultAllocator);
  217. if (!NT_SUCCESS(status)) {
  218. return status;
  219. }
  220. status = RtlXmlInitializeNextLogicalThing(
  221. &MasterParseState,
  222. pvData,
  223. cbData,
  224. &g_DefaultAllocator);
  225. while (NT_SUCCESS(status)) {
  226. status = RtlXmlNextLogicalThing(
  227. &MasterParseState,
  228. NULL,
  229. &DocumentPiece,
  230. &AttributeList);
  231. if (!NT_SUCCESS(status)) {
  232. break;
  233. }
  234. if (s_fDisplay)
  235. DisplayLogicalThing(&DocumentPiece, &AttributeList);
  236. if ((DocumentPiece.ulThingType == XMLDOC_THING_ERROR) ||
  237. (DocumentPiece.ulThingType == XMLDOC_THING_END_OF_STREAM)) {
  238. break;
  239. }
  240. }
  241. QueryPerformanceCounter(&liEnd);
  242. liEnd.QuadPart -= liStart.QuadPart;
  243. QueryPerformanceFrequency(&liStart);
  244. printf("%I64d ticks, %f seconds\n", liEnd.QuadPart, (double)liEnd.QuadPart / (double)liStart.QuadPart);
  245. if (DocumentPiece.ulThingType == XMLDOC_THING_END_OF_STREAM) {
  246. if (DocumentPiece.ulDocumentDepth == 0) {
  247. printf("Completed input stream\n");
  248. }
  249. else {
  250. printf("EOF before end of stream, %d elements on stack.\n",
  251. DocumentPiece.ulDocumentDepth);
  252. }
  253. }
  254. else {
  255. printf("Error found in stream processing at %.*s, byte offset %d.\n",
  256. DocumentPiece.TotalExtent.cbData,
  257. DocumentPiece.TotalExtent.pvData,
  258. (PBYTE)DocumentPiece.TotalExtent.pvData - (PBYTE)pvData
  259. );
  260. }
  261. return status;
  262. }
  263. NTSTATUS
  264. TimeFileRun(
  265. PVOID pvFileData,
  266. SIZE_T dwFileSize,
  267. PLARGE_INTEGER pliTickCount,
  268. double* pdblSecondCount)
  269. {
  270. XML_LOGICAL_STATE State;
  271. XML_TOKEN Token;
  272. LARGE_INTEGER liStartTime, liEndTime;
  273. SIZE_T ulEncodingBytes;
  274. NTSTATUS success;
  275. //
  276. // Start up the parser
  277. //
  278. success = RtlXmlInitializeTokenization(&State.ParseState, pvFileData, dwFileSize, NULL, NULL, NULL);
  279. if (!NT_SUCCESS(success)) {
  280. printf("Initialization failure\n");
  281. }
  282. State.ulElementStackDepth = 0;
  283. success = RtlInitializeGrowingList(
  284. &State.ElementStack,
  285. sizeof(XMLDOC_THING),
  286. 40,
  287. State.InlineElements,
  288. sizeof(State.InlineElements),
  289. &g_DefaultAllocator);
  290. if (!NT_SUCCESS(success)) {
  291. printf("Unable to create element stack");
  292. return success;
  293. }
  294. //
  295. // Let's determine the encoding
  296. //
  297. success = RtlXmlDetermineStreamEncoding(&State.ParseState, &ulEncodingBytes, &State.EncodingMarker);
  298. if (!NT_SUCCESS(success)) {
  299. printf("Unable to determine the encoding type\n");
  300. }
  301. //
  302. // Advance cursor past encoding bytes if necessary
  303. //
  304. State.ParseState.RawTokenState.pvCursor = ((PBYTE)State.ParseState.RawTokenState.pvCursor) + ulEncodingBytes;
  305. QueryPerformanceCounter(&liStartTime);
  306. do
  307. {
  308. if (NT_SUCCESS(success = RtlXmlNextToken(&State.ParseState, &Token, TRUE))) {
  309. //
  310. // Was there an error in this token?
  311. //
  312. if (s_fDisplay)
  313. DisplayToken(&Token, stdout);
  314. if (Token.fError) {
  315. printf("(Which was considered an error)\n");
  316. break;
  317. }
  318. }
  319. }
  320. while (NT_SUCCESS(success) && !Token.fError && (Token.State != XTSS_STREAM_END));
  321. QueryPerformanceCounter(&liEndTime);
  322. pliTickCount->QuadPart = liEndTime.QuadPart - liStartTime.QuadPart;
  323. QueryPerformanceFrequency(&liStartTime);
  324. *pdblSecondCount = (double)pliTickCount->QuadPart / liStartTime.QuadPart;
  325. return success;
  326. }
  327. DWORD WARMUP_COUNT = 3;
  328. DWORD REAL_COUNT = 5;
  329. int __cdecl wmain(int argc, WCHAR* argv[])
  330. {
  331. NTSTATUS success = STATUS_SUCCESS;
  332. HANDLE hFile = INVALID_HANDLE_VALUE;
  333. HANDLE hFileMapping = INVALID_HANDLE_VALUE;
  334. PVOID pvFileData = NULL;
  335. DWORD dwFileSize = 0;
  336. BOOL fFirstElementFound = FALSE;
  337. LARGE_INTEGER liTickCount, liTotalTicks;
  338. double dblSeconds, dblTotalSeconds;
  339. PCWSTR pcwszFileName = NULL;
  340. DWORD dw = 0;
  341. BOOL fJustRun = FALSE;
  342. int i;
  343. for (i = 1; i < argc; i++)
  344. {
  345. if (lstrcmpiW(L"-file", argv[i]) == 0) {
  346. pcwszFileName = argv[++i];
  347. }
  348. else if (lstrcmpiW(L"-warmup", argv[i]) == 0) {
  349. WARMUP_COUNT = _wtoi(argv[++i]);
  350. }
  351. else if (lstrcmpiW(L"-real", argv[i]) == 0) {
  352. REAL_COUNT = _wtoi(argv[++i]);
  353. }
  354. else if (lstrcmpiW(L"-display", argv[i]) == 0) {
  355. s_fDisplay = TRUE;
  356. }
  357. }
  358. if (pcwszFileName == NULL)
  359. {
  360. wprintf(L"Must specify at least '-file somefile'\r\n");
  361. return -1;
  362. }
  363. hFile = CreateFileW(
  364. pcwszFileName,
  365. GENERIC_READ,
  366. FILE_SHARE_READ,
  367. NULL,
  368. OPEN_EXISTING,
  369. FILE_ATTRIBUTE_NORMAL,
  370. NULL);
  371. if (hFile == INVALID_HANDLE_VALUE) {
  372. printf("Can't open file %ls\n", pcwszFileName);
  373. return -1;
  374. }
  375. dwFileSize = GetFileSize(hFile, NULL);
  376. hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, dwFileSize, NULL);
  377. if ((hFileMapping == NULL) || (hFileMapping == INVALID_HANDLE_VALUE)) {
  378. CloseHandle(hFile);
  379. wprintf(L"Can't create file mapping of %ls, lasterror %d\n", pcwszFileName, GetLastError());
  380. return -1;
  381. }
  382. pvFileData = MapViewOfFile(hFileMapping, FILE_MAP_READ, 0, 0, dwFileSize);
  383. if (pvFileData == NULL) {
  384. CloseHandle(hFile);
  385. CloseHandle(hFileMapping);
  386. wprintf(L"Can't create mapped view of file %ls\n", pcwszFileName);
  387. return -1;
  388. }
  389. for (dw = 0; dw < WARMUP_COUNT; dw++) {
  390. wprintf(L"Warmup cycle %d\n", dw);
  391. success = TimeFileRun(pvFileData, dwFileSize, &liTickCount, &dblSeconds);
  392. wprintf(L"%I64d ticks, %f seconds\n", liTickCount.QuadPart, dblSeconds);
  393. }
  394. wprintf(L"This one counts:\n");
  395. liTotalTicks.QuadPart = 0;
  396. dblTotalSeconds = 0.0;
  397. for (dw = 0; dw < REAL_COUNT; dw++) {
  398. success = TimeFileRun(pvFileData, dwFileSize, &liTickCount, &dblSeconds);
  399. dblTotalSeconds += dblSeconds;
  400. liTotalTicks.QuadPart += liTickCount.QuadPart;
  401. wprintf(L".");
  402. }
  403. wprintf(L"\n");
  404. if (REAL_COUNT == 0)
  405. {
  406. wprintf(L"No real runs, can't calculate time.\n");
  407. }
  408. else {
  409. wprintf(L"%d runs: %I64d total ticks, %I64d average, %f total seconds, %f average\n",
  410. REAL_COUNT,
  411. liTotalTicks.QuadPart,
  412. liTotalTicks.QuadPart / REAL_COUNT,
  413. dblTotalSeconds,
  414. dblTotalSeconds / REAL_COUNT);
  415. }
  416. success = RunThroughFile(pvFileData, dwFileSize);
  417. CloseHandle(hFile);
  418. CloseHandle(hFileMapping);
  419. UnmapViewOfFile(pvFileData);
  420. return success;
  421. success = RtlInstallAssembly(0, argv[1]);
  422. }