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.
954 lines
23 KiB
954 lines
23 KiB
/*++
|
|
|
|
Copyright (c) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
oemkm.c
|
|
|
|
Abstract:
|
|
|
|
Kernel mode support for OEM plugins
|
|
|
|
Environment:
|
|
|
|
Windows NT Unidrv driver
|
|
|
|
Revision History:
|
|
|
|
04/01/97 -zhanw-
|
|
Adapted from Pscript source
|
|
|
|
--*/
|
|
|
|
#include "unidrv.h"
|
|
|
|
#ifdef WINNT_40
|
|
|
|
//
|
|
// The global link list of ref counts for currently loaded OEM render plugin DLLs
|
|
//
|
|
|
|
POEM_PLUGIN_REFCOUNT gpOEMPluginRefCount;
|
|
|
|
static const CHAR szDllInitialize[] = "DllInitialize";
|
|
|
|
#endif // WINNT_40
|
|
|
|
//
|
|
// Unidrv specific OEM entrypoints
|
|
//
|
|
// NOTE: Please keep this in sync with indices defined in printer5\inc\oemutil.h!!!
|
|
//
|
|
|
|
static CONST PSTR OEMUnidrvProcNames[MAX_UNIDRV_ONLY_HOOKS] = {
|
|
"OEMCommandCallback",
|
|
"OEMImageProcessing",
|
|
"OEMFilterGraphics",
|
|
"OEMCompression",
|
|
"OEMHalftonePattern",
|
|
"OEMMemoryUsage",
|
|
"OEMDownloadFontHeader",
|
|
"OEMDownloadCharGlyph",
|
|
"OEMTTDownloadMethod",
|
|
"OEMOutputCharStr",
|
|
"OEMSendFontCmd",
|
|
"OEMTTYGetInfo",
|
|
"OEMTextOutAsBitmap",
|
|
"OEMWritePrinter",
|
|
};
|
|
|
|
|
|
static CONST PSTR COMUnidrvProcNames[MAX_UNIDRV_ONLY_HOOKS] = {
|
|
"CommandCallback",
|
|
"ImageProcessing",
|
|
"FilterGraphics",
|
|
"Compression",
|
|
"HalftonePattern",
|
|
"MemoryUsage",
|
|
"DownloadFontHeader",
|
|
"DownloadCharGlyph",
|
|
"TTDownloadMethod",
|
|
"OutputCharStr",
|
|
"SendFontCmd",
|
|
"TTYGetInfo",
|
|
"TextOutAsBitmap",
|
|
"WritePrinter",
|
|
|
|
};
|
|
|
|
//
|
|
// OEM plugin helper function table
|
|
//
|
|
|
|
static const DRVPROCS OEMHelperFuncs = {
|
|
(PFN_DrvWriteSpoolBuf) WriteSpoolBuf,
|
|
(PFN_DrvXMoveTo) XMoveTo,
|
|
(PFN_DrvYMoveTo) YMoveTo,
|
|
(PFN_DrvGetDriverSetting) BGetDriverSettingForOEM,
|
|
(PFN_DrvGetStandardVariable) BGetStandardVariable,
|
|
(PFN_DrvUnidriverTextOut) FMTextOut,
|
|
(PFN_DrvWriteAbortBuf) WriteAbortBuf,
|
|
};
|
|
|
|
|
|
INT
|
|
IMapDDIIndexToOEMIndex(
|
|
ULONG ulDdiIndex
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Maps DDI entrypoint index to OEM entrypoint index
|
|
|
|
Arguments:
|
|
|
|
ulDdiIndex - DDI entrypoint index
|
|
|
|
Return Value:
|
|
|
|
OEM entrypoint index corresponding to the specified DDI entrypoint index
|
|
-1 if the specified DDI entrypoint cannot be hooked out by OEM plugins
|
|
|
|
--*/
|
|
|
|
{
|
|
static const struct {
|
|
ULONG ulDdiIndex;
|
|
INT iOemIndex;
|
|
}
|
|
OemToDdiMapping[] =
|
|
{
|
|
INDEX_DrvRealizeBrush, EP_OEMRealizeBrush,
|
|
INDEX_DrvDitherColor, EP_OEMDitherColor,
|
|
INDEX_DrvCopyBits, EP_OEMCopyBits,
|
|
INDEX_DrvBitBlt, EP_OEMBitBlt,
|
|
INDEX_DrvStretchBlt, EP_OEMStretchBlt,
|
|
#ifndef WINNT_40
|
|
INDEX_DrvStretchBltROP, EP_OEMStretchBltROP,
|
|
INDEX_DrvPlgBlt, EP_OEMPlgBlt,
|
|
INDEX_DrvTransparentBlt, EP_OEMTransparentBlt,
|
|
INDEX_DrvAlphaBlend, EP_OEMAlphaBlend,
|
|
INDEX_DrvGradientFill, EP_OEMGradientFill,
|
|
#endif
|
|
INDEX_DrvTextOut, EP_OEMTextOut,
|
|
INDEX_DrvStrokePath, EP_OEMStrokePath,
|
|
INDEX_DrvFillPath, EP_OEMFillPath,
|
|
INDEX_DrvStrokeAndFillPath, EP_OEMStrokeAndFillPath,
|
|
INDEX_DrvPaint, EP_OEMPaint,
|
|
INDEX_DrvLineTo, EP_OEMLineTo,
|
|
INDEX_DrvStartPage, EP_OEMStartPage,
|
|
INDEX_DrvSendPage, EP_OEMSendPage,
|
|
INDEX_DrvEscape, EP_OEMEscape,
|
|
INDEX_DrvStartDoc, EP_OEMStartDoc,
|
|
INDEX_DrvEndDoc, EP_OEMEndDoc,
|
|
INDEX_DrvNextBand, EP_OEMNextBand,
|
|
INDEX_DrvStartBanding, EP_OEMStartBanding,
|
|
INDEX_DrvQueryFont, EP_OEMQueryFont,
|
|
INDEX_DrvQueryFontTree, EP_OEMQueryFontTree,
|
|
INDEX_DrvQueryFontData, EP_OEMQueryFontData,
|
|
INDEX_DrvQueryAdvanceWidths, EP_OEMQueryAdvanceWidths,
|
|
INDEX_DrvFontManagement, EP_OEMFontManagement,
|
|
INDEX_DrvGetGlyphMode, EP_OEMGetGlyphMode,
|
|
};
|
|
|
|
INT iIndex;
|
|
INT iLimit = sizeof(OemToDdiMapping) / (sizeof(INT) * 2);
|
|
|
|
for (iIndex=0; iIndex < iLimit; iIndex++)
|
|
{
|
|
if (OemToDdiMapping[iIndex].ulDdiIndex == ulDdiIndex)
|
|
return OemToDdiMapping[iIndex].iOemIndex;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
BLoadAndInitOemPlugins(
|
|
PDEV *pPDev
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Get information about OEM plugins associated with the current device
|
|
Load them into memory and call OEMEnableDriver for each of them
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to our device data structure
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
PFN_OEMEnableDriver pfnOEMEnableDriver;
|
|
DRVENABLEDATA ded;
|
|
DWORD dwCount;
|
|
INT iIndex;
|
|
PDRVFN pdrvfn;
|
|
OEMPROC oemproc;
|
|
|
|
//
|
|
// Load OEM plugins into memory
|
|
//
|
|
|
|
pPDev->devobj.pDrvProcs = (PDRVPROCS) &OEMHelperFuncs;
|
|
|
|
if (! (pPDev->pOemPlugins = PGetOemPluginInfo(pPDev->devobj.hPrinter,
|
|
pPDev->pDriverInfo3->pDriverPath,
|
|
pPDev->pDriverInfo3)) ||
|
|
! BLoadOEMPluginModules(pPDev->pOemPlugins))
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
//
|
|
// Init pdriverobj to point to devobj for OEM to access private setting
|
|
//
|
|
|
|
pPDev->pOemPlugins->pdriverobj = &pPDev->devobj;
|
|
|
|
//
|
|
// If there is no OEM plugin, return success
|
|
//
|
|
|
|
if (pPDev->pOemPlugins->dwCount == 0)
|
|
return TRUE;
|
|
|
|
//
|
|
// Call OEM plugin's OEMEnableDriver entrypoint
|
|
// and find out if any of them has hook out DDI entrypoints
|
|
//
|
|
|
|
pPDev->pOemHookInfo = MemAllocZ(sizeof(OEM_HOOK_INFO) * MAX_OEMHOOKS);
|
|
|
|
if (pPDev->pOemHookInfo == NULL)
|
|
return FALSE;
|
|
|
|
START_OEMENTRYPOINT_LOOP(pPDev)
|
|
// this macro defined in oemkm.h in conjunction with its partner END_OEMENTRYPOINT_LOOP,
|
|
// acts like a for() loop initializing and incrementing pOemEntry each pass through the
|
|
// loop.
|
|
|
|
ZeroMemory(&ded, sizeof(ded));
|
|
|
|
//
|
|
// COM Plug-in case
|
|
//
|
|
if (pOemEntry->pIntfOem != NULL)
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = HComOEMEnableDriver(pOemEntry,
|
|
PRINTER_OEMINTF_VERSION,
|
|
sizeof(ded),
|
|
&ded);
|
|
|
|
if (hr == E_NOTIMPL)
|
|
goto UNIDRV_SPECIFIC;
|
|
|
|
if (FAILED(hr))
|
|
{
|
|
ERR(("OEMEnableDriver failed for '%ws': %d\n",
|
|
pOemEntry->ptstrDriverFile,
|
|
GetLastError()));
|
|
|
|
break;
|
|
}
|
|
}
|
|
//
|
|
// Non-COM Plug-in case
|
|
//
|
|
else
|
|
{
|
|
if (!(pfnOEMEnableDriver = GET_OEM_ENTRYPOINT(pOemEntry, OEMEnableDriver)))
|
|
goto UNIDRV_SPECIFIC;
|
|
|
|
//
|
|
// Call OEM plugin's entrypoint
|
|
//
|
|
|
|
if (! pfnOEMEnableDriver(PRINTER_OEMINTF_VERSION, sizeof(ded), &ded))
|
|
{
|
|
ERR(("OEMEnableDriver failed for '%ws': %d\n",
|
|
pOemEntry->ptstrDriverFile,
|
|
GetLastError()));
|
|
|
|
break;
|
|
}
|
|
//
|
|
// Verify the driver version (do this only if not COM)
|
|
//
|
|
|
|
if (ded.iDriverVersion != PRINTER_OEMINTF_VERSION)
|
|
{
|
|
ERR(("Invalid driver version for '%ws': 0x%x\n",
|
|
pOemEntry->ptstrDriverFile,
|
|
ded.iDriverVersion));
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
pOemEntry->dwFlags |= OEMENABLEDRIVER_CALLED;
|
|
|
|
|
|
//
|
|
// Check if OEM plugin has hooked out any DDI entrypoints
|
|
//
|
|
|
|
for (dwCount=ded.c, pdrvfn=ded.pdrvfn; dwCount-- > 0; pdrvfn++)
|
|
{
|
|
if ((iIndex = IMapDDIIndexToOEMIndex(pdrvfn->iFunc)) >= 0)
|
|
{
|
|
if (pPDev->pOemHookInfo[iIndex].pfnHook != NULL)
|
|
{
|
|
WARNING(("Multiple hooks for entrypoint: %d\n"
|
|
" %ws\n"
|
|
" %ws\n",
|
|
iIndex,
|
|
pOemEntry->ptstrDriverFile,
|
|
pPDev->pOemHookInfo[iIndex].pOemEntry->ptstrDriverFile));
|
|
}
|
|
else
|
|
{
|
|
pPDev->pOemHookInfo[iIndex].pfnHook = (OEMPROC) pdrvfn->pfn;
|
|
pPDev->pOemHookInfo[iIndex].pOemEntry = pOemEntry;
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// check if OEM plugin has any Unidrv-specific callbacks exported
|
|
//
|
|
|
|
UNIDRV_SPECIFIC:
|
|
for (dwCount = 0; dwCount < MAX_UNIDRV_ONLY_HOOKS; dwCount++)
|
|
{
|
|
oemproc = NULL;
|
|
|
|
if(pOemEntry->pIntfOem) // is this a COM component, do special processing
|
|
{
|
|
if(S_OK == HComGetImplementedMethod(pOemEntry, COMUnidrvProcNames[dwCount]) )
|
|
oemproc = (OEMPROC)pOemEntry;
|
|
// note oemproc/pfnHook only used as a BOOLEAN in COM path code.
|
|
// do not use pfnHook to call a COM function! we will use
|
|
// ganeshp's wrapper functions (declared in unidrv2\inc\oemkm.h) to do this.
|
|
}
|
|
else if (pOemEntry->hInstance != NULL)
|
|
oemproc = (OEMPROC) GetProcAddress(pOemEntry->hInstance,
|
|
OEMUnidrvProcNames[dwCount]) ;
|
|
|
|
if(oemproc)
|
|
{
|
|
//
|
|
// check if another OEM has already hooked out this function.
|
|
// If so, ignore this one.
|
|
//
|
|
iIndex = dwCount + EP_UNIDRV_ONLY_FIRST;
|
|
if (pPDev->pOemHookInfo[iIndex].pfnHook != NULL)
|
|
{
|
|
WARNING(("Multiple hooks for entrypoint: %d\n"
|
|
" %ws\n"
|
|
" %ws\n",
|
|
iIndex,
|
|
pOemEntry->ptstrDriverFile,
|
|
pPDev->pOemHookInfo[iIndex].pOemEntry->ptstrDriverFile));
|
|
}
|
|
else
|
|
{
|
|
DWORD dwSize;
|
|
HRESULT hr;
|
|
|
|
pPDev->pOemHookInfo[iIndex].pfnHook = oemproc;
|
|
pPDev->pOemHookInfo[iIndex].pOemEntry = pOemEntry;
|
|
|
|
//
|
|
// Set WritePrinter flag (OEMWRITEPRINTER_HOOKED).
|
|
// Plug-in DLL needs to return S_OK with pBuff = NULL, size = 0,
|
|
// and pdevobj = NULL.
|
|
//
|
|
if (iIndex == EP_OEMWritePrinter)
|
|
{
|
|
hr = HComWritePrinter(pOemEntry,
|
|
NULL,
|
|
NULL,
|
|
0,
|
|
&dwSize);
|
|
|
|
if (hr == S_OK)
|
|
{
|
|
//
|
|
// Set WritePrinter hook flag in plug-in info.
|
|
//
|
|
pOemEntry->dwFlags |= OEMWRITEPRINTER_HOOKED;
|
|
|
|
//
|
|
// Set WritePrinter hook flag in UNIDRV PDEV.
|
|
//
|
|
pPDev->fMode2 |= PF2_WRITE_PRINTER_HOOKED;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
END_OEMENTRYPOINT_LOOP
|
|
|
|
//
|
|
// cache callback function ptrs
|
|
//
|
|
pPDev->pfnOemCmdCallback =
|
|
(PFN_OEMCommandCallback)pPDev->pOemHookInfo[EP_OEMCommandCallback].pfnHook;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
VOID
|
|
VUnloadOemPlugins(
|
|
PDEV *pPDev
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Unload OEM plugins and free all relevant resources
|
|
|
|
Arguments:
|
|
|
|
pPDev - Points to our device data structure
|
|
|
|
Return Value:
|
|
|
|
NONE
|
|
|
|
--*/
|
|
|
|
{
|
|
PFN_OEMDisableDriver pfnOEMDisableDriver;
|
|
PFN_OEMDisablePDEV pfnOEMDisablePDEV;
|
|
|
|
if (pPDev->pOemPlugins == NULL)
|
|
return;
|
|
|
|
//
|
|
// Call OEMDisablePDEV for all OEM plugins, if necessary
|
|
//
|
|
|
|
START_OEMENTRYPOINT_LOOP(pPDev)
|
|
|
|
if (pOemEntry->dwFlags & OEMENABLEPDEV_CALLED)
|
|
{
|
|
if (pOemEntry->pIntfOem != NULL)
|
|
{
|
|
(VOID)HComOEMDisablePDEV(pOemEntry, (PDEVOBJ)pPDev);
|
|
}
|
|
else
|
|
{
|
|
if (pfnOEMDisablePDEV = GET_OEM_ENTRYPOINT(pOemEntry, OEMDisablePDEV))
|
|
{
|
|
pfnOEMDisablePDEV((PDEVOBJ) pPDev);
|
|
}
|
|
}
|
|
}
|
|
|
|
END_OEMENTRYPOINT_LOOP
|
|
|
|
//
|
|
// Call OEMDisableDriver for all OEM plugins, if necessary
|
|
//
|
|
|
|
START_OEMENTRYPOINT_LOOP(pPDev)
|
|
|
|
if (pOemEntry->dwFlags & OEMENABLEDRIVER_CALLED)
|
|
{
|
|
if (pOemEntry->pIntfOem != NULL)
|
|
{
|
|
(VOID)HComOEMDisableDriver(pOemEntry);
|
|
}
|
|
else
|
|
{
|
|
if ((pfnOEMDisableDriver = GET_OEM_ENTRYPOINT(pOemEntry, OEMDisableDriver)))
|
|
{
|
|
pfnOEMDisableDriver();
|
|
}
|
|
}
|
|
}
|
|
|
|
END_OEMENTRYPOINT_LOOP
|
|
|
|
MemFree(pPDev->pOemHookInfo);
|
|
pPDev->pOemHookInfo = NULL;
|
|
|
|
VFreeOemPluginInfo(pPDev->pOemPlugins);
|
|
pPDev->pOemPlugins = NULL;
|
|
}
|
|
|
|
|
|
|
|
BOOL
|
|
BGetDriverSettingForOEM(
|
|
PDEV *pPDev,
|
|
PCSTR pFeatureKeyword,
|
|
PVOID pOutput,
|
|
DWORD cbSize,
|
|
PDWORD pcbNeeded,
|
|
PDWORD pdwOptionsReturned
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Provide OEM plugins access to driver private settings
|
|
|
|
Arguments:
|
|
|
|
pDev - Points to our device data structure
|
|
pFeatureKeyword - Specifies the keyword the caller is interested in
|
|
pOutput - Points to output buffer
|
|
cbSize - Size of output buffer
|
|
pcbNeeded - Returns the expected size of output buffer
|
|
pdwOptionsReturned - Returns the number of options selected
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
ULONG_PTR dwIndex;
|
|
BOOL bResult;
|
|
|
|
ASSERT_VALID_PDEV(pPDev);
|
|
|
|
//
|
|
// This is not very portable: If the pointer value for pFeatureKeyword
|
|
// is less than 0x10000, we assume that the pointer value actually
|
|
// specifies a predefined index.
|
|
//
|
|
|
|
// ASSERT(sizeof(pFeatureKeyword) == sizeof(DWORD)); changed for sundown
|
|
|
|
dwIndex = (ULONG_PTR) pFeatureKeyword;
|
|
|
|
if (dwIndex >= OEMGDS_MIN_DOCSTICKY && dwIndex < OEMGDS_MIN_PRINTERSTICKY)
|
|
{
|
|
bResult = BGetDevmodeSettingForOEM(
|
|
pPDev->pdm,
|
|
(DWORD)dwIndex,
|
|
pOutput,
|
|
cbSize,
|
|
pcbNeeded);
|
|
|
|
if (bResult)
|
|
*pdwOptionsReturned = 1;
|
|
}
|
|
else if (dwIndex >= OEMGDS_MIN_PRINTERSTICKY && dwIndex < OEMGDS_MAX)
|
|
{
|
|
bResult = BGetPrinterDataSettingForOEM(
|
|
&pPDev->PrinterData,
|
|
(DWORD)dwIndex,
|
|
pOutput,
|
|
cbSize,
|
|
pcbNeeded);
|
|
|
|
if (bResult)
|
|
*pdwOptionsReturned = 1;
|
|
}
|
|
else
|
|
{
|
|
bResult = BGetGenericOptionSettingForOEM(
|
|
pPDev->pUIInfo,
|
|
pPDev->pOptionsArray,
|
|
pFeatureKeyword,
|
|
pOutput,
|
|
cbSize,
|
|
pcbNeeded,
|
|
pdwOptionsReturned);
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
BOOL
|
|
BGetStandardVariable(
|
|
PDEV *pPDev,
|
|
DWORD dwIndex,
|
|
PVOID pBuffer,
|
|
DWORD cbSize,
|
|
PDWORD pcbNeeded
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Provide OEM plugins access to driver private settings
|
|
|
|
Arguments:
|
|
|
|
pDev - Points to our device data structure
|
|
dwIndex - an index into the arStdPtr array defined in pdev.h and gpd.h
|
|
pBuffer - the data is returned in this buffer
|
|
cbSize - size of the pBuffer
|
|
pcbNeeded - number of bytes actually written into pBuffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL bResult = FALSE;
|
|
DWORD dwData;
|
|
|
|
if (dwIndex >= SVI_MAX) // how could a DWORD be < 0?
|
|
{
|
|
ERR(("Index must be >= 0 or < SVI_MAX \n"));
|
|
return( FALSE);
|
|
}
|
|
else
|
|
{
|
|
if(!pcbNeeded)
|
|
{
|
|
ERR(("pcbNeeded must not be NULL \n"));
|
|
return( FALSE);
|
|
}
|
|
*pcbNeeded = sizeof(dwData);
|
|
if(!pBuffer)
|
|
return(TRUE);
|
|
if(*pcbNeeded > cbSize)
|
|
return(FALSE);
|
|
|
|
dwData = *(pPDev->arStdPtrs[dwIndex]);
|
|
memcpy( pBuffer, &dwData, *pcbNeeded );
|
|
bResult = TRUE;
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL
|
|
BGetGPDData(
|
|
PDEV *pPDev,
|
|
DWORD dwType, // Type of the data
|
|
PVOID pInputData, // reserved. Should be set to 0
|
|
PVOID pBuffer, // Caller allocated Buffer to be copied
|
|
DWORD cbSize, // Size of the buffer
|
|
PDWORD pcbNeeded // New Size of the buffer if needed.
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Provide OEM plugins access to GPD data.
|
|
|
|
Arguments:
|
|
|
|
pDev - Points to our device data structure
|
|
dwType, // Type of the data
|
|
at this time
|
|
#define GPD_OEMCUSTOMDATA 1
|
|
pInputData will be ignored.
|
|
|
|
In NT6, we will
|
|
#define GPD_OEMDATA 2
|
|
at which time the caller will supply pInputData
|
|
which points to a data specifier , catagory or label.
|
|
(Specifics to be determined when we get there.)
|
|
|
|
|
|
pInputData - reserved. Should be set to 0
|
|
pBuffer - the data is returned in this buffer
|
|
cbSize - size of the pBuffer
|
|
pcbNeeded - number of bytes actually written into pBuffer
|
|
|
|
Return Value:
|
|
|
|
TRUE if successful, FALSE if there is an error or dwType not
|
|
supported
|
|
|
|
--*/
|
|
|
|
{
|
|
BOOL bResult = FALSE;
|
|
DWORD dwData;
|
|
|
|
if(!pcbNeeded)
|
|
{
|
|
ERR(("pcbNeeded must not be NULL \n"));
|
|
return( FALSE);
|
|
}
|
|
switch(dwType)
|
|
{
|
|
case GPD_OEMCUSTOMDATA:
|
|
*pcbNeeded = pPDev->pGlobals->dwOEMCustomData ;
|
|
|
|
if( !pBuffer)
|
|
{
|
|
return TRUE; // all goes well.
|
|
}
|
|
|
|
if(*pcbNeeded > cbSize)
|
|
return FALSE ; // caller supplied buffer too small.
|
|
|
|
CopyMemory(pBuffer,
|
|
pPDev->pGlobals->pOEMCustomData,
|
|
*pcbNeeded);
|
|
|
|
|
|
return TRUE; // all goes well.
|
|
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return bResult ;
|
|
}
|
|
|
|
|
|
#ifdef WINNT_40
|
|
|
|
|
|
PVOID
|
|
DrvMemAllocZ(
|
|
ULONG ulSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
return(MemAllocZ(ulSize));
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
DrvMemFree(
|
|
PVOID pMem
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
MemFree(pMem);
|
|
}
|
|
|
|
|
|
LONG
|
|
DrvInterlockedIncrement(
|
|
PLONG pRef
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
|
|
ENTER_CRITICAL_SECTION();
|
|
|
|
++(*pRef);
|
|
|
|
LEAVE_CRITICAL_SECTION();
|
|
|
|
|
|
return (*pRef);
|
|
|
|
}
|
|
|
|
|
|
LONG
|
|
DrvInterlockedDecrement(
|
|
PLONG pRef
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
Return Value:
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
ENTER_CRITICAL_SECTION();
|
|
|
|
--(*pRef);
|
|
|
|
LEAVE_CRITICAL_SECTION();
|
|
|
|
return (*pRef);
|
|
|
|
}
|
|
|
|
|
|
BOOL
|
|
BHandleOEMInitialize(
|
|
POEM_PLUGIN_ENTRY pOemEntry,
|
|
ULONG ulReason
|
|
)
|
|
|
|
/*++
|
|
|
|
Routine Description:
|
|
|
|
Manage reference counting for OEM render plugin DLLs to determine
|
|
when plugin's DLLInitliaze() should be called.
|
|
|
|
This function is supported only for NT4 kernel mode render plugin
|
|
DLLs because only in that situation plugin needs to use kernel
|
|
semaphore to implement COM's AddRef and Release.
|
|
|
|
If the plugin DLL is loaded for the first time, call its
|
|
DLLInitialize(DLL_PROCESS_ATTACH) so it can initialize its
|
|
semaphore.
|
|
|
|
If the plugin DLL is unloaded by its last client, call its
|
|
DLLInitialize(DLL_PROCESS_DETACH) so it can delete its
|
|
semaphore.
|
|
|
|
Arguments:
|
|
|
|
pOemEntry - Points to information about the OEM plugin
|
|
ulReason - either DLL_PROCESS_ATTACH or DLL_PROCESS_DETACH
|
|
|
|
Return Value:
|
|
|
|
TRUE is succeeded, FALSE otherwise.
|
|
|
|
--*/
|
|
|
|
{
|
|
LPFNDLLINITIALIZE pfnDllInitialize;
|
|
BOOL bCallDllInitialize;
|
|
BOOL bRetVal = TRUE;
|
|
|
|
if (pOemEntry->hInstance &&
|
|
(pfnDllInitialize = (LPFNDLLINITIALIZE)GetProcAddress(
|
|
(HMODULE) pOemEntry->hInstance,
|
|
(CHAR *) szDllInitialize)))
|
|
{
|
|
switch (ulReason) {
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
|
|
ENTER_CRITICAL_SECTION();
|
|
|
|
//
|
|
// Managing the global ref count link list must be done
|
|
// inside critical section.
|
|
//
|
|
|
|
bCallDllInitialize = BOEMPluginFirstLoad(pOemEntry->ptstrDriverFile,
|
|
&gpOEMPluginRefCount);
|
|
|
|
LEAVE_CRITICAL_SECTION();
|
|
|
|
if (bCallDllInitialize)
|
|
{
|
|
//
|
|
// The render plugin DLL is loaded for the first time.
|
|
//
|
|
|
|
bRetVal = pfnDllInitialize(ulReason);
|
|
}
|
|
|
|
break;
|
|
|
|
case DLL_PROCESS_DETACH:
|
|
|
|
ENTER_CRITICAL_SECTION();
|
|
|
|
//
|
|
// Managing the global ref count link list must be done
|
|
// inside critical section.
|
|
//
|
|
|
|
bCallDllInitialize = BOEMPluginLastUnload(pOemEntry->ptstrDriverFile,
|
|
&gpOEMPluginRefCount);
|
|
|
|
LEAVE_CRITICAL_SECTION();
|
|
|
|
if (bCallDllInitialize)
|
|
{
|
|
//
|
|
// The render plugin DLL is unloaded by its last client.
|
|
//
|
|
|
|
bRetVal = pfnDllInitialize(ulReason);
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
ERR(("BHandleOEMInitialize is called with an unknown ulReason.\n"));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return bRetVal;
|
|
}
|
|
|
|
#endif // WINNT_40
|