From d10dba35e60e024267c8acf7e5bc79fd713fea57 Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Fri, 18 Feb 2005 15:13:02 +0000 Subject: [PATCH] don't call win32k for GetObjectType() and query the information directly from the shared handle table svn path=/trunk/; revision=13632 --- reactos/lib/gdi32/gdi32.def | 3 +- reactos/lib/gdi32/include/precomp.h | 5 +++ reactos/lib/gdi32/main/dllmain.c | 1 + reactos/lib/gdi32/misc/misc.c | 30 +++++++++++++ reactos/lib/gdi32/objects/dc.c | 70 ++++++++++++++++++++++++++++- 5 files changed, 106 insertions(+), 3 deletions(-) diff --git a/reactos/lib/gdi32/gdi32.def b/reactos/lib/gdi32/gdi32.def index dd78ff6da07..fcf7a82aa6d 100644 --- a/reactos/lib/gdi32/gdi32.def +++ b/reactos/lib/gdi32/gdi32.def @@ -358,7 +358,7 @@ GetMiterLimit@8 GetNearestColor@8=NtGdiGetNearestColor@8 GetNearestPaletteIndex@8=NtGdiGetNearestPaletteIndex@8 GetObjectA@12 -GetObjectType@4=NtGdiGetObjectType@4 +GetObjectType@4 GetObjectW@12 GetOutlineTextMetricsA@12 GetOutlineTextMetricsW@12 @@ -560,4 +560,3 @@ bInitSystemAndFontsDirectoriesW@8 bMakePathNameW@16 ;cGetTTFFromFOT gdiPlaySpoolStream@24 - \ No newline at end of file diff --git a/reactos/lib/gdi32/include/precomp.h b/reactos/lib/gdi32/include/precomp.h index 0985e46cca1..141f82ceb03 100644 --- a/reactos/lib/gdi32/include/precomp.h +++ b/reactos/lib/gdi32/include/precomp.h @@ -36,6 +36,7 @@ typedef CHWIDTHINFO *PCHWIDTHINFO; extern PGDI_TABLE_ENTRY GdiHandleTable; extern HANDLE hProcessHeap; +extern HANDLE CurrentProcessId; /* == HEAP ================================================================== */ @@ -49,4 +50,8 @@ BOOL FASTCALL TextMetricW2A(TEXTMETRICA *tma, TEXTMETRICW *tmw); BOOL FASTCALL NewTextMetricW2A(NEWTEXTMETRICA *tma, NEWTEXTMETRICW *tmw); BOOL FASTCALL NewTextMetricExW2A(NEWTEXTMETRICEXA *tma, NEWTEXTMETRICEXW *tmw); +/* == GDI HANDLES =========================================================== */ +BOOL GdiIsHandleValid(HGDIOBJ hGdiObj); +BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, PVOID *UserData); + /* EOF */ diff --git a/reactos/lib/gdi32/main/dllmain.c b/reactos/lib/gdi32/main/dllmain.c index 7215fca89d1..229c8117df9 100644 --- a/reactos/lib/gdi32/main/dllmain.c +++ b/reactos/lib/gdi32/main/dllmain.c @@ -33,6 +33,7 @@ GdiProcessSetup (VOID) /* map the gdi handle table to user space */ GdiHandleTable = NtCurrentTeb()->Peb->GdiSharedHandleTable; + CurrentProcessId = NtCurrentTeb()->Cid.UniqueProcess; } diff --git a/reactos/lib/gdi32/misc/misc.c b/reactos/lib/gdi32/misc/misc.c index 97a99d455b2..ee76fadb58a 100644 --- a/reactos/lib/gdi32/misc/misc.c +++ b/reactos/lib/gdi32/misc/misc.c @@ -29,6 +29,7 @@ #include "precomp.h" PGDI_TABLE_ENTRY GdiHandleTable = NULL; +HANDLE CurrentProcessId = NULL; /* * @implemented @@ -39,3 +40,32 @@ GdiQueryTable(VOID) { return (PVOID)GdiHandleTable; } + +BOOL GdiIsHandleValid(HGDIOBJ hGdiObj) +{ + PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj); + if(Entry->KernelData != NULL && (Entry->Type & GDI_HANDLE_TYPE_MASK) == GDI_HANDLE_GET_TYPE(hGdiObj)) + { + HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1); + if(pid == NULL || pid == CurrentProcessId) + { + return TRUE; + } + } + return FALSE; +} + +BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, PVOID *UserData) +{ + PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj); + if(Entry->KernelData != NULL && (Entry->Type & GDI_HANDLE_TYPE_MASK) == GDI_HANDLE_GET_TYPE(hGdiObj)) + { + HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1); + if(pid == NULL || pid == CurrentProcessId) + { + *UserData = Entry->UserData; + return TRUE; + } + } + return FALSE; +} diff --git a/reactos/lib/gdi32/objects/dc.c b/reactos/lib/gdi32/objects/dc.c index 243a05d1d6b..476aa3ad9e2 100644 --- a/reactos/lib/gdi32/objects/dc.c +++ b/reactos/lib/gdi32/objects/dc.c @@ -193,12 +193,14 @@ BOOL STDCALL DeleteObject(HGDIOBJ hObject) { - if (0 != ((DWORD) hObject & 0x00800000)) + if (0 != ((DWORD) hObject & GDI_HANDLE_STOCK_MASK)) { DPRINT1("Trying to delete system object 0x%x\n", hObject); return TRUE; } + /* deleting a handle that doesn't belong to the caller should be rather rarely + so for the sake of speed just try to delete it without checking validity */ return NtGdiDeleteObject(hObject); } @@ -400,3 +402,69 @@ StartDocW( { return NtGdiStartDoc ( hdc, (DOCINFOW *)a1 ); } + + +/* + * @implemented + */ +DWORD +STDCALL +GetObjectType( + HGDIOBJ h + ) +{ + DWORD Ret = 0; + + if(GdiIsHandleValid(h)) + { + LONG Type = GDI_HANDLE_GET_TYPE(h); + switch(Type) + { + case GDI_OBJECT_TYPE_PEN: + Ret = OBJ_PEN; + break; + case GDI_OBJECT_TYPE_BRUSH: + Ret = OBJ_BRUSH; + break; + case GDI_OBJECT_TYPE_BITMAP: + Ret = OBJ_BITMAP; + break; + case GDI_OBJECT_TYPE_FONT: + Ret = OBJ_FONT; + break; + case GDI_OBJECT_TYPE_PALETTE: + Ret = OBJ_PAL; + break; + case GDI_OBJECT_TYPE_REGION: + Ret = OBJ_REGION; + break; + case GDI_OBJECT_TYPE_DC: + Ret = OBJ_DC; + break; + case GDI_OBJECT_TYPE_METADC: + Ret = OBJ_METADC; + break; + case GDI_OBJECT_TYPE_METAFILE: + Ret = OBJ_METAFILE; + break; + case GDI_OBJECT_TYPE_ENHMETAFILE: + Ret = OBJ_ENHMETAFILE; + break; + case GDI_OBJECT_TYPE_ENHMETADC: + Ret = OBJ_ENHMETADC; + break; + case GDI_OBJECT_TYPE_EXTPEN: + Ret = OBJ_EXTPEN; + break; + case GDI_OBJECT_TYPE_MEMDC: + Ret = OBJ_MEMDC; + break; + + default: + DPRINT1("GetObjectType: Magic 0x%08x not implemented\n", Type); + break; + } + } + + return Ret; +}