Hi guys!

I get this exact error Main.obj : error LNK2001: unresolved external symbol "public: int __thiscall CGui::GetActiveState(void)" (?GetActiveState@CGui@@QAEHXZ)
Release/test.dll : fatal error LNK1120: 1 unresolved externals

Heres the code:

#include "Gui.h"

#define WINDOW "3D World" 

HWND ( __stdcall *pCreateWindowExA )( DWORD, LPCTSTR, LPCTSTR, DWORD, int, int, int, int, HWND, HMENU, HINSTANCE, LPVOID );
FARPROC ( __stdcall *pGetProcAddress )( HMODULE, LPCSTR );
BOOL ( __stdcall *pSetCursorPos )( int, int );
BOOL ( __stdcall *pGetCursorPos )( LPPOINT );

void *InterceptDllCall( char *szDllName, char *szFuncName, DWORD dwNewFunction );

WNDPROC pWndProc;

LRESULT __stdcall myWndProc( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
{
	switch( iMsg )
	{
		case WM_SYSKEYDOWN:
		case WM_KEYDOWN:
		case WM_SYSKEYUP:
		case WM_SYSCHAR:
		case WM_CHAR:
		case WM_KEYUP:
		case WM_MOUSEMOVE:
		case WM_LBUTTONDOWN:
		case WM_LBUTTONUP:
		case WM_RBUTTONDOWN:
		case WM_RBUTTONUP:
			// Check for these messages only.
			if( !Gui.HandleMsg( iMsg, wParam, lParam ) )
				return( 0 );
	}

	// Call original WinProc
	return( CallWindowProc( pWndProc, hWnd, iMsg, wParam, lParam ) );
}

void SubClass( HWND hWnd )
{
	Gui.SetWinHandle( hWnd );

	// Store the original WinProc
	pWndProc = ( WNDPROC )GetWindowLong( Gui.GetWinHandle( ), GWL_WNDPROC );

	// Set the game's WinProc to ours.
	SetWindowLong( Gui.GetWinHandle( ), GWL_WNDPROC, ( long )myWndProc );
}

BOOL __stdcall mySetCursorPos( int x, int y )
{
	Gui.SetOrigMouse( x, y );

	if( Gui.GetActiveState( ) == 1 )
		return( TRUE );
	
	return( pSetCursorPos( x, y ) );
}

BOOL __stdcall myGetCursorPos( LPPOINT lpPoint )
{
	BOOL bRetval = pGetCursorPos( lpPoint );

	if( Gui.GetActiveState( ) == 1 )
	{
		// So the view doesnt move.
		lpPoint->x = Gui.GetOrigMouse( 0 );
		lpPoint->y = Gui.GetOrigMouse( 1 );
		return( TRUE );
	}

	return( bRetval );
}

HWND __stdcall myCreateWindowExA( DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent, HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam )
{
	HWND hRetval = pCreateWindowExA( dwExStyle, lpClassName, lpWindowName, dwStyle, x, y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam );

	if( lpWindowName && strstr( lpWindowName, WINDOW ) )
		SubClass( hRetval );

	return( hRetval );
}

FARPROC __stdcall myGetProcAddress( HMODULE hModule, LPCSTR lpProcName )
{
	if( HIWORD( lpProcName ) )
	{
		if( !strcmp( lpProcName, "GetProcAddress" ) )
		{
			return( ( FARPROC )myGetProcAddress );
		}
		else if	( !strcmp( lpProcName, "glEnable" ) )
		{
			// hook glEnable, store original in pglEnable
			pGetProcAddress( hModule, lpProcName );
			_asm mov [pglEnable], eax

			return( ( FARPROC )myglEnable );
		}
		else if	( !strcmp( lpProcName, "glViewport" ) )
		{
			// hook glViewport, store original in pglViewport
			pGetProcAddress( hModule, lpProcName );
			_asm mov [pglViewport], eax

			return( ( FARPROC )myglViewport );
		}
	}

	return( pGetProcAddress( hModule, lpProcName ) );
}

bool __stdcall DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
{
	switch( dwReason ) 
	{ 
		case DLL_PROCESS_ATTACH:
		{
			// hook GetProcAddress, CreateWindowExA, GetCursorPos and SetCursorPos

			InterceptDllCall( "kernel32.dll", "GetProcAddress", ( DWORD )&myGetProcAddress );
			_asm mov [pGetProcAddress], eax

			InterceptDllCall( "user32.dll", "CreateWindowExA", ( DWORD )&myCreateWindowExA );
			_asm mov [pCreateWindowExA], eax

			InterceptDllCall( "user32.dll", "GetCursorPos", ( DWORD )&myGetCursorPos );
			_asm mov [pGetCursorPos], eax

			InterceptDllCall( "user32.dll", "SetCursorPos", ( DWORD )&mySetCursorPos );
			_asm mov [pSetCursorPos], eax
			break;
		}
	}

	return( true );
}

#define MakePtr( type, ptr, addValue )( type )( ( DWORD )( ptr ) + ( DWORD )( addValue ) )

void *InterceptDllCall( char *szDllName, char *szFunctionName, DWORD pNewFunction )
{
	HMODULE hModule = GetModuleHandle( 0 );

	PIMAGE_DOS_HEADER pDosHeader;
	PIMAGE_NT_HEADERS pNTHeader;
	PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
	PIMAGE_THUNK_DATA pThunk;

	DWORD dwOldProtect, dwOldProtect2;

	void *pOldFunction;

	if( !( pOldFunction = GetProcAddress( GetModuleHandle( szDllName ), szFunctionName ) ) )
		return( NULL );

	pDosHeader = ( PIMAGE_DOS_HEADER )hModule;

	if( pDosHeader->e_magic != IMAGE_DOS_SIGNATURE )
		return( NULL );

	pNTHeader = MakePtr( PIMAGE_NT_HEADERS, pDosHeader,pDosHeader->e_lfanew );

	if( pNTHeader->Signature != IMAGE_NT_SIGNATURE || ( pImportDesc = MakePtr( PIMAGE_IMPORT_DESCRIPTOR, pDosHeader, pNTHeader->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress ) ) == ( PIMAGE_IMPORT_DESCRIPTOR )pNTHeader )
		return( NULL );

	while( pImportDesc->Name )
	{
		char *szModuleName = MakePtr( char *, pDosHeader,	pImportDesc->Name );
		if( !stricmp( szModuleName, szDllName ) )
			break;
		pImportDesc++;
	}
	if( pImportDesc->Name == NULL )
		return( NULL );

	pThunk = MakePtr( PIMAGE_THUNK_DATA, pDosHeader,	pImportDesc->FirstThunk );
	while( pThunk->u1.Function )
	{
		if( pThunk->u1.Function == ( DWORD * )pOldFunction )
		{
			VirtualProtect( ( void * )&pThunk->u1.Function, sizeof( DWORD ), PAGE_EXECUTE_READWRITE, &dwOldProtect );
			pThunk->u1.Function = ( DWORD * )pNewFunction;
			VirtualProtect( ( void * )&pThunk->u1.Function, sizeof( DWORD ), dwOldProtect, &dwOldProtect2 );
			return( pOldFunction );
		}
		pThunk++;
	}
	return( NULL ); 
}

you have to either include the implementation file for Gui class in the dll project, or link with a *.lib file that includes it in either another dll or static library.

This article has been dead for over six months. Start a new discussion instead.