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.

782 lines
28 KiB

  1. /***************************************************************************
  2. Name : RECV.C
  3. Comment : Receiver functions
  4. Revision Log
  5. Date Name Description
  6. -------- ----- ---------------------------------------------------------
  7. ***************************************************************************/
  8. #include "prep.h"
  9. #include <comdevi.h>
  10. #include <faxcodec.h>
  11. #include "efaxcb.h"
  12. //#include "debug.h"
  13. #include "cas.h"
  14. #include "bgt30.h"
  15. //#include "dynload.h"
  16. #include "awg3file.h"
  17. #include "glbproto.h"
  18. #include "t30gl.h"
  19. #define faxTlog(m) DEBUGMSG(ZONE_RECV, m);
  20. #define RINGIGNORE_TIMEOUT 60000L
  21. #define RINGINACTIVITY_TIMEOUT 15000L
  22. BOOL ICommRecvParams(PThrdGlbl pTG, LPBC lpBC)
  23. {
  24. BOOL fLin;
  25. BOOL fRet = FALSE;
  26. BG_CHK(lpBC);
  27. BG_CHK(lpBC->bctype == RECV_PARAMS);
  28. BG_CHK(lpBC->wTotalSize>=sizeof(BC));
  29. BG_CHK(lpBC->wTotalSize<=sizeof(pTG->Inst.RecvParams));
  30. if (pTG->fAbortRequested) {
  31. MyDebugPrint(pTG, LOG_ALL, "ICommRecvParams. got ABORT at %ld", GetTickCount() );
  32. fRet = FALSE;
  33. goto mutexit;
  34. }
  35. if(pTG->Inst.fAbort) // RecvParams
  36. {
  37. fRet = FALSE;
  38. goto mutexit;
  39. }
  40. if(pTG->Inst.state != BEFORE_RECVPARAMS)
  41. {
  42. // this will break if we send EOM...
  43. // then we should go back into RECV_CAPS state
  44. fRet = TRUE;
  45. goto mutexit;
  46. }
  47. _fmemset(&pTG->Inst.RecvParams, 0, sizeof(pTG->Inst.RecvParams));
  48. _fmemcpy(&pTG->Inst.RecvParams, lpBC, min(sizeof(pTG->Inst.RecvParams), lpBC->wTotalSize));
  49. // first try EFAX, then IFAX then G3
  50. // pTG->Inst.fG3 = FALSE;
  51. BG_CHK(lpBC->Std.GroupNum == 0);
  52. BG_CHK(lpBC->Std.GroupLength <= sizeof(BCHDR));
  53. if( lpBC->NSS.GroupNum == GROUPNUM_NSS &&
  54. lpBC->NSS.GroupLength >= sizeof(BCHDR) &&
  55. lpBC->NSS.vMsgProtocol != 0)
  56. {
  57. /***
  58. if(!lpBC->NSS.fBinaryData) // vMsgProtocol != 0 && Binary
  59. {
  60. pTG->Inst.szFile[9]='I'; pTG->Inst.szFile[10]='F'; pTG->Inst.szFile[11]='X';
  61. fLin=TRUE;
  62. }
  63. else
  64. ***/
  65. // on recv don't know if binary files or not, so always assume
  66. {
  67. pTG->Inst.szFile[9]='E'; pTG->Inst.szFile[10]='F'; pTG->Inst.szFile[11]='X';
  68. fLin=TRUE;
  69. }
  70. }
  71. else // not Msg Protocol must be G3
  72. {
  73. BG_CHK(lpBC->NSS.vMsgProtocol == 0);
  74. pTG->Inst.szFile[9]='M'; pTG->Inst.szFile[10]='G'; pTG->Inst.szFile[11]='3';
  75. fLin = FALSE;
  76. }
  77. wsprintf(pTG->Inst.szPath, "%s%s", (LPSTR)pTG->Inst.szFaxDir, (LPSTR)pTG->Inst.szFile);
  78. // make sure we don't have a file already open
  79. pTG->Inst.cbPage = 0;
  80. #ifdef CHK
  81. pTG->Inst.fRecvChecking = FALSE;
  82. #endif // CHK
  83. pTG->Inst.uNumBadPages = 0;
  84. BG_CHK(pTG->Inst.fReceiving || (!pTG->Inst.fReceiving)); ///RSL && uMyListen==2));
  85. pTG->Inst.fReceiving = TRUE; // we now do this in FileT30Answer as well...
  86. // BCtoAWFI(lpBC, &pTG->Inst.awfi);
  87. // WriteFileHeader(pTG->Inst.hfile, &pTG->Inst.awfi, fLin);
  88. pTG->Inst.awfi.fLin = fLin != FALSE;
  89. pTG->Inst.state = RECVDATA_BETWEENPAGES;
  90. fRet = TRUE;
  91. // fall through
  92. mutexit:
  93. return fRet;
  94. }
  95. void ICommGotDisconnect(PThrdGlbl pTG)
  96. {
  97. // faxTlog((SZMOD "GotDisconnect\r\n"));
  98. }
  99. void ICommSetRecvMode(PThrdGlbl pTG, BOOL fECM)
  100. {
  101. // faxTlog((SZMOD "SetRecvMode fECM=%d\r\n", fECM));
  102. }
  103. USHORT ICommGetRecvPageAck(PThrdGlbl pTG, BOOL fSleep)
  104. {
  105. USHORT uRet = 2;
  106. // ENTER_EFAXRUN_MUTEX;
  107. // error == 2
  108. // faxTlog((SZMOD "GetRecvPageAck = %d\r\n", pTG->Inst.uRecvPageAck));
  109. uRet = pTG->Inst.uRecvPageAck;
  110. //mutexit:
  111. //EXIT_EFAXRUN_MUTEX;
  112. return uRet;
  113. }
  114. BOOL ICommPutRecvBuf(PThrdGlbl pTG, LPBUFFER lpbf, SLONG slOffset)
  115. {
  116. /**
  117. slOffset == RECV_STARTBLOCK marks beginning of new block
  118. slOffset == RECV_STARTPAGE marks beginning of new block *and* page
  119. slOffset == RECV_ENDPAGE marks end of page
  120. slOffset == RECV_ENDDOC marks end of document (close file etc.)
  121. (for all above no data supplied -- i.e lpbf == 0)
  122. slOffset == RECV_SEQ means put buffer at current file position
  123. slOffset >= 0 gives the offset in bytes from the last marked position
  124. (beginning of block) to put buffer
  125. pTG->Inst.cbBlockStart is always the file offset of start of current block
  126. pTG->Inst.cbBlockSize and cbPage are only used fro debugging
  127. **/
  128. BOOL fRet = TRUE;
  129. DWORD BytesWritten;
  130. DWORD NumHandles=2;
  131. HANDLE HandlesArray[2];
  132. DWORD WaitResult = WAIT_TIMEOUT;
  133. CHAR Buffer[DECODE_BUFFER_SIZE];
  134. BOOL fEof;
  135. DWORD BytesToRead;
  136. DWORD BytesHaveRead;
  137. DWORD BytesLeft;
  138. HandlesArray[0] = pTG->AbortReqEvent;
  139. switch (slOffset)
  140. {
  141. case RECV_STARTBLOCK:
  142. MyDebugPrint(pTG, LOG_ALL, "ICommPutRecvBuf called. Reason: RECV_STARTBLOCK\r\n");
  143. break;
  144. case RECV_STARTPAGE:
  145. MyDebugPrint(pTG, LOG_ALL, "ICommPutRecvBuf called. Reason: RECV_STARTPAGE\r\n");
  146. break;
  147. case RECV_ENDPAGE:
  148. MyDebugPrint(pTG, LOG_ALL, "ICommPutRecvBuf called. Reason: RECV_ENDPAGE\r\n");
  149. break;
  150. case RECV_ENDDOC:
  151. MyDebugPrint(pTG, LOG_ALL, "ICommPutRecvBuf called. Reason: RECV_ENDDOC\r\n");
  152. break;
  153. default:
  154. break;
  155. }
  156. if(slOffset==RECV_ENDPAGE || slOffset==RECV_ENDDOC)
  157. {
  158. BG_CHK(pTG->Inst.state == RECVDATA_PHASE);
  159. BG_CHK(lpbf == 0);
  160. pTG->Inst.uRecvPageAck = TRUE;
  161. //SetStatus((pTG->Inst.uRecvPageAck ? T30STATR_CONFIRM : T30STATR_REJECT), pTG->Inst.awfi.uNumPages, 0, 0);
  162. //////////// moved to ICommGetRecvPageAck() callback ////////////
  163. // if(pTG->Inst.uModemClass==FAXCLASS1 || pTG->Inst.uModemClass == FAXCLASS0)
  164. // {
  165. // LPFNCHK(lpfnET30ProtRecvPageAck);
  166. // lpfnET30ProtRecvPageAck(pTG->Inst.uRecvPageAck);
  167. // }
  168. // else
  169. //////////// moved to ICommGetRecvPageAck() callback ////////////
  170. #if defined(CL2) || defined(CL2_0)
  171. //////////// moved to ICommGetRecvPageAck() callback ////////////
  172. // if(pTG->Inst.uModemClass==FAXCLASS2 || pTG->Inst.uModemClass==FAXCLASS2_0)
  173. // {
  174. // LPFNCHK(lpfnClass2RecvPageAck);
  175. // lpfnClass2RecvPageAck(pTG->Inst.uRecvPageAck);
  176. // }
  177. ////////////// moved to ICommGetRecvPageAck() callback ////////////
  178. #endif //CL2
  179. //here we need to wait until helper thread finishes with the page
  180. if (! pTG->fPageIsBad) {
  181. MyDebugPrint(pTG, LOG_ALL, "RECV: EOP. Not bad yet. Start waiting for Rx_thrd to finish at %ld\n",
  182. GetTickCount() );
  183. HandlesArray[1] = pTG->ThrdDoneSignal;
  184. if ( ( WaitResult = WaitForMultipleObjects(NumHandles, HandlesArray, FALSE, RX_ACK_THRD_TIMEOUT) ) == WAIT_TIMEOUT) {
  185. pTG->fPageIsBad = 1;
  186. MyDebugPrint(pTG, LOG_ALL, "RECV: ERROR. EOP. Never waked up by Rx_thrd at %ld\n", GetTickCount() );
  187. }
  188. else {
  189. MyDebugPrint(pTG, LOG_ALL, "RECV: EOP. Waked up by Rx_thrd at %ld\n", GetTickCount() );
  190. }
  191. }
  192. if (WaitResult == WAIT_OBJECT_0) {
  193. (MyDebugPrint(pTG, LOG_ALL, "RECV: wait for next page ABORTED at %ld \n", GetTickCount() ) );
  194. if (pTG->InFileHandleNeedsBeClosed) {
  195. CloseHandle(pTG->InFileHandle);
  196. pTG->InFileHandleNeedsBeClosed = 0;
  197. }
  198. return FALSE;
  199. }
  200. //
  201. // If page is good then write it to a TIFF file.
  202. //
  203. if (! pTG->fPageIsBad) {
  204. if ( ! TiffStartPage( (HANDLE) pTG->Inst.hfile ) ) {
  205. MyDebugPrint(pTG, LOG_ERR, "RECV: ERROR TiffStartPage failed\r\n");
  206. if (pTG->InFileHandleNeedsBeClosed) {
  207. CloseHandle(pTG->InFileHandle);
  208. pTG->InFileHandleNeedsBeClosed = 0;
  209. }
  210. return FALSE;
  211. }
  212. if ( SetFilePointer(pTG->InFileHandle, 0, NULL, FILE_BEGIN) == 0xffffffff ) {
  213. MyDebugPrint(pTG, LOG_ERR, "RECV: ERROR SetFilePointer failed le=%ld\r\n", GetLastError() );
  214. if (pTG->InFileHandleNeedsBeClosed) {
  215. CloseHandle(pTG->InFileHandle);
  216. pTG->InFileHandleNeedsBeClosed = 0;
  217. }
  218. return FALSE;
  219. }
  220. fEof = 0;
  221. BytesLeft = pTG->BytesIn;
  222. while (! fEof) {
  223. if (BytesLeft <= DECODE_BUFFER_SIZE) {
  224. BytesToRead = BytesLeft;
  225. fEof = 1;
  226. }
  227. else {
  228. BytesToRead = DECODE_BUFFER_SIZE;
  229. BytesLeft -= DECODE_BUFFER_SIZE;
  230. }
  231. if (! ReadFile(pTG->InFileHandle, Buffer, BytesToRead, &BytesHaveRead, NULL ) ) {
  232. MyDebugPrint(pTG, LOG_ERR, "RECV: ERROR ReadFile failed le=%ld\r\n", GetLastError() );
  233. if (pTG->InFileHandleNeedsBeClosed) {
  234. CloseHandle(pTG->InFileHandle);
  235. pTG->InFileHandleNeedsBeClosed = 0;
  236. }
  237. return FALSE;
  238. }
  239. if (BytesToRead != BytesHaveRead) {
  240. MyDebugPrint(pTG, LOG_ERR, "RECV: ERROR ReadFile have read=%d wanted=%d\n", BytesHaveRead, BytesToRead);
  241. if (pTG->InFileHandleNeedsBeClosed) {
  242. CloseHandle(pTG->InFileHandle);
  243. pTG->InFileHandleNeedsBeClosed = 0;
  244. }
  245. return FALSE;
  246. }
  247. if (! TiffWriteRaw( (HANDLE) pTG->Inst.hfile, Buffer, BytesToRead ) ) {
  248. MyDebugPrint(pTG, LOG_ERR, "RECV: ERROR TiffWriteRaw failed \n");
  249. if (pTG->InFileHandleNeedsBeClosed) {
  250. CloseHandle(pTG->InFileHandle);
  251. pTG->InFileHandleNeedsBeClosed = 0;
  252. }
  253. return FALSE;
  254. }
  255. MyDebugPrint(pTG, LOG_ALL, "RECV: TiffWriteRaw done \n");
  256. }
  257. pTG->PageCount++;
  258. MyDebugPrint(pTG, LOG_ALL, "Calling TiffEndPage page=%d bytes=%d \n", pTG->PageCount, pTG->BytesIn);
  259. if (! TiffEndPage( (HANDLE) pTG->Inst.hfile ) ) {
  260. MyDebugPrint(pTG, LOG_ERR, "RECV: ERROR TiffEndPage failed \n");
  261. if (pTG->InFileHandleNeedsBeClosed) {
  262. CloseHandle(pTG->InFileHandle);
  263. pTG->InFileHandleNeedsBeClosed = 0;
  264. }
  265. return FALSE;
  266. }
  267. }
  268. if (pTG->InFileHandleNeedsBeClosed) {
  269. CloseHandle(pTG->InFileHandle);
  270. pTG->InFileHandleNeedsBeClosed = 0;
  271. }
  272. if(slOffset == RECV_ENDDOC)
  273. {
  274. // if page was bad, mark it so in the return value for this call
  275. // (otherwise EFAXPUMP will not display "above received fax contains
  276. // errors). This is will only work if last page is bad. To be more
  277. // accurate we should count the bad pages and if they are non-zero
  278. // we should mark the recvd document as CALLFAIL.
  279. #if 0
  280. if (glSimulateError && (glSimulateErrorType == SIMULATE_ERROR_RX_IO) ) {
  281. SimulateError( EXCEPTION_ACCESS_VIOLATION);
  282. }
  283. #endif
  284. MyDebugPrint(pTG, LOG_ALL, "Calling TiffClose\r\n");
  285. if ( pTG->fTiffOpenOrCreated ) {
  286. TiffClose( (HANDLE) pTG->Inst.hfile );
  287. pTG->fTiffOpenOrCreated = 0;
  288. }
  289. // request Rx_thrd to terminate itself.
  290. pTG->ReqTerminate = 1;
  291. SetEvent(pTG->ThrdSignal);
  292. pTG->Inst.state = BEFORE_RECVPARAMS;
  293. }
  294. else
  295. pTG->Inst.state = RECVDATA_BETWEENPAGES;
  296. }
  297. else if(slOffset == RECV_STARTPAGE)
  298. {
  299. // Fax Server wants to know when we start RX new page
  300. SignalStatusChange(pTG, FS_RECEIVING);
  301. BG_CHK(pTG->Inst.state == RECVDATA_BETWEENPAGES);
  302. BG_CHK(lpbf == 0);
  303. pTG->Inst.cbPage = 0;
  304. pTG->Inst.cbBlockSize = 0;
  305. pTG->Inst.state = RECVDATA_PHASE;
  306. pTG->Inst.awfi.lDataSize = 0;
  307. // awfi.lNextHeaderOffset here points to current header (starts at ptr to first pageheader in BCtoAWFI)
  308. // awfi.lDataOffset set to point to the actual data. NOT the count DWORD
  309. pTG->Inst.awfi.lDataOffset = pTG->Inst.awfi.lNextHeaderOffset + sizeof(AWG3HEADER) + 4;
  310. pTG->Inst.awfi.uNumPages++;
  311. ///ICommStatus(T30STATR_RECV, pTG->Inst.awfi.uNumPages, 0, 0);
  312. ///lOldRecvCount = 0;
  313. if( pTG->Inst.RecvParams.NSS.vMsgProtocol == 0 && // G3
  314. pTG->Inst.RecvParams.Fax.Encoding != MMR_DATA && // MH or MR only
  315. pTG->Inst.uCopyQualityCheckLevel)
  316. {
  317. // For Recvd T4 checking
  318. BG_CHK((pTG->Inst.RecvParams.Fax.Encoding == MH_DATA) ||
  319. (pTG->Inst.RecvParams.Fax.Encoding == MR_DATA));
  320. BG_CHK(pTG->Inst.RecvParams.Fax.PageWidth <= WIDTH_MAX);
  321. // +++ 4/25/95 JosephJ WARNING -- we could be doing ecm-MH or
  322. // ecm-MR, so we really need to check if we're receiving ECM or
  323. // not. Unfortunately this information is currently not propogated
  324. // back up from T.30 and it's too late to that -- so (HACK)
  325. // we enable receive-checking here, but disable it later
  326. // if we get a RECV_STARTBLOCK or a >=0 lsOffset (later indicates
  327. // a resend. The proper fix for this is to propogate the
  328. // fact that we're doing ecm up from t.30.
  329. }
  330. // seek to right place, write out enough space for header
  331. // and place file ptr in the right place to write data
  332. //
  333. // start Helper thread once per RX session
  334. //
  335. if (!pTG->fTiffThreadCreated) {
  336. USHORT uEnc;
  337. DWORD TiffConvertThreadId;
  338. if (pTG->ModemClass != MODEM_CLASS1) {
  339. if (pTG->Encoding == MR_DATA) {
  340. pTG->TiffConvertThreadParams.tiffCompression = TIFF_COMPRESSION_MR;
  341. }
  342. else {
  343. pTG->TiffConvertThreadParams.tiffCompression = TIFF_COMPRESSION_MH;
  344. }
  345. if (pTG->Resolution & (AWRES_mm080_077 | AWRES_200_200) ) {
  346. pTG->TiffConvertThreadParams.HiRes = 1;
  347. }
  348. else {
  349. pTG->TiffConvertThreadParams.HiRes = 0;
  350. }
  351. }
  352. else {
  353. uEnc = ProtGetRecvEncoding(pTG);
  354. BG_CHK(uEnc==MR_DATA || uEnc==MH_DATA);
  355. if (uEnc == MR_DATA) {
  356. pTG->TiffConvertThreadParams.tiffCompression = TIFF_COMPRESSION_MR;
  357. }
  358. else {
  359. pTG->TiffConvertThreadParams.tiffCompression = TIFF_COMPRESSION_MH;
  360. }
  361. if (pTG->ProtInst.RecvParams.Fax.AwRes & (AWRES_mm080_077 | AWRES_200_200) ) {
  362. pTG->TiffConvertThreadParams.HiRes = 1;
  363. }
  364. else {
  365. pTG->TiffConvertThreadParams.HiRes = 0;
  366. }
  367. }
  368. _fmemcpy (pTG->TiffConvertThreadParams.lpszLineID, pTG->lpszPermanentLineID, 8);
  369. pTG->TiffConvertThreadParams.lpszLineID[8] = 0;
  370. (MyDebugPrint(pTG, LOG_ALL, "RECV: Creating TIFF helper thread comp=%d res=%d at %ld \n",
  371. pTG->TiffConvertThreadParams.tiffCompression,
  372. pTG->TiffConvertThreadParams.HiRes,
  373. GetTickCount() ) );
  374. pTG->hThread = CreateThread(
  375. NULL,
  376. 0,
  377. (LPTHREAD_START_ROUTINE) PageAckThreadSafe,
  378. (LPVOID) pTG,
  379. 0,
  380. &TiffConvertThreadId
  381. );
  382. if (!pTG->hThread) {
  383. (MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> TiffConvertThread create FAILED\r\n"));
  384. return FALSE;
  385. }
  386. pTG->fTiffThreadCreated = 1;
  387. pTG->AckTerminate = 0;
  388. pTG->fOkToResetAbortReqEvent = 0;
  389. if ( (pTG->RecoveryIndex >=0 ) && (pTG->RecoveryIndex < MAX_T30_CONNECT) ) {
  390. T30Recovery[pTG->RecoveryIndex].TiffThreadId = TiffConvertThreadId;
  391. T30Recovery[pTG->RecoveryIndex].CkSum = ComputeCheckSum(
  392. (LPDWORD) &T30Recovery[pTG->RecoveryIndex].fAvail,
  393. sizeof ( T30_RECOVERY_GLOB ) / sizeof (DWORD) - 1 );
  394. }
  395. }
  396. _fmemcpy (pTG->InFileName, gT30.TmpDirectory, gT30.dwLengthTmpDirectory);
  397. _fmemcpy (&pTG->InFileName[gT30.dwLengthTmpDirectory], pTG->TiffConvertThreadParams.lpszLineID, 8);
  398. sprintf (&pTG->InFileName[gT30.dwLengthTmpDirectory+8], "%s", ".RX");
  399. DeleteFileA(pTG->InFileName);
  400. if ( ( pTG->InFileHandle = CreateFileA(pTG->InFileName, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ,
  401. NULL, OPEN_ALWAYS, 0, NULL) ) == INVALID_HANDLE_VALUE ) {
  402. (MyDebugPrint(pTG, LOG_ERR, "<<ERROR>> RECV: Create file %s FAILED le=%lx\n"), GetLastError() );
  403. return FALSE;
  404. }
  405. pTG->InFileHandleNeedsBeClosed = 1;
  406. // Reset control data for the new page ack, interface
  407. pTG->fLastReadBlock = 0;
  408. pTG->BytesInNotFlushed = 0;
  409. pTG->BytesIn = 0;
  410. pTG->BytesOut = 0;
  411. pTG->fPageIsBad = 0;
  412. ResetEvent(pTG->ThrdDoneSignal);
  413. // get current offset
  414. /// pTG->Inst.cbBlockStart = DosSeek(pTG->Inst.hfile, 0, 1);
  415. }
  416. else if(slOffset == RECV_STARTBLOCK)
  417. {
  418. BG_CHK(pTG->Inst.state == RECVDATA_PHASE);
  419. BG_CHK(lpbf == 0);
  420. #ifdef CHK
  421. BG_CHK(!pTG->Inst.fRecvChecking); // MUST NOT have Recv Checking in ECM
  422. // Above check will fail if encoding is MH or MR -- see
  423. // 4/25/95 JosephJ WARNING above -- we have a workaround -- see below
  424. // if (slOffset>=0)
  425. #endif
  426. // seek to end of file (we may be arbitrarily in the middle)
  427. // and get file pos
  428. /// pTG->Inst.cbBlockStart = DosSeek(pTG->Inst.hfile, 0, 2);
  429. pTG->Inst.cbBlockSize = 0;
  430. }
  431. else if(slOffset >= 0)
  432. {
  433. BG_CHK(pTG->Inst.state == RECVDATA_PHASE);
  434. #if 0 //RSL ifdef CHK
  435. if (pTG->Inst.fRecvChecking)
  436. {
  437. BG_CHK((pTG->Inst.RecvParams.Fax.Encoding == MH_DATA) ||
  438. (pTG->Inst.RecvParams.Fax.Encoding == MR_DATA));
  439. // +++ Above should be BG_CHK(FALSE), but see
  440. // 4/25/95 JosephJ WARNING above.
  441. MyDebugPrint(pTG, LOG_ALL, "<<WARNING>> Disabling RecvChecking for MH/MR ECM recv\r\n");
  442. pTG->Inst.fRecvChecking=FALSE;
  443. }
  444. #endif
  445. // This may not hold since we may not even have gotten the
  446. // whole block the first time around, so Size cannot be
  447. // accurately calculated
  448. // BG_CHK(slOffset <= pTG->Inst.cbBlockSize);
  449. BG_CHK(((ULONG)slOffset) <= (((ULONG)lpbf->wLengthData) << 8));
  450. if(slOffset >= pTG->Inst.cbBlockSize)
  451. {
  452. pTG->Inst.cbPage += (long)lpbf->wLengthData;
  453. }
  454. MyFreeBuf(pTG, lpbf);
  455. }
  456. else if (slOffset == RECV_FLUSH) {
  457. if (! FlushFileBuffers (pTG->InFileHandle ) ) {
  458. MyDebugPrint(pTG, LOG_ALL, "ERROR: FlushFileBuffers FAILED LE=%lx at %ld \n",
  459. GetLastError(), GetTickCount() );
  460. return FALSE;
  461. }
  462. MyDebugPrint(pTG, LOG_ALL, "RECV: ThrdSignal FLUSH at %ld \n", GetTickCount() );
  463. pTG->BytesIn = pTG->BytesInNotFlushed;
  464. if (! pTG->fPageIsBad) {
  465. SetEvent(pTG->ThrdSignal);
  466. }
  467. return TRUE;
  468. }
  469. else // if(slOffset == RECV_SEQ)
  470. {
  471. BG_CHK(pTG->Inst.state == RECVDATA_PHASE);
  472. BG_CHK(slOffset==RECV_SEQ || slOffset==RECV_SEQBAD);
  473. MyDebugPrint(pTG, LOG_ALL, "Write RAW Page ptr=%x; len=%d Time=%ld\r\n",
  474. lpbf->lpbBegData, lpbf->wLengthData, GetTickCount() );
  475. if ( ! WriteFile( pTG->InFileHandle, lpbf->lpbBegData, lpbf->wLengthData, &BytesWritten, NULL ) ) {
  476. MyDebugPrint(pTG, LOG_ALL, "ERROR: WriteFile FAILED %s ptr=%x; len=%d LE=%d Time=%ld\r\n",
  477. pTG->InFileName, lpbf->lpbBegData, lpbf->wLengthData, GetLastError(), GetTickCount() );
  478. return FALSE;
  479. }
  480. if (BytesWritten != lpbf->wLengthData) {
  481. MyDebugPrint(pTG, LOG_ALL, "ERROR: WriteFile %s written ONLY %d ptr=%x; len=%d LE=%d Time=%ld\r\n",
  482. pTG->InFileName, BytesWritten, lpbf->lpbBegData, lpbf->wLengthData, GetLastError(), GetTickCount() );
  483. fRet = FALSE;
  484. return fRet;
  485. }
  486. pTG->BytesInNotFlushed += BytesWritten;
  487. // control helper thread
  488. if ( (!pTG->fTiffThreadRunning) || (pTG->fLastReadBlock) ) {
  489. if ( (pTG->BytesInNotFlushed - pTG->BytesOut > DECODE_BUFFER_SIZE) || (pTG->fLastReadBlock) ) {
  490. if (! FlushFileBuffers (pTG->InFileHandle ) ) {
  491. MyDebugPrint(pTG, LOG_ALL, "ERROR: FlushFileBuffers FAILED LE=%lx at %ld \n",
  492. GetLastError(), GetTickCount() );
  493. fRet = FALSE;
  494. return fRet;
  495. }
  496. pTG->BytesIn = pTG->BytesInNotFlushed;
  497. if (! pTG->fPageIsBad) {
  498. MyDebugPrint(pTG, LOG_ALL, "RECV: ThrdSignal at %ld \n", GetTickCount() );
  499. pTG->fTiffThreadRunning = 1;
  500. SetEvent(pTG->ThrdSignal);
  501. }
  502. }
  503. }
  504. pTG->Inst.cbPage += (long)lpbf->wLengthData;
  505. pTG->Inst.cbBlockSize += lpbf->wLengthData;
  506. ///if((pTG->Inst.cbPage - lOldRecvCount) >= 4000)
  507. {
  508. ///USHORT usKB = (USHORT) (LongShr8(pTG->Inst.cbPage) >> 2);
  509. ///SetStatus(T30STATR_RECV, pTG->Inst.awfi.uNumPages, LOBYTE(usKB), HIBYTE(usKB));
  510. ///lOldRecvCount = pTG->Inst.cbPage;
  511. }
  512. #if 0 //RSL ifdef CHK
  513. if(pTG->Inst.fRecvChecking)
  514. {
  515. // For Recvd T4 checking
  516. // why bother? He doesn't use it & it's 0 from startup time anyway...
  517. // _fmemset(&bfDummy, 0, sizeof(BUFFER));
  518. BG_CHK(lpfnFaxCodecConvert);
  519. BG_CHK(lpT4Inst);
  520. ///lpfnFaxCodecConvert(lpT4Inst, lpbf, &bfDummy);
  521. }
  522. #endif //CHK
  523. MyFreeBuf(pTG, lpbf);
  524. }
  525. fRet = TRUE;
  526. return fRet;
  527. }
  528. LPBC ICommGetBC(PThrdGlbl pTG, BCTYPE bctype, BOOL fSleep)
  529. {
  530. LPBC lpbc = NULL;
  531. BG_CHK(bctype==SEND_CAPS || bctype==SEND_PARAMS);
  532. if(bctype == SEND_CAPS)
  533. {
  534. BG_CHK(pTG->Inst.SendCaps.bctype == SEND_CAPS);
  535. lpbc = (LPBC)&pTG->Inst.SendCaps;
  536. }
  537. else
  538. {
  539. #ifdef POLLREQ
  540. if(pTG->Inst.fInPollReq)
  541. {
  542. BG_CHK(pTG->Inst.SendPollReq.bctype == SEND_POLLREQ);
  543. lpbc = (LPBC)(&(pTG->Inst.SendPollReq));
  544. }
  545. else
  546. #endif //POLLREQ
  547. {
  548. BG_CHK(pTG->Inst.SendParams.bctype == SEND_PARAMS);
  549. lpbc = (LPBC)(&(pTG->Inst.SendParams));
  550. }
  551. // in cases where DIS is received again after sending DCS-TCF,
  552. // this gets called multiple times & we need to return the same
  553. // SendParams BC each time
  554. }
  555. return lpbc;
  556. }
  557. BOOL ICommRecvPollReq(PThrdGlbl pTG, LPBC lpBC)
  558. {
  559. BOOL fRet = FALSE;
  560. return fRet;
  561. }