⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monitor.cpp

📁 打印机监视器
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// 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 + -