The Windows DllMain(), creating a DLL program without the lib file
// DLL project name: moredll, source file name: dllentryfunc.cpp generating moredll.dll
// but no moredll.lib! The DLL entry-point function sets up shared memory using a named file-mapping object.
#include <windows.h>
#include <stdio.h>
#include <memory.h>
#define SHMEMSIZE 4096
static LPVOID lpvMem = NULL; // pointer to shared memory
static HANDLE hMapObject = NULL; // handle to file mapping
BOOL DllMain(HINSTANCE hinstDLL, // DLL module handle
DWORD fdwReason, // reason called
LPVOID lpvReserved) // reserved
{
BOOL fInit, fIgnore;
switch (fdwReason)
{
// The DLL is loading due to process initialization or a call to LoadLibrary().
case DLL_PROCESS_ATTACH:
printf("The DLL is loading...from moredll.dll.\n");
// Create a named file mapping object.
hMapObject = CreateFileMapping(
INVALID_HANDLE_VALUE, // use paging file
NULL, // default security attributes
PAGE_READWRITE, // read/write access
0, // size: high 32-bits
SHMEMSIZE, // size: low 32-bits
L"dllmemfilemap"); // name of map object
if (hMapObject == NULL)
return FALSE;
else
printf("CreateFileMapping() is OK.\n");
// The first process to attach initializes memory.
fInit = (GetLastError() != ERROR_ALREADY_EXISTS);
// Get a pointer to the file-mapped shared memory.
lpvMem = MapViewOfFile(
hMapObject, // object to map view of
FILE_MAP_WRITE, // read/write access
0, // high offset: map from
0, // low offset: beginning
0); // default: map entire file
if (lpvMem == NULL)
return FALSE;
else
printf("MapViewOfFile() is OK.\n");
// Initialize memory if this is the first process.
if (fInit)
memset(lpvMem, '\0', SHMEMSIZE);
break;
// The attached process creates a new thread.
case DLL_THREAD_ATTACH:
printf("The attached process creates a new thread...from moredll.dll.\n");
break;
// The thread of the attached process terminates.
case DLL_THREAD_DETACH:
printf("The thread of the attached process terminates... from moredll.dll.\n");
break;
// The DLL is unloading from a process due to process termination or a call to FreeLibrary().
case DLL_PROCESS_DETACH:
printf("The DLL is unloading from a process... from moredll.dll.\n");
// Unmap shared memory from the process's address space.
fIgnore = UnmapViewOfFile(lpvMem);
// Close the process's handle to the file-mapping object.
fIgnore = CloseHandle(hMapObject);
break;
default:
printf("Reason called not matched, error if any: %d... from moredll.dll.\n", GetLastError());
break;
}
return TRUE;
UNREFERENCED_PARAMETER(hinstDLL);
UNREFERENCED_PARAMETER(lpvReserved);
}
// Can be commented out for this example...
// SetSharedMem() sets the contents of shared memory.
VOID SetSharedMem(LPTSTR lpszBuf)
{
LPTSTR lpszTmp = L"Testing some string";
// Get the address of the shared memory block.
lpszTmp = (LPTSTR) lpvMem;
// Copy the null-terminated string into shared memory.
while (*lpszBuf)
*lpszTmp++ = *lpszBuf++;
*lpszTmp = '\0';
printf("The content: %S.\n", lpszTmp);
}
// Can be commented out for this example...
// GetSharedMem() gets the contents of shared memory.
VOID GetSharedMem(LPTSTR lpszBuf, DWORD cchSize)
{
LPTSTR lpszTmp;
// Get the address of the shared memory block.
lpszTmp = (LPTSTR) lpvMem;
// Copy from shared memory into the caller's buffer.
while (*lpszTmp && --cchSize)
*lpszBuf++ = *lpszTmp++;
*lpszBuf = '\0';
printf("The caller buffer: %S.\n", lpszBuf);
}
Output example:
// Need other program to run this DLL, see the next example
Compiler: Visual C++ Express Edition 2005
Compiled on Platform: Windows Xp Pro SP2
Target platform: none, just for learning and fun
Header file: Standard and Windows
Additional library: Windows Platform SDK
Additional project setting: Set project to be compiled as C.
Project->your_project_name Properties->Configuration Properties->C/C++->Advanced->Compiled As: Compiled as C Code (/TC)
Other info: This is DLL project. non-CLR or unmanaged.
Need to add Advapi32.lib (Advapi32.dll) to the project. Click the Project menu->Select the your_project_name Properties...sub menu->Expand the Configuration Properties folder on the left pane->Expand the Linker subfolder->Select the Input subfolder->Select the Additional Dependencies field on the right pane->Click the ... at the end of the field->Type in 'Advapi32.lib' in the empty pane->Click the OK button->Click the OK button second time to close the project Properties dialog.
Using __stdcall. Project->your_project_name Properties->Configuration Properties->C/C++->Advanced->Calling Convention->Change __cdecl (/Gd) to __stdcall (/Gz)
To do: The Windows DllMain() programming, creating a DLL program without the lib file
To show: The Windows process, thread and Dynamic Link Library (DLL) Win32 programming