2010-02-26 11:43:19 +00:00
|
|
|
#pragma once
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2009-03-17 01:41:33 +00:00
|
|
|
typedef struct INTENG_ENTER_LEAVE_TAG
|
|
|
|
{
|
|
|
|
/* Contents is private to EngEnter/EngLeave */
|
|
|
|
SURFOBJ *DestObj;
|
|
|
|
SURFOBJ *OutputObj;
|
|
|
|
HBITMAP OutputBitmap;
|
|
|
|
CLIPOBJ *TrivialClipObj;
|
|
|
|
RECTL DestRect;
|
|
|
|
BOOL ReadOnly;
|
|
|
|
} INTENG_ENTER_LEAVE, *PINTENG_ENTER_LEAVE;
|
|
|
|
|
|
|
|
extern BOOL APIENTRY IntEngEnter(PINTENG_ENTER_LEAVE EnterLeave,
|
|
|
|
SURFOBJ *DestObj,
|
|
|
|
RECTL *DestRect,
|
|
|
|
BOOL ReadOnly,
|
|
|
|
POINTL *Translate,
|
|
|
|
SURFOBJ **OutputObj);
|
|
|
|
|
|
|
|
extern BOOL APIENTRY IntEngLeave(PINTENG_ENTER_LEAVE EnterLeave);
|
|
|
|
|
2008-11-26 20:44:41 +00:00
|
|
|
extern HGDIOBJ StockObjects[];
|
2019-07-31 13:24:01 +00:00
|
|
|
extern USHORT gusLanguageID;
|
2008-10-30 10:46:27 +00:00
|
|
|
|
[NTGDI][NTUSER] Load DirectX graphics driver at system startup (#4551)
CORE-18221
Load the DirectX graphics kernel driver (dxg.sys) by win32k at WINSRV
initialization time, in NtUserInitialize(). Keep it always loaded in
memory, as on Windows, instead of loading it only by DirectX dlls.
This fixes the problem of acessing this driver: we need only to call
DxDdEnableDirectDraw() and do other stuff when DirectDraw/Direct3D is
required by anything. In other cases, it is called from win32k PDEV
functions when changing display mode (as in Windows). Since it's used
by other things too, it needs to be always loaded.
Otherwise, if it's not loaded, its APIs are not accessible when needed,
and execution fails.
For example, it fixes display mode change problem in VMWare, when a
new mode fails to be applied. Indeed, when it manages DirectDraw stuff,
it calls DXG routines, and therefore fails if dxg.sys isn't loaded
in memory at this moment.
- Implement InitializeGreCSRSS() initialization routine, that initializes
supplemental NTGDI/GRE data once CSRSS and WINSRV are loaded:
* Call DxDdStartupDxGraphics() inside it, which loads dxg.sys.
* Additionally, move fonts and language ID initialization there, from
win32k!DriverEntry. Confirmed by analysis on Windows.
- Call InitializeGreCSRSS() in NtUserInitialize() main initialization routine
(called by WINSRV initialization).
Moved to NTGDI from previously NTUSER place:
Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
2022-06-18 18:35:17 +00:00
|
|
|
BOOL InitializeGreCSRSS(VOID);
|
2019-07-31 13:24:01 +00:00
|
|
|
USHORT FASTCALL UserGetLanguageID(VOID);
|
[NTGDI][NTUSER] Load DirectX graphics driver at system startup (#4551)
CORE-18221
Load the DirectX graphics kernel driver (dxg.sys) by win32k at WINSRV
initialization time, in NtUserInitialize(). Keep it always loaded in
memory, as on Windows, instead of loading it only by DirectX dlls.
This fixes the problem of acessing this driver: we need only to call
DxDdEnableDirectDraw() and do other stuff when DirectDraw/Direct3D is
required by anything. In other cases, it is called from win32k PDEV
functions when changing display mode (as in Windows). Since it's used
by other things too, it needs to be always loaded.
Otherwise, if it's not loaded, its APIs are not accessible when needed,
and execution fails.
For example, it fixes display mode change problem in VMWare, when a
new mode fails to be applied. Indeed, when it manages DirectDraw stuff,
it calls DXG routines, and therefore fails if dxg.sys isn't loaded
in memory at this moment.
- Implement InitializeGreCSRSS() initialization routine, that initializes
supplemental NTGDI/GRE data once CSRSS and WINSRV are loaded:
* Call DxDdStartupDxGraphics() inside it, which loads dxg.sys.
* Additionally, move fonts and language ID initialization there, from
win32k!DriverEntry. Confirmed by analysis on Windows.
- Call InitializeGreCSRSS() in NtUserInitialize() main initialization routine
(called by WINSRV initialization).
Moved to NTGDI from previously NTUSER place:
Co-authored-by: Hermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
2022-06-18 18:35:17 +00:00
|
|
|
|
2008-11-29 22:48:58 +00:00
|
|
|
PVOID APIENTRY HackSecureVirtualMemory(IN PVOID,IN SIZE_T,IN ULONG,OUT PVOID *);
|
|
|
|
VOID APIENTRY HackUnsecureVirtualMemory(IN PVOID);
|
2006-11-08 11:47:44 +00:00
|
|
|
|
2010-10-24 23:32:18 +00:00
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RegOpenKey(
|
|
|
|
LPCWSTR pwszKeyName,
|
|
|
|
PHKEY phkey);
|
|
|
|
|
|
|
|
NTSTATUS
|
|
|
|
NTAPI
|
|
|
|
RegQueryValue(
|
|
|
|
IN HKEY hkey,
|
|
|
|
IN PCWSTR pwszValueName,
|
|
|
|
IN ULONG ulType,
|
|
|
|
OUT PVOID pvData,
|
|
|
|
IN OUT PULONG pcbValue);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2024-02-23 12:26:12 +00:00
|
|
|
RegWriteSZ(HKEY hkey, PCWSTR pwszValue, PWSTR pwszData);
|
2010-10-24 23:32:18 +00:00
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2024-02-23 12:26:12 +00:00
|
|
|
RegWriteDWORD(HKEY hkey, PCWSTR pwszValue, DWORD dwData);
|
2010-10-24 23:32:18 +00:00
|
|
|
|
|
|
|
BOOL
|
|
|
|
NTAPI
|
2024-02-23 12:26:12 +00:00
|
|
|
RegReadDWORD(HKEY hkey, PCWSTR pwszValue, PDWORD pdwData);
|
2010-10-24 23:32:18 +00:00
|
|
|
|
2022-11-15 08:10:06 +00:00
|
|
|
DWORD
|
|
|
|
NTAPI
|
2024-02-23 12:26:12 +00:00
|
|
|
RegGetSectionDWORD(LPCWSTR pszSection, PCWSTR pszValue, DWORD dwDefault);
|
2022-11-15 08:10:06 +00:00
|
|
|
|
2023-12-17 21:13:45 +00:00
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
SetLastNtError(_In_ NTSTATUS Status);
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
|
|
|
|
typedef struct _GDI_POOL *PGDI_POOL;
|
|
|
|
|
|
|
|
PGDI_POOL
|
|
|
|
NTAPI
|
|
|
|
GdiPoolCreate(
|
|
|
|
ULONG cjAllocSize,
|
|
|
|
ULONG ulTag);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
GdiPoolDestroy(PGDI_POOL pPool);
|
|
|
|
|
|
|
|
PVOID
|
|
|
|
NTAPI
|
|
|
|
GdiPoolAllocate(
|
|
|
|
PGDI_POOL pPool);
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
|
|
|
GdiPoolFree(
|
|
|
|
PGDI_POOL pPool,
|
|
|
|
PVOID pvAlloc);
|
|
|
|
|
|
|
|
FORCEINLINE
|
|
|
|
VOID
|
|
|
|
ExAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
|
|
|
|
{
|
|
|
|
/* Try acquiring the lock */
|
|
|
|
if (InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V))
|
|
|
|
{
|
|
|
|
/* Someone changed it, use the slow path */
|
|
|
|
ExfAcquirePushLockExclusive(PushLock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-29 18:32:14 +00:00
|
|
|
FORCEINLINE
|
|
|
|
BOOLEAN
|
|
|
|
ExTryAcquirePushLockExclusive(PEX_PUSH_LOCK PushLock)
|
|
|
|
{
|
|
|
|
/* Try acquiring the lock */
|
|
|
|
return !InterlockedBitTestAndSet((PLONG)PushLock, EX_PUSH_LOCK_LOCK_V);
|
|
|
|
}
|
|
|
|
|
[WIN32K]
Rewrite of the GDI handle manager
- The old handle manager used a completely retarded spinlock in combination with KeDelayExecutionThread() for both exclusive
and shared locks. This is probably the most uneffective algorithm possible. It was also duplicating code everywhere and it was a overall mess It
is now replaced with a lock-free reference counter for shared locks and a pushlock for exclusive locks. -> Better performance and scalability.
- Allocate user mode object attributes from the new gdi pool. This way, we don't need any caching, since the pool serves as a cache. Its also
much faster and uses much less memory.
- Allow object allocations of different size, instead of fixed size from a table. This way a single allocation can take care of actual needs.
- Allow allcoating objects without a handle and insert them into the handle table later
- Properly synchronize the process GDIHandleCount. Now gdiview and taskmanager show the correct number of gdi handles.
- Implement a new event tracking system, that is capable of tracking all reverences and locks of objects and pool allocations to help track
possible leaks
- Make sure that all objects of a process are deleted in cleanup
- Make sure all usermode memory allocations are freed, when cleaning up the process pool.
- Make sure that each object type is using the correct type of lock (either shared or exclusive, not a mixture)
- Fix some object / reference leaks
- Lots of inferface improvements
- Use global variables for certain things instead of members in the mapped gdi handle table
- Make IntSysCreateRectpRgn create a region without a handle
- Fix detection od source and mask use in GreStretchBltMask
- Use GDIOBJ_bLockMultipleObjects in NtGdiCombineRegion to avoid possible deadlocks
- Fix NtGdiAbortPath to reset DCPATH_ACTIVE flag in the dc and only bail out on error, instead of always
- Replace DC_AllocateDcAttr and DC_AllocDcAttr with DC_bAllocDcAttr using the new user mode pool
- Remove DCU_SyncDcAttrtoUser and DCU_SynchDcAttrtoUser. Those functions were unused and didn't do anything useful anyway,
- Replace IntGdiSetDCOwnerEx and DC_SetOwnership with GreSetDCOwner, remove unused NoSetBrush parameter
- Replace GDIOBJ_bValidateHandle and IsObjectDead with GreIsHandleValid
- Chage GDIOBJ_bLockMultipleObjects: pass object type, return a BOOL, whether all objects could be locked, cleanup on failure
svn path=/trunk/; revision=51470
2011-04-28 08:26:46 +00:00
|
|
|
FORCEINLINE
|
|
|
|
VOID
|
|
|
|
ExReleasePushLockExclusive(PEX_PUSH_LOCK PushLock)
|
|
|
|
{
|
|
|
|
EX_PUSH_LOCK OldValue;
|
|
|
|
|
|
|
|
/* Unlock the pushlock */
|
|
|
|
OldValue.Value = InterlockedExchangeAddSizeT((PSIZE_T)PushLock,
|
|
|
|
-(SSIZE_T)EX_PUSH_LOCK_LOCK);
|
|
|
|
/* Check if anyone is waiting on it and it's not already waking */
|
|
|
|
if ((OldValue.Waiting) && !(OldValue.Waking))
|
|
|
|
{
|
|
|
|
/* Wake it up */
|
|
|
|
ExfTryToWakePushLock(PushLock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
FORCEINLINE
|
|
|
|
VOID
|
|
|
|
_ExInitializePushLock(PEX_PUSH_LOCK Lock)
|
|
|
|
{
|
|
|
|
*(PULONG_PTR)Lock = 0;
|
|
|
|
}
|
|
|
|
#define ExInitializePushLock _ExInitializePushLock
|
2011-08-27 12:38:23 +00:00
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
IntSafeCopyUnicodeString(PUNICODE_STRING Dest,
|
|
|
|
PUNICODE_STRING Source);
|
|
|
|
|
|
|
|
NTSTATUS FASTCALL
|
|
|
|
IntSafeCopyUnicodeStringTerminateNULL(PUNICODE_STRING Dest,
|
|
|
|
PUNICODE_STRING Source);
|
|
|
|
|
2011-09-20 18:04:14 +00:00
|
|
|
HBITMAP NTAPI UserLoadImage(PCWSTR);
|
|
|
|
|
|
|
|
BOOL NTAPI W32kDosPathNameToNtPathName(PCWSTR, PUNICODE_STRING);
|
2011-08-27 18:26:37 +00:00
|
|
|
|