Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

398 lines
8.7 KiB

  1. #include "faxrtp.h"
  2. #pragma hdrstop
  3. LPCTSTR PrintPlatforms[] =
  4. {
  5. TEXT("Windows NT x86"),
  6. TEXT("Windows NT R4000"),
  7. TEXT("Windows NT Alpha_AXP"),
  8. TEXT("Windows NT PowerPC")
  9. };
  10. BOOL
  11. IsPrinterFaxPrinter(
  12. LPCTSTR PrinterName
  13. )
  14. /*++
  15. Routine Description:
  16. Determines if a printer is a fax printer.
  17. Arguments:
  18. PrinterName - Name of the printer
  19. Return Value:
  20. TRUE for success.
  21. FALSE for failure.
  22. --*/
  23. {
  24. HANDLE hPrinter = NULL;
  25. PRINTER_DEFAULTS PrinterDefaults;
  26. SYSTEM_INFO SystemInfo;
  27. DWORD Size;
  28. DWORD Rval = FALSE;
  29. LPDRIVER_INFO_2 DriverInfo = NULL;
  30. PrinterDefaults.pDatatype = NULL;
  31. PrinterDefaults.pDevMode = NULL;
  32. PrinterDefaults.DesiredAccess = PRINTER_READ;
  33. if (!OpenPrinter( (LPWSTR) PrinterName, &hPrinter, &PrinterDefaults )) {
  34. DebugPrint(( TEXT("OpenPrinter(%d) failed, ec=%d"), __LINE__, GetLastError() ));
  35. return FALSE;
  36. }
  37. GetSystemInfo( &SystemInfo );
  38. Size = 4096;
  39. DriverInfo = (LPDRIVER_INFO_2) MemAlloc( Size );
  40. if (!DriverInfo) {
  41. DebugPrint(( TEXT("Memory allocation failed, size=%d"), Size ));
  42. goto exit;
  43. }
  44. Rval = GetPrinterDriver(
  45. hPrinter,
  46. (LPWSTR) PrintPlatforms[SystemInfo.wProcessorArchitecture],
  47. 2,
  48. (LPBYTE) DriverInfo,
  49. Size,
  50. &Size
  51. );
  52. if (!Rval) {
  53. DebugPrint(( TEXT("GetPrinterDriver() failed, ec=%d"), GetLastError() ));
  54. goto exit;
  55. }
  56. if (_tcscmp( DriverInfo->pName, FAX_DRIVER_NAME ) == 0) {
  57. Rval = TRUE;
  58. } else {
  59. Rval = FALSE;
  60. }
  61. exit:
  62. MemFree( DriverInfo );
  63. ClosePrinter( hPrinter );
  64. return Rval;
  65. }
  66. BOOL
  67. ReadTiffData(
  68. HANDLE hTiff,
  69. LPBYTE *TiffData,
  70. DWORD Width,
  71. LPDWORD TiffDataLinesAlloc,
  72. DWORD PageNumber
  73. )
  74. {
  75. DWORD Lines = 0;
  76. TiffSeekToPage( hTiff, PageNumber, FILLORDER_LSB2MSB );
  77. TiffUncompressMmrPage( hTiff, (LPDWORD) *TiffData, &Lines );
  78. if (Lines > *TiffDataLinesAlloc) {
  79. *TiffDataLinesAlloc = Lines;
  80. VirtualFree( *TiffData, 0, MEM_RELEASE );
  81. *TiffData = (LPBYTE) VirtualAlloc(
  82. NULL,
  83. Lines * (Width / 8),
  84. MEM_COMMIT,
  85. PAGE_READWRITE
  86. );
  87. if (!*TiffData) {
  88. return FALSE;
  89. }
  90. }
  91. if (!TiffUncompressMmrPage( hTiff, (LPDWORD) *TiffData, &Lines )) {
  92. return FALSE;
  93. }
  94. return TRUE;
  95. }
  96. BOOL
  97. TiffPrint(
  98. LPCTSTR TiffFileName,
  99. PTCHAR Printer
  100. )
  101. /*++
  102. Routine Description:
  103. Prints TIFF file.
  104. Arguments:
  105. TiffFileName - Name of TIFF file to print
  106. Printer - Printer to print to
  107. Return Value:
  108. TRUE for success, FALSE on error
  109. --*/
  110. {
  111. TIFF_INFO TiffInfo;
  112. HANDLE hTiff;
  113. LPBYTE TiffData = NULL;
  114. DWORD i;
  115. PTCHAR Device;
  116. HDC PrinterDC = NULL;
  117. INT HorzRes;
  118. INT VertRes;
  119. INT PrintJobId = 0;
  120. DOCINFO DocInfo;
  121. BOOL Result = FALSE;
  122. BOOL IsFaxPrinter = FALSE;
  123. DWORD VertResFactor = 1;
  124. struct {
  125. BITMAPINFOHEADER bmiHeader;
  126. RGBQUAD bmiColors[2];
  127. } SrcBitmapInfo = {
  128. {
  129. sizeof(BITMAPINFOHEADER), // biSize
  130. 0, // biWidth
  131. 0, // biHeight
  132. 1, // biPlanes
  133. 1, // biBitCount
  134. BI_RGB, // biCompression
  135. 0, // biSizeImage
  136. 7874, // biXPelsPerMeter - 200dpi
  137. 7874, // biYPelsPerMeter
  138. 0, // biClrUsed
  139. 0, // biClrImportant
  140. },
  141. {
  142. {
  143. 255, // rgbBlue
  144. 255, // rgbGreen
  145. 255, // rgbRed
  146. 0 // rgbReserved
  147. },
  148. {
  149. 0, // rgbBlue
  150. 0, // rgbGreen
  151. 0, // rgbRed
  152. 0 // rgbReserved
  153. }
  154. }
  155. };
  156. DocInfo.cbSize = sizeof(DOCINFO);
  157. DocInfo.lpszDocName = TiffFileName;
  158. DocInfo.lpszOutput = NULL;
  159. DocInfo.lpszDatatype = NULL;
  160. DocInfo.fwType = 0;
  161. hTiff = TiffOpen(
  162. (LPWSTR) TiffFileName,
  163. &TiffInfo,
  164. TRUE,
  165. FILLORDER_LSB2MSB
  166. );
  167. if ( !hTiff ) {
  168. goto exit;
  169. }
  170. TiffData = (LPBYTE) VirtualAlloc(
  171. NULL,
  172. MAXVERTBITS * (MAXHORZBITS / 8),
  173. MEM_COMMIT,
  174. PAGE_READWRITE
  175. );
  176. if ( !TiffData ) {
  177. goto exit;
  178. }
  179. if( (Device = _tcstok( Printer, TEXT(","))) ) {
  180. if (IsFaxPrinter = IsPrinterFaxPrinter( Device )) {
  181. // return TRUE here so we don't try to route it to this printer again
  182. goto exit;
  183. } else {
  184. PrinterDC = CreateDC( TEXT("WINSPOOL"), Device, NULL, NULL );
  185. }
  186. }
  187. if ( !PrinterDC ) {
  188. goto exit;
  189. }
  190. HorzRes = GetDeviceCaps( PrinterDC, HORZRES );
  191. VertRes = GetDeviceCaps( PrinterDC, VERTRES );
  192. PrintJobId = StartDoc( PrinterDC, &DocInfo );
  193. if (PrintJobId <= 0) {
  194. goto exit;
  195. }
  196. if (TiffInfo.YResolution <= 100) {
  197. SrcBitmapInfo.bmiHeader.biYPelsPerMeter /= 2;
  198. VertResFactor = 2;
  199. }
  200. for (i = 0; i < TiffInfo.PageCount; i++)
  201. {
  202. BOOL ReadOk;
  203. DWORD Lines;
  204. DWORD StripDataSize;
  205. DWORD ImageWidth = TiffInfo.ImageWidth;
  206. DWORD ImageHeight = TiffInfo.ImageHeight;
  207. DWORD LinesAllocated = MAXVERTBITS;
  208. INT DestWidth;
  209. INT DestHeight;
  210. FLOAT ScaleX;
  211. FLOAT ScaleY;
  212. FLOAT Scale;
  213. ReadOk = ReadTiffData(
  214. hTiff,
  215. &TiffData,
  216. ImageWidth,
  217. &LinesAllocated,
  218. i + 1
  219. );
  220. if (!ReadOk) {
  221. goto exit;
  222. }
  223. TiffGetCurrentPageData(
  224. hTiff,
  225. &Lines,
  226. &StripDataSize,
  227. &ImageWidth,
  228. &ImageHeight
  229. );
  230. ScaleX = (FLOAT) ImageWidth / (FLOAT) HorzRes;
  231. ScaleY = ((FLOAT) ImageHeight * VertResFactor) / (FLOAT) VertRes;
  232. Scale = ScaleX > ScaleY ? ScaleX : ScaleY;
  233. DestWidth = (int) ((FLOAT) ImageWidth / Scale);
  234. DestHeight = (int) (((FLOAT) ImageHeight * VertResFactor) / Scale);
  235. SrcBitmapInfo.bmiHeader.biWidth = ImageWidth;
  236. // build a top-down DIB
  237. SrcBitmapInfo.bmiHeader.biHeight = - (INT) ImageHeight;
  238. StartPage( PrinterDC );
  239. StretchDIBits(
  240. PrinterDC,
  241. 0,
  242. 0,
  243. DestWidth,
  244. DestHeight,
  245. 0,
  246. 0,
  247. ImageWidth,
  248. ImageHeight,
  249. TiffData,
  250. (BITMAPINFO *) &SrcBitmapInfo,
  251. DIB_RGB_COLORS,
  252. SRCCOPY
  253. );
  254. EndPage ( PrinterDC ) ;
  255. }
  256. EndDoc( PrinterDC );
  257. Result = TRUE;
  258. exit:
  259. if (hTiff) {
  260. TiffClose( hTiff );
  261. }
  262. if (TiffData) {
  263. VirtualFree( TiffData, 0 , MEM_RELEASE );
  264. }
  265. if (PrinterDC && PrintJobId > 0) {
  266. EndDoc( PrinterDC );
  267. }
  268. if (PrinterDC) {
  269. DeleteDC( PrinterDC );
  270. }
  271. if (Result) {
  272. if (IsFaxPrinter) {
  273. FaxLog(
  274. FAXLOG_CATEGORY_INBOUND,
  275. FAXLOG_LEVEL_MIN,
  276. 2,
  277. MSG_FAX_PRINT_TO_FAX,
  278. TiffFileName,
  279. Device
  280. );
  281. } else {
  282. FaxLog(
  283. FAXLOG_CATEGORY_INBOUND,
  284. FAXLOG_LEVEL_MAX,
  285. 2,
  286. MSG_FAX_PRINT_SUCCESS,
  287. TiffFileName,
  288. Printer
  289. );
  290. }
  291. } else {
  292. FaxLog(
  293. FAXLOG_CATEGORY_INBOUND,
  294. FAXLOG_LEVEL_MIN,
  295. 3,
  296. MSG_FAX_PRINT_FAILED,
  297. TiffFileName,
  298. Printer,
  299. GetLastErrorText(GetLastError())
  300. );
  301. }
  302. return Result;
  303. }