NOT PART OF BUILD. Utility for turning ActiveX typelibraries into XPCOM IDL and XPT files

This commit is contained in:
locka%iol.ie 2001-12-06 21:16:30 +00:00
Родитель 0a6833ac79
Коммит c176d3ff0f
7 изменённых файлов: 850 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1 @@
Utility for turning ActiveX typelibrary files into XPCOM xpt, idl & stub files

Просмотреть файл

@ -0,0 +1,8 @@
// stdafx.cpp : source file that includes just the standard includes
// tlb2xpt.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information
#include "stdafx.h"
// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

Просмотреть файл

@ -0,0 +1,30 @@
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#if !defined(AFX_STDAFX_H__55CC9557_F6D1_4BE8_A84D_BBCC8E265BDC__INCLUDED_)
#define AFX_STDAFX_H__55CC9557_F6D1_4BE8_A84D_BBCC8E265BDC__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <windows.h>
#include <comdef.h>
#include <stddef.h>
#include <stdio.h>
#include <string>
#include <crtdbg.h>
#include <atlconv.h>
#include "TypeDesc.h"
// TODO: reference additional headers your program requires here
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_STDAFX_H__55CC9557_F6D1_4BE8_A84D_BBCC8E265BDC__INCLUDED_)

Просмотреть файл

@ -0,0 +1,242 @@
#include "stdafx.h"
#include "TypeDesc.h"
TypeDesc::TypeDesc(ITypeInfo* pti, TYPEDESC* ptdesc)
{
if (ptdesc->vt == VT_PTR)
{
// ptdesc->lptdesc points to a TYPEDESC that specifies the thing pointed to
mType = T_POINTER;
mData.mPtr = new TypeDesc(pti, ptdesc->lptdesc);
}
else if ((ptdesc->vt & 0x0FFF) == VT_CARRAY)
{
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_CARRAY");
/*
// ptdesc->lpadesc points to an ARRAYDESC
str = TYPEDESCtoString(pti, &ptdesc->lpadesc->tdescElem );
// Allocate cDims * lstrlen("[123456]")
char buf[20];
for (USHORT n = 0; n < ptdesc->lpadesc->cDims; n++)
{
sprintf(buf, "[%d]", ptdesc->lpadesc->rgbounds[n].cElements);
str += buf;
}
return str;
*/
}
else if ((ptdesc->vt & 0x0FFF) == VT_SAFEARRAY)
{
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_SAFEARRAY");
/*
str = "SAFEARRAY(" + TYPEDESCtoString( pti, ptdesc->lptdesc ) + ")";
return str;
*/
}
else switch(ptdesc->vt)
{
case VT_VOID:
mType = T_VOID;
break;
case VT_HRESULT:
mType = T_RESULT;
break;
case VT_I1:
mType = T_INT8;
break;
case VT_I2:
mType = T_INT16;
break;
case VT_INT:
case VT_I4:
mType = T_INT32;
break;
case VT_I8:
mType = T_INT64;
break;
case VT_UI1:
mType = T_UINT8;
break;
case VT_UI2:
mType = T_UINT16;
break;
case VT_UINT:
case VT_UI4:
mType = T_UINT32;
break;
case VT_UI8:
mType = T_UINT64;
break;
case VT_BSTR:
case VT_LPWSTR:
mType = T_WSTRING;
break;
case VT_LPSTR:
mType = T_STRING;
break;
case VT_UNKNOWN:
case VT_DISPATCH:
mType = T_INTERFACE;
break;
case VT_BOOL:
mType = T_BOOL;
break;
case VT_R4:
mType = T_FLOAT;
break;
case VT_R8:
mType = T_DOUBLE;
break;
case VT_EMPTY:
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_EMPTY");
break;
case VT_NULL:
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_NULL");
break;
case VT_CY:
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_CY");
break;
case VT_DATE:
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_DATE");
break;
case VT_ERROR:
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_ERROR");
break;
case VT_VARIANT:
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_VARIANT");
break;
case VT_USERDEFINED:
mType = T_UNSUPPORTED;
mData.mName = strdup("VT_USERDEFINED");
break;
default:
{
char szBuf[50];
sprintf(szBuf, "VT = %08x", ptdesc->vt);
mType = T_UNSUPPORTED;
mData.mName = strdup(szBuf);
}
break;
}
}
TypeDesc::~TypeDesc()
{
if (mType == T_ARRAY)
{
delete mData.mArray.mElements;
}
else if (mType == T_POINTER)
{
delete mData.mPtr;
}
else if (mType == T_UNSUPPORTED)
{
free(mData.mName);
}
}
std::string TypeDesc::ToCString()
{
std::string str;
if (mType == T_POINTER)
{
// ptdesc->lptdesc points to a TYPEDESC that specifies the thing pointed to
str = mData.mPtr->ToXPIDLString();
str += " *";
return str;
}
else if (mType == T_ARRAY)
{
// TODO
str = "void * /* T_ARRAY */";
return str;
}
else switch (mType) {
case T_VOID: return "void";
case T_RESULT: return "nsresult";
case T_CHAR: return "char";
case T_WCHAR: return "PRUnichar";
case T_INT8: return "PRInt8";
case T_INT16: return "PRInt16";
case T_INT32: return "PRInt32";
case T_INT64: return "PRInt64";
case T_UINT8: return "PRUint8";
case T_UINT16: return "PRUint16";
case T_UINT32: return "PRUint32";
case T_UINT64: return "PRUint64";
case T_STRING: return "char*";
case T_WSTRING: return "PRUnichar*";
case T_FLOAT: return "float";
case T_DOUBLE: return "double";
case T_BOOL: return "PRBool";
case T_INTERFACE: return "nsISupports *";
default:
case T_UNSUPPORTED:
{
std::string str = "void * /* ";
str += mData.mName;
str += " */";
return str;
}
}
}
std::string TypeDesc::ToXPIDLString()
{
std::string str;
if (mType == T_POINTER)
{
// ptdesc->lptdesc points to a TYPEDESC that specifies the thing pointed to
str = mData.mPtr->ToXPIDLString();
str += " *";
return str;
}
else if (mType == T_ARRAY)
{
// TODO
str = "void * /* T_ARRAY */";
return str;
}
else switch (mType) {
case T_VOID: return "void";
case T_RESULT: return "nsresult";
case T_CHAR: return "char";
case T_WCHAR: return "wchar";
case T_INT8: return "octet";
case T_INT16: return "short";
case T_INT32: return "long";
case T_INT64: return "long long";
case T_UINT8: return "octect";
case T_UINT16: return "unsigned short";
case T_UINT32: return "unsigned long";
case T_UINT64: return "unsigned long long";
case T_STRING: return "string";
case T_WSTRING: return "wstring";
case T_FLOAT: return "float";
case T_DOUBLE: return "double";
case T_BOOL: return "boolean";
case T_INTERFACE: return "nsISupports";
default:
case T_UNSUPPORTED:
{
std::string str = "void * /* ";
str += mData.mName;
str += " */";
return str;
}
}
}

Просмотреть файл

@ -0,0 +1,53 @@
#ifndef TYPEDESC_H
#define TYPEDESC_H
class TypeDesc
{
public:
enum Type
{
T_POINTER, // A pointer to something else
T_ARRAY, // An array of other things
T_VOID,
T_RESULT, // nsresult / HRESULT
T_CHAR,
T_WCHAR,
T_INT8,
T_INT16,
T_INT32,
T_INT64,
T_UINT8,
T_UINT16,
T_UINT32,
T_UINT64,
T_STRING,
T_WSTRING,
T_FLOAT,
T_DOUBLE,
T_BOOL,
T_INTERFACE,
T_OTHER,
T_UNSUPPORTED
};
Type mType;
union {
// T_POINTER
TypeDesc *mPtr;
// T_ARRAY
struct {
long mNumElements;
TypeDesc **mElements;
} mArray;
// T_UNSUPPORTED
char *mName;
} mData;
TypeDesc(ITypeInfo* pti, TYPEDESC* ptdesc);
~TypeDesc();
std::string ToXPIDLString();
std::string ToCString();
};
#endif

Просмотреть файл

@ -0,0 +1,52 @@
#!nmake
#
# The contents of this file are subject to the Netscape Public
# License Version 1.1 (the "License"); you may not use this file
# except in compliance with the License. You may obtain a copy of
# the License at http://www.mozilla.org/NPL/
#
# Software distributed under the License is distributed on an "AS
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is Netscape
# Communications Corporation. Portions created by Netscape are
# Copyright (C) 1998 Netscape Communications Corporation. All
# Rights Reserved.
#
# Contributor(s):
DEPTH=..\..\..\..\..
REQUIRES = xpcom \
$(NULL)
MAKE_OBJ_TYPE = EXE
PROGRAM = .\$(OBJDIR)\tlb2xpt.exe
LCFLAGS = /D "WIN32" /GX
LLIBS= \
$(DIST)\lib\xpcomxpt_s.lib \
$(NULL)
OBJS = \
.\$(OBJDIR)\tlb2xpt.obj \
.\$(OBJDIR)\TypeDesc.obj \
$(NULL)
MOZ_NO_COVERAGE=1
include <$(DEPTH)\config\rules.mak>
export:: $(PROGRAM)
$(MAKE_INSTALL) $(PROGRAM) $(DIST)\bin
clobber::
rm -f $(DIST)\bin\tlb2xpt.exe

Просмотреть файл

@ -0,0 +1,464 @@
// tlb2xpt.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
std::string TYPEDESCtoString(ITypeInfo* pti, TYPEDESC* ptdesc);
std::string VTtoString(VARTYPE vt);
void DumpXPCOMInterfaceIDL(ITypeInfo *typeInfo);
FILE *fidl = NULL;
FILE *fxpt = NULL;
FILE *fstubc = NULL;
FILE *fstubh = NULL;
int main(int argc, char* argv[])
{
BOOL verbose = FALSE;
BOOL genIDL = FALSE;
BOOL genXPT = FALSE;
BOOL genStubs = FALSE;
char *inputTLB = NULL;
char *output = NULL;
for (int arg = 1; arg < argc; arg++)
{
if (stricmp(argv[arg], "-verbose") == 0)
{
verbose = TRUE;
}
else if (stricmp(argv[arg], "-idl") == 0)
{
genIDL = TRUE;
}
else if (stricmp(argv[arg], "-xpt") == 0)
{
genXPT = TRUE;
}
else if (stricmp(argv[arg], "-stubs") == 0)
{
genStubs = TRUE;
}
else if (!inputTLB)
{
inputTLB = argv[arg];
}
else if (!output)
{
output = argv[arg];
}
}
if (inputTLB == NULL)
{
fprintf(stderr, "Usage: tlb2xpt [-verbose] [-idl] [-stubs] [-xpt] typelibrary outputname\n");
fputs("Files will be created with the outputname and .cpp, .h, .idl\n"
"and .xpt extensions as appropriate for the specified switches.\n",
stderr);
return 1;
}
// Open FILE handles to the various things that need to be generated
if (genIDL)
{
if (output)
{
std::string filename(output);
filename += ".idl";
fidl = fopen(filename.c_str(), "wt");
}
else
{
fidl = stdout;
}
}
// TODO genStubs, genXPT
if (verbose)
fprintf(stderr, "Opening TLB \"%s\"\n", inputTLB);
ITypeLibPtr typeLib;
USES_CONVERSION;
HRESULT hr = LoadTypeLib(A2W(inputTLB), &typeLib);
if (FAILED(hr))
{
fprintf(stderr, "Error: failed to open \"%s\"\n", inputTLB);
return 1;
}
UINT count = typeLib->GetTypeInfoCount();
if (verbose)
fprintf(stderr, "TLB contains %d entries\n", count);
for (UINT i = 0; i < count; i++)
{
ITypeInfoPtr typeInfo;
typeLib->GetTypeInfo(i, &typeInfo);
ITypeInfo2Ptr type2Info = typeInfo;
TYPEATTR *attr;
type2Info->GetTypeAttr(&attr);
char *type;
switch (attr->typekind)
{
case TKIND_ENUM:
type = "TKIND_ENUM";
break;
case TKIND_RECORD:
type = "TKIND_RECORD";
break;
case TKIND_MODULE:
type = "TKIND_MODULE";
break;
case TKIND_INTERFACE:
type = "TKIND_INTERFACE";
if (genIDL)
DumpXPCOMInterfaceIDL(type2Info);
break;
case TKIND_DISPATCH:
type = "TKIND_DISPATCH";
break;
case TKIND_COCLASS:
type = "TKIND_COCLASS";
break;
case TKIND_ALIAS:
type = "TKIND_ALIAS";
break;
case TKIND_UNION:
type = "TKIND_UNION";
break;
case TKIND_MAX:
type = "TKIND_MAX";
break;
default:
type = "default";
break;
}
if (verbose)
fprintf(stderr, "Reading %s type\n", type);
type2Info->ReleaseTypeAttr(attr);
}
return 0;
}
// [scriptable, uuid(00000000-0000-0000-0000-000000000000)]
// interface axIFoo : axIBar
void DumpXPCOMInterfaceIDL(ITypeInfo *tiInterface)
{
HRESULT hr;
TYPEATTR *attr;
tiInterface->GetTypeAttr(&attr);
USES_CONVERSION;
//
// Attribute block
//
fputs("[scriptable, ", fidl);
// uuid()
WCHAR szGUID[64];
StringFromGUID2(attr->guid, szGUID, sizeof(szGUID));
szGUID[0] = L'(';
szGUID[wcslen(szGUID) - 1] = L')';
fprintf(fidl, "uuid%s", W2A(szGUID));
fputs("]\n", fidl);
//
// Interface block
//
fprintf(fidl, "interface ");
BSTR bstrName = NULL;
hr = tiInterface->GetDocumentation( MEMBERID_NIL, &bstrName, NULL, NULL, NULL);
fprintf(fidl, "ax%s", W2A(bstrName));
// Check for the base interface
for (UINT n = 0; n < attr->cImplTypes; n++)
{
HREFTYPE href = NULL;
if (FAILED(hr = tiInterface->GetRefTypeOfImplType(n, &href)))
// TODO
;
ITypeInfoPtr tiParent;
if (FAILED(hr = tiInterface->GetRefTypeInfo(href, &tiParent)))
// TODO
;
if (FAILED(hr = tiParent->GetDocumentation( MEMBERID_NIL, &bstrName, NULL, NULL, NULL)))
// TODO
;
fprintf(fidl, " : ax%s", W2A(bstrName));
SysFreeString(bstrName);
bstrName = NULL;
tiParent.Release();
}
//
// Methods and properties block
//
fprintf(fidl, "\n");
fprintf(fidl, "{\n");
for (n = 0; n < attr->cFuncs; n++)
{
FUNCDESC *func;
tiInterface->GetFuncDesc(n, &func);
fprintf(fidl, " ");
if (func->invkind & INVOKE_PROPERTYPUT ||
func->invkind & INVOKE_PROPERTYGET)
{
}
// Return type
TypeDesc tf(tiInterface, &func->elemdescFunc.tdesc);
fprintf(fidl, "%s ", tf.ToXPIDLString().c_str());
// Method / property name
BSTR bstrName = NULL;
tiInterface->GetDocumentation(func->memid, &bstrName, NULL, NULL, NULL);
fprintf(fidl, "%s (\n", W2A(bstrName));
SysFreeString(bstrName);
// Get the names of all the arguments
UINT cNames;
BSTR rgbstrNames[100];
hr = tiInterface->GetNames(func->memid, rgbstrNames, 100, (UINT FAR*) &cNames);
// Dump out all parameters
for (int p = 0; p < func->cParams; p++)
{
fputs(" ", fidl);
BOOL isIn = FALSE;
BOOL isOut = FALSE;
// Keywords
if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FRETVAL)
{
fputs("[retval] ", fidl);
}
if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FIN &&
func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FOUT)
{
fputs("inout ", fidl);
}
else if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FIN)
{
fputs("in ", fidl);
}
else if (func->lprgelemdescParam[p].idldesc.wIDLFlags & IDLFLAG_FOUT)
{
fputs("out ", fidl);
}
// Type
TypeDesc tp(tiInterface, &func->lprgelemdescParam[p].tdesc);
fprintf(fidl, "%s ", tp.ToXPIDLString().c_str());
// Name
fputs(W2A(rgbstrNames[p+1]), fidl);
if (p < func->cParams - 1)
{
fprintf(fidl, ",\n");
}
else
{
fprintf(fidl, "\n");
}
SysFreeString(rgbstrNames[0]);
}
fputs(" );\n", fidl);
tiInterface->ReleaseFuncDesc(func);
}
// Fin
fputs("};\n\n", fidl);
tiInterface->ReleaseTypeAttr(attr);
}
static char *g_rgszVT[] =
{
"void", //VT_EMPTY = 0, /* [V] [P] nothing */
"null", //VT_NULL = 1, /* [V] SQL style Null */
"short", //VT_I2 = 2, /* [V][T][P] 2 byte signed int */
"long", //VT_I4 = 3, /* [V][T][P] 4 byte signed int */
"single", //VT_R4 = 4, /* [V][T][P] 4 byte real */
"double", //VT_R8 = 5, /* [V][T][P] 8 byte real */
"CURRENCY", //VT_CY = 6, /* [V][T][P] currency */
"DATE", //VT_DATE = 7, /* [V][T][P] date */
"BSTR", //VT_BSTR = 8, /* [V][T][P] binary string */
"IDispatch*", //VT_DISPATCH = 9, /* [V][T] IDispatch FAR* */
"SCODE", //VT_ERROR = 10, /* [V][T] SCODE */
"boolean", //VT_BOOL = 11, /* [V][T][P] True=-1, False=0 */
"VARIANT", //VT_VARIANT = 12, /* [V][T][P] VARIANT FAR* */
"IUnknown*", //VT_UNKNOWN = 13, /* [V][T] IUnknown FAR* */
"wchar_t", //VT_WBSTR = 14, /* [V][T] wide binary string */
"", // = 15,
"char", //VT_I1 = 16, /* [T] signed char */
"unsigned char", //VT_UI1 = 17, /* [T] unsigned char */
"unsigned short", //VT_UI2 = 18, /* [T] unsigned short */
"unsigned long", //VT_UI4 = 19, /* [T] unsigned short */
"int64", //VT_I8 = 20, /* [T][P] signed 64-bit int */
"uint64", //VT_UI8 = 21, /* [T] unsigned 64-bit int */
"int", //VT_INT = 22, /* [T] signed machine int */
"unsigned int", //VT_UINT = 23, /* [T] unsigned machine int */
"void", //VT_VOID = 24, /* [T] C style void */
"HRESULT", //VT_HRESULT = 25, /* [T] */
"PTR", //VT_PTR = 26, /* [T] pointer type */
"SAFEARRAY", //VT_SAFEARRAY = 27, /* [T] (use VT_ARRAY in VARIANT) */
"CARRAY", //VT_CARRAY = 28, /* [T] C style array */
"USERDEFINED", //VT_USERDEFINED = 29, /* [T] user defined type */
"LPSTR", //VT_LPSTR = 30, /* [T][P] null terminated string */
"LPWSTR", //VT_LPWSTR = 31, /* [T][P] wide null terminated string */
"", // = 32,
"", // = 33,
"", // = 34,
"", // = 35,
"", // = 36,
"", // = 37,
"", // = 38,
"", // = 39,
"", // = 40,
"", // = 41,
"", // = 42,
"", // = 43,
"", // = 44,
"", // = 45,
"", // = 46,
"", // = 47,
"", // = 48,
"", // = 49,
"", // = 50,
"", // = 51,
"", // = 52,
"", // = 53,
"", // = 54,
"", // = 55,
"", // = 56,
"", // = 57,
"", // = 58,
"", // = 59,
"", // = 60,
"", // = 61,
"", // = 62,
"", // = 63,
"FILETIME", //VT_FILETIME = 64, /* [P] FILETIME */
"BLOB", //VT_BLOB = 65, /* [P] Length prefixed bytes */
"STREAM", //VT_STREAM = 66, /* [P] Name of the stream follows */
"STORAGE", //VT_STORAGE = 67, /* [P] Name of the storage follows */
"STREAMED_OBJECT", //VT_STREAMED_OBJECT = 68, /* [P] Stream contains an object */
"STORED_OBJECT", //VT_STORED_OBJECT = 69, /* [P] Storage contains an object */
"BLOB_OBJECT", //VT_BLOB_OBJECT = 70, /* [P] Blob contains an object */
"CF", //VT_CF = 71, /* [P] Clipboard format */
"CLSID", //VT_CLSID = 72 /* [P] A Class ID */
};
std::string VTtoString(VARTYPE vt)
{
std::string str;
vt &= ~0xF000;
if (vt <= VT_CLSID)
str = g_rgszVT[vt];
else
str = "BAD VARTYPE";
return str;
}
std::string TYPEDESCtoString(ITypeInfo* pti, TYPEDESC* ptdesc)
{
std::string str;
if (ptdesc->vt == VT_PTR)
{
// ptdesc->lptdesc points to a TYPEDESC that specifies the thing pointed to
str = TYPEDESCtoString( pti, ptdesc->lptdesc );
str += "*";
return str;
}
if ((ptdesc->vt & 0x0FFF) == VT_CARRAY)
{
// ptdesc->lpadesc points to an ARRAYDESC
str = TYPEDESCtoString(pti, &ptdesc->lpadesc->tdescElem );
// Allocate cDims * lstrlen("[123456]")
char buf[20];
for (USHORT n = 0; n < ptdesc->lpadesc->cDims; n++)
{
sprintf(buf, "[%d]", ptdesc->lpadesc->rgbounds[n].cElements);
str += buf;
}
return str;
}
if ((ptdesc->vt & 0x0FFF) == VT_SAFEARRAY)
{
str = "SAFEARRAY(" + TYPEDESCtoString( pti, ptdesc->lptdesc ) + ")";
return str;
}
if (ptdesc->vt == VT_USERDEFINED)
{
// Use ptdesc->hreftype and pti->GetRefTypeInfo
//
ITypeInfo* ptiRefType = NULL;
HRESULT hr = pti->GetRefTypeInfo( ptdesc->hreftype, &ptiRefType );
if (SUCCEEDED(hr))
{
BSTR bstrName = NULL;
BSTR bstrDoc = NULL;
BSTR bstrHelp = NULL;
DWORD dwHelpID;
hr = ptiRefType->GetDocumentation( MEMBERID_NIL, &bstrName, &bstrDoc, &dwHelpID, &bstrHelp );
if (FAILED(hr))
{
return std::string("ITypeInfo::GetDocumentation() failed in TYPEDESCToString");
}
USES_CONVERSION;
str = W2A(bstrName);
SysFreeString(bstrName);
SysFreeString(bstrDoc);
SysFreeString(bstrHelp);
ptiRefType->Release();
}
else
{
return std::string("<GetRefTypeInfo failed>");
}
return str;
}
return VTtoString(ptdesc->vt);
}