I just found out that there is a minimal unmanaged API for ClickOnce applications in windows that is located in dfshim.dll. Unfortunately I could only find a very incomplete documentation on MSDN: http://msdn.microsoft.com/en-us/library/bb629396.aspx
There are only very few references in the web. All of them are using the DLL by executing command lines to call the DLL's functions using rundll32.exe.
I would like to call the DLL's functions from C++ code. I did not find a header file to include or a stub-file to link.
I could explicitely load the DLL during runtime and resolve the function symbols manually but that seems pretty uncommon for a Windows API. Also I would need to guess the signature for many of the functions.
How can I use that DLL with Visual Studio 2013? Why is there no include file? Is this actually an official/public API?
Strange, this code is hardly documented.
we ended up in this code:
bool LaunchClickOnceApplication(LPCSTR pszApplication)
{
HRESULT hr(-1);
HINSTANCE hInst = ::LoadLibrary("dfshim.dll");
if ( hInst )
{
typedef HRESULT (WINAPI *dfshim_LaunchApplicationProc) (LPCWSTR pszApplication, LPVOID pData, DWORD dwFlags);
dfshim_LaunchApplicationProc fnLaunch = (dfshim_LaunchApplicationProc)GetProcAddress(hInst, "LaunchApplication");
if ( fnLaunch )
{
hr = fnLaunch(CA2W(pszApplication), NULL, 0);
}
::FreeLibrary(hInst);
return SUCCEEDED(hr);
}
else
{
DWORD dwErr = ::GetLastError();
char szMsg[128];
_snprintf_s(szMsg, sizeof(szMsg), _TRUNCATE, "Cannot load dfshim.dll: %lu", dwErr);
AfxMessageBox(szMsg);
return false;
}
}
It is kind of unprofessional not to rely on documentation. It it more like a hack, but I don't see an alternative way. This code works for us.
Related
I want to a create .dll, which shows some dialog.
In my .dll I have this code:
HWND hDlg = CreateDialogParam(NULL, MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);
if (!hDlg) {
ShowError(GetLastErrorAsString().c_str());
return false;
}
ShowError calls Message box and GetLastErrorAsString() just calls standard GetLastError and converts to string.
I have this output:
The specified resource type cannot be found in the image file.
Then I have a standard win32 Window application and there I call method, which calls the mentioned code.
DialogTest test;
test.showDialog(); // calls functionality from .dll
What I am doing wrong? Do I need to link resource files to .dll?
I am using Visual studio 2010 and dialog is specified in my resource file (.rc).
The error code and message are accurate: The resource cannot be found where you instructed the system to go looking for it: The executable image that was used to start the process, not your DLL. The behavior is documented (see CreateDialogParam):
hInstance [in, optional]
Type: HINSTANCE
A handle to the module which contains the dialog box template. If this parameter is NULL, then the current executable is used.
Since you have the dialog template stored inside your DLL, you will have to pass the HINSTANCE that identifies your DLL. There are a number of ways to get the correct value, but passing NULL or GetModuleHandle(NULL) won't work. Both of these return the module handle to the executable image that started the process (not your DLL).
The easy solution: Pick the hInstance passed into your DllMain and store it in a global variable for later use.
HINSTANCE g_hInst = NULL;
BOOL WINAPI DllMain( HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved ) {
switch ( fdwReason ) {
case DLL_PROCESS_ATTACH:
g_hInst = hinstDLL;
break;
default:
break;
}
return TRUE;
}
The robust solution: This solution can be used anywhere, in a DLL, an EXE, or a static LIB. Only down-side: It relies on undocumented features of Microsoft's linker. Don't worry, though, it won't fail silently.
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISMODULE ((HINSTANCE)&__ImageBase)
HINST_THISMODULE will always hold the correct value, regardless of where it is used.1)
The same can be achieved using official interfaces (GetModuleHandleEx) as well. The following solution can be used from an EXE, a DLL, or a static LIB as well, so long as you make sure to compile and link the function into the respective module:
HMODULE GetCurrentModuleHandle() {
HMODULE hModule = NULL;
GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
(LPCTSTR)GetCurrentModuleHandle,
&hModule );
return hModule;
}
This returns an HMODULE, not an HINSTANCE. This is not an issue, though, since they are the same thing2).
1) From Accessing the current module’s HINSTANCE from a static library
2) What is the difference between HINSTANCE and HMODULE?
You specified NULL as the first parameter to CreateDialogParam. If you want to load the dialog resource file from the Win32 Window Application, you should use this instead:
HWND hDlg = CreateDialogParam(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_RANKING_DIALOG), NULL, msgProc, NULL);
However, if you want to load it from the DLL itself, you should replace the first parameter with the HINSTANCE parameter from the DllMain entry point function of the DLL.
I have this MFC app that loads strings from string resource using CString::LoadString function. Each of the apps dialogue box's classes and its associated resources are contained in an MFC extension DLL.
CString::LoadString loads strings from the main module's(.exe) resource's string resource successfully but fails to load string from the DLL's resource's string resource.
In each case I get my instance handle for load string from CWinApp object by calling :
CWinApp *WinApp = AfxGetApp(),
and of course the instance's handle is WinApp->m_hInstance which I use as the first argument in my call to CString::LoadString function.
What could be the cause and what could be the solution.
Are you passing the EXE's HINSTANCE to load a string from the extension library? Sounds like it.
With MFC, if you have extension libraries and you make sure your string identifiers are unique, you just need to call the CString::LoadString(UINT nID) version. Because extension libraries create CDynLinkLibrary structures that go into a global linked list, the LoadString(UINT) function will search through all your MFC libraries until it finds the HINSTANCE that contains that string, and then it will load from there. If you insist on using the LoadString() function with an HINSTANCE argument, be sure to use the HINSTANCE of the extension DLL, and not the extension of the EXE when you want to load a string or dialog from the DLL.
For small projects, like less than a dozen DLLs, you probably manage to just use unique IDs for everything. When you get into the insanely large projects like 100+ DLLs, then you have to use other techniques like specially named functions in your DLL that call AfxSetResourceHandle() or know to always use the HINSTANCE of the DLL. That's another topic.
Just to complement Joe Willcoxson's answer, be sure to check that every MFC Extension DLL you are using,needs a special initialization code, similar to the example below:
#include "stdafx.h"
#include <afxdllx.h>
static AFX_EXTENSION_MODULE MyExtDLL = { NULL, NULL };
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
TRACE0("MyExt.DLL Initializing!\n");
// Extension DLL one-time initialization
if (!AfxInitExtensionModule(MyExtDLL, hInstance))
return 0;
new CDynLinkLibrary(MyExtDLL);
}
else if (dwReason == DLL_PROCESS_DETACH)
{
TRACE0("MyExt.DLL Terminating!\n");
// Terminate the library before destructors are called
AfxTermExtensionModule(MyExtDLL);
}
return 1; // ok
}
This code just takes care of CDynLinkLibrary creation, the key to share resources between MFC modules.
If all this are setup correctly -- and without ID clashes -- then it's simply a mather of calling:
CString str;
str.LoadString(IDS_MY_STRING_ID);
anywhere in your code, no matter where the string actually persists.
A good start point on resource IDs and numbering can be found in this link.
i made a win32 console application that imports an ".ocx" file from geovision SDK. I found proper CLSID and interface ID of COM components in generated ".tli" and ".tlh" headers and everything works until i invoke any method(Login2 for example in my code below). Then _com_exception occurs and it gives no detailed info about what exactly happens.
Can anybody give me a hint what should i do next or where should i look for solution? It took me over a week to reach this point of using COM components in console application... I hope its possible to do it.
#include "stdafx.h"
#include "stdio.h"
#import "C:\Windows\GeoOCX\SinglePlayer\20121003\GVSinglePlayer.ocx" \
named_guids no_namespace no_smart_pointers
int _tmain(int argc, _TCHAR* argv[])
{
try
{
CoInitialize(NULL);
_DGVSinglePlayer* pSP = 0;
HRESULT hr = CoCreateInstance(CLSID_GVSinglePlayer ,NULL, CLSCTX_INPROC_SERVER,DIID__DGVSinglePlayer,reinterpret_cast <void**>(&pSP));
_bstr_t lpIPAddress("11.11.11.11");
long iPort=10000;
_bstr_t lpUserID("abcde");
_bstr_t lpPassword("password");
if ( SUCCEEDED ( hr ) )
{
hr = pSP->Login2(lpIPAddress,iPort,lpUserID,lpPassword );
if ( SUCCEEDED ( hr ) )
{
printf("Cool");
}
}else
{
}
pSP->Release();
CoUninitialize();
} catch (_com_error& e)
{
char buf[80];
sprintf(buf, "Error: %S",e.Description());
printf("%s\n",buf);
}
return 0;
}
Since e.Description() prints no info, I attatched visual info about the error.
Many ActiveX controls want to be properly hosted (meaning, the host implements IOleClientSite and related interfaces, and passes the pointer to the control's IOleObject::SetClientSite). Such controls return E_UNEXPECTED for all method calls until the OLE activation dance is performed.
In particular, ActiveX controls developed with MFC usually behave this way; the behavior is baked into MFC framework.
I suspect your control might be one of those. In this case, you wouldn't be able to use it easily in a console app. You would need a windowed application using a framework that implements ActiveX hosting (MFC, ATL, WinForms; others likely exist that I'm not familiar with).
Sorry if my question is previously answered here but I have, for days, searched the internet including SO with no solution.
Basically I want to Implement Download Manager for IE webbrowser control (Not IDE itself).
I have read a lot on MSDN and among them is this link which shows how to create it.
The Problem with this example (and my problem in that case) is where do I register/apply the IServiceProvider to my web browser. The Article does not say. However searching I found this question and it say I quote
Use CAxWindow::QueryHost to get IObjectWithSite pointer. Call SetSite
passing your IServiceProvider implementation.
Unfortunately I don't use or know anything about ATL as I use wxWidgets. So where do I get that in wxWebview or "vanilla" MS COM?
here is what I have so far
HRESULT wxDownloadMgr::Download(IMoniker *pmk, IBindCtx *pbc,DWORD dwBindVerb,
LONG grfBINDF,BINDINFO *pBindInfo, LPCOLESTR pszHeaders,LPCOLESTR pszRedir,UINT uiCP )
{
// Get URL
LPOLESTR urlToFile;
HRESULT result = pmk->GetDisplayName( pbc, NULL, &urlToFile );
//OLECHAR is simply a wchar_t and an LPOLESTR is a wide character string (e.g. wchar_t*).
wxString url(urlToFile);
wxWebViewEvent event(wxEVT_COMMAND_WEB_VIEW_DOWNLOAD_BEGINS,GetId(), url, "");
event.SetEventObject(this);//WHICH OBJECT TO SET HERE????????
HandleWindowEvent(event);
::MessageBox(NULL,"Download","Download Manager",MB_OK);
return S_OK;
}
STDMETHODIMP wxServiceProvider::QueryService(REFGUID guidService,
REFIID riid,
void **ppv)
{
HRESULT hr = E_NOINTERFACE;
if (guidService == SID_SDownloadManager && riid == IID_IDownloadManager)
{
// Create new DownloadMgr object using ATL.
CComObject<wxDownloadMgr>* pDownloadMgr;
hr = CComObject<wxDownloadMgr>::CreateInstance(&pDownloadMgr);
// Query the new CDownloadMgr object for IDownloadManager interface.
hr = pDownloadMgr->QueryInterface(IID_IDownloadManager, ppv);
}
return hr;
}
You can override wxActiveXContainer::QueryClientSiteInterface to add your own interface implementation like IServiceProvider or IDocHostUIHandler to the client site. An example can be found in the wxIEContainer class.
I want to detour EndScene from an arbitrary DirectX 9 application to create a small overlay. As an example, you could take the frame counter overlay of FRAPS, which is shown in games when activated.
I know the following methods to do this:
Creating a new d3d9.dll, which is then copied to the games path. Since the current folder is searched first, before going to system32 etc., my modified DLL gets loaded, executing my additional code.
Downside: You have to put it there before you start the game.
Same as the first method, but replacing the DLL in system32 directly.
Downside: You cannot add game specific code. You cannot exclude applications where you don't want your DLL to be loaded.
Getting the EndScene offset directly from the DLL using tools like IDA Pro 4.9 Free. Since the DLL gets loaded as is, you can just add this offset to the DLL starting address, when it is mapped to the game, to get the actual offset, and then hook it.
Downside: The offset is not the same on every system.
Hooking Direct3DCreate9 to get the D3D9, then hooking D3D9->CreateDevice to get the device pointer, and then hooking Device->EndScene through the virtual table.
Downside: The DLL cannot be injected, when the process is already running. You have to start the process with the CREATE_SUSPENDED flag to hook the initial Direct3DCreate9.
Creating a new Device in a new window, as soon as the DLL gets injected. Then, getting the EndScene offset from this device and hooking it, resulting in a hook for the device which is used by the game.
Downside: as of some information I have read, creating a second device may interfere with the existing device, and it may bug with windowed vs. fullscreen mode etc.
Same as the third method. However, you'll do a pattern scan to get EndScene.
Downside: doesn't look that reliable.
How can I hook EndScene from an injected DLL, which may be loaded when the game is already running, without having to deal with different d3d9.dll's on other systems, and with a method which is reliable? How does FRAPS for example perform it's DirectX hooks?
The DLL should not apply to all games, just to specific processes where I inject it via CreateRemoteThread.
You install a system wide hook. (SetWindowsHookEx) With this done, you get to be loaded into every process.
Now when the hook is called, you look for a loaded d3d9.dll.
If one is loaded, you create a temporary D3D9 object, and walk the vtable to get the address of the EndScene method.
Then you can patch the EndScene call, with your own method. (Replace the first instruction in EndScene by a call to your method.
When you are done, you have to patch the call back, to call the original EndScene method. And then reinstall your patch.
This is the way FRAPS does it. (Link)
You can find a function address from the vtable of an interface.
So you can do the following (Pseudo-Code):
IDirect3DDevice9* pTempDev = ...;
const int EndSceneIndex = 26 (?);
typedef HRESULT (IDirect3DDevice9::* EndSceneFunc)( void );
BYTE* pVtable = reinterpret_cast<void*>( pTempDev );
EndSceneFunc = pVtable + sizeof(void*) * EndSceneIndex;
EndSceneFunc does now contain a pointer to the function itself. We can now either patch all call-sites or we can patch the function itself.
Beware that this all depends on the knowledge of the implementation of COM-Interfaces in Windows. But this works on all windows versions (either 32 or 64, not both at the same time).
I know this question is old, but this should work for any program using DirectX9, You are creating your own instance basically, and then getting the pointer to the VTable, then you just hook it. You will need detours 3.X btw:
//Just some typedefs:
typedef HRESULT (WINAPI* oEndScene) (LPDIRECT3DDEVICE9 D3DDevice);
static oEndScene EndScene;
//Do this in a function or whatever
HMODULE hDLL=GetModuleHandleA("d3d9");
LPDIRECT3D9(__stdcall*pDirect3DCreate9)(UINT) = (LPDIRECT3D9(__stdcall*)(UINT))GetProcAddress( hDLL, "Direct3DCreate9");
LPDIRECT3D9 pD3D = pDirect3DCreate9(D3D_SDK_VERSION);
D3DDISPLAYMODE d3ddm;
HRESULT hRes = pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm );
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp));
d3dpp.Windowed = true;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
WNDCLASSEX wc = { sizeof(WNDCLASSEX),CS_CLASSDC,TempWndProc,0L,0L,GetModuleHandle(NULL),NULL,NULL,NULL,NULL,("1"),NULL};
RegisterClassEx(&wc);
HWND hWnd = CreateWindow(("1"),NULL,WS_OVERLAPPEDWINDOW,100,100,300,300,GetDesktopWindow(),NULL,wc.hInstance,NULL);
hRes = pD3D->CreateDevice(
D3DADAPTER_DEFAULT,
D3DDEVTYPE_HAL,
hWnd,
D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_DISABLE_DRIVER_MANAGEMENT,
&d3dpp, &ppReturnedDeviceInterface);
pD3D->Release();
DestroyWindow(hWnd);
if(pD3D == NULL){
//printf ("WARNING: D3D FAILED");
return false;
}
pInterface = (unsigned long*)*((unsigned long*)ppReturnedDeviceInterface);
EndScene = (oEndScene) (DWORD) pInterface[42];
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)EndScene, newEndScene);
DetourTransactionCommit();
And then your function:
HRESULT WINAPI D3D9Hook::newEndScene(LPDIRECT3DDEVICE9 pDevice)
{
//Do your stuff here
//Call the original (if you want)
return EndScene(pDevice);
}
A slightly old question I know - but in case anyone is interested in doing this with C#, here is my example on hooking the Direct3D 9 API using C#. This utilizes EasyHook an open source .NET assembly that allows you to 'safely' install hooks from managed code into unmanaged functions. (Note: EasyHook takes care of all the issues surrounding DLL injection - e.g. CREATE_SUSPENDED, ACL's, 32 vs 64-bit and so on)
I use a similar VTable approach as mentioned by Christopher via a small C++ helper dll to dynamically determine the address of the IDirect3DDevice9 functions to hook. This is done by creating a temporary window handle, and creating a throw-away IDirect3Device9 within the injected assembly before then hooking the desired functions. This allows your application to hook a target that is already running (Update: note that this is possible entirely within C# also - see comments on the linked page).
Update: there is also an updated version for hooking Direct3D 9, 10 and 11 still using EasyHook and with SharpDX instead of SlimDX