I'm writting a Microsoft Universal Printer Driver for our printer (User Mode Driver).
When implementing the OEMTextOut() hook, we need to get the font information from the FONTOBJ, but seems there no way to do that, below are what I have tried:
- Try to get IFIMETRICS by FONTOBJ_pifi() which come from win32k library, but the driver just simple crash if we link to win32k.lib
- Call DRVENABLEDATA->pdrvfn[INDEX_DrvQueryFont] which comes from IPrintOemUni2::EnablePDEV, not working, that function just reports "OEMTextOut failed with error 87: " (argument error) I take a research on it's argument dhpdev: The PDEVOEM which we generated in the EnablePDEV()
iFile: 0ll
iFace: 1l
- Search on the network, does not find any related information
I take weeks to try to get a way out, but seems no luck. Could someone give me a hand? Thanks!
Sample Code:
typedef struct _OEMPDEV {
// The full driver function table table
PFN drvfn[INDEX_LAST + 1];
} OEMPDEV, * POEMPDEV;
HRESULT __stdcall OemUni::EnablePDEV(
PDEVOBJ pdevobj,
_In_ PWSTR pPrinterName,
ULONG cPatterns,
HSURF* phsurfPatterns,
ULONG cjGdiInfo,
GDIINFO* pGdiInfo,
ULONG cjDevInfo,
DEVINFO* pDevInfo,
DRVENABLEDATA* pded,
OUT PDEVOEM* pDevOem)
{
POEMPDEV poempdev;
INT i;
PDRVFN pdrvfn;
//
// Allocate the OEMDev
//
poempdev = new OEMPDEV;
if (NULL == poempdev)
{
return NULL;
}
//
// Fill in OEMDEV
//
memset(poempdev->drvfn, 0, sizeof(poempdev->drvfn));
for (i = 0; i < (INT)pded->c; ++i)
{
if (i >= _countof(poempdev->drvfn))
{
break;
}
pdrvfn = &pded->pdrvfn[i];
poempdev->drvfn[pdrvfn->iFunc] = pdrvfn->pfn;
}
*pDevOem = (POEMPDEV)poempdev;
return (NULL != *pDevOem ? S_OK : E_FAIL);
}
BOOL APIENTRY
OEMTextOut(
SURFOBJ* pso,
STROBJ* pstro,
FONTOBJ* pfo,
CLIPOBJ* pco,
RECTL* prclExtra,
RECTL* prclOpaque,
BRUSHOBJ* pboFore,
BRUSHOBJ* pboOpaque,
POINTL* pptlOrg,
MIX mix
)
{
ULONG_PTR _pid = 0;
PDEVOBJ pdevobj;
POEMPDEV poempdev;
pdevobj = (PDEVOBJ)pso->dhpdev;
poempdev = (POEMPDEV)pdevobj->pdevOEM;
// Pass DHPDEV which output from EnablePDEV, failed return error 87, with NULL result
PIFIMETRICS metrics = ((PFN_DrvQueryFont)poempdev->drvfn[INDEX_DrvQueryFont])((DHPDEV)poempdev, pfo->iFile, pfo->iFace, &_pid);
// Driver crash, not allowed
metrics = FONTOBJ_pifi(pfo);
// Try pass the dhpdev of SURFOBJ, but still failed return error 87, with NULL result
metrics = ((PFN_DrvQueryFont)(poempdev->drvfn[INDEX_DrvQueryFont]))(pso->dhpdev, pfo->iFile, pfo->iFace, &_pid);
return (((PFN_DrvTextOut)(poempdev->drvfn[INDEX_DrvTextOut])) (
pso,
pstro,
pfo,
pco,
prclExtra,
prclOpaque,
pboFore,
pboOpaque,
pptlOrg,
mix));
}