#include "faxrtp.h" #pragma hdrstop LPCTSTR PrintPlatforms[] = { TEXT("Windows NT x86"), TEXT("Windows NT R4000"), TEXT("Windows NT Alpha_AXP"), TEXT("Windows NT PowerPC") }; BOOL IsPrinterFaxPrinter( LPCTSTR PrinterName ) /*++ Routine Description: Determines if a printer is a fax printer. Arguments: PrinterName - Name of the printer Return Value: TRUE for success. FALSE for failure. --*/ { HANDLE hPrinter = NULL; PRINTER_DEFAULTS PrinterDefaults; SYSTEM_INFO SystemInfo; DWORD Size; DWORD Rval = FALSE; LPDRIVER_INFO_2 DriverInfo = NULL; PrinterDefaults.pDatatype = NULL; PrinterDefaults.pDevMode = NULL; PrinterDefaults.DesiredAccess = PRINTER_READ; if (!OpenPrinter( (LPWSTR) PrinterName, &hPrinter, &PrinterDefaults )) { DebugPrint(( TEXT("OpenPrinter(%d) failed, ec=%d"), __LINE__, GetLastError() )); return FALSE; } GetSystemInfo( &SystemInfo ); Size = 4096; DriverInfo = (LPDRIVER_INFO_2) MemAlloc( Size ); if (!DriverInfo) { DebugPrint(( TEXT("Memory allocation failed, size=%d"), Size )); goto exit; } Rval = GetPrinterDriver( hPrinter, (LPWSTR) PrintPlatforms[SystemInfo.wProcessorArchitecture], 2, (LPBYTE) DriverInfo, Size, &Size ); if (!Rval) { DebugPrint(( TEXT("GetPrinterDriver() failed, ec=%d"), GetLastError() )); goto exit; } if (_tcscmp( DriverInfo->pName, FAX_DRIVER_NAME ) == 0) { Rval = TRUE; } else { Rval = FALSE; } exit: MemFree( DriverInfo ); ClosePrinter( hPrinter ); return Rval; } BOOL ReadTiffData( HANDLE hTiff, LPBYTE *TiffData, DWORD Width, LPDWORD TiffDataLinesAlloc, DWORD PageNumber ) { DWORD Lines = 0; TiffSeekToPage( hTiff, PageNumber, FILLORDER_LSB2MSB ); TiffUncompressMmrPage( hTiff, (LPDWORD) *TiffData, &Lines ); if (Lines > *TiffDataLinesAlloc) { *TiffDataLinesAlloc = Lines; VirtualFree( *TiffData, 0, MEM_RELEASE ); *TiffData = (LPBYTE) VirtualAlloc( NULL, Lines * (Width / 8), MEM_COMMIT, PAGE_READWRITE ); if (!*TiffData) { return FALSE; } } if (!TiffUncompressMmrPage( hTiff, (LPDWORD) *TiffData, &Lines )) { return FALSE; } return TRUE; } BOOL TiffPrint( LPCTSTR TiffFileName, PTCHAR Printer ) /*++ Routine Description: Prints TIFF file. Arguments: TiffFileName - Name of TIFF file to print Printer - Printer to print to Return Value: TRUE for success, FALSE on error --*/ { TIFF_INFO TiffInfo; HANDLE hTiff; LPBYTE TiffData = NULL; DWORD i; PTCHAR Device; HDC PrinterDC = NULL; INT HorzRes; INT VertRes; INT PrintJobId = 0; DOCINFO DocInfo; BOOL Result = FALSE; BOOL IsFaxPrinter = FALSE; DWORD VertResFactor = 1; struct { BITMAPINFOHEADER bmiHeader; RGBQUAD bmiColors[2]; } SrcBitmapInfo = { { sizeof(BITMAPINFOHEADER), // biSize 0, // biWidth 0, // biHeight 1, // biPlanes 1, // biBitCount BI_RGB, // biCompression 0, // biSizeImage 7874, // biXPelsPerMeter - 200dpi 7874, // biYPelsPerMeter 0, // biClrUsed 0, // biClrImportant }, { { 255, // rgbBlue 255, // rgbGreen 255, // rgbRed 0 // rgbReserved }, { 0, // rgbBlue 0, // rgbGreen 0, // rgbRed 0 // rgbReserved } } }; DocInfo.cbSize = sizeof(DOCINFO); DocInfo.lpszDocName = TiffFileName; DocInfo.lpszOutput = NULL; DocInfo.lpszDatatype = NULL; DocInfo.fwType = 0; hTiff = TiffOpen( (LPWSTR) TiffFileName, &TiffInfo, TRUE, FILLORDER_LSB2MSB ); if ( !hTiff ) { goto exit; } TiffData = (LPBYTE) VirtualAlloc( NULL, MAXVERTBITS * (MAXHORZBITS / 8), MEM_COMMIT, PAGE_READWRITE ); if ( !TiffData ) { goto exit; } if( (Device = _tcstok( Printer, TEXT(","))) ) { if (IsFaxPrinter = IsPrinterFaxPrinter( Device )) { // return TRUE here so we don't try to route it to this printer again goto exit; } else { PrinterDC = CreateDC( TEXT("WINSPOOL"), Device, NULL, NULL ); } } if ( !PrinterDC ) { goto exit; } HorzRes = GetDeviceCaps( PrinterDC, HORZRES ); VertRes = GetDeviceCaps( PrinterDC, VERTRES ); PrintJobId = StartDoc( PrinterDC, &DocInfo ); if (PrintJobId <= 0) { goto exit; } if (TiffInfo.YResolution <= 100) { SrcBitmapInfo.bmiHeader.biYPelsPerMeter /= 2; VertResFactor = 2; } for (i = 0; i < TiffInfo.PageCount; i++) { BOOL ReadOk; DWORD Lines; DWORD StripDataSize; DWORD ImageWidth = TiffInfo.ImageWidth; DWORD ImageHeight = TiffInfo.ImageHeight; DWORD LinesAllocated = MAXVERTBITS; INT DestWidth; INT DestHeight; FLOAT ScaleX; FLOAT ScaleY; FLOAT Scale; ReadOk = ReadTiffData( hTiff, &TiffData, ImageWidth, &LinesAllocated, i + 1 ); if (!ReadOk) { goto exit; } TiffGetCurrentPageData( hTiff, &Lines, &StripDataSize, &ImageWidth, &ImageHeight ); ScaleX = (FLOAT) ImageWidth / (FLOAT) HorzRes; ScaleY = ((FLOAT) ImageHeight * VertResFactor) / (FLOAT) VertRes; Scale = ScaleX > ScaleY ? ScaleX : ScaleY; DestWidth = (int) ((FLOAT) ImageWidth / Scale); DestHeight = (int) (((FLOAT) ImageHeight * VertResFactor) / Scale); SrcBitmapInfo.bmiHeader.biWidth = ImageWidth; // build a top-down DIB SrcBitmapInfo.bmiHeader.biHeight = - (INT) ImageHeight; StartPage( PrinterDC ); StretchDIBits( PrinterDC, 0, 0, DestWidth, DestHeight, 0, 0, ImageWidth, ImageHeight, TiffData, (BITMAPINFO *) &SrcBitmapInfo, DIB_RGB_COLORS, SRCCOPY ); EndPage ( PrinterDC ) ; } EndDoc( PrinterDC ); Result = TRUE; exit: if (hTiff) { TiffClose( hTiff ); } if (TiffData) { VirtualFree( TiffData, 0 , MEM_RELEASE ); } if (PrinterDC && PrintJobId > 0) { EndDoc( PrinterDC ); } if (PrinterDC) { DeleteDC( PrinterDC ); } if (Result) { if (IsFaxPrinter) { FaxLog( FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MIN, 2, MSG_FAX_PRINT_TO_FAX, TiffFileName, Device ); } else { FaxLog( FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MAX, 2, MSG_FAX_PRINT_SUCCESS, TiffFileName, Printer ); } } else { FaxLog( FAXLOG_CATEGORY_INBOUND, FAXLOG_LEVEL_MIN, 3, MSG_FAX_PRINT_FAILED, TiffFileName, Printer, GetLastErrorText(GetLastError()) ); } return Result; }