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.
 
 
 
 
 
 

573 lines
14 KiB

/* File: C:\WACKER\xfer\krm.c (Created: 28-Jan-1994)
* created from HAWIN source file
* krm.c -- Functions common to both kermit send and kermit receive
* routines.
*
* Copyright 1989,1990,1991,1994 by Hilgraeve Inc. -- Monroe, MI
* All rights reserved
*
* $Revision: 6 $
* $Date: 4/10/02 3:05p $
*/
#include <windows.h>
#pragma hdrstop
#include <time.h>
#include <stdlib.h>
#include <sys\types.h>
#include <sys\utime.h>
#include <term\res.h>
#include <tdll\stdtyp.h>
#include <tdll\mc.h>
#include <tdll\com.h>
#include <tdll\assert.h>
#include <tdll\session.h>
#include <tdll\load_res.h>
#include <tdll\xfer_msc.h>
#include <tdll\globals.h>
#include <tdll\file_io.h>
#if !defined(BYTE)
#define BYTE unsigned char
#endif
#include "cmprs.h"
#include "xfr_dsp.h"
#include "xfr_todo.h"
#include "xfr_srvc.h"
#include "xfer.h"
#include "xfer.hh"
#include "xfer_tsc.h"
#include "krm.h"
#include "krm.hh"
// int krm_dbg; /* used for real-time debugging using dbg.c */
// int k_useattr; /* send 'normalized' file names ? */
// int k_maxl; /* maximum packet length we'll take */
// int k_timeout; /* time they should wait for us */
// uchar k_chkt; /* check type we want to use */
// int k_retries; /* no. of retries */
// uchar k_markchar; /* first char of each packet */
// uchar k_eol; /* end of line character for packets */
// int k_npad; /* no. of pad chars. to send us */
// uchar k_padc; /* pad char. we want */
// struct s_krm_control FAR *kc;
// void (NEARF *KrmProgress)(HSESSION, bits);
// unsigned ke_msg[] =
// {
// TM_NULL,
// TM_NO_RESP,
// TM_GOT_RETRY,
// TM_ERR_DATA,
// TM_RMT_ERR,
// TM_BAD_FMT,
// TM_PCKT_REPT,
// TM_BAD_SEQ,
// TM_FAILED,
// };
/* for mapping Kermit result codes to Transfer Status Codes */
int kresult_code[] =
{
TSC_OK, /* KA_OK 0 */
TSC_USER_CANNED, /* KA_LABORT1 1 */
TSC_RMT_CANNED, /* KA_RABORT1 2 */
TSC_USER_CANNED, /* KA_LABORTALL 3 */
TSC_RMT_CANNED, /* KA_RABORTALL 4 */
TSC_USER_CANNED, /* KA_IMMEDIATE 5 */
TSC_RMT_CANNED, /* KA_RMTERR 6 */
TSC_LOST_CARRIER, /* KA_LOST_CARRIER 7 */
TSC_ERROR_LIMIT, /* KA_ERRLIMIT 8 */
TSC_OUT_OF_SEQ, /* KA_OUT_OF_SEQ 9 */
TSC_BAD_FORMAT, /* KA_BAD_FORMAT 10 */
TSC_TOO_MANY, /* KA_TOO_MANY 11 */
TSC_CANT_OPEN, /* KA_CANT_OPEN 12 */
TSC_DISK_FULL, /* KA_DISK_FULL 13 */
TSC_DISK_ERROR, /* KA_DISK_ERROR 14 */
TSC_OLDER_FILE, /* KA_OLDER_FILE 15 */
TSC_NO_FILETIME, /* KA_NO_FILETIME 16 */
TSC_WONT_CANCEL, /* KA_WONT_CANCEL 17 */
TSC_VIRUS_DETECT, /* KA_VIRUS_DETECT 18 */
TSC_REFUSE /* KA_USER_REFUSED 19 */
};
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* krmGetParameters
*
* DESCRIPTION:
* This function is called to initialize all of the user settable values
* that get passed in from the parameters dialog box.
*
* ARGUMENTS:
* kc -- pointer to the Kermit data block
*
* RETURNS:
* Nothing.
*
*/
void krmGetParameters(ST_KRM *kc)
{
XFR_PARAMS *pX;
XFR_KR_PARAMS *pK;
pX = (XFR_PARAMS *)0;
xfrQueryParameters(sessQueryXferHdl(kc->hSession), (VOID **)&pX);
assert(pX);
if (pX != (XFR_PARAMS *)0)
kc->k_useattr = pX->fUseDateTime;
pK = (XFR_KR_PARAMS *)xfer_get_params(kc->hSession, XF_KERMIT);
assert(pK);
if (pK)
{
kc->k_maxl = pK->nBytesPerPacket;
kc->k_timeout = pK->nSecondsWaitPacket;
kc->k_chkt = (BYTE)pK->nErrorCheckSize;
kc->k_retries = pK->nRetryCount;
kc->k_markchar = (BYTE)pK->nPacketStartChar;
kc->k_eol = (BYTE)pK->nPacketEndChar;
kc->k_npad = pK->nNumberPadChars;
kc->k_padc = (BYTE)pK->nPadChar;
}
else
{
//
// Set to the defaults set in xfrInitializeKermit().
//
kc->k_maxl = 94;
kc->k_timeout = 5;
kc->k_chkt = 1;
kc->k_retries = 5;
kc->k_markchar = 1;
kc->k_eol = 13;
kc->k_npad = 0;
kc->k_padc = 0;
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* ksend_packet
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void ksend_packet(ST_KRM *kc,
unsigned char type,
unsigned dlength,
int seq,
KPCKT FAR *pckt)
{
unsigned csum;
unsigned crc;
int i;
char *cp;
int iSendStatus = COM_OK;
if (type == 'N' || type == 'E') /* wait for input to clear */
ComRcvBufrClear(kc->hCom);
/* send any padding necessary */
for (i = kc->its_npad + 1; --i > 0; )
ComSendCharNow(kc->hCom, kc->its_padc);
/* when received, only packet data is valid, we fill in remainder */
pckt->pmark = kc->k_markchar;
pckt->plen = (int)tochar(dlength + 3);
if (kc->its_chkt == K_CHK2)
pckt->plen += 1;
else if (kc->its_chkt == K_CHK3)
pckt->plen += 2;
pckt->pseq = (int)tochar(seq);
pckt->ptype = type;
/* now figure check bytes */
if (kc->its_chkt == K_CHK3)
{
crc = kcalc_crc((unsigned)0,
(unsigned char *)&pckt->plen,
(int)dlength + 3);
cp = pckt->pdata + dlength;
*cp++ = (char)tochar((crc >> 12) & 0x0F);
*cp++ = (char)tochar((crc >> 6) & 0x3F);
*cp++ = (char)tochar(crc & 0x3F);
}
else
{
csum = 0;
cp = (char *)&pckt->plen;
for (i = dlength + 4; --i > 0; )
csum += *cp++;
/* cp is left pointing to first byte past data */
if (kc->its_chkt == K_CHK2)
{
*cp++ = (char)tochar((csum >> 6) & 0x3F);
*cp++ = (char)tochar(csum & 0x3F);
}
else
*cp++ = (char)tochar((((csum & 0xC0) >> 6) + csum) & 0x3F);
}
*cp = kc->its_eol;
/* send off all chars in buffer */
// (VOID)mComSndBufr(comhdl, (char *)pckt,
// (uchar)(unchar(pckt->plen) + 3), /* include mark, len & eol */
// 100, kc->flagkey_hdl);
iSendStatus = ComSndBufrSend(kc->hCom,
(void *)pckt,
(int)(unchar(pckt->plen) + 3),
100);
assert(iSendStatus == COM_OK);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* krec_packet
*
* DESCRIPTION:
* Receive a kermit packet, check it for validity and return either the
* type of the received packet or an error code.
*
* ARGUMENTS:
* len
* seq
* data
*
* RETURNS:
*
*/
int krec_packet(ST_KRM *kc,
int *len,
int *seq,
unsigned char *data)
{
TCHAR c = 0;
char *bp;
char hdr[3];
int done, got_hdr;
int cnt, i;
long j;
unsigned chksum;
unsigned rchk;
long stime;
long timelimit = kc->its_timeout * 10L;
/* wait until any packet is transmitted */
// (VOID)mComSndBufrWait(comhdl, 100, kc->flagkey_hdl);
if (ComSndBufrWait(kc->hCom, 100) == COM_PORT_NOT_OPEN)
{
return(BAD_PACKET);
}
stime = (long)startinterval();
while (c != (int)kc->k_markchar)
{
if (j = xfer_user_interrupt(kc->hSession))
{
/* Yes, this is needed */
// XferAbort(kc->hSession, (LPVOID)((LPSTR)j));
xfer_user_abort(kc->hSession, j);
return(BAD_PACKET);
}
if (xfer_carrier_lost(kc->hSession))
{
return(BAD_PACKET);
}
(*kc->KrmProgress)(kc, 0);
// if ((c = mComRcvChar(comhdl)) == -1)
if (mComRcvChar(kc->hCom, &c) == 0)
{
if ((long)interval(stime) > timelimit)
{
return('T');
}
xfer_idle(kc->hSession, XFER_IDLE_IO);
}
else if (c != (int)kc->k_markchar)
{
}
else
; /* for lint */
}
getpacket:
chksum = 0;
done = got_hdr = FALSE;
bp = &hdr[0];
cnt = 3;
while (!done)
{
for (i = cnt + 1; --i > 0; )
{
// while ((c = mComRcvChar(comhdl)) == -1)
while (mComRcvChar(kc->hCom, &c) == 0)
{
if (j = xfer_user_interrupt(kc->hSession))
{
// XferAbort(kc->hSession, (LPVOID)((LPSTR)j));
xfer_user_abort(kc->hSession, j);
return(BAD_PACKET);
}
if (xfer_carrier_lost(kc->hSession))
{
return(BAD_PACKET);
}
(*kc->KrmProgress)(kc, 0);
if ((long)interval(stime) > timelimit)
{
return('T');
}
xfer_idle(kc->hSession, XFER_IDLE_IO);
}
*bp = (char)c;
if ((unsigned char)*bp == kc->k_markchar)
{
goto getpacket;
}
chksum += *bp++;
}
if (!got_hdr)
{
got_hdr = TRUE;
*seq = unchar(hdr[1]);
cnt = unchar(hdr[0]) - 2; /* we've already got seq & len chars */
if (cnt < 0 || cnt > 92)
{
return(BAD_PACKET);
}
bp = data;
}
else
done = TRUE;
}
bp -= kc->its_chkt; /* move pointer back to beginning of check field */
switch(kc->its_chkt)
{
case 1:
*len = cnt - 1;
chksum -= bp[0];
chksum = (((chksum & 0xC0) >> 6) + chksum) & 0x3F;
rchk = (unsigned char)unchar(bp[0]);
break;
case 2:
*len = cnt - 2;
chksum = (chksum - (bp[0] + bp[1])) & 0x0FFF;
rchk = ((unsigned char)unchar(bp[0]) << 6) + unchar(bp[1]);
break;
case 3:
*len = cnt - 3;
rchk = ((unsigned char)unchar(bp[0]) << 12) +
((unsigned char)unchar(bp[1]) << 6) +
unchar(bp[2]);
chksum = kcalc_crc((unsigned)0, hdr, 3);
if (*len > 0)
chksum = kcalc_crc(chksum, data, *len);
break;
default:
break;
}
*bp = '\0';
if (*len < 0 || chksum != rchk)
{
return(BAD_PACKET);
}
else
{
return(hdr[2]);
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* buildparams
*
* DESCRIPTION:
* Build a packet containing our initializing parameters. Return length of
* data in packet.
*
* ARGUMENTS:
* initiating -- TRUE if we're initiating the transfer, FALSE if we're ACKing
* its initializing packet
* bufr -- a place to put the results
* RETURNS:
*
*/
int buildparams(ST_KRM *kc, int initiating, unsigned char *bufr)
{
unsigned char *bp = bufr;
if (initiating) /* just tell them what we want to do */
{
*bp++ = (unsigned char)tochar(kc->k_maxl); /* MAXL */
*bp++ = (unsigned char)tochar(kc->k_timeout); /* TIME */
*bp++ = (unsigned char)tochar(kc->k_npad); /* NPAD */
*bp++ = (unsigned char)ctl(kc->k_padc); /* PADC */
*bp++ = (unsigned char)tochar(kc->k_eol); /* EOL */
*bp++ = K_QCTL; /* QCTL */
*bp++ = 'Y'; /* QBIN */
*bp++ = (unsigned char)(kc->k_chkt + '0'); /* CHKT */
*bp++ = K_REPT; /* REPT */
*bp++ = (unsigned char)tochar(CAPMASK_ATTR);/* CAPAS */
}
else /* we're responding to them */
{
/* MAXL */
*bp++ = (char)tochar(kc->k_maxl);
/* TIME */
*bp++ = (char)tochar((abs(kc->k_timeout - kc->its_timeout) <= 2) ?
kc->k_timeout + 2 : kc->k_timeout);
/* NPAD */
*bp++ = (unsigned char)tochar(kc->k_npad);
/* PADC */
*bp++ = (unsigned char)ctl(kc->k_padc);
/* EOL */
*bp++ = (unsigned char)tochar(kc->k_eol);
/* QCTL */
*bp++ = K_QCTL;
/* QBIN */
if (kc->its_qbin == 'Y')
kc->its_qbin = (char)(cnfgBitsPerChar(kc->hSession) == 8 ? 'N' : K_QBIN);
if (IN_RANGE(kc->its_qbin, 33, 62) || IN_RANGE(kc->its_qbin, 96, 126))
*bp++ = kc->its_qbin;
else
*bp++ = 'N', kc->its_qbin = '\0';
/* CHKT */
if (!IN_RANGE(kc->its_chkt, 1, 3))
kc->its_chkt = 1;
*bp++ = (unsigned char)(kc->its_chkt + '0');
/* REPT */
if (IN_RANGE(kc->its_rept, 33, 62) || IN_RANGE(kc->its_rept, 96, 126))
*bp++ = kc->its_rept;
else
*bp++ = ' ', kc->its_rept = '\0';
if (kc->its_capat) /* if sender can handle A packets, we can too */
*bp++ = tochar(CAPMASK_ATTR);
}
return (int)(bp - bufr);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* getparams
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
* nothing
*/
void getparams(ST_KRM *kc, int initiating, unsigned char *bufr)
{
if (!*bufr)
return;
kc->its_maxl = (*bufr == ' ' ? 80 : unchar(*bufr));
/* if user has shortened packet length, he must know something about
intervening transmission system that other end may not know about */
if (kc->its_maxl > kc->k_maxl)
kc->its_maxl = kc->k_maxl;
if (!*++bufr)
return;
kc->its_timeout = (*bufr == ' ' ? 10 : unchar(*bufr));
if (!initiating && abs(kc->k_timeout - kc->its_timeout) <= 2)
kc->its_timeout = kc->k_timeout + 2;
if (!*++bufr)
return;
kc->its_npad = unchar(*bufr);
if (!*++bufr)
return;
kc->its_padc = (char)(*bufr == ' ' ? '\0' : ctl(*bufr));
if (!*++bufr)
return;
kc->its_eol = (char)(*bufr == ' ' ? '\r' : unchar(*bufr));
if (!*++bufr)
return;
kc->its_qctl = (char)(*bufr == ' ' ? K_QCTL : *bufr);
if (!*++bufr)
return;
kc->its_qbin = *bufr;
if (initiating &&
!(IN_RANGE(kc->its_qbin, 33, 62) || IN_RANGE(kc->its_qbin, 96, 126)))
kc->its_qbin = '\0';
if (!*++bufr)
return;
kc->its_chkt = (unsigned char)(*bufr - '0');
if (initiating && kc->its_chkt != kc->k_chkt)
kc->its_chkt = 1;
if (!*++bufr)
return;
kc->its_rept = *bufr;
if (!(IN_RANGE(kc->its_rept, 33, 62) || IN_RANGE(kc->its_rept, 96, 126)))
kc->its_rept = '\0';
if (initiating && kc->its_rept != K_REPT)
kc->its_rept = '\0';
if (!*++bufr)
return;
if (unchar(*bufr) & CAPMASK_ATTR)
kc->its_capat = TRUE;
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* kcalc_crc
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
// #if FALSE /* implemented in machine code for speed */
unsigned kcalc_crc(unsigned crc, unsigned char *data, int cnt)
{
unsigned int c;
unsigned q;
while (cnt--)
{
c = *data++;
q = (crc ^ c) & 017;
crc = (crc >> 4) ^ (q * 010201);
q = (crc ^ (c >> 4)) & 017;
crc = (crc >> 4) ^ (q * 010201);
}
return(crc);
}
// #endif
/* end of krm.c */