Leaked source code of windows server 2003
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.

403 lines
12 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. tx_thrd.c
  5. Abstract:
  6. This module implements MMR->MR and MMR->MH conversion in a separate thread.
  7. Author:
  8. Rafael Lisitsa (RafaelL) 14-Aug-1996
  9. Revision History:
  10. --*/
  11. #define USE_DEBUG_CONTEXT DEBUG_CONTEXT_T30_MAIN
  12. #include "prep.h"
  13. #include "efaxcb.h"
  14. #include "t30.h"
  15. #include "hdlc.h"
  16. #include "debug.h"
  17. #include "tiff.h"
  18. #include "glbproto.h"
  19. #include "t30gl.h"
  20. // Don't want to limit time to transmit page
  21. #define WAIT_FOR_NEXT_STRIP_TX_TIMEOUT INFINITE
  22. // Max size for converted page
  23. #define MAX_CONVERTED_SIZE 3000000
  24. DWORD
  25. TiffConvertThread
  26. (
  27. PThrdGlbl pTG
  28. )
  29. {
  30. DWORD tiffCompression = pTG->TiffConvertThreadParams.tiffCompression;
  31. BOOL NegotHiRes = pTG->TiffConvertThreadParams.HiRes;
  32. BOOL SrcHiRes = pTG->SrcHiRes;
  33. char OutFileName[_MAX_FNAME];
  34. HANDLE OutFileHandle;
  35. DWORD *lpdwOutputBuffer = NULL;
  36. DWORD dwBytesWritten;
  37. DWORD dwSizeOutputBuffer = 500000;
  38. DWORD dwUsedSizeOutputBuffer;
  39. DWORD StripDataSize;
  40. DWORD NumHandles=2;
  41. HANDLE HandlesArray[2];
  42. DWORD WaitResult;
  43. DWORD RetCode = FALSE;
  44. BOOL fOutFileNeedsBeClosed = 0;
  45. BOOL fResScan = 0;
  46. DEBUG_FUNCTION_NAME(_T("TiffConvertThread"));
  47. HandlesArray[0] = pTG->AbortReqEvent;
  48. HandlesArray[1] = pTG->ThrdSignal;
  49. lpdwOutputBuffer = (DWORD *) VirtualAlloc(
  50. NULL,
  51. dwSizeOutputBuffer,
  52. MEM_COMMIT,
  53. PAGE_READWRITE
  54. );
  55. if (! lpdwOutputBuffer)
  56. {
  57. DebugPrintEx(DEBUG_ERR, "lpdwOutputBuffer can't VirtualAlloc");
  58. goto l_exit;
  59. }
  60. //
  61. // Set the appropriate PRTY for this thread
  62. // I/O threads run at 15. TIFF - at 9...11
  63. //
  64. DebugPrintEx( DEBUG_MSG,
  65. "NegotHiRes=%d SrcHiRes=%d Started",
  66. NegotHiRes,
  67. SrcHiRes);
  68. if (! SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_HIGHEST) )
  69. {
  70. DebugPrintEx( DEBUG_ERR,
  71. "SetThreadPriority HIGHEST failed le=%x",
  72. GetLastError() );
  73. goto l_exit;
  74. }
  75. // need test below to make sure that pTG is still valid
  76. if (pTG->ReqTerminate)
  77. {
  78. goto l_exit;
  79. }
  80. //
  81. // TIFF file was already opened in FaxDevSendA
  82. // in order to get the YResolution tag to negotiate resolution.
  83. //
  84. pTG->CurrentOut = 1;
  85. //
  86. // loop thru all pages
  87. //
  88. do
  89. {
  90. pTG->fTiffPageDone = 0;
  91. _fmemcpy (OutFileName, gT30.TmpDirectory, gT30.dwLengthTmpDirectory);
  92. _fmemcpy (&OutFileName[gT30.dwLengthTmpDirectory], pTG->TiffConvertThreadParams.lpszLineID, 8);
  93. sprintf( &OutFileName[gT30.dwLengthTmpDirectory+8], ".%03d", pTG->CurrentOut);
  94. if ( ( OutFileHandle = CreateFileA( OutFileName,
  95. GENERIC_WRITE,
  96. FILE_SHARE_READ,
  97. NULL,
  98. CREATE_ALWAYS,
  99. 0,
  100. NULL) ) == INVALID_HANDLE_VALUE )
  101. {
  102. DebugPrintEx( DEBUG_ERR,
  103. "ec: %lx CREATING file %s",
  104. GetLastError(),
  105. OutFileName);
  106. goto l_exit;
  107. }
  108. fOutFileNeedsBeClosed = 1;
  109. DebugPrintEx( DEBUG_MSG,
  110. "Page %d started",
  111. pTG->CurrentOut);
  112. if (! TiffSeekToPage( pTG->Inst.hfile, pTG->CurrentOut, FILLORDER_LSB2MSB ) )
  113. {
  114. DebugPrintEx(DEBUG_ERR, "seeking to page");
  115. goto l_exit;
  116. }
  117. else
  118. {
  119. DebugPrintEx(DEBUG_MSG, "TIFF_TX: Tiff seeking to page -OK");
  120. }
  121. //
  122. // check the current page dimensions. Add memory if needed.
  123. //
  124. TiffGetCurrentPageData( pTG->Inst.hfile,
  125. NULL,
  126. &StripDataSize,
  127. NULL,
  128. NULL
  129. );
  130. if (StripDataSize > 1500000)
  131. {
  132. DebugPrintEx( DEBUG_ERR,
  133. "Tiff CONVERTING %d page StripSize = %d",
  134. pTG->CurrentOut,
  135. StripDataSize);
  136. goto l_exit;
  137. }
  138. // convert-reallocate loop
  139. do
  140. {
  141. dwUsedSizeOutputBuffer = dwSizeOutputBuffer;
  142. if (tiffCompression == TIFF_COMPRESSION_MR)
  143. {
  144. if (NegotHiRes == SrcHiRes)
  145. {
  146. fResScan = ConvMmrPageToMrSameRes ( pTG->Inst.hfile,
  147. lpdwOutputBuffer,
  148. &dwUsedSizeOutputBuffer,
  149. NegotHiRes);
  150. }
  151. else
  152. {
  153. fResScan = ConvMmrPageHiResToMrLoRes ( pTG->Inst.hfile,
  154. lpdwOutputBuffer,
  155. &dwUsedSizeOutputBuffer);
  156. }
  157. }
  158. else
  159. {
  160. fResScan = ConvMmrPageToMh ( pTG->Inst.hfile,
  161. lpdwOutputBuffer,
  162. &dwUsedSizeOutputBuffer,
  163. NegotHiRes,
  164. SrcHiRes);
  165. }
  166. if (!fResScan)
  167. {
  168. DWORD dwLastError = GetLastError();
  169. if ((dwLastError==ERROR_INSUFFICIENT_BUFFER) && (dwSizeOutputBuffer < MAX_CONVERTED_SIZE))
  170. {
  171. // Buffer was too small, reallocate bigger buffer
  172. if (!VirtualFree(lpdwOutputBuffer, 0 , MEM_RELEASE))
  173. {
  174. DebugPrintEx(DEBUG_ERR, "VirtualFree failed, LE=%d", GetLastError());
  175. goto l_exit;
  176. }
  177. lpdwOutputBuffer = NULL;
  178. dwSizeOutputBuffer += 500000;
  179. DebugPrintEx(DEBUG_MSG, "CONVERTING %d page, LE=%d, reallocating %d bytes",
  180. pTG->CurrentOut, dwLastError, dwSizeOutputBuffer);
  181. lpdwOutputBuffer = (DWORD *) VirtualAlloc(
  182. NULL,
  183. dwSizeOutputBuffer,
  184. MEM_COMMIT,
  185. PAGE_READWRITE
  186. );
  187. if (! lpdwOutputBuffer)
  188. {
  189. DebugPrintEx( DEBUG_ERR,
  190. "lpdwOutputBuffer can't VirtualAlloc %d",
  191. dwSizeOutputBuffer);
  192. goto l_exit;
  193. }
  194. }
  195. else
  196. {
  197. DebugPrintEx(DEBUG_ERR, "CONVERTING %d page, LE=%d", pTG->CurrentOut, dwLastError);
  198. goto l_exit;
  199. }
  200. }
  201. } while (!fResScan);
  202. if ( ( ! WriteFile(OutFileHandle, (BYTE *) lpdwOutputBuffer, dwUsedSizeOutputBuffer, &dwBytesWritten, NULL) ) ||
  203. (dwUsedSizeOutputBuffer != dwBytesWritten ) )
  204. {
  205. DebugPrintEx(DEBUG_ERR, "Tiff writing file %s", OutFileName);
  206. goto l_exit;
  207. }
  208. if ( ! CloseHandle(OutFileHandle) )
  209. {
  210. fOutFileNeedsBeClosed = 0;
  211. DebugPrintEx(DEBUG_ERR, "Tiff closing file %s", OutFileName);
  212. goto l_exit;
  213. }
  214. fOutFileNeedsBeClosed = 0;
  215. pTG->fTiffPageDone = 1;
  216. if (!SetEvent(pTG->FirstPageReadyTxSignal))
  217. {
  218. DebugPrintEx( DEBUG_ERR,
  219. "SetEvent(0x%lx) returns failure code: %ld",
  220. (ULONG_PTR)pTG->FirstPageReadyTxSignal,
  221. (long) GetLastError());
  222. RetCode = FALSE;
  223. goto l_exit;
  224. }
  225. DebugPrintEx( DEBUG_MSG,
  226. "Done page %d size=%d",
  227. pTG->CurrentOut,
  228. dwUsedSizeOutputBuffer);
  229. if (!pTG->FirstOut)
  230. {
  231. pTG->FirstOut = 1;
  232. }
  233. pTG->LastOut++;
  234. //
  235. // check to see if we are done
  236. //
  237. if (pTG->LastOut >= pTG->TiffInfo.PageCount)
  238. {
  239. DebugPrintEx( DEBUG_MSG,
  240. "Done whole document Last page %d size=%d",
  241. pTG->CurrentOut,
  242. dwUsedSizeOutputBuffer);
  243. pTG->fTiffDocumentDone = 1;
  244. goto good_exit;
  245. }
  246. //
  247. // we want to maintain 2 pages ahead
  248. //
  249. if (pTG->LastOut - pTG->CurrentIn >= 2)
  250. {
  251. WaitResult = WaitForMultipleObjects(NumHandles, HandlesArray, FALSE, WAIT_FOR_NEXT_STRIP_TX_TIMEOUT);
  252. if (WaitResult == WAIT_TIMEOUT)
  253. {
  254. DebugPrintEx(DEBUG_ERR, "WaitForMultipleObjects TIMEOUT");
  255. goto l_exit;
  256. }
  257. if (WaitResult == WAIT_FAILED)
  258. {
  259. DebugPrintEx( DEBUG_ERR,
  260. "WaitForMultipleObjects FAILED le=%lx",
  261. GetLastError());
  262. }
  263. if (pTG->ReqTerminate)
  264. {
  265. DebugPrintEx(DEBUG_MSG,"Received TERMINATE request");
  266. goto good_exit;
  267. }
  268. else if (pTG->ReqStartNewPage)
  269. {
  270. DebugPrintEx(DEBUG_MSG,"Received START NEW PAGE request");
  271. pTG->AckStartNewPage = 1;
  272. pTG->ReqStartNewPage = 0;
  273. }
  274. else
  275. {
  276. DebugPrintEx(DEBUG_ERR,"Received WRONG request");
  277. WaitResult = WaitForMultipleObjects(NumHandles, HandlesArray, FALSE, WAIT_FOR_NEXT_STRIP_TX_TIMEOUT);
  278. if (WaitResult == WAIT_TIMEOUT)
  279. {
  280. DebugPrintEx(DEBUG_ERR,"WaitForMultipleObjects TIMEOUT");
  281. goto l_exit;
  282. }
  283. if (WaitResult == WAIT_FAILED)
  284. {
  285. DebugPrintEx( DEBUG_ERR,
  286. "WaitForMultipleObjects FAILED le=%lx",
  287. GetLastError());
  288. }
  289. }
  290. }
  291. pTG->CurrentOut++;
  292. DebugPrintEx(DEBUG_MSG,"Start page %d", pTG->CurrentOut);
  293. }
  294. while (1);
  295. good_exit:
  296. if (pTG->fTiffOpenOrCreated)
  297. {
  298. TiffClose( pTG->Inst.hfile);
  299. pTG->fTiffOpenOrCreated = 0;
  300. }
  301. RetCode = TRUE;
  302. l_exit:
  303. if (fOutFileNeedsBeClosed)
  304. {
  305. CloseHandle(OutFileHandle);
  306. }
  307. if (lpdwOutputBuffer)
  308. {
  309. VirtualFree(lpdwOutputBuffer, 0 , MEM_RELEASE);
  310. // Nothing to do if it fails...
  311. lpdwOutputBuffer = NULL;
  312. }
  313. pTG->AckTerminate = 1;
  314. pTG->fOkToResetAbortReqEvent = 1;
  315. if (!SetEvent(pTG->ThrdAckTerminateSignal))
  316. {
  317. DebugPrintEx( DEBUG_ERR,
  318. "SetEvent(0x%lx) returns failure code: %ld",
  319. (ULONG_PTR)pTG->ThrdAckTerminateSignal,
  320. (long) GetLastError());
  321. RetCode = FALSE;
  322. }
  323. if (!SetEvent(pTG->FirstPageReadyTxSignal))
  324. {
  325. DebugPrintEx( DEBUG_ERR,
  326. "SetEvent(0x%lx) returns failure code: %ld",
  327. (ULONG_PTR)pTG->FirstPageReadyTxSignal,
  328. (long) GetLastError());
  329. RetCode = FALSE;
  330. }
  331. DebugPrintEx(DEBUG_MSG,"EXITs");
  332. return (RetCode);
  333. }