PLDC FASTCALL GdiGetLDC(HDC hDC) { PDC_ATTR Dc_Attr; PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX((HGDIOBJ) hDC); HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1); // Don't check the mask, just the object type. if ( Entry->ObjectType == GDIObjType_DC_TYPE && (pid == NULL || pid == CurrentProcessId) ) { BOOL Result = TRUE; if (Entry->UserData) { volatile CHAR *Current = (volatile CHAR*)Entry->UserData; _SEH2_TRY { *Current = *Current; } _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) { Result = FALSE; } _SEH2_END } else
VOID FASTCALL IntGdiReleaseVisRgn(PDC pDC) { INT Index = GDI_HANDLE_GET_INDEX(pDC->BaseObject.hHmgr); PGDI_TABLE_ENTRY Entry = &GdiHandleTable->Entries[Index]; pDC->fs |= DC_FLAG_DIRTY_RAO; Entry->Flags |= GDI_ENTRY_VALIDATE_VIS; RECTL_vSetEmptyRect(&pDC->erclClip); REGION_Delete(pDC->prgnVis); pDC->prgnVis = prgnDefault; }
BOOL GdiIsHandleValid(HGDIOBJ hGdiObj) { PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj); // We are only looking for TYPE not the rest here, and why is FullUnique filled up with CRAP!? // DPRINT1("FullUnique -> %x\n", Entry->FullUnique); if((Entry->Type & GDI_ENTRY_BASETYPE_MASK) != 0 && ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & 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; }
/* * @implemented */ HGDIOBJ WINAPI GdiFixUpHandle(HGDIOBJ hGdiObj) { PGDI_TABLE_ENTRY Entry; if (((ULONG_PTR)(hGdiObj)) & GDI_HANDLE_UPPER_MASK ) { return hGdiObj; } /* FIXME is this right ?? */ Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj); /* Rebuild handle for Object */ return hGdiObj = (HGDIOBJ)(((LONG_PTR)(hGdiObj)) | (Entry->Type << GDI_ENTRY_UPPER_SHIFT)); }
/* * @implemented */ BOOL WINAPI GdiValidateHandle(HGDIOBJ hobj) { PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hobj); if ( (Entry->Type & GDI_ENTRY_BASETYPE_MASK) != 0 && ( (Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK ) == GDI_HANDLE_GET_TYPE(hobj) ) { HANDLE pid = (HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1); if(pid == NULL || pid == CurrentProcessId) { return TRUE; } } return FALSE; }
BOOL GdiGetHandleUserData(HGDIOBJ hGdiObj, DWORD ObjectType, PVOID *UserData) { PGDI_TABLE_ENTRY Entry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hGdiObj); /* Check if twe have the correct type */ if (GDI_HANDLE_GET_TYPE(hGdiObj) != ObjectType || ((Entry->Type << GDI_ENTRY_UPPER_SHIFT) & GDI_HANDLE_TYPE_MASK) != ObjectType || (Entry->Type & GDI_ENTRY_BASETYPE_MASK) != (ObjectType & GDI_ENTRY_BASETYPE_MASK)) { return FALSE; } /* Check if we are the owner */ if ((HANDLE)((ULONG_PTR)Entry->ProcessId & ~0x1) != CurrentProcessId) { return FALSE; } *UserData = Entry->UserData; return TRUE; }
/* * @implemented */ INT WINAPI ExtSelectClipRgn( _In_ HDC hdc, _In_ HRGN hrgn, _In_ INT iMode) { INT Ret; HRGN NewRgn = NULL; HANDLE_METADC(INT, ExtSelectClipRgn, 0, hdc, hrgn, iMode); #if 0 if ( hrgn ) { if ( GetLayout(hdc) & LAYOUT_RTL ) { if ( MirrorRgnDC(hdc, hrgn, &NewRgn) ) { if ( NewRgn ) hrgn = NewRgn; } } } #endif /* Batch handles RGN_COPY only! */ if (iMode == RGN_COPY) { #if 0 PDC_ATTR pDc_Attr; PRGN_ATTR pRgn_Attr = NULL; /* hrgn can be NULL unless the RGN_COPY mode is specified. */ if (hrgn) GdiGetHandleUserData((HGDIOBJ) hrgn, GDI_OBJECT_TYPE_REGION, (PVOID) &pRgn_Attr); if ( GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &pDc_Attr) && pDc_Attr ) { PGDI_TABLE_ENTRY pEntry = GdiHandleTable + GDI_HANDLE_GET_INDEX(hdc); PTEB pTeb = NtCurrentTeb(); if ( pTeb->Win32ThreadInfo != NULL && pTeb->GdiTebBatch.HDC == hdc && !(pDc_Attr->ulDirty_ & DC_DIBSECTION) && !(pEntry->Flags & GDI_ENTRY_VALIDATE_VIS) ) { if (!hrgn || (hrgn && pRgn_Attr && pRgn_Attr->iComplexity <= SIMPLEREGION) ) { if ((pTeb->GdiTebBatch.Offset + sizeof(GDIBSEXTSELCLPRGN)) <= GDIBATCHBUFSIZE) { // FIXME: This is broken, use GdiAllocBatchCommand! PGDIBSEXTSELCLPRGN pgO = (PGDIBSEXTSELCLPRGN)(&pTeb->GdiTebBatch.Buffer[0] + pTeb->GdiTebBatch.Offset); pgO->gbHdr.Cmd = GdiBCExtSelClipRgn; pgO->gbHdr.Size = sizeof(GDIBSEXTSELCLPRGN); pgO->fnMode = iMode; if ( hrgn && pRgn_Attr ) { Ret = pRgn_Attr->iComplexity; if ( pDc_Attr->VisRectRegion.Rect.left >= pRgn_Attr->Rect.right || pDc_Attr->VisRectRegion.Rect.top >= pRgn_Attr->Rect.bottom || pDc_Attr->VisRectRegion.Rect.right <= pRgn_Attr->Rect.left || pDc_Attr->VisRectRegion.Rect.bottom <= pRgn_Attr->Rect.top ) Ret = NULLREGION; pgO->left = pRgn_Attr->Rect.left; pgO->top = pRgn_Attr->Rect.top; pgO->right = pRgn_Attr->Rect.right; pgO->bottom = pRgn_Attr->Rect.bottom; } else { Ret = pDc_Attr->VisRectRegion.Flags; pgO->fnMode |= 0x80000000; // Set no hrgn mode. } pTeb->GdiTebBatch.Offset += sizeof(GDIBSEXTSELCLPRGN); pTeb->GdiBatchCount++; if (pTeb->GdiBatchCount >= GDI_BatchLimit) NtGdiFlush(); if ( NewRgn ) DeleteObject(NewRgn); return Ret; } } } } #endif } Ret = NtGdiExtSelectClipRgn(hdc, hrgn, iMode); if ( NewRgn ) DeleteObject(NewRgn); return Ret; }
void Test_ExtPen(void) { HPEN hPen; EXTLOGPEN extlogpen; LOGBRUSH logbrush; DWORD dwStyles[17] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16}; struct { EXTLOGPEN extlogpen; DWORD dwStyles[50]; } elpUserStyle; int i; SetLastError(ERROR_SUCCESS); ok(GetObjectA((HANDLE)GDI_OBJECT_TYPE_EXTPEN, 0, NULL) == 0, "\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); SetLastError(ERROR_SUCCESS); ok(GetObjectW((HANDLE)GDI_OBJECT_TYPE_EXTPEN, 0, NULL) == 0, "\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "\n"); FillMemory(&extlogpen, sizeof(EXTLOGPEN), 0x77); logbrush.lbStyle = BS_SOLID; logbrush.lbColor = RGB(1,2,3); logbrush.lbHatch = 22; hPen = ExtCreatePen(PS_GEOMETRIC | PS_DASH, 5, &logbrush, 0, NULL); SetLastError(ERROR_SUCCESS); ok(GDI_HANDLE_GET_TYPE(hPen) == GDI_OBJECT_TYPE_EXTPEN, "\n"); ok(GetObject(hPen, sizeof(EXTLOGPEN), NULL) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetObject(hPen, 0, NULL) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetObject((HANDLE)GDI_HANDLE_GET_INDEX(hPen), 0, NULL) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetObject(hPen, 5, NULL) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetObject(hPen, -5, NULL) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetLastError() == ERROR_SUCCESS, "\n"); ok(GetObject((HANDLE)GDI_OBJECT_TYPE_EXTPEN, 0, NULL) == 0, "\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %ld\n", GetLastError()); SetLastError(0xbadbad00); ok(GetObject(hPen, 0, &extlogpen) == 0, "\n"); ok((GetLastError() == 0xbadbad00) || (GetLastError() == ERROR_NOACCESS), "wrong error: %ld\n", GetLastError()); SetLastError(ERROR_SUCCESS); ok(GetObject(hPen, 4, &extlogpen) == 0, "\n"); ok(GetLastError() == ERROR_SUCCESS, "got %ld\n", GetLastError()); SetLastError(ERROR_SUCCESS); ok(GetObject((HANDLE)GDI_OBJECT_TYPE_EXTPEN, 0, &extlogpen) == 0, "\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %ld\n", GetLastError()); SetLastError(ERROR_SUCCESS); ok(GetObject((HANDLE)GDI_OBJECT_TYPE_EXTPEN, 4, &extlogpen) == 0, "\n"); ok(GetLastError() == ERROR_INVALID_PARAMETER, "got %ld\n", GetLastError()); SetLastError(ERROR_SUCCESS); ok(GetObject(hPen, sizeof(EXTLOGPEN) - 5, &extlogpen) == 0, "\n"); ok(GetLastError() == ERROR_SUCCESS, "got %ld\n", GetLastError()); /* Nothing should be filled */ ok(extlogpen.elpPenStyle == 0x77777777, "\n"); ok(extlogpen.elpWidth == 0x77777777, "\n"); ok(GetObject(hPen, sizeof(EXTLOGPEN), &extlogpen) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetObject(hPen, sizeof(EXTLOGPEN)-sizeof(DWORD), &extlogpen) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetObject(hPen, sizeof(EXTLOGPEN)-sizeof(DWORD)-1, &extlogpen) == 0, "\n"); ok(GetObject(hPen, sizeof(EXTLOGPEN)+2, &extlogpen) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); ok(GetObject(hPen, -5, &extlogpen) == sizeof(EXTLOGPEN)-sizeof(DWORD), "\n"); /* test if the fields are filled correctly */ ok(extlogpen.elpPenStyle == (PS_GEOMETRIC | PS_DASH), "\n"); ok(extlogpen.elpWidth == 5, "\n"); ok(extlogpen.elpBrushStyle == 0, "\n"); ok(extlogpen.elpColor == RGB(1,2,3), "\n"); ok(extlogpen.elpHatch == 22, "\n"); ok(extlogpen.elpNumEntries == 0, "\n"); DeleteObject(hPen); /* A maximum of 16 Styles is allowed */ hPen = ExtCreatePen(PS_GEOMETRIC | PS_USERSTYLE, 5, &logbrush, 16, (CONST DWORD*)&dwStyles); ok(GetObject(hPen, 0, NULL) == sizeof(EXTLOGPEN) + 15*sizeof(DWORD), "\n"); ok(GetObject(hPen, sizeof(EXTLOGPEN) + 15*sizeof(DWORD), &elpUserStyle) == sizeof(EXTLOGPEN) + 15*sizeof(DWORD), "\n"); for (i = 0; i <= 15; i++) ok(((EXTLOGPEN*)&elpUserStyle)->elpStyleEntry[i] == i, "%d\n", i); DeleteObject(hPen); }