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.

379 lines
9.8 KiB

  1. /* File: C:\WACKER\xfer\hpr_res.c (Created: 25-Jan-1995)
  2. * created from HAWIN source file
  3. * hpr_res.c -- Routines to implement HyperProtocol. These are the routines
  4. * that make character-by-character calls and must be fast
  5. *
  6. * Copyright 1989,1994 by Hilgraeve Inc. -- Monroe, MI
  7. * All rights reserved
  8. *
  9. * $Revision: 1 $
  10. * $Date: 10/05/98 1:16p $
  11. */
  12. // #define DEBUGSTR 1
  13. #include <windows.h>
  14. #include <setjmp.h>
  15. #include <time.h>
  16. #include <term\res.h>
  17. #include <sys\types.h>
  18. #include <sys\utime.h>
  19. #include <tdll\stdtyp.h>
  20. #include <tdll\mc.h>
  21. #include <tdll\com.h>
  22. #include <tdll\session.h>
  23. #include <tdll\load_res.h>
  24. #include <tdll\xfer_msc.h>
  25. #include <tdll\globals.h>
  26. #include <tdll\file_io.h>
  27. #if !defined(BYTE)
  28. #define BYTE unsigned char
  29. #endif
  30. #include "cmprs.h"
  31. #include "xfr_dsp.h"
  32. #include "xfr_todo.h"
  33. #include "xfr_srvc.h"
  34. #include "xfer.h"
  35. #include "xfer.hh"
  36. #include "xfer_tsc.h"
  37. #include "hpr.h"
  38. #include "hpr.hh"
  39. #include "hpr_sd.hh"
  40. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  41. * hr_collect_data
  42. *
  43. * DESCRIPTION:
  44. * Collects and stores bytes for HyperProtocol
  45. * save routine. This routine exits when one of several conditions
  46. * is detected and returns a code to indicate which condition caused
  47. * it to exit. Exit conditions are decribed below.
  48. * In any case, the checksum, crc, and character count variables have
  49. * valid values up to the point where collection stopped.
  50. *
  51. * ARGUMENTS:
  52. * charcount -- number of characters to collect
  53. * docheck -- TRUE if collected data should be subject to error checking
  54. * timeout -- idle time (in tenths of seconds) after which we should give
  55. * up and return HR_TIMEOUT
  56. *
  57. * RETURNS:
  58. * A status code is returned which may be one of:
  59. *
  60. * HR_COMPLETE -- The predetermined maximum received character count
  61. * was reached.
  62. * HR_BADCHECK -- All characters were received, but a checksum error
  63. * was detected.
  64. * HR_MESSAGE -- The message character, ASCII 01, was detected followed
  65. * by a character other than another ASCII 01. The 2nd
  66. * character of the sequence is NOT removed from the buffer.
  67. * HR_TIMEOUT -- There was a period of time during which no characters
  68. * were received that exceeded the predetermined limit.
  69. * HR_KBDINT -- The user typed an ESC key at the keyboard. This will only
  70. * be detected by the hr_collect_data routine if there is a
  71. * break in the received data.
  72. * HR_FILEERR -- An error occured while storing a byte of the received
  73. * data.
  74. * HR_LOST_CARR -- Carrier was lost while waiting for data
  75. *
  76. */
  77. int hr_collect_data(struct s_hc *hc, int *charcount, int docheck, long timeout)
  78. {
  79. HCOM hCom;
  80. register int ourcount = *charcount;
  81. int rcvd_msgnum = -1;
  82. int chkbytes_needed = 2;
  83. int iret;
  84. TCHAR cc;
  85. int got1 = FALSE;
  86. long timer;
  87. int result = HR_UNDECIDED;
  88. unsigned rcvd_checksum = 0;
  89. hCom = sessQueryComHdl(hc->hSession);
  90. for ( ; ; )
  91. {
  92. if (mComRcvChar(hCom, &cc) == 0)
  93. {
  94. timer = startinterval();
  95. while (mComRcvChar(hCom, &cc) == 0) /* while no chars */
  96. {
  97. xfer_idle(hc->hSession);
  98. iret = xfer_user_interrupt(hc->hSession);
  99. if (iret == XFER_ABORT)
  100. {
  101. result = HR_KBDINT;
  102. break;
  103. }
  104. else if (iret == XFER_SKIP)
  105. {
  106. hr_reject_file(hc, HRE_USER_SKIP);
  107. }
  108. if (xfer_carrier_lost(hc->hSession))
  109. {
  110. result = HR_LOST_CARR;
  111. break;
  112. }
  113. #if !defined(NOTIMEOUTS)
  114. if ((long)interval(timer) > timeout)
  115. {
  116. hrdsp_event(hc, HRE_TIMEOUT);
  117. result = HR_TIMEOUT;
  118. break;
  119. }
  120. #endif
  121. }
  122. if (result != HR_UNDECIDED)
  123. break;
  124. }
  125. if ((!got1 && cc != H_MSGCHAR) || (got1 && cc == H_MSGCHAR))
  126. {
  127. got1 = FALSE;
  128. if (hc->usecrc)
  129. h_crc_calc(hc, (BYTE)cc);
  130. if (ourcount > 0)
  131. {
  132. hc->h_checksum += (unsigned)cc;
  133. if ((*hc->rc.hr_ptr_putc)(hc, cc) == -1 /* ERROR */)
  134. {
  135. result = decompress_error() ? HR_DCMPERR : HR_FILEERR;
  136. break;
  137. }
  138. else if (--ourcount <= 0 && !docheck)
  139. {
  140. result = HR_COMPLETE;
  141. break;
  142. }
  143. }
  144. else if (rcvd_msgnum == -1)
  145. {
  146. rcvd_msgnum = cc;
  147. hc->h_checksum += (unsigned)cc;
  148. }
  149. else
  150. {
  151. rcvd_checksum +=
  152. ((unsigned)cc * (chkbytes_needed == 2 ? 1 : 256));
  153. if (--chkbytes_needed <= 0)
  154. {
  155. result = HR_COMPLETE;
  156. break;
  157. }
  158. }
  159. }
  160. else if (got1) /* got1 && cc != H_MSGCHAR */
  161. {
  162. result = HR_MESSAGE; /* leave char. in buffer */
  163. mComRcvBufrPutback(hCom, cc);
  164. break;
  165. }
  166. else /* !got1 && cc == H_MSGCHAR */
  167. got1 = TRUE;
  168. }
  169. if (result == HR_COMPLETE && docheck)
  170. {
  171. if (hc->usecrc)
  172. result = (hc->h_crc == 0 ? HR_COMPLETE : HR_BADCHECK);
  173. else if (hc->h_checksum != rcvd_checksum)
  174. result = HR_BADCHECK;
  175. if (result == HR_COMPLETE)
  176. if (rcvd_msgnum == hc->rc.expected_msg)
  177. hc->rc.expected_msg = ++hc->rc.expected_msg % 256;
  178. else
  179. result = HR_LOSTDATA;
  180. }
  181. *charcount = ourcount;
  182. if (hc->rc.virus_detected)
  183. result = HR_VIRUS_FOUND;
  184. return(result);
  185. }
  186. // extern char FAR *storageptr; /* place to put data as we receive it */
  187. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  188. * hr_storedata
  189. *
  190. * DESCRIPTION:
  191. * This is a little routine used by hr_collect_msg to collect the data
  192. * within a message. Data is normally written directly to the receive file.
  193. * This routine, however, collects it into memory.
  194. *
  195. * ARGUMENTS:
  196. * c -- a character to be stored
  197. *
  198. * RETURNS:
  199. * Returns the character stored.
  200. */
  201. int hr_storedata(struct s_hc *hc, int c)
  202. {
  203. *hc->storageptr++ = (char)c;
  204. return(c);
  205. }
  206. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  207. * hr_putc
  208. *
  209. * DESCRIPTION:
  210. * This is the normal function for dispatching received characters. It
  211. * is normally called through a pointer to a function. When decompression
  212. * is active, the pointer be redirected to point at the decompression
  213. * routine and the decompression code may then be calling this function.
  214. * In either case, this function writes one character to the output file
  215. * and counts it.
  216. *
  217. * ARGUMENTS:
  218. * c -- the character to be written
  219. *
  220. * RETURNS:
  221. * The argument.
  222. */
  223. int hr_putc(struct s_hc *hc, int c)
  224. {
  225. return (fio_putc(c, hc->fhdl));
  226. // return (FilePutc(c, hc->fhdl));
  227. }
  228. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  229. * hr_putc_vir
  230. *
  231. * DESCRIPTION:
  232. * This is the normal function for dispatching received characters. It
  233. * is normally called through a pointer to a function. When decompression
  234. * is active, the pointer be redirected to point at the decompression
  235. * routine and the decompression code may then be calling this function.
  236. * In either case, this function writes one character to the output file
  237. * and counts it.
  238. * This version also performs virus checking. If a virus is detected, the
  239. * StrSrchNextChar routine will call hr_virus_detect().
  240. *
  241. * ARGUMENTS:
  242. * c -- the character to be written
  243. *
  244. * RETURNS:
  245. * The argument.
  246. */
  247. int hr_putc_vir(struct s_hc *hc, int c)
  248. {
  249. // ++hc->h_filebytes;
  250. // StrSrchNextChar(hc->rc.ssmchVscan, (VOID FAR *)NULL, (UCHAR)c);
  251. return (fio_putc(c, hc->fhdl));
  252. // return (FilePutc(c, hc->fhdl));
  253. }
  254. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  255. * hr_toss
  256. *
  257. * DESCRIPTION:
  258. * This function is installed in place of hr_putc during periods between when
  259. * a data error has been detected and the transfer successfully resynchs so
  260. * that bogus data will not be stored in the output file. It merely tosses
  261. * the character.
  262. *
  263. * ARGUMENTS:
  264. * c -- the received character.
  265. *
  266. * RETURNS:
  267. * the argument
  268. */
  269. int hr_toss(struct s_hc *hc, int c)
  270. {
  271. /* throw character away without counting it */
  272. return(c);
  273. }
  274. // Resident routines for sending
  275. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  276. * hs_datasend
  277. *
  278. * DESCRIPTION:
  279. * Attempts to send enough data to complete the current data block (as
  280. * defined by (hc->blocksize).
  281. *
  282. * ARGUMENTS:
  283. * none
  284. *
  285. * RETURNS:
  286. * TRUE if all bytes were sent.
  287. * FALSE if an EOF is encountered prior to the end of the block.
  288. */
  289. int hs_datasend(struct s_hc *hc)
  290. {
  291. register int cc;
  292. register int count = hc->blocksize - hc->datacnt;
  293. for ( ; ; )
  294. {
  295. if ((cc = (*hc->sc.hs_ptrgetc)(hc)) == EOF)
  296. {
  297. hc->datacnt = hc->blocksize - count;
  298. return(FALSE);
  299. }
  300. hc->h_checksum += (unsigned)cc;
  301. if (hc->usecrc)
  302. h_crc_calc(hc, (BYTE)cc);
  303. HS_XMIT(hc, (BYTE)cc);
  304. if (--count == 0)
  305. {
  306. hc->datacnt = hc->blocksize - count;
  307. /* Display current compression status */
  308. hsdsp_compress(hc, compress_status() == COMPRESS_ACTIVE);
  309. return(TRUE);
  310. }
  311. }
  312. /*lint -unreachable*/
  313. }
  314. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  315. * hs_reteof
  316. *
  317. * DESCRIPTION:
  318. * This function merely returns an EOF code. Since all requests for file
  319. * characters are made through a pointer to a function, that pointer can
  320. * be set to this function to force the next request to return an EOF.
  321. * It is normally used to interrupt the transmission of data and force a
  322. * call to hs_filebreak to set a new location.
  323. *
  324. * ARGUMENTS:
  325. * none
  326. *
  327. * RETURNS:
  328. * Always returns EOF
  329. */
  330. int hs_reteof(struct s_hc *hc)
  331. {
  332. return(EOF);
  333. }
  334. /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  335. * hs_getc
  336. *
  337. * DESCRIPTION:
  338. * Fetches one character from the input file and counts it in h_filebytes.
  339. *
  340. * ARGUMENTS:
  341. * none
  342. *
  343. * RETURNS:
  344. * The character fetched.
  345. */
  346. int hs_getc(struct s_hc *hc)
  347. {
  348. return(fio_getc(hc->fhdl));
  349. // return(FileGetc(hc->fhdl));
  350. }