Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1478 lines
55 KiB

/*++
Copyright (c) 1997-1999 Microsoft Corporation
Module Name:
umpddrv.c
Abstract:
User-mode printer driver stubs for Drv callback functions
Environment:
Windows NT 5.0
Revision History:
09/30/97 -lingyunw-
Created it by moving GdiPrinterThunk out of umpd.c.
--*/
#include "precomp.h"
#pragma hdrstop
RTL_CRITICAL_SECTION semUMPD; // Critical section for user-mode printer driver
#if !defined(_GDIPLUS_)
#include "winddi.h"
#include "proxyport.h"
/*
#if DBG
#define DBG_TRACE(x) DbgPrint("UMPD: "#x"\n")
#else
#define DBG_TRACE(x)
#endif
*/
//
// Adjust user mode printer driver DHPDEV field in a SURFOBJ
//
__inline PUMDHPDEV
AdjustUMdhpdev(
SURFOBJ *pso
)
{
PUMDHPDEV pUMdhpdev = (PUMDHPDEV) pso->dhpdev;
pso->dhpdev = pUMdhpdev->dhpdev;
return pUMdhpdev;
}
BOOL
GdiCopyFD_GLYPHSET(
FD_GLYPHSET *dst,
FD_GLYPHSET *src,
ULONG cjSize
)
{
ULONG index, offset, size;
PBYTE phg, pbMax;
size = offsetof(FD_GLYPHSET, awcrun) + src->cRuns * sizeof(WCRUN);
RtlCopyMemory(dst, src, size);
dst->cjThis = cjSize;
pbMax = (PBYTE)dst + cjSize;
phg = (PBYTE)dst + size;
//
// Patch up memory pointers in each WCRUN structure
//
for (index=0; index < src->cRuns; index++)
{
if (src->awcrun[index].phg != NULL)
{
size = src->awcrun[index].cGlyphs * sizeof(HGLYPH);
if (phg + size <= pbMax)
{
RtlCopyMemory(phg, src->awcrun[index].phg, size);
dst->awcrun[index].phg = (HGLYPH*) phg;
phg += size;
}
else
return FALSE;
}
}
return TRUE;
}
BOOL bAddPrinterHandle(PUMPD pUMPD, DWORD clientPid, DWORD hPrinter32, HANDLE hPrinter64)
{
PHPRINTERLIST pPtrList;
BOOL bRet = FALSE;
if (pPtrList = LOCALALLOC(sizeof(HPRINTERLIST)))
{
pPtrList->clientPid = clientPid;
pPtrList->hPrinter32 = hPrinter32;
pPtrList->hPrinter64 = hPrinter64;
ENTERCRITICALSECTION(&semUMPD);
pPtrList->pNext = pUMPD->pHandleList;
pUMPD->pHandleList = pPtrList;
bRet = TRUE;
LEAVECRITICALSECTION(&semUMPD);
}
return bRet;
}
PHPRINTERLIST FindPrinterHandle(PUMPD pUMPD, DWORD clientPid, DWORD hPrinter32)
{
PHPRINTERLIST pList;
ENTERCRITICALSECTION(&semUMPD);
pList = pUMPD->pHandleList;
while(pList)
{
if (pList->clientPid == clientPid && pList->hPrinter32 == hPrinter32)
{
break;
}
pList = pList->pNext;
}
LEAVECRITICALSECTION(&semUMPD);
return pList;
}
VOID DeletePrinterHandle(PUMPD pUMPD, PHPRINTERLIST pNode)
{
PHPRINTERLIST pList;
ENTERCRITICALSECTION(&semUMPD);
pList = pUMPD->pHandleList;
if (pList == pNode)
{
pUMPD->pHandleList = pNode->pNext;
}
else
{
while(pList && pList->pNext != pNode)
{
pList = pList->pNext;
}
if (pList)
{
pList->pNext = pNode->pNext;
}
}
LEAVECRITICALSECTION(&semUMPD);
if (pList)
{
LOCALFREE(pNode);
}
}
//
// KERNEL_PVOID UMPDAllocUserMem
//
// WOW64 printing only
//
KERNEL_PVOID UMPDAllocUserMem(ULONG cjSize)
{
return ((KERNEL_PVOID) LOCALALLOC(cjSize));
}
//
// KERNEL_PVOID UMPDCopyMemory
//
// WOW64 printing only
//
// pvSrc
// source
//
// pvDest
// dest
//
// cjBits
// size to copy
//
KERNEL_PVOID UMPDCopyMemory(
KERNEL_PVOID pvSrc,
KERNEL_PVOID pvDest,
ULONG cjBits
)
{
if (pvDest != NULL)
RtlCopyMemory(pvDest, pvSrc, cjBits);
return pvDest;
}
//
// BOOL UMPDFreeMemory
//
// WOW64 only
//
BOOL UMPDFreeMemory(
KERNEL_PVOID pv1,
KERNEL_PVOID pv2,
KERNEL_PVOID pv3
)
{
if (pv1)
LOCALFREE(pv1);
if (pv2)
LOCALFREE(pv2);
if (pv3)
LOCALFREE(pv3);
return TRUE;
}
/******************************Public*Routine******************************\
* GdiPrinterThunk function
*
* GDI callback for user-mode printer drivers.
*
* Parameters pumth
* Pointer to input buffer. Buffer has UMTHDR at
* beginning.
*
* pvOut
* Output buffer.
*
* cjOut
* Size of output buffer.
*
* Return Value
*
* The function returns GPT_ERROR if an error occurs. Otherwise, the
* return value is dependent on the command specified by pumth->ulType.
*
* History:
* 7/17/97 -by- Lingyun Wang [lingyunw] Added giant body to
* Make it do the real work
* 30-Jun-1997 -by- Gilman Wong [gilmanw]
* Wrote it.
\**************************************************************************/
extern PUMPD
FindUserModePrinterDriver(
PCWSTR pDriverDllName,
DWORD dwDriverVersion,
BOOL bUseVersion
);
WINGDIAPI
ULONG
WINAPI
GdiPrinterThunk (
UMTHDR * pvIn,
PVOID pvOut,
ULONG cjOut
)
{
INT iRet = 1;
UMPDTHDR * pumpdthdr = (UMPDTHDR *) pvIn;
HUMPD hSaved;
BOOL bWOW64 = FALSE, bSetPUMPD = FALSE;
ULONG ulType = pvIn->ulType;
//
// Call NtGdiSetPUMPDOBJ to set the W32THREAD.pUMPDObj pointer
// only if this is a DDI thunk
//
if (ulType <= INDEX_LAST+1)
{
if (!(bSetPUMPD = NtGdiSetPUMPDOBJ(pumpdthdr->humpd, TRUE, &hSaved, &bWOW64)))
{
WARNING ("NtGdiSetPUMPDOBJ failed\n");
return GPT_ERROR;
}
}
switch (ulType)
{
case INDEX_LoadUMPrinterDrv:
{
PLOADDRIVERINPUT pInput = (PLOADDRIVERINPUT) pvIn;
PUMPD pUMPD = NULL;
HANDLE hPrinter = NULL;
*((PUMPD *)pvOut) = NULL;
if(BLOADSPOOLER)
{
(*fpOpenPrinterW)(pInput->pPrinterName, &hPrinter, (LPPRINTER_DEFAULTSW)&pInput->defaults);
if(hPrinter)
{
if(LoadUserModePrinterDriverEx((PDRIVER_INFO_5W)&pInput->driverInfo, NULL, &pUMPD, NULL, 0) &&
bAddPrinterHandle(pUMPD, pInput->clientPid, pInput->hPrinter32, hPrinter))
{
*((PUMPD *) pvOut) = pUMPD;
}
else
{
if (pUMPD)
UnloadUserModePrinterDriver(pUMPD, TRUE, 0);
(*fpClosePrinter)(hPrinter);
WARNING("GdiPrinterThunk: failed to load umpd or add printer handles\n");
}
}
else
{
WARNING(("failed opening printer '%ls' on proxy\n", (PCH)pInput->pPrinterName));
}
}
else
{
WARNING("GdiPrinterThunk: failed loading spooler\n");
}
}
break;
case INDEX_UnloadUMPrinterDrv:
{
PUNLOADDRIVERINPUT pInput = (PUNLOADDRIVERINPUT) pvIn;
PUMPD pUMPD = (PUMPD) pInput->umpdCookie;
PHPRINTERLIST pList;
if (pInput->hPrinter32 &&
(pList = FindPrinterHandle(pUMPD, pInput->clientPid, pInput->hPrinter32)))
{
(*fpClosePrinter)(pList->hPrinter64);
DeletePrinterHandle(pUMPD, pList);
}
UnloadUserModePrinterDriver(pUMPD, pInput->bNotifySpooler, 0);
}
break;
case INDEX_UMDriverFN:
{
PDRVDRIVERFNINPUT pInput = (PDRVDRIVERFNINPUT) pvIn;
PUMPD pUMPD = (PUMPD) pInput->cookie;
BOOL * pbDrvFn = (BOOL *) pvOut;
int index;
if(pUMPD)
{
for(index = 0; index < INDEX_LAST; index++)
pbDrvFn[index] = (pUMPD->apfn[index] != NULL ? TRUE : FALSE);
}
else
{
RtlZeroMemory(pvOut, sizeof(BOOL) * INDEX_LAST);
}
}
break;
case INDEX_DocumentEvent:
{
PDOCUMENTEVENTINPUT pInput = (PDOCUMENTEVENTINPUT) pvIn;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
{
*((int*)pvOut) = (*fpDocumentEvent)(pList->hPrinter64,
pInput->hdc,
pInput->iEsc,
pInput->cjIn,
(PVOID)pInput->pvIn,
pInput->cjOut,
(PVOID)pInput->pvOut);
if (pInput->iEsc == DOCUMENTEVENT_CREATEDCPRE || pInput->iEsc == DOCUMENTEVENT_RESETDCPRE)
{
if ((*((int*)pvOut) != DOCUMENTEVENT_FAILURE) &&
*((DEVMODEW**)pInput->pvOut))
{
RtlCopyMemory(pInput->pdmCopy, *((DEVMODEW**)pInput->pvOut), sizeof(DEVMODEW));
}
}
}
else
*((int*)pvOut) = DOCUMENTEVENT_FAILURE;
}
break;
case INDEX_StartDocPrinterW:
{
PSTARTDOCPRINTERWINPUT pInput = (PSTARTDOCPRINTERWINPUT) pvIn;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
{
*((DWORD*)pvOut) = (*fpStartDocPrinterW)(pList->hPrinter64,
pInput->level,
(LPBYTE)&pInput->docInfo);
pInput->lastError = GetLastError();
}
else
*((DWORD*)pvOut) = 0;
}
break;
case INDEX_StartPagePrinter:
{
PUMPDSIMPLEINPUT pInput = (PUMPDSIMPLEINPUT) pvIn;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
*((BOOL*)pvOut) = (*fpStartPagePrinter)(pList->hPrinter64);
else
*((BOOL*)pvOut) = FALSE;
}
break;
case INDEX_EndPagePrinter:
{
PUMPDSIMPLEINPUT pInput = (PUMPDSIMPLEINPUT) pvIn;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
{
*((BOOL*)pvOut) = (*fpEndPagePrinter)(pList->hPrinter64);
}
else
{
*((BOOL*)pvOut) = FALSE;
}
}
break;
case INDEX_EndDocPrinter:
{
PUMPDSIMPLEINPUT pInput = (PUMPDSIMPLEINPUT) pvIn;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
*((BOOL*)pvOut) = (*fpEndDocPrinter)(pList->hPrinter64);
else
*((BOOL*)pvOut) = FALSE;
}
break;
case INDEX_AbortPrinter:
{
PUMPDSIMPLEINPUT pInput = (PUMPDSIMPLEINPUT) pvIn;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
*((BOOL*)pvOut) = (*fpAbortPrinter)(pList->hPrinter64);
else
*((BOOL*)pvOut) = FALSE;
}
break;
case INDEX_ResetPrinterW:
{
PRESETPRINTERWINPUT pInput = (PRESETPRINTERWINPUT) pvIn;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
{
*((BOOL*)pvOut) = (*fpResetPrinterW)(pList->hPrinter64,
(PRINTER_DEFAULTSW*)&pInput->ptrDef);
}
else
*((BOOL*)pvOut) = FALSE;
}
break;
case INDEX_QueryColorProfile:
{
PQUERYCOLORPROFILEINPUT pInput = (PQUERYCOLORPROFILEINPUT) pvIn;
ULONG cjProfileSizeOld = pInput->cjProfileSize;
PHPRINTERLIST pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, pInput->hPrinter32);
if (pList)
{
*((BOOL*)pvOut) = (*fpQueryColorProfile)(pList->hPrinter64,
pInput->pDevMode,
pInput->ulQueryMode,
pInput->pvProfileData,
&pInput->cjProfileSize,
&pInput->flProfileFlag);
if ((*(INT*)pvOut) == 0 &&
pInput->cjProfileSize > cjProfileSizeOld &&
(GetLastError() == ERROR_INSUFFICIENT_BUFFER))
{
pInput->lastError = GetLastError();
}
}
else
*((BOOL*)pvOut) = FALSE;
}
break;
case INDEX_UMPDDrvEnableDriver: // special index for DrvEnableDriver
{
PDRVENABLEDRIVERINPUT pInput = (PDRVENABLEDRIVERINPUT) pvIn;
*((PUMPD *) pvOut) = UMPDDrvEnableDriver(pInput->pwszDriver, DDI_DRIVER_VERSION_NT5_01_SP1);
}
break;
case INDEX_DrvEnablePDEV:
{
PDRVENABLEPDEVINPUT pInput = (PDRVENABLEPDEVINPUT) pvIn;
PUMPD pUMPD = (PUMPD) pInput->umpdCookie;
PFN pfn = pUMPD->apfn[INDEX_DrvEnablePDEV];
PUMDHPDEV pUMdhpdev;
HANDLE hPrinter = NULL;
PHPRINTERLIST pList;
// If we have a local hPrinter use it
if (pInput->bWOW64 &&
(pList = FindPrinterHandle((PUMPD)pInput->umpdCookie, pInput->clientPid, HandleToUlong(pInput->hPrinter))))
{
hPrinter = pList->hPrinter64;
}
else
{
hPrinter = pInput->hPrinter;
}
if (pUMdhpdev = (PUMDHPDEV) LOCALALLOC(sizeof(UMDHPDEV)))
{
ZeroMemory(pUMdhpdev, sizeof(UMDHPDEV));
pUMdhpdev->pUMPD = pUMPD;
pUMdhpdev->dhpdev = (DHPDEV) pfn(
pInput->pdm,
pInput->pLogAddress,
pInput->cPatterns,
pInput->phsurfPatterns,
pInput->cjCaps,
pInput->pdevcaps,
pInput->cjDevInfo,
pInput->pDevInfo,
pInput->hdev,
pInput->pDeviceName,
hPrinter);
if (pUMdhpdev->dhpdev == NULL)
{
WARNING ("Driver's DrvEnablePDEV failed\n");
LOCALFREE(pUMdhpdev);
pUMdhpdev = NULL;
}
#if defined(_WIN64)
else
{
if (pInput->bWOW64 && pInput->pdevcaps)
{
GDIINFO *pGdiInfo = (GDIINFO*)pInput->pdevcaps;
if (pGdiInfo->ulHTPatternSize == HT_PATSIZE_USER &&
pGdiInfo->cxHTPat <= HT_USERPAT_CX_MAX &&
pGdiInfo->cyHTPat <= HT_USERPAT_CY_MAX)
{
pInput->cxHTPat = pGdiInfo->cxHTPat;
pInput->cyHTPat = pGdiInfo->cyHTPat;
pInput->bHTPatA = pGdiInfo->pHTPatA ? TRUE : FALSE;
pInput->bHTPatB = pGdiInfo->pHTPatB ? TRUE : FALSE;
pInput->bHTPatC = pGdiInfo->pHTPatC ? TRUE : FALSE;
if (pInput->bHTPatA)
{
RtlCopyMemory(pInput->pHTPatA,
pGdiInfo->pHTPatA,
pInput->cxHTPat*
pInput->cyHTPat);
}
if (pInput->bHTPatB)
{
RtlCopyMemory(pInput->pHTPatB,
pGdiInfo->pHTPatB,
pInput->cxHTPat*
pInput->cyHTPat);
}
if (pInput->bHTPatC)
{
RtlCopyMemory(pInput->pHTPatC,
pGdiInfo->pHTPatC,
pInput->cxHTPat*
pInput->cyHTPat);
}
}
}
}
#endif
}
else
{
WARNING ("umEnablePDEV failed memory allocation \n");
}
*((DHPDEV *) pvOut) = (DHPDEV) pUMdhpdev;
}
break;
case INDEX_DrvCompletePDEV:
{
PDRVCOMPLETEPDEVINPUT pInput = (PDRVCOMPLETEPDEVINPUT) pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV) pInput->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvCompletePDEV];
pfn(pUMdhpdev->dhpdev, pInput->hdev);
}
break;
case INDEX_DrvFree:
{
PDRVFREEINPUT pInput = (PDRVFREEINPUT) pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV) pInput->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvFree];
if (pfn)
pfn(pInput->pv, pInput->id);
}
break;
case INDEX_DrvResetPDEV:
{
PDRVRESETPDEVINPUT pInput = (PDRVRESETPDEVINPUT) pvIn;
PUMDHPDEV pUMdhpdevOld= (PUMDHPDEV) pInput->dhpdevOld;
PUMDHPDEV pUMdhpdevNew= (PUMDHPDEV) pInput->dhpdevNew;
PUMPD pUMPDNew = pUMdhpdevNew->pUMPD;
PFN pfn = pUMPDNew->apfn[INDEX_DrvResetPDEV];
*((BOOL *) pvOut) = (BOOL)pfn(pUMdhpdevOld->dhpdev, pUMdhpdevNew->dhpdev);
}
break;
case INDEX_DrvDisablePDEV:
{
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)((PDHPDEVINPUT)pvIn)->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvDisablePDEV];
pfn(pUMdhpdev->dhpdev);
// free up memory allocated for user mode printer drivers
if (pUMdhpdev)
{
LOCALFREE (pUMdhpdev);
}
}
break;
case INDEX_DrvEnableSurface:
{
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)((PDHPDEVINPUT)pvIn)->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvEnableSurface];
*((HSURF *) pvOut) = (HSURF) pfn(pUMdhpdev->dhpdev);
}
break;
case INDEX_DrvDisableSurface:
{
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)((PDHPDEVINPUT)pvIn)->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvDisableSurface];
pfn(pUMdhpdev->dhpdev);
}
break;
case INDEX_DrvStartDoc:
{
PDRVSTARTDOCINPUT pInput = (PDRVSTARTDOCINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
//
// check to make sure we have a dhpdev in the surface
// neither Unidrv or Pscript checks if EngAssociateSurface is
// successful or not
//
if (pUMdhpdev)
{
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvStartDoc];
*((BOOL *) pvOut) = (BOOL)pfn(pInput->pso, pInput->pwszDocName, pInput->dwJobId);
}
else
*(BOOL *)pvOut = FALSE;
}
break;
case INDEX_DrvEndDoc:
{
PDRVENDDOCINPUT pInput = (PDRVENDDOCINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvEndDoc];
*((BOOL *) pvOut) = (BOOL)pfn(pInput->pso, pInput->fl );
}
break;
case INDEX_DrvStartPage:
{
PSURFOBJINPUT pInput = (PSURFOBJINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvStartPage];
*((BOOL *) pvOut) = (BOOL)pfn(pInput->pso);
}
break;
case INDEX_DrvSendPage:
{
PSURFOBJINPUT pInput = (PSURFOBJINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvSendPage];
*((BOOL *) pvOut) = (BOOL)pfn(pInput->pso);
}
break;
case INDEX_DrvEscape:
{
PDRVESCAPEINPUT pInput = (PDRVESCAPEINPUT) pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvEscape];
*((ULONG *) pvOut) = (ULONG) pfn(pInput->pso,
pInput->iEsc,
pInput->cjIn,
pInput->pvIn,
pInput->cjOut,
pInput->pvOut);
}
break;
case INDEX_DrvDrawEscape:
{
PDRVDRAWESCAPEINPUT pInput = (PDRVDRAWESCAPEINPUT) pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvDrawEscape];
*((ULONG *) pvOut) = (ULONG) pfn(pInput->pso,
pInput->iEsc,
pInput->pco,
pInput->prcl,
pInput->cjIn,
pInput->pvIn);
}
break;
case INDEX_DrvStartBanding:
{
PDRVBANDINGINPUT pInput = (PDRVBANDINGINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvStartBanding];
*((BOOL *) pvOut) = (BOOL)pfn(pInput->pso, pInput->pptl);
}
break;
case INDEX_DrvQueryPerBandInfo:
{
PDRVPERBANDINPUT pInput = (PDRVPERBANDINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvQueryPerBandInfo];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->pso, pInput->pbi);
}
break;
case INDEX_DrvNextBand:
{
PDRVBANDINGINPUT pInput = (PDRVBANDINGINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvNextBand];
*((BOOL *) pvOut) = (BOOL)pfn(pInput->pso, pInput->pptl);
}
break;
case INDEX_DrvBitBlt:
{
PDRVBITBLTINPUT pInput = (PDRVBITBLTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvBitBlt];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->psoTrg,
pInput->psoSrc,
pInput->psoMask,
pInput->pco,
pInput->pxlo,
pInput->prclTrg,
pInput->pptlSrc,
pInput->pptlMask,
pInput->pbo,
pInput->pptlBrush,
pInput->rop4);
if (bWOW64 && pInput->pbo)
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pbo, NULL);
}
}
break;
case INDEX_DrvStretchBlt:
{
PDRVSTRETCHBLTINPUT pInput = (PDRVSTRETCHBLTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvStretchBlt];
*((BOOL *) pvOut) = (BOOL) pfn (pInput->psoTrg,
pInput->psoSrc,
pInput->psoMask,
pInput->pco,
pInput->pxlo,
pInput->pca,
pInput->pptlHTOrg,
pInput->prclTrg,
pInput->prclSrc,
pInput->pptlMask,
pInput->iMode);
}
break;
case INDEX_DrvStretchBltROP:
{
PDRVSTRETCHBLTINPUT pInput = (PDRVSTRETCHBLTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvStretchBltROP];
*((BOOL *) pvOut) = (BOOL) pfn (pInput->psoTrg,
pInput->psoSrc,
pInput->psoMask,
pInput->pco,
pInput->pxlo,
pInput->pca,
pInput->pptlHTOrg,
pInput->prclTrg,
pInput->prclSrc,
pInput->pptlMask,
pInput->iMode,
pInput->pbo,
pInput->rop4);
if (bWOW64 && pInput->pbo)
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pbo, NULL);
}
}
break;
case INDEX_DrvPlgBlt:
{
PDRVPLGBLTINPUT pInput = (PDRVPLGBLTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvPlgBlt];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->psoTrg,
pInput->psoSrc,
pInput->psoMask,
pInput->pco,
pInput->pxlo,
pInput->pca,
pInput->pptlBrushOrg,
pInput->pptfx,
pInput->prcl,
pInput->pptl,
pInput->iMode);
}
break;
case INDEX_DrvCopyBits:
{
PDRVCOPYBITSINPUT pInput = (PDRVCOPYBITSINPUT) pvIn;
PUMDHPDEV pUMdhpdev;
PUMPD pUMPD;
PFN pfn;
SURFOBJ *pso;
//
// Special case when psoSrc is a device surface and
// psoTrg is a bitmap surface. This is used by the engine
// during simulation of certain drawing calls.
//
pso = (pInput->psoTrg->iType == STYPE_BITMAP &&
pInput->psoTrg->dhpdev == NULL) ?
pInput->psoSrc :
pInput->psoTrg;
if (pso && (pUMdhpdev = AdjustUMdhpdev(pso)))
{
pUMPD = pUMdhpdev->pUMPD;
pfn = pUMPD->apfn[INDEX_DrvCopyBits];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->psoTrg,
pInput->psoSrc,
pInput->pco,
pInput->pxlo,
pInput->prclTrg,
pInput->pptlSrc);
}
else
{
*((BOOL *) pvOut) = FALSE;
}
}
break;
case INDEX_DrvRealizeBrush:
{
PDRVREALIZEBRUSHINPUT pInput = (PDRVREALIZEBRUSHINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvRealizeBrush];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->pbo,
pInput->psoTrg,
pInput->psoPat,
pInput->psoMsk,
pInput->pxlo,
pInput->iHatch);
}
break;
case INDEX_DrvLineTo:
{
PDRVLINETOINPUT pInput = (PDRVLINETOINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvLineTo];
*((BOOL *) pvOut) = (BOOL) pfn (pInput->pso,
pInput->pco,
pInput->pbo,
pInput->x1,
pInput->y1,
pInput->x2,
pInput->y2,
pInput->prclBounds,
pInput->mix);
if (bWOW64 && pInput->pbo)
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pbo, NULL);
}
}
break;
case INDEX_DrvStrokePath:
{
PSTROKEANDFILLINPUT pInput = (PSTROKEANDFILLINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvStrokePath];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->pso,
pInput->ppo,
pInput->pco,
pInput->pxo,
pInput->pbo,
pInput->pptlBrushOrg,
pInput->plineattrs,
pInput->mix);
if (bWOW64 && pInput->pbo)
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pbo, NULL);
}
}
break;
case INDEX_DrvFillPath:
{
PSTROKEANDFILLINPUT pInput = (PSTROKEANDFILLINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvFillPath];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->pso,
pInput->ppo,
pInput->pco,
pInput->pbo,
pInput->pptlBrushOrg,
pInput->mix,
pInput->flOptions);
if (bWOW64 && pInput->pbo)
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pbo, NULL);
}
}
break;
case INDEX_DrvStrokeAndFillPath:
{
PSTROKEANDFILLINPUT pInput = (PSTROKEANDFILLINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvStrokeAndFillPath];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->pso,
pInput->ppo,
pInput->pco,
pInput->pxo,
pInput->pbo,
pInput->plineattrs,
pInput->pboFill,
pInput->pptlBrushOrg,
pInput->mix,
pInput->flOptions);
if (bWOW64 && (pInput->pbo || pInput->pboFill))
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pbo, pInput->pboFill);
}
}
break;
case INDEX_DrvPaint:
{
PSTROKEANDFILLINPUT pInput = (PSTROKEANDFILLINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvPaint];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->pso,
pInput->pco,
pInput->pbo,
pInput->pptlBrushOrg,
pInput->mix);
if (bWOW64 && pInput->pbo)
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pbo, NULL);
}
}
break;
case INDEX_DrvGradientFill:
{
PGRADIENTINPUT pInput = (PGRADIENTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvGradientFill];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->psoTrg,
pInput->pco,
pInput->pxlo,
pInput->pVertex,
pInput->nVertex,
pInput->pMesh,
pInput->nMesh,
pInput->prclExtents,
pInput->pptlDitherOrg,
pInput->ulMode);
}
break;
case INDEX_DrvAlphaBlend:
{
PALPHAINPUT pInput = (PALPHAINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvAlphaBlend];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->psoTrg,
pInput->psoSrc,
pInput->pco,
pInput->pxlo,
pInput->prclDest,
pInput->prclSrc,
pInput->pBlendObj);
}
break;
case INDEX_DrvTransparentBlt:
{
PTRANSPARENTINPUT pInput = (PTRANSPARENTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->psoTrg);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvTransparentBlt];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->psoTrg,
pInput->psoSrc,
pInput->pco,
pInput->pxlo,
pInput->prclDst,
pInput->prclSrc,
pInput->TransColor,
pInput->ulReserved);
}
break;
case INDEX_DrvTextOut:
{
PTEXTOUTINPUT pInput = (PTEXTOUTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvTextOut];
*((BOOL *) pvOut) = (BOOL) pfn(pInput->pso,
pInput->pstro,
pInput->pfo,
pInput->pco,
pInput->prclExtra,
pInput->prclOpaque,
pInput->pboFore,
pInput->pboOpaque,
pInput->pptlOrg,
pInput->mix);
if (bWOW64 && (pInput->pboFore || pInput->pboOpaque))
{
NtGdiBRUSHOBJ_DeleteRbrush(pInput->pboFore, pInput->pboOpaque);
}
}
break;
case INDEX_DrvQueryFont:
{
PQUERYFONTINPUT pInput = (PQUERYFONTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)(pInput->dhpdev);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvQueryFont];
*((PIFIMETRICS *) pvOut) = (PIFIMETRICS) pfn(
pUMdhpdev->dhpdev,
pInput->iFile,
pInput->iFace,
pInput->pid);
if (pInput->iFace && *((PIFIMETRICS*)pvOut) && pInput->pv)
{
ASSERTGDI(pInput->cjMaxData >= (*(PIFIMETRICS*)pvOut)->cjThis, "gdi32!GdiPrinterThunk: not enough buffer for ifimetrics\n");
if (pInput->cjMaxData >= (*(PIFIMETRICS*)pvOut)->cjThis)
{
RtlCopyMemory(pInput->pv, (PBYTE)(*(PIFIMETRICS*)pvOut), (*(PIFIMETRICS*)pvOut)->cjThis);
}
else
{
iRet = -1;
WARNING(("Not enough buffer for ifimetrics cjMaxData: 0x%lx cjSize: 0x%lx pInput.pv %lp pvOut %lp\n",
pInput->cjMaxData, (*(PIFIMETRICS*)pvOut)->cjThis, pInput->pv, pvOut));
pInput->cjMaxData = 0;
}
}
}
break;
case INDEX_DrvQueryFontTree:
{
PQUERYFONTINPUT pInput = (PQUERYFONTINPUT)pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)(pInput->dhpdev);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvQueryFontTree];
ULONG cjSize = 0;
FD_GLYPHSET* pfdg;
*((PVOID *) pvOut) = (PVOID) pfn (pUMdhpdev->dhpdev,
pInput->iFile,
pInput->iFace,
pInput->iMode,
pInput->pid);
if (pInput->iMode == QFT_GLYPHSET && *((FD_GLYPHSET**)pvOut) && pInput->pv)
{
pfdg = *((FD_GLYPHSET**)pvOut);
cjSize = offsetof(FD_GLYPHSET, awcrun) + pfdg->cRuns * sizeof(WCRUN) + pfdg->cGlyphsSupported * sizeof(HGLYPH);
ASSERTGDI(pInput->cjMaxData >= cjSize, "gdi32!GdiPrinterThunk: not enough buffer for glyphset\n");
if ((pInput->cjMaxData < cjSize) ||
!GdiCopyFD_GLYPHSET((FD_GLYPHSET*)pInput->pv, pfdg, cjSize))
{
WARNING("GDI32: Not enough bufer or error copying FD_GLYPHSET\n");
pInput->cjMaxData = 0;
iRet = -1;
}
}
else if (pInput->iMode == QFT_KERNPAIRS && *(FD_KERNINGPAIR **)pvOut && pInput->pv)
{
FD_KERNINGPAIR *pkpEnd = *(FD_KERNINGPAIR **)pvOut;
while ((pkpEnd->wcFirst) || (pkpEnd->wcSecond) || (pkpEnd->fwdKern))
{
pkpEnd += 1;
cjSize++;
}
cjSize = (cjSize + 1) * sizeof(FD_KERNINGPAIR);
ASSERTGDI(pInput->cjMaxData >= cjSize, "gdi32!GdiPrinterThunk: not enough buffer for Kerningpairs\n");
if (pInput->cjMaxData >= cjSize)
{
RtlCopyMemory(pInput->pv, (PBYTE)(*(FD_KERNINGPAIR **)pvOut), cjSize);
}
else
{
WARNING(("Not enough buffer forkerningpair cjMaxData: 0x%lx cjSize: 0x%lx pInput.pv %lp pvOut %lp\n",
pInput->cjMaxData, cjSize, pInput->pv, pvOut));
pInput->cjMaxData = 0;
iRet = -1;
}
}
}
break;
case INDEX_DrvQueryFontData:
{
PQUERYFONTDATAINPUT pInput = (PQUERYFONTDATAINPUT)pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)(pInput->dhpdev);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvQueryFontData];
*((ULONG *) pvOut) = (ULONG)pfn (pUMdhpdev->dhpdev,
pInput->pfo,
pInput->iMode,
pInput->hg,
pInput->pgd,
pInput->pv,
pInput->cjSize);
}
break;
case INDEX_DrvQueryAdvanceWidths:
{
PQUERYADVWIDTHSINPUT pInput = (PQUERYADVWIDTHSINPUT)pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)(pInput->dhpdev);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvQueryAdvanceWidths];
*((BOOL *) pvOut) = (BOOL)pfn (pUMdhpdev->dhpdev,
pInput->pfo,
pInput->iMode,
pInput->phg,
pInput->pvWidths,
pInput->cGlyphs);
}
break;
case INDEX_DrvGetGlyphMode:
{
PQUERYFONTDATAINPUT pInput = (PQUERYFONTDATAINPUT)pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)(pInput->dhpdev);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvGetGlyphMode];
*((ULONG *) pvOut) = (ULONG) pfn (pUMdhpdev->dhpdev, pInput->pfo);
}
break;
case INDEX_DrvFontManagement:
{
PFONTMANAGEMENTINPUT pInput = (PFONTMANAGEMENTINPUT)pvIn;
PUMDHPDEV pUMdhpdev;
PUMPD pUMPD;
PFN pfn;
if (pInput->iMode == QUERYESCSUPPORT)
pUMdhpdev = (PUMDHPDEV) pInput->dhpdev;
else
pUMdhpdev = AdjustUMdhpdev(pInput->pso);
pUMPD = pUMdhpdev->pUMPD;
pfn = pUMPD->apfn[INDEX_DrvFontManagement];
*((ULONG *) pvOut) = (ULONG)pfn(pInput->pso,
pInput->pfo,
pInput->iMode,
pInput->cjIn,
pInput->pvIn,
pInput->cjOut,
pInput->pvOut);
}
break;
case INDEX_DrvDitherColor:
{
PDRVDITHERCOLORINPUT pInput = (PDRVDITHERCOLORINPUT)pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV)pInput->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvDitherColor];
*((ULONG *) pvOut) = (ULONG)pfn(pUMdhpdev->dhpdev,
pInput->iMode,
pInput->rgb,
pInput->pul);
}
break;
case INDEX_DrvDeleteDeviceBitmap:
{
PDRVDELETEDEVBITMAP pInput = (PDRVDELETEDEVBITMAP) pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV) pInput->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvDeleteDeviceBitmap];
pfn(pUMdhpdev->dhpdev, pInput->dhsurf);
}
break;
case INDEX_DrvIcmDeleteColorTransform:
{
PDRVICMDELETECOLOR pInput = (PDRVICMDELETECOLOR)pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV) pInput->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvIcmDeleteColorTransform];
*((BOOL *) pvOut) = (BOOL)pfn(pUMdhpdev->dhpdev, pInput->hcmXform);
}
break;
case INDEX_DrvIcmCreateColorTransform:
{
PDRVICMCREATECOLORINPUT pInput = (PDRVICMCREATECOLORINPUT) pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV) pInput->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvIcmCreateColorTransform];
*((HANDLE *) pvOut) = (HANDLE)pfn(pUMdhpdev->dhpdev,
pInput->pLogColorSpace,
pInput->pvSourceProfile,
pInput->cjSourceProfile,
pInput->pvDestProfile,
pInput->cjDestProfile,
pInput->pvTargetProfile,
pInput->cjTargetProfile,
pInput->dwReserved);
}
break;
case INDEX_DrvIcmCheckBitmapBits:
{
PDRVICMCHECKBITMAPINPUT pInput = (PDRVICMCHECKBITMAPINPUT) pvIn;
PUMDHPDEV pUMdhpdev = (PUMDHPDEV) pInput->dhpdev;
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvIcmCheckBitmapBits];
pfn(pUMdhpdev->dhpdev,
pInput->hColorTransform,
pInput->pso,
pInput->paResults);
}
break;
case INDEX_DrvQueryDeviceSupport:
{
PDRVQUERYDEVICEINPUT pInput = (PDRVQUERYDEVICEINPUT) pvIn;
PUMDHPDEV pUMdhpdev = AdjustUMdhpdev(pInput->pso);
PUMPD pUMPD = pUMdhpdev->pUMPD;
PFN pfn = pUMPD->apfn[INDEX_DrvQueryDeviceSupport];
*((ULONG *) pvOut) = (ULONG) pfn(pInput->pso,
pInput->pxlo,
pInput->pxo,
pInput->iType,
pInput->cjIn,
pInput->pvIn,
pInput->cjOut,
pInput->pvOut);
}
break;
case INDEX_UMPDAllocUserMem:
{
PUMPDALLOCUSERMEMINPUT pInput = (PUMPDALLOCUSERMEMINPUT) pvIn;
ASSERTGDI(bWOW64, "Calling INDEX_UMPDAllocUserMem during NONE wow64 printing\n");
*((KERNEL_PVOID*)pvOut) = UMPDAllocUserMem(pInput->cjSize);
}
break;
case INDEX_UMPDCopyMemory:
{
PUMPDCOPYMEMINPUT pInput = (PUMPDCOPYMEMINPUT) pvIn;
ASSERTGDI(bWOW64, "Calling INDEX_UMPDCopyMemory during NONE wow64 printing\n");
*((KERNEL_PVOID*)pvOut) = UMPDCopyMemory(pInput->pvSrc,
pInput->pvDest,
pInput->cjSize);
}
break;
case INDEX_UMPDFreeMemory:
{
PUMPDFREEMEMINPUT pInput = (PUMPDFREEMEMINPUT) pvIn;
ASSERTGDI(bWOW64, "Calling INDEX_UMPDFreeMemory during NONE wow64 printing\n");
*((BOOL*)pvOut) = UMPDFreeMemory(pInput->pvTrg,
pInput->pvSrc,
pInput->pvMsk);
}
break;
case INDEX_UMPDEngFreeUserMem:
{
PUMPDFREEMEMINPUT pInput = (PUMPDFREEMEMINPUT) pvIn;
if (bWOW64)
{
*((BOOL*)pvOut) = NtGdiUMPDEngFreeUserMem(&pInput->pvTrg);
}
}
break;
default:
WARNING ("Drv call is not supported\n");
iRet = GPT_ERROR;
break;
}
if (bSetPUMPD)
{
NtGdiSetPUMPDOBJ(hSaved, FALSE, &pumpdthdr->humpd, NULL);
}
return (iRet);
}
#endif // !_GDIPLUS_