I am writing\compiling a DLL that(currently) only exports a blank function. Source code:
DLLMain.cpp-
LIBRARYEXPORT LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
){
return 0;
}
Everything is okay so far, and here is my DLLMain.h-
using namespace std;
#include <iostream>
#include <fstream>
#include <string>
#include <Windows.h>
#define LIBRARYEXPORT __declspec(dllexport)
LIBRARYEXPORT LRESULT CALLBACK KeyboardProc(
int code,
WPARAM wParam,
LPARAM lParam
);
I plan to use this DLL with windows hooks to detect key presses, but when I call LoadLibrary from a separate executable, it returns with a runtime error saying
"DLL 'C:\Users\Orin\Documents\Visual Studio 2010\Projects\winmain\Debug\winmain.dll' is attempting managed execution inside OS Loader lock. Do not attempt to run managed code inside a DllMain or image initialization function since doing so can cause the application to hang."
That's great, but here's the catch: I'm not running any code at all in my KeyboardProc function, and I don't even have a DllMain routine
What I've tried(and hasn't worked):
Disabling CLR in project properties
Removing my "DllMain" routine
Using '#pragma unmanaged' when declaring functions
Suggestions and comments are really appreciated!
Found Answer:
When using Visual Studio, you must not choose a CLR Library project. Instead use the "Win32 Project" template. I can't believe I missed that!
Related
I am trying to hook the keyboard and mouse events of a target application.
I followed the SO question How to hook external process with SetWindowsHookEx and WH_KEYBOARD, and the hooks are installed and uninstalled correctly the first time. However, after I uninstall the hook once and then install it again, trying to uninstall the hook the second time crashes the target application. The purpose of the hook is to monitor application idle time, so that I can do some tasks when the application is idle.
I apologize for the length of the question, but I tried to put in all the details that might help
Thanks
I need to be able to install and uninstall the hooks based on menu commands from a system tray icon. I have a console application [HookApp] which calls the install and uninstall methods in a DLL [HookDLL]. The console application also creates a window to handle menu events. I use the thread of the window to actually install and uninstall the hooks, because the same thread that installed the hook must uninstall it. The Console and the window both must be invisible. Only the system tray icon and its associated menu must be visible.
I start the hooking application from the command line with the parameters
i. ProcessId of the target process
ii. Process Name
iii. Idle time [in seconds] -Idle time before starting the action in the DLL
I am wondering if the timer I start in the HookProcs is responsible for the crash.
Event Viewer Logs
Faulting application name: notepad.exe, version: 10.0.17134.1, time stamp: 0x9d4727c2
Faulting module name: HookDLL_x64.dll_unloaded, version: 0.0.0.0, time stamp: 0x5c31aabd
Exception code: 0xc0000005
Fault offset: 0x00000000000ba505
Faulting process id: 0x2bac
The exception code seems to suggest a memory access violation.
I have tried the following
I.
a. Call the SendMessageTimeout API with HWND_BROADCAST from HookApp
b. Call the SendMessageTimeout API with HWND_BROADCAST from HookDLL
based on Unloading DLL from all processes after unhooking global CBT hook
II.
a. call FreeLibraryAndExitThread API in the DLLMain method on DLL_PROCESS_DETACH AND DLL_THREAD_DETACH -both together and singly
based on http://www.rohitab.com/discuss/topic/42505-unloading-dll-crashes-exe/
III. Made the HookApp console and the window visible and hidden to see if it makes any difference
IV. Was unable to try the following because of 64 bit architecture
https://www.unknowncheats.me/forum/programming-for-beginners/73377-unload-injected-dll-thread-process.html
Other Links I referred to
a. Several programs crash when unhooking with UnhookWindowsHookEx()
b. How to correctly use SetWindowsHookEx & CallNextHookEx
c. Unloading an Injected DLL
d. FreeLibraryAndExitThread crashes program when unloading injected DLL
//Code in the DLL
extern "C" __declspec(dllexport) void install(unsigned long threadID,int _nIdleTime) {
nIdleTime = _nIdleTime;
Log(L"install proc called from app: _nIdleTime", _nIdleTime);
hhKeyboard = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hinst, threadID);
hhMouse = SetWindowsHookEx(WH_MOUSE, MouseProc, hinst, threadID);
logger->Log("Install");
logger->Log("Keyboard", (LONG)hhKeyboard);
logger->Log("Mouse", (LONG)hhMouse);
}
//Uninstall the dll from the Target Process
DWORD WINAPI UnInjectDLLFromTarget() {
uninstall();
//DWORD_PTR dwResult = 0;
//SendMessageTimeout(HWND_BROADCAST, WM_NULL, 0, 0, SMTO_ABORTIFHUNG | SMTO_NOTIMEOUTIFNOTHUNG, 1000, &dwResult);
return TRUE;
}
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam) {
if (code < 0) {
return CallNextHookEx(0, code, wParam, lParam);
}
StartTimer();
Beep(1000, 20);
return CallNextHookEx(hhKeyboard, code, wParam, lParam);
}
LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) {
if (code < 0) {
return CallNextHookEx(0, code, wParam, lParam);
}
// StartTimer();
//Beep(1000, 20);
return CallNextHookEx(hhMouse, code, wParam, lParam);
}
BOOL WINAPI DllMain(__in HINSTANCE hinstDLL, __in DWORD fdwReason, __in LPVOID lpvReserved) {
if (fdwReason == DLL_PROCESS_DETACH || fdwReason==DLL_THREAD_DETACH) {
FreeLibraryAndExitThread(hinstDLL, 0);
return 0;
}
}
//Code in the Application [HookApp]
Similar to [But not exactly the same - It is a bit more involved because of the need to create the message pump and the menu event handling window]
HINSTANCE hinst = LoadLibrary(_T("MyDLL.dll"));
if (hinst) {
typedef void (*Install)(unsigned long);
typedef void (*Uninstall)();
Install install = (Install) GetProcAddress(hinst, "install");
Uninstall uninstall = (Uninstall) GetProcAddress(hinst, "uninstall");
install(threadID);
Sleep(20000);
uninstall();
}
SendMessageTimeout in the DLL [HookDLL] method Uninstall immediately crashes the application
SendMessageTimeout in the application [HookApp] doesnt appear to do anything useful.
FreeLibraryAndExitThread does not appear to do anything useful.
However, with 2 and 3, I think I am able to install the hook for the second time. Without them, the first unhook crashes the application.
I was unable to try the suggestion using assembly language inline because of 64 bit architecture.
Please help.
for uninstall hook and unload your dll all what you need - call UnhookWindowsHookEx for every hook handle obtained by a previous call to SetWindowsHookEx. all. you not need call FreeLibrary[AndExitThread] yourself. system auto call FreeLibrary on your hook dll after UnhookWindowsHookEx callend, when first (any) message will be received by target application thread and this thread call GetMessage or PeekMessage. so for just unload your dll after several UnhookWindowsHookEx - you need post message to thread, for which you install hook. if you do this for concrete single thread (dwThreadId) - you need PostThreadMessageW(dwThreadId, WM_NULL, 0, 0); - system yourself call FreeLibrary ( called from user32!__ClientFreeLibrary which called from ntdll!KiUserCallbackDispatcher - called inside GetMessage or PeekMessage when thread (or it window) got any message)
call FreeLibrary from dll for yourself - always error - if assume dll will be unloaded by this call - to where we return after call ? to unloaded place. call FreeLibraryAndExitThread exist sense in some cases, but only from thread, which you create yourself. call FreeLibraryAndExitThread from dll entry point at all fatal error - you kill not self thread, thread which you kill - hold critical section (loader lock) inside which called dll entry point - so fatal error. and at all absolute senseless call here - if you say receive DLL_PROCESS_DETACH this mean that dll already in unload process. DLL_THREAD_DETACH - arbitrary point, why and how many time you try call unload for self here ? exit thread while holding process wide critical section without release it. fatal error.
also because the same thread that installed the hook must uninstall it. - this is not true. another thread from also can do this.
also StartTimer(); in your code look like suspicious here. what this code is do ? are and where you cancel timer ?
I'm working on a BHO written a long time ago in C++, without the use of any of the VS wizards. As a result, this project deviates from the COM conventions and the boilerplate for a COM product. I worked with COM long ago, but never really did any Windows GUI/dialog stuff...
I'm trying to add a dialog box to allow the user to set the values of some new settings:
// serverDialog will be NULL
HWND serverDialog = CreateDialog(GetModuleHandle(NULL), MAKEINTRESOURCE(IDD_PROPPAGE_SETTINGS), NULL, DialogProc);
id (!serverDialog)
{
int error = GetLastError(); //1813
...
}
....
1813 means that the resource cannot be found. The IDD used there is in resource.h, which I manually included where needed.
DialogProc is defined as:
INT_PTR CALLBACK DialogProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
return FALSE;
}
Which I know I will have to change later if I want the dialog to actually process messages, but I haven't gotten that far yet. The 1813 error suggests failure before the dialog is even created as does the NULL dialog handle returned.
To add the dialog I used the Add Resource wizard and added a small property page.
I've tried to follow advice here, but to no avail.
Thanks!
You are passing GetModuleHandle(NULL) as the instance of the module that contains the resource. But GetModuleHandle(NULL) defines the executable file module. You need to pass the instance of the module containing your code. This question covers that topic: How do I get the HMODULE for the currently executing code?
You probably ought to pass a window handle to the hWndParent parameter so that the dialog is owned.
Having searched for days now i decided to post a question here and hope that somebody has the ultimate idea or advice.
I wrote a WINAPI wrapping mechanism consisting of a WindowManager and a WINAPIWindow class. The latter uses the famous "First WINAPI Window" functionality known from most tutorials in a more structured manner, mainly HWND and HINSTANCE.
Remarks: the macro "_ WINDOWS _" (without spaces but this tool makes it bold otherwise ) is a macro defined in one of my headers to determine, wether the compilation environment supports WIN32 and the WINAPI.
#if defined(_ _WINDOWS_ _)
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
#pragma region WINAPIWindow
class WINAPIWindow : public WindowBase
{
friend class WindowManager;
public:
virtual ~WINAPIWindow();
RESULT show();
inline HWND handle() const;
LRESULT CALLBACK wndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
private:
WINAPIWindow(__in const HINSTANCE hInstance, __in const Rect& bounds, __in const String& title = "", __in const int flags = WDF_DEFAULT);
HRESULT createWindowClass(__in const HINSTANCE hInstance, __in const String& clsName);
tInt16 _wndState;
HWND _hWnd;
};
typedef WINAPIWindow Window;
#pragma endregion
#elif
The mechanism is located in a static library called "ShirabePlatformFeatureLayer.lib".
This static library uses classes and code from another custom static lib called "ShiCore.lib" which does not use any platform dependent code.
My actual application project (x64!) now imports both as additional depenencies using the WindowManager.
Although both library projects compile fine and without errors, compiling the Application Project leads to the following error messages.
Error 43 error LNK2019: unresolved external symbol "public: struct HWND__ * __cdecl ShirabePlatformFeatureLayer::WINAPIWindow::handle(void)const " (?handle#WINAPIWindow#ShirabePlatformFeatureLayer##QEBAPEAUHWND__##XZ) referenced in function wWinMain C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Win32TestProject\main.obj Win32TestProject
Error 45 error LNK2019: unresolved external symbol "__int64 __cdecl ShirabePlatformFeatureLayer::gDefaultWndProcFwd(struct HWND__ *,unsigned int,unsigned __int64,__int64)" (?gDefaultWndProcFwd#ShirabePlatformFeatureLayer##YA_JPEAUHWND__##I_K_J#Z) referenced in function "private: long __cdecl ShirabePlatformFeatureLayer::WINAPIWindow::createWindowClass(struct HINSTANCE__ * const,class ShirabeCORE::String const &)" (?createWindowClass#WINAPIWindow#ShirabePlatformFeatureLayer##AEAAJQEAUHINSTANCE__##AEBVString#ShirabeCORE###Z) C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Win32TestProject\ShirabePlatformFeatureLayer.lib(Window.obj) Win32TestProject
Error 44 error LNK2001: unresolved external symbol "public: struct HWND__ * __cdecl ShirabePlatformFeatureLayer::WINAPIWindow::handle(void)const " (?handle#WINAPIWindow#ShirabePlatformFeatureLayer##QEBAPEAUHWND__##XZ) C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Win32TestProject\ShirabePlatformFeatureLayer.lib(WindowManager.obj) Win32TestProject
Error 46 error LNK1120: 2 unresolved externals C:\Users\Dev.Dev-PC\Documents\Workspaces\ShirabeEngine\ShirabeDevelopment\Debug\Win32TestProject.exe Win32TestProject
I checked, whether the methods are declared and defined properly. I also included and imported the libs.
#if defined(_ _WINDOWS_ _)
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "gdi32.lib")
#include <Windows.h>
#endif
In addition i registered the 3 libs above as additional dependencies and the lib-directories are $(VC_LibraryPath_x64) and $(WindowsSDK_LibraryPath_x64).
My first thoughts after having analyzed this a bit is, that all methods or functions that use WINAPI classes and structs are not linked into the import library "ShirabePlatformFeatureLayer.lib". Having registered them above 3 libs as additional dependencies with equal library paths as above and the /VERBOSE:LIB shows me that the libraries are appended but not with "x64\gdi32.lib" as the message but "GDI32.DLL". Likewise for the other two.
Doing /VERBOSE:LIB in the application project shows me the actual relative paths to the "~.lib" and not "~.DLL".
What can cause the methods to not being linked/included/important when they use WINAPI functionality?
Is the general build design with so many .libs the problem?
Does anybody else have an idea?
Here the entire affected code ( imho ): http://pastebin.com/f7MaBBwM
If any further information is required, please tell me.
EDIT: I've continued searching and came up with the "project to project" dependencies in the new MSBuild system. Although this appeared to be the same problem, it isn't since obviously the dependency of "ShirabePlatformFeatureLayer.lib" to the import libs kernel32, gdi32 and user32 causes problem, when effectively being consumed by the Win32TestProject using the ShirabePlatformFeatureLayer.lib code.
Unfortunately i wasn't able to solve the problem yet with the various advice given est. 10 different articles on the topic. :/
Edit: Consulting Rodrigo s remarks i was able to get rid of the handle() unresolved symbol. However the second with gDefaultWndProcFwd seems to be a logic/design error.
Once i managed to get 10 Reputation I'll attach an image of the relation between WindowManager, WINAPIWindow and gDefaultWndProcFwd!
That said here a textual description:
1) Creating the window implies creating the WindowClassEx structure that refers to gDefaultWndProcFwd using a forward declaration in Window.h.
2) When the window is created and shown the method should be called, which consults WIndowManager::get(key : HWND) : WindowBase*;
3) If found, the function invokes wndProc on the window pointer and leaves handling to the specified implementation of the wndproc.
The gDefaultWndProcFwd is declared and defined in WindowManager.h/.cpp.
The design flaw becomes more and more obvious, as I'm thinking about a solution!
See the pastebin link for the actual code!
Thank you very much for your help in advance.
Sincerely, Marc
You have 2 unresolved external symbols:
HWND ShirabePlatformFeatureLayer::WINAPIWindow::handle(void) const
LRESULT ShirabePlatformFeatureLayer::gDefaultWndProcFwd(HWND,UINT,WPARAM,LPARAM)
The first one is probably due to handle() being inline. You probably defined it in the CPP file (or you forgot it?) , but since it is inline, the definition is not exported. Instead it is expected to be available to every compilation unit that needs it. In other words, inline functions should be defined in the same header file as the declaration.
The second one is trickier without seeing all your code. But I'd bet that you simply forgot to write the defintion of gDefaultWndProcFwd(). Or maybe you wrote it in a different namespace, or with different parameters.
Note that static libraries are not linked, so unresolved symbol errors such as yours, will never happen when building the library, even when the defect is in the library itself. Linker errors will always happen when linking the final executable.
UPDATE: Ok, I said it was tricky... Re-reading your code I noticed that the offending function is declared twice, and defined once. That itself is not a problem, but look at the two declarations together:
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam);
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
And the definition is:
LRESULT CALLBACK gDefaultWndProcFwd(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam)
Do you see the difference? WPARAM and LPARAM are swapped!!!
I really want to use some features from MFC but its been a pain to get working.
All I originally wanted to do was add two Spin Control and their respective Edit Controls. Once I implemented their appropriate methods to set Range, I found out I needed to use MFC.
So VS complain no MFC. So I go to project properties and add Use MFC shared DLL. Run it, Crash!
Unhandled exception at 0x5964D8D2 (mfc120ud.dll) in Win32Project1.exe: 0xC0000005: Access violation reading location 0x00000000
So I tried Static, ERRORS! Lots of linker errors, to many to list.
So I went back to Shared. The error occurs right in this area.
/////////////////////////////////////////////////////////////////////////////
// export WinMain to force linkage to this module
extern int AFXAPI AfxWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow);
extern "C" int WINAPI
_tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
_In_ LPTSTR lpCmdLine, int nCmdShow)
#pragma warning(suppress: 4985)
{
// call shared/exported WinMain
return AfxWinMain(hInstance, hPrevInstance, lpCmdLine, nCmdShow);
}
with an arrow at the last }
Locals shows the value of hInstance as red with +
hInstance 0x000d0000 {Win32Project1.exe!_IMAGE_DOS_HEADER ImageBase} {unused=9460301 } HINSTANCE *
and at lpCmdLine
+ lpCmdLine 0x00831f8c L"" wchar_t *
This is beyond my expertise of debugging and quite frankely would consider another alternative to the spin box that doesn't use MFC, but it seems like I'm need MFC more and more as I want to include more functionality, so it would be nice to get MFC working, but it also seems a lot more fragile. Perhaps to sensitive for a crude programmer such as myself.
I'm wondering if #includes could be a cause of this error? Either the order? Or lack thereof?
Here is what I have so far in stdafx.h
#pragma once
#pragma comment ( lib, "user32.lib" )
#pragma comment ( lib, "comctl32.lib" )
#pragma comment ( lib, "winmm.lib")//to play audio
#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
#include "targetver.h"
//#include <WinSDKVer.h>
//#include <afxwin.h>
#include <afxcmn.h>//for spinControl
#include <Afx.h>
#include <stdio.h>
#include <tchar.h>
#include "iostream"
#include "string.h"
#include <math.h>
//#include <ctime>//more time related stuff
#include <fstream>//for file io
#include <thread>//for threads
//#include <chrono> //for time related stuff
//#include <windows.h>
#include <Mmsystem.h>//to play audio
#include <commctrl.h>
#include <atlstr.h>//for some type of string
#include <io.h>
#include <fcntl.h>
#include <commctrl.h> //For button sytles, maybe other styles
This can never work. Remove your WinMain.
You Need a CWinApp object for your application. And with this CWinApp Object thee is a MFC specific WinMain entry point.
The MFC relays on an internal singleton that points to your CWinApp object. Without it nearly everything can fail, and can throw ASSERTs.
I would suggest that you create a sample MFC app, then move the MFC code from the sample app to your Win32 app. If the Win32 app is smaller, you can instead move the Win32 code to the MFC app.
Typically, instead of WinMain, you would use CWinApp class from the sample app.
If you do not intend to use the MFC UI classes & only wish to use some supporting classes like CString etc, then you can create a sample console app with MFC support which will tell you how to use CString in console app. The console app will give you an insight on how to add the required headers in your Win32 project.
As the previous answers have mentioned, but I thought I'd clarify - try adding a CWinApp (or CWinAppEx) object in your code to define the WinMain, for example:
class MyApp : public CWinApp
{
public:
virtual BOOL InitInstance()
{
// Add initialisation code here e.g. show a dialog or main window, etc.
return TRUE; // enter the message loop;
// could return FALSE to just exit the application if for example the
// dialog response is all you need to then quit.
}
};
// And somewhere in your code be sure to instantiate the object so that it can be linked
MyApp theApp;
I want to subclass RichEdit in my program (here is c++ code: http://dumpz.org/46182/). _native_log is a hwnd of richedit. At first all works fine and LogWindow::wndProc callback called normal, but if i set some text in RichEdit or click on them LogWindow::wndProc stops work (there no any further calls of it). Is there any thoughts what's i do wrong?
void LogWindow::replaceNativeLog(HWND native_log_handle) {
_native_log = native_log_handle;
SendMessage(_native_log, EM_GETOLEINTERFACE, 0, (LPARAM) &_rich_edit_ole);
_old_wnd_proc = (WNDPROC) SetWindowLongPtr(_native_log, GWLP_WNDPROC, (LONG) &wndProc);
}
LRESULT LogWindow::wndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
switch (Msg) {
case EM_STREAMIN:
break;
case WM_SETTEXT:
break;
};
return CallWindowProc(_old_wnd_proc, _native_log, Msg, wParam, lParam);
}
Starting with Common Controls version 6 the procedure of subclassing windows has been revised to eliminate the issues with previous versions. In particular it is no longer a problem if a control is subclassed more than once.
A comparison between subclassing pre-v6 Common Controls and the v6 way of doing things can be found at "Subclassing Controls". Instead of calling SetWindowLongPtr to replace the window procedure there is SetWindowSubclass which in addition to replacing the window procedure does all the internal bookkeeping. A consequence of the redesign is that you do not have to store a pointer to the previous window procedure either; if you need to call into the original window procedure there is DefSubclassProc at your disposal.
This of course will only help if all competing clients trying to subclass the a control all agree on using the v6 style subclassing.
Finally, I found the problem. I actually develop a plugin for Miranda IM, and there was another function trying to subclass richedit i want. So there is a kind of conflict between my and that functions. Thanks all for trying to help.