基于HOOK 和 状态轮询的 打印机监控,内容抓取

本文介绍了如何结合HOOK技术和状态轮询来实现打印机监控及内容抓取。通过设置钩子记录打印信息,并利用管道消息通知进程检查打印机状态。提供了具体的代码示例,并附带了工程下载链接。
摘要由CSDN通过智能技术生成

    基于HOOK 和 状态轮询的 打印机监控,内容抓取,网上例子要么都是介绍如何挂钩子监控,要么是轮询查询打印机状态,很少有两者联合起来监控,兼抓取内容的。先贴下代码。

    

// PrinterHook.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"
#include "PrinterHook.h"

#define PRINTER_PIPE_NAME  "\\\\.\\Pipe\\PrinterPipeName"
//老的函数指针声明
typedef HDC  (WINAPI* pOldCreateDCA)(LPCSTR pwszDriver, LPCSTR pwszDevice, LPCSTR pszPort,  CONST DEVMODEA * pdm);
typedef HDC  (WINAPI* pOldCreateDCW)(LPCWSTR pwszDriver, LPCWSTR pwszDevice, LPCWSTR pszPort,  CONST DEVMODEW * pdm);
typedef int  (WINAPI* pOldStartDocA)( HDC hdc,  CONST DOCINFOA *lpdi);
typedef int  (WINAPI* pOldStartDocW)( HDC hdc,  CONST DOCINFOW *lpdi);
typedef int (WINAPI* pOldEndDoc)(HDC hdc);
typedef int  (WINAPI* pOldStartPage)(HDC hdc);
typedef int  (WINAPI* pOldEndtPage)(HDC hdc);
//文字绘制HOOK
typedef BOOL (WINAPI* pOldTextOutA)( HDC hdc, int x, int y,  LPCSTR lpString, int c);
typedef BOOL (WINAPI* pOldTextOutW)( HDC hdc, int x, int y,  LPCWSTR lpString, int c);
typedef int  (WINAPI* pOldDrawTextExA)(HDC hdc,LPSTR lpchText,int cchText,LPRECT lprc, UINT format,LPDRAWTEXTPARAMS lpdtp);
typedef int  (WINAPI* pOldDrawTextExW)(HDC hdc,LPWSTR lpchText,int cchText,LPRECT lprc, UINT format,LPDRAWTEXTPARAMS lpdtp);
typedef BOOL (WINAPI* pOldExtTextOutA)(  HDC hdc,  int x,  int y,  UINT options,  CONST RECT * lprect,  LPCSTR lpString,  UINT c, CONST INT * lpDx);
typedef BOOL (WINAPI* pOldExtTextOutW)(  HDC hdc,  int x,  int y,  UINT options,  CONST RECT * lprect,  LPCWSTR lpString,  UINT c, CONST INT * lpDx);
typedef BOOL (WINAPI* pOldPolyTextOutA)( HDC hdc, CONST POLYTEXTA * ppt,  int nstrings);
typedef BOOL (WINAPI* pOldPolyTextOutW)( HDC hdc, CONST POLYTEXTW * ppt,  int nstrings);
typedef int  (WINAPI* pOldDrawTextA)(HDC hdc, LPCSTR lpchText,int cchText, LPRECT lprc,UINT format);
typedef int  (WINAPI* pOldDrawTextW)(HDC hdc, LPCWSTR lpchText,int cchText, LPRECT lprc,UINT format);
typedef LONG (WINAPI* pOldTabbedTextOutA)(HDC hdc,int x,int y,LPCSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin);
typedef LONG (WINAPI* pOldTabbedTextOutW)(HDC hdc,int x,int y,LPCWSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin);

typedef struct _PrintFileInfo
{
    FILE*       pFile;
    DWORD       dwPage;
    std::string strFileTime;
    std::string strFileName;
    std::string strDocName;
}PrintFileInfo;

enum
{
    emStartCheck,
    emReturnResult
};

PVOID g_pOldCreateDCA = NULL;
PVOID g_pOldCreateDCW = NULL;
PVOID g_pOldStartDocA = NULL;
PVOID g_pOldStartDocW = NULL;
PVOID g_pOldEndDoc = NULL;
PVOID g_pOldStartPage = NULL;
PVOID g_pOldEndPage = NULL;
PVOID g_pOldTextOutA = NULL;
PVOID g_pOldTextOutW = NULL;
PVOID g_pOldDrawTextExA = NULL;
PVOID g_pOldDrawTextExW = NULL;
PVOID g_pOldExtTextOutA = NULL;
PVOID g_pOldExtTextOutW = NULL;
PVOID g_pOldPolyTextOutA = NULL;
PVOID g_pOldPolyTextOutW = NULL;
PVOID g_pOldDrawTextA = NULL;
PVOID g_pOldDrawTextW = NULL;
PVOID g_pOldTabbedTextOutA = NULL;
PVOID g_pOldTabbedTextOutW = NULL;

PrintFileInfo PrinterFileInfo = {NULL};
HDC hDc = NULL;

HDC  WINAPI CreateDCAHook(  LPCSTR pwszDriver,  LPCSTR pwszDevice,  LPCSTR pszPort,  CONST DEVMODEA * pdm);
HDC  WINAPI CreateDCWHook(  LPCWSTR pwszDriver,  LPCWSTR pwszDevice,  LPCWSTR pszPort,  CONST DEVMODEW * pdm);

int WINAPI StartPageHook(HDC hdc);
int WINAPI EndPageHook(HDC hdc);

int WINAPI StartDocAHook( HDC hdc,  CONST DOCINFOA *lpdi);
int WINAPI StartDocWHook( HDC hdc,  CONST DOCINFOW *lpdi);

int WINAPI  EndDocHook(HDC hdc);

BOOL  WINAPI TextOutAHook( HDC hdc, int x, int y,  LPCSTR lpString, int c);
BOOL  WINAPI TextOutWHook( HDC hdc, int x, int y,  LPCWSTR lpString, int c);

int  WINAPI DrawTextExAHook( HDC hdc, LPSTR lpchText,int cchText,LPRECT lprc,UINT format,LPDRAWTEXTPARAMS lpdtp);
int  WINAPI DrawTextExWHook( HDC hdc, LPWSTR lpchText,int cchText,LPRECT lprc,UINT format,LPDRAWTEXTPARAMS lpdtp);

BOOL WINAPI ExtTextOutAHook(  HDC hdc,  int x,  int y,  UINT options,  CONST RECT * lprect,  LPCSTR lpString,  UINT c, CONST INT * lpDx);
BOOL WINAPI ExtTextOutWHook(  HDC hdc,  int x,  int y,  UINT options,  CONST RECT * lprect,  LPCWSTR lpString,  UINT c, CONST INT * lpDx);

BOOL WINAPI PolyTextOutAHook( HDC hdc, CONST POLYTEXTA * ppt,  int nstrings);
BOOL WINAPI PolyTextOutWHook( HDC hdc, CONST POLYTEXTW * ppt,  int nstrings);
int  WINAPI DrawTextAHook(HDC hdc, LPCSTR lpchText,int cchText, LPRECT lprc,UINT format);
int  WINAPI DrawTextWHook(HDC hdc, LPCWSTR lpchText,int cchText, LPRECT lprc,UINT format);
LONG WINAPI TabbedTextOutAHook(HDC hdc,int x,int y,LPCSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin);
LONG WINAPI TabbedTextOutWHook(HDC hdc,int x,int y,LPCWSTR lpString,int chCount,int nTabPositions,CONST INT *lpnTabStopPositions,int nTabOrigin);

 PrinterHook* PrinterHook::m_pInstance = NULL;

 PrinterHook::CGarbo PrinterHook::Garbo;

PrinterHook::PrinterHook()
{
	
}
PrinterHook::~PrinterHook()
{

}

string  U2A(const wchar_t* szU)
{
    int nRetCode = (int)WideCharToMultiByte (CP_ACP, 0, szU, -1, 0, 0, NULL, NULL) ;
    if ( nRetCode ==0 )
    {
        return "";
    }
    std::string str(nRetCode-1, '\0');
    WideCharToMultiByte (CP_ACP, 0, szU, -1, (char*)(str.c_str()), nRetCode, NULL, NULL) ;
    return str;
}

void WriteContextTextA(LPCSTR lpString)
{
    if (PrinterFileInfo.pFile != NULL)
    {
        fwrite(lpString,sizeof(char),strlen(lpString),PrinterFileInfo.pFile);
    }
}

string GetDocName(std::string& strDocName)
{
    std::string strName = "";
    if (!strDocName.empty())
    {
        strName = strDocName;
        size_t pos = strName.find_last_of('\\');
        strName = strName.substr(pos+1,strName.length());
        pos = strName.find_last_of('.');
        if (pos != std::string::npos)
        {
            strName = strName.substr(0,pos);
        }
    }
    return strName;
}

void WriteContextTextW(LPCWSTR lpString)
{
    if (PrinterFileInfo.pFile != NULL)
    {
        std::string str = U2A(lpString);
        fwrite(str.c_str(),sizeof(char),str.length(),PrinterFileInfo.pFile);
    }
}

std::wstring GetWString(LPCWSTR lpString,int c)
{
    if (lpString == NULL || c == 0)
    {
        return L"";
    }
    std::wstring strTmp = L"";
    WCHAR* wbuff = new WCHAR[c + 1];
    ZeroMemory(wbuff,sizeof(WCHAR)*c + 1);
    memcpy_s(wbuff,sizeof(WCHAR)*c,lpString,sizeof(WCHAR)*c);
    *(wbuff+c) = 0;
    strTmp = wbuff;
    strTmp.erase(0,strTmp.find_first_not_of(L" "));
    strTmp.erase(strTmp.find_last_not_of(L" ") + 1);
    delete [] wbuff;
    return strTmp;
}

std::string GetString(LPCSTR lpString,int c)
{
    if (lpString == NULL || c == 0)
    {
        return "";
    }
    std::string strTmp = "";
    CHAR* buff = new CHAR[c + 1];
    ZeroMemory(buff,sizeof(CHAR)*c + 1);
    memcpy_s(buff,sizeof(CHAR)*c,lpString,sizeof(CHAR)*c);
    *(buff+c) = 0;
    strTmp = buff;
    strTmp.erase(0,strTmp.find_first_not_of(" "));
    strTmp.erase(strTmp.find_last_not_of(" ") + 1);
    delete [] buff;
    return strTmp;
}

void PrinterHook::StartHook()
{
#define STR(str) #str
#define DETOURATTACH(dll,name) \
    {g_pOld##name = DetourFindFunction(dll,STR(name));\
     DetourAttach(&g_pOld##name,name##Hook);}\

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());//得到当前线程
    DETOURATTACH("Gdi32.dll",CreateDCA);
    DETOURATTACH("Gdi32.dll",CreateDCW);
    DETOURATTACH("Gdi32.dll",StartDocW);
    DETOURATTACH("Gdi32.dll",StartDocA);
    DETOURATTACH("Gdi32.dll",StartPage);
    DETOURATTACH("Gdi32.dll",EndPage);
    DETOURATTACH("Gdi32.dll",EndDoc);
    //文字相关
    DETOURATTACH("Gdi32.dll",TextOutA);
    DETOURATTACH("Gdi32.dll",TextOutW);
    DETOURATTACH("User32.dll",DrawTextExA);
    DETOURATTACH("User32.dll",DrawTextExW);
    DETOURATTACH("Gdi32.dll",ExtTextOutA);
    DETOURATTACH("Gdi32.dll",ExtTextOutW);
    DETOURATTACH("Gdi32.dll",PolyTextOutA);
    DETOURATTACH("Gdi32.dll",PolyTextOutW);
    DETOURATTACH("User32.dll",DrawTextA);
    DETOURATTACH("User32.dll",DrawTextW);
    DETOURATTACH("User32.dll",TabbedTextOutA);
    DETOURATTACH("User32.dll",TabbedTextOutW);
    LONG ret=DetourTransactionCommit();
}

void PrinterHook::StopHook()
{
#define DETOURDETACH(name) \
    if (g_pOld##name) \
    {\
        DetourDetach(&g_pOld##name,name##Hook);\
    }\

    DetourTransactionBegin();
    DetourUpdateThread(GetCurrentThread());
    DETOURDETACH(CreateDCA);
    DETOURDETACH(CreateDCW);
    DETOURDETACH(StartPage);
    DETOURDETACH(EndPage);
    DETOURDETACH(EndDoc
客户端安装个软件。负责监控该电脑的打印动作。并把内容转成图片储存。并将图片传送到服务器机器上,并将打印内容传到服务器上面. 解决方案: 1. 先用api打印函数连接到指定的打印机.再试着用枚举函数()获得打印作业信息.根据信息得知打印内容,及当前的状态. 2. 获知内容,得知打印内容所在的位置,再某种方式将数据导在图片;再传到服务器上. 技术问题: 1. 打印枚举函数中找不到JOB_INFO_1 或 JOB_INFO_2结构的定义.(已解决) 2. 怎么样获得打印内容.是通过原本的驱动还是其它办法, 其它: 文件传给pdf打印机之前已经存成raw格式了,应该是从缓冲池中直接读取数据 接下去要完成的应该是怎么把raw格式读出来, 具我推测在获得打印信息的时候肯定有某个参数跟这个RAW格式是对应的.读出某个参数后才能再继续读取对RAW文件读取 具微软件网站显示,打印机的格式应该分成5种.raw的三种格式,text,emf(增强型图元文件) RAW格式指是最原始的数据 CreateDC("WINSPOOL", printer, null, ref dv);//用DISPLAY,是获取整个屏幕的设备场景;2、用WINSPOOL,则是访问打印驱动 返回新设备场景句柄,若出错则为零 EMFStreamPrintDocument 实力问题:就算获得句柄也没有办法接下去要做什么.(想错了) 目前状态:EMF图片取出来,监控也可以实现了.但监控打印作业跟EMF图片不知道怎么产生关联.而且EMF图片读起出来比较慢. 取EMF图片本身spl就已经读入内存,但是有一种办法为了要读取图片只能将spl文件考出来再做成emf文件. 新的思路能不能将文件 shd文件中包含了一个作业ID RPC 命名管道 Server(服务器) Server 系统服务提供 RPC 支持以及文件、打印和命名管道在网络上的共享。Server 服务允许本地资源(如磁盘和打印机)共享,因此网络上的其他用户可以访问它们。它还允许在其他计算机上的应用程序与您计算机上的应用程序之间进行命名管道通信,这是用于 RPC 的。命名管道通信是为一个进程的输出(此输出用作另外一个进程的输入)而保留的内存。接受输入的进程不必是本地进程。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值