📄 monitor.cpp
字号:
// Monitor.cpp : main module; defines all functions
// which are exported from the DLL
#define MONITOR_EXPORTS
#include "resource.h"
#include "PortList.h"
#include "Monitor.h"
//#include "atltime.h"
#include "logger.h"
#include "DialogPathPrinter.h"
#define szLocalMonitor _T("sgPrintAgent Print Monitor")
#define szPortDesc _T("sgPrintAgent")
HINSTANCE hInst=NULL;
HINSTANCE hSpoolssDll=NULL;
CRITICAL_SECTION SpoolerSection;
class CAutoLocker
{
public:
CAutoLocker()
{
EnterCriticalSection(&SpoolerSection);
}
~CAutoLocker()
{
LeaveCriticalSection(&SpoolerSection);
}
};
HANDLE m_hEvent=NULL;
CPortList *m_portlist=NULL;
TCHAR *m_sRegistryRoot=NULL;
typedef BOOL (WINAPI *fpENUMPORTS)
(
LPWSTR pName,
DWORD Level,
LPBYTE pPorts,
DWORD cbBuf,
LPDWORD pcbNeeded,
LPDWORD pcReturned
);
BOOL PortExists(
TCHAR *pServerName,
TCHAR *pPortName,
DWORD *pError)
{
::Debug(_T("执行顺序4:PortExists"));
BOOL Found = TRUE;
fpENUMPORTS pfnSpoolssEnumPorts;
DWORD cbNeeded;
DWORD cReturned;
DWORD cbPorts;
LPPORT_INFO_1 pPorts;
*pError = NO_ERROR;
// load SPOOLSS.DLL
if (!hSpoolssDll)
hSpoolssDll = LoadLibrary(L"SPOOLSS.DLL");
if(!hSpoolssDll)
{
*pError=GetLastError();
}
else
{
// get function EnumPort
pfnSpoolssEnumPorts = (fpENUMPORTS)GetProcAddress(hSpoolssDll,"EnumPortsW");
if(!pfnSpoolssEnumPorts)
{
*pError = GetLastError();
FreeLibrary(hSpoolssDll);
hSpoolssDll = NULL;
}
}
// got no function
if (!pfnSpoolssEnumPorts)
Found=TRUE;
// execute EnumPorts, to obtain needed buffer size
(*pfnSpoolssEnumPorts)(pServerName, 1, NULL, 0, &cbNeeded, &cReturned);
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
Found=TRUE;
}
else
{
cbPorts = cbNeeded;
pPorts = (LPPORT_INFO_1)new BYTE[cbPorts];
if(!pPorts)
{
Found=TRUE;
}
else
{
if(!(*pfnSpoolssEnumPorts)(
pServerName,
1,
(LPBYTE)pPorts,
cbPorts,
&cbNeeded,
&cReturned))
{
Found=TRUE;
}
else
{
Found = FALSE;
for (DWORD z = 0; z < cReturned; z++)
{
if(_tcsicmp(pPorts[z].pName, pPortName)==0)
Found = TRUE;
}
}
}//(!pPorts)
delete pPorts;
}//(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
return Found;
}
BOOL FileExists(TCHAR *sFilePath)
{
::Debug(_T("执行顺序20:FileExists"));
WIN32_FIND_DATA w32fd;
HANDLE hFile=FindFirstFile(sFilePath,&w32fd);
if(hFile!=INVALID_HANDLE_VALUE)
{
FindClose(hFile);
return TRUE;
}
return FALSE;
}
BOOL APIENTRY DllMain(
HINSTANCE hModule,
DWORD dwReason,
LPVOID lpRes)
{
::Debug(_T("执行顺序21:DllMain"));
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
hInst = hModule;
InitializeCriticalSection(&SpoolerSection);
DisableThreadLibraryCalls((HINSTANCE)hModule);
m_portlist=new CPortList();
return TRUE;
case DLL_PROCESS_DETACH:
case DLL_THREAD_DETACH:
if(m_hEvent)
CloseHandle(m_hEvent);
if(m_sRegistryRoot)
free((void*)m_sRegistryRoot);
if(hSpoolssDll)
FreeLibrary(hSpoolssDll);
delete m_portlist;
return TRUE;
}
UNREFERENCED_PARAMETER( lpRes );
return TRUE;
}
BOOL WINAPI MyEnumPorts(
LPWSTR pName,
DWORD dwLevel,
LPBYTE pPorts,
DWORD cbBuf,
LPDWORD pdwNeeded,
LPDWORD pdwReturned)
{
::Debug(_T("执行顺序9:MyEnumPorts"));
CAutoLocker a;
BOOL bResult = m_portlist->EnumPorts(
pName,
dwLevel,
pPorts,
cbBuf,
pdwNeeded,
pdwReturned);
return bResult;
}
BOOL WINAPI MyOpenPort(
LPWSTR pName,
PHANDLE pHandle)
{
::Debug(_T("执行顺序8:MyOpenPort"));
CAutoLocker a;
TCHAR s[200];
PORT *pPort=m_portlist->FindPort(pName);
*pHandle=(HANDLE)pPort;
pPort->dwStatus |= PS_OPENED;
//孙刚增加:
if(pPort!=NULL)
{
_tcscpy(s,_T("nOpenPort:"));
_tcscat(s,pName);
Debug(s);
}
else
{
_tcscpy(s,pName);
_tcscat(s,_T("不存在"));
Debug(s);
}
//孙刚增加结束
return pPort!=NULL;
}
BOOL getJobUser(PORT *pPort,TCHAR *sUser)
{
::Debug(_T("执行顺序18:getJobUser"));
sUser[0]=0;
TCHAR s[MAX_PATH];
HANDLE hPrinter;
BOOL bRet=false;
if(OpenPrinter(pPort->sPrinterLocalDirectory,&hPrinter,NULL))
{
DWORD dwNeeded;
BYTE*pJob=new BYTE[10];
bRet=GetJob(hPrinter,pPort->dwJobID,pPort->Level,pJob,0,&dwNeeded);
if(!bRet)
{
delete []pJob;
pJob=new BYTE[dwNeeded];
bRet=GetJob(hPrinter,pPort->dwJobID,pPort->Level,pJob,dwNeeded,&dwNeeded);
}
if(!bRet)
{
_tcscpy(s,_T("无法取得任务信息(:"));
TCHAR s1[MAX_PATH];
_tcscat(s,_ultot(pPort->dwJobID,s1,10));
_tcscat(s,_T(")"));
_tcscat(s,pPort->sCurDocument);
TCHAR s2[MAX_PATH];
_tcscat(s,formatLastError(s2));
Error(s);
}
else
{
switch(pPort->Level)
{
case 1:
{
JOB_INFO_1 *pJobInfo=(JOB_INFO_1*)pJob;
Log(_T("Print a Doc"),pJobInfo->pPrinterName,pJobInfo->pDocument,pJobInfo->TotalPages,pJobInfo->pUserName,pJobInfo->pMachineName);
_tcscpy(sUser,pJobInfo->pUserName);
}
break;
case 2:
{
JOB_INFO_2 *pJobInfo=(JOB_INFO_2*)pJob;
Log(_T("Print a Doc"),pJobInfo->pPrinterName,pJobInfo->pDocument,pJobInfo->TotalPages,pJobInfo->pUserName,pJobInfo->pMachineName);
_tcscpy(sUser,pJobInfo->pUserName);
}
break;
}
}
delete []pJob;
CloseHandle(hPrinter);
}
else
{
bRet=false;
_tcscpy(s,_T("无法打开代理打印机失败:"));
_tcscat(s,pPort->sPrinterLocalDirectory);
TCHAR s1[MAX_PATH];
_tcscat(s,formatLastError(s1));
Error(s);
}
return bRet;
}
TCHAR*ValidatePath(const TCHAR*sPath,TCHAR*sPathOK)
{
::Debug(_T("执行顺序2:ValidatePath"));
int iLen=0;
const TCHAR BAD[100]=_T(" `~!@#$%^&*|{}[]::;<>?,./\"'\\");
for(int i=0;i<_tcslen(sPath);i++)
{
int ok=true;
for(int j=0;j<_tcslen(BAD);j++)
{
if(sPath[i]==BAD[j])
{
ok=false;
break;
}
}
if(ok)
{
sPathOK[iLen++]=sPath[i];
}
}
sPathOK[iLen]=0;
return sPathOK;
}
void getFileFullPath(const TCHAR*sPrinterPath,const TCHAR*sUser,const TCHAR*sDocName,TCHAR *filefullpath)
{
::Debug(_T("执行顺序19:getFileFullPath"));
_tcscpy(filefullpath,sPrinterPath);
if(sUser[0]!=0)
{
_tcscat(filefullpath,sUser);
_tcscat(filefullpath,_T("/"));
}
TCHAR s[MAX_PATH];
_tcscat(filefullpath,ValidatePath(sDocName,s));
//filepath contains now the full path of output file
//change file extension to .ps
PathRenameExtension(filefullpath,_T(".prn"));
}
BOOL WINAPI MyStartDocPort(
HANDLE hPort,
LPWSTR pPrinterName,
DWORD JobId,
DWORD Level,
LPBYTE pDocInfo)
{
::Debug(_T("执行顺序6:MyStartDocPort"));
CAutoLocker a;
TCHAR s[MAX_PATH];
PORT *pPort=(PORT*)hPort;
pPort->Level=Level;
//检查状态:
if(pPort->dwStatus & PS_STARTDOC)
{
Error(_T("代理打印机状态忙,无法开始文档!"));
return FALSE;
}
//检查物理打印机关联情况:
if(pPort->sPrinterPhysics==NULL)
{
Error(_T("没有关联物理打印机,无法开始文档!"));
return false;
}
//计算文件保存路径:
TCHAR filepath[MAX_PATH];
_tcscpy(filepath,pPort->sPath);
TCHAR sDocName[100];
switch(Level)
{
case 1:
{
DOC_INFO_1 *pDoc=(DOC_INFO_1*)pDocInfo;
_tcscpy(sDocName,pDoc->pDocName);
break;
}
case 2:
{
DOC_INFO_2 *pDoc=(DOC_INFO_2*)pDocInfo;
_tcscpy(sDocName,pDoc->pDocName);
break;
}
}
getFileFullPath(pPort->sPath,_T(""),sDocName,filepath);
//在物理打印机上开始文档:
pPort->hPrinterPhysics=NULL;
pPort->dwJobIdPhysics=0;
if(OpenPrinter(pPort->sPrinterPhysics,&pPort->hPrinterPhysics,NULL))
{
pPort->dwJobIdPhysics=::StartDocPrinter(pPort->hPrinterPhysics,Level,pDocInfo);
if(pPort->dwJobIdPhysics!=0)
{
_tcscpy(s,_T("在物理打印机上开始文档:"));
_tcscat(s,filepath);
_tcscat(s,_T("成功!文档号码:"));
TCHAR s1[50];
_tcscat(s,_ultot(pPort->dwJobIdPhysics,s1,10));
::Debug(s,pPort->sPrinterPhysics,filepath);
}
else
{
_tcscpy(s,_T("在物理打印机上开始文档:"));
_tcscat(s,filepath);
_tcscat(s,_T("失败!"));
TCHAR s1[MAX_PATH];
_tcscat(s,formatLastError(s1));
::Error(s,pPort->sPrinterPhysics,filepath);
::CloseHandle(pPort->hPrinterPhysics);
pPort->hPrinterPhysics=NULL;
pPort->dwJobIdPhysics=0;
return false;
}
// CloseHandle(hPrinter);
}
else
{
_tcscpy(s,_T("打开物理打印机:"));
_tcscat(s,pPort->sPrinterPhysics);
_tcscat(s,_T("失败!,无法开始文档!"));
TCHAR s1[MAX_PATH];
_tcscat(s,formatLastError(s1));
::Error(s);
pPort->hPrinterPhysics=NULL;
pPort->dwJobIdPhysics=0;
return false;
}
//创建代理文档:
//If output file exists: try to delete
if(FileExists(filepath))
DeleteFile(filepath);
pPort->hFile=::CreateFile(
filepath,
GENERIC_WRITE,
0, //dont share the file
NULL, //SECURITY_ATTRIBUTES --> Handle cannot be inherited
CREATE_NEW,
FILE_ATTRIBUTE_NORMAL,
NULL); //no template file
if(pPort->hFile==INVALID_HANDLE_VALUE)//创建代理文档失败:
{
CloseHandle(pPort->hPrinterPhysics);
pPort->hPrinterPhysics=NULL;
pPort->dwJobIdPhysics=0;
//could not open file
pPort->hFile=0;
HANDLE hPrinter;
if(OpenPrinter(pPrinterName,&hPrinter,NULL))
{
SetJob(
hPrinter,
JobId,
0,
NULL,
JOB_CONTROL_RESTART);
SetJob(
hPrinter,
JobId,
0,
NULL,
JOB_CONTROL_PAUSE);
CloseHandle(hPrinter);
}
_tcscpy(s,_T("创建代理文档:"));
_tcscat(s,filepath);
_tcscat(s,_T("失败,"));
TCHAR s1[MAX_PATH];
_tcscat(s,formatLastError(s1));
::Error(s,pPort->sPrinterPhysics,filepath);
return FALSE;
}
else//创建代理文档成功:
{
_tcscpy(s,_T("创建代理文档和代理任务:"));
_tcscat(s,filepath);
_tcscat(s,_T("成功,任务号:"));
TCHAR s1[10];
_tcscat(s,_ultot(JobId,s1,10));
::Debug(s,pPort->sPrinterPhysics,filepath);
//file successfully opened
_tcscpy(pPort->sCurDocument,sDocName);
_tcscpy(pPort->sPrinterLocalDirectory,pPrinterName);
pPort->dwStatus|=PS_STARTDOC;
pPort->dwJobID=JobId;
}
return TRUE;
}
BOOL WINAPI MyWritePort(
HANDLE hPort,
LPBYTE pBuffer,
DWORD cbBuf,
LPDWORD pcbWritten)
{
::Debug(_T("执行顺序5:MyWritePort"));
CAutoLocker a;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -