0

I've recently come up with some code that logic (and various places on the internet) says should work. When injecting my Win32 DLL into any program though to test it, the Window I've create doesn't appear. I have no idea why this is, my code is as follows:

main.cpp

#include "stdafx.h"
#include "resource.h"
#include <tchar.h>

HWND PGHWND;

BOOL CALLBACK EventHandler(HWND hDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)
{
    return 0;
}

DWORD WINAPI MainWin(HMODULE hMod)
{
    DialogBox(hMod, MAKEINTRESOURCE(IDD_DIALOG1), NULL, (DLGPROC)EventHandler);
    ExitThread(0);
    return 0;
}

void GetWnd()
{
    DialogBox(0,MAKEINTRESOURCE(IDD_DIALOG1),0,0);
    for(;;)
    {
        PGHWND = FindWindow(NULL, "3D Pinball for Windows - Space Cadet");
        if(PGHWND)
        {
            break;
        }
    }
}

__declspec(dllexport) bool __stdcall DllMain(HMODULE hModule,DWORD Reason,LPVOID lpv) //DllMain
{      
    switch (Reason){ //What happened?
        case DLL_PROCESS_ATTACH: //Did the DLL attach?
            DisableThreadLibraryCalls(hModule); //Disable THREAD_ATTACH and THREAD_DETACH
            CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MainWin, hModule, 0, NULL); //Start the thread to create the dialog
            CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)&GetWnd,NULL,0,NULL); //Start our thread to get the window
            MessageBox(0, _T("This program was created by Joe Savage"), _T("Pinball Modifications!"), 0);
            break;
        break;
    }
    return true;
}

Main.rc

// Generated by ResEdit 1.5.4
// Copyright (C) 2006-2010
// http://www.resedit.net

#include <windows.h>
#include <commctrl.h>
#include <richedit.h>
#include "resource.h"




//
// Dialog resources
//
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
IDD_DIALOG1 DIALOG 0, 0, 55, 24
STYLE DS_3DLOOK | DS_CENTER | DS_MODALFRAME | DS_SHELLFONT | WS_CAPTION | WS_VISIBLE | WS_POPUP | WS_SYSMENU
CAPTION "Dialog"
FONT 8, "Ms Shell Dlg"
{
    DEFPUSHBUTTON   "OK", IDOK, 3, 3, 50, 14
}

resource.h

#ifndef IDC_STATIC
#define IDC_STATIC (-1)
#endif

#define IDD_DIALOG1                             100
  • 1
    Did you debug it? What about error handling? Does your code even run? Tip: NEVER cast function pointers. Erase the `(DLGPROC)` and `(LPTHREAD_START_ROUTINE)` from your code. And a final red flag: you should not be doing anything in `DllMain`. See here: http://stackoverflow.com/questions/1688290/creating-a-thread-in-dllmain – tenfour Oct 09 '11 at 10:48
  • The code all runs correctly - but the window simply doesn't show. I've tried removing the casts, but this doesn't help either.. –  Oct 09 '11 at 11:00
  • The most important code, the one that does the injecting, is missing. Odds are also very good that the dialog box simply isn't visible, either because it is a full screen DirectX app or because the window is hidden behind the main one. – Hans Passant Oct 09 '11 at 12:35
  • 1
    @tenfour Casting function pointers is not terribly safe, but can be necessary (see `GetProcAddress`, which only ever returns on type of function and must be cast into the proper type). – ssube Oct 09 '11 at 13:32
  • What's the error-code returned by `GetLastError`? –  Oct 10 '11 at 19:19

1 Answers1

0

In function GetWnd() the statement DialogBox(0,MAKEINTRESOURCE(IDD_DIALOG1),0,0); is wrong.

it must be something like :

DialogBox( hInst ,MAKEINTRESOURCE(IDD_DIALOG1),0 ,EventHandler );

where hInst is the instance-handle of your dll.

engf-010
  • 3,980
  • 1
  • 14
  • 25
  • If you mean simply putting "DefDlgProc(hDlg, uMsg, wParam, lParam);" into the EventHandler function - then this doesn't appear to have done anything :( –  Oct 09 '11 at 11:50
  • @Joesavage: you don't process any message in EventHandler. Try "return DefDlgProc( hDlg ,uMsg ,wParam ,lParam );" and if that doesn't work you must process some messages to get the dialog working. – engf-010 Oct 09 '11 at 11:56
  • I've tried adding the return, and that didn't do anything. And I also tried processing some messages (such as WM_INITDIALOG) and doing some basic processing, but this didn't help either. I ever tried making WM_INITDIALOG always return true and the whole event handler always return true, but it didn't help :/ –  Oct 09 '11 at 12:09
  • You can check the return-value of the call to DialogBox(...) if it's -1 then you could call GetLastError() to get the actual error that occured. BTW if the GetWnd-Thread is executed then you should give the DLGPROC-parameter a value (that one is missing). – engf-010 Oct 09 '11 at 12:23
  • Note: you GetWnd-function does have the LPTHREAD_START_ROUTINE signature. – engf-010 Oct 09 '11 at 12:28
  • Giving EventHandler some parameters means that the code in it now gets executed: EventHandler(NULL, WM_INITDIALOG, 0, 0)! The problem is that the window still doesn't appear... –  Oct 09 '11 at 12:36
  • From the SDK docs: `The DefDlgProc function must not be called by a dialog box procedure; doing so results in recursive execution` – Hans Passant Oct 09 '11 at 12:37
  • @HansPassant I'm not using DefDlgProc anymore though, so that shouldn't be the problem. –  Oct 09 '11 at 12:39
  • @HansPassant: I knew there was something the matter with DefDlgProc ,didn't read the last sentence in the docs. – engf-010 Oct 09 '11 at 12:49
  • @Joesavage1: Not sure what you did with giving some parameters to EventHandler. The thing that meant is in the call to DialogBox(...) in GetWnd() there are 2 things wrong. First the HINSTANCE parameter is NULL which means your resource is only searched in the System (not your DLL). Secondly the DLGPROC parameter is NULL which should be set to EventHandler. – engf-010 Oct 09 '11 at 12:56
  • @Edwin But I don't have a hInst, I just want it to use the process of whatever it's attached to. Do I even need the DialogBox in GetWnd? I already have the one in MainWin? (Removing the DialogBox in GetWnd doesn't seem to make a difference when testing) –  Oct 09 '11 at 13:13
  • A FALSE return is correct. http://msdn.microsoft.com/en-us/library/windows/desktop/ms644995%28v=vs.85%29.aspx#procedures – Hans Passant Oct 09 '11 at 13:19
  • @JoeSavage1: Make the signature of GetWnd() the same as that of WinMain and make the CreateThread call the same as that of the to WinMain-Thread (passing hMod). Or use GetInstanceHandle(NULL) to get the handle of the Dll (but I don't know if that is allowed during execution of DllMain). – engf-010 Oct 09 '11 at 13:21
  • @HansPassant: you're right ,was confusing WM_INITDIALOG with WM_CREATE. – engf-010 Oct 09 '11 at 13:34
  • Making the DialogBox call in GetWnd correct (with the hMod and such) doesn't seem to affect it at all - the Window still doesn't appear. –  Oct 09 '11 at 13:48
  • Did you check the return value of DialogBox(...) and possibly GetLastError() like I suggested before ? Does the code in your threads even get executed? – engf-010 Oct 09 '11 at 13:57
  • Instead of your DialogBoxes ,try the use of MessageBoxes. If that doesn't work then there is something else wrong. – engf-010 Oct 09 '11 at 14:01