Connect to new object returns -3 in powerbuilder - powerbuilder

I am working on project where i am connecting dot net dll in powerbuilder . In dll project at dot net i am referencing two more dlls . My project dll is made COM type and it has been registered successfully using regasm.exe "mydll.dll" in dot net version directory. I can see the registry entry in my windows registry but when I test on other machine, it throws exception of connecting to com object failed return -3.
I am stuck badly and unable to figure out the solution.
Here in my code for powerbuilder:
dw_data.accepttext()
oleobject obj
obj= create oleobject
ll_obj= obj.connecttonewobject("classname")
IF ll_obj < 0 THEN
DESTROY obj
MessageBox("Verify","Connecting to COM Object Failed Error: " + String(ll_obj))
Return
END IF
ll_obj returns -3 in other machines .
Any helping hand around ?

From a quick Google search on 'connecttonewobject' I found this suggestion:
Have all classes a strong name?
Are all classes installed in the GAC?
Bruce Armstrong also suggests using Dependency Walker to assist in determining that all objects are deployed on the machine running the code.

Related

RegisterClassObjects() Doesn't Find Classes To Register

I'm in the process of converting an application from Visual Studio C++ 6.0 to Visual Studio 2008 and am running into problems with ATL.
I've been having a whole host of issues, but this is the first call that differs in return values between the two different compilers.
The following line, when compiled with VC++ 6.0, returns S-OK. When running in VS 2008, it returns S-FALSE. According to the MSDN documentation, this means it couldn't find any classes to register.
_Module.RegisterClassObjects(CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER, REGCLS_MULTIPLEUSE)
Any help would be greatly appreciated. Thanks!
I too ran into an issue related to RegisterClassObjects returning S_FALSE unexpectedly. In my scenario, the service state was not changing from Starting to Running in a legacy C++/ATL/COM project. RegisterClassObjects was returning S_FALSE (effectively a warning message) because:
the previous developer had enabled COM (_ATL_NO_COM_SUPPORT had not been defined)
no COM objects had been defined within the *.EXE
CALL STACK
line 8192: *ppEntry was always NULL
AtlComModuleRegisterClassObjects
CAltExeModule.RegisterClassObjects
CAtlServiceModuleT.PreMessageLoop
if RegisterClassObjects did not return S_OK, then the the service state was not updated to Running
NEXT STEPS
The options available to you will depend on your situation. Why is RegisterClassObjects being called? Why are no COM objects being detected?
In my case:
I could not prevent RegisterClassObjects from being called
I did not want to disable COM by introducing the _ATL_NO_COM_SUPPORT because I did not fully understand the repercussions of making such a change on an application I knew nothing about
I did not want to modify the SDK by replacing if (FAILED(hr)) with if (SUCCEEDED(hr))
So I ensured that AtlComModuleRegisterClassObjects was able to find a valid COM object in the auto map (which is referenced by pComModule->m_ppAutoObjMapFirst)
CONTEXT
Visual Studio 2013
Windows SDK 7.1A
Active Template Library version 12.00
REFERENCES
Given that I know little about COM & ATL, I found this statement to be a real eye opener:
ATL Services are designed to serve COM objects. You failed to provide
any objects in the object map. Technically, ATL is working even better
- it detects there are no objects to serve, so there's no point in starting the service at all... The fault is yours - for using ATL in
an unsupported way. This said however, it's very simple to remove the
function call registering the objects...
[SOURCE: ATL Services and 2003]

C++ : Dll injection. Why CreateRemoteThread() fail on Notepad?

I'm pretty new to DLL injection, doing this by curiosty and because I want to create an overlay in a game, without modifying his source code.
But for now, I'm stuck with a basic DLL injection : the one using CreateRemoteThread().
I followed this tutorial (in french, be carefull):
http://xevia.webege.com/old/atoray/2010/06180.php
What I have done :
Injection works fine on a basic program Target.exe (see Xevia's link)
I can see DLL loaded by a process with EnumProcessModules()
After the injection in Target.exe, I can see that my "Hook.dll" has been added.
[edit] Checked the exe version : both notepad and my injector are 32-bits
But when I inject the dll in other processes, it doesn't seems to work, even if CreateRemoteThread() does not return NULL.
So I've checked many posts, including this one: How do I prevent DLL injection
And this one : C++ - CreateRemoteThread DLL Injection [Windows 7] (tried the absolute path, without success)
And many others, without being able to really point what was wrong. So I invoke SO-gods.
1) Could it be an access-rights issue ?
2) Could it be my method of injection, too classical ? Which one should I try ?
3) [Topic question] Why my dll isn't injected in Notepad with CreateRemoteThread?
Thanks for your time.
[open to any grammar/formulation edit]
It works!
What I needed to change :
Build in x86 in order to match with target app
Use an absolute path
I did both but forgot to change my absolute path when switching between x86/x64...
Thanks to Adrian Roman, who put me in the right way.

32bit COM dll (surrogate) doesn't load in 64bit Application (E_NOINTERFACE error)

I have a COM object (C# .NET) which is registered and works fine when using it from a 32bit C++ application.
When using a 64bit C++ application it didn't work. I followed these steps (click) to load the COM object in a 32bit process, however when calling CreateInstance (more exactly at the call to IUnknown->QueryInterface(...)) I get a E_NOINTERFACE error. (I see the DllHost.exe *32 in TaskManager)
Unfortunately this is not code I have written and I have absolutely no experience using COM objects. Could anyone point me in a direction how I could debug that or even what could be the problem with this?
I'm importing a type library in my code via
#import "BrowserClient.tlb"
and the call itself is:
hr = client.CreateInstance(__uuidof(BrowserClient::BrowserClient));
Edit: I don't know if this is useful, but the COM object is registered as InProcServer32. I use OLE/COM Object Viewer to look at it.

Class not registered (0x80040154) on my own COM component

I am learning basics in COM, so I try to write simple COM component in VS2010 C++ Windows 7.
I created dll for component, registered it using following REG-file:
REGEDIT
HKEY_CLASSES_ROOT\Math.Component.1 = Chapter 6 Math Component
HKEY_CLASSES_ROOT\Math.Component.1\CurVer = Math.Component.1
HKEY_CLASSES_ROOT\Math.Component.1\CLSID = {A888F560-58E4-11d0-A68A-0000837E3100}
HKEY_CLASSES_ROOT\CLSID\{A888F560-58E4-11d0-A68A-0000837E3100} = Chapter 6 Math Component
HKEY_CLASSES_ROOT\CLSID\{A888F560-58E4-11d0-A68A-0000837E3100}\ProgID = Math.Component.1
HKEY_CLASSES_ROOT\CLSID\{A888F560-58E4-11d0-A68A-0000837E3100}\VersionIndependentProgID = Math.Component
HKEY_CLASSES_ROOT\CLSID\{A888F560-58E4-11d0-A68A-0000837E3100}\InprocServer32 = D:\Proga\COM\Debug\server.dll
HKEY_CLASSES_ROOT\CLSID\{A888F560-58E4-11d0-A68A-0000837E3100}\NotInsertable
In dll I exported (stubs for last two)
DllGetClassObject
DllCanUnloadNow
DllRegisterServer
DllUnregisterServer
In my COM client CLSIDFromProgID( szWideProgID, &clsid ); works as expected, returning {A888F560-58E4-11d0-A68A-0000837E3100}.
But when I try to get access to IClassFactory REGDB_E_CLASSNOTREG CoGetClassObject(clsid, CLSCTX_INPROC, NULL, IID_IClassFactory, (void **)&pCF) I get (0x80040154) error.
Both server and client compiled for Win32 target platform (although I tried x64 too). Source code I got from tutorial, so I don't understand what is wrong.
The tutorial you found no doubt is old, written long before 64-bit Windows came around. Registry keys need to be written to HKLM\Software\Wow6432Node\Classes for 32-bit COM servers, to HKLM\Software\Classes for 64-bit COM servers. Your .reg file isn't going to take care of that. You must avoid the HKEY_CLASSES_ROOT alias and replace it with the explicit HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Classes to avoid accidents.
Use the SysInternals' ProcMon utility if you still have problems, you'll see your test program searching for the registry keys and the DLL.

HRESULT “Class Not Registered” Implementing simple COM server DLL

I'm following this sites tutorial:
http://progtutorials.tripod.com/COM.htm
Preliminary evidence: Visual Studio 2010, Windows 7 64 bit.
and I'm coding the examples in section 3. (Implementing a server DLL). I've typed out the code exactly as shown and I'm getting a "Class not registered" exception when executing this code on line 12 of the code outlined in section 4.1 (where the tutorial shows you how to access the DLL and I have followed 3.1 to the letter):
hresult hr = CoGetClassObject(CLSID_Car, CLSCTX_SERVER, NULL, IID_IClassFactory, (void **) &pClassFactory);
I tried running:
regsvr32 xyz.dll
with xyz.dll being the path to my dll in order to register the DLL. This resulted in an error trying to find DLLRegisterServer:
I have already run
REGEDIT
HKEY_CLASSES_ROOT\CarDLL.Car\CLSID = {d969084c-b758-43ea-a218-a48763167abd}
HKEY_CLASSES_ROOT\CLSID\{d969084c-b758-43ea-a218-a48763167abd} = CarDLL.Car
HKEY_CLASSES_ROOT\CLSID\{d969084c-b758-43ea-a218-a48763167abd}\InProcServer32 = C:\Users\wiocl2\Documents\Visual Studio 2010\Projects\CarDLL\debug\CarDLL.dll
that I assumed put all the GUIDS I needed in the registry (The GUIDS were generated by me).
I'm assuming that a function is needed to be added to the class that allows it to be registered but I don't know how to do this and how to go about figuring it out. I'm kind of lost, as I haven't been working with COM for very long. If someone could give me a shove in the right direction that would be helpful.
Edit: Oh yes, I moved
#include // contains definition of DEFINE_GUID
to the iid.h file from iid.cpp, otherwise I was getting unresolved external errors on the build.
The most likely explanation: you are building your COM object as a 32-bit DLL, but the registration has been performed as a 64-bit DLL.
The treatment: open an admin privileged command window and navigate to the location of your DLL (C:\Users\wiocl2\Documents\Visual Studio 2010\Projects\CarDLL\debug). Once there, type:
c:\windows\sysWOW64\regedit <filename of .reg file whose contents are displayed above>
This will run the 32-bit version of REGEDIT, ensuring that the registry entries are created in the correct part of the hive. To verify this, you should see an entry for {d969084c-b758-43ea-a218-a48763167abd} in HKLM\Software\Wow6432Node\Classes\CLSID, not HKLM\Software\Classes\CLSID.
DllRegisterServer is a method you can implement in your COM server DLL, and is required if you want to use regsvr32 to perform the same operation you are currently using the .REG approach for. The same caveat applies: for a 32-bit DLL, you'll need to invoke c:\windows\sysWOW64\regsvr32.exe.
And Yes! COM is still mostly alive and well :) At least there is still standard support for it in VS 2012.
Hope that helps.

Resources