Windows NT 4.0 source code leak
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.

695 lines
17 KiB

4 years ago
  1. #include <malloc.h>
  2. #include <string.h>
  3. #include "ntsdp.h"
  4. #include "types.h"
  5. #include "cvtypes.h"
  6. #include "cvinfo.h"
  7. #include "shapi.h"
  8. #include "sapi.h"
  9. #include "shiproto.h"
  10. #include "ntsapi.h"
  11. /*
  12. * Preprocessor things
  13. */
  14. LPB LpbBase;
  15. #define T_UNKNOWN T_NOTYPE
  16. #define T_TYPMAX 48
  17. #define PTR_TO(base) ( (base) + (IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT) )
  18. /*
  19. * Function Prototypes
  20. */
  21. int AccessNode(PSYMCONTEXT, PNODE); // NTSYM.C
  22. /*
  23. * Global Memory (File)
  24. */
  25. static BYTE underlines[16] = "________________";
  26. static USHORT CVtypes[T_TYPMAX] = {
  27. // Basic Types
  28. T_NOTYPE, T_VOID, T_CHAR, T_SHORT, //NULL VOID CHAR SHORT
  29. T_INT4, T_LONG, T_REAL32, T_REAL64, //INT LONG FLOAT DOUBL
  30. T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, //STRUCT UNION ENUM MOE
  31. T_UCHAR, T_USHORT, T_UINT4, T_ULONG, //UCHAR USHORT UINT ULONG
  32. // Point to Basic Type
  33. T_NOTYPE, T_32PVOID, T_32PCHAR, T_32PSHORT, //NULL VOID CHAR SHORT
  34. T_32PINT4, T_32PLONG, T_32PREAL32,T_32PREAL64,//INT LONG FLOAT DOUBL
  35. T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, //STRUCT UNION ENUM MOE
  36. T_32PUCHAR,T_32PUSHORT,T_32PUINT4, T_32PULONG, //UCHAR USHORT UINT ULONG
  37. // Function Returning
  38. T_NOTYPE, T_VOID, T_CHAR, T_SHORT, //NULL VOID CHAR SHORT
  39. T_INT4, T_LONG, T_REAL32, T_REAL64, //INT LONG FLOAT DOUBL
  40. T_INT4, T_INT4, T_INT4, T_INT4, //STRUCT UNION ENUM MOE
  41. T_UCHAR, T_USHORT, T_UINT4, T_ULONG, //UCHAR USHORT UINT ULONG
  42. };
  43. /*
  44. * Da Code
  45. */
  46. /*** FUNCNAME
  47. **
  48. ** Synopsis:
  49. ** USHORT TH_CoffToCVtype( USHORT CoffType, ULONG CoffAux,
  50. ** PIMAGE_INFO pImage);
  51. ** Entry:
  52. ** CoffType - Type according to COFF
  53. ** CoffAux - Aux Information (Structure Index)
  54. ** pImage - Image type is in (hexe)
  55. **
  56. ** Returns:
  57. ** CV4 version of the type
  58. **
  59. ** Description:
  60. ** Translates an COFF type into an CV4 type. Returns T_UNKNOWN if we
  61. ** can't translate.
  62. **
  63. */
  64. #pragma message("M00OPT - Check that we can turn back on under C7")
  65. #pragma optimize("",off)
  66. USHORT TH_CoffToCVtype( USHORT CoffType, ULONG CoffAux, PIMAGE_INFO pImage)
  67. {
  68. PSTRUCT pStruct;
  69. STRUCT Struct;
  70. int status;
  71. Unreferenced(pImage);
  72. if ( CoffType == IMAGE_SYM_TYPE_STRUCT ||
  73. CoffType == IMAGE_SYM_TYPE_UNION ||
  74. CoffType == PTR_TO(IMAGE_SYM_TYPE_STRUCT) ||
  75. CoffType == PTR_TO(IMAGE_SYM_TYPE_UNION ) ) {
  76. memset(&Struct, 0, sizeof(Struct));
  77. Struct.offset = CoffAux;
  78. Struct.string[0] = '\0';
  79. // access the structure in the tree with the specified value
  80. status = AccessNode(&(pProcessCurrent->symcontextStructOffset),
  81. &(Struct.nodeOffset));
  82. if (status) {
  83. // create temporary structure with the specified value. NOTE:
  84. // -2 IS DUE TO A CONVERTER/LINKER BUG.
  85. memset(&Struct, 0, sizeof(Struct));
  86. Struct.offset = CoffAux - 2;
  87. Struct.string[0] = 0;
  88. status = AccessNode(&(pProcessCurrent->symcontextStructOffset),
  89. &(Struct.nodeOffset));
  90. }
  91. if (!status) {
  92. pStruct = (PSTRUCT) PNODE_TO_PSYMBOL (
  93. pProcessCurrent->symcontextStructOffset.pNodeRoot,
  94. &(pProcessCurrent->symcontextStructOffset));
  95. if ( ISPTR(CoffType) )
  96. return pStruct->cvtype + (USHORT)2;
  97. else
  98. return pStruct->cvtype;
  99. }
  100. return T_UNKNOWN;
  101. }
  102. else if (CoffType < T_TYPMAX )
  103. return (USHORT)CVtypes[CoffType];
  104. else
  105. return T_UNKNOWN;
  106. }
  107. #pragma optimize("",on)
  108. /*** TH_AddBytes
  109. **
  110. ** Synopsis:
  111. ** uint = TH_AddBytes(lpbAdd, cbAdd)
  112. **
  113. ** Entry:
  114. ** lpbAdd - pointer to the bytes to be added to the types stream
  115. ** cbAdd - number of bytes to be addded to the types stream
  116. **
  117. ** Returns:
  118. ** offset from start of type info where data was written
  119. **
  120. ** Description:
  121. ** This routine is used to add bytes to the types information stream.
  122. ** If needed the allocated area which contains type information will
  123. ** be both allocated and reallocated as needed to add new data.
  124. **
  125. ** NOTE: No htypes should be given out until all symbol information
  126. ** as been read in as a realloc may cause the address in memory
  127. ** to be changed.
  128. */
  129. UINT TH_AddBytes(LPB lpbAdd, UINT cbAdd)
  130. {
  131. UINT cbT;
  132. if (LpbBase == NULL) {
  133. LpbBase = malloc(cbAdd+sizeof(long));
  134. cbT = sizeof(long);
  135. *((long *) LpbBase) = sizeof(long);
  136. } else {
  137. cbT = *((long *) LpbBase);
  138. if (_expand(LpbBase, cbT + cbAdd) == NULL) {
  139. LpbBase = realloc(LpbBase, cbT + cbAdd);
  140. }
  141. }
  142. *((long *) LpbBase) = cbT + cbAdd;
  143. memcpy(LpbBase+cbT, lpbAdd, cbAdd);
  144. return cbT;
  145. } /* TH_AddBytes() */
  146. /*** TH_AddInt
  147. **
  148. ** Synopsis:
  149. ** lpb = TH_AddInt(i)
  150. **
  151. ** Entry:
  152. ** i - the integer value to be inserted in the type info
  153. **
  154. ** Returns:
  155. ** The updated types pointer
  156. **
  157. ** Description:
  158. ** Adds an Interger to the Current Type record. If the value
  159. ** is to big for I2, puts out an LF_ULONG item, and the value
  160. ** as an I4.
  161. **
  162. */
  163. #pragma optimize("",off)
  164. UINT TH_AddUInt(UINT i)
  165. {
  166. uint ui;
  167. int j;
  168. if (i < 0x8000) {
  169. ui = TH_AddBytes((LPB) &i, 2);
  170. } else {
  171. j = LF_ULONG;
  172. TH_AddBytes((LPB) &j, 2);
  173. TH_AddBytes((LPB) &i, 4);
  174. }
  175. return ui;
  176. } /* TH_AddUInt() */
  177. #pragma optimize("",on)
  178. /*** TH_GetBase
  179. **
  180. ** Synopsis:
  181. ** LPB TH_GetBase(void)
  182. **
  183. ** Entry:
  184. **
  185. ** Returns:
  186. ** Returns the address of the base of the current type record
  187. **
  188. ** Description:
  189. ** Returns the address of the base of the current type record
  190. **
  191. */
  192. LPB TH_GetBase()
  193. {
  194. return LpbBase;
  195. } /* TH_GetBase() */
  196. /*** TH_GetOffset
  197. **
  198. ** Synopsis:
  199. ** UINT TH_GetOffset(void);
  200. **
  201. ** Entry:
  202. **
  203. ** Returns:
  204. ** The first Unsigned Int in the type record.
  205. **
  206. ** Description:
  207. ** The first Unsigned Int in the type record.
  208. **
  209. */
  210. UINT TH_GetOffset()
  211. {
  212. return *((long *) LpbBase);
  213. } /* TH_GetOffset() */
  214. /*** TH_PatchBytes
  215. **
  216. ** Synopsis:
  217. ** UINT TH_PatchBytes( LPB lpbPatch, UINT cbPatch, UINT cbOffset);
  218. **
  219. ** Entry:
  220. ** lpbPatch - Pointer to Bytes that are to be patched in
  221. ** cbPatch - Number of Bytes to patch
  222. ** cbOffset - Offset from Base to patch
  223. **
  224. ** Returns:
  225. ** The cbOffset
  226. **
  227. ** Description:
  228. ** Patchs the Type record we're currently working on. Move <cbPatch>
  229. ** bytes from <lpbPatch> to the offset <cbOffset> from the base
  230. ** of the type record
  231. **
  232. */
  233. UINT TH_PatchBytes(LPB lpbPatch, UINT cbPatch, UINT cbOffset)
  234. {
  235. memcpy(LpbBase+cbOffset, lpbPatch, cbPatch);
  236. return cbOffset;
  237. } /* TH_PatchBytes() */
  238. /*** TH_SetBase
  239. **
  240. ** Synopsis:
  241. ** VOID TH_SetBase(LPB lpb);
  242. **
  243. ** Entry:
  244. ** lpb - The address for the base of a new type record
  245. **
  246. ** Returns:
  247. **
  248. ** Description:
  249. ** Set the new base for a type record.
  250. */
  251. VOID TH_SetBase(LPB lpb)
  252. {
  253. LpbBase = lpb;
  254. return;
  255. } /* TH_SetBase() */
  256. /*** TH_SetupCVfield
  257. **
  258. ** Synopsis:
  259. ** void TH_SetupCVfield( PIMAGE_INFO pImage, PFIELD pField,
  260. ** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
  261. **
  262. ** Entry:
  263. ** pImage - Image (hexe) for the field
  264. ** pField - Pointer to the field record (hsym)
  265. ** SymbolEntry - Coff Symbol Record for the field
  266. ** AuxEntry - Coff Aux Symbol Record for the field
  267. **
  268. ** Returns:
  269. **
  270. ** Description:
  271. ** Create the CV4 type records for the field that COFF has
  272. ** just read in.
  273. **
  274. */
  275. void TH_SetupCVfield(PIMAGE_INFO pImage, PFIELD pField,
  276. IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry)
  277. {
  278. Unreferenced(AuxEntry);
  279. pField->cvkind = K_FIELD;
  280. pField->cvtype = TH_CoffToCVtype(SymbolEntry->Type,
  281. AuxEntry->Sym.TagIndex, pImage);
  282. }
  283. /*** TH_SetupCVfunction
  284. **
  285. ** Synopsis:
  286. ** void TH_SetupCVfunction( PIMAGE_INFO pImage, PSYMBOL pFunct,
  287. ** PSYMBOL pPublic);
  288. **
  289. ** Entry:
  290. ** pImage - Image (hexe) for the function
  291. ** pFunct - Pointer to the function record (hsym)
  292. ** pPublic - Pointer to the public record (hsym) for this function
  293. **
  294. ** Returns:
  295. **
  296. ** Description:
  297. ** Create the CV4 type records for the function that COFF has
  298. ** just read in.
  299. **
  300. */
  301. void TH_SetupCVfunction(PIMAGE_INFO pImage, PSYMBOL pFunct, PSYMBOL pPublic)
  302. {
  303. long i,n;
  304. USHORT cvreturn;
  305. UINT offLength;
  306. PLOCAL pLocal;
  307. TH_SetBase(NULL);
  308. pImage->rgTypeInfo = realloc( pImage->rgTypeInfo,
  309. sizeof(PUCHAR) * (pImage->TypeCount+2));
  310. pFunct->cvkind = K_PROC;
  311. pFunct->cvtype = (USHORT) (pImage->TypeCount + CV_FIRST_NONPRIM);
  312. /*
  313. * We didn't know that the previous public was a function, so save
  314. * its type (the return type) and patch the kind to KPROC and the
  315. * cvtype record to point to the one we're creating.
  316. */
  317. cvreturn = pPublic->cvtype;
  318. pPublic->cvtype = pFunct->cvtype;
  319. pPublic->cvkind = K_PROC;
  320. /*
  321. * Build the Type record
  322. */
  323. offLength = TH_AddBytes((LPB) &i, 2); // LENGTH;
  324. i = LF_PROCEDURE;
  325. TH_AddBytes((LPB) &i, 2); // LF_PROCEDURE;
  326. TH_AddBytes((LPB) &cvreturn, 2); // return type
  327. i = 0; // M00BUG (No Pascal)
  328. TH_AddBytes((LPB) &i, 1); // Calling Convection
  329. TH_AddBytes((LPB) &i, 1); // reserved
  330. n = 0;
  331. for ( pLocal=pFunct->pLocal; pLocal!=NULL; pLocal=pLocal->next)
  332. if (pLocal->value > 0) n++;
  333. TH_AddBytes((LPB) &n, 2); // # params
  334. i = pImage->TypeCount+1 + CV_FIRST_NONPRIM;
  335. TH_AddBytes((LPB) &i, 2); // arg list types
  336. /*
  337. ** Back patch length
  338. */
  339. i = TH_GetOffset() - offLength - 2;
  340. TH_PatchBytes((LPB) &i, 2, offLength);
  341. pImage->rgTypeInfo[pImage->TypeCount] = TH_GetBase();
  342. *((SHORT *)pImage->rgTypeInfo[pImage->TypeCount]) = K_TYPE;
  343. /*
  344. */
  345. TH_SetBase(NULL);
  346. TH_AddBytes((LPB) &i, 2); // LENGTH
  347. i = LF_ARGLIST;
  348. TH_AddBytes((LPB) &i, 2); // LF_ARGLIST
  349. TH_AddBytes((LPB) &n, 2); // arg count
  350. // M00BUG needs to be placed out in correct order -- assending
  351. for (pLocal=pFunct->pLocal ; pLocal != NULL; pLocal = pLocal->next) {
  352. if (pLocal->value > 0)
  353. TH_AddBytes((LPB) &pLocal->cvtype, 2);
  354. }
  355. pImage->rgTypeInfo[pImage->TypeCount+1] = TH_GetBase();
  356. *((SHORT *)pImage->rgTypeInfo[pImage->TypeCount+1]) = K_TYPE;
  357. pImage->TypeCount += 2;
  358. }
  359. /*** TH_SetupCVlocal
  360. **
  361. ** Synopsis:
  362. ** void TH_SetupCVlocal( PIMAGE_INFO pImage, PLOCAL pLocal
  363. ** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
  364. **
  365. ** Entry:
  366. ** pImage - Image (hexe) for the local
  367. ** pLocal - Pointer to the local record (hsym)
  368. ** SymbolEntry - Coff Symbol Record for the local
  369. ** AuxEntry - Coff Aux Symbol Record for the local
  370. **
  371. ** Returns:
  372. **
  373. ** Description:
  374. ** Create the CV4 type records for the local that COFF has
  375. ** just read in.
  376. **
  377. */
  378. void TH_SetupCVlocal(PIMAGE_INFO pImage, PLOCAL pLocal,
  379. IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry)
  380. {
  381. Unreferenced(AuxEntry);
  382. pLocal->cvkind = K_LOCAL;
  383. pLocal->cvtype = TH_CoffToCVtype(SymbolEntry->Type,
  384. AuxEntry->Sym.TagIndex, pImage);
  385. }
  386. /*** TH_SetupCVpublic
  387. **
  388. ** Synopsis:
  389. ** void TH_SetupCVpublic( PIMAGE_INFO pImage, PSYMBOL pSymbol,
  390. ** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
  391. **
  392. ** Entry:
  393. ** pImage - Image (hexe) for the structure
  394. ** pSymbol - Pointer to the symbol record (hsym)
  395. ** SymbolEntry - Coff Symbol Record for the symbol
  396. ** AuxEntry - Coff Aux Symbol Record for the symbol
  397. **
  398. ** Returns:
  399. **
  400. ** Description:
  401. ** Create the CV4 type records for the public that COFF has
  402. ** just read in.
  403. **
  404. */
  405. void TH_SetupCVpublic(PIMAGE_INFO pImage, PSYMBOL pSymbol,
  406. IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry)
  407. {
  408. Unreferenced(AuxEntry);
  409. pSymbol->cvkind = K_PUBLIC;
  410. pSymbol->cvtype = TH_CoffToCVtype(SymbolEntry->Type,
  411. AuxEntry->Sym.TagIndex, pImage);
  412. }
  413. /*** TH_SetupCVstruct
  414. **
  415. ** Synopsis:
  416. ** void TH_SetupCVstruct( PIMAGE_INFO pImage, PSTRUCT pStruct,
  417. ** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
  418. **
  419. ** Entry:
  420. ** pImage - Image (hexe) for the structure
  421. ** pStruct - Pointer to the Structure record (hsym)
  422. ** SymbolEntry - Coff Symbol Record for the structure
  423. ** AuxEntry - Coff Aux Symbol Record for the structure
  424. **
  425. ** Returns:
  426. **
  427. ** Description:
  428. ** Create the CV4 type records for the structure that COFF has
  429. ** just read in.
  430. **
  431. */
  432. void TH_SetupCVstruct( PIMAGE_INFO pImage, PSTRUCT pStruct,
  433. IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
  434. {
  435. long i;
  436. UINT count = 0;
  437. UINT offLength;
  438. PFIELD pField;
  439. Unreferenced(SymbolEntry);
  440. /*
  441. ** Count the number of fields in the structure
  442. */
  443. for (pField=pStruct->pField; pField != NULL; pField = pField->next)
  444. count++;
  445. /*
  446. ** Allocate and the typeinfo header for this structure
  447. */
  448. TH_SetBase(NULL);
  449. pImage->rgTypeInfo = realloc( pImage->rgTypeInfo,
  450. sizeof(PUCHAR)* (pImage->TypeCount+3));
  451. pStruct->cvkind = K_STRUCT;
  452. pStruct->cvtype = (USHORT) (pImage->TypeCount + CV_FIRST_NONPRIM);
  453. /*
  454. ** Now put out the structure record
  455. */
  456. i = 14;
  457. offLength = TH_AddBytes((LPB) &i, 2); // LENGTH
  458. i = LF_STRUCTURE;
  459. TH_AddBytes((LPB) &i, 2); // LF_STRUCTURE
  460. TH_AddBytes((LPB)&count,2); // count of fields
  461. i = pImage->TypeCount+1+CV_FIRST_NONPRIM; // field list type
  462. TH_AddBytes((LPB) &i, 2);
  463. TH_AddUInt(0); // property list
  464. TH_AddUInt(0); // derivation list
  465. TH_AddUInt(0); // VT Shape type
  466. TH_AddUInt(8*AuxEntry->Sym.Misc.TotalSize); // # bits
  467. i = pStruct->underscores + STRLEN(pStruct->string); // Length Prefix
  468. TH_AddBytes((LPB) &i, 1);
  469. TH_AddBytes((LPB)&underlines,pStruct->underscores); // Add underscores
  470. i = STRLEN(pStruct->string); // Length of name
  471. TH_AddBytes((LPB) &pStruct->string, i); // structure name
  472. i = TH_GetOffset() - offLength - 2; // Backpatch length
  473. TH_PatchBytes((LPB) &i, 2, offLength);
  474. pImage->rgTypeInfo[pImage->TypeCount] = TH_GetBase();
  475. *((SHORT *)pImage->rgTypeInfo[pImage->TypeCount]) = K_TYPE;
  476. /*
  477. ** Now write out the field list record
  478. */
  479. TH_SetBase(NULL);
  480. offLength = TH_AddBytes((LPB) &i, 2); // LENGTH
  481. i = LF_FIELDLIST;
  482. TH_AddBytes((LPB) &i, 2); // LF_FIELDLIST
  483. for (pField=pStruct->pField; pField != NULL; pField = pField->next) {
  484. i = LF_MEMBER; // LF_MEMBER
  485. TH_AddBytes((LPB) &i, 2);
  486. TH_AddBytes((LPB) &(pField->cvtype), 2);// type
  487. TH_AddUInt(0); // attributes
  488. TH_AddUInt(pField->value); // offset
  489. i = strlen(pField->pszFieldName);
  490. TH_AddBytes((LPB) &i, 1); // Length prefix name
  491. TH_AddBytes(&(pField->pszFieldName[0]), i);
  492. }
  493. i = TH_GetOffset() - offLength - 2; // Backpatch the length
  494. TH_PatchBytes((LPB) &i, 2, offLength); // Get the base and type
  495. pImage->rgTypeInfo[pImage->TypeCount+1] = TH_GetBase();
  496. *((SHORT *)pImage->rgTypeInfo[pImage->TypeCount+1]) = K_TYPE;
  497. /*
  498. ** Now write out the pointer to record
  499. */
  500. TH_SetBase(NULL);
  501. offLength = TH_AddBytes((LPB) &i, 2); // LENGTH
  502. i = LF_POINTER;
  503. TH_AddBytes((LPB) &i, 2); // LF_POINTER
  504. TH_AddUInt(0x10a); // attributes (isflag32)
  505. i = pImage->TypeCount + CV_FIRST_NONPRIM; // The base cvtype
  506. TH_AddBytes((LPB) &i, 2);
  507. i = TH_GetOffset() - offLength - 2; // Backpatch the length
  508. TH_PatchBytes((LPB) &i, 2, offLength);
  509. pImage->rgTypeInfo[pImage->TypeCount+2] = TH_GetBase();
  510. *((SHORT *)pImage->rgTypeInfo[pImage->TypeCount+2]) = K_TYPE;
  511. /*
  512. */
  513. pImage->TypeCount += 3;
  514. }
  515. /*** THGetTypeFromIndex
  516. **
  517. ** Synopsis:
  518. ** HTYPE THGetTypeFromIndex ( HMOD hmod, THIDX index );
  519. **
  520. ** Entry:
  521. ** hmod - The Module the type index is located in
  522. ** index - The Index we want a type record for.
  523. **
  524. ** Returns:
  525. ** Handle to a type record or NULL if not found.
  526. **
  527. ** Description:
  528. ** Given a module and a type index, return a handle to the
  529. ** type record or NULL if not found.
  530. **
  531. */
  532. HTYPE LOADDS PASCAL THGetTypeFromIndex ( HMOD hmod, THIDX index ) {
  533. HTYPE htype = (HTYPE)NULL;
  534. if ( hmod ) {
  535. HEXE hexe = SHHexeFromHmod ( hmod );
  536. PIMAGE_INFO pImage = (PIMAGE_INFO) hexe;
  537. assert(pImage);
  538. if ( !CV_IS_PRIMITIVE (index) && (pImage->rgTypeInfo != NULL)) {
  539. // adjust the pointer to an internal index
  540. index -= CV_FIRST_NONPRIM;
  541. // if type is in range, return it
  542. if( index < pImage->TypeCount ) {
  543. // load the lookup table, get the ems pointer to the type
  544. htype = (HTYPE) (pImage->rgTypeInfo[index]);
  545. }
  546. }
  547. }
  548. return htype;
  549. }
  550. /*** THGetNextType
  551. **
  552. ** Synopsis:
  553. ** HTYPE THGetNextType( HMODE hmod, HTYPE hType);
  554. **
  555. ** Entry:
  556. ** hmod - Not Referenced
  557. ** hType - Not Referenced
  558. **
  559. ** Returns:
  560. ** Returns NULL always
  561. **
  562. ** Description:
  563. ** Routine stubbed out for now.
  564. **
  565. */
  566. HTYPE LOADDS PASCAL THGetNextType ( HMOD hmod, HTYPE hType ) {
  567. Unreferenced( hmod );
  568. Unreferenced( hType );
  569. return((HTYPE) NULL);
  570. }