dll initializing

Started by
8 comments, last by b1gjo3 15 years, 10 months ago
ok so i have this dll application which runs an instance of this dll provided below. the problem i am having is that this dll seems to keep getting re-initialized whenever i select over to another window process. thus, the filepath variable i set by using my main exe program is not initialized by all later calls from other processes. how can i stop this dll from being initialized more than once? .dll file

#include <windows.h>
#include <CharFunc.h>
#include <iostream>
#include <fstream>

#pragma data_seg("SharedBlock")
	HINSTANCE	hInst = NULL;
	HHOOK		keyHook = NULL;
	FILE*		file1 = NULL;
	char*		filepath = NULL;
	int	        hookState = -1;
#pragma data_seg()

extern "C" __declspec (dllexport) int _stdcall GetHookState()
{
	return hookState;
}

extern "C" __declspec (dllexport) int _stdcall AppendToLog(char* append)
{
	fopen_s(&file1, filepath, "a");
	fwrite(append, 1, strlen(append), file1);
	fclose(file1);
	return 0;
}

extern "C" __declspec (dllexport) LRESULT CALLBACK __stdcall KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
	if ( (code < 0) || (wParam == VK_CONTROL) || (wParam >= VK_F1 && wParam <= VK_F11))
		return CallNextHookEx(keyHook, code, wParam, lParam);

	if (code == HC_ACTION)
	{
		if( (GetKeyState(VK_SHIFT) & 0x8000) != 0)
			shiftState = true;
		else
			shiftState = false;

		if ((HIWORD(lParam) & KF_UP) == 0)
		{
			MessageBox(NULL, ConvertCharToWide(filepath), TEXT("FilePath"), MB_OK);
			fopen_s(&file1, filepath, "a");

                        count++;
                        //..output int to file
                       
			fclose(file1);
		}//end key up
	}//end if (code == HC_ACTION)
	return  CallNextHookEx(keyHook, code, wParam, lParam);	
}

extern "C" int __declspec (dllexport) __stdcall SetKeyboardHook(char* fpath)
{
	//set the keyboard hook
	keyHook = SetWindowsHookEx(WH_KEYBOARD, KeyboardProc, hInst, 0); 

	if (keyHook == NULL)
	{
		//MessageBox(NULL, TEXT("Could Not Set Hook"), TEXT("Error #003"), NULL);
		hookState = -1;
		return -1;
	}
	else
	{
		filepath = new char[strlen(fpath) + 1];
		strcpy_s(filepath, strlen(fpath) + 2, fpath);
		//MessageBox(NULL,TEXT("Hooked"),TEXT("Hookoed"),MB_OK);
		hookState = 0;
		return 0;
	}
}

extern "C" int __declspec (dllexport) __stdcall UnsetKeyboardHook()
{
	//unhook
	UnhookWindowsHookEx(keyHook);

	if (filepath != NULL)
		delete [] filepath;

	hookState = -1;
	//MessageBox(NULL,TEXT("Unhooked"),TEXT("Unhooked"),MB_OK);
	return 0;
}

extern "C" BOOL __declspec (dllexport) __stdcall DllMain (HINSTANCE hInstance, DWORD reason, LPVOID reserved)
{
	switch (reason)
	{
		case DLL_PROCESS_ATTACH:
		{
			//save instance
			hInst = hInstance;
			MessageBox(NULL,TEXT("Attached"),TEXT("Attached"),MB_OK);
			break;
		}
		case DLL_PROCESS_DETACH:
		{
			MessageBox(NULL,TEXT("Detached"),TEXT("Detached"),MB_OK);
			break;
		}
    }
    return TRUE;
}

Advertisement
Mark the section as shared. Add the folling after your #pragma data_seg() line:
#pragma comment(linker, "/section:SharedBlock,RWS")
what exactly does that line do? also, for some reason the program works if i put in a string constant such as "C:\\Users\\BigJoe\\Desktop\\fab.txt". but when i copy that into the filepath variable it just doesnt work. also when i specify the filepath variable, im not even getting the messagebox i built into the keyboardproc.

what could be going on?
By default each process loads a different 'instance' of a dll in it's own address space which is why setting a value in one won't be reflected in the others, unless such value is set to a variable that is into a section marked as shared
ok, is there any reason why the application still wont work with the #pragma line?
Quote:Original post by b1gjo3
ok, is there any reason why the application still wont work with the #pragma line?
Each EXE has it's own heap, and they can't easily share information that way. I'd make the string a static sized buffer, of say 512 bytes, then just copy into that. Then there's no memory allocation going on, so the different heaps don't matter.
that did the trick! i dont really understand why because i didnt think there was much difference between..

char filepath[MAX_PATH] = {}
char* filepath = new char[MAX_PATH];
Quote:Original post by b1gjo3
that did the trick! i dont really understand why because i didnt think there was much difference between..

char filepath[MAX_PATH] = {}
char* filepath = new char[MAX_PATH];
The first one allocates MAX_PATH characters on the stack or .data segment, the second allocates MAX_PATH characters from the heap.

In your DLL, the .data segment is shared, so that memory for filepath is shared, but the heap isn't shared (And there's no way to share it between processes).


When a DLL is loaded by an EXE, you can think of it as copying everything in the DLL into the EXE. Because of that, each EXE gets its own heap, and can't access each others. Your shared segment means it's shared between all EXEs that load it, meaning the variable is shared. In the second case, only the pointer is shared, and it doesn't point to anywhere useful - it'd be like getting a pointer, and then telling someone the address for them to use that memory in another program; it just won't work.
Ok, listen carefully

Each executable has it's own heap, which is where "new" allocates memory from.

You tagged "filepath" as a shared location, using the #pragma directive. "filepath" is of type "char*", therefore you are sharing 4 bytes (let's assume that the size of a pointer is 4 bytes) between all the instances of your dll.

Now, when you run your first executable, "new char[MAX_PATH]" allocates a memory buffer of "MAX_PATH * sizeof(char)" bytes IN THE HEAP OF THIS EXECUTABLE. Therefore, "filepath" stores the address of that buffer IN THE HEAP OF THIS EXECUTABLE.

Then you run your second executable, which in turns loads a new instance of your dll. "filepath" is already initialized, with an address of a memory buffer into another process's heap. Since each process has it's own address space, this is totally illegal, and you program will exhibit undefined behavior.

In conlusion, if you want to share the whole char array, you need to tag a whole char array as shared like Evil Steve said.

Hope that helps..
JA

Edit: geez.. beaten :/
Quote:Original post by janta
Edit: geez.. beaten :/


hah.. anyways i think you both helped me to understand this problem. I do appreciate your help and its working fine now. much much appreciation guys.

This topic is closed to new replies.

Advertisement