生成基本的 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 打印机驱动程序
如有侵权联系删除 仅供学习交流使用