• 控制除WORD外的打印份数


    要实现一个小功能:监视所有打印任务,使得每次只能打印一份

    思路:使用EnumJobs 函数枚举所有的打印任务,得到打印的份数,如果发现份数不是1就将任务删除

    其中要用SetJob把任务删除的话需要有一定的权限。如果打印机的句柄是自己打开的,由于OpenPrinter 函数第三个参数不好设置,

    因此决定用API hook的办法。截获 EndDocPrinter函数,在里面实现主要功能

    PS:蛋疼的WORD真是恶心,用EnumJobs获取的打印份数始终是1,不知道是怎么回事

    主要代码如下:

    EndDocPrinter.h
     1 #pragma once
     2 
     3 #include "stdafx.h"
     4 
     5 typedef
     6     BOOL (WINAPI * __pfnEndDocPrinter)(
     7     _In_  HANDLE hPrinter
     8     );
     9 
    10 BOOL WINAPI my_EndDocPrinter(
    11     _In_  HANDLE hPrinter
    12     );
    13 
    14 extern __pfnEndDocPrinter pfnEndDocPrinter;
    EndDocPrinter.cpp:
     1 #include "stdafx.h"
     2 #include <Winspool.h>
     3 
     4 BOOL WINAPI my_EndDocPrinter(
     5                       _In_  HANDLE hPrinter
     6                    )
     7 {
     8     BOOL ret = FALSE;
     9     DWORD cbNeeded = 0, cReturned = 0;
    10     DWORD actNeeded = 0;
    11     TCHAR szCopys[MAX_PATH];
    12     ret = EnumJobs(hPrinter, 0, 127, 2, NULL, 0, &cbNeeded, &cReturned);
    13     actNeeded = cbNeeded;
    14     JOB_INFO_2* print_job = new JOB_INFO_2[actNeeded];
    15     ret = EnumJobs(hPrinter, 0, 127, 2, (LPBYTE)print_job, actNeeded, &cbNeeded, &cReturned);
    16     for (int i = 0; i < cReturned; i++)
    17     {
    18         short num=print_job[i].pDevMode->dmCopies;
    19         if(num!=1)
    20         {
    21             SetJob(hPrinter, print_job[i].JobId,2,(LPBYTE)&(print_job[i]),JOB_CONTROL_DELETE);
    22         }
    23     }
    24 
    25     return pfnEndDocPrinter(hPrinter);
    26 }

    DllMain中还是用之前的inline HOOK:

     1 // dllmain.cpp : 定义 DLL 应用程序的入口点。
     2 #include "stdafx.h"
     3 
     4 
     5 __pfnEndDocPrinter pfnEndDocPrinter = (__pfnEndDocPrinter)GetProcAddress(GetModuleHandle(TEXT("Winspool.drv")), "EndDocPrinter"); 
     6 
     7 BOOL APIENTRY DllMain( HMODULE hModule,
     8                        DWORD  ul_reason_for_call,
     9                        LPVOID lpReserved
    10                      )
    11 {
    12     switch (ul_reason_for_call)
    13     {
    14     case DLL_PROCESS_ATTACH:
    15         InlineHook(
    16             (__pfnEndDocPrinter)GetProcAddress(GetModuleHandle(TEXT("Winspool.drv")), "EndDocPrinter"),
    17             my_EndDocPrinter,
    18             (void **)&pfnEndDocPrinter
    19             );
    20     case DLL_THREAD_ATTACH:
    21     case DLL_THREAD_DETACH:
    22     case DLL_PROCESS_DETACH:
    23         break;
    24     }
    25     return TRUE;
    26 }
  • 相关阅读:
    微软经典面试笔试题
    Websense一面、二面及Offer
    微软2014年技术岗位在线笔试题
    2013年微软面试经历 – 终究离他们的要求还是有一定距离
    Mesos:数据库使用的持久化卷
    Mesos和Docker的集成
    可扩展架构取舍
    组织架构适配下的敏捷开发
    TensorFlow与主流深度学习框架对比
    Pokémon Go呼应设计:让全世界玩家疯狂沉迷
  • 原文地址:https://www.cnblogs.com/02xiaoma/p/2765295.html
Copyright © 2020-2023  润新知