mirror of
https://github.com/reactos/reactos.git
synced 2024-08-25 04:38:43 +00:00
![Baruch Rutman](/assets/img/avatar_default.png)
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.
120 lines
2.6 KiB
C
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 */
|