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.

1663 lines
52 KiB

  1. /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name:
  4. frmtstr.hxx
  5. Abstract:
  6. Notes:
  7. History:
  8. DKays Oct-1993 Created.
  9. ----------------------------------------------------------------------------*/
  10. #include "becls.hxx"
  11. #pragma hdrstop
  12. extern CMD_ARG * pCommand;
  13. const char * pExprFormatCharNames[] =
  14. {
  15. ""
  16. ,"FC_EXPR_CONST32"
  17. ,"FC_EXPR_CONST64"
  18. ,"FC_EXPR_VAR"
  19. ,"FC_EXPR_OPER"
  20. ,"FC_EXPR_PAD"
  21. };
  22. const char * pFormatCharNames[] =
  23. {
  24. "", // FC_ZERO
  25. "FC_BYTE",
  26. "FC_CHAR",
  27. "FC_SMALL",
  28. "FC_USMALL",
  29. "FC_WCHAR",
  30. "FC_SHORT",
  31. "FC_USHORT",
  32. "FC_LONG",
  33. "FC_ULONG",
  34. "FC_FLOAT",
  35. "FC_HYPER",
  36. "FC_DOUBLE",
  37. "FC_ENUM16",
  38. "FC_ENUM32",
  39. "FC_IGNORE",
  40. "FC_ERROR_STATUS_T",
  41. "FC_RP", // 11
  42. "FC_UP",
  43. "FC_OP",
  44. "FC_FP",
  45. "FC_STRUCT",
  46. "FC_PSTRUCT",
  47. "FC_CSTRUCT",
  48. "FC_CPSTRUCT",
  49. "FC_CVSTRUCT",
  50. "FC_BOGUS_STRUCT",
  51. "FC_CARRAY",
  52. "FC_CVARRAY",
  53. "FC_SMFARRAY",
  54. "FC_LGFARRAY",
  55. "FC_SMVARRAY",
  56. "FC_LGVARRAY or FC_SPLIT", // 20
  57. "FC_BOGUS_ARRAY",
  58. "FC_C_CSTRING",
  59. "FC_C_BSTRING",
  60. "FC_C_SSTRING",
  61. "FC_C_WSTRING",
  62. "FC_CSTRING",
  63. "FC_BSTRING",
  64. "FC_SSTRING",
  65. "FC_WSTRING",
  66. "FC_ENCAPSULATED_UNION",
  67. "FC_NON_ENCAPSULATED_UNION",
  68. "FC_BYTE_COUNT_POINTER",
  69. "FC_TRANSMIT_AS",
  70. "FC_REPRESENT_AS",
  71. "FC_IP",
  72. "FC_BIND_CONTEXT", // 30
  73. "FC_BIND_GENERIC",
  74. "FC_BIND_PRIMITIVE",
  75. "FC_AUTO_HANDLE",
  76. "FC_CALLBACK_HANDLE",
  77. "FC_UNUSED1",
  78. "FC_POINTER",
  79. "FC_ALIGNM2",
  80. "FC_ALIGNM4",
  81. "FC_ALIGNM8",
  82. "FC_UNUSED2",
  83. "FC_UNUSED3",
  84. "FC_UNUSED4",
  85. "FC_STRUCTPAD1",
  86. "FC_STRUCTPAD2",
  87. "FC_STRUCTPAD3",
  88. "FC_STRUCTPAD4", // 40
  89. "FC_STRUCTPAD5",
  90. "FC_STRUCTPAD6",
  91. "FC_STRUCTPAD7",
  92. "FC_STRING_SIZED",
  93. "FC_UNUSED5",
  94. "FC_NO_REPEAT",
  95. "FC_FIXED_REPEAT",
  96. "FC_VARIABLE_REPEAT",
  97. "FC_FIXED_OFFSET",
  98. "FC_VARIABLE_OFFSET",
  99. "FC_PP",
  100. "FC_EMBEDDED_COMPLEX",
  101. "FC_IN_PARAM",
  102. "FC_IN_PARAM_BASETYPE",
  103. "FC_IN_PARAM_NO_FREE_INST",
  104. "FC_IN_OUT_PARAM", // 50
  105. "FC_OUT_PARAM",
  106. "FC_RETURN_PARAM",
  107. "FC_RETURN_PARAM_BASETYPE",
  108. "FC_DEREFERENCE", // 54
  109. "FC_DIV_2", // 55
  110. "FC_MULT_2", // 56
  111. "FC_ADD_1", // 57
  112. "FC_SUB_1", // 58
  113. "FC_CALLBACK", // 59
  114. "FC_CONSTANT_IID", // 5a
  115. "FC_END", // 5b
  116. "FC_PAD", // 5c
  117. "FC_EXPR", // 5d
  118. "FC_PARTIAL_IGNORE_PARAM", // 5e,
  119. "?", // 5f
  120. "?", "?", "?", "?", "?", "?", "?", "?", // 60-67
  121. "?", "?", "?", "?", "?", "?", "?", "?", // 68-6f
  122. "?", "?", "?", "?", // 70-73
  123. "FC_SPLIT_DEREFERENCE", // 74
  124. "FC_SPLIT_DIV_2", // 75
  125. "FC_SPLIT_MULT_2", // 76
  126. "FC_SPLIT_ADD_1", // 77
  127. "FC_SPLIT_SUB_1", // 78
  128. "FC_SPLIT_CALLBACK", // 79
  129. "?", "?", "?", "?", "?", "?", // 7a-7f
  130. "?", "?", "?", "?", "?", "?", "?", "?", // 80-87
  131. "?", "?", "?", "?", "?", "?", "?", "?", // 88-8f
  132. "?", "?", "?", "?", "?", "?", "?", "?", // 90-97
  133. "?", "?", "?", "?", "?", "?", "?", "?", // 98-9f
  134. "?", "?", "?", "?", "?", "?", "?", "?", // a0-a7
  135. "?", "?", "?", "?", "?", "?", "?", "?", // a8-af
  136. "?", // b0
  137. "FC_HARD_STRUCT",
  138. "FC_TRANSMIT_AS_PTR",
  139. "FC_REPRESENT_AS_PTR",
  140. "FC_USER_MARSHAL",
  141. "FC_PIPE",
  142. "?", // FC_BLKHOLE. obselete
  143. "FC_RANGE", // b7
  144. "FC_INT3264", // b8
  145. "FC_UINT3264", // b9
  146. // Post NT5.0
  147. "FC_CSARRAY", // ba
  148. "FC_CS_TAG", // bb
  149. "FC_STRUCTPADN", // bc
  150. "FC_INT128", // 0xbd
  151. "FC_UINT128", // 0xbe
  152. "FC_FLOAT80", // 0xbf
  153. "FC_FLOAT128", // 0xc0
  154. "FC_BUFFER_ALIGN", // 0xc1
  155. "FC_ENCAP_UNION", // 0xc2
  156. // new 64bit array types
  157. "FC_FIX_ARRAY", // 0xc3
  158. "FC_CONF_ARRAY", // 0xc4
  159. "FC_VAR_ARRAY", // 0xc5
  160. "FC_CONFVAR_ARRAY", // 0xc6
  161. "FC_FIX_FORCED_BOGUS_ARRAY",// 0xc7
  162. "FC_FIX_BOGUS_ARRAY", // 0xc8
  163. "FC_FORCED_BOGUS_ARRAY", // 0xc9
  164. "FC_CHAR_STRING", // 0xca
  165. "FC_WCHAR_STRING", // 0xcb
  166. "FC_STRUCT_STRING", // 0xcc
  167. "FC_CONF_CHAR_STRING", // 0xcd
  168. "FC_CONF_WCHAR_STRING", // 0xce
  169. "FC_CONF_STRUCT_STRING", // 0xcf
  170. // new structure types
  171. "FC_CONF_STRUCT", // 0xd0
  172. "FC_CONF_PSTRUCT", // 0xd1
  173. "FC_CONFVAR_STRUCT", // 0xd2
  174. "FC_CONFVAR_PSTRUCT", // 0xd3
  175. "FC_FORCED_BOGUS_STRUCT", // 0xd4
  176. "FC_CONF_BOGUS_STRUCT", // 0xd5
  177. "FC_FORCED_CONF_BOGUS_STRUCT",// 0xd7
  178. "FC_END_OF_UNIVERSE" // 0xd8
  179. };
  180. const char * pExprOpFormatCharNames[] =
  181. {
  182. "",
  183. "OP_UNARY_PLUS",
  184. "OP_UNARY_MINUS",
  185. "OP_UNARY_NOT",
  186. "OP_UNARY_COMPLEMENT",
  187. "OP_UNARY_INDIRECTION",
  188. "OP_UNARY_CAST",
  189. "OP_UNARY_AND",
  190. "OP_UNARY_SIZEOF",
  191. "OP_UNARY_ALIGNOF",
  192. "OP_PRE_INCR",
  193. "OP_PRE_DECR",
  194. "OP_POST_INCR",
  195. "OP_POST_DECR",
  196. "OP_PLUS",
  197. "OP_MINUS",
  198. "OP_STAR",
  199. "OP_SLASH",
  200. "OP_MOD",
  201. "OP_LEFT_SHIFT",
  202. "OP_RIGHT_SHIFT",
  203. "OP_LESS",
  204. "OP_LESS_EQUAL",
  205. "OP_GREATER_EQUAL",
  206. "OP_GREATER",
  207. "OP_EQUAL",
  208. "OP_NOT_EQUAL",
  209. "OP_AND",
  210. "OP_OR",
  211. "OP_XOR",
  212. "OP_LOGICAL_AND",
  213. "OP_LOGICAL_OR",
  214. "OP_EXPRESSION",
  215. "",
  216. "",
  217. "", // function
  218. "", // param
  219. "", // pointsto
  220. "", // dot
  221. "", // index
  222. "", // comma
  223. "", // stmt
  224. "", // assign
  225. "OP_ASYNCSPLIT", // asyncsplit
  226. "OP_CORR_POINTER", // corr_pointer
  227. "OP_CORR_TOP_LEVEL", // corr_toplevel
  228. };
  229. //
  230. // This table is indexed by FORMAT_CHARACTER (see ndrtypes.h).
  231. // To construct the correct name concatenate the name in this table with
  232. // "Marshall", "Unmarshall", "BufferSize" etc.
  233. //
  234. char * pNdrRoutineNames[] =
  235. {
  236. "", // FC_ZERO
  237. "NdrSimpleType", // FC_BYTE
  238. "NdrSimpleType", // FC_CHAR
  239. "NdrSimpleType", // FC_SMALL
  240. "NdrSimpleType", // FC_USMALL
  241. "NdrSimpleType", // FC_WCHAR
  242. "NdrSimpleType", // FC_SHORT
  243. "NdrSimpleType", // FC_USHORT
  244. "NdrSimpleType", // FC_LONG
  245. "NdrSimpleType", // FC_ULONG
  246. "NdrSimpleType", // FC_FLOAT
  247. "NdrSimpleType", // FC_HYPER
  248. "NdrSimpleType", // FC_DOUBLE
  249. "NdrSimpleType", // FC_ENUM16
  250. "NdrSimpleType", // FC_ENUM32
  251. "NdrSimpleType", // FC_IGNORE
  252. "NdrSimpleType", // FC_ERROR_STATUS_T
  253. "NdrPointer", // FC_RP
  254. "NdrPointer", // FC_UP
  255. "NdrPointer", // FC_OP
  256. "NdrPointer", // FC_FP
  257. "NdrSimpleStruct", // FC_STRUCT
  258. "NdrSimpleStruct", // FC_PSTRUCT
  259. "NdrConformantStruct", // FC_CSTRUCT
  260. "NdrConformantStruct", // FC_CPSTRUCT
  261. "NdrConformantVaryingStruct", // FC_CVSTRUCT
  262. "NdrComplexStruct", // FC_BOGUS_STRUCT
  263. "NdrConformantArray", // FC_CARRAY
  264. "NdrConformantVaryingArray", // FC_CVARRAY
  265. "NdrFixedArray", // FC_SMFARRAY
  266. "NdrFixedArray", // FC_LGFARRAY
  267. "NdrVaryingArray", // FC_SMVARRAY
  268. "NdrVaryingArray", // FC_LGVARRAY
  269. "NdrComplexArray", // FC_BOGUS_ARRAY
  270. "NdrConformantString", // FC_C_CSTRING
  271. "NdrConformantString", // FC_C_BSTRING
  272. "NdrConformantString", // FC_C_SSTRING
  273. "NdrConformantString", // FC_C_WSTRING
  274. "NdrNonConformantString", // FC_CSTRING
  275. "NdrNonConformantString", // FC_BSTRING
  276. "NdrNonConformantString", // FC_SSTRING
  277. "NdrNonConformantString", // FC_WSTRING
  278. "NdrEncapsulatedUnion", // FC_ENCAPSULATED_UNION
  279. "NdrNonEncapsulatedUnion", // FC_NON_ENCAPSULATED_UNION
  280. "NdrByteCountPointer", // FC_BYTE_COUNT_POINTER
  281. "NdrXmitOrRepAs", // FC_TRANSMIT_AS
  282. "NdrXmitOrRepAs", // FC_REPRESENT_AS
  283. "NdrInterfacePointer", // FC_INTERFACE_POINTER
  284. "NdrContextHandle", // FC_BIND_CONTEXT
  285. "?", "?", "?", "?", "?", "?", "?", // 31-37
  286. "?", "?", "?", "?", "?", "?", "?", "?", // 38-3f
  287. "?", "?", "?", "?", "?", "?", "?", "?", // 40-47
  288. "?", "?", "?", "?", "?", "?", "?", "?", // 48-4f
  289. "?", "?", "?", "?", "?", "?", "?", "?", // 50-57
  290. "?", "?", "?", // 58-5a
  291. "?", "?", // FC_END & FC_PAD
  292. "?", "?", "?", // 5d-5f
  293. "?", "?", "?", "?", "?", "?", "?", "?", // 60-67
  294. "?", "?", "?", "?", "?", "?", "?", "?", // 68-6f
  295. "?", "?", "?", "?", "?", "?", "?", "?", // 70-77
  296. "?", "?", "?", "?", "?", "?", "?", "?", // 78-7f
  297. "?", "?", "?", "?", "?", "?", "?", "?", // 80-87
  298. "?", "?", "?", "?", "?", "?", "?", "?", // 88-8f
  299. "?", "?", "?", "?", "?", "?", "?", "?", // 90-97
  300. "?", "?", "?", "?", "?", "?", "?", "?", // 98-9f
  301. "?", "?", "?", "?", "?", "?", "?", "?", // a0-a7
  302. "?", "?", "?", "?", "?", "?", "?", "?", // a8-af
  303. "?", // 0xb0
  304. "NdrHardStruct", // FC_HARD_STRUCT
  305. "NdrXmitOrRepAs", // FC_TRANSMIT_AS_PTR
  306. "NdrXmitOrRepAs", // FC_REPRESENT_AS_PTR
  307. "NdrUserMarshal", // FC_USER_MARSHAL
  308. "NdrPipe", // FC_PIPE
  309. 0, // FC_BLKHOLE
  310. 0, // FC_RANGE
  311. "NdrSimpleType", // FC_INT3264
  312. "NdrSimpleType", // FC_UINT3264
  313. "NdrCsArray", // FC_CSARRAY
  314. "NdrCsTag", // FC_CS_TAG
  315. 0
  316. };
  317. // ============================================================================
  318. //
  319. // FORMAT_STRING class, general comments on fragment optimization.
  320. //
  321. // There are 3 type of offsets that matter a lot when format string fragments
  322. // are optimized. These are absolute type offsets, relative type offsets and
  323. // stack (or field) offsets.
  324. //
  325. // - Absolute type offsets are offsets from the proc format string to type
  326. // format string. For 32b implementation they are limited to ushort32 range.
  327. // An absolute type offset indicates a type of a parameter.
  328. // Note that there is only one absolute type offset for a parameter regardless
  329. // of the platform.
  330. //
  331. // - Relative type offsets are offsets within the type format string.
  332. // For 32b implementation they are limited to short32 range.
  333. // A relative type offset indicates a type of a component for a compund type.
  334. // Note that there is only one relative type offset for a field or element
  335. // regardless of the platform.
  336. //
  337. // - Stack offset is a stack offset to a parameter within a proc stack or
  338. // a field offset to a field within a struct.
  339. // For a 32b implementation stack offsets are limited to a short32 range. This
  340. // is because some of these offsets are relative to a current position within
  341. // a struct or union. They have been clampd together because of correlation
  342. // descriptors may have stack or field offsets.
  343. // Proper stack offsets actually come in a ushort and usmall range variaty.
  344. // Proper field offsets come in as shorts.
  345. // For a given position in the format string, there is a set of stack offsets
  346. // as in general a x86 stack offset is different from other platform offsets
  347. // and a field offset may be different as well.
  348. //
  349. // Proc format string uses only absolute type offsets and stack offsets.
  350. //
  351. // the constructor
  352. FORMAT_STRING::FORMAT_STRING()
  353. {
  354. // Allocate the buffer and align it on a short boundary.
  355. pBuffer = (unsigned char *) new short[ DEFAULT_FORMAT_STRING_SIZE / 2 ];
  356. // Allocate the cousin buffer type array. This does not need to
  357. // be aligned.
  358. pBufferType = new unsigned char[ DEFAULT_FORMAT_STRING_SIZE ];
  359. memset( pBuffer, 0, DEFAULT_FORMAT_STRING_SIZE );
  360. memset( pBufferType, FS_FORMAT_CHARACTER, DEFAULT_FORMAT_STRING_SIZE );
  361. BufferSize = DEFAULT_FORMAT_STRING_SIZE;
  362. CurrentOffset = 0;
  363. LastOffset = 0;
  364. pReuseDict = new FRMTREG_DICT( this );
  365. }
  366. void
  367. FORMAT_STRING::CheckSize()
  368. /*++
  369. Routine Description :
  370. Reallocates a new format string buffer if the current buffer is within
  371. 4 bytes of overflowing.
  372. Arguments :
  373. None.
  374. --*/
  375. {
  376. //
  377. // Allocate a new buffer if we're within 4 bytes of
  378. // overflowing the current buffer.
  379. //
  380. if ( CurrentOffset + 3 > BufferSize )
  381. {
  382. unsigned char * pBufferNew;
  383. // double the Buffer size
  384. pBufferNew = (unsigned char *) new short[ BufferSize ];
  385. memcpy( pBufferNew,
  386. pBuffer,
  387. (unsigned int) BufferSize );
  388. memset( pBufferNew + BufferSize, 0, BufferSize );
  389. delete pBuffer;
  390. pBuffer = pBufferNew;
  391. // double the BufferType size
  392. pBufferNew = (unsigned char *) new short[ BufferSize ];
  393. memcpy( pBufferNew,
  394. pBufferType,
  395. (unsigned int) BufferSize );
  396. memset( pBufferNew + BufferSize, FS_FORMAT_CHARACTER, BufferSize );
  397. delete pBufferType;
  398. pBufferType = pBufferNew;
  399. BufferSize *= 2;
  400. }
  401. }
  402. //
  403. // Push a short type-fmt-string offset at the current offset.
  404. // This is used as the offset from a parameter into type format string.
  405. // For 32b code, this needs to be a value within an unsigned short.
  406. // We use a long value internally for better fragment optimization.
  407. //
  408. void
  409. FORMAT_STRING::PushShortTypeOffset( long s )
  410. {
  411. CheckSize();
  412. if ( s < 0 || s > _UI16_MAX )
  413. {
  414. // CG_NDR * pNdr = pCCB->GetLastPlaceholderClass();
  415. CG_NDR * pNdr = 0;
  416. char * pName = pNdr ? pNdr->GetSymName()
  417. : "";
  418. RpcError(NULL, 0, FORMAT_STRING_LIMITS, pName );
  419. exit( FORMAT_STRING_LIMITS );
  420. }
  421. pBufferType[CurrentOffset] = FS_SHORT_TYPE_OFFSET;
  422. pBufferType[CurrentOffset+1] = FS_SMALL;
  423. *((unsigned short UNALIGNED *)(pBuffer + CurrentOffset)) = (unsigned short)s;
  424. TypeOffsetDict.Insert( (long) CurrentOffset, s );
  425. IncrementOffset(2);
  426. }
  427. //
  428. // Push a short offset at the current offset.
  429. // This is the relative type offset within the type string.
  430. // For 32b code, this needs to be a value within a signed short, eventually.
  431. // We use a long value internally for better fragment optimization.
  432. //
  433. void
  434. FORMAT_STRING::PushShortOffset( long TypeOffset )
  435. {
  436. CheckSize();
  437. // We don't check the range for the offset here for better optimization.
  438. pBufferType[ CurrentOffset ] = FS_SHORT_OFFSET;
  439. pBufferType[ CurrentOffset + 1 ] = FS_SMALL;
  440. *((short UNALIGNED *)(pBuffer + CurrentOffset)) = (short)TypeOffset;
  441. TypeOffsetDict.Insert( (long) CurrentOffset, TypeOffset );
  442. IncrementOffset(2);
  443. }
  444. // This an auxilary method to handle relative offsets.
  445. // It is used when we need to write out an offset temporarily and then fix it
  446. // later, for example in pointers, structs etc.
  447. //
  448. void
  449. FORMAT_STRING::PushShortOffset( long TypeOffset, long Position )
  450. {
  451. // We don't check the range for the offset here for better optimization.
  452. pBufferType[ Position ] = FS_SHORT_OFFSET;
  453. pBufferType[ Position + 1 ] = FS_SMALL;
  454. *((short UNALIGNED *)(pBuffer + Position)) = (short)TypeOffset;
  455. TypeOffsetDict.Insert( Position, TypeOffset );
  456. }
  457. //
  458. // Push a stack size or an absolute offset.
  459. //
  460. void
  461. FORMAT_STRING::PushUShortStackOffsetOrSize(
  462. long X86Offset )
  463. {
  464. CheckSize();
  465. if ( X86Offset < 0 || X86Offset > _UI16_MAX )
  466. {
  467. // Make it a warning with a name.
  468. // CG_NDR * pNdr = pCCB->GetLastPlaceholderClass();
  469. CG_NDR * pNdr = 0;
  470. char * pName = pNdr ? pNdr->GetSymName()
  471. : "";
  472. RpcError(NULL, 0, STACK_SIZE_TOO_BIG, pName );
  473. exit( FORMAT_STRING_LIMITS );
  474. }
  475. pBufferType[CurrentOffset] = FS_SHORT_STACK_OFFSET;
  476. pBufferType[CurrentOffset+1] = FS_SMALL;
  477. *((short UNALIGNED *)(pBuffer + CurrentOffset)) = (short) X86Offset;
  478. #if defined(RKK_FRAG_OPT)
  479. {
  480. printf("PushShortStackOffset CurrentOffset %d\n", CurrentOffset );
  481. int offLow = CurrentOffset - 10; if (offLow < 0) offLow = 0;
  482. int offHig = CurrentOffset + 10;
  483. printf(" off=%d ", offLow );
  484. for (int off = offLow; off < offHig; off++)
  485. printf("%02x ", pBuffer[ off ]);
  486. printf( "\n" );
  487. printf(" off=%d ", offLow );
  488. for ( off = offLow; off < offHig; off++)
  489. printf("%02x ", pBufferType[ off ]);
  490. printf( "\n" );
  491. }
  492. #endif
  493. OffsetDict.Insert( (long) CurrentOffset,
  494. X86Offset );
  495. IncrementOffset(2);
  496. }
  497. //
  498. // Push a stack offset.
  499. // Needs to be relative because of offsets in structs etc.
  500. //
  501. void
  502. FORMAT_STRING::PushShortStackOffset(
  503. long X86Offset )
  504. {
  505. CheckSize();
  506. if ( X86Offset < _I16_MIN || X86Offset > _I16_MAX )
  507. {
  508. // Make it a warning with a name.
  509. // CG_NDR * pNdr = pCCB->GetLastPlaceholderClass();
  510. CG_NDR * pNdr = 0;
  511. char * pName = pNdr ? pNdr->GetSymName()
  512. : "";
  513. RpcError(NULL, 0, FORMAT_STRING_LIMITS, pName );
  514. exit( FORMAT_STRING_LIMITS );
  515. }
  516. pBufferType[CurrentOffset] = FS_SHORT_STACK_OFFSET;
  517. pBufferType[CurrentOffset+1] = FS_SMALL;
  518. *((short UNALIGNED *)(pBuffer + CurrentOffset)) = (short) X86Offset;
  519. #if defined(RKK_FRAG_OPT)
  520. {
  521. printf("PushShortStackOffset CurrentOffset %d\n", CurrentOffset );
  522. int offLow = CurrentOffset - 10; if (offLow < 0) offLow = 0;
  523. int offHig = CurrentOffset + 10;
  524. printf(" off=%d ", offLow );
  525. for (int off = offLow; off < offHig; off++)
  526. printf("%02x ", pBuffer[ off ]);
  527. printf( "\n" );
  528. printf(" off=%d ", offLow );
  529. for ( off = offLow; off < offHig; off++)
  530. printf("%02x ", pBufferType[ off ]);
  531. printf( "\n" );
  532. }
  533. #endif
  534. OffsetDict.Insert( (long) CurrentOffset,
  535. X86Offset );
  536. IncrementOffset(2);
  537. }
  538. // =============================================================================
  539. //
  540. // Helper routines writing comments about some tokens.
  541. //
  542. __inline void
  543. Out_PointerFlags(
  544. ISTREAM * pStream,
  545. unsigned char * pFlags
  546. )
  547. {
  548. if ( *pFlags & FC_ALLOCATE_ALL_NODES )
  549. pStream->Write( " [all_nodes]");
  550. if ( *pFlags & FC_DONT_FREE )
  551. pStream->Write( " [dont_free]");
  552. if ( *pFlags & FC_ALLOCED_ON_STACK )
  553. pStream->Write( " [alloced_on_stack]");
  554. if ( *pFlags & FC_SIMPLE_POINTER )
  555. pStream->Write( " [simple_pointer]");
  556. if ( *pFlags & FC_POINTER_DEREF )
  557. pStream->Write( " [pointer_deref]");
  558. }
  559. __inline void
  560. Out_OldProcFlags(
  561. ISTREAM * pStream,
  562. unsigned char * pFlags
  563. )
  564. {
  565. INTERPRETER_FLAGS * pOiFlags = (INTERPRETER_FLAGS *)pFlags;
  566. if ( pOiFlags->FullPtrUsed )
  567. pStream->Write( " full ptr,");
  568. if ( pOiFlags->RpcSsAllocUsed )
  569. pStream->Write( " DCE mem package,");
  570. if ( pOiFlags->ObjectProc )
  571. {
  572. pStream->Write( " object,");
  573. if ( pOiFlags->IgnoreObjectException )
  574. pStream->Write( " ignore obj exc,");
  575. if ( pOiFlags->HasCommOrFault )
  576. pStream->Write( " Oi2");
  577. }
  578. else
  579. {
  580. if ( pOiFlags->IgnoreObjectException )
  581. pStream->Write( " encode,");
  582. if ( pOiFlags->HasCommOrFault )
  583. pStream->Write( " comm or fault/decode");
  584. }
  585. }
  586. __inline void
  587. Out_Oi2ProcFlags(
  588. ISTREAM * pStream,
  589. unsigned char * pFlags
  590. )
  591. {
  592. INTERPRETER_OPT_FLAGS * pOi2Flags = (INTERPRETER_OPT_FLAGS *)pFlags;
  593. if ( pOi2Flags->ServerMustSize )
  594. pStream->Write( " srv must size,");
  595. if ( pOi2Flags->ClientMustSize )
  596. pStream->Write( " clt must size,");
  597. if ( pOi2Flags->HasReturn )
  598. pStream->Write( " has return,");
  599. if ( pOi2Flags->HasPipes )
  600. pStream->Write( " has pipes,");
  601. if ( pOi2Flags->HasAsyncUuid )
  602. pStream->Write( " has async uuid,");
  603. if ( pOi2Flags->HasExtensions )
  604. pStream->Write( " has ext,");
  605. if ( pOi2Flags->HasAsyncHandle )
  606. pStream->Write( " has async handle");
  607. }
  608. __inline void
  609. Out_ExtProcFlags(
  610. ISTREAM * pStream,
  611. unsigned char * pFlags
  612. )
  613. {
  614. INTERPRETER_OPT_FLAGS2 * pExtFlags = (INTERPRETER_OPT_FLAGS2 *)pFlags;
  615. if ( pExtFlags->HasNewCorrDesc )
  616. pStream->Write( " new corr desc,");
  617. if ( pExtFlags->ClientCorrCheck )
  618. pStream->Write( " clt corr check,");
  619. if ( pExtFlags->ServerCorrCheck )
  620. pStream->Write( " srv corr check,");
  621. if ( pExtFlags->HasNotify )
  622. pStream->Write( " has notify");
  623. if ( pExtFlags->HasNotify2 )
  624. pStream->Write( " has notify_flag");
  625. if ( pExtFlags->HasComplexReturn )
  626. pStream->Write( " has complex return");
  627. }
  628. __inline void
  629. Out_ParameterFlags(
  630. ISTREAM * pStream,
  631. PARAM_ATTRIBUTES * pParamAttr
  632. )
  633. {
  634. char Buf[8];
  635. if ( pParamAttr->MustSize )
  636. pStream->Write( " must size,");
  637. if ( pParamAttr->MustFree )
  638. pStream->Write( " must free,");
  639. if ( pParamAttr->IsPipe )
  640. pStream->Write( " pipe,");
  641. if ( pParamAttr->IsIn )
  642. pStream->Write( " in,");
  643. if ( pParamAttr->IsOut )
  644. pStream->Write( " out,");
  645. if ( pParamAttr->IsReturn )
  646. pStream->Write( " return,");
  647. if ( pParamAttr->IsBasetype )
  648. pStream->Write( " base type,");
  649. if ( pParamAttr->IsByValue )
  650. pStream->Write( " by val,");
  651. if ( pParamAttr->IsSimpleRef )
  652. pStream->Write( " simple ref,");
  653. if ( pParamAttr->IsDontCallFreeInst )
  654. pStream->Write( " dont call free inst,");
  655. if ( pParamAttr->IsForceAllocate )
  656. pStream->Write( " force allocate," );
  657. if ( pParamAttr->SaveForAsyncFinish )
  658. pStream->Write( " split async,");
  659. if ( pParamAttr->ServerAllocSize )
  660. {
  661. pStream->Write( " srv alloc size=");
  662. pStream->Write( MIDL_ITOA( 8 * pParamAttr->ServerAllocSize, Buf, 10) );
  663. }
  664. }
  665. __inline void
  666. Out_CorrelationType(
  667. ISTREAM * pStream,
  668. unsigned char * pCorrType
  669. )
  670. {
  671. unsigned char CorrType = *pCorrType;
  672. if ( CorrType & FC_NORMAL_CONFORMANCE )
  673. pStream->Write( " field, ");
  674. if ( CorrType & FC_POINTER_CONFORMANCE )
  675. pStream->Write( " field pointer, ");
  676. if ( CorrType & FC_TOP_LEVEL_CONFORMANCE )
  677. pStream->Write( " parameter, ");
  678. if ( CorrType & FC_TOP_LEVEL_MULTID_CONFORMANCE )
  679. pStream->Write( " multidim parameter, ");
  680. if ( CorrType & FC_CONSTANT_CONFORMANCE )
  681. {
  682. unsigned long ConstVal;
  683. char Buf[12];
  684. pStream->Write( " constant, val=");
  685. // next three bytes: just a weird way of generating it
  686. ConstVal = (ulong) pCorrType[1] << 16;
  687. ConstVal |= *(unsigned short UNALIGNED *)( pCorrType + 2);
  688. pStream->Write( MIDL_ITOA( ConstVal, Buf, 10) );
  689. }
  690. else
  691. {
  692. pStream->Write( pFormatCharNames[ CorrType & 0xf ] );
  693. }
  694. }
  695. __inline void
  696. Out_CorrelationFlags(
  697. ISTREAM * pStream,
  698. unsigned char * pNewCorrFlags
  699. )
  700. {
  701. NDR_CORRELATION_FLAGS * pCorrFlags = (NDR_CORRELATION_FLAGS *)pNewCorrFlags;
  702. if ( pCorrFlags->Early )
  703. pStream->Write( " early," );
  704. if ( pCorrFlags->Split )
  705. pStream->Write( " split," );
  706. if ( pCorrFlags->IsIidIs )
  707. pStream->Write( " iid_is," );
  708. if ( pCorrFlags->DontCheck )
  709. pStream->Write( " dont check" );
  710. }
  711. __inline void
  712. Out_ContextHandleFlags(
  713. ISTREAM * pStream,
  714. unsigned char * pContextFlags
  715. )
  716. {
  717. PNDR_CONTEXT_HANDLE_FLAGS pFlags = (PNDR_CONTEXT_HANDLE_FLAGS)pContextFlags;
  718. if ( pFlags->IsViaPtr )
  719. pStream->Write( " via ptr," );
  720. if ( pFlags->IsIn )
  721. pStream->Write( " in," );
  722. if ( pFlags->IsOut )
  723. pStream->Write( " out," );
  724. if ( pFlags->IsReturn )
  725. pStream->Write( " ret," );
  726. if ( pFlags->IsStrict )
  727. pStream->Write( " strict," );
  728. if ( pFlags->NoSerialize )
  729. pStream->Write( " no serialize," );
  730. if ( pFlags->Serialize )
  731. pStream->Write( " serialize," );
  732. if ( pFlags->CannotBeNull)
  733. pStream->Write( " can't be null" );
  734. }
  735. __inline void
  736. Out_SmallStackSize(
  737. ISTREAM * pStream,
  738. long StackSize,
  739. char * pEnvComment
  740. )
  741. {
  742. char Buf[102];
  743. //
  744. // Non-Alpha stack size.
  745. //
  746. pStream->Write( "0x" );
  747. pStream->Write( MIDL_ITOA(StackSize, Buf, 16) );
  748. pStream->Write( ",\t\t/* ");
  749. pStream->Write( pEnvComment );
  750. pStream->Write( " stack size = ");
  751. pStream->Write( MIDL_ITOA(StackSize, Buf, 10) );
  752. pStream->Write( " */");
  753. }
  754. // The comment table is initialized in FORMAT_STRING::Output as appropriate
  755. // for a given environment { 64b, 32b, others }.
  756. // The comments correspond to the ifdef situation described below.
  757. static char * Env64Comment = "ia64";
  758. static char * Env32Comment = "x86";
  759. static char * OtherEnvComment = "";
  760. __inline void
  761. Out_ShortStackOffset(
  762. ISTREAM * pStream,
  763. OffsetDictElem * pStackOffsets,
  764. char * EnvComment
  765. )
  766. {
  767. char Buf[102];
  768. //
  769. // Emit the main (x86 or ia64) offset.
  770. //
  771. unsigned long OffsetValue = pStackOffsets->X86Offset;
  772. pStream->Write( "NdrFcShort( 0x" );
  773. pStream->Write( MIDL_ITOA( OffsetValue, Buf, 16) );
  774. pStream->Write( " ),\t/* " );
  775. pStream->Write( EnvComment );
  776. pStream->Write( " Stack size/offset = " );
  777. pStream->Write( MIDL_ITOA( OffsetValue, Buf, 10) );
  778. pStream->Write( " */");
  779. }
  780. void
  781. FORMAT_STRING::Output(
  782. ISTREAM * pStream,
  783. char * pTypeName,
  784. char * pName,
  785. RepAsPadExprDict * pPadDict,
  786. RepAsSizeDict * pSizeDict )
  787. /*++
  788. Routine Description :
  789. Outputs the format string structure.
  790. Arguments :
  791. pStream - Stream to output the format string to.
  792. --*/
  793. {
  794. long Offset;
  795. long LastPrinted = 0;
  796. char Buf[102];
  797. BOOL InPP = FALSE;
  798. REP_AS_PAD_EXPR_DESC * pPadExprDesc;
  799. REP_AS_SIZE_DESC * pSizeDesc;
  800. char * pComment;
  801. BOOL fLimitErr = FALSE;
  802. pStream->NewLine();
  803. pStream->Write( "static const " );
  804. pStream->Write( pTypeName );
  805. pStream->Write( ' ' );
  806. pStream->Write( pName );
  807. pStream->Write( " =");
  808. pStream->IndentInc();
  809. pStream->NewLine();
  810. pStream->Write( '{' );
  811. pStream->IndentInc();
  812. pStream->NewLine();
  813. pStream->Write( "0," );
  814. pStream->NewLine();
  815. pStream->Write( '{' );
  816. pStream->IndentInc();
  817. // Reset the pad and size macro dictionaries
  818. pPadExprDesc = pPadDict->GetFirst();
  819. pSizeDesc = pSizeDict->GetFirst();
  820. pStream->IndentDec();
  821. pStream->IndentDec();
  822. pStream->IndentDec();
  823. BOOL f32 = pCommand->GetEnv() == ENV_WIN32;
  824. BOOL f64 = pCommand->GetEnv() == ENV_WIN64;
  825. char * EnvComment;
  826. if ( f32 )
  827. {
  828. EnvComment = Env32Comment;
  829. }
  830. else if ( f64 )
  831. {
  832. EnvComment = Env64Comment;
  833. }
  834. else
  835. {
  836. EnvComment = OtherEnvComment;
  837. }
  838. for ( Offset = 0; Offset < (long)LastOffset; )
  839. {
  840. pStream->NewLine();
  841. pComment = CommentDict.GetComments( Offset );
  842. if ( pComment )
  843. pStream->Write( pComment );
  844. if ( ! (Offset % 2) && ( Offset != LastPrinted ) )
  845. {
  846. sprintf(Buf,"/* %2d */\t",Offset);
  847. LastPrinted = Offset;
  848. pStream->Write(Buf);
  849. }
  850. else
  851. {
  852. pStream->Write("\t\t\t");
  853. }
  854. switch ( pBufferType[Offset] )
  855. {
  856. case FS_FORMAT_CHARACTER :
  857. // Make the format string readable.
  858. switch ( pBuffer[Offset] )
  859. {
  860. case FC_IN_PARAM :
  861. case FC_IN_OUT_PARAM :
  862. case FC_PARTIAL_IGNORE_PARAM :
  863. case FC_OUT_PARAM :
  864. case FC_RETURN_PARAM :
  865. case FC_STRUCT :
  866. case FC_PSTRUCT :
  867. case FC_CSTRUCT :
  868. case FC_CPSTRUCT :
  869. case FC_CVSTRUCT :
  870. case FC_BOGUS_STRUCT :
  871. case FC_NO_REPEAT :
  872. case FC_FIXED_REPEAT :
  873. case FC_VARIABLE_REPEAT :
  874. case FC_CARRAY :
  875. case FC_CVARRAY :
  876. case FC_SMFARRAY :
  877. case FC_LGFARRAY :
  878. case FC_SMVARRAY :
  879. case FC_LGVARRAY :
  880. case FC_BOGUS_ARRAY :
  881. case FC_C_CSTRING :
  882. case FC_C_SSTRING :
  883. case FC_C_WSTRING :
  884. case FC_CSTRING :
  885. case FC_SSTRING :
  886. case FC_WSTRING :
  887. case FC_ENCAPSULATED_UNION :
  888. case FC_NON_ENCAPSULATED_UNION :
  889. case FC_IP :
  890. pStream->NewLine();
  891. pStream->Write("\t\t\t");
  892. break;
  893. case FC_RP :
  894. case FC_UP :
  895. case FC_OP :
  896. case FC_FP :
  897. //
  898. // If we're not in a pointer layout, and the previous
  899. // format char was not a param/result char then print
  900. // a new line.
  901. //
  902. if ( ! InPP &&
  903. ( Offset &&
  904. pBuffer[Offset - 1] != FC_IN_PARAM &&
  905. pBuffer[Offset - 1] != FC_IN_OUT_PARAM &&
  906. pBuffer[Offset - 1] != FC_PARTIAL_IGNORE_PARAM &&
  907. pBuffer[Offset - 1] != FC_OUT_PARAM &&
  908. pBuffer[Offset - 1] != FC_IN_PARAM_NO_FREE_INST &&
  909. pBuffer[Offset - 1] != FC_RETURN_PARAM )
  910. )
  911. {
  912. pStream->NewLine();
  913. pStream->Write("\t\t\t");
  914. }
  915. break;
  916. case FC_PP :
  917. InPP = TRUE;
  918. pStream->NewLine();
  919. pStream->Write("\t\t\t");
  920. break;
  921. case FC_END :
  922. if ( InPP )
  923. {
  924. pStream->NewLine();
  925. pStream->Write("\t\t\t");
  926. }
  927. break;
  928. default:
  929. break;
  930. }
  931. pStream->Write( "0x" );
  932. pStream->Write( MIDL_ITOA( pBuffer[Offset], Buf, 16 ) );
  933. pStream->Write( ",\t\t/* ");
  934. pStream->Write( pFormatCharNames[pBuffer[Offset]] );
  935. pStream->Write( " */");
  936. if ( (pBuffer[Offset] == FC_END) && InPP )
  937. {
  938. pStream->NewLine();
  939. InPP = FALSE;
  940. }
  941. Offset++;
  942. break;
  943. case FS_POINTER_FORMAT_CHARACTER :
  944. //
  945. // If we're not in a pointer layout, and the previous
  946. // format char was not a param/result char then print
  947. // a new line.
  948. //
  949. if ( ! InPP &&
  950. ( Offset &&
  951. pBuffer[Offset - 1] != FC_IN_PARAM &&
  952. pBuffer[Offset - 1] != FC_IN_OUT_PARAM &&
  953. pBuffer[Offset - 1] != FC_PARTIAL_IGNORE_PARAM &&
  954. pBuffer[Offset - 1] != FC_OUT_PARAM &&
  955. pBuffer[Offset - 1] != FC_RETURN_PARAM )
  956. )
  957. {
  958. pStream->NewLine();
  959. pStream->Write("\t\t\t");
  960. }
  961. pStream->Write( "0x" );
  962. pStream->Write( MIDL_ITOA( pBuffer[Offset], Buf, 16 ) );
  963. pStream->Write( ", 0x" );
  964. pStream->Write( MIDL_ITOA( pBuffer[Offset + 1] & 0x00ff, Buf, 16 ) );
  965. pStream->Write( ",\t/* ");
  966. pStream->Write( pFormatCharNames[pBuffer[Offset]] );
  967. Out_PointerFlags( pStream, pBuffer + Offset + 1 );
  968. pStream->Write( " */");
  969. Offset += 2;
  970. break;
  971. case FS_SMALL :
  972. pStream->Write( "0x" );
  973. pStream->Write( MIDL_ITOA( pBuffer[Offset] & 0x00ff, Buf, 16 ) );
  974. pStream->Write( ",\t\t/* ");
  975. pStream->Write( MIDL_ITOA( pBuffer[Offset], Buf, 10 ) );
  976. pStream->Write( " */");
  977. Offset++;
  978. break;
  979. case FS_OLD_PROC_FLAG_BYTE :
  980. pStream->Write( "0x" );
  981. pStream->Write( MIDL_ITOA( pBuffer[Offset] & 0x00ff, Buf, 16 ) );
  982. pStream->Write( ",\t\t/* Old Flags: ");
  983. Out_OldProcFlags( pStream, pBuffer + Offset );
  984. pStream->Write( " */");
  985. Offset++;
  986. break;
  987. case FS_Oi2_PROC_FLAG_BYTE :
  988. pStream->Write( "0x" );
  989. pStream->Write( MIDL_ITOA( pBuffer[Offset] & 0x00ff, Buf, 16 ) );
  990. pStream->Write( ",\t\t/* Oi2 Flags: ");
  991. Out_Oi2ProcFlags( pStream, pBuffer + Offset );
  992. pStream->Write( " */");
  993. Offset++;
  994. break;
  995. case FS_EXT_PROC_FLAG_BYTE :
  996. pStream->Write( "0x" );
  997. pStream->Write( MIDL_ITOA( pBuffer[Offset] & 0x00ff, Buf, 16 ) );
  998. pStream->Write( ",\t\t/* Ext Flags: ");
  999. Out_ExtProcFlags( pStream, pBuffer + Offset );
  1000. pStream->Write( " */");
  1001. Offset++;
  1002. break;
  1003. case FS_CORR_TYPE_BYTE :
  1004. pStream->Write( "0x" );
  1005. pStream->Write( MIDL_ITOA( pBuffer[Offset] & 0x00ff, Buf, 16 ) );
  1006. pStream->Write( ",\t\t/* Corr desc: ");
  1007. Out_CorrelationType( pStream, pBuffer + Offset );
  1008. pStream->Write( " */");
  1009. Offset++;
  1010. break;
  1011. case FS_CONTEXT_HANDLE_FLAG_BYTE :
  1012. pStream->Write( "0x" );
  1013. pStream->Write( MIDL_ITOA( pBuffer[Offset] & 0x00ff, Buf, 16 ) );
  1014. pStream->Write( ",\t\t/* Ctxt flags: ");
  1015. Out_ContextHandleFlags( pStream, pBuffer + Offset );
  1016. pStream->Write( " */");
  1017. Offset++;
  1018. break;
  1019. case FS_SHORT :
  1020. pStream->Write( "NdrFcShort( 0x" );
  1021. pStream->Write(
  1022. MIDL_ITOA( *((unsigned short UNALIGNED *)(pBuffer+Offset)), Buf, 16));
  1023. pStream->Write( " ),\t/* ");
  1024. pStream->Write(
  1025. MIDL_ITOA(*((short UNALIGNED *)(pBuffer+Offset)), Buf, 10));
  1026. pStream->Write( " */");
  1027. Offset += 2;
  1028. break;
  1029. case FS_MAGIC_UNION_SHORT :
  1030. pStream->Write( "NdrFcShort( 0x" );
  1031. pStream->Write(
  1032. MIDL_ITOA( *((unsigned short UNALIGNED *)(pBuffer+Offset)), Buf, 16));
  1033. pStream->Write( " ),\t/* Simple arm type: ");
  1034. pStream->Write( pFormatCharNames[ pBuffer[Offset] ]
  1035. ? pFormatCharNames[ pBuffer[Offset] ]
  1036. : "" );
  1037. pStream->Write( " */");
  1038. Offset += 2;
  1039. break;
  1040. case FS_PARAM_FLAG_SHORT :
  1041. pStream->Write( "NdrFcShort( 0x" );
  1042. pStream->Write(
  1043. MIDL_ITOA( *((unsigned short UNALIGNED *)(pBuffer + Offset)), Buf, 16));
  1044. pStream->Write( " ),\t/* Flags: ");
  1045. Out_ParameterFlags( pStream, (PARAM_ATTRIBUTES *)(pBuffer + Offset) );
  1046. pStream->Write( " */");
  1047. Offset += 2;
  1048. break;
  1049. case FS_CORR_FLAG_SHORT :
  1050. pStream->Write( "NdrFcShort( 0x" );
  1051. pStream->Write(
  1052. MIDL_ITOA( *((unsigned short UNALIGNED *)(pBuffer + Offset)), Buf, 16));
  1053. pStream->Write( " ),\t/* Corr flags: ");
  1054. Out_CorrelationFlags( pStream, pBuffer + Offset );
  1055. pStream->Write( " */");
  1056. Offset += 2;
  1057. break;
  1058. case FS_SHORT_OFFSET :
  1059. {
  1060. // The relative type offset.
  1061. TypeOffsetDictElem * pTO;
  1062. long ItsOffset;
  1063. ItsOffset = *((short UNALIGNED *)(pBuffer + Offset));
  1064. pTO = TypeOffsetDict.LookupOffset( Offset );
  1065. if ( pTO->TypeOffset != ItsOffset ||
  1066. pTO->TypeOffset < UNION_OFFSET16_MIN )
  1067. {
  1068. pStream->Write( "Relative type offset out of range" );
  1069. pStream->NewLine();
  1070. RpcError(NULL, 0, FORMAT_STRING_LIMITS, "" );
  1071. fLimitErr = TRUE;
  1072. }
  1073. if ( 0 == ( pTO->TypeOffset + Offset ) ||
  1074. -1 == ( pTO->TypeOffset + Offset ) )
  1075. {
  1076. fprintf( stdout, " MIDL_fixup: Invalid offset at %d\n", Offset );
  1077. RpcError( NULL, 0, FORMAT_STRING_OFFSET_IS_ZERO, "" );
  1078. }
  1079. pStream->Write( "NdrFcShort( 0x" );
  1080. pStream->Write( MIDL_ITOA( ItsOffset, Buf, 16 ) );
  1081. pStream->Write( " ),\t/* Offset= ");
  1082. pStream->Write( MIDL_ITOA( pTO->TypeOffset, Buf, 10 ) );
  1083. pStream->Write( " (");
  1084. pStream->Write( MIDL_ITOA( pTO->TypeOffset + Offset, Buf, 10 ) );
  1085. pStream->Write( ") */");
  1086. Offset += 2;
  1087. }
  1088. break;
  1089. case FS_SHORT_TYPE_OFFSET :
  1090. {
  1091. // The absolute type offset.
  1092. TypeOffsetDictElem * pTO;
  1093. long ItsOffset;
  1094. ItsOffset = *((unsigned short UNALIGNED *)(pBuffer + Offset));
  1095. pTO = TypeOffsetDict.LookupOffset( Offset );
  1096. if ( pTO->TypeOffset != ItsOffset )
  1097. {
  1098. pStream->Write( "Type offset out of range" );
  1099. pStream->NewLine();
  1100. RpcError(NULL, 0, FORMAT_STRING_LIMITS, "" );
  1101. fLimitErr = TRUE;
  1102. }
  1103. if ( 0 == pTO->TypeOffset || -1 == pTO->TypeOffset )
  1104. {
  1105. fprintf( stdout, " MIDL_fixup: Invalid type offset at %d\n", Offset );
  1106. RpcError( NULL, 0, TYPE_OFFSET_IS_ZERO, "" );
  1107. }
  1108. pStream->Write( "NdrFcShort( 0x" );
  1109. pStream->Write( MIDL_ITOA( ItsOffset, Buf, 16 ) );
  1110. pStream->Write( " ),\t/* Type Offset=");
  1111. pStream->Write( MIDL_ITOA( pTO->TypeOffset, Buf, 10 ) );
  1112. pStream->Write( " */");
  1113. Offset += 2;
  1114. }
  1115. break;
  1116. case FS_SHORT_STACK_OFFSET :
  1117. {
  1118. Out_ShortStackOffset( pStream,
  1119. OffsetDict.LookupOffset( Offset ),
  1120. EnvComment );
  1121. Offset += 2;
  1122. break;
  1123. }
  1124. case FS_SMALL_STACK_SIZE :
  1125. {
  1126. Out_SmallStackSize( pStream,
  1127. pBuffer[Offset],
  1128. EnvComment );
  1129. Offset++;
  1130. break;
  1131. }
  1132. case FS_LONG :
  1133. pStream->Write( "NdrFcLong( 0x" );
  1134. pStream->Write(
  1135. MIDL_LTOA( *((long UNALIGNED *)(pBuffer+Offset)), Buf, 16));
  1136. pStream->Write( " ),\t/* ");
  1137. pStream->Write(
  1138. MIDL_LTOA(*((long UNALIGNED *)(pBuffer+Offset)), Buf, 10));
  1139. pStream->Write( " */");
  1140. Offset += 4;
  1141. break;
  1142. case FS_PAD_MACRO :
  1143. if ( pPadExprDesc )
  1144. {
  1145. MIDL_ASSERT( Offset == (long)pPadExprDesc->KeyOffset );
  1146. pPadDict->WriteCurrentPadDesc( pStream );
  1147. pPadExprDesc = pPadDict->GetNext();
  1148. }
  1149. else
  1150. {
  1151. pStream->Write( "0x0,\t\t/* macro */" );
  1152. MIDL_ASSERT( 0 && "Pad macro missing" );
  1153. }
  1154. Offset++;
  1155. break;
  1156. case FS_SIZE_MACRO :
  1157. if ( pSizeDesc )
  1158. {
  1159. MIDL_ASSERT( Offset == (long)pSizeDesc->KeyOffset );
  1160. pSizeDict->WriteCurrentSizeDesc( pStream );
  1161. pSizeDesc = pSizeDict->GetNext();
  1162. }
  1163. else
  1164. {
  1165. pStream->Write( "0x0, 0x0,\t\t// macro" );
  1166. MIDL_ASSERT( 0 && "Size macro missing" );
  1167. }
  1168. Offset += 2;
  1169. break;
  1170. case FS_UNKNOWN_STACK_SIZE :
  1171. {
  1172. char * LongBuf = Buf;
  1173. long NameLen = (long) strlen(
  1174. UnknownStackSizeDict.LookupTypeName( (long) Offset ));
  1175. if ( NameLen > 25 )
  1176. LongBuf = new char[ 75 + NameLen ];
  1177. sprintf(
  1178. LongBuf,
  1179. "%s ( (sizeof(%s) + %s) & ~ (%s) ),",
  1180. "(unsigned char)",
  1181. UnknownStackSizeDict.LookupTypeName( (long) Offset ),
  1182. "sizeof(int) - 1",
  1183. "sizeof(int) - 1" );
  1184. pStream->Write( LongBuf );
  1185. }
  1186. Offset++;
  1187. break;
  1188. }
  1189. }
  1190. pStream->NewLine( 2 );
  1191. //
  1192. // Spit out a terminating 0 so we don't ever fall off the end
  1193. // of the world.
  1194. //
  1195. pStream->Write( "\t\t\t0x0" );
  1196. pStream->IndentInc();
  1197. pStream->IndentInc();
  1198. pStream->IndentInc();
  1199. pStream->IndentDec();
  1200. pStream->NewLine();
  1201. pStream->Write( '}' );
  1202. pStream->IndentDec();
  1203. pStream->NewLine();
  1204. pStream->Write( "};" );
  1205. pStream->IndentDec();
  1206. pStream->NewLine();
  1207. if ( LastOffset > _UI16_MAX )
  1208. {
  1209. pStream->Write( "Total Format String size is too big." );
  1210. pStream->NewLine();
  1211. fprintf(stdout, "Total Format String size = %d\n", LastOffset );
  1212. RpcError(NULL, 0, FORMAT_STRING_LIMITS, "" );
  1213. fLimitErr = TRUE;
  1214. }
  1215. if ( fLimitErr )
  1216. exit( FORMAT_STRING_LIMITS );
  1217. }
  1218. long
  1219. FORMAT_STRING::OptimizeFragment(
  1220. CG_NDR * pNode )
  1221. /*++
  1222. Routine Description :
  1223. Optimize a format string fragment away.
  1224. Arguments :
  1225. pNode - CG_NDR node, with format string start
  1226. and end offsets already set.
  1227. --*/
  1228. {
  1229. long StartOffset = pNode->GetFormatStringOffset();
  1230. long EndOffset = pNode->GetFormatStringEndOffset();
  1231. FRMTREG_ENTRY NewFragment( StartOffset, EndOffset );
  1232. FRMTREG_ENTRY * pOldFragment;
  1233. // perform format string optimization
  1234. #if defined(RKK_FRAG_OPT)
  1235. {
  1236. printf("Optimizing: start=%d, end=%d\n", StartOffset, EndOffset);
  1237. printf(" off str=%d ", StartOffset );
  1238. for (int off = StartOffset; off <= EndOffset; off++)
  1239. printf("%02x ", pBuffer[ off ]);
  1240. printf( "\n" );
  1241. printf(" off typ=%d ", StartOffset );
  1242. for ( off = StartOffset; off <= EndOffset; off++)
  1243. printf("%02x ", pBufferType[ off ]);
  1244. printf( "\n" );
  1245. }
  1246. #endif
  1247. if ( pCommand->IsSwitchDefined( SWITCH_NO_FMT_OPT ) )
  1248. return StartOffset;
  1249. // We attempt to optimize fragments even if they are apart by more than 32k.
  1250. MIDL_ASSERT ( EndOffset <= (long)LastOffset );
  1251. // add to dictionary
  1252. // if match found, reset format string offset back to our start
  1253. if ( GetReuseDict()->GetReUseEntry( pOldFragment, &NewFragment ) )
  1254. {
  1255. long OldStartOffset = pOldFragment->GetStartOffset();
  1256. // if we are not the end, we can't do anything about ourselves
  1257. // similarly, if we match ourselves, don't do anything
  1258. if ( ( GetCurrentOffset() == EndOffset ) &&
  1259. ( OldStartOffset != StartOffset ) )
  1260. {
  1261. // move format string offset back
  1262. SetCurrentOffset( StartOffset );
  1263. pNode->SetFormatStringOffset( OldStartOffset );
  1264. pNode->SetFormatStringEndOffset( pOldFragment->GetEndOffset() );
  1265. return OldStartOffset;
  1266. }
  1267. #if defined(RKK_FRAG_OPT)
  1268. else if ( GetCurrentOffset() != EndOffset )
  1269. {
  1270. printf( "OptimizeFragment fragment not at the end End=%d, frag End=%d\n",
  1271. GetCurrentOffset(), EndOffset );
  1272. }
  1273. #endif
  1274. } // duplicate found
  1275. return StartOffset;
  1276. }
  1277. unsigned short
  1278. FORMAT_STRING::RegisterFragment(
  1279. CG_NDR * pNode )
  1280. /*++
  1281. Routine Description :
  1282. Register, but do not remove, a format string fragment.
  1283. Arguments :
  1284. pNode - CG_NDR node, with format string start offset already set.
  1285. EndOffset - end offset of format string fragment
  1286. --*/
  1287. {
  1288. unsigned short StartOffset = (unsigned short)
  1289. pNode->GetFormatStringOffset();
  1290. unsigned short EndOffset = (unsigned short)
  1291. pNode->GetFormatStringEndOffset();
  1292. FRMTREG_ENTRY NewFragment( StartOffset, EndOffset );
  1293. FRMTREG_ENTRY * pOldFragment;
  1294. // perform format string optimization
  1295. if ( pCommand->IsSwitchDefined( SWITCH_NO_FMT_OPT ) )
  1296. return StartOffset;
  1297. MIDL_ASSERT( ( ((short) StartOffset) != -1 ) &&
  1298. ( ((short) EndOffset) != -1 ) );
  1299. MIDL_ASSERT ( EndOffset <= LastOffset );
  1300. // add to dictionary, or return pointer to old entry
  1301. GetReuseDict()->GetReUseEntry( pOldFragment, &NewFragment );
  1302. return StartOffset;
  1303. }
  1304. char *
  1305. CommentDictionary::GetComments(
  1306. long Offset
  1307. )
  1308. {
  1309. CommentDictElem Elem;
  1310. CommentDictElem * pHead;
  1311. CommentDictElem * pElem;
  1312. Dict_Status DictStatus;
  1313. char * Comments;
  1314. long Length;
  1315. Elem.FormatStringOffset = Offset;
  1316. DictStatus = Dict_Find( &Elem );
  1317. if ( DictStatus != SUCCESS )
  1318. return 0;
  1319. pHead = (CommentDictElem *) Dict_Item();
  1320. Length = 0;
  1321. for ( pElem = pHead; pElem; pElem = pElem->Next )
  1322. Length += (long) strlen( pElem->Comment );
  1323. Comments = new char[Length+1];
  1324. Comments[0] = 0;
  1325. for ( pElem = pHead; pElem; pElem = pElem->Next )
  1326. strcat( Comments, pElem->Comment );
  1327. return Comments;
  1328. }
  1329. void
  1330. CommentDictionary::Insert(
  1331. long FormatStringOffset,
  1332. char * Comment
  1333. )
  1334. {
  1335. CommentDictElem Elem;
  1336. CommentDictElem * pHead;
  1337. CommentDictElem * pElem;
  1338. Dict_Status DictStatus;
  1339. Elem.FormatStringOffset = FormatStringOffset;
  1340. DictStatus = Dict_Find( &Elem );
  1341. if ( DictStatus == SUCCESS )
  1342. pHead = (CommentDictElem *) Dict_Item();
  1343. else
  1344. pHead = 0;
  1345. pElem = new CommentDictElem;
  1346. pElem->Next = pHead;
  1347. pElem->FormatStringOffset = FormatStringOffset;
  1348. pElem->Comment = Comment;
  1349. //
  1350. // We delete any current entry and add a new entry so that comments
  1351. // are always prepended to the list.
  1352. //
  1353. if ( pHead )
  1354. Dict_Delete( (pUserType *) &pHead );
  1355. Dict_Insert( pElem );
  1356. }