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.

826 lines
21 KiB

  1. /*****************************************************************************/
  2. /* Copyright (c) 1987 - 1988, Future Soft Engineering, Inc. */
  3. /* Houston, Texas */
  4. /*****************************************************************************/
  5. #define NOLSTRING TRUE /* jtf win3 mod */
  6. #include <windows.h>
  7. #include "port1632.h"
  8. #include "dcrc.h"
  9. #include "dynacomm.h"
  10. /*---------------------------------------------------------------------------*/
  11. #define XM_ABORT 0x8000
  12. #define XM_COMPLETE 0x4000
  13. #define XM_BLKREPEAT 0x2000
  14. #define XM_CRC 0x0800
  15. #define YM_1KBLK 0x0400
  16. #define YM_GOPTION 0x0200
  17. #define XM_RETRYMASK 0x001F /* mbbx 1.04: relax 15 -> 31 */
  18. #define XM_RETRIES 0x0014 /* mbbx 1.04: relax 10 -> 20 */
  19. #define XM_RETRYINITCRC 4
  20. #define XM_RETRYINITCKS 10
  21. #define XM_WAITRCVINIT 50 /* mbbx 1.04: relax... */
  22. #define XM_WAITNEXTBLK 100
  23. #define XM_WAITNEXTCHAR 50 //sdj: was 20 to get rid of xmodem
  24. //sdj: retries when moused moved..move to 50
  25. #define XM_WAITSNDINIT 600
  26. BOOL YM_RcvBatch(WORD);
  27. BOOL NEAR YM_RcvFileInfo(WORD *, WORD *);
  28. BOOL XM_RcvFile(WORD);
  29. BOOL NEAR XM_RcvInit(WORD *, WORD *);
  30. BOOL NEAR XM_RcvData(WORD *, WORD *);
  31. BOOL NEAR XM_RcvBlockHeader(WORD *, WORD *);
  32. BOOL NEAR XM_RcvBlockData(WORD *blockNumber, WORD blockSize,WORD *rcvStatus);
  33. VOID NEAR XM_RcvBlockAbort(WORD *);
  34. BOOL NEAR XM_RcvEnd();
  35. VOID NEAR XM_RcvAbort();
  36. BOOL YM_SndBatch(WORD);
  37. BOOL NEAR YM_SndFileInfo(WORD *, BOOL);
  38. BOOL XM_SndFile(WORD sndStatus);
  39. BOOL NEAR XM_SndInit(WORD *);
  40. BOOL NEAR XM_SndData(WORD *);
  41. BOOL NEAR XM_SndBlockData(WORD *, WORD *, WORD *);
  42. BOOL NEAR XM_SndEnd();
  43. VOID NEAR XM_SndAbort();
  44. BYTE XM_CheckSum(BYTE *dataBlock, WORD blockSize); /* mbbx 2.00: NEAR -> FAR */
  45. WORD XM_CalcCRC(BYTE *, INT); /* mbbx 2.00: NEAR -> FAR */
  46. /*---------------------------------------------------------------------------*/
  47. /* UTILITIES --> RCVBFILE.C */
  48. BOOL initXfrBuffer(WORD wBufSize);
  49. VOID fillXfrBuffer(BYTE *, WORD);
  50. WORD readXfrBuffer(BYTE *dataBlock,WORD blockSize,BOOL bBlkRepeat);
  51. BOOL writeXfrBuffer(BYTE *dataBlock, WORD blockSize,BOOL bBlkRepeat);
  52. VOID grabXfrBuffer(BYTE *, WORD);
  53. BOOL clearXfrBuffer();
  54. VOID freeXfrBuffer();
  55. /*---------------------------------------------------------------------------*/
  56. /* XM_RcvFile() - [mbb] */
  57. /*---------------------------------------------------------------------------*/
  58. BOOL XM_RcvFile(WORD rcvStatus)
  59. {
  60. WORD blockSize;
  61. if(XM_RcvInit(&blockSize, &rcvStatus))
  62. if(XM_RcvData(&blockSize, &rcvStatus))
  63. if(XM_RcvEnd())
  64. return(TRUE);
  65. XM_RcvAbort();
  66. return(FALSE);
  67. }
  68. /*---------------------------------------------------------------------------*/
  69. /* XM_RcvInit() - [mbb] */
  70. /*---------------------------------------------------------------------------*/
  71. BOOL NEAR XM_RcvInit(WORD *blockSize, WORD *rcvStatus)
  72. {
  73. BYTE work[3];
  74. WORD retry;
  75. LoadString(hInst, STR_RI, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
  76. bSetup(work);
  77. *blockSize = 128;
  78. *rcvStatus |= XM_RETRIES;
  79. if(*rcvStatus & (YM_1KBLK | YM_GOPTION))
  80. *rcvStatus |= XM_CRC;
  81. while(*rcvStatus & XM_CRC)
  82. {
  83. for(retry = XM_RETRYINITCRC; retry > 0; retry -= 1)
  84. {
  85. modemWr('C');
  86. if(xferPSChar) /* mbbx 1.02: packet switching */
  87. modemWr(xferPSChar);
  88. if(waitRcvChar(work, XM_WAITRCVINIT, 0, CHSTX, CHSOH, CHEOT, CHCAN, NULL))
  89. {
  90. switch(work[0])
  91. {
  92. case CHSTX:
  93. *blockSize = 1024;
  94. /* then fall thru... */
  95. case CHSOH:
  96. return(TRUE);
  97. case CHEOT:
  98. *rcvStatus |= XM_COMPLETE;
  99. return(TRUE);
  100. case CHCAN:
  101. return(FALSE);
  102. }
  103. }
  104. if(xferStopped)
  105. return(FALSE);
  106. }
  107. *rcvStatus &= ((*rcvStatus & YM_GOPTION) ? ~YM_GOPTION : ~XM_CRC);
  108. }
  109. for(retry = XM_RETRYINITCKS; retry > 0; retry -= 1) /* mbbx 1.04: relax */
  110. {
  111. modemWr(CHNAK);
  112. if(xferPSChar) /* mbbx 1.02: packet switching */
  113. modemWr(xferPSChar);
  114. if(waitRcvChar(work, XM_WAITRCVINIT, 0, CHSTX, CHSOH, CHEOT, CHCAN, NULL))
  115. {
  116. switch(work[0])
  117. {
  118. case CHSTX:
  119. *blockSize = 1024;
  120. /* then fall thru... */
  121. case CHSOH:
  122. return(TRUE);
  123. case CHEOT:
  124. *rcvStatus |= XM_COMPLETE;
  125. return(TRUE);
  126. case CHCAN:
  127. return(FALSE);
  128. }
  129. }
  130. if(xferStopped)
  131. break;
  132. showBErrors(++xferErrors);
  133. }
  134. return(FALSE);
  135. }
  136. /*---------------------------------------------------------------------------*/
  137. /* XM_RcvData() - [mbb] */
  138. /*---------------------------------------------------------------------------*/
  139. BOOL NEAR XM_RcvData(WORD *blockSize, WORD *rcvStatus)
  140. {
  141. BYTE work[3];
  142. WORD blockNumber = 1;
  143. if(*rcvStatus & XM_COMPLETE)
  144. return(TRUE);
  145. LoadString(hInst, STR_DF, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
  146. bSetup(work);
  147. if(initXfrBuffer(12 * 1024))
  148. {
  149. XM_RcvBlockData(&blockNumber, *blockSize, rcvStatus);
  150. while(!(*rcvStatus & (XM_COMPLETE | XM_ABORT)))
  151. {
  152. if(XM_RcvBlockHeader(blockSize, rcvStatus))
  153. XM_RcvBlockData(&blockNumber, *blockSize, rcvStatus);
  154. }
  155. if(!(*rcvStatus & XM_ABORT))
  156. if(!clearXfrBuffer())
  157. *rcvStatus |= XM_ABORT;
  158. freeXfrBuffer();
  159. }
  160. return(!(*rcvStatus & XM_ABORT));
  161. }
  162. /*---------------------------------------------------------------------------*/
  163. /* XM_RcvBlockHeader() - [mbb] */
  164. /*---------------------------------------------------------------------------*/
  165. BOOL NEAR XM_RcvBlockHeader(WORD *blockSize, WORD *rcvStatus)
  166. {
  167. BYTE work[1];
  168. if(waitRcvChar(work, XM_WAITNEXTBLK, 0, CHSTX, CHSOH, CHEOT, CHCAN, NULL))
  169. {
  170. switch(work[0])
  171. {
  172. case CHSTX:
  173. *blockSize = 1024;
  174. return(TRUE);
  175. case CHSOH:
  176. *blockSize = 128;
  177. return(TRUE);
  178. case CHEOT:
  179. *rcvStatus |= XM_COMPLETE;
  180. return(FALSE);
  181. case CHCAN:
  182. xferStopped = TRUE;
  183. break;
  184. }
  185. }
  186. XM_RcvBlockAbort(rcvStatus);
  187. return(FALSE);
  188. }
  189. /*---------------------------------------------------------------------------*/
  190. /* XM_RcvBlockData() - [mbb] */
  191. /*---------------------------------------------------------------------------*/
  192. BOOL NEAR XM_RcvBlockData(WORD *blockNumber, WORD blockSize,WORD *rcvStatus)
  193. {
  194. BYTE work[2];
  195. BOOL bBlkRepeat;
  196. WORD ndx;
  197. BYTE dataBlock[1024];
  198. signed char i,j;
  199. while(waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0) &&
  200. waitRcvChar(work+1, XM_WAITNEXTCHAR, 0, 0) &&
  201. ( (j=(signed char)work[0]) == ~(i = (signed char)work[1]) ) )
  202. //sdj: on mips xmodem rcv was broken due to (BYTE)~work[1]
  203. {
  204. if(bBlkRepeat = (work[0] != (BYTE) *blockNumber))
  205. if(work[0] != (BYTE) (*blockNumber-1))
  206. break;
  207. for(ndx = 0; ndx < blockSize; ndx += 1)
  208. if(!waitRcvChar(dataBlock+ndx, XM_WAITNEXTCHAR, 0, 0))
  209. break;
  210. if(ndx < blockSize)
  211. break;
  212. if(!waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0))
  213. break;
  214. if(!(*rcvStatus & XM_CRC))
  215. {
  216. if(XM_CheckSum(dataBlock, blockSize) != work[0])
  217. break;
  218. }
  219. else
  220. {
  221. if(!waitRcvChar(work+1, XM_WAITNEXTCHAR, 0, 0) || (XM_CalcCRC(dataBlock, blockSize) != ((work[0] << 8) | work[1])))
  222. break;
  223. }
  224. if(!writeXfrBuffer(dataBlock, blockSize, bBlkRepeat))
  225. {
  226. xferStopped = TRUE;
  227. break;
  228. }
  229. if(!bBlkRepeat) /* mbb: reset retry counter */
  230. {
  231. *blockNumber += 1;
  232. *rcvStatus = (*rcvStatus & ~XM_RETRYMASK) | XM_RETRIES;
  233. if(*blockNumber > 1) /* mbb: skip block 0 */
  234. {
  235. if(xferOrig > 0)
  236. {
  237. xferBytes -= blockSize;
  238. updateProgress(FALSE);
  239. }
  240. else
  241. showBBytes(xferLength += blockSize, FALSE); /* mbbx 2.00: xfer ctrls */
  242. }
  243. }
  244. if(!(*rcvStatus & YM_GOPTION))
  245. {
  246. modemWr(CHACK);
  247. if(xferPSChar) /* mbbx 1.02: packet switching */
  248. modemWr(xferPSChar);
  249. }
  250. return(TRUE);
  251. }
  252. XM_RcvBlockAbort(rcvStatus);
  253. return(FALSE);
  254. }
  255. /*---------------------------------------------------------------------------*/
  256. /* XM_RcvBlockAbort() - [mbb] */
  257. /*---------------------------------------------------------------------------*/
  258. VOID NEAR XM_RcvBlockAbort(WORD *rcvStatus)
  259. {
  260. BYTE work[1];
  261. if(xferStopped || (((*rcvStatus -= 1) & XM_RETRYMASK) == 0))
  262. *rcvStatus |= XM_ABORT;
  263. else
  264. {
  265. while(waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0));
  266. modemWr(CHNAK);
  267. if(xferPSChar) /* mbbx 1.02: packet switching */
  268. modemWr(xferPSChar);
  269. }
  270. if(!xferStopped)
  271. showBErrors(++xferErrors);
  272. }
  273. /*---------------------------------------------------------------------------*/
  274. /* XM_RcvEnd() - [mbb] */
  275. /*---------------------------------------------------------------------------*/
  276. BOOL NEAR XM_RcvEnd()
  277. {
  278. BYTE work[3];
  279. WORD retry;
  280. LoadString(hInst, STR_RE, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
  281. bSetup(work);
  282. modemWr(CHACK);
  283. if(xferPSChar) /* mbbx 1.02: packet switching */
  284. modemWr(xferPSChar);
  285. for(retry = XM_RETRIES; retry > 0; retry -= 1) /* mbbx 1.04: relax */
  286. {
  287. if(waitRcvChar(work, XM_WAITNEXTBLK / 2, 0, CHEOT, CHCAN, NULL))
  288. {
  289. switch(work[0])
  290. {
  291. case CHEOT:
  292. modemWr(CHACK);
  293. if(xferPSChar) /* mbbx 1.02: packet switching */
  294. modemWr(xferPSChar);
  295. showBErrors(++xferErrors);
  296. continue;
  297. case CHCAN:
  298. xferStopped = TRUE;
  299. break;
  300. }
  301. }
  302. if(xferStopped)
  303. break;
  304. return(TRUE);
  305. }
  306. return(FALSE);
  307. }
  308. /*---------------------------------------------------------------------------*/
  309. /* XM_RcvAbort() - [mbb] */
  310. /*---------------------------------------------------------------------------*/
  311. VOID NEAR XM_RcvAbort()
  312. {
  313. BYTE work[1];
  314. rcvAbort();
  315. while(waitRcvChar(work, XM_WAITNEXTCHAR, 0, 0));
  316. modemWr(CHCAN);
  317. modemWr(CHCAN);
  318. modemWr(CHCAN);
  319. modemWr(CHCAN);
  320. modemWr(CHCAN);
  321. modemWr(BS);
  322. modemWr(BS);
  323. modemWr(BS);
  324. modemWr(BS);
  325. modemWr(BS);
  326. if(xferPSChar) /* mbbx 1.02: packet switching */
  327. modemWr(xferPSChar);
  328. }
  329. /*---------------------------------------------------------------------------*/
  330. /* XM_SndFile() - [mbb] */
  331. /*---------------------------------------------------------------------------*/
  332. BOOL XM_SndFile(WORD sndStatus)
  333. {
  334. if(XM_SndInit(&sndStatus))
  335. if(XM_SndData(&sndStatus))
  336. if(XM_SndEnd())
  337. return(TRUE);
  338. XM_SndAbort();
  339. return(FALSE);
  340. }
  341. /*---------------------------------------------------------------------------*/
  342. /* XM_SndInit() - [mbb] */
  343. /*---------------------------------------------------------------------------*/
  344. BOOL NEAR XM_SndInit(WORD *sndStatus)
  345. {
  346. BYTE work[3];
  347. LoadString(hInst, STR_SI, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
  348. bSetup(work);
  349. *sndStatus |= XM_RETRIES;
  350. if(waitRcvChar(work, XM_WAITSNDINIT, 0, 'C', CHNAK, CHCAN, 0))
  351. {
  352. switch(work[0])
  353. {
  354. case 'C':
  355. *sndStatus |= XM_CRC;
  356. if(!(*sndStatus & YM_1KBLK) && waitRcvChar(work, XM_WAITNEXTCHAR / 2, 0, 'K', 0))
  357. *sndStatus |= YM_1KBLK;
  358. return(TRUE);
  359. case CHNAK:
  360. *sndStatus &= ~(XM_CRC | YM_1KBLK);
  361. return(TRUE);
  362. case CHCAN:
  363. break;
  364. }
  365. }
  366. return(FALSE);
  367. }
  368. /*---------------------------------------------------------------------------*/
  369. /* XM_SndData() - [mbb] */
  370. /*---------------------------------------------------------------------------*/
  371. BOOL NEAR XM_SndData(WORD *sndStatus)
  372. {
  373. BYTE work[3];
  374. WORD blockNumber = 1;
  375. WORD blockSize;
  376. LoadString(hInst, STR_DF, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
  377. bSetup(work);
  378. if(initXfrBuffer(12 * 1024))
  379. {
  380. blockSize = (!(*sndStatus & YM_1KBLK) ? 128 : 1024);
  381. while(!(*sndStatus & (XM_COMPLETE | XM_ABORT)))
  382. XM_SndBlockData(&blockNumber, &blockSize, sndStatus);
  383. freeXfrBuffer();
  384. }
  385. return(!(*sndStatus & XM_ABORT));
  386. }
  387. /*---------------------------------------------------------------------------*/
  388. /* XM_SndBlockData() - [mbb] */
  389. /*---------------------------------------------------------------------------*/
  390. BOOL NEAR XM_SndBlockData(WORD *blockNumber, WORD *blockSize, WORD *sndStatus)
  391. {
  392. BYTE dataBlock[1024];
  393. WORD dataBytes;
  394. WORD wCRC;
  395. BYTE work[1];
  396. BOOL writeGood;
  397. switch(dataBytes = readXfrBuffer(dataBlock, *blockSize, (*sndStatus & XM_BLKREPEAT)))
  398. {
  399. case (WORD)-1:
  400. xferStopped = TRUE;
  401. break;
  402. case 0:
  403. *sndStatus |= XM_COMPLETE;
  404. return(TRUE);
  405. default:
  406. if((*blockSize == 1024) && (dataBytes <= (5 * 128)) && !(*sndStatus & XM_BLKREPEAT))
  407. readXfrBuffer(dataBlock, *blockSize = 128, TRUE);
  408. modemWr((*blockSize == 128) ? CHSOH : CHSTX);
  409. modemWr((BYTE) *blockNumber);
  410. modemWr((BYTE) ~*blockNumber);
  411. writeGood = modemWrite((LPSTR) dataBlock, (INT)(*blockSize));
  412. if(!writeGood)
  413. {
  414. wCRC = 0;
  415. break;
  416. }
  417. if(!(*sndStatus & XM_CRC))
  418. modemWr(XM_CheckSum(dataBlock, *blockSize));
  419. else
  420. {
  421. wCRC = XM_CalcCRC(dataBlock, *blockSize);
  422. modemWr(HIBYTE(wCRC));
  423. modemWr(LOBYTE(wCRC));
  424. }
  425. if(xferPSChar) /* mbbx 1.02: packet switching */
  426. modemWr(xferPSChar);
  427. if(!waitRcvChar(work, XM_WAITSNDINIT, 0, CHACK, CHNAK, CHCAN, (*blockNumber <= 1) ? 'C' : 0, 0))
  428. {
  429. xferStopped = TRUE;
  430. break;
  431. }
  432. switch(work[0])
  433. {
  434. case CHACK:
  435. *blockNumber += 1;
  436. *sndStatus = (*sndStatus & ~(XM_BLKREPEAT | XM_RETRYMASK)) | XM_RETRIES;
  437. if(*blockNumber > 1)
  438. {
  439. xferBytes -= *blockSize;
  440. updateProgress(FALSE);
  441. }
  442. return(TRUE);
  443. case CHNAK:
  444. break;
  445. case CHCAN:
  446. xferStopped = TRUE;
  447. break;
  448. }
  449. break;
  450. }
  451. if(xferStopped || (((*sndStatus -= 1) & XM_RETRYMASK) == 0))
  452. *sndStatus |= XM_ABORT;
  453. else
  454. *sndStatus |= XM_BLKREPEAT;
  455. if(!xferStopped)
  456. showBErrors(++xferErrors);
  457. return(FALSE);
  458. }
  459. /*---------------------------------------------------------------------------*/
  460. /* XM_SndEnd() - [mbb] */
  461. /*---------------------------------------------------------------------------*/
  462. BOOL NEAR XM_SndEnd()
  463. {
  464. BYTE work[3];
  465. WORD retry;
  466. LoadString(hInst, STR_SE, (LPSTR) work, 4); /* mbbx 1.04: REZ... */
  467. bSetup(work);
  468. for(retry = XM_RETRIES; retry > 0; retry -= 1) /* mbbx 1.04: relax */
  469. {
  470. modemWr(CHEOT);
  471. if(xferPSChar) /* mbbx 1.02: packet switching... */
  472. modemWr(xferPSChar);
  473. if(waitRcvChar(work, XM_WAITNEXTBLK, 0, CHACK, CHCAN, 0)) /* mbbx 1.04: relax 15 -> 60 */
  474. {
  475. switch(work[0])
  476. {
  477. case CHACK:
  478. return(TRUE);
  479. case CHCAN:
  480. xferStopped = TRUE;
  481. break;
  482. }
  483. }
  484. if(xferStopped)
  485. break;
  486. showBErrors(++xferErrors);
  487. }
  488. return(FALSE);
  489. }
  490. /*---------------------------------------------------------------------------*/
  491. /* XM_SndAbort() - [mbb] */
  492. /*---------------------------------------------------------------------------*/
  493. VOID NEAR XM_SndAbort()
  494. {
  495. BYTE work[1];
  496. sndAbort();
  497. modemWr(CHCAN);
  498. modemWr(CHCAN);
  499. modemWr(CHCAN);
  500. modemWr(CHCAN);
  501. modemWr(CHCAN);
  502. modemWr(BS);
  503. modemWr(BS);
  504. modemWr(BS);
  505. modemWr(BS);
  506. modemWr(BS);
  507. if(xferPSChar) /* mbbx 1.02: packet switching */
  508. modemWr(xferPSChar);
  509. }
  510. /*---------------------------------------------------------------------------*/
  511. /* XM_CheckSum() - [mbb] */
  512. /*---------------------------------------------------------------------------*/
  513. BYTE XM_CheckSum(BYTE *dataBlock, WORD blockSize) /* mbbx 2.00: NEAR -> FAR */
  514. {
  515. BYTE XM_CheckSum = 0;
  516. while(blockSize > 0)
  517. XM_CheckSum += dataBlock[--blockSize];
  518. return(XM_CheckSum);
  519. }
  520. /*---------------------------------------------------------------------------*/
  521. /* XM_CalcCRC() - [mbb] */
  522. /*---------------------------------------------------------------------------*/
  523. WORD XM_CalcCRC(BYTE *dataBlock, INT blockSize)
  524. {
  525. WORD XM_CalcCRC = 0;
  526. INT ndx;
  527. while(--blockSize >= 0)
  528. {
  529. XM_CalcCRC = XM_CalcCRC ^ (((WORD) *dataBlock++) << 8);
  530. for(ndx = 0; ndx < 8; ndx += 1)
  531. {
  532. if(XM_CalcCRC & 0x8000)
  533. XM_CalcCRC = (XM_CalcCRC << 1) ^ 0x1021;
  534. else
  535. XM_CalcCRC = (XM_CalcCRC << 1);
  536. }
  537. }
  538. return(XM_CalcCRC & 0xFFFF);
  539. }
  540. /*---------------------------------------------------------------------------*/
  541. /* UTILITIES --> file buffering to be used by all RCV protocols !!! [mbb] */
  542. /*---------------------------------------------------------------------------*/
  543. HANDLE hXfrBuf;
  544. LPSTR lpXfrBuf;
  545. WORD wXfrBufSize;
  546. WORD wXfrBufBytes;
  547. WORD wXfrBufIndex;
  548. WORD wXfrBufExtend;
  549. BOOL initXfrBuffer(WORD wBufSize)
  550. {
  551. wXfrBufSize = wBufSize;
  552. if((hXfrBuf = GlobalAlloc(GMEM_MOVEABLE, (DWORD) wXfrBufSize)) != NULL)
  553. {
  554. #ifdef ORGCODE
  555. if((lpXfrBuf = GlobalWire(hXfrBuf)) != NULL)
  556. #else
  557. if((lpXfrBuf = GlobalLock(hXfrBuf)) != NULL)
  558. #endif
  559. {
  560. wXfrBufBytes = 0;
  561. wXfrBufIndex = 0;
  562. wXfrBufExtend = 0;
  563. return(TRUE);
  564. }
  565. GlobalFree(hXfrBuf);
  566. }
  567. rcvFileErr();
  568. return(FALSE);
  569. }
  570. WORD readXfrBuffer(BYTE *dataBlock, WORD blockSize, BOOL bBlkRepeat)
  571. {
  572. if(!bBlkRepeat)
  573. wXfrBufIndex += wXfrBufExtend;
  574. if((wXfrBufIndex+blockSize) > wXfrBufBytes)
  575. {
  576. if((wXfrBufBytes -= wXfrBufIndex) > 0)
  577. lmovmem(lpXfrBuf+wXfrBufIndex, lpXfrBuf, wXfrBufBytes);
  578. if((wXfrBufIndex = (WORD)_lread(xferRefNo, lpXfrBuf, wXfrBufSize-wXfrBufBytes)) == (WORD)-1)
  579. {
  580. return((WORD)-1);
  581. }
  582. wXfrBufBytes += wXfrBufIndex;
  583. wXfrBufIndex = 0;
  584. }
  585. if((wXfrBufExtend = (wXfrBufBytes-wXfrBufIndex)) > 0)
  586. {
  587. if(wXfrBufExtend > blockSize)
  588. wXfrBufExtend = blockSize;
  589. lmovmem(lpXfrBuf+wXfrBufIndex, (LPSTR) dataBlock, wXfrBufExtend);
  590. if(wXfrBufExtend < blockSize)
  591. memset(dataBlock+wXfrBufExtend, CNTRLZ, blockSize-wXfrBufExtend);
  592. }
  593. return(wXfrBufExtend);
  594. }
  595. BOOL writeXfrBuffer(BYTE *dataBlock, WORD blockSize,BOOL bBlkRepeat)
  596. {
  597. if(!bBlkRepeat)
  598. wXfrBufBytes += wXfrBufExtend;
  599. if((wXfrBufBytes+blockSize) > wXfrBufSize)
  600. {
  601. if(_lwrite(xferRefNo, lpXfrBuf, wXfrBufBytes) != wXfrBufBytes)
  602. {
  603. rcvFileErr();
  604. return(FALSE);
  605. }
  606. wXfrBufBytes = 0;
  607. }
  608. lmovmem((LPSTR) dataBlock, lpXfrBuf+wXfrBufBytes, wXfrBufExtend = blockSize);
  609. return(TRUE);
  610. }
  611. BOOL clearXfrBuffer()
  612. {
  613. if(wXfrBufExtend > 0)
  614. {
  615. while(wXfrBufExtend > 0) /* mbbx 1.04 ... */
  616. {
  617. if(*(lpXfrBuf+(wXfrBufBytes+wXfrBufExtend-1)) != CNTRLZ)
  618. break;
  619. wXfrBufExtend -= 1;
  620. }
  621. wXfrBufBytes += wXfrBufExtend;
  622. wXfrBufExtend = 0;
  623. }
  624. if(wXfrBufBytes > 0)
  625. {
  626. if(_lwrite(xferRefNo, lpXfrBuf, wXfrBufBytes) != wXfrBufBytes)
  627. {
  628. rcvFileErr();
  629. return(FALSE);
  630. }
  631. wXfrBufBytes = 0;
  632. }
  633. return(TRUE);
  634. }
  635. VOID freeXfrBuffer()
  636. {
  637. #ifdef ORGCODE
  638. GlobalUnWire(hXfrBuf);
  639. #else
  640. GlobalUnlock(hXfrBuf);
  641. #endif
  642. GlobalFree(hXfrBuf);
  643. }