|
|
/*++
Copyright (c) 1996-1998 Microsoft Corporation
Module Name:
comoem.cpp
Abstract:
Necessary COM class definition to Unidrv OEM rendering module plug-in.
Environment:
Windows NT Unidrv driver
Revision History:
98/4/24 takashim: Written the original sample so that it is more C++.
98/9/3 v-yutah: Because of suggestion from ganeshp, Modified PublishDriverInterface(), and related to it, Modified EnableDriver(), DisableDriver() 03/11/02 v-satois For security issues, addition null-checking of pointer.
--*/
// NTRAID#NTBUG9-588572-2002/03/28-v-sueyas-: Correct the return values for each COM I/F methods
#define INITGUID // for GUID one-time initialization
#include "pdev.h"
#include "names.h"
// Globals
static HMODULE g_hModule = NULL ; // DLL module handle
static long g_cComponents = 0 ; // Count of active components
static long g_cServerLocks = 0 ; // Count of locks
//
// IOemCB Definition
//
class IOemCB : public IPrintOemUni { public:
//
// IUnknown methods
//
STDMETHODIMP QueryInterface( const IID& iid, void** ppv) { VERBOSE((DLLTEXT("IOemCB: QueryInterface entry\n"))); if (ppv == NULL) // Checking null-pointer.
{ return E_NOINTERFACE; } if (iid == IID_IUnknown) { *ppv = static_cast<IUnknown*>(this); VERBOSE((DLLTEXT("IOemCB:Return pointer to IUnknown.\n"))); } else if (iid == IID_IPrintOemUni) { *ppv = static_cast<IPrintOemUni*>(this); VERBOSE((DLLTEXT("IOemCB:Return pointer to IPrintOemUni.\n"))); } else { *ppv = NULL ; VERBOSE((DLLTEXT("IOemCB:Return NULL.\n"))); return E_NOINTERFACE ; } reinterpret_cast<IUnknown*>(*ppv)->AddRef(); return S_OK ; }
STDMETHODIMP_(ULONG) AddRef() { VERBOSE((DLLTEXT("IOemCB::AddRef() entry.\n"))); return InterlockedIncrement(&m_cRef); }
STDMETHODIMP_(ULONG) Release() { VERBOSE((DLLTEXT("IOemCB::Release() entry.\n"))); if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; }
//
// IPrintOemCommon methods
//
// Function Name: GetInfo
// Plug-in: Any
// Driver: Any
// Type: Mandatory
//
STDMETHODIMP GetInfo( DWORD dwMode, PVOID pBuffer, DWORD cbSize, PDWORD pcbNeeded) { VERBOSE((DLLTEXT("IOemCB::GetInfo() entry.\n"))); if (OEMGetInfo(dwMode, pBuffer, cbSize, pcbNeeded)) return S_OK; else return E_FAIL; }
//
// Function Name: DevMode
// Plug-in: Rendering module
// Driver: Any
// Type: Optional
//
STDMETHODIMP DevMode( DWORD dwMode, POEMDMPARAM pOemDMParam) { VERBOSE((DLLTEXT("IOemCB::DevMode() entry.\n"))); return E_NOTIMPL; }
//
// IPrintOemEngine methods
//
//
// Function Name: EnableDriver
// Plug-in: Rendering module
// Driver: Any
// Type: Optional
//
STDMETHODIMP EnableDriver( DWORD dwDriverVersion, DWORD cbSize, PDRVENABLEDATA pded) { VERBOSE((DLLTEXT("IOemCB::EnableDriver() entry.\n"))); #if 1 // Suggested by ganeshp
// Need to return S_OK so that DisableDriver() will be called, which Releases
// the reference to the Printer Driver's interface.
return S_OK; #else // Suggested by ganeshp
return E_NOTIMPL; #endif // Suggested by ganeshp
}
//
// Function Name: DisableDriver
// Plug-in: Rendering module
// Driver: Any
// Type: Optional
//
STDMETHODIMP DisableDriver(VOID) { VERBOSE((DLLTEXT("IOemCB::DisaleDriver() entry.\n"))); #if 1 // Suggested by ganeshp
// Release reference to Printer Driver's interface.
if (this->pOEMHelp) { this->pOEMHelp->Release(); this->pOEMHelp = NULL; } return S_OK; #else // Suggested by ganeshp
return E_NOTIMPL; #endif // Suggested by ganeshp
}
//
// Function Name: EnablePDEV
// Plug-in: Rendering module
// Driver: Any
// Type: Optional
//
STDMETHODIMP EnablePDEV( PDEVOBJ pdevobj, PWSTR pPrinterName, ULONG cPatterns, HSURF *phsurfPatterns, ULONG cjGdiInfo, GDIINFO *pGdiInfo, ULONG cjDevInfo, DEVINFO *pDevInfo, DRVENABLEDATA *pded, OUT PDEVOEM *pDevOem) { PDEVOEM pTemp;
VERBOSE((DLLTEXT("IOemCB::EnablePDEV() entry.\n")));
if (pDevOem == NULL) // Checking null-pointer.
{ return E_FAIL; }
if ((pTemp = OEMEnablePDEV(pdevobj, pPrinterName, cPatterns, phsurfPatterns, cjGdiInfo, pGdiInfo, cjDevInfo, pDevInfo, pded))) { *pDevOem = pTemp; return S_OK; } return E_FAIL; }
//
// Function Name: DisablePDEV
// Plug-in: Rendering module
// Driver: Any
// Type: Optional
//
STDMETHODIMP DisablePDEV( PDEVOBJ pdevobj) { VERBOSE((DLLTEXT("IOemCB::DisablePDEV() entry.\n")));
OEMDisablePDEV(pdevobj); return S_OK; }
//
// Function Name: ResetPDEV
// Plug-in: Rendering module
// Driver: Any
// Type: Optional
//
STDMETHODIMP ResetPDEV( PDEVOBJ pdevobjOld, PDEVOBJ pdevobjNew) { // VERBOSE((DLLTEXT("IOemCB::ResetPDEV() entry.\n")));
if (OEMResetPDEV(pdevobjOld, pdevobjNew)) return S_OK; else return E_FAIL; }
//
// IPrintOemUni methods
//
//
// Function Name: PublishDriverInterface
// Plug-in: Rendering module
// Driver: Any
// Type: Mandatory
//
STDMETHODIMP PublishDriverInterface( IUnknown *pIUnknown) { VERBOSE((DLLTEXT("IOemCB::PublishDriverInterface() entry.\n"))); #if 1 // Suggested by ganeshp
// Need to store pointer to Driver Helper functions, if we already haven't.
if (this->pOEMHelp == NULL) { HRESULT hResult; // Get Interface to Helper Functions.
if (pIUnknown == NULL) // Checking null-pointer.
{ return E_FAIL; } hResult = pIUnknown->QueryInterface(IID_IPrintOemDriverUni, (void** ) &(this->pOEMHelp)); if(!SUCCEEDED(hResult)) { // Make sure that interface pointer reflects interface query failure.
this->pOEMHelp = NULL; return E_FAIL; } } return S_OK; #else // Suggested by ganeshp
if (this->pOEMHelp == NULL) { if (pIUnknown == NULL) // Checking null-pointer.
{ return E_FAIL; } pIUnknown->AddRef(); } this->pOEMHelp = reinterpret_cast<IPrintOemDriverUni*>(pIUnknown); return S_OK; #endif // Suggested by ganeshp
}
//
// Function Name: GetImplementationMethod
// Plug-in: Rendering module
// Driver: Any
// Type: Mandatory
//
//
// Needed to be static so that it can be passed
// to the bsearch() as a pointer to a functin.
//
static int __cdecl iCompNames( const void *p1, const void *p2) {
return strcmp( *((char **)p1), *((char **)p2)); }
STDMETHODIMP GetImplementedMethod( PSTR pMethodName) { LONG lRet = E_NOTIMPL; PSTR pTemp;
VERBOSE((DLLTEXT("IOemCB::GetImplementedMethod() entry.\n")));
if (NULL != pMethodName) {
pTemp = (PSTR)bsearch( &pMethodName, gMethodsSupported, (sizeof (gMethodsSupported) / sizeof (PSTR)), sizeof (PSTR), iCompNames);
if (NULL != pTemp) lRet = S_OK; }
VERBOSE((DLLTEXT("pMethodName = %s, lRet = %d\n"), pMethodName, lRet));
return lRet; }
//
// Function Name: CommandCallback
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP CommandCallback( PDEVOBJ pdevobj, DWORD dwCallbackID, DWORD dwCount, PDWORD pdwParams, OUT INT *piResult) { INT retv;
VERBOSE((DLLTEXT("IOemCB::CommandCallback() entry.\n")));
if (piResult == NULL) // Checking null-pointer.
{ return E_FAIL; }
// Checking the return value.
retv = OEMCommandCallback(pdevobj, dwCallbackID, dwCount, pdwParams); if (retv < 0) { *piResult = 0; return E_FAIL; } else { *piResult = retv; }
return S_OK; }
//
// Function Name: ImageProcessing
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP ImageProcessing( PDEVOBJ pdevobj, PBYTE pSrcBitmap, PBITMAPINFOHEADER pBitmapInfoHeader, PBYTE pColorTable, DWORD dwCallbackID, PIPPARAMS pIPParams, OUT PBYTE *ppbResult) { VERBOSE((DLLTEXT("IOemCB::ImageProcessing() entry.\n"))); return E_NOTIMPL; }
//
// Function Name: FilterGraphics
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP FilterGraphics( PDEVOBJ pdevobj, PBYTE pBuf, DWORD dwLen) { VERBOSE((DLLTEXT("IOemCB::FilterGraphis() entry.\n"))); return E_NOTIMPL; }
//
// Function Name: Compression
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP Compression( PDEVOBJ pdevobj, PBYTE pInBuf, PBYTE pOutBuf, DWORD dwInLen, DWORD dwOutLen, OUT INT *piResult) { VERBOSE((DLLTEXT("IOemCB::Compression() entry.\n"))); return E_NOTIMPL; }
//
// Function Name: HalftonePattern
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP HalftonePattern( PDEVOBJ pdevobj, PBYTE pHTPattern, DWORD dwHTPatternX, DWORD dwHTPatternY, DWORD dwHTNumPatterns, DWORD dwCallbackID, PBYTE pResource, DWORD dwResourceSize) { VERBOSE((DLLTEXT("IOemCB::HalftonePattern() entry.\n"))); return E_NOTIMPL; }
//
// Function Name: MemoryUsge
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP MemoryUsage( PDEVOBJ pdevobj, POEMMEMORYUSAGE pMemoryUsage) { VERBOSE((DLLTEXT("IOemCB::MemoryUsage() entry.\n"))); return E_NOTIMPL; }
//
// Function Name: DownloadFontHeader
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP DownloadFontHeader( PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, OUT DWORD *pdwResult) { VERBOSE((DLLTEXT("IOemCB::DownloadFontHeader() entry.\n")));
#ifdef DOWNLOADFONT
if (pdwResult == NULL) // Checking null-pointer.
{ return E_FAIL; } if (0 < (*pdwResult = OEMDownloadFontHeader(pdevobj, pUFObj))) { return S_OK; } else { return E_FAIL; } #else // DOWNLOADFONT
return E_NOTIMPL; #endif // DOWNLOADFONT
}
//
// Function Name: DownloadCharGlyph
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP DownloadCharGlyph( PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, HGLYPH hGlyph, PDWORD pdwWidth, OUT DWORD *pdwResult) { VERBOSE((DLLTEXT("IOemCB::DownloadCharGlyph() entry.\n")));
#ifdef DOWNLOADFONT
if (pdwResult == NULL) // Checking null-pointer.
{ return E_FAIL; }
if (0 < (*pdwResult = OEMDownloadCharGlyph(pdevobj, pUFObj, hGlyph, pdwWidth))) { return S_OK; } else { return E_FAIL; } #else // DOWNLOADFONT
return E_NOTIMPL; #endif // DOWNLOADFONT
}
//
// Function Name: TTDonwloadMethod
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP TTDownloadMethod( PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, OUT DWORD *pdwResult) { VERBOSE((DLLTEXT("IOemCB::TTDownloadMethod() entry.\n"))); #ifdef DOWNLOADFONT
if (pdwResult == NULL) // Checking null-pointer.
{ return E_FAIL; }
*pdwResult = OEMTTDownloadMethod(pdevobj, pUFObj); return S_OK; #else // DOWNLOADFONT
return E_NOTIMPL; #endif // DOWNLOADFONT
}
//
// Function Name: OutputCharStr
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP OutputCharStr( PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, DWORD dwType, DWORD dwCount, PVOID pGlyph) { VERBOSE((DLLTEXT("IOemCB::OutputCharStr() entry.\n")));
OEMOutputCharStr(pdevobj, pUFObj, dwType, dwCount, pGlyph); return S_OK; }
//
// Function Name: SendFontCmd
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP SendFontCmd( PDEVOBJ pdevobj, PUNIFONTOBJ pUFObj, PFINVOCATION pFInv) { VERBOSE((DLLTEXT("IOemCB::SendFontCmd() entry.\n")));
OEMSendFontCmd(pdevobj, pUFObj, pFInv); return S_OK; }
//
// Function Name: DriverDMS
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP DriverDMS( PVOID pDevObj, PVOID pBuffer, DWORD cbSize, PDWORD pcbNeeded) { VERBOSE((DLLTEXT("IOemCB::DriverDMS() entry.\n"))); return E_NOTIMPL; }
//
// Function Name: TextOutputAsBitmap
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP TextOutAsBitmap( SURFOBJ *pso, STROBJ *pstro, FONTOBJ *pfo, CLIPOBJ *pco, RECTL *prclExtra, RECTL *prclOpaque, BRUSHOBJ *pboFore, BRUSHOBJ *pboOpaque, POINTL *pptlOrg, MIX mix) { VERBOSE((DLLTEXT("IOemCB::TextOutAsBitmap() entry.\n"))); return E_NOTIMPL; }
//
// Function Name: TTYGetInfo
// Plug-in: Rendering module
// Driver: Unidrv
// Type: Optional
//
STDMETHODIMP TTYGetInfo( PDEVOBJ pdevobj, DWORD dwInfoIndex, PVOID pOutputBuf, DWORD dwSize, DWORD *pcbcNeeded) { VERBOSE((DLLTEXT("IOemCB::TTYGetInfo() entry.\n"))); return E_NOTIMPL; }
//
// Constructors
//
IOemCB() { m_cRef = 1; pOEMHelp = NULL; }; ~IOemCB() { };
protected: IPrintOemDriverUni* pOEMHelp; LONG m_cRef; };
//
// Class factory definition
//
class IOemCF : public IClassFactory { public: //
// IUnknown methods
//
STDMETHODIMP QueryInterface(const IID& iid, void** ppv) { if (ppv == NULL) // Checking null-pointer.
{ return E_NOINTERFACE; }
if ((iid == IID_IUnknown) || (iid == IID_IClassFactory)) { *ppv = static_cast<IOemCF*>(this); } else { *ppv = NULL ; return E_NOINTERFACE ; } reinterpret_cast<IUnknown*>(*ppv)->AddRef(); return S_OK ; }
STDMETHODIMP_(ULONG) AddRef() { return InterlockedIncrement(&m_cRef); }
STDMETHODIMP_(ULONG) Release() { if (InterlockedDecrement(&m_cRef) == 0) { delete this ; return 0 ; } return m_cRef ; }
//
// IClassFactory methods
//
STDMETHODIMP CreateInstance( IUnknown *pUnknownOuter, const IID &iid, void **ppv) { //VERBOSE((DLLTEXT("IOemCF::CreateInstance() called\n.")));
// Cannot aggregate.
if (NULL != pUnknownOuter) {
return CLASS_E_NOAGGREGATION; }
// Create component.
IOemCB* pOemCB = new IOemCB; if (NULL == pOemCB) {
return E_OUTOFMEMORY; }
// Get the requested interface.
HRESULT hr = pOemCB->QueryInterface(iid, ppv);
// Release the IUnknown pointer.
// (If QueryInterface failed, component will delete itself.)
pOemCB->Release(); return hr ; }
// LockServer
STDMETHODIMP LockServer(BOOL bLock) { if (bLock) { InterlockedIncrement(&g_cServerLocks); } else { InterlockedDecrement(&g_cServerLocks); } return S_OK ; }
//
// Constructor
//
IOemCF(): m_cRef(1) { }; ~IOemCF() { };
protected: LONG m_cRef; };
//
// Export functions
//
//
// Get class factory
//
STDAPI DllGetClassObject( const CLSID &clsid, const IID &iid, void **ppv) { //VERBOSE((DLLTEXT("DllGetClassObject:\tCreate class factory.")));
// Can we create this component?
if (clsid != CLSID_OEMRENDER) { return CLASS_E_CLASSNOTAVAILABLE ; }
// Create class factory.
IOemCF* pFontCF = new IOemCF ; // Reference count set to 1
// in constructor
if (pFontCF == NULL) { return E_OUTOFMEMORY ; }
// Get requested interface.
HRESULT hr = pFontCF->QueryInterface(iid, ppv); pFontCF->Release();
return hr ; }
//
//
// Can DLL unload now?
//
STDAPI DllCanUnloadNow() { if ((g_cComponents == 0) && (g_cServerLocks == 0)) { return S_OK; } else { return S_FALSE; } }
|