Hi,
I am quite new I am trying to create COM class to be able to access it via VB.NET. The code compiles fine,but on createObject returns null (no class). The main conde is taken
from codeguru, but I've tried to simplify interface (don't want to be completely visible via object browser).
Could anyone help me to solve this?
extern long g_nComObjsInUse;
class CNewCamdFactory : public IClassFactory
{
public:
CNewCamdFactory()
{
m_nRefCount=0;
InterlockedIncrement(&g_nComObjsInUse);
}
~CNewCamdFactory()
{
InterlockedDecrement(&g_nComObjsInUse);
}
HRESULT __stdcall QueryInterface(
REFIID riid ,
void **ppObj);
ULONG __stdcall AddRef()
{
return InterlockedIncrement(&m_nRefCount) ;
}
ULONG __stdcall Release()
{
long nRefCount=0;
nRefCount=InterlockedDecrement(&m_nRefCount) ;
if (nRefCount == 0) delete this;
return nRefCount;
}
virtual HRESULT __stdcall CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv) ;
virtual HRESULT __stdcall LockServer(BOOL bLock) ;
private:
long m_nRefCount;
};
#include <objbase.h>
#include "NewCamdFactory.h"
#include "NewCamdLib.h"
HRESULT __stdcall CNewCamdFactory::QueryInterface(
const IID& iid,
void** ppv)
{
if ((iid == IID_IUnknown) || (iid == IID_IClassFactory))
{
*ppv = static_cast<IClassFactory*>(this) ;
}
else
{
*ppv = NULL ;
return E_NOINTERFACE ;
}
reinterpret_cast<IUnknown*>(*ppv)->AddRef() ;
return S_OK ;
}
HRESULT __stdcall CNewCamdFactory::LockServer(BOOL bLock)
{
return E_NOTIMPL;
}
HRESULT __stdcall CNewCamdFactory::CreateInstance(IUnknown* pUnknownOuter,
const IID& iid,
void** ppv)
{
if (pUnknownOuter != NULL)
{
return CLASS_E_NOAGGREGATION ;
}
CNewCamdLib* pObject = new CNewCamdLib ;
if (pObject == NULL)
{
return E_OUTOFMEMORY ;
}
return pObject->QueryInterface(iid, ppv) ;
}
#ifndef __NewCamdGuid_h__
#define __NewCamdGuid_h__
static const GUID CLSID_NewCamdObject =
{ 0x92f7a9cc, 0xf4cb, 0x11d4, { 0x82, 0x6d, 0x0, 0x17, 0x4b, 0x36, 0x46, 0xc0 } };
static const GUID IID_IStatus =
{ 0xd518b0bf, 0x3ee1, 0x4976, {0x9b, 0x6a, 0x9f, 0x34, 0x43, 0xa2, 0xa1, 0x86 } };
struct IStatus : public IUnknown
{
virtual HRESULT __stdcall Register(int RegisterCode, int Licence) = 0;
};
#endif
#include <objbase.h>
#include "NewCamdLib.h"
#include "NewCamdFactory.h"
#include "NewCamdGuid.h"
HMODULE g_hModule=NULL;
long g_nComObjsInUse=0;
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD dwReason,
void* lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
g_hModule = (HMODULE)hModule ;
}
return TRUE ;
}
STDAPI DllGetClassObject(const CLSID& clsid,
const IID& iid,
void** ppv)
{
if (clsid == CLSID_NewCamdObject)
{
CNewCamdFactory *pNewCamd = new CNewCamdFactory;
if (pNewCamd == NULL)
return E_OUTOFMEMORY;
else
{
return pNewCamd->QueryInterface(iid , ppv);
}
}
return CLASS_E_CLASSNOTAVAILABLE;
}
STDAPI DllCanUnloadNow()
{
if (g_nComObjsInUse == 0)
{
return S_OK;
}
else
{
return S_FALSE;
}
}
Exports.Def
;
;contains the list of functions that are being exported from this DLL
;
DESCRIPTION "NewCamdD COM object"
LIBRARY "NewCamdLib"
EXPORTS
DllGetClassObject PRIVATE
DllCanUnloadNow PRIVATE
DllRegisterServer PRIVATE
DllUnregisterServer PRIVATE
Registry.h
#ifndef __Registry_H__
#define __Registry_H__
HRESULT RegisterServer(HMODULE hModule,
const CLSID& clsid,
const char* szFriendlyName,
const char* szVerIndProgID,
const char* szProgID) ;
HRESULT UnregisterServer(const CLSID& clsid,
const char* szVerIndProgID,
const char* szProgID) ;
#endif
#include <windows.h>
#include <objbase.h>
#include "NewCamDGuid.h"
#define NewCamDProgId "TomSoft.NewCamDLibrary"
extern HMODULE g_hModule;
BOOL HelperWriteKey(
HKEY roothk,
const char *lpSubKey,
LPCTSTR val_name,
DWORD dwType,
void *lpvData,
DWORD dwDataSize)
{
HKEY hk;
if (ERROR_SUCCESS != RegCreateKey(roothk,lpSubKey,&hk) ) return FALSE;
if (ERROR_SUCCESS != RegSetValueEx(hk,val_name,0,dwType,(CONST BYTE *)lpvData,dwDataSize)) return FALSE;
if (ERROR_SUCCESS != RegCloseKey(hk)) return FALSE;
return TRUE;
}
HRESULT __stdcall DllRegisterServer(void)
{
WCHAR *lpwszClsid;
char szBuff[MAX_PATH]="";
char szClsid[MAX_PATH]="", szInproc[MAX_PATH]="",szProgId[MAX_PATH];
char szDescriptionVal[256]="";
StringFromCLSID(
CLSID_NewCamdObject,
&lpwszClsid);
wsprintf(szClsid,"%S",lpwszClsid);
wsprintf(szInproc,"%s\\%s\\%s","clsid",szClsid,"InprocServer32");
wsprintf(szProgId,"%s\\%s\\%s","clsid",szClsid,"ProgId");
wsprintf(szBuff,"%s","Fast Addition Algorithm");
wsprintf(szDescriptionVal,"%s\\%s","clsid",szClsid);
HelperWriteKey (
HKEY_CLASSES_ROOT,
szDescriptionVal,
NULL, REG_SZ,
(void*)szBuff,
lstrlen(szBuff)
);
GetModuleFileName(
g_hModule,
szBuff,
sizeof(szBuff));
HelperWriteKey (
HKEY_CLASSES_ROOT,
szInproc,
NULL, REG_SZ,
(void*)szBuff,
lstrlen(szBuff)
);
lstrcpy(szBuff,NewCamDProgId);
HelperWriteKey (
HKEY_CLASSES_ROOT,
szProgId,
NULL,
REG_SZ,
(void*)szBuff,
lstrlen(szBuff)
);
wsprintf(szBuff,"%s","OpenSSL Algorithm support for NewCamd");
HelperWriteKey (
HKEY_CLASSES_ROOT,
NewCamDProgId,
NULL,
REG_SZ,
(void*)szBuff,
lstrlen(szBuff)
);
wsprintf(szProgId,"%s\\%s",NewCamDProgId,"CLSID");
HelperWriteKey (
HKEY_CLASSES_ROOT,
szProgId,
NULL,
REG_SZ,
(void*)szClsid,
lstrlen(szClsid)
);
return 1;
}
HRESULT __stdcall DllUnregisterServer(void)
{
char szKeyName[256]="",szClsid[256]="";
WCHAR *lpwszClsid;
wsprintf(szKeyName,"%s\\%s",NewCamDProgId,"CLSID");
RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName);
RegDeleteKey(HKEY_CLASSES_ROOT,NewCamDProgId);
StringFromCLSID(
CLSID_NewCamdObject,
&lpwszClsid);
wsprintf(szClsid,"%S",lpwszClsid);
wsprintf(szKeyName,"%s\\%s\\%s","CLSID",szClsid,"InprocServer32");
RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName);
wsprintf(szKeyName,"%s\\%s\\%s","CLSID",szClsid,"ProgId");
RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName);
wsprintf(szKeyName,"%s\\%s","CLSID",szClsid);
RegDeleteKey(HKEY_CLASSES_ROOT,szKeyName);
return 1;
}
NewCamdLib.h
#include "NewCamdGuid.h"
extern long g_nComObjsInUse;
class CNewCamdLib: public IStatus {
public:
HRESULT __stdcall CNewCamdLib::Register(int RegisterCode, int Licence);
HRESULT __stdcall QueryInterface(
REFIID riid ,
void **ppObj);
ULONG __stdcall AddRef()
{
return InterlockedIncrement(&m_nRefCount) ;
}
ULONG __stdcall Release()
{
long nRefCount=0;
nRefCount=InterlockedDecrement(&m_nRefCount) ;
if (nRefCount == 0) delete this;
return nRefCount;
}
CNewCamdLib()
{
m_nRefCount=0;
m_reg = false;
InterlockedIncrement(&g_nComObjsInUse);
}
~CNewCamdLib()
{
InterlockedDecrement(&g_nComObjsInUse);
}
private:
bool m_reg;
long m_nRefCount; };
newCamdLib.cpp file which returns interface and probably null:
#include <objbase.h>
#include "NewCamdLib.h"
#include "NewCamdGuid.h"
HRESULT __stdcall CNewCamdLib::Register(int RegisterCode, int Licence)
{
if (RegisterCode == 888 && Licence == 111)
{
m_reg = true;
return 1;
}
return 0;
}
HRESULT __stdcall CNewCamdLib::QueryInterface(
REFIID riid ,
void **ppObj)
{
if (riid == IID_IUnknown)
{
*ppObj =static_cast<IStatus *> (this) ;
((IUnknown *)(*ppObj))->AddRef();
return S_OK;
}
if (riid == IID_IStatus)
{
*ppObj =static_cast<IStatus *> (this) ;
((IUnknown *)(*ppObj))->AddRef();
return S_OK;
}
*ppObj = NULL ;
return E_NOINTERFACE ;
}
My VB6 testing code:
Option Explicit
Private Sub Form_Load()
Dim obj As Object, ret As Integer
Set obj = CreateObject("TomSoft.NewCamDLibrary")
Dim lbCode As Long, Licence As Long
Licence = 11111
lbCode = 3333
ret = obj.Register(lbCode, Licence)
MsgBox "Returned = " & ret
End Sub