PrintUtil

来源:互联网 发布:docker 连接 数据库 编辑:程序博客网 时间:2024/06/06 11:36

// LSPrinterUtil.h: interface for the CLSPrinterUtil class.
//
//////////////////////////////////////////////////////////////////////

/********************************************************************
Summary:
(c)1999-2009 SBR-INFO INC., All Rights Reserved.
*********************************************************************/

/********************************************************************
 Summary:
  打印监控工具类 
 History:
  <TABLE>
   最后修改时间   修改人  修改后版本  修改说明
   ------------   ------  ----------  ---------
   2009-06-04         1.0       创建
  </TABLE>
 TODO: 
  * TODO: 枚举出主机上的所有打印机
  * TODO: 审计所有打印的文档
  * TODO: 禁止、恢复打印机的使用
*********************************************************************/

#if !defined(AFX_LSPRINTERUTIL_H__EB557D77_8850_45CC_89C4_08ECBCDB4D3D__INCLUDED_)
#define AFX_LSPRINTERUTIL_H__EB557D77_8850_45CC_89C4_08ECBCDB4D3D__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include <WinSpool.h>
#include <atlbase.h>

namespace LSSDK
{
 typedef struct _PRINTER_INFO_WRAPPER
 {
  DWORD dwAttribute;      //打印机的属性
  DWORD dwPortType;      //打印机的接口类型
  DWORD dwStatus;       //打印机的状态

  CString strServerName;     //打印机的服务名称
  CString strPrinterName;     //打印机的名称
  CString strShareName;     //打印机的共享名称
  CString strPortName;     //打印机的接口名称
  CString strPortDesc;     //打印机的接口描述
  CString strDriverName;     //打印机的驱动名称
  CString strPrintProcessor;    //打印机的打印进程
  BOOL    bInit;       //打印机信息的初始化状态
  HANDLE  hPrinter;      //打印机句柄

  _PRINTER_INFO_WRAPPER()
  {
   dwAttribute = 0;
   dwPortType  = 0;
   dwStatus = -1;
   bInit    = FALSE;
   hPrinter = NULL;
  }

  ~_PRINTER_INFO_WRAPPER()
  {
  }

 }PRINTER_INFO_WRAPPER_ST;

 typedef enum _TAG_PRINTER_TYPE
 {
  NETWORK_PRINTER,
  SHARE_PRINTER,
  LOCAL_PRINTER,
  VIRTUAL_PRINTER,
 }PRINTER_TYPE_ENUM;

 typedef std::map<CString, PRINTER_INFO_WRAPPER_ST> PRINTER_MAP;

 class AFX_EXT_CLASS CLSPrinterUtil : public CLSBaseUtil
 {
 public:
  /********************************************************************
  Summary:
   CLSPrinterUtil类对象构造函数
  *********************************************************************/
  CLSPrinterUtil();

  /********************************************************************
  Summary:
   CLSPrinterUtil类对象析构函数
  *********************************************************************/
  virtual ~CLSPrinterUtil();

  /********************************************************************
  Summary:
   从注册表中读取某项目的值
  Parameters:
   strValueName  - 获取值的名称
   strValue   - 获取值
  Returns:
   成功返回TRUE, 失败返回FALSE
  *********************************************************************/
  BOOL GetRegString(CString strValueName, CString &strValue);
  
  /********************************************************************
  Summary:
   获取网络打印机的服务名称
  Parameters:
   strValueName  - 获取值的名称
   dwValue    - 获取值
  Returns:
   成功返回TRUE, 失败返回FALSE
  *********************************************************************/
  BOOL GetRegDWORD(CString strValueName, DWORD &dwValue);

  /********************************************************************
  Summary:
   枚举出所有的打印机,并初始化打印机信息
  Returns:
   成功返回TRUE, 失败返回FALSE
  *********************************************************************/
  BOOL GetAllPrintersInfo(PRINTER_MAP &mPrinter);

  /********************************************************************
  Summary:
   获取打印机的类型
  Parameters:
   dwAttribute - 打印机的属性
   dwPortType  - 打印机的接口类型,目前不用此属性判断
  Returns:
   返回打印机的类型
  *********************************************************************/
  PRINTER_TYPE_ENUM GetPrinterType(DWORD dwAttribute, DWORD dwPortType = 0);

  /********************************************************************
  Summary:
   根据打印机名称初始化打印机信息
  Parameters:
   strPrinterName - 打印机名称
   stPrinterInfo  - 要初始化的打印机信息
  Returns:
   成功返回TRUE, 失败返回FALSE
  *********************************************************************/
  BOOL GetPrinterInfo(const CString strPrinterName, PRINTER_INFO_WRAPPER_ST& stPrinterInfo);

  /********************************************************************
  Summary:
   获得打印机作业的状态信息,用字符串标识
  Parameters:
   dwStatus  - 作业的状态信息
  Returns:
   作业的状态信息
  *********************************************************************/
  CString GetJobStatusStr(DWORD dwStatus);

  /********************************************************************
  Summary:
   判断打印机的句柄是否有效
  Parameters:
   hPrinter  - 打印机句柄
  Returns:
   成功返回TRUE, 失败返回FALSE
  *********************************************************************/
  BOOL IsPrinterHandle(HANDLE hPrinter);

  /********************************************************************
  Summary:
   在堆上分配内存,并初始化
  Parameters:
   uBytes - 分配内存的大小
  Returns:
   成功返回分配内存的句柄,失败抛出异常
  *********************************************************************/
  HLOCAL AllocMem(const UINT uBytes);

  /********************************************************************
  Summary:
   在堆上释放分配内存
  Parameters:
   hMem - 释放内存的句柄
  Returns:
   失败抛出异常
  *********************************************************************/
  void FreeMem(HLOCAL hMem);

 private:
  /********************************************************************
  Summary:
   输出打印机的接口信息,只有在DEBUG环境下运行。
  Parameters:
   pPortInfo  - 打印机接口信息
   dwPortCount  - 打印机接口数
  *********************************************************************/
  void PrintPortInfo(PPORT_INFO_2 pPortInfo, DWORD dwPortCount);

  /********************************************************************
  Summary:
   输出打印机信息,只有在DEBUG环境下运行。
  Parameters:
   pPrinterInfo - 打印机信息
   dwIndex   - 打印机索引值
  *********************************************************************/
  void PrintPrinterInfo(LPPRINTER_INFO_2 pPrinterInfo, DWORD dwIndex);
 
 protected:
  CRegKey m_reg;
 };
}

#endif // !defined(AFX_LSPRINTERUTIL_H__EB557D77_8850_45CC_89C4_08ECBCDB4D3D__INCLUDED_)

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

// LSPrinterUtil.cpp: implementation of the CLSPrinterUtil class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "LSPrinterUtil.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CLSPrinterUtil::CLSPrinterUtil()
{
}

CLSPrinterUtil::~CLSPrinterUtil()
{
}

HLOCAL CLSPrinterUtil::AllocMem(const UINT uBytes)
{
 HLOCAL hMem = NULL;

 hMem = LocalAlloc(LPTR, uBytes);
 
 if (hMem == NULL)
 {
  ThrowException(_T("LocalAlloc"));
 }

 return hMem;
}

void CLSPrinterUtil::FreeMem(HLOCAL hMem)
{
 if (hMem != NULL)
 {
  if ( LocalFree(hMem) != NULL )
  {
   ThrowException(_T("LocalFree"));
  }
  else
  {
   hMem = NULL;
  }
 }
}

void CLSPrinterUtil::PrintPortInfo(PPORT_INFO_2 pPortInfo, DWORD dwPortCount)
{
 for (DWORD dwIndex = 0; dwIndex < dwPortCount; dwIndex++)
 {
  TRACE("PortName: %s/n",pPortInfo[dwIndex].pPortName);
  TRACE("MonitorName: %s/n",pPortInfo[dwIndex].pMonitorName);
  TRACE("Description: %s/n",pPortInfo[dwIndex].pDescription);
  TRACE("PortType: %d/n",pPortInfo[dwIndex].fPortType);
  
  TRACE("/n/n");
 }
}

void CLSPrinterUtil::PrintPrinterInfo(LPPRINTER_INFO_2 pPrinterInfo, DWORD dwIndex)
{
 TRACE("ServerName: %s/n", pPrinterInfo[dwIndex].pServerName);
 TRACE("PrinterName: %s/n", pPrinterInfo[dwIndex].pPrinterName);
 TRACE("ShareName: %s/n", pPrinterInfo[dwIndex].pShareName);
 TRACE("PortName: %s/n", pPrinterInfo[dwIndex].pPortName);
 TRACE("DriverName: %s/n", pPrinterInfo[dwIndex].pDriverName);
 TRACE("Comment: %s/n", pPrinterInfo[dwIndex].pComment);
 TRACE("Location: %s/n", pPrinterInfo[dwIndex].pLocation);
 TRACE("SepFile: %s/n", pPrinterInfo[dwIndex].pSepFile);
 TRACE("PrintProcessor: %s/n", pPrinterInfo[dwIndex].pPrintProcessor);
 TRACE("DataType: %s/n", pPrinterInfo[dwIndex].pDatatype);
 TRACE("Parameters: %s/n", pPrinterInfo[dwIndex].pParameters);
 
 TRACE("Attributes: %d/n", pPrinterInfo[dwIndex].Attributes);
 TRACE("Priority: %d/n", pPrinterInfo[dwIndex].Priority);
 TRACE("DefaultPriority: %d/n", pPrinterInfo[dwIndex].DefaultPriority);
 TRACE("UntilTime: %d/n", pPrinterInfo[dwIndex].UntilTime);
 TRACE("Status: %d/n", pPrinterInfo[dwIndex].Status);
 TRACE("cJobs: %d/n", pPrinterInfo[dwIndex].cJobs);
 TRACE("AveragerPPM: %d/n", pPrinterInfo[dwIndex].AveragePPM);
 
 TRACE("/n/n");
}

PRINTER_TYPE_ENUM CLSPrinterUtil::GetPrinterType(DWORD dwAttribute, DWORD dwPortType)
{
 PRINTER_TYPE_ENUM enumPrinterType;

 if (dwAttribute & PRINTER_ATTRIBUTE_NETWORK)
 {
  enumPrinterType = NETWORK_PRINTER;
  
  if ( dwAttribute & PRINTER_ATTRIBUTE_SHARED)
   enumPrinterType = SHARE_PRINTER;
 }

 if (dwAttribute & PRINTER_ATTRIBUTE_LOCAL)
 {
  enumPrinterType = LOCAL_PRINTER;
  
  //此处判断虚拟打印机
  //if ();
 }

 return enumPrinterType;
}

BOOL CLSPrinterUtil::GetRegString(CString strValueName, CString &strValue)
{
 BOOL bReturn = FALSE;
 DWORD dwSize = MAX_PATH;
 char szString[MAX_PATH];
 
 long lReturn = m_reg.QueryValue(szString, strValueName, &dwSize);
 
 if (lReturn == ERROR_MORE_DATA)
 {
  char * szNewString = new char[dwSize];
  
  lReturn = m_reg.QueryValue(szNewString, strValueName, &dwSize);

  if(ERROR_SUCCESS == lReturn)
  {
   strValue = szNewString;
   delete [] szNewString;

   bReturn = TRUE;
  }
 }
 else if(lReturn == ERROR_SUCCESS)
 {
  strValue = szString;
  bReturn = TRUE;
 }

 return bReturn;
}

BOOL CLSPrinterUtil::GetRegDWORD(CString strValueName, DWORD &dwValue)
{
 long lReturn = m_reg.QueryValue(dwValue, strValueName);

 if(lReturn==ERROR_SUCCESS)
 {
  return TRUE;
 }

 return FALSE;
}

BOOL CLSPrinterUtil::GetAllPrintersInfo(PRINTER_MAP &mPrinter)
{
 DWORD dwPortCbNeeded = 0;
 DWORD dwPortCount = 0;
 PPORT_INFO_2 pPortInfo = NULL;
 BOOL bStatus;
 
 EnumPorts(NULL, 2, NULL, 0, &dwPortCbNeeded, &dwPortCount);

 pPortInfo = (PPORT_INFO_2)AllocMem(dwPortCbNeeded);

 bStatus = EnumPorts(NULL, 2, (LPBYTE)pPortInfo, dwPortCbNeeded, &dwPortCbNeeded, &dwPortCount);

 if (!bStatus)
 {
  FreeMem(pPortInfo);
  TRACE("EnumPorts 失败/n");
  
  return bStatus;
 }

 PrintPortInfo(pPortInfo, dwPortCount);
 
 LPPRINTER_INFO_2 pPrinterInfo = NULL;
    DWORD dwPrinterCbNeeded = 0;
 DWORD dwPrinterCount = 0;
 
 EnumPrinters( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
      NULL,
      2,
      NULL,
      0,
      &dwPrinterCbNeeded,
      &dwPrinterCount );

 pPrinterInfo = (LPPRINTER_INFO_2)AllocMem(dwPrinterCbNeeded);

 bStatus = EnumPrinters( PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
       NULL,
       2,
       (LPBYTE)pPrinterInfo,
       dwPrinterCbNeeded,
       &dwPrinterCbNeeded,
       &dwPrinterCount );

 if (!bStatus)
 {
  FreeMem(pPortInfo);
  FreeMem(pPrinterInfo);

  TRACE("EnumPrinters 失败/n");
  
  return bStatus;
 }

 for (DWORD i = 0; i < dwPrinterCount; ++i)
 {
  PRINTER_INFO_WRAPPER_ST stPrinterInfo;

  stPrinterInfo.strPrinterName = pPrinterInfo[i].pPrinterName;
  stPrinterInfo.strServerName  = pPrinterInfo[i].pServerName;
  stPrinterInfo.strShareName   = pPrinterInfo[i].pShareName;
  stPrinterInfo.strPortName    = pPrinterInfo[i].pPortName;
  stPrinterInfo.strDriverName  = pPrinterInfo[i].pDriverName;
  stPrinterInfo.strPrintProcessor = pPrinterInfo[i].pPrintProcessor;
  stPrinterInfo.dwAttribute  = pPrinterInfo[i].Attributes;
  stPrinterInfo.dwStatus   = pPrinterInfo[i].Status;

  for (DWORD dwIndex = 0; dwIndex < dwPortCount; dwIndex++)
  {
   if (stPrinterInfo.strPortName.CompareNoCase(pPortInfo[dwIndex].pPortName) == 0)
   {
    stPrinterInfo.dwPortType = pPortInfo[dwIndex].fPortType;
    stPrinterInfo.strPortDesc = pPortInfo[dwIndex].pDescription;
    stPrinterInfo.bInit = TRUE;

    if ((stPrinterInfo.dwPortType & PORT_TYPE_NET_ATTACHED) && stPrinterInfo.strServerName.IsEmpty())
    {
     CString strPath;
     strPath.Format("SYSTEM//CurrentControlSet//Control//Print//Monitors//%s//Ports//%s",
             stPrinterInfo.strPortDesc, stPrinterInfo.strPortName);
     
     if (m_reg.Open(HKEY_LOCAL_MACHINE, strPath) == ERROR_SUCCESS)
     {
      CString strServerIp;
      DWORD dwPortNumber;

      GetRegString(_T("IPAddress"), strServerIp);
      GetRegDWORD(_T("PortNumber"), dwPortNumber);

      if (!strServerIp.IsEmpty())
      {
       stPrinterInfo.strServerName.Format("%s:%d", strServerIp, dwPortNumber);
      }

      m_reg.Close();
     }
    }
    break;
   }
  }

  if (mPrinter.find(pPrinterInfo[i].pPrinterName) == mPrinter.end())
  {
   mPrinter.insert(make_pair(pPrinterInfo[i].pPrinterName, stPrinterInfo));
  }

  PrintPrinterInfo(pPrinterInfo, i);
 }
 
 FreeMem(pPortInfo);
 FreeMem(pPrinterInfo);

 return bStatus;
}

BOOL CLSPrinterUtil::GetPrinterInfo(const CString strPrinterName, PRINTER_INFO_WRAPPER_ST& stPrinterInfo)
{
 BOOL bStatus = FALSE;
 DWORD dwPortCbNeeded = 0;
 DWORD dwPortCount = 0;
 DWORD dwPrinterCbNeeded = 0;
 PPORT_INFO_2  pPortInfo    = NULL;
 LPPRINTER_INFO_2 pPrinterInfo = NULL;
 HANDLE hPrinter = NULL;
 
 if (strPrinterName.IsEmpty())
  return bStatus;
 
 EnumPorts(NULL, 2, NULL, 0, &dwPortCbNeeded, &dwPortCount);
 
 pPortInfo = (PPORT_INFO_2)AllocMem(dwPortCbNeeded);
 
 bStatus = EnumPorts(NULL, 2, (LPBYTE)pPortInfo, dwPortCbNeeded, &dwPortCbNeeded, &dwPortCount);
 
 if (!bStatus)
 {
  FreeMem(pPortInfo);
  TRACE("EnumPorts 失败/n");
  
  return bStatus;
 }
 
 bStatus = OpenPrinter((char *)(LPCTSTR)strPrinterName, &hPrinter, NULL);
 
 if (!bStatus)
 {
  FreeMem(pPortInfo);
  TRACE("OpenPrinter 失败/n");
  
  return bStatus;
 }
 
 GetPrinter(hPrinter, 2, NULL, 0, &dwPrinterCbNeeded);
 
 pPrinterInfo = (LPPRINTER_INFO_2)AllocMem(dwPrinterCbNeeded);
 
 bStatus = GetPrinter(hPrinter, 2, (LPBYTE)pPrinterInfo, dwPrinterCbNeeded, &dwPrinterCbNeeded);
 
 if (!bStatus)
 {
  FreeMem(pPortInfo);
  FreeMem(pPrinterInfo);
  TRACE("GetPrinter 失败/n");
  
  return bStatus;
 }
 
 stPrinterInfo.strPrinterName = pPrinterInfo->pPrinterName;
 stPrinterInfo.strServerName  = pPrinterInfo->pServerName;
 stPrinterInfo.strShareName   = pPrinterInfo->pShareName;
 stPrinterInfo.strPortName    = pPrinterInfo->pPortName;
 stPrinterInfo.strDriverName  = pPrinterInfo->pDriverName;
 stPrinterInfo.strPrintProcessor = pPrinterInfo->pPrintProcessor;
 stPrinterInfo.dwAttribute  = pPrinterInfo->Attributes;
 stPrinterInfo.dwStatus   = pPrinterInfo->Status;
 
 for (DWORD dwIndex = 0; dwIndex < dwPortCount; dwIndex++)
 {
  if (stPrinterInfo.strPortName.CompareNoCase(pPortInfo[dwIndex].pPortName) == 0)
  {
   stPrinterInfo.dwPortType = pPortInfo[dwIndex].fPortType;
   stPrinterInfo.strPortDesc = pPortInfo[dwIndex].pDescription;
   stPrinterInfo.bInit = TRUE;
   
   if((stPrinterInfo.dwPortType & PORT_TYPE_NET_ATTACHED) && stPrinterInfo.strServerName.IsEmpty())
   {
    CString strPath;
    strPath.Format("SYSTEM//CurrentControlSet//Control//Print//Monitors//%s//Ports//%s",
             stPrinterInfo.strPortDesc, stPrinterInfo.strPortName);
    
    if (m_reg.Open(HKEY_LOCAL_MACHINE, strPath) == ERROR_SUCCESS)
    {
     CString strServerIp;
     DWORD dwPortNumber;
     
     GetRegString(_T("IPAddress"), strServerIp);
     GetRegDWORD(_T("PortNumber"), dwPortNumber);
     
     if (!strServerIp.IsEmpty())
     {
      stPrinterInfo.strServerName.Format("%s:%d", strServerIp, dwPortNumber);
     }
     
     m_reg.Close();
    }
   }
   break;
  }
 }
 
 FreeMem(pPortInfo);
 FreeMem(pPrinterInfo);
 
 return bStatus;
}

BOOL CLSPrinterUtil::IsPrinterHandle(HANDLE hPrinter)
{
 DWORD dwCbNeeded;
    DWORD dwError;
    BOOL bRet;

 bRet = GetPrinter(hPrinter, 2, (LPBYTE)NULL, 0, &dwCbNeeded);
 
    if (!bRet)
    {
        dwError = GetLastError();
  
        if( dwError == ERROR_INSUFFICIENT_BUFFER )
        {
            bRet = TRUE;
        }
    }

    return bRet;
}

CString CLSPrinterUtil::GetJobStatusStr(DWORD dwStatus)
{
 DWORD dwClearWord = 0;
 CString strJobStatus;
 
 //由状态位构造状态字符串,当处理完所有的位标识结束
 while (dwStatus)
 {
  //由分割符分割多个状态字符串
  if (dwClearWord)
   strJobStatus += "-";
  
  if (JOB_STATUS_SPOOLING & dwStatus)
  {
   strJobStatus += "正在进行后台打印";
   dwClearWord |= JOB_STATUS_SPOOLING;
  }
  else if (JOB_STATUS_ERROR & dwStatus)
  {
   strJobStatus += "错误";
   dwClearWord |= JOB_STATUS_ERROR;
  }
  else if (JOB_STATUS_PRINTING & dwStatus)
  {
   strJobStatus += "正在打印";
   dwClearWord |= JOB_STATUS_PRINTING;
  }
  else if (JOB_STATUS_DELETING & dwStatus)
  {
   strJobStatus += "正在删除";
   dwClearWord |= JOB_STATUS_DELETING;
  }
  else if (JOB_STATUS_PAUSED & dwStatus)
  {
   strJobStatus += "暂停";
   dwClearWord |= JOB_STATUS_PAUSED;
  }
  else if (JOB_STATUS_PRINTED & dwStatus)
  {
   strJobStatus += "已打印";
   dwClearWord |= JOB_STATUS_PRINTED;
  }
  else if (JOB_STATUS_DELETED & dwStatus)
  {
   strJobStatus += "已删除";
   dwClearWord |= JOB_STATUS_DELETED;
  }
  else if (JOB_STATUS_OFFLINE & dwStatus)
  {
   strJobStatus += "脱机";
   dwClearWord |= JOB_STATUS_OFFLINE;
  }
  else if (JOB_STATUS_PAPEROUT & dwStatus)
  {
   strJobStatus += "缺纸";
   dwClearWord |= JOB_STATUS_PAPEROUT;
  }
  else if (JOB_STATUS_BLOCKED_DEVQ & dwStatus)
  {
   strJobStatus += "无法打印";
   dwClearWord |= JOB_STATUS_BLOCKED_DEVQ;
  }
  else if (JOB_STATUS_USER_INTERVENTION & dwStatus)
  {
   strJobStatus += "需要手动参与";
   dwClearWord |= JOB_STATUS_USER_INTERVENTION;
  }
  else if (JOB_STATUS_RESTART & dwStatus)
  {
   strJobStatus += "重新启动";
   dwClearWord |= JOB_STATUS_RESTART;
  }
  else
  {
   strJobStatus += "未知状态";
   dwClearWord = dwStatus;
  }
  
  //清楚已经处理的标识位
  dwStatus = dwStatus & ~dwClearWord;
 }

 return strJobStatus;
}

原创粉丝点击