reactos/win32ss/gdi/gdi32/main/dllmain.c
Baruch Rutman 6a3b1879a1 [LPK][GDI32] Enable mirroring via version resource (#965)
Add a mechanism that detects via the version resource whether it's needed to mirror
the application layout or not. This is a "follow up" to commit 5b14b6f.

This code is taken from the GetProcessDefaultLayout() function from Wine
(called there "WIN_CreateWindowEx").

In Windows the version-resource mirroring happens when the GDI is loading the LPK.

- Implement mirroring via version resource. GDI linking on startup is required.

- GDI32: Add LPK loading on GDI startup.

To enable mirroring via version resource the lpk.dll must be loaded before any windows are created.
This is done through GdiInitializeLanguagePack() function which is called in GdiProcessSetup().

- LPK: Use Wine debug messaging.
2018-10-24 21:34:38 +02:00

120 lines
2.6 KiB
C

/*
* dllmain.c
*/
#include <precomp.h>
extern HGDIOBJ stock_objects[];
BOOL SetStockObjects = FALSE;
PDEVCAPS GdiDevCaps = NULL;
PGDIHANDLECACHE GdiHandleCache = NULL;
BOOL gbLpk = FALSE;
RTL_CRITICAL_SECTION semLocal;
extern CRITICAL_SECTION gcsClientObjLinks;
/*
* GDI32.DLL does have an entry point for disable threadlibrarycall,. The initialization is done by a call
* to GdiDllInitialize(). This call is done from the entry point of USER32.DLL.
*/
BOOL
WINAPI
DllMain(
HANDLE hDll,
DWORD dwReason,
LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH :
DisableThreadLibraryCalls(hDll);
break;
default:
break;
}
return TRUE;
}
VOID
WINAPI
GdiProcessSetup(VOID)
{
hProcessHeap = GetProcessHeap();
/* map the gdi handle table to user space */
GdiHandleTable = NtCurrentTeb()->ProcessEnvironmentBlock->GdiSharedHandleTable;
GdiSharedHandleTable = NtCurrentTeb()->ProcessEnvironmentBlock->GdiSharedHandleTable;
GdiDevCaps = &GdiSharedHandleTable->DevCaps;
CurrentProcessId = NtCurrentTeb()->ClientId.UniqueProcess;
GDI_BatchLimit = (DWORD) NtCurrentTeb()->ProcessEnvironmentBlock->GdiDCAttributeList;
GdiHandleCache = (PGDIHANDLECACHE)NtCurrentTeb()->ProcessEnvironmentBlock->GdiHandleBuffer;
RtlInitializeCriticalSection(&semLocal);
InitializeCriticalSection(&gcsClientObjLinks);
GdiInitializeLanguagePack(0);
}
VOID
WINAPI
GdiProcessShutdown(VOID)
{
DeleteCriticalSection(&gcsClientObjLinks);
RtlDeleteCriticalSection(&semLocal);
}
/*
* @implemented
*/
BOOL
WINAPI
GdiDllInitialize(
HANDLE hDll,
DWORD dwReason,
LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
{
/* Don't bother us for each thread */
// DisableThreadLibraryCalls(hDll);
/* Initialize the kernel part of GDI first */
if (!NtGdiInit()) return FALSE;
/* Now initialize ourselves */
GdiProcessSetup();
break;
}
case DLL_THREAD_ATTACH:
{
NtCurrentTeb()->GdiTebBatch.Offset = 0;
NtCurrentTeb()->GdiBatchCount = 0;
break;
}
case DLL_PROCESS_DETACH:
{
/* Cleanup */
GdiProcessShutdown();
return TRUE;
}
default:
return FALSE;
}
/* Very simple, the list will fill itself as it is needed */
if (!SetStockObjects)
{
RtlZeroMemory(&stock_objects, NB_STOCK_OBJECTS); // Assume ROS is dirty
SetStockObjects = TRUE;
}
return TRUE;
}
/* EOF */