windows-nt/Source/XPSP1/NT/com/rpc/ndrexts/jitdump/jitdump.cxx
2020-09-26 16:20:57 +08:00

257 lines
6.2 KiB
C++

/*++
Copyright (c) 1999 Microsoft Corporation
Module Name:
jitdump.cxx
Abstract:
This file contains routines to dump typelib generated proxy information.
Author:
Yong Qu (yongqu) August 24 1999
Revision History:
--*/
#include <ole2.h>
#include <oleauto.h>
#include <oaidl.h>
#include <windows.h>
#include <malloc.h>
#include <stdio.h>
#include "jitdump.h"
// CreateStubFromTypeInfo is a private export. We have to LoadLibrary to
// retrieve it.
PFNCREATESTUBFROMTYPEINFO pfnCreateStubFromTypeInfo = NULL;
void PrintHelp()
{
printf("usage: jitdump <tlbname> [{iid} [<procnum>]]\n");
printf("Arguments:\n");
printf("\t<tlbname> typelibrary filename.\n");
printf("\t[{iid}] when presented, jitdump will dump all proc info of the interface \n");
printf("\t[<procnum>] when presented, jitdump will dump only the specified proc info\n");
}
//+---------------------------------------------------------------------------
//
// Function: PrintStubInfo
//
// Synopsis: Create a proxy from given type library name and IID, then
// dump the specified procedure information accordingly.
// NdrpDumpStubProc is exported from ndrexts.dll. The debug
// extension needs to be presented during runtime.
// Dump all the methods if nProcNum is 0.
//
// Returns:
// S_OK if everything is fine.
// error code if error occur somewhere.
//
//----------------------------------------------------------------------------
HRESULT PrintStubInfo(LPOLESTR wszFile, REFIID riid, unsigned long nProcNum)
{
HRESULT hr;
ITypeLib *pTypeLib = NULL;
ITypeInfo *pTypeInfo = NULL;
IRpcStubBuffer *pStub;
hr = LoadTypeLib(wszFile,&pTypeLib);
if (SUCCEEDED(hr))
{
hr = pTypeLib->GetTypeInfoOfGuid(riid,&pTypeInfo);
}
if (SUCCEEDED(hr))
{
hr = (*pfnCreateStubFromTypeInfo)(pTypeInfo,riid,NULL, &pStub);
}
if (SUCCEEDED(hr))
{
if (nProcNum > 0)
NdrpDumpStubProc(pStub,nProcNum);
else
NdrpDumpStub(pStub);
pStub->Release();
}
if (pTypeLib)
pTypeLib->Release();
return hr;
}
// dump all the interface defined in the tlb.
HRESULT PrintAllStubInfo(LPOLESTR wszFile)
{
int nCount = 0;
HRESULT hr = S_OK;
ITypeLib *pTypeLib = NULL;
ITypeInfo *pTypeInfo = NULL;
IRpcStubBuffer *pStub = NULL;
TYPEATTR *pTypeAttr = NULL;
TYPEKIND tkind;
hr = LoadTypeLib(wszFile,&pTypeLib);
if (SUCCEEDED(hr))
{
nCount = pTypeLib->GetTypeInfoCount();
}
for (int i = 0; ( i < nCount ) ; i++)
{
hr = pTypeLib->GetTypeInfoType(i,&tkind);
if (FAILED(hr))
break;
// we need to process interface only.
if (tkind == TKIND_INTERFACE ||
tkind == TKIND_DISPATCH )
{
hr = pTypeLib->GetTypeInfo(i,&pTypeInfo);
if (SUCCEEDED(hr))
{
hr = pTypeInfo->GetTypeAttr(&pTypeAttr);
if (SUCCEEDED(hr))
{
hr = (*pfnCreateStubFromTypeInfo)(pTypeInfo,pTypeAttr->guid,NULL, &pStub);
// IDispatch, IUnknown etc. would show up here also. We'll continue without
// dumping those interface.
if (SUCCEEDED(hr))
{
NdrpDumpStub(pStub);
pStub->Release();
}
pTypeInfo->ReleaseTypeAttr(pTypeAttr);
}
pTypeInfo->Release();
}
}
}
if (pTypeLib)
pTypeLib->Release();
return hr;
}
void __cdecl main(int argc, char *argv[])
{
HRESULT ret;
GUID riid;
unsigned long nProcNum,dwlen = 0;
WCHAR *wszGUID = NULL, *wszFile = NULL;
char *szTLB;
if ( argc < 2 || argc > 4)
{
PrintHelp();
return;
}
ret = CoInitialize(NULL);
if (FAILED (ret) )
{
printf("CoInitialize failed 0x%x\n",ret);
return;
}
// load rpcrt4!CreateStubFromTypeInfo. It's not in .lib file
if (NULL == pfnCreateStubFromTypeInfo )
{
HMODULE hMod = LoadLibraryA("rpcrt4.dll");
if (hMod)
{
pfnCreateStubFromTypeInfo = (PFNCREATESTUBFROMTYPEINFO)GetProcAddress(hMod,
"CreateStubFromTypeInfo");
}
if (NULL == hMod || NULL == pfnCreateStubFromTypeInfo )
{
printf("can't load rpcrt4.dll\n");
return;
}
}
// covert the filename to LPOLESTR to be used in LoadTypeLib
dwlen = ( strlen(argv[1]) + 1 ) * sizeof(OLECHAR) ;
wszFile = (LPOLESTR)alloca( dwlen );
memset( wszFile , 0 , dwlen );
dwlen /= sizeof(OLECHAR); // MultiByteTo wants a char count
if ( !MultiByteToWideChar(CP_ACP, 0, argv[1], -1, wszFile, dwlen ) )
{
printf("Can't process iid, error is 0x%x \n", GetLastError() );
return;
}
if ( argc == 2 )
{
// dump all interfaces if only tlb name is provided.
ret = PrintAllStubInfo(wszFile);
}
else
{
// convert iid string into real iid.
dwlen = ( strlen(argv[2]) + 1 ) * sizeof(OLECHAR) ;
wszGUID = (LPOLESTR)alloca( dwlen );
memset( wszGUID , 0 , dwlen );
dwlen /= sizeof(OLECHAR);
if ( !MultiByteToWideChar(CP_ACP, 0, argv[2], -1, wszGUID, dwlen ) )
{
printf("Can't process iid, error is 0x%x \n", GetLastError() );
return;
}
ret = IIDFromString(wszGUID, &riid );
if ( FAILED (ret) )
{
printf("can't convert iid %S 0x%x\n",wszGUID,ret);
PrintHelp();
return;
}
if ( argc == 3 )
{
ret = PrintStubInfo(wszFile,riid,0);
}
else
{
nProcNum = atol(argv[3]);
ret = PrintStubInfo(wszFile,riid,nProcNum);
}
}
if ( ret != S_OK )
{
printf("failed to dump the proxy 0x%x \n",ret);
}
CoUninitialize();
}