Fixed byte order problems in typelib loading code
Gregg Mattinson
gm138242 at scot.canada.sun.com
Wed Jun 19 15:15:17 CDT 2002
Changelog: dlls/oleaut32/typelib.c dlls/oleaut32/typelib.h
- Patched to allow big endian machines to load MSFT typelib files.
- Tested with atl.tlb (which was compiled on Windows) and atl.dll can be
registered now.
I did not touch the SLTG portion of typelib.c, so that code is still broken.
Gregg Mattinson
Co-op Developer
Sun Microsystems of Canada
-------------- next part --------------
*** wine-20020605/dlls/oleaut32/typelib.c Wed Jun 19 15:20:11 2002
--- wine/dlls/oleaut32/typelib.c Wed Jun 19 10:48:49 2002
***************
*** 76,81 ****
--- 76,146 ----
WINE_DECLARE_DEBUG_CHANNEL(typelib);
/****************************************************************************
+ * FromLExxx
+ *
+ * Takes p_iVal (which is in little endian) and returns it
+ * in the host machine's byte order.
+ */
+ #ifdef WORDS_BIGENDIAN
+ static WORD FromLEWord(WORD p_iVal)
+ {
+ return (((p_iVal & 0x00FF) << 8) |
+ ((p_iVal & 0xFF00) >> 8));
+ }
+
+
+ static DWORD FromLEDWord(DWORD p_iVal)
+ {
+ return (((p_iVal & 0x000000FF) << 24) |
+ ((p_iVal & 0x0000FF00) << 8) |
+ ((p_iVal & 0x00FF0000) >> 8) |
+ ((p_iVal & 0xFF000000) >> 24));
+ }
+ #else
+ #define FromLEWord(X) (X)
+ #define FromLEDWord(X) (X)
+ #endif
+
+
+ /****************************************************************************
+ * FromLExxx
+ *
+ * Fix byte order in any structure if necessary
+ */
+ #ifdef WORDS_BIGENDIAN
+ static void FromLEWords(void *p_Val, int p_iSize)
+ {
+ WORD *Val = p_Val;
+
+ p_iSize /= sizeof(WORD);
+
+ while (p_iSize) {
+ *Val = FromLEWord(*Val);
+ Val++;
+ p_iSize--;
+ }
+ }
+
+
+ static void FromLEDWords(void *p_Val, int p_iSize)
+ {
+ DWORD *Val = p_Val;
+
+ p_iSize /= sizeof(DWORD);
+
+ while (p_iSize) {
+ *Val = FromLEDWord(*Val);
+ Val++;
+ p_iSize--;
+ }
+ }
+ #else
+ #define FromLEWords(X,Y) (X,Y)
+ #define FromLEDWords(X,Y) (X,Y)
+ #endif
+
+
+ /****************************************************************************
* QueryPathOfRegTypeLib [TYPELIB.14]
*
* the path is "Classes\Typelib\<guid>\<major>.<minor>\<lcid>\win16\"
***************
*** 1163,1177 ****
--- 1228,1266 ----
return count;
}
+ static DWORD MSFT_ReadLEDWords(void *buffer, DWORD count, TLBContext *pcx,
+ long where )
+ {
+ DWORD ret;
+
+ ret = MSFT_Read(buffer, count, pcx, where);
+ FromLEDWords(buffer, ret);
+
+ return ret;
+ }
+
+ static DWORD MSFT_ReadLEWords(void *buffer, DWORD count, TLBContext *pcx,
+ long where )
+ {
+ DWORD ret;
+
+ ret = MSFT_Read(buffer, count, pcx, where);
+ FromLEWords(buffer, ret);
+
+ return ret;
+ }
+
static void MSFT_ReadGuid( GUID *pGuid, int offset, TLBContext *pcx)
{
- TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
if(offset<0 || pcx->pTblDir->pGuidTab.offset <0){
memset(pGuid,0, sizeof(GUID));
return;
}
MSFT_Read(pGuid, sizeof(GUID), pcx, pcx->pTblDir->pGuidTab.offset+offset );
+ pGuid->Data1 = FromLEDWord(pGuid->Data1);
+ pGuid->Data2 = FromLEWord(pGuid->Data2);
+ pGuid->Data3 = FromLEWord(pGuid->Data3);
+ TRACE_(typelib)("%s\n", debugstr_guid(pGuid));
}
BSTR MSFT_ReadName( TLBContext *pcx, int offset)
***************
*** 1182,1189 ****
--- 1271,1278 ----
WCHAR* pwstring = NULL;
BSTR bstrName = NULL;
- MSFT_Read(&niName, sizeof(niName), pcx,
- pcx->pTblDir->pNametab.offset+offset);
+ MSFT_ReadLEDWords(&niName, sizeof(niName), pcx,
+ pcx->pTblDir->pNametab.offset+offset);
niName.namelen &= 0xFF; /* FIXME: correct ? */
name=TLB_Alloc((niName.namelen & 0xff) +1);
MSFT_Read(name, (niName.namelen & 0xff), pcx, DO_NOT_SEEK);
***************
*** 1217,1223 ****
--- 1306,1312 ----
BSTR bstr = NULL;
if(offset<0) return NULL;
- MSFT_Read(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
+ MSFT_ReadLEWords(&length, sizeof(INT16), pcx, pcx->pTblDir->pStringtab.offset+offset);
if(length <= 0) return 0;
string=TLB_Alloc(length +1);
MSFT_Read(string, length, pcx, DO_NOT_SEEK);
***************
*** 1256,1263 ****
--- 1345,1352 ----
V_UNION(pVar, iVal) = offset & 0xffff;
return;
}
- MSFT_Read(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
- pcx->pTblDir->pCustData.offset + offset );
+ MSFT_ReadLEWords(&(V_VT(pVar)), sizeof(VARTYPE), pcx,
+ pcx->pTblDir->pCustData.offset + offset );
TRACE_(typelib)("Vartype = %x\n", V_VT(pVar));
switch (V_VT(pVar)){
case VT_EMPTY: /* FIXME: is this right? */
***************
*** 1287,1293 ****
--- 1376,1382 ----
/* pointer types with known behaviour */
case VT_BSTR :{
char * ptr;
- MSFT_Read(&size, sizeof(INT), pcx, DO_NOT_SEEK );
+ MSFT_ReadLEDWords(&size, sizeof(INT), pcx, DO_NOT_SEEK );
if(size <= 0) {
FIXME("BSTR length = %d?\n", size);
} else {
***************
*** 1343,1349 ****
--- 1432,1438 ----
while(offset >=0){
count++;
pNew=TLB_Alloc(sizeof(TLBCustData));
- MSFT_Read(&entry, sizeof(entry), pcx,
+ MSFT_ReadLEDWords(&entry, sizeof(entry), pcx,
pcx->pTblDir->pCDGuids.offset+offset);
MSFT_ReadGuid(&(pNew->guid), entry.GuidOffset , pcx);
MSFT_ReadValue(&(pNew->data), entry.DataOffset, pcx);
***************
*** 1410,1416 ****
--- 1499,1505 ----
TRACE_(typelib)("\n");
- MSFT_Read(&infolen, sizeof(INT), pcx, offset);
+ MSFT_ReadLEDWords(&infolen, sizeof(INT), pcx, offset);
for ( i = 0; i < cFuncs ; i++ )
{
***************
*** 1417,1423 ****
--- 1506,1512 ----
*pptfd = TLB_Alloc(sizeof(TLBFuncDesc));
/* name, eventually add to a hash table */
- MSFT_Read(&nameoffset,
+ MSFT_ReadLEDWords(&nameoffset,
sizeof(INT),
pcx,
offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
***************
*** 1425,1435 ****
--- 1514,1524 ----
(*pptfd)->Name = MSFT_ReadName(pcx, nameoffset);
/* read the function information record */
- MSFT_Read(&reclength, sizeof(INT), pcx, recoffset);
+ MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
reclength &= 0x1ff;
- MSFT_Read(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
+ MSFT_ReadLEDWords(pFuncRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
/* do the attributes */
nrattributes = (reclength - pFuncRec->nrargs * 3 * sizeof(int) - 0x18)
***************
*** 1471,1479 ****
--- 1560,1568 ----
}
/* fill the FuncDesc Structure */
- MSFT_Read( & (*pptfd)->funcdesc.memid,
- sizeof(INT), pcx,
- offset + infolen + ( i + 1) * sizeof(INT));
+ MSFT_ReadLEDWords( & (*pptfd)->funcdesc.memid,
+ sizeof(INT), pcx,
+ offset + infolen + ( i + 1) * sizeof(INT));
(*pptfd)->funcdesc.funckind = (pFuncRec->FKCCIC) & 0x7;
(*pptfd)->funcdesc.invkind = (pFuncRec->FKCCIC) >> 3 & 0xF;
***************
*** 1500,1510 ****
--- 1589,1599 ----
(*pptfd)->pParamDesc =
TLB_Alloc(pFuncRec->nrargs * sizeof(TLBParDesc));
- MSFT_Read(¶minfo,
- sizeof(paraminfo),
- pcx,
- recoffset + reclength -
- pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
+ MSFT_ReadLEDWords(¶minfo,
+ sizeof(paraminfo),
+ pcx,
+ recoffset + reclength -
+ pFuncRec->nrargs * sizeof(MSFT_ParameterInfo));
for ( j = 0 ; j < pFuncRec->nrargs ; j++ )
{
***************
*** 1523,1529 ****
--- 1612,1618 ----
* from there jump to the end of record,
* go back by (j-1) arguments
*/
- MSFT_Read( ¶minfo ,
+ MSFT_ReadLEDWords( ¶minfo ,
sizeof(MSFT_ParameterInfo), pcx,
recoffset + reclength - ((pFuncRec->nrargs - j - 1)
* sizeof(MSFT_ParameterInfo)));
***************
*** 1646,1665 ****
--- 1735,1754 ----
TRACE_(typelib)("\n");
- MSFT_Read(&infolen,sizeof(INT), pcx, offset);
- MSFT_Read(&recoffset,sizeof(INT), pcx, offset + infolen +
+ MSFT_ReadLEDWords(&infolen,sizeof(INT), pcx, offset);
+ MSFT_ReadLEDWords(&recoffset,sizeof(INT), pcx, offset + infolen +
((cFuncs+cVars)*2+cFuncs + 1)*sizeof(INT));
recoffset += offset+sizeof(INT);
for(i=0;i<cVars;i++){
*pptvd=TLB_Alloc(sizeof(TLBVarDesc));
/* name, eventually add to a hash table */
- MSFT_Read(&nameoffset, sizeof(INT), pcx,
+ MSFT_ReadLEDWords(&nameoffset, sizeof(INT), pcx,
offset + infolen + (cFuncs + cVars + i + 1) * sizeof(INT));
(*pptvd)->Name=MSFT_ReadName(pcx, nameoffset);
/* read the variable information record */
- MSFT_Read(&reclength, sizeof(INT), pcx, recoffset);
+ MSFT_ReadLEDWords(&reclength, sizeof(INT), pcx, recoffset);
reclength &=0xff;
- MSFT_Read(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK) ;
+ MSFT_ReadLEDWords(pVarRec, reclength - sizeof(INT), pcx, DO_NOT_SEEK);
/* Optional data */
if(reclength >(6*sizeof(INT)) )
(*pptvd)->HelpContext=pVarRec->HelpContext;
***************
*** 1669,1675 ****
--- 1758,1764 ----
if(reclength >(9*sizeof(INT)) )
(*pptvd)->HelpStringContext=pVarRec->HelpStringContext;
/* fill the VarDesc Structure */
- MSFT_Read(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
+ MSFT_ReadLEDWords(&(*pptvd)->vardesc.memid, sizeof(INT), pcx,
offset + infolen + ( i + 1) * sizeof(INT));
(*pptvd)->vardesc.varkind = pVarRec->VarKind;
(*pptvd)->vardesc.wVarFlags = pVarRec->Flags;
***************
*** 1714,1720 ****
--- 1803,1809 ----
TRACE_(typelib)("offset %x, masked offset %x\n", offset, offset + (offset & 0xfffffffc));
- MSFT_Read(&impinfo, sizeof(impinfo), pcx,
+ MSFT_ReadLEDWords(&impinfo, sizeof(impinfo), pcx,
pcx->pTblDir->pImpInfo.offset + (offset & 0xfffffffc));
for(j=0;pImpLib;j++){ /* search the known offsets of all import libraries */
if(pImpLib->offset==impinfo.oImpFile) break;
***************
*** 1751,1757 ****
--- 1840,1846 ----
for(i=0;i<count;i++){
if(offset<0) break; /* paranoia */
*ppImpl=TLB_Alloc(sizeof(**ppImpl));
- MSFT_Read(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
+ MSFT_ReadLEDWords(&refrec,sizeof(refrec),pcx,offset+pcx->pTblDir->pRefTab.offset);
MSFT_DoRefType(pcx, pTI, refrec.reftype);
(*ppImpl)->hRef = refrec.reftype;
(*ppImpl)->implflags=refrec.flags;
***************
*** 1775,1781 ****
--- 1864,1870 ----
TRACE_(typelib)("count=%u\n", count);
ptiRet = (ITypeInfoImpl*) ITypeInfo_Constructor();
- MSFT_Read(&tiBase, sizeof(tiBase) ,pcx ,
+ MSFT_ReadLEDWords(&tiBase, sizeof(tiBase) ,pcx ,
pcx->pTblDir->pTypeInfoTab.offset+count*sizeof(tiBase));
/* this is where we are coming from */
ptiRet->pTypeLib = pLibInfo;
***************
*** 1925,1931 ****
--- 2014,2020 ----
DWORD dwTLBLength = GetFileSize(hFile, NULL);
/* first try to load as *.tlb */
- dwSignature = *((DWORD*) pBase);
+ dwSignature = FromLEDWord(*((DWORD*) pBase));
if ( dwSignature == MSFT_SIGNATURE)
{
*ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
***************
*** 1961,1967 ****
--- 2050,2056 ----
if (pBase)
{
/* try to load as incore resource */
- dwSignature = *((DWORD*) pBase);
+ dwSignature = FromLEDWord(*((DWORD*) pBase));
if ( dwSignature == MSFT_SIGNATURE)
{
*ppTypeLib = ITypeLib2_Constructor_MSFT(pBase, dwTLBLength);
***************
*** 2022,2031 ****
--- 2111,2120 ----
cx.length = dwTLBLength;
/* read header */
- MSFT_Read((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
+ MSFT_ReadLEDWords((void*)&tlbHeader, sizeof(tlbHeader), &cx, 0);
TRACE("header:\n");
TRACE("\tmagic1=0x%08x ,magic2=0x%08x\n",tlbHeader.magic1,tlbHeader.magic2 );
- if (memcmp(&tlbHeader.magic1,TLBMAGIC2,4)) {
+ if (tlbHeader.magic1 != MSFT_SIGNATURE) {
FIXME("Header type magic 0x%08x not supported.\n",tlbHeader.magic1);
return NULL;
}
***************
*** 2036,2042 ****
--- 2125,2131 ----
/* now read the segment directory */
TRACE("read segment directory (at %ld)\n",lPSegDir);
- MSFT_Read((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
+ MSFT_ReadLEDWords((void*)&tlbSegDir, sizeof(tlbSegDir), &cx, lPSegDir);
cx.pTblDir = &tlbSegDir;
/* just check two entries */
***************
*** 2073,2079 ****
--- 2162,2168 ----
if( tlbHeader.varflags & HELPDLLFLAG)
{
int offset;
- MSFT_Read(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
+ MSFT_ReadLEDWords(&offset, sizeof(offset), &cx, sizeof(tlbHeader));
pTypeLibImpl->HelpStringDll = MSFT_ReadString(&cx, offset);
}
***************
*** 2091,2097 ****
--- 2180,2186 ----
int i, j, cTD = tlbSegDir.pTypdescTab.length / (2*sizeof(INT));
INT16 td[4];
pTypeLibImpl->pTypeDesc = TLB_Alloc( cTD * sizeof(TYPEDESC));
- MSFT_Read(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
+ MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pTypdescTab.offset);
for(i=0; i<cTD; )
{
/* FIXME: add several sanity checks here */
***************
*** 2113,2119 ****
--- 2202,2209 ----
{
pTypeLibImpl->pTypeDesc[i].u.hreftype = MAKELONG(td[2],td[3]);
}
- if(++i<cTD) MSFT_Read(td, sizeof(td), &cx, DO_NOT_SEEK);
+ if(++i<cTD)
+ MSFT_ReadLEWords(td, sizeof(td), &cx, DO_NOT_SEEK);
}
/* second time around to fill the array subscript info */
***************
*** 2122,2128 ****
--- 2212,2218 ----
if(pTypeLibImpl->pTypeDesc[i].vt != VT_CARRAY) continue;
if(tlbSegDir.pArrayDescriptions.offset>0)
{
- MSFT_Read(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) pTypeLibImpl->pTypeDesc[i].u.lpadesc);
+ MSFT_ReadLEWords(td, sizeof(td), &cx, tlbSegDir.pArrayDescriptions.offset + (int) pTypeLibImpl->pTypeDesc[i].u.lpadesc);
pTypeLibImpl->pTypeDesc[i].u.lpadesc = TLB_Alloc(sizeof(ARRAYDESC)+sizeof(SAFEARRAYBOUND)*(td[3]-1));
if(td[1]<0)
***************
*** 2134,2142 ****
--- 2224,2232 ----
for(j = 0; j<td[2]; j++)
{
- MSFT_Read(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].cElements,
+ MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].cElements,
sizeof(INT), &cx, DO_NOT_SEEK);
- MSFT_Read(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound,
+ MSFT_ReadLEDWords(& pTypeLibImpl->pTypeDesc[i].u.lpadesc->rgbounds[j].lLbound,
sizeof(INT), &cx, DO_NOT_SEEK);
}
}
***************
*** 2159,2170 ****
--- 2249,2260 ----
{
*ppImpLib = TLB_Alloc(sizeof(TLBImpLib));
(*ppImpLib)->offset = offset - tlbSegDir.pImpFiles.offset;
- MSFT_Read(&oGuid, sizeof(INT), &cx, offset);
+ MSFT_ReadLEDWords(&oGuid, sizeof(INT), &cx, offset);
- MSFT_Read(&(*ppImpLib)->lcid, sizeof(LCID), &cx, DO_NOT_SEEK);
- MSFT_Read(&(*ppImpLib)->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK);
- MSFT_Read(&(*ppImpLib)->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK);
- MSFT_Read(& size, sizeof(UINT16), &cx, DO_NOT_SEEK);
+ MSFT_ReadLEDWords(&(*ppImpLib)->lcid, sizeof(LCID), &cx, DO_NOT_SEEK);
+ MSFT_ReadLEWords(&(*ppImpLib)->wVersionMajor, sizeof(WORD), &cx, DO_NOT_SEEK);
+ MSFT_ReadLEWords(&(*ppImpLib)->wVersionMinor, sizeof(WORD), &cx, DO_NOT_SEEK);
+ MSFT_ReadLEWords(& size, sizeof(UINT16), &cx, DO_NOT_SEEK);
size >>= 2;
(*ppImpLib)->name = TLB_Alloc(size+1);
***************
*** 2781,2787 ****
--- 2871,2877 ----
TRACE("header:\n");
TRACE("\tmagic=0x%08lx, file blocks = %d\n", pHeader->SLTG_magic,
pHeader->nrOfFileBlks );
- if (memcmp(&pHeader->SLTG_magic, TLBMAGIC1, 4)) {
+ if (pHeader->SLTG_magic != SLTG_SIGNATURE) {
FIXME("Header type magic 0x%08lx not supported.\n",
pHeader->SLTG_magic);
return NULL;
*** wine-20020605/dlls/oleaut32/typelib.h Wed Jun 19 15:20:11 2002
--- wine/dlls/oleaut32/typelib.h Wed Jun 19 10:48:49 2002
***************
*** 24,31 ****
--- 24,29 ----
#include "oleauto.h"
#include "wine/windef16.h"
- #define TLBMAGIC2 "MSFT"
- #define TLBMAGIC1 "SLTG"
#define HELPDLLFLAG (0x0100)
#define DO_NOT_SEEK (-1)
***************
*** 137,144 ****
--- 135,147 ----
/*040*/ INT helpstringcontext; /* */
INT helpcontext; /* */
INT oCustData; /* offset in customer data table */
+ #ifdef WORDS_BIGENDIAN
+ INT16 cbSizeVft; /* virtual table size, not including inherits */
+ INT16 cImplTypes; /* nr of implemented interfaces */
+ #else
INT16 cImplTypes; /* nr of implemented interfaces */
INT16 cbSizeVft; /* virtual table size, not including inherits */
+ #endif
/*050*/ INT size; /* size in bytes, at least for structures */
/* FIXME: name of this field */
INT datatype1; /* position in type description table */
***************
*** 164,171 ****
--- 167,179 ----
/* INT recsize; record size including some xtra stuff */
INT DataType; /* data type of the memeber, eg return of function */
INT Flags; /* something to do with attribute flags (LOWORD) */
+ #ifdef WORDS_BIGENDIAN
+ INT16 res3; /* some offset into dunno what */
+ INT16 VtableOffset; /* offset in vtable */
+ #else
INT16 VtableOffset; /* offset in vtable */
INT16 res3; /* some offset into dunno what */
+ #endif
INT FKCCIC; /* bit string with the following */
/* meaning (bit 0 is the msb): */
/* bit 2 indicates that oEntry is numeric */
***************
*** 174,181 ****
--- 182,194 ----
/* bit 8 indicates that custom data is present */
/* Invokation kind (bits 9-12 ) */
/* function kind (eg virtual), bits 13-15 */
+ #ifdef WORDS_BIGENDIAN
+ INT16 nroargs; /* nr of optional arguments */
+ INT16 nrargs; /* number of arguments (including optional ????) */
+ #else
INT16 nrargs; /* number of arguments (including optional ????) */
INT16 nroargs; /* nr of optional arguments */
+ #endif
/* optional attribute fields, the number of them is variable */
INT OptAttr[1];
/*
***************
*** 208,215 ****
--- 221,233 ----
/* INT recsize; // record size including some xtra stuff */
INT DataType; /* data type of the variable */
INT Flags; /* VarFlags (LOWORD) */
+ #ifdef WORDS_BIGENDIAN
+ INT16 res3; /* some offset into dunno what */
+ INT16 VarKind; /* VarKind */
+ #else
INT16 VarKind; /* VarKind */
INT16 res3; /* some offset into dunno what */
+ #endif
INT OffsValue; /* value of the variable or the offset */
/* in the data structure */
/* optional attribute fields, the number of them is variable */
More information about the wine-patches
mailing list