Click here to Skip to main content
6,291,124 members and growing! (15,534 online)
Email Password   helpLost your password?
Platforms, Frameworks & Libraries » COM / COM+ » COM     Intermediate

Emulating CoCreateInstance()

By lallous

Describes how to use COM objects without registration.
VC6, VC7, VC7.1, VC8.0Win2K, WinXP, Win2003, Visual Studio, COM, Dev
Posted:16 Apr 2007
Views:25,973
Bookmarked:38 times
Announcements
Loading...
 
Search    
Advanced Search
printPrint   Broken Article?Report       add Share
  Discuss Discuss   Recommend Article Email
24 votes for this article.
Popularity: 6.18 Rating: 4.48 out of 5
1 vote, 4.2%
1
1 vote, 4.2%
2
1 vote, 4.2%
3
4 votes, 16.7%
4
17 votes, 70.8%
5

Introduction

A while ago, I wrote a small utility that converts DOT syntax into an image using the WinGraphViz.DLL COM component.

However, it is not very usual to have the user register this component before running the tool, thus I started looking around for a way to use COM components as if they were normal DLLs. The research yielded that there are many techniques to accomplish that:

  1. Registration-Free COM (for XP and above)
  2. Emulating the CoCreateInstance()

To learn more about Registration-Free COM, please check the references at the end of this article.

Emulating CoCreateInstance()

Normally, to create an instance, you would do something like:

hr = CoCreateInstance(CLSID_DOT, NULL, CLSCTX_ALL,
                      IID_IDOT, (LPVOID *)&pIDOT);

This will cause OLE to fetch the associated DLL from the registry and call its DllGetClassObject() method to get a class factory, then from the class factory an instance of your required IID will be created.

For that reason, we may emulate the CoCreateInstance() by the following code:

HRESULT __stdcall MyCoCreateInstance(
  LPCTSTR szDllName,
  IN REFCLSID rclsid,
  IUnknown* pUnkOuter,
  IN REFIID riid,
  OUT LPVOID FAR* ppv)
{
  HRESULT hr = REGDB_E_KEYMISSING;

  HMODULE hDll = ::LoadLibrary(szDllName);
  if (hDll == 0)
    return hr;

  typedef HRESULT (__stdcall *pDllGetClassObject)(IN REFCLSID rclsid, 
                   IN REFIID riid, OUT LPVOID FAR* ppv);

  pDllGetClassObject GetClassObject = 
     (pDllGetClassObject)::GetProcAddress(hDll, "DllGetClassObject");
  if (GetClassObject == 0)
  {
    ::FreeLibrary(hDll);
    return hr;
  }

  IClassFactory *pIFactory;

  hr = GetClassObject(rclsid, IID_IClassFactory, (LPVOID *)&pIFactory);

  if (!SUCCEEDED(hr))
    return hr;

  hr = pIFactory->CreateInstance(pUnkOuter, riid, ppv);
  pIFactory->Release();

  return hr;
}

Notice how this function takes a parameter holding the DLL's name.

Using the code

You need your application to run first if the COM is registered, if not you would resort to emulating the CoCreateInstance(). Your code could look like this:

hr = CoCreateInstance(CLSID_DOT, NULL, CLSCTX_ALL,
     IID_IDOT, (LPVOID *)&pIDOT);

if (hr == REGDB_E_CLASSNOTREG)
{
  hr = MyCoCreateInstance(_T("WinGraphViz.dll"), CLSID_DOT, 
       NULL, IID_IDOT, (LPVOID *)&pIDOT);
}

if (FAILED(hr))
{
  cout << "CoCreateInstance Failed: " << hr 
       << "nn";
  return -1;
}

Reference

The following links were helpful during the building of this simple snippet:

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

lallous


Member
Elias (aka lallous) has always been interested in the making of things and their inner workings.

His computer interests include system programming, reverse engineering, writing libraries, tutorials and articles.

In his free time, and apart from researching, his favorite reading topics include: dreams, metaphysics, philosophy, psychology and any other human/mystical science.

Elias maintains a blog at http://lallousx86.wordpress.com/ and a website at http://lgwm.org/
Occupation: Web Developer
Location: Lebanon Lebanon

Other popular COM / COM+ articles:

Article Top
You must Sign In to use this message board.
FAQ FAQ 
 
Noise Tolerance  Layout  Per page   
 Msgs 1 to 12 of 12 (Total in Forum: 12) (Refresh)FirstPrevNext
GeneralHow do I get clsid/iid unless the COM dll is not registered Pinmemberehaerim19:50 23 Dec '07  
Questionun freed addtional dlls Pinmemberirol5:46 9 Nov '07  
AnswerRe: un freed addtional dlls Pinmemberlallous23:19 11 Nov '07  
GeneralRe: un freed addtional dlls Pinmemberirol0:57 13 Nov '07  
QuestionOCX? Pinmembersammytheblowfish21:28 10 Jul '07  
QuestionRe: OCX? Pinmembersammytheblowfish13:18 14 Jul '07  
AnswerRe: OCX? Pinmembercharlieqin7:54 8 Nov '07  
GeneralFreeLibrary? Pinmemberpestking16:03 17 Apr '07  
GeneralRe: FreeLibrary? Pinmemberlallous19:49 17 Apr '07  
GeneralRe: FreeLibrary? PinmemberPhish Bulb6:27 13 Sep '07  
GeneralRe: FreeLibrary? Pinmemberlallous22:01 20 Sep '07  
GeneralGood stuff Pinmembersprymak0:13 17 Apr '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 16 Apr 2007
Editor: Smitha Vijayan
Copyright 2007 by lallous
Everything else Copyright © CodeProject, 1999-2009
Web17 | Advertise on the Code Project