生成基本的 v4 打印机驱动程序-dllentry.cpp
- dllentry.cpp
//
// File Name:
//
// dllentry.cpp
//
// Abstract:
//
// XPS Rendering Filter DLL entry points.
//
#include "precomp.h"
#include "WppTrace.h"
#include "CustomWppCommands.h"
#include "Exception.h"
#include "filtertypes.h"
#include "UnknownBase.h"
#include "RenderFilter.h"
#include "dllentry.tmh"
namespace MyV4PrintDriver_Render_Filter
{
//
// Class Factory returned by DllGetClassObject()
//
class __declspec(uuid("ccf3dccf-b589-48b9-ab27-fd463caf8855")) RenderFilterFactory : public UnknownBase<IClassFactory>
{
public:
RenderFilterFactory() :
m_serverLocks(0)
{
::InterlockedIncrement(&RenderFilter::ms_numObjects);
}
~RenderFilterFactory()
{
::InterlockedDecrement(&RenderFilter::ms_numObjects);
}
//
//Routine Name:
//
// RenderFilterFactory::CreateInstance
//
//Routine Description:
//
// Returns an instance of RenderFilter.
//
//Arguments:
//
// pUnkOuter - Outer class (must be NULL)
// riid - Requested interface (IPrintPipelineFilter)
// ppvObject - Pointer to the requested interface
//
//Return Value:
//
// HRESULT
// S_OK - On success
// Otherwise - Failure
//
HRESULT
STDMETHODCALLTYPE
CreateInstance(
IUnknown *pUnkOuter,
REFIID riid,
void **ppvObject
)
{
HRESULT hr = S_OK;
if (pUnkOuter != NULL)
{
WPP_LOG_ON_FAILED_HRESULT(CLASS_E_NOAGGREGATION);
return CLASS_E_NOAGGREGATION;
}
if (ppvObject == NULL)
{
WPP_LOG_ON_FAILED_HRESULT(E_POINTER);
return E_POINTER;
}
*ppvObject = NULL;
MyV4PrintDriver_Render_Filter::RenderFilter *pFilter = NULL;
//
// RenderFilter::RenderFilter() can throw, as can new
//
try
{
DoTraceMessage(RENDERFILTER_TRACE_INFO, L"Instantiating filter");
pFilter = new MyV4PrintDriver_Render_Filter::RenderFilter();
}
CATCH_VARIOUS(hr)
if (SUCCEEDED(hr))
{
WPP_LOG_ON_FAILED_HRESULT(
hr = pFilter->QueryInterface(riid, ppvObject)
);
pFilter->Release();
}
return hr;
}
//
//Routine Name:
//
// RenderFilterFactory::LockServer
//
//Routine Description:
//
// Allows clients to lock the filter factory in
// memory.
//
//Arguments:
//
// fLock - TRUE - lock; FALSE - unlock
//
//Return Value:
//
// HRESULT
// S_OK - On success
//
HRESULT
STDMETHODCALLTYPE
LockServer(
BOOL fLock
)
{
LONG result;
if (fLock) // lock
{
result = ::InterlockedIncrement(&m_serverLocks);
if (result == 1)
{
//
// This was the first 'lock' call; increment the
// global numObjects
//
::InterlockedIncrement(&RenderFilter::ms_numObjects);
}
}
else // unlock
{
result = ::InterlockedDecrement(&m_serverLocks);
if (result == 0)
{
//
// All locks have been unlocked; decrement the
// global numObjects
//
::InterlockedDecrement(&RenderFilter::ms_numObjects);
}
}
return S_OK;
}
private:
volatile LONG m_serverLocks;
};
} // namespace MyV4PrintDriver_Render_Filter
//
//Routine Name:
//
// DllGetClassObject
//
//Routine Description:
//
// Returns an instance of RenderFilterFactory.
//
//Arguments:
//
// rclsid - Requested class (RenderFilter)
// riid - Requested interface (IClassFactory)
// ppv - Pointer to the requested interface
//
//Return Value:
//
// HRESULT
// S_OK - On success
// Otherwise - Failure
//
STDAPI
DllGetClassObject(
_In_ REFCLSID rclsid,
_In_ REFIID riid,
_Outptr_ LPVOID *ppv
)
{
HRESULT hr = S_OK;
if (ppv == NULL)
{
WPP_LOG_ON_FAILED_HRESULT(E_POINTER);
return E_POINTER;
}
*ppv = NULL;
if (rclsid != __uuidof(MyV4PrintDriver_Render_Filter::RenderFilterFactory))
{
WPP_LOG_ON_FAILED_HRESULT(CLASS_E_CLASSNOTAVAILABLE);
return CLASS_E_CLASSNOTAVAILABLE;
}
DoTraceMessage(RENDERFILTER_TRACE_INFO, L"Instantiating class factory");
MyV4PrintDriver_Render_Filter::RenderFilterFactory *pFactory = NULL;
pFactory = new(std::nothrow) MyV4PrintDriver_Render_Filter::RenderFilterFactory();
if (pFactory == NULL)
{
WPP_LOG_ON_FAILED_HRESULT(E_OUTOFMEMORY);
hr = E_OUTOFMEMORY;
}
if (SUCCEEDED(hr))
{
WPP_LOG_ON_FAILED_HRESULT(
hr = pFactory->QueryInterface(riid, ppv)
);
pFactory->Release();
}
return hr;
}
//
//Routine Name:
//
// DllCanUnloadNow
//
//Routine Description:
//
// Checks whether the DLL can be unloaded. That is,
// whether there are any instances of RenderFilter.
//
//Arguments:
//
// None
//
//Return Value:
//
// HRESULT
// S_OK - Can unload.
// Otherwise - Cannot unload.
//
STDAPI
DllCanUnloadNow()
{
return (0 == MyV4PrintDriver_Render_Filter::RenderFilter::ms_numObjects) ? S_OK : S_FALSE;
}
//
//Routine Name:
//
// DllMain
//
//Routine Description:
//
// Initializes WPP tracing when the DLL is loaded
// and cleans up WPP tracing when the DLL is unloaded.
//
//Arguments:
//
// None
//
//Return Value:
//
// HRESULT
// S_OK - On success.
// Otherwise - Otherwise.
//
extern "C"
BOOL
WINAPI
DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_opt_ LPVOID /*lpvReserved*/
)
{
switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
::DisableThreadLibraryCalls(hinstDLL);
WPP_INIT_TRACING(L"MyV4PrintDriverRenderFilter");
DoTraceMessage(RENDERFILTER_TRACE_INFO, L"DLL_PROCESS_ATTACH");
break;
case DLL_PROCESS_DETACH:
DoTraceMessage(RENDERFILTER_TRACE_INFO, L"DLL_PROCESS_DETACH");
WPP_CLEANUP();
break;
}
return TRUE;
}
- 文件定位
这是渲染过滤器DLL的入口文件。XPS渲染过滤器是V4打印机驱动中用于拦截和处理打印管道中XPS数据流的模块。 - 引用的头文件
WppTrace/CustomWppCommands:用于日志和错误追踪(WPP tracing)。
Exception/filtertypes/UnknownBase:异常处理、接口类型定义、COM 基类。
RenderFilter.h:渲染过滤器类,核心逻辑实现。
dllentry.tmh:WPP tracing 自动生成的文件。 - RenderFilterFactory类
class __declspec(uuid("ccf3dccf-b589-48b9-ab27-fd463caf8855")) RenderFilterFactory : public UnknownBase<IClassFactory>
这是一个COM类工厂(Class Factory),用于创建RenderFilter对象。
它继承自UnknownBase<IClassFactory>,提供IUnknown和IClassFactory接口的实现。
构造 & 析构
RenderFilterFactory() :
m_serverLocks(0)
{
::InterlockedIncrement(&RenderFilter::ms_numObjects);
}
~RenderFilterFactory()
{
::InterlockedDecrement(&RenderFilter::ms_numObjects);
}
使用InterlockedIncrement/Decrement操作全局静态变量RenderFilter::ms_numObjects,维护当前活动对象的计数。
CreateInstance
HRESULT
STDMETHODCALLTYPE
CreateInstance(
IUnknown *pUnkOuter,
REFIID riid,
void **ppvObject
)
检查聚合:如果pUnkOuter != NULL,返回CLASS_E_NOAGGREGATION(不支持聚合)。
检查参数:如果ppvObject == NULL,返回E_POINTER。
创建对象:pFilter = new RenderFilter();可能抛异常,所以用try / CATCH_VARIOUS保护。
返回接口:调用QueryInterface获取所需的接口指针。
释放引用:工厂持有的引用释放,交给调用方。
LockServer
HRESULT
STDMETHODCALLTYPE
LockServer(
BOOL fLock
)
允许客户端锁定工厂驻留在内存中。
fLock = TRUE→ 增加锁计数并增加ms_numObjects。
fLock = FALSE→ 减少锁计数,并在最后一个锁释放时减少ms_numObjects。
返回S_OK。
- DllGetClassObject
STDAPI
DllGetClassObject(
_In_ REFCLSID rclsid,
_In_ REFIID riid,
_Outptr_ LPVOID *ppv
)
检查参数:ppv == NULL→E_POINTER。
检查 CLSID:如果不是RenderFilterFactory的CLSID→CLASS_E_CLASSNOTAVAILABLE。
创建工厂对象:new RenderFilterFactory()。
查询接口:通过QueryInterface返回IClassFactory指针。
释放工厂引用:保持COM引用计数语义。
这是标准COM DLL必须导出的函数之一,提供类工厂。
- DllCanUnloadNow
STDAPI
DllCanUnloadNow()
{
return (0 == MyV4PrintDriver_Render_Filter::RenderFilter::ms_numObjects) ? S_OK : S_FALSE;
}
如果没有活动对象(ms_numObjects == 0),返回S_OK,DLL可以卸载。
否则返回S_FALSE,表示仍有对象在使用。
- DllMain
extern "C"
BOOL
WINAPI
DllMain(
_In_ HINSTANCE hinstDLL,
_In_ DWORD fdwReason,
_In_opt_ LPVOID /*lpvReserved*/
)
DLL_PROCESS_ATTACH:
禁用线程通知(DisableThreadLibraryCalls)。
初始化WPP tracing(WPP_INIT_TRACING)。
打日志:DLL_PROCESS_ATTACH。
DLL_PROCESS_DETACH:
打日志:DLL_PROCESS_DETACH。
清理WPP tracing(WPP_CLEANUP)。
返回TRUE。
这是DLL的入口点,负责初始化/清理日志系统
- 总结
这段程序实现了一个XPS渲染过滤器DLL的COM入口模块,主要功能:
RenderFilterFactory提供IClassFactory,用于生成RenderFilter对象。
DllGetClassObject导出工厂接口。
DllCanUnloadNow检查是否可以安全卸载DLL。
DllMain管理DLL生命周期,初始化/清理WPP tracing。
作用:
确保驱动中的渲染过滤器作为 COM 组件被系统正确加载、实例化、释放。
提供调试和错误日志功能,方便诊断问题。
管理全局对象数量,确保 DLL 不会过早卸载。
原始资料地址:
生成基本的 v4 打印机驱动程序
如有侵权联系删除 仅供学习交流使用