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.

364 lines
13 KiB

  1. /***************************************************************************
  2. Name : SEND.C
  3. Comment : Sender functions
  4. Revision Log
  5. Date Name Description
  6. -------- ----- ---------------------------------------------------------
  7. ***************************************************************************/
  8. #define USE_DEBUG_CONTEXT DEBUG_CONTEXT_T30_MAIN
  9. #include "prep.h"
  10. #include "efaxcb.h"
  11. #include "glbproto.h"
  12. #include "t30gl.h"
  13. SWORD ICommGetSendBuf(PThrdGlbl pTG, LPBUFFER far* lplpbf, SLONG slOffset)
  14. {
  15. /**
  16. slOffset == SEND_STARTPAGE marks beginning of new block *and* page
  17. (returns with data from the "appropriate" file offset).
  18. slOffset == SEND_SEQ means get buffer from current file position
  19. slOffset >= 0 gives the offset in bytes from the last marked position
  20. (beginning of block) to start reading from
  21. returns: SEND_ERROR on error, SEND_EOF on eof, SEND_OK otherwise.
  22. Does not return data on EOF or ERROR, i.e. *lplpbf==0
  23. **/
  24. SWORD sRet = SEND_ERROR;
  25. LPBUFFER lpbf;
  26. DWORD dwBytesRead;
  27. DEBUG_FUNCTION_NAME(_T("ICommGetSendBuf"));
  28. if (pTG->fAbortRequested)
  29. {
  30. DebugPrintEx(DEBUG_MSG,"got ABORT");
  31. sRet = SEND_ERROR;
  32. goto mutexit;
  33. }
  34. if(slOffset == SEND_STARTPAGE)
  35. {
  36. pTG->fTxPageDone = FALSE; // This to mark that we did not finish yet.
  37. if (pTG->T30.ifrResp == ifrRTN)
  38. {
  39. DebugPrintEx( DEBUG_MSG,
  40. "Re-transmitting: We open again the file: %s",
  41. pTG->InFileName);
  42. if ( ( pTG->InFileHandle = CreateFileA(pTG->InFileName, GENERIC_READ, FILE_SHARE_READ,
  43. NULL, OPEN_EXISTING, 0, NULL) ) == INVALID_HANDLE_VALUE )
  44. {
  45. DebugPrintEx( DEBUG_ERR,
  46. "OpenFile for Retranmit %s fails; CurrentOut=%d;"
  47. " CurrentIn=%d",
  48. pTG->InFileName,
  49. pTG->CurrentOut,
  50. pTG->CurrentIn);
  51. sRet = SEND_ERROR;
  52. goto mutexit;
  53. }
  54. pTG->InFileHandleNeedsBeClosed = TRUE;
  55. SignalStatusChange(pTG, FS_TRANSMITTING); // This will report the current status
  56. DebugPrintEx( DEBUG_MSG,
  57. "SEND_STARTPAGE: CurrentOut=%d, FirstOut=%d,"
  58. " LastOut=%d, CurrentIn=%d",
  59. pTG->CurrentOut,
  60. pTG->FirstOut,
  61. pTG->LastOut,
  62. pTG->CurrentIn);
  63. }
  64. else //First try for the current page
  65. {
  66. // Delete last successfully transmitted Tiff Page file.
  67. // Lets reset the counter of the retries. Attention: The speed remains the same.
  68. pTG->ProtParams.RTNNumOfRetries = 0;
  69. _fmemcpy (pTG->InFileName, gT30.TmpDirectory, gT30.dwLengthTmpDirectory);
  70. _fmemcpy (&pTG->InFileName[gT30.dwLengthTmpDirectory], pTG->lpszPermanentLineID, 8);
  71. if (pTG->PageCount != 0)
  72. {
  73. sprintf( &pTG->InFileName[gT30.dwLengthTmpDirectory+8], ".%03d", pTG->PageCount);
  74. if (! DeleteFileA (pTG->InFileName) )
  75. {
  76. DebugPrintEx( DEBUG_ERR,
  77. "file %s can't be deleted; le=%lx",
  78. pTG->InFileName,
  79. GetLastError());
  80. }
  81. else
  82. {
  83. DebugPrintEx( DEBUG_MSG,
  84. "SEND_STARTPAGE: Previous file %s deleted."
  85. " PageCount=%d, CurrentIn=%d",
  86. pTG->InFileName,
  87. pTG->PageCount,
  88. pTG->CurrentIn);
  89. }
  90. }
  91. pTG->PageCount++ ;
  92. pTG->CurrentIn++ ;
  93. DebugPrintEx( DEBUG_MSG,
  94. "SendBuf: Starting New PAGE %d First=%d Last=%d",
  95. pTG->PageCount,
  96. pTG->FirstOut,
  97. pTG->LastOut);
  98. // Server wants to know when we start TX new page.
  99. SignalStatusChange(pTG, FS_TRANSMITTING);
  100. DebugPrintEx( DEBUG_MSG,
  101. "SEND_STARTPAGE (cont): CurrentOut=%d, FirstOut=%d,"
  102. " LastOut=%d, CurrentIn=%d",
  103. pTG->CurrentOut,
  104. pTG->FirstOut,
  105. pTG->LastOut,
  106. pTG->CurrentIn);
  107. if (pTG->CurrentOut < pTG->CurrentIn )
  108. {
  109. DebugPrintEx( DEBUG_ERR,
  110. "TIFF PAGE hadn't been started CurrentOut=%d;",
  111. " CurrentIn=%d",
  112. pTG->CurrentOut,
  113. pTG->CurrentIn);
  114. sRet = SEND_ERROR;
  115. goto mutexit;
  116. }
  117. // some slack for 1st page
  118. if ( (pTG->CurrentOut == pTG->CurrentIn) && (pTG->CurrentIn == 1 ) )
  119. {
  120. DebugPrintEx( DEBUG_MSG,
  121. "SEND: Wait for 1st page: CurrentOut=%d; In=%d",
  122. pTG->CurrentOut,
  123. pTG->CurrentIn);
  124. if ( WaitForSingleObject(pTG->FirstPageReadyTxSignal, 5000) == WAIT_TIMEOUT )
  125. {
  126. DebugPrintEx( DEBUG_ERR,
  127. "SEND: TIMEOUT ERROR Wait for 1st page:"
  128. " CurrentOut=%d; In=%d",
  129. pTG->CurrentOut,
  130. pTG->CurrentIn);
  131. }
  132. DebugPrintEx( DEBUG_MSG,
  133. "SEND: Wakeup for 1st page: CurrentOut=%d; In=%d",
  134. pTG->CurrentOut,
  135. pTG->CurrentIn);
  136. }
  137. // open the file created by tiff thread
  138. sprintf( &pTG->InFileName[gT30.dwLengthTmpDirectory+8], ".%03d", pTG->PageCount);
  139. if ( ( pTG->InFileHandle = CreateFileA(pTG->InFileName, GENERIC_READ, FILE_SHARE_READ,
  140. NULL, OPEN_EXISTING, 0, NULL) ) == INVALID_HANDLE_VALUE )
  141. {
  142. DebugPrintEx( DEBUG_ERR,
  143. "OpenFile %s fails; CurrentOut=%d;"
  144. " CurrentIn=%d",
  145. pTG->InFileName,
  146. pTG->CurrentOut,
  147. pTG->CurrentIn);
  148. sRet = SEND_ERROR;
  149. goto mutexit;
  150. }
  151. pTG->InFileHandleNeedsBeClosed = TRUE;
  152. if ( pTG->CurrentOut == pTG->CurrentIn )
  153. {
  154. DebugPrintEx( DEBUG_WRN,
  155. "CurrentOut=%d; CurrentIn=%d",
  156. pTG->CurrentOut,
  157. pTG->CurrentIn);
  158. }
  159. //
  160. // Signal TIFF thread to start preparing new page if needed.
  161. //
  162. if ( (! pTG->fTiffDocumentDone) && (pTG->LastOut - pTG->CurrentIn < 2) )
  163. {
  164. if (!ResetEvent(pTG->ThrdSignal))
  165. {
  166. DebugPrintEx( DEBUG_ERR,
  167. "ResetEvent(0x%lx) returns failure code: %ld",
  168. (ULONG_PTR)pTG->ThrdSignal,
  169. (long) GetLastError());
  170. // this is bad, but not fatal yet.
  171. // let's wait and see what happens with SetEvent...
  172. }
  173. pTG->ReqStartNewPage = 1;
  174. pTG->AckStartNewPage = 0;
  175. DebugPrintEx( DEBUG_MSG,
  176. "SIGNAL NEW PAGE CurrentOut=%d; CurrentIn=%d",
  177. pTG->CurrentOut,
  178. pTG->CurrentIn);
  179. if (!SetEvent(pTG->ThrdSignal))
  180. {
  181. DebugPrintEx( DEBUG_ERR,
  182. "SetEvent(0x%lx) returns failure code: %ld",
  183. (ULONG_PTR)pTG->ThrdSignal,
  184. (long) GetLastError());
  185. sRet = SEND_ERROR;
  186. goto mutexit;
  187. }
  188. }
  189. }
  190. pTG->Inst.state = SENDDATA_PHASE;
  191. sRet = SEND_OK;
  192. goto mutexit;
  193. }
  194. *lplpbf=0;
  195. if(slOffset == SEND_SEQ)
  196. {
  197. if (pTG->fTxPageDone)
  198. { //In the last read from the file, we can tell that the page is over
  199. sRet = SEND_EOF;
  200. if (pTG->InFileHandleNeedsBeClosed)
  201. {
  202. CloseHandle(pTG->InFileHandle); // If we close the file so rashly, open it again later
  203. pTG->InFileHandleNeedsBeClosed = FALSE;
  204. }
  205. goto mutexit;
  206. }
  207. lpbf = MyAllocBuf(pTG, MY_BIGBUF_SIZE);
  208. lpbf->lpbBegData = lpbf->lpbBegBuf+4;
  209. lpbf->wLengthData = MY_BIGBUF_SIZE;
  210. if ( ! ReadFile(pTG->InFileHandle, lpbf->lpbBegData, lpbf->wLengthData, &dwBytesRead, 0) )
  211. {
  212. DebugPrintEx( DEBUG_ERR,
  213. "Can't read %d bytes from %s. Last error:%d",
  214. lpbf->wLengthData,
  215. pTG->InFileName,
  216. GetLastError());
  217. MyFreeBuf (pTG, lpbf);
  218. sRet = SEND_ERROR;
  219. goto mutexit;
  220. }
  221. if ( lpbf->wLengthData != (unsigned) dwBytesRead )
  222. {
  223. if (pTG->fTiffPageDone || (pTG->CurrentIn != pTG->CurrentOut) )
  224. {
  225. // actually reached EndOfPage
  226. lpbf->wLengthData = (unsigned) dwBytesRead;
  227. pTG->fTxPageDone = TRUE;
  228. }
  229. else
  230. {
  231. DebugPrintEx( DEBUG_ERR,
  232. "Wanted %d bytes but ONLY %d ready from %s",
  233. lpbf->wLengthData,
  234. dwBytesRead,
  235. pTG->InFileName);
  236. MyFreeBuf (pTG, lpbf);
  237. sRet = SEND_ERROR;
  238. goto mutexit;
  239. }
  240. }
  241. *lplpbf = lpbf;
  242. DebugPrintEx(DEBUG_MSG,"SEND_SEQ: length=%d", lpbf->wLengthData);
  243. }
  244. sRet = SEND_OK;
  245. mutexit:
  246. return sRet;
  247. }
  248. USHORT ICommNextSend(PThrdGlbl pTG)
  249. {
  250. USHORT uRet = NEXTSEND_ERROR;
  251. DEBUG_FUNCTION_NAME(_T("ICommNextSend"));
  252. if (pTG->PageCount >= pTG->TiffInfo.PageCount)
  253. {
  254. pTG->Inst.awfi.fLastPage = 1;
  255. }
  256. if(pTG->Inst.awfi.fLastPage)
  257. {
  258. uRet = NEXTSEND_EOP;
  259. }
  260. else
  261. {
  262. uRet = NEXTSEND_MPS;
  263. }
  264. DebugPrintEx( DEBUG_MSG,
  265. "uRet=%d, fLastPage=%d",
  266. uRet,
  267. pTG->Inst.awfi.fLastPage);
  268. return uRet;
  269. }
  270. BOOL ICommRecvCaps(PThrdGlbl pTG, LPBC lpBC)
  271. {
  272. BOOL fRet = FALSE;
  273. DEBUG_FUNCTION_NAME(_T("ICommRecvCaps"));
  274. if (pTG->fAbortRequested)
  275. {
  276. DebugPrintEx(DEBUG_MSG,"got ABORT");
  277. fRet = FALSE;
  278. goto mutexit;
  279. }
  280. if(pTG->Inst.state != BEFORE_RECVCAPS)
  281. {
  282. DebugPrintEx(DEBUG_WRN,"Got caps unexpectedly--ignoring");
  283. // this will break if we send EOM...
  284. // then we should go back into RECV_CAPS state
  285. fRet = TRUE;
  286. //RSL goto mutexit;
  287. }
  288. _fmemset(&pTG->Inst.RemoteRecvCaps, 0, sizeof(pTG->Inst.RemoteRecvCaps));
  289. _fmemcpy(&pTG->Inst.RemoteRecvCaps, lpBC, min(sizeof(pTG->Inst.RemoteRecvCaps), lpBC->wTotalSize));
  290. if(!NegotiateCaps(pTG))
  291. {
  292. _fmemset(&pTG->Inst.SendParams, 0, sizeof(pTG->Inst.SendParams));
  293. fRet = FALSE;
  294. goto mutexit;
  295. }
  296. pTG->Inst.state = SENDDATA_BETWEENPAGES;
  297. fRet = TRUE;
  298. mutexit:
  299. return fRet;
  300. }