696 lines
17 KiB
C
696 lines
17 KiB
C
#include <malloc.h>
|
||
#include <string.h>
|
||
|
||
#include "ntsdp.h"
|
||
#include "types.h"
|
||
#include "cvtypes.h"
|
||
#include "cvinfo.h"
|
||
#include "shapi.h"
|
||
#include "sapi.h"
|
||
#include "shiproto.h"
|
||
#include "ntsapi.h"
|
||
|
||
/*
|
||
* Preprocessor things
|
||
*/
|
||
|
||
LPB LpbBase;
|
||
|
||
#define T_UNKNOWN T_NOTYPE
|
||
#define T_TYPMAX 48
|
||
|
||
#define PTR_TO(base) ( (base) + (IMAGE_SYM_DTYPE_POINTER<<N_BTSHFT) )
|
||
|
||
/*
|
||
* Function Prototypes
|
||
*/
|
||
|
||
int AccessNode(PSYMCONTEXT, PNODE); // NTSYM.C
|
||
|
||
/*
|
||
* Global Memory (File)
|
||
*/
|
||
|
||
static BYTE underlines[16] = "________________";
|
||
|
||
static USHORT CVtypes[T_TYPMAX] = {
|
||
|
||
// Basic Types
|
||
|
||
T_NOTYPE, T_VOID, T_CHAR, T_SHORT, //NULL VOID CHAR SHORT
|
||
T_INT4, T_LONG, T_REAL32, T_REAL64, //INT LONG FLOAT DOUBL
|
||
T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, //STRUCT UNION ENUM MOE
|
||
T_UCHAR, T_USHORT, T_UINT4, T_ULONG, //UCHAR USHORT UINT ULONG
|
||
|
||
// Point to Basic Type
|
||
|
||
T_NOTYPE, T_32PVOID, T_32PCHAR, T_32PSHORT, //NULL VOID CHAR SHORT
|
||
T_32PINT4, T_32PLONG, T_32PREAL32,T_32PREAL64,//INT LONG FLOAT DOUBL
|
||
T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, T_UNKNOWN, //STRUCT UNION ENUM MOE
|
||
T_32PUCHAR,T_32PUSHORT,T_32PUINT4, T_32PULONG, //UCHAR USHORT UINT ULONG
|
||
|
||
// Function Returning
|
||
|
||
T_NOTYPE, T_VOID, T_CHAR, T_SHORT, //NULL VOID CHAR SHORT
|
||
T_INT4, T_LONG, T_REAL32, T_REAL64, //INT LONG FLOAT DOUBL
|
||
T_INT4, T_INT4, T_INT4, T_INT4, //STRUCT UNION ENUM MOE
|
||
T_UCHAR, T_USHORT, T_UINT4, T_ULONG, //UCHAR USHORT UINT ULONG
|
||
};
|
||
|
||
|
||
/*
|
||
* Da Code
|
||
*/
|
||
|
||
|
||
/*** FUNCNAME
|
||
**
|
||
** Synopsis:
|
||
** USHORT TH_CoffToCVtype( USHORT CoffType, ULONG CoffAux,
|
||
** PIMAGE_INFO pImage);
|
||
** Entry:
|
||
** CoffType - Type according to COFF
|
||
** CoffAux - Aux Information (Structure Index)
|
||
** pImage - Image type is in (hexe)
|
||
**
|
||
** Returns:
|
||
** CV4 version of the type
|
||
**
|
||
** Description:
|
||
** Translates an COFF type into an CV4 type. Returns T_UNKNOWN if we
|
||
** can't translate.
|
||
**
|
||
*/
|
||
|
||
#pragma message("M00OPT - Check that we can turn back on under C7")
|
||
#pragma optimize("",off)
|
||
USHORT TH_CoffToCVtype( USHORT CoffType, ULONG CoffAux, PIMAGE_INFO pImage)
|
||
{
|
||
PSTRUCT pStruct;
|
||
STRUCT Struct;
|
||
int status;
|
||
|
||
Unreferenced(pImage);
|
||
|
||
if ( CoffType == IMAGE_SYM_TYPE_STRUCT ||
|
||
CoffType == IMAGE_SYM_TYPE_UNION ||
|
||
CoffType == PTR_TO(IMAGE_SYM_TYPE_STRUCT) ||
|
||
CoffType == PTR_TO(IMAGE_SYM_TYPE_UNION ) ) {
|
||
|
||
memset(&Struct, 0, sizeof(Struct));
|
||
Struct.offset = CoffAux;
|
||
Struct.string[0] = '\0';
|
||
|
||
// access the structure in the tree with the specified value
|
||
|
||
status = AccessNode(&(pProcessCurrent->symcontextStructOffset),
|
||
&(Struct.nodeOffset));
|
||
if (status) {
|
||
// create temporary structure with the specified value. NOTE:
|
||
// -2 IS DUE TO A CONVERTER/LINKER BUG.
|
||
|
||
memset(&Struct, 0, sizeof(Struct));
|
||
Struct.offset = CoffAux - 2;
|
||
Struct.string[0] = 0;
|
||
|
||
status = AccessNode(&(pProcessCurrent->symcontextStructOffset),
|
||
&(Struct.nodeOffset));
|
||
}
|
||
|
||
if (!status) {
|
||
pStruct = (PSTRUCT) PNODE_TO_PSYMBOL (
|
||
pProcessCurrent->symcontextStructOffset.pNodeRoot,
|
||
&(pProcessCurrent->symcontextStructOffset));
|
||
|
||
if ( ISPTR(CoffType) )
|
||
return pStruct->cvtype + (USHORT)2;
|
||
else
|
||
return pStruct->cvtype;
|
||
}
|
||
return T_UNKNOWN;
|
||
|
||
}
|
||
|
||
else if (CoffType < T_TYPMAX )
|
||
|
||
return (USHORT)CVtypes[CoffType];
|
||
|
||
|
||
else
|
||
return T_UNKNOWN;
|
||
}
|
||
#pragma optimize("",on)
|
||
|
||
|
||
|
||
/*** TH_AddBytes
|
||
**
|
||
** Synopsis:
|
||
** uint = TH_AddBytes(lpbAdd, cbAdd)
|
||
**
|
||
** Entry:
|
||
** lpbAdd - pointer to the bytes to be added to the types stream
|
||
** cbAdd - number of bytes to be addded to the types stream
|
||
**
|
||
** Returns:
|
||
** offset from start of type info where data was written
|
||
**
|
||
** Description:
|
||
** This routine is used to add bytes to the types information stream.
|
||
** If needed the allocated area which contains type information will
|
||
** be both allocated and reallocated as needed to add new data.
|
||
**
|
||
** NOTE: No htypes should be given out until all symbol information
|
||
** as been read in as a realloc may cause the address in memory
|
||
** to be changed.
|
||
*/
|
||
|
||
UINT TH_AddBytes(LPB lpbAdd, UINT cbAdd)
|
||
{
|
||
UINT cbT;
|
||
|
||
if (LpbBase == NULL) {
|
||
LpbBase = malloc(cbAdd+sizeof(long));
|
||
cbT = sizeof(long);
|
||
*((long *) LpbBase) = sizeof(long);
|
||
} else {
|
||
cbT = *((long *) LpbBase);
|
||
if (_expand(LpbBase, cbT + cbAdd) == NULL) {
|
||
LpbBase = realloc(LpbBase, cbT + cbAdd);
|
||
}
|
||
}
|
||
|
||
*((long *) LpbBase) = cbT + cbAdd;
|
||
memcpy(LpbBase+cbT, lpbAdd, cbAdd);
|
||
return cbT;
|
||
} /* TH_AddBytes() */
|
||
|
||
|
||
|
||
/*** TH_AddInt
|
||
**
|
||
** Synopsis:
|
||
** lpb = TH_AddInt(i)
|
||
**
|
||
** Entry:
|
||
** i - the integer value to be inserted in the type info
|
||
**
|
||
** Returns:
|
||
** The updated types pointer
|
||
**
|
||
** Description:
|
||
** Adds an Interger to the Current Type record. If the value
|
||
** is to big for I2, puts out an LF_ULONG item, and the value
|
||
** as an I4.
|
||
**
|
||
*/
|
||
|
||
#pragma optimize("",off)
|
||
UINT TH_AddUInt(UINT i)
|
||
{
|
||
uint ui;
|
||
int j;
|
||
|
||
if (i < 0x8000) {
|
||
ui = TH_AddBytes((LPB) &i, 2);
|
||
} else {
|
||
j = LF_ULONG;
|
||
TH_AddBytes((LPB) &j, 2);
|
||
TH_AddBytes((LPB) &i, 4);
|
||
}
|
||
return ui;
|
||
} /* TH_AddUInt() */
|
||
#pragma optimize("",on)
|
||
|
||
/*** TH_GetBase
|
||
**
|
||
** Synopsis:
|
||
** LPB TH_GetBase(void)
|
||
**
|
||
** Entry:
|
||
**
|
||
** Returns:
|
||
** Returns the address of the base of the current type record
|
||
**
|
||
** Description:
|
||
** Returns the address of the base of the current type record
|
||
**
|
||
*/
|
||
|
||
LPB TH_GetBase()
|
||
{
|
||
return LpbBase;
|
||
} /* TH_GetBase() */
|
||
|
||
|
||
/*** TH_GetOffset
|
||
**
|
||
** Synopsis:
|
||
** UINT TH_GetOffset(void);
|
||
**
|
||
** Entry:
|
||
**
|
||
** Returns:
|
||
** The first Unsigned Int in the type record.
|
||
**
|
||
** Description:
|
||
** The first Unsigned Int in the type record.
|
||
**
|
||
*/
|
||
|
||
UINT TH_GetOffset()
|
||
{
|
||
return *((long *) LpbBase);
|
||
} /* TH_GetOffset() */
|
||
|
||
|
||
/*** TH_PatchBytes
|
||
**
|
||
** Synopsis:
|
||
** UINT TH_PatchBytes( LPB lpbPatch, UINT cbPatch, UINT cbOffset);
|
||
**
|
||
** Entry:
|
||
** lpbPatch - Pointer to Bytes that are to be patched in
|
||
** cbPatch - Number of Bytes to patch
|
||
** cbOffset - Offset from Base to patch
|
||
**
|
||
** Returns:
|
||
** The cbOffset
|
||
**
|
||
** Description:
|
||
** Patchs the Type record we're currently working on. Move <cbPatch>
|
||
** bytes from <lpbPatch> to the offset <cbOffset> from the base
|
||
** of the type record
|
||
**
|
||
*/
|
||
|
||
UINT TH_PatchBytes(LPB lpbPatch, UINT cbPatch, UINT cbOffset)
|
||
{
|
||
memcpy(LpbBase+cbOffset, lpbPatch, cbPatch);
|
||
return cbOffset;
|
||
} /* TH_PatchBytes() */
|
||
|
||
|
||
/*** TH_SetBase
|
||
**
|
||
** Synopsis:
|
||
** VOID TH_SetBase(LPB lpb);
|
||
**
|
||
** Entry:
|
||
** lpb - The address for the base of a new type record
|
||
**
|
||
** Returns:
|
||
**
|
||
** Description:
|
||
** Set the new base for a type record.
|
||
*/
|
||
|
||
VOID TH_SetBase(LPB lpb)
|
||
{
|
||
LpbBase = lpb;
|
||
return;
|
||
} /* TH_SetBase() */
|
||
|
||
|
||
/*** TH_SetupCVfield
|
||
**
|
||
** Synopsis:
|
||
** void TH_SetupCVfield( PIMAGE_INFO pImage, PFIELD pField,
|
||
** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
|
||
**
|
||
** Entry:
|
||
** pImage - Image (hexe) for the field
|
||
** pField - Pointer to the field record (hsym)
|
||
** SymbolEntry - Coff Symbol Record for the field
|
||
** AuxEntry - Coff Aux Symbol Record for the field
|
||
**
|
||
** Returns:
|
||
**
|
||
** Description:
|
||
** Create the CV4 type records for the field that COFF has
|
||
** just read in.
|
||
**
|
||
*/
|
||
|
||
void TH_SetupCVfield(PIMAGE_INFO pImage, PFIELD pField,
|
||
IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry)
|
||
{
|
||
Unreferenced(AuxEntry);
|
||
pField->cvkind = K_FIELD;
|
||
pField->cvtype = TH_CoffToCVtype(SymbolEntry->Type,
|
||
AuxEntry->Sym.TagIndex, pImage);
|
||
}
|
||
|
||
|
||
/*** TH_SetupCVfunction
|
||
**
|
||
** Synopsis:
|
||
** void TH_SetupCVfunction( PIMAGE_INFO pImage, PSYMBOL pFunct,
|
||
** PSYMBOL pPublic);
|
||
**
|
||
** Entry:
|
||
** pImage - Image (hexe) for the function
|
||
** pFunct - Pointer to the function record (hsym)
|
||
** pPublic - Pointer to the public record (hsym) for this function
|
||
**
|
||
** Returns:
|
||
**
|
||
** Description:
|
||
** Create the CV4 type records for the function that COFF has
|
||
** just read in.
|
||
**
|
||
*/
|
||
|
||
void TH_SetupCVfunction(PIMAGE_INFO pImage, PSYMBOL pFunct, PSYMBOL pPublic)
|
||
{
|
||
long i,n;
|
||
USHORT cvreturn;
|
||
UINT offLength;
|
||
PLOCAL pLocal;
|
||
|
||
TH_SetBase(NULL);
|
||
|
||
pImage->rgTypeInfo = realloc( pImage->rgTypeInfo,
|
||
sizeof(PUCHAR) * (pImage->TypeCount+2));
|
||
|
||
pFunct->cvkind = K_PROC;
|
||
pFunct->cvtype = (USHORT) (pImage->TypeCount + CV_FIRST_NONPRIM);
|
||
|
||
/*
|
||
* We didn't know that the previous public was a function, so save
|
||
* its type (the return type) and patch the kind to KPROC and the
|
||
* cvtype record to point to the one we're creating.
|
||
*/
|
||
cvreturn = pPublic->cvtype;
|
||
pPublic->cvtype = pFunct->cvtype;
|
||
pPublic->cvkind = K_PROC;
|
||
|
||
/*
|
||
* Build the Type record
|
||
*/
|
||
|
||
offLength = TH_AddBytes((LPB) &i, 2); // LENGTH;
|
||
i = LF_PROCEDURE;
|
||
TH_AddBytes((LPB) &i, 2); // LF_PROCEDURE;
|
||
TH_AddBytes((LPB) &cvreturn, 2); // return type
|
||
|
||
i = 0; // M00BUG (No Pascal)
|
||
TH_AddBytes((LPB) &i, 1); // Calling Convection
|
||
TH_AddBytes((LPB) &i, 1); // reserved
|
||
|
||
n = 0;
|
||
for ( pLocal=pFunct->pLocal; pLocal!=NULL; pLocal=pLocal->next)
|
||
if (pLocal->value > 0) n++;
|
||
TH_AddBytes((LPB) &n, 2); // # params
|
||
|
||
i = pImage->TypeCount+1 + CV_FIRST_NONPRIM;
|
||
TH_AddBytes((LPB) &i, 2); // arg list types
|
||
|
||
/*
|
||
** Back patch length
|
||
*/
|
||
|
||
i = TH_GetOffset() - offLength - 2;
|
||
TH_PatchBytes((LPB) &i, 2, offLength);
|
||
|
||
pImage->rgTypeInfo[pImage->TypeCount] = TH_GetBase();
|
||
*((SHORT *)pImage->rgTypeInfo[pImage->TypeCount]) = K_TYPE;
|
||
|
||
/*
|
||
*/
|
||
|
||
TH_SetBase(NULL);
|
||
|
||
TH_AddBytes((LPB) &i, 2); // LENGTH
|
||
i = LF_ARGLIST;
|
||
TH_AddBytes((LPB) &i, 2); // LF_ARGLIST
|
||
TH_AddBytes((LPB) &n, 2); // arg count
|
||
|
||
// M00BUG needs to be placed out in correct order -- assending
|
||
|
||
for (pLocal=pFunct->pLocal ; pLocal != NULL; pLocal = pLocal->next) {
|
||
if (pLocal->value > 0)
|
||
TH_AddBytes((LPB) &pLocal->cvtype, 2);
|
||
}
|
||
|
||
pImage->rgTypeInfo[pImage->TypeCount+1] = TH_GetBase();
|
||
*((SHORT *)pImage->rgTypeInfo[pImage->TypeCount+1]) = K_TYPE;
|
||
|
||
pImage->TypeCount += 2;
|
||
}
|
||
|
||
|
||
|
||
/*** TH_SetupCVlocal
|
||
**
|
||
** Synopsis:
|
||
** void TH_SetupCVlocal( PIMAGE_INFO pImage, PLOCAL pLocal
|
||
** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
|
||
**
|
||
** Entry:
|
||
** pImage - Image (hexe) for the local
|
||
** pLocal - Pointer to the local record (hsym)
|
||
** SymbolEntry - Coff Symbol Record for the local
|
||
** AuxEntry - Coff Aux Symbol Record for the local
|
||
**
|
||
** Returns:
|
||
**
|
||
** Description:
|
||
** Create the CV4 type records for the local that COFF has
|
||
** just read in.
|
||
**
|
||
*/
|
||
|
||
void TH_SetupCVlocal(PIMAGE_INFO pImage, PLOCAL pLocal,
|
||
IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry)
|
||
|
||
{
|
||
Unreferenced(AuxEntry);
|
||
pLocal->cvkind = K_LOCAL;
|
||
pLocal->cvtype = TH_CoffToCVtype(SymbolEntry->Type,
|
||
AuxEntry->Sym.TagIndex, pImage);
|
||
}
|
||
|
||
|
||
/*** TH_SetupCVpublic
|
||
**
|
||
** Synopsis:
|
||
** void TH_SetupCVpublic( PIMAGE_INFO pImage, PSYMBOL pSymbol,
|
||
** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
|
||
**
|
||
** Entry:
|
||
** pImage - Image (hexe) for the structure
|
||
** pSymbol - Pointer to the symbol record (hsym)
|
||
** SymbolEntry - Coff Symbol Record for the symbol
|
||
** AuxEntry - Coff Aux Symbol Record for the symbol
|
||
**
|
||
** Returns:
|
||
**
|
||
** Description:
|
||
** Create the CV4 type records for the public that COFF has
|
||
** just read in.
|
||
**
|
||
*/
|
||
|
||
void TH_SetupCVpublic(PIMAGE_INFO pImage, PSYMBOL pSymbol,
|
||
IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry)
|
||
{
|
||
Unreferenced(AuxEntry);
|
||
pSymbol->cvkind = K_PUBLIC;
|
||
pSymbol->cvtype = TH_CoffToCVtype(SymbolEntry->Type,
|
||
AuxEntry->Sym.TagIndex, pImage);
|
||
}
|
||
|
||
|
||
/*** TH_SetupCVstruct
|
||
**
|
||
** Synopsis:
|
||
** void TH_SetupCVstruct( PIMAGE_INFO pImage, PSTRUCT pStruct,
|
||
** IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
|
||
**
|
||
** Entry:
|
||
** pImage - Image (hexe) for the structure
|
||
** pStruct - Pointer to the Structure record (hsym)
|
||
** SymbolEntry - Coff Symbol Record for the structure
|
||
** AuxEntry - Coff Aux Symbol Record for the structure
|
||
**
|
||
** Returns:
|
||
**
|
||
** Description:
|
||
** Create the CV4 type records for the structure that COFF has
|
||
** just read in.
|
||
**
|
||
*/
|
||
|
||
void TH_SetupCVstruct( PIMAGE_INFO pImage, PSTRUCT pStruct,
|
||
IMAGE_SYMBOL * SymbolEntry, IMAGE_AUX_SYMBOL *AuxEntry )
|
||
{
|
||
long i;
|
||
UINT count = 0;
|
||
UINT offLength;
|
||
PFIELD pField;
|
||
|
||
Unreferenced(SymbolEntry);
|
||
|
||
/*
|
||
** Count the number of fields in the structure
|
||
*/
|
||
|
||
for (pField=pStruct->pField; pField != NULL; pField = pField->next)
|
||
count++;
|
||
|
||
/*
|
||
** Allocate and the typeinfo header for this structure
|
||
*/
|
||
|
||
TH_SetBase(NULL);
|
||
pImage->rgTypeInfo = realloc( pImage->rgTypeInfo,
|
||
sizeof(PUCHAR)* (pImage->TypeCount+3));
|
||
pStruct->cvkind = K_STRUCT;
|
||
pStruct->cvtype = (USHORT) (pImage->TypeCount + CV_FIRST_NONPRIM);
|
||
|
||
/*
|
||
** Now put out the structure record
|
||
*/
|
||
|
||
i = 14;
|
||
offLength = TH_AddBytes((LPB) &i, 2); // LENGTH
|
||
i = LF_STRUCTURE;
|
||
TH_AddBytes((LPB) &i, 2); // LF_STRUCTURE
|
||
TH_AddBytes((LPB)&count,2); // count of fields
|
||
i = pImage->TypeCount+1+CV_FIRST_NONPRIM; // field list type
|
||
TH_AddBytes((LPB) &i, 2);
|
||
TH_AddUInt(0); // property list
|
||
TH_AddUInt(0); // derivation list
|
||
TH_AddUInt(0); // VT Shape type
|
||
TH_AddUInt(8*AuxEntry->Sym.Misc.TotalSize); // # bits
|
||
|
||
i = pStruct->underscores + STRLEN(pStruct->string); // Length Prefix
|
||
TH_AddBytes((LPB) &i, 1);
|
||
TH_AddBytes((LPB)&underlines,pStruct->underscores); // Add underscores
|
||
i = STRLEN(pStruct->string); // Length of name
|
||
TH_AddBytes((LPB) &pStruct->string, i); // structure name
|
||
|
||
i = TH_GetOffset() - offLength - 2; // Backpatch length
|
||
TH_PatchBytes((LPB) &i, 2, offLength);
|
||
pImage->rgTypeInfo[pImage->TypeCount] = TH_GetBase();
|
||
*((SHORT *)pImage->rgTypeInfo[pImage->TypeCount]) = K_TYPE;
|
||
|
||
/*
|
||
** Now write out the field list record
|
||
*/
|
||
|
||
TH_SetBase(NULL);
|
||
offLength = TH_AddBytes((LPB) &i, 2); // LENGTH
|
||
i = LF_FIELDLIST;
|
||
TH_AddBytes((LPB) &i, 2); // LF_FIELDLIST
|
||
|
||
for (pField=pStruct->pField; pField != NULL; pField = pField->next) {
|
||
i = LF_MEMBER; // LF_MEMBER
|
||
TH_AddBytes((LPB) &i, 2);
|
||
TH_AddBytes((LPB) &(pField->cvtype), 2);// type
|
||
TH_AddUInt(0); // attributes
|
||
TH_AddUInt(pField->value); // offset
|
||
i = strlen(pField->pszFieldName);
|
||
TH_AddBytes((LPB) &i, 1); // Length prefix name
|
||
TH_AddBytes(&(pField->pszFieldName[0]), i);
|
||
}
|
||
|
||
i = TH_GetOffset() - offLength - 2; // Backpatch the length
|
||
TH_PatchBytes((LPB) &i, 2, offLength); // Get the base and type
|
||
pImage->rgTypeInfo[pImage->TypeCount+1] = TH_GetBase();
|
||
*((SHORT *)pImage->rgTypeInfo[pImage->TypeCount+1]) = K_TYPE;
|
||
|
||
/*
|
||
** Now write out the pointer to record
|
||
*/
|
||
|
||
TH_SetBase(NULL);
|
||
offLength = TH_AddBytes((LPB) &i, 2); // LENGTH
|
||
i = LF_POINTER;
|
||
TH_AddBytes((LPB) &i, 2); // LF_POINTER
|
||
TH_AddUInt(0x10a); // attributes (isflag32)
|
||
i = pImage->TypeCount + CV_FIRST_NONPRIM; // The base cvtype
|
||
TH_AddBytes((LPB) &i, 2);
|
||
|
||
i = TH_GetOffset() - offLength - 2; // Backpatch the length
|
||
TH_PatchBytes((LPB) &i, 2, offLength);
|
||
pImage->rgTypeInfo[pImage->TypeCount+2] = TH_GetBase();
|
||
*((SHORT *)pImage->rgTypeInfo[pImage->TypeCount+2]) = K_TYPE;
|
||
|
||
/*
|
||
*/
|
||
|
||
pImage->TypeCount += 3;
|
||
}
|
||
|
||
|
||
/*** THGetTypeFromIndex
|
||
**
|
||
** Synopsis:
|
||
** HTYPE THGetTypeFromIndex ( HMOD hmod, THIDX index );
|
||
**
|
||
** Entry:
|
||
** hmod - The Module the type index is located in
|
||
** index - The Index we want a type record for.
|
||
**
|
||
** Returns:
|
||
** Handle to a type record or NULL if not found.
|
||
**
|
||
** Description:
|
||
** Given a module and a type index, return a handle to the
|
||
** type record or NULL if not found.
|
||
**
|
||
*/
|
||
|
||
HTYPE LOADDS PASCAL THGetTypeFromIndex ( HMOD hmod, THIDX index ) {
|
||
HTYPE htype = (HTYPE)NULL;
|
||
|
||
if ( hmod ) {
|
||
HEXE hexe = SHHexeFromHmod ( hmod );
|
||
PIMAGE_INFO pImage = (PIMAGE_INFO) hexe;
|
||
|
||
assert(pImage);
|
||
|
||
if ( !CV_IS_PRIMITIVE (index) && (pImage->rgTypeInfo != NULL)) {
|
||
|
||
// adjust the pointer to an internal index
|
||
|
||
index -= CV_FIRST_NONPRIM;
|
||
|
||
// if type is in range, return it
|
||
|
||
if( index < pImage->TypeCount ) {
|
||
// load the lookup table, get the ems pointer to the type
|
||
|
||
htype = (HTYPE) (pImage->rgTypeInfo[index]);
|
||
}
|
||
}
|
||
}
|
||
return htype;
|
||
}
|
||
|
||
|
||
/*** THGetNextType
|
||
**
|
||
** Synopsis:
|
||
** HTYPE THGetNextType( HMODE hmod, HTYPE hType);
|
||
**
|
||
** Entry:
|
||
** hmod - Not Referenced
|
||
** hType - Not Referenced
|
||
**
|
||
** Returns:
|
||
** Returns NULL always
|
||
**
|
||
** Description:
|
||
** Routine stubbed out for now.
|
||
**
|
||
*/
|
||
|
||
HTYPE LOADDS PASCAL THGetNextType ( HMOD hmod, HTYPE hType ) {
|
||
Unreferenced( hmod );
|
||
Unreferenced( hType );
|
||
return((HTYPE) NULL);
|
||
}
|