Why is CoCreateInstance failing?

Just starting out? Need help? Post your questions and find answers here.
swhite
Enthusiast
Enthusiast
Posts: 794
Joined: Thu May 21, 2009 6:56 pm

Why is CoCreateInstance failing?

Post by swhite »

Hi

I have tried the equivalent code in another development language and everything works and the COM object is created but it fails in PureBasic. Can anyone see why CoCreateInstance fails with error #REGDB_E_CLASSNOTREG? I compiled the code as Unicode so that the GUIDs are passed to the CLSIDFromString as unicode as required and all the steps indicate success until I get to CoCreateInstance.

Thanks,
Simon

Code: Select all

Interface Idckardauth Extends IDispatch
	PrepareResponse.s(tcRcvd.p-bstr)
EndInterface	
Define.i CLSID_Class,CLSID_Interface,lnRtn
lnRtn = CLSIDFromString_("{8DC6BA5D-6861-4F0A-A080-7DEDCC97C10F}",@CLSID_Class)
Select lnRTn
   Case #NOERROR
      Debug "Success"
   Case #CO_E_CLASSSTRING
      Debug "The class string was improperly formatted."
   Case #REGDB_E_CLASSNOTREG
      Debug "The CLSID corresponding to the class string was not found in the registry."
   Case #REGDB_E_READREGDB
      Debug "The registry could not be opened for reading."
   Default
      Debug lnRtn
EndSelect

      
lnRtn =  CLSIDFromString_("{4C791FAF-8649-462D-A93A-185F95C2DC0E}",@CLSID_Interface)
Select lnRTn
   Case #NOERROR
      Debug "Success"
   Case #CO_E_CLASSSTRING
      Debug "The class string was improperly formatted."
   Case #REGDB_E_CLASSNOTREG
      Debug "The CLSID corresponding to the class string was not found in the registry."
   Case #REGDB_E_READREGDB
      Debug "The registry could not be opened for reading."
   Default
      Debug lnRtn
EndSelect

Define loVFP.idckardauth


lnRtn = CoInitializeEx_(0,#COINIT_MULTITHREADED)
;hr = CoInitializeEx_(0,#COINIT_APARTMENTTHREADED)

Select lnRtn
Case #S_OK
 Debug "Success"
Case #S_FALSE
   Debug "Failed"
Case #RPC_E_CHANGED_MODE
   Debug "A previous call to CoInitializeEx specified the concurrency model for this thread as multithread apartment (MTA). This could also indicate that a change from neutral-threaded apartment to single-threaded apartment has occurred." 
EndSelect

lnRtn = CoCreateInstance_(@CLSID_Class, 0,5,@CLSID_Interface,@loVFP)

Select lnRtn
Case #S_OK
 Debug "Success"

Case #REGDB_E_CLASSNOTREG
Debug "A specified class is Not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX Enumeration is Not registered Or the values For the server types in the registry are corrupt."

Case #CLASS_E_NOAGGREGATION
Debug "This class cannot be created As part of an aggregate."

Case #E_NOINTERFACE
Debug "The specified class does Not implement the requested Interface, Or the controlling IUnknown does Not expose the requested Interface."

Case #E_POINTER
   Debug "The ppv parameter is NULL."
Default
   Debug lnRtn
EndSelect
Simon White
dCipher Computing
User avatar
spikey
Enthusiast
Enthusiast
Posts: 758
Joined: Wed Sep 22, 2010 1:17 pm
Location: United Kingdom

Re: Why is CoCreateInstance failing?

Post by spikey »

Your two CLSIDFromString commands are wrong.
lnRtn = CLSIDFromString_("{8DC6BA5D-6861-4F0A-A080-7DEDCC97C10F}", @CLSID_Class)
lnRtn = CLSIDFromString_("{4C791FAF-8649-462D-A93A-185F95C2DC0E}", @CLSID_Interface)

Look at http://msdn.microsoft.com/en-us/library ... s.85).aspx

It says the syntax for the command is:-
HRESULT CLSIDFromString(
__in LPCOLESTR lpsz,
__out LPCLSID pclsid
);

CLSIDFromString doesn't accept a string as an argument directly for the CLSID but a long pointer to a string - that's what the LPCOLESTR lpsz bit means. You can't call it the way you are trying to. You need to pass it a pointer to a string.

I'm surprised that these commands aren't generating an error for you but even if the functions return a #NOERROR value - the content of CLSID_Class and CLSID_Interface will be meaningless. Consequently when these values arrive at CoCreateInstance_ - that function complains that the object and interface don't exist.
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Re: Why is CoCreateInstance failing?

Post by Trond »

Did you try to read your own error message?
A specified class is Not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX Enumeration is Not registered Or the values For the server types in the registry are corrupt.
You pass the value 5 as the third parameter. This value cannot be 5, as it must be one of the values in the CLSCTX enumeration, and there is no number 5 in that enumeration: http://msdn.microsoft.com/en-us/library ... S.85).aspx
swhite
Enthusiast
Enthusiast
Posts: 794
Joined: Thu May 21, 2009 6:56 pm

Re: Why is CoCreateInstance failing?

Post by swhite »

Trond wrote:Did you try to read your own error message?
A specified class is Not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX Enumeration is Not registered Or the values For the server types in the registry are corrupt.
You pass the value 5 as the third parameter. This value cannot be 5, as it must be one of the values in the CLSCTX enumeration, and there is no number 5 in that enumeration: http://msdn.microsoft.com/en-us/library ... S.85).aspx
The documentation also states:
To indicate that more than one context is acceptable, you can combine multiple values with Boolean ORs. The contexts are tried in the order in which they are listed.
Simon White
dCipher Computing
swhite
Enthusiast
Enthusiast
Posts: 794
Joined: Thu May 21, 2009 6:56 pm

Re: Why is CoCreateInstance failing?

Post by swhite »

Hi

I had previously tried the code using pointers as shown below but the results are the same.

Code: Select all

Interface Idckardauth Extends IDispatch
	PrepareResponse.s(tcRcvd.p-bstr)
EndInterface	

Define.i CLSID_Class,CLSID_Interface,lnRtn
Define.s GUID_C,GUID_I

GUID_C = "{8DC6BA5D-6861-4F0A-A080-7DEDCC97C10F}"

lnRtn = CLSIDFromString_(@GUID_C,@CLSID_Class)
Select lnRTn
   Case #NOERROR
      Debug "Success"
   Case #CO_E_CLASSSTRING
      Debug "The class string was improperly formatted."
   Case #REGDB_E_CLASSNOTREG
      Debug "The CLSID corresponding to the class string was not found in the registry."
   Case #REGDB_E_READREGDB
      Debug "The registry could not be opened for reading."
   Default
      Debug lnRtn
EndSelect

GUID_I = "{4C791FAF-8649-462D-A93A-185F95C2DC0E}"
      
lnRtn =  CLSIDFromString_(@GUID_I,@CLSID_Interface)
Select lnRTn
   Case #NOERROR
      Debug "Success"
   Case #CO_E_CLASSSTRING
      Debug "The class string was improperly formatted."
   Case #REGDB_E_CLASSNOTREG
      Debug "The CLSID corresponding to the class string was not found in the registry."
   Case #REGDB_E_READREGDB
      Debug "The registry could not be opened for reading."
   Default
      Debug lnRtn
EndSelect

Define loVFP.idckardauth

lnRtn = CoInitializeEx_(0,#COINIT_MULTITHREADED)
;hr = CoInitializeEx_(0,#COINIT_APARTMENTTHREADED)

Select lnRtn
Case #S_OK
 Debug "Success"
Case #S_FALSE
   Debug "Failed"
Case #RPC_E_CHANGED_MODE
   Debug "A previous call to CoInitializeEx specified the concurrency model for this thread as multithread apartment (MTA). This could also indicate that a change from neutral-threaded apartment to single-threaded apartment has occurred." 
EndSelect

lnRtn = CoCreateInstance_(@CLSID_Class, 0,1,@CLSID_Interface,@loVFP)

Select lnRtn
Case #S_OK
 Debug "Success"

Case #REGDB_E_CLASSNOTREG
Debug "A specified class is Not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX Enumeration is Not registered Or the values For the server types in the registry are corrupt."

Case #CLASS_E_NOAGGREGATION
Debug "This class cannot be created As part of an aggregate."

Case #E_NOINTERFACE
Debug "The specified class does Not implement the requested Interface, Or the controlling IUnknown does Not expose the requested Interface."

Case #E_POINTER
   Debug "The ppv parameter is NULL."
Default
   Debug lnRtn
EndSelect

Just for the curious this is the VFP code that works correctly:

Code: Select all

#Define NOERROR                    0
#Define CO_E_CLASSSTRING           0x800401f3
#Define REGDB_E_CLASSNOTREG        0x80040154
#Define REGDB_E_READREGDB          0x80040150
#Define S_OK                       0
#Define S_FALSE                    1
#Define RPC_E_CHANGED_MODE         0x80010106
#Define CLASS_E_NOAGGREGATION      0x80040110
#DEfine E_NOINTERFACE              0x80004002
#Define COINIT_APARTMENTTHREADED   0x2
#Define COINIT_MULTITHREADED       0x0
#Define E_POINTER                  0x80004003


DECLARE INTEGER CLSIDFromString IN ole32 STRING   lpsz,STRING @ pclsid
Declare Integer CoInitializeEx IN ole32 Integer lpsz, Integer lpsz2
Declare Integer CoCreateInstance In ole32 String lpClass, Integer,Integer lnSrvType,String lpInterface, Object @ loVFP
Declare Integer CoUninitialize in Ole32

lcRcvd = "DONEY CRES  PVSystem211001.2@KT782448300000013004T01011.000201DATE02162011TIME0952060011$"
Local lcClass,lcInterface,lnRtn,loVFP

lcClass = REPLICATE(CHR(0), 16)

*
* option 5 in StrConv() converts the string to Unicode
*
lnRtn = CLSIDFromString(Strconv("{8DC6BA5D-6861-4F0A-A080-7DEDCC97C10F}",5),@lcClass)

Do Case 
   Case lnRtn = NOERROR
      DebugOut "Success"
   Case lnRtn = CO_E_CLASSSTRING
      DebugOut "The class string was improperly formatted."
   Case lnRtn = REGDB_E_CLASSNOTREG
      DebugOut "The CLSID corresponding to the class string was not found in the registry."
   Case lnRtn = REGDB_E_READREGDB
      DebugOut "The registry could not be opened for reading."
   Otherwise
      DebugOut lnRtn
EndCase

lcInterface = REPLICATE(CHR(0), 16)  
*
* option 5 in StrConv() converts the string to Unicode
*    
lnRtn =  CLSIDFromString(Strconv("{4C791FAF-8649-462D-A93A-185F95C2DC0E}",5),@lcInterface)

Do Case
   Case lnRtn = NOERROR
      DebugOut "Success"
   Case lnRtn = CO_E_CLASSSTRING
      DebugOut "The class string was improperly formatted."
   Case lnRtn = REGDB_E_CLASSNOTREG
      DebugOut "The CLSID corresponding to the class string was not found in the registry."
   Case lnRtn = REGDB_E_READREGDB
      DebugOut "The registry could not be opened for reading."
   Otherwise
      DebugOut lnRtn
EndCase

lnRtn = CoInitializeEx(0,COINIT_MULTITHREADED)
*lnRtn = CoInitializeEx(0,COINIT_APARTMENTTHREADED)

Do Case
Case lnRtn = S_OK
 DebugOut "Success"
Case lnRtn = S_FALSE
   DebugOut "Failed"
Case lnRtn = RPC_E_CHANGED_MODE
   DebugOut "A previous call to CoInitializeEx specified the concurrency model for this thread as multithread apartment (MTA). This could also indicate that a change from neutral-threaded apartment to single-threaded apartment has occurred." 
EndCase

loVFP = 0

lnRtn = CoCreateInstance(@lcClass, 0,5,@lcInterface,@loVFP)

Do Case
Case lnRtn = S_OK
 DebugOut "Success"
Case lnRtn = REGDB_E_CLASSNOTREG
DebugOut "A specified class is Not registered in the registration database. Also can indicate that the type of server you requested in the CLSCTX Enumeration is Not registered Or the values For the server types in the registry are corrupt."

Case lnRtn = CLASS_E_NOAGGREGATION
DebugOut "This class cannot be created As part of an aggregate."

Case lnRtn = E_NOINTERFACE
DebugOut "The specified class does Not implement the requested Interface, Or the controlling IUnknown does Not expose the requested Interface."

Case lnRtn = E_POINTER
   DebugOut "The ppv parameter is NULL."
Otherwise
   DebugOut lnRtn
EndCase

Debugout loVFP.PrepareResponse(lcRcvd)
loVFP = 0
CoUninitialize()

Simon White
dCipher Computing
freak
PureBasic Team
PureBasic Team
Posts: 5940
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Re: Why is CoCreateInstance failing?

Post by freak »

This part is wrong:

Code: Select all

Define.i CLSID_Class,CLSID_Interface,lnRtn
It should be:

Code: Select all

Define.CLSID CLSID_Class,CLSID_Interface
Define.i lnRtn
A CLSID is a structure with 16byte length and you tried to put them into 4byte integer variables. That is why things get overwritten and the resulting values are wrong.
quidquid Latine dictum sit altum videtur
swhite
Enthusiast
Enthusiast
Posts: 794
Joined: Thu May 21, 2009 6:56 pm

Re: Why is CoCreateInstance failing?

Post by swhite »

Thanks Freak I did not know they were structures.

Have I defined the other items correctly because my CoCreateInstance succeeds but the loVFP\PrepareResponse does not actually trigger the method? I really need to understand how this should be done as I would like to use more COM automation for this project but it is taking me a long time to find what I need to learn. So any help would be appreciated.

Secondly it only works if I indicate that I want a "unicode" executable. Is that what I must use when I am doing COM automation?

The PrepareResponse() method returns a string but I do not know how to do that properly in PB either. If I do the following I get and invalid memory error.

Code: Select all

  lcTxt.s = loVFP\PrepareResponse(lcRcvd)
Thanks again,
Simon
Last edited by swhite on Thu Feb 24, 2011 10:29 pm, edited 1 time in total.
Simon White
dCipher Computing
swhite
Enthusiast
Enthusiast
Posts: 794
Joined: Thu May 21, 2009 6:56 pm

Re: Why is CoCreateInstance failing?

Post by swhite »

Hi Freak

Now I have just discovered that the CLSID is documented in the Stucture viewer. I have got to make more use of this tool. :)

Thanks,
Simon
Simon White
dCipher Computing
Post Reply