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
*** 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 */