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
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_
|
|
|