reverser
first of all - my biggest thanks to you, sir. Sources open... Good!
secondly - I'd prefer not to have the tool, honestly, I don't need it. What I'd prefer to have is a METHODOLOGY of how to obtain the structure of the given inx file and how to decompile the higher versions inx files.
That's why I'm digging COM IS files now. That's why I'm playing with InstDev now.
BTW, nikolastela, the utility has been finished. It is better then Pietrek's one

For each CoClass we are enumerating through the list of methods and fulfilling them with VAs. The sources are open:
//copyright flankerx and volodya 2004
#include <windows.h>
#include <ole2.h>
#include <iostream>
using namespace::std;
char* lpFuncType[] = {
"FUNC_VIRTUAL",
"FUNC_PUREVIRTUAL",
"FUNC_NONVIRTUAL",
"FUNC_STATIC",
"FUNC_DISPATCH"
};
char* lpTypeKind[] = {
"enum",
"struct",
"module",
"interface",
"dispinterface",
"coclass",
"typedef",
"union"
};
int wmain(int argc, wchar_t *argv[ ], wchar_t *envp[ ])
{
ITypeLib *pITypeLib = 0;
ITypeLib *pTL = 0;
ITypeInfo *ptInfo = 0;
ITypeInfo *pInfo = 0;
TYPEATTR *lpTypeAttr = 0;
TYPEATTR *lpIntAttr = 0;
VARDESC *lpVarDesc = 0;
BSTR bstrGUID = 0;
BSTR bstrName = 0;
GUID clsid;
GUID iid;
CoInitialize( 0 );
if( argc != 2)
{
wcerr << "Usage: com_va filename" << endl;
return -1;
}
if ((LoadTypeLib(argv[1], &pITypeLib )) != S_OK)
{
wcerr << "LoadTypeLib failed for file: " << argv[1] << endl;
return -1;
}
unsigned tiCount = pITypeLib->GetTypeInfoCount();
/* procedure outline:
foreach typeinfo
if typekind == TKIND_COCLASS
foreach member interface
print_interface_info(clsid, iid)
end foreach
end if
end foreach
*/
for ( unsigned i = 0; i < tiCount; i++ )
{
if (!LOWORD(pITypeLib->GetTypeInfo(i, &ptInfo)))
{
if(!LOWORD(ptInfo->GetTypeAttr(&lpTypeAttr)))
{
if(lpTypeAttr->typekind != TKIND_COCLASS)
continue;
clsid = lpTypeAttr->guid;
StringFromCLSID(clsid, &bstrGUID);
pITypeLib->GetDocumentation(i, &bstrName, 0, 0, 0);
wcout << "coclass " << bstrName << " GUID: " << bstrGUID << endl;
SysFreeString(bstrName);
SysFreeString(bstrGUID);
unsigned mCount = lpTypeAttr->cImplTypes;
//foreach member interface
for(unsigned j = 0; j < mCount; j++)
{
HREFTYPE ref = 0;
ptInfo->GetRefTypeOfImplType(j, &ref);
if(!LOWORD(ptInfo->GetRefTypeInfo(ref, &pInfo)))
{
// get index in typelib
UINT index = 0;
pInfo->GetContainingTypeLib(&pTL, &index);
pTL->GetDocumentation(index, &bstrName, 0, 0, 0);
pInfo->GetTypeAttr(&lpIntAttr);
iid = lpIntAttr->guid;
StringFromCLSID(iid, &bstrGUID);
wcout << "\t" << lpTypeKind[lpIntAttr->typekind] << " " << bstrName << "GUID: " << bstrGUID << endl;
SysFreeString(bstrName);
SysFreeString(bstrGUID);
unsigned fCount = lpIntAttr->cFuncs;
for(unsigned k = 0; k < fCount; k++)
{
FUNCDESC* fdesc = 0;
pInfo->GetFuncDesc(k, &fdesc);
pInfo->GetDocumentation(fdesc->memid, &bstrName, 0, 0, 0);
LPVOID iUnk = 0;
if (!LOWORD(CoCreateInstance(clsid, 0, CLSCTX_ALL, iid, &iUnk)))
{
BYTE* pVTable = (BYTE*)*(DWORD*)(iUnk);
DWORD pFunction = *(DWORD*)(pVTable + fdesc->oVft);
wcout.unsetf( ios_base::dec );
wcout.setf( ios_base::hex );
wcout << "\t\t" << lpFuncType[fdesc->funckind] << " " << bstrName << " VA: " << pFunction << " Offset: " << fdesc->oVft << endl;
}
SysFreeString(bstrName);
pInfo->ReleaseFuncDesc(fdesc);
}
pInfo->ReleaseTypeAttr(lpIntAttr);
pInfo->Release();
}//if(!LOWORD(ptInfo->GetRefTypeInfo(ref, &pInfo)))
}//for(UINT j = 0; j < mCount; j++)
ptInfo->ReleaseTypeAttr(lpTypeAttr);
}//if(!LOWORD(ptInfo->GetTypeAttr(&lpTypeAttr)))
ptInfo->Release();
}//if (!LOWORD(pITypeLib->GetTypeInfo(i, &ptInfo)))
}//for ( UINT i = 0; i < tiCount; i++ )
CoUninitialize();
return 0;
}