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

📄 prspoolerdatafile.cpp

📁 虚拟打印机
💻 CPP
字号:
/* * prspoolerdatafile.cpp *   Copyright (C) 2006 Michael H. Overlin   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA      Contact at poster_printer@yahoo.com */// 6/25 DEBUG / FIX DONT SAVE A SEP COPY OF TARGET PRINTER DEVMODE, SINCE WE ARE TOO LAZY// TO DO THIS PROPERLY FOR EACH PAGE AS NEEDED#include "prspoolerdatafile.h"#include "buffer.h"#include "devmode.h"#include "printResizerCommon.h"#include "renderpages.h"#include <windows.h>static const DWORD PRSPOOLERDATAFILE_VERSION = 0x100;#define PRSPOOLERDATAFILE_MAGIC				{ 'P', 'R', 'S', 'P', 'O', 'O', 'L', 'E', 'R', 'D', 'A', 'T', 'A', 'F', 'I', 'L', 'E' }// ********************************************************************// **  MODULE PRIVATE TYPES  *****************************************// ********************************************************************struct PRDataFileHeader {	char acMagic[17];	DWORD dwVersion;	BOOL operator ==(const PRDataFileHeader& prdfh) const { return memcmp(this, &prdfh, sizeof(*this)) == 0; }	BOOL operator !=(const PRDataFileHeader& prdfh) const { return ! ( *this == prdfh ); }};struct SplFileIterator {	DWORD dwSize;	DWORD dwOffset;	union {		PCBYTE pb;		PCSPL_HEADER psplheader;		PCSMR psmr;		PCSMR_PAGE psmrpage;		PCSMR_DEVMODE psmrdm;	};	SplFileIterator(IN const MyFileMap& mfm, IN DWORD dwOffset) ;	BOOL Next(void) ;};// ********************************************************************// **  MODULE PRIVATE GLOBALS  ****************************************// ********************************************************************static const PRDataFileHeader g_prdfHeader = { PRSPOOLERDATAFILE_MAGIC, PRSPOOLERDATAFILE_VERSION };static const ::MarginSpec g_msOriginal = { 0, 0, 0, 0, 0, 0 };// ********************************************************************// **  MODULE PRIVATE PROTOTYPES  *************************************// ********************************************************************BOOL MyWriteFile(HANDLE hFile, LPCVOID lpData, DWORD dwcData)  ;BOOL MyWriteFile(HANDLE hFile, LPCTSTR lptstr) ;// ********************************************************************// **  MODULE PUBLIC ROUTINES  ****************************************// ********************************************************************BOOL PRSpoolerDataFile::WriteUserInterfaceData(const tstring& tstrFileName, LPCTSTR lptstrPrinterName, 											   PCEXTDEVMODE pextdm) {	BOOL bRetValue = FALSE;	HANDLE hFile = ::CreateFile( 		tstrFileName.c_str(),		GENERIC_WRITE,           		FILE_SHARE_READ,        		NULL,                   		CREATE_ALWAYS,          		FILE_ATTRIBUTE_NORMAL,  		NULL                     		);	if (hFile != INVALID_HANDLE_VALUE) {		try {			if (::MyWriteFile(hFile, &g_prdfHeader, sizeof(g_prdfHeader))) {				if (::MyWriteFile(hFile, lptstrPrinterName)) {					if (::MyWriteFile(hFile, (LPCVOID) pextdm, (DWORD) EXTDM_Sizeof())) {						bRetValue = TRUE;					}				}			}			::CloseHandle(hFile);		} catch(...) {			bRetValue = FALSE;			::CloseHandle(hFile);			::DeleteFile(tstrFileName.c_str());		}	}	return bRetValue;}BOOL PRSpoolerDataFile::WritePrintProcessorData(const tstring& tstrFileName, HANDLE hPrinter) {	BOOL bRetValue = FALSE;	HANDLE hAppend = CreateFile(		tstrFileName.c_str(),		FILE_APPEND_DATA,   		FILE_SHARE_READ,    		NULL,               		OPEN_EXISTING,        		FILE_ATTRIBUTE_NORMAL, 		NULL		);                 	if (hAppend != INVALID_HANDLE_VALUE) {		try {			const DWORD dwcBuff = (DWORD) 1 << 16;			Buffer buff((DWORD) 1 << 16);			BOOL bIOError = FALSE;			DWORD dwcRead = 0;			do {				dwcRead = 1;				BOOL b = ReadPrinter(hPrinter, buff.GetPtr(), buff.GetSize(), &dwcRead);				if (!b && dwcRead != 0) { // IT MAY CONSIDER A NO DATA CONDITION TO BE A FAIL					bIOError = TRUE;					break;				}				if (dwcRead != 0) {					if (! MyWriteFile(hAppend, buff.GetPtr(), dwcRead)) {						bIOError = TRUE;						break;					}				}			} while(dwcRead != 0);			CloseHandle(hAppend);			bRetValue = ! bIOError;		} catch(...) {			bRetValue  = FALSE;			CloseHandle(hAppend);		}	}	return bRetValue;}// ***// *** PRSpoolerDataFile// ***PRSpoolerDataFile::PRSpoolerDataFile(void) {	// NOTHING TO DO}PRSpoolerDataFile::~PRSpoolerDataFile() {	// 6/2	if (this->IsOpen()) {		this->Close();	}	// FIX - MAYBE THIS SHOULD JUST CLOSE IF STILL OPEN	ASSERT(!IsOpen());	ASSERT(this->m_vdmPages.size() == 0);	ASSERT(m_tstrFileName.empty());}BOOL PRSpoolerDataFile::Open(const tstring& tstrFileName) {	BOOL bRetValue = FALSE;	ASSERT(!this->IsOpen());	ASSERT(m_vpi.size() == 0);	ASSERT(m_vdmPages.size() == 0);	ASSERT(m_tstrFileName.empty());	// DEBUG / FIX	//::DebugBreak();	m_tstrFileName = tstrFileName;	try {		BOOL bIOError = FALSE;		if (!m_mfm.Open(tstrFileName)) {			bIOError = TRUE;		}		DWORD dwOffset = 0;		if (!bIOError) {			const PRDataFileHeader header = * (const PRDataFileHeader *) m_mfm.GetOffsetPtr(dwOffset);			dwOffset += sizeof(header);			if (header != g_prdfHeader) {				bIOError = TRUE;			}		}		if (!bIOError) {			m_tstrPrinterName = (LPTSTR) m_mfm.GetOffsetPtr(dwOffset);			dwOffset += (DWORD) ::StringBufferSize( m_tstrPrinterName.c_str() );			// DEBUG / FIX EVENTUALLY MAY NEED SOME KIND OF CONVERT DEVMODE CALL HERE, IF VERSION CHANGES			PCEXTDEVMODE pextdmRead = (PCEXTDEVMODE) m_mfm.GetOffsetPtr(dwOffset);			dwOffset += ::DM_GetTotalSize( (PCDEVMODE) pextdmRead);			{				PEXTDEVMODE pextdmTemp = (PEXTDEVMODE) DM_Duplicate( (PCDEVMODE) (PVOID) pextdmRead );				m_vdmPages.push_back(pextdmTemp);			}			SplFileIterator iter(m_mfm, dwOffset);			if (iter.psplheader->SIGNATURE != SPLMETA_SIGNATURE) {				bIOError = TRUE;			}			if (!bIOError) {				m_tstrJobName = (LPCTSTR) (iter.pb + iter.psplheader->offDocumentName);				uint nPages = 0;				while(iter.Next()) {					DWORD dwType = iter.psmr->iType;					switch(dwType) {					case SRT_PAGE: {						PageInfo pi;						pi.dwOffset = iter.dwOffset;						pi.uiDMIndex = (uint) m_vdmPages.size() - 1;						m_vpi.push_back(pi);					} break;					case SRT_DEVMODE: {						::PCSMR_DEVMODE p = iter.psmrdm;						PDEVMODE pdmTemp = DM_Duplicate( (PCDEVMODE) p->DEVMODEData);						m_vdmPages.push_back( (PEXTDEVMODE) pdmTemp );						// DEVMODE RECORD SEEMS TO FOLLOW THE EMF						if (m_vpi.size() != 0) {							uint uiPage = (uint) m_vpi.size() - 1;							PageInfo& pi = m_vpi[uiPage];							pi.uiDMIndex = (uint) m_vdmPages.size() - 1;						}					} break;					default:						break;					}				}			}		}		bRetValue = ! bIOError;	} catch(...) {		bRetValue = FALSE;	}	return bRetValue;}void PRSpoolerDataFile::Close(void) {	ASSERT(IsOpen());	m_vpi.clear();	m_tstrJobName.erase();	for(uint k = 0; k < m_vdmPages.size(); ++k) {		free(m_vdmPages[k]);	}	m_vdmPages.clear();	m_mfm.Close();	if (! m_tstrFileName.empty()) {		::DeleteFile(m_tstrFileName.c_str());		m_tstrFileName.erase();	}}const tstring &PRSpoolerDataFile::GetJobName(void) const {	ASSERT(IsOpen());	return m_tstrJobName;}const tstring & PRSpoolerDataFile::GetPrinterName(void) const {	ASSERT(IsOpen());	return m_tstrPrinterName;}uint PRSpoolerDataFile::GetPageCount(void) const {	ASSERT(IsOpen());	uint ui = (uint) m_vpi.size();	return ui;}HENHMETAFILE PRSpoolerDataFile::GetPageEMF(uint uiPage) const {	HENHMETAFILE hMeta = NULL;	ASSERT(IsOpen());	ASSERT(uiPage < m_vpi.size());	try {		PageInfo pi = m_vpi[uiPage];		PCSMR_PAGE psmrpage = (PCSMR_PAGE) m_mfm.GetOffsetPtr(pi.dwOffset);		hMeta = SetEnhMetaFileBits(psmrpage->smr.nSize, psmrpage->EMFData);	} catch( ... ) {		// RETURN FAILURE CODE OF NULL	}	return hMeta;}BOOL PRSpoolerDataFile::GetSourcePageSpec(IN uint uiPage, OUT ::PageSpec& ps) const {	BOOL bRetValue = FALSE;	const tstring& tstrPrinterName = this->GetPrinterName();	PCDEVMODE pdm = (PCDEVMODE) this->GetPRDevMode(uiPage);	if (pdm != NULL) {		::PageSpec psTemp;		if (::GetPageSpec(psTemp, g_msOriginal, pdm, tstrPrinterName.c_str(), FALSE, FALSE)) {			ps = psTemp;			bRetValue = TRUE;		}	}	return bRetValue;}PDEVMODE PRSpoolerDataFile::GetTargetPrinter(IN uint uiPage, OUT tstring& tstrTargetPrinterName) const {	PDEVMODE pdmRetValue;	PCEXTDEVMODE pextdm = GetPRDevMode(uiPage);	LPCTSTR lptstrTargetPrinterName = ::EXTDM_GetTargetPrinterName(pextdm);	PCDEVMODE pdmTarget = ::EXTDM_GetTargetPrinterDevMode(pextdm);	if (pdmTarget != NULL) {		pdmRetValue = ::DM_Duplicate(pdmTarget);		if (pdmRetValue != NULL) {			tstrTargetPrinterName = lptstrTargetPrinterName;		}	}	return pdmRetValue;}BOOL PRSpoolerDataFile::GetResizedRenderSpec(IN uint uiPage, OUT ::RenderSpec& rs) const {	// NO RENDERSPEC INFO STORED IN OUR SPOOLER DATA FILE CURRENTLY	return FALSE;}//BOOL PRSpoolerDataFile::GetSourceSelection(IN uint uiPage, OUT ::RECTD& rdSourceSelection_Inches) const {//	return FALSE;//}BOOL PRSpoolerDataFile::GetResizedSourceSpec(IN uint uiPage, OUT ::SourceSpec& ssResized) const {	// NO SOURCESPEC INFO STORED IN OUR SPOOLER DATA FILE CURRENTLY	return FALSE;}PCEXTDEVMODE PRSpoolerDataFile::GetPRHeaderDevMode(void) const {	ASSERT(IsOpen());	PCEXTDEVMODE pextdm = m_vdmPages[0];	return pextdm;}PCEXTDEVMODE PRSpoolerDataFile::GetPRDevMode(uint uiPage) const {	ASSERT(IsOpen());	ASSERT(uiPage < m_vpi.size());	PageInfo pi = m_vpi[uiPage];	PCEXTDEVMODE pextdm = m_vdmPages[pi.uiDMIndex];	return pextdm;}// ************************************************************************// **  PRIVATE TO MODULE  ************************************************// ************************************************************************// ***// *** SplFileIterator// ***SplFileIterator::SplFileIterator(IN const MyFileMap& mfm, IN DWORD dwOffset) {	this->dwSize = mfm.GetSize();	ASSERT(dwOffset < this->dwSize);	this->pb = (PCBYTE) mfm.GetBasePtr() + dwOffset;	this->dwOffset = dwOffset;}BOOL SplFileIterator::Next(void) {	BOOL bRetValue = FALSE;	DWORD dwNewOffset;	DWORD dwcInc;	// (SPL FILE HEADER RECORD ALSO STARTS W/SMR, WITH "iType" BEING THE SIGNATURE)	dwcInc = this->psmr->nSize;	if (this->psmr->iType != SPLMETA_SIGNATURE) {		dwcInc += sizeof(SMR);	}	dwNewOffset = this->dwOffset + dwcInc;	if (dwNewOffset < this->dwSize) {		this->dwOffset = dwNewOffset;		this->pb += dwcInc;		if (this->psmr->iType != SRT_PAGE ||			this->psmr->nSize != 0			) {			bRetValue = TRUE;		} 	}	return bRetValue;}// ***// ***  UTILITY ROUTINES// ***BOOL MyWriteFile(HANDLE hFile, LPCVOID lpData, DWORD dwcData) {	BOOL bRetValue = FALSE;	DWORD dwcWritten;	BOOL b = WriteFile(hFile, lpData, dwcData, &dwcWritten, NULL);	if (b && dwcData == dwcWritten) {		bRetValue = TRUE;	}	return bRetValue;}BOOL MyWriteFile(HANDLE hFile, LPCTSTR lptstr) {	DWORD dwCb = (DWORD) ::StringBufferSize(lptstr);	BOOL bRetValue = MyWriteFile(hFile, (LPCVOID) lptstr, dwCb);	return bRetValue;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -