One time Hook DLL initialization - c

My program uses SetWindowsHookEx to set a global hook function in my DLL. However I want the DLL to work with a file so I need it a file to be opened once. I can't use DllMain's DLL_PROCESS_ATTACH because it's called multiple times. What is the best solution to my problem?

Use a static flag to tell whether you've initialized already or not.
void DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
static BOOL initialized = FALSE;
switch(dwReason) {
case DLL_PROCESS_ATTACH:
if(!initialized) {
// Perform initialization here...ex: open your file.
initialized = TRUE;
}
break;
case DLL_PROCESS_DETACH:
if(initialized) {
// Perform cleanup here...ex: close your file.
initialized = FALSE;
}
break;
};
}

Related

Critical Sections and Memory Fences / Barriers on a multi-processor system

I have a Windows DLL (in C) that uses Critical Sections. A specific routine, which is called numerous times, needs to perform some initialization code the first time it is called, so I am using a Critical Section. However, since it is called so many times I am trying to avoid the overhead of entering the section each time it is called. It seems to be working, but I am wondering if there is a flaw considering memory barriers / fences when running on a multi-processor (Intel) system with an x64 OS? Here is the stripped down code:
int _isInitialized = FALSE;
CRITICAL_SECTION _InitLock = {0};
BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved )
{
ARM_SECTION_BEGIN(ul_reason_for_call)
switch (ul_reason_for_call)
{
case (DLL_PROCESS_ATTACH):
InitializeCriticalSection(&_InitLock);
break;
case (DLL_THREAD_ATTACH):
break;
case (DLL_THREAD_DETACH):
break;
case (DLL_PROCESS_DETACH):
DeleteCriticalSection(&_InitLock);
break;
}
return (TRUE);
}
int myproc(parameters...)
{
if (!_isInitialized) // check first time
{
EnterCriticalSection(&_InitLock);
if (_isInitialized) // check it again
{
LeaveCriticalSection(&_InitLock);
goto initialized;
}
... do stuff ...
_isInitialized = TRUE;
LeaveCriticalSection(&_InitLock);
}
initialized:
... do more stuff ...
return(something)
}
... if there is a flaw considering memory barriers / fences ... ?
Use volatile
Code certainly appears to risk using a stale value for _isInitialized in the 2nd test.
if (!_isInitialized) {
EnterCriticalSection(&_InitLock);
if (_isInitialized) // Risk
To insure a re-read of _isInitialized, use volatile. #JimmyB
// int _isInitialized = FALSE;
volatile int _isInitialized = FALSE;
Other Shared Data
Other data than _isInitialized assigned in the ... do stuff ... and used in the later ... do more stuff ... code risks the same problem due to an optimization may read other_data before the the first if (!_isInitialized).
Code could use volatile other_data. Unfortunately that may incur an unacceptable performance drag. Alternatives depend on what is inside stuff.
Style
I'd make _isInitialized local to the function, drop the _ and avoid the goto.
int myproc(parameters...) {
static volatile int isInitialized = FALSE;
if (!isInitialized) {
EnterCriticalSection(&_InitLock);
if (!isInitialized) {
// ... do stuff ...
isInitialized = TRUE;
}
LeaveCriticalSection(&_InitLock);
}
// ... do more stuff ...
return(something)
}

Trouble calling a .DLL function from a Console Application

I really need your help because I'm having many problems integrating one .DLL function into my Console Application.This .DLL consists on getting 2 chars(Char a and Char b)(Input) and adding them to one char.For example:
Char A=H
Char B=I
Output=HI
But here's the problem.When I compile the console application and when I run it,it says that the function hasn't been detected.And here's my question..Why the hell doesn't it find the function even though in the .def file I've listed the LIBRARY and the only exported function?Please help me.
THIS IS THE .DLL SOURCE
#include "stdafx.h"
char concatenazione(char a,char b)
{
return a+b;
}
**THIS IS THE .DEF FILE OF THE .DLL**
LIBRARY Concatenazione
EXPORTS
concatenazione #1
**And this is the dllmain.cpp**
#include "stdafx.h"
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
**This is the Console Application partial source(For now it just includes the functions import part)**
#include <iostream>
#include <windows.h>
#include <stdio.h>
typedef int (__cdecl *MYPROC)(LPWSTR);
int main( void )
{
HINSTANCE hinstLib;
MYPROC ProcAdd;
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE;
// Get a handle to the DLL module.
hinstLib = LoadLibrary(TEXT("C:\\ConcatenazioneDiAyoub.dll"));
// If the handle is valid, try to get the function address.
if (hinstLib != NULL)
{
ProcAdd = (MYPROC) GetProcAddress(hinstLib, "concatenazione");
// If the function address is valid, call the function.
if (NULL != ProcAdd)
{
fRunTimeLinkSuccess = TRUE;
(ProcAdd) (L"Message sent to the DLL function\n");
}
// Free the DLL module.
fFreeResult = FreeLibrary(hinstLib);
}
// If unable to call the DLL function, use an alternative.
if (! fRunTimeLinkSuccess)
printf("Message printed from executable\n");
return 0;
}
**The Console Applications runs fine but the output is "Message printed from executable".This means that the function hasn't been detected.**
Ok, I looked at what you have above and wondered where in your code you import the dll. I'm kind of new at this myself, so I found this article on how to do it.
If I understand correctly, in your console application you need to have a line like (assuming the name of your dll is "your.dll":
[DllImport("your.Dll")]
by the way, welcome to Stack Overflow, I noticed it is your first day! CHEERS!

Equivalent of PTHREAD_MUTEX_INITIALIZER on Windows?

Is it possible to initialise CRITICAL_SECTION statically, as in pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER?
In other words, is it possible in C to initialize a global CRITICAL_SECTION inside a library without having to mess with DllMain etc.?
Yes, simply initialize in DLL_PROCESS_ATTACH and delete in DLL_PROCESS_DETACH
CRITICAL_SECTION g_cs = {0};
BOOL WINAPI DllMain(
HINSTANCE hinstDLL, // handle to DLL module
DWORD fdwReason, // reason for calling function
LPVOID lpReserved ) // reserved
{
// Perform actions based on the reason for calling.
switch( fdwReason )
{
case DLL_PROCESS_ATTACH:
// Initialize once for each new process.
// Return FALSE to fail DLL load.
InitializeCriticalSection(&g_cs);
break;
case DLL_THREAD_ATTACH:
// Do thread-specific initialization.
break;
case DLL_THREAD_DETACH:
// Do thread-specific cleanup.
break;
case DLL_PROCESS_DETACH:
// Perform any necessary cleanup.
DeleteCriticalSection(&g_cs);
break;
}
return TRUE; // Successful DLL_PROCESS_ATTACH.
}
References:
InitializeCriticalSection
DeleteCriticalSection
Yes! But you have to make sure that it's only done once per process.
But this is typically easiest to achieve by using the DLL_PROCESS_ATTACH case of the DLLMain
switch( fdwReason ) statement.
Another possibility in earlier versions is to instruct the linker to set a pointer to your initialization function as a user-defined global initializer. There is some discussion of this here:
http://msdn.microsoft.com/en-us/library/bb918180.aspx
Here is an example:
CRITICAL_SECTION criticalSection;
static void __cdecl Initialize(void) {
InitializeCriticalSection(&criticalSection);
}
#pragma section(".CRT$XCU", read)
__declspec(allocate(".CRT$XCU"))
const void (__cdecl *pInitialize)(void) = Initialize;
The answer above from Raymond Chen solves the problem: "You can use InitOnceExecuteOnce to initialize the critical section on first use. That's what PTHREAD_MUTEX_INITIALIZER does under the covers."
note that this will work on Vista and above only --- #rkosegi
You can do it for older versions of Windows by writing your own InitOnceExecuteOnce function using InterlockedCompareExchange. --- #RaymondChen

How do I embed and use resource files in a C program using VS11?

This is my first attempt at using a resource file. I have seen a lot of answers that apply to C# but not C. Any suggestions?
Assuming you mean the method used by Sysinternals and others to carry the drivers or needed DLLs (or even the x64 version of the program itself) in the resource section of a program (e.g. Sysinternals' Process Explorer), using Microsoft Visual C you can use this code:
BOOL ExtractResTo(HINSTANCE Instance, LPCTSTR BinResName, LPCTSTR NewPath, LPCTSTR ResType)
{
BOOL bResult = FALSE;
HRSRC hRsrc;
if(hRsrc = FindResource(HMODULE(Instance), BinResName, ResType))
{
HGLOBAL hGlob
if(HGLOBAL hGlob = LoadResource(Instance, hRsrc))
{
DWORD dwResSize = SizeofResource(Instance, hRsrc);
HANDLE hFileWrite = CreateFile(NewPath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_ARCHIVE, 0);
if(hFileWrite != INVALID_HANDLE_VALUE)
__try
{
DWORD dwSizeWritten = 0;
bResult = (WriteFile(hFileWrite, LockResource(hGlob), dwResSize, &dwSizeWritten, NULL) && (dwSizeWritten == dwResSize));
}
__finally
{
CloseHandle(hFileWrite);
}
}
}
return bResult;
}
This saves the given resource (BinResName) of resource type (ResType) from the module (e.g. a DLL) Instance to file NewPath. Obviously if your C doesn't understand __try and __finally you'll have to adjust the code accordingly.
Taken from here (in SIDT.rar) and adjusted for C. The code is under the liberal BSD license according to the website.
Now if you wanted to get the pointer to the data (ppRes) and its size (pwdResSize):
BOOL GetResourcePointer(HINSTANCE Instance, LPCTSTR ResName, LPCTSTR ResType, LPVOID* ppRes, DWORD* pdwResSize)
{
// Check the pointers to which we want to write
if(ppRes && pdwResSize)
{
HRSRC hRsrc;
// Find the resource ResName of type ResType in the DLL/EXE described by Instance
if(hRsrc = FindResource((HMODULE)Instance, ResName, ResType))
{
HGLOBAL hGlob;
// Make sure it's in memory ...
if(hGlob = LoadResource(Instance, hRsrc))
{
// Now lock it to get a pointer
*ppRes = LockResource(hGlob);
// Also retrieve the size of the resource
*pdwResSize = SizeofResource(Instance, hRsrc);
// Return TRUE only if both succeeded
return (*ppRes && *pdwResSize);
}
}
}
// Failure means don't use the values in *ppRes and *pdwResSize
return FALSE;
}
Call like this:
LPVOID pResource;
DWORD pResourceSize;
if(GetResourcePointer(hInstance, _T("somename"), _T("sometype"), &pResource, &pResourceSize))
{
// use pResource and pResourceSize
// e.g. store into a string buffer or whatever you want to do with it ...
}
Note, this also works for resources with integer IDs. You can detect these by using the macro IS_INTRESOURCE.
The resource script, e.g. myresources.rc, itself is trivial:
#include <winnt.rh>
"somename" "sometype" "path\to\file\to\embed"
RCDATA instead of sometype is a reasonable choice
#include <winnt.rh> // for RCDATA to be known to rc.exe
"somename" RCDATA "path\to\file\to\embed"
... in which case you would adjust the above call to be:
GetResourcePointer(hInstance, _T("somename"), RT_RCDATA, &pResource, &pResourceSize)
Complete example making use of GetResourcePointer above. Let's say you have a pointer variable char* buf and you know your resource is actual text, then you need to make sure that it is zero-terminated when used as a string, that's all.
Resource script:
#include <winnt.rh>
"test" RCDATA "Test.txt"
The code accessing it
char* buf = NULL;
LPVOID pResource;
DWORD pResourceSize;
if(GetResourcePointer(hInstance, _T("test"), RT_RCDATA, &pResource, &pResourceSize))
{
if(buf = calloc(pResourceSize+1, sizeof(char)))
{
memcpy(buf, pResource, pResourceSize);
// Now use buf
free(buf);
}
}
Unless, of course you meant to simply link a .res file which works by passing it to the linker command line.

Switch/case without break inside DllMain

I have a Dllmain that allocates Thread local storage when a thread attaches to this DLL. Code as below:
BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
LPVOID lpvData;
BOOL fIgnore;
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
onProcessAttachDLL();
// Allocate a TLS index.
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
return FALSE;
// how can it jump to next case???
case DLL_THREAD_ATTACH:
// Initialize the TLS index for this thread.
lpvData = (LPVOID) LocalAlloc(LPTR, MAX_BUFFER_SIZE);
if (lpvData != NULL)
fIgnore = TlsSetValue(dwTlsIndex, lpvData);
break;
...
}
I know that for the main thread, the DLL_THREAD_ATTACH is not entered, as per Microsoft Documentation. However, the above code worked. I am using VC2005. When I entered the debugger, I saw that after it entered DLL_THREAD_ATTACH case when ul_reason_for_call = 1! How can that happen? If I add `break' at the end of DLL_PROCESS_ATTACH block, the DLL failed to work.
How can this happen?
If I understand you correctly, you are wondering why, after entering the DLL_PROCESS_ATTACH case, the execution continues on the DLL_THREAD_ATTACH case, instead of after the end of the switch.
This behaviour is called "fall through", and it is standard C. Without an explicit break statement, the execution continues on the next case.
Of course, it is quite counterintuitive for programmers who see it the first time, so it is a constant source of misunderstanding and even bugs (you may not always know whether the break was left out intentionally, or by mistake). It is considered good practice, therefore, when using this construct, to mark it explicitly with a comment, like:
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
onProcessAttachDLL();
// Allocate a TLS index.
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES)
return FALSE;
// fall through
case DLL_THREAD_ATTACH:
// Initialize the TLS index for this thread.
lpvData = (LPVOID) LocalAlloc(LPTR, MAX_BUFFER_SIZE);
if (lpvData != NULL)
fIgnore = TlsSetValue(dwTlsIndex, lpvData);
break;
...
Do you understand how switch statements work? if you do NOT put a break at the end of the case, then the code just continues into the next case:
switch (3)
{
case 3:
cout << "3";
case 4:
cout << "4";
}
prints both 3 and 4.

Resources