mirror of https://github.com/lianthony/NT4.0
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.
563 lines
12 KiB
563 lines
12 KiB
/* Setup Instatllation Program
|
|
* (C) Copyright 1987 by Microsoft
|
|
* Written By Steven Zeck
|
|
*
|
|
* All the generic I/O functions are defined here.
|
|
*************************************************************************/
|
|
|
|
#include "core.h"
|
|
#include <fcntl.h>
|
|
#include <io.h>
|
|
#include <errno.h>
|
|
#include <sys\types.h>
|
|
#include <sys\stat.h>
|
|
#include <crtapi.h>
|
|
|
|
#define FAST
|
|
//#define FAST _fastcall
|
|
|
|
int FAST writeOutBuff(char c);
|
|
|
|
int _cdecl _far _fmemcmp(const void far *, const void far *, int);
|
|
int _cdecl _far _fmemcpy(const void far *, const void far *, int);
|
|
|
|
long cbExpanded;
|
|
FARB pInBuff, pInBuffEnd;
|
|
FARB pOutBuff, pOutBuffEnd;
|
|
int fhFrom, fhTo;
|
|
|
|
char cPartFile; // file part of multi disk file
|
|
|
|
|
|
/* loadFile - load a file into far memory
|
|
*
|
|
* Inputs
|
|
* The global ST
|
|
* Returns
|
|
*
|
|
****************************************************************************/
|
|
loadFile (pST)
|
|
ST *pST;
|
|
{
|
|
int fChange, cbRead;
|
|
int fh;
|
|
long cb;
|
|
char buffT[TOKEN_MAX];
|
|
|
|
strcat (strcpy(buffT, pST->fileName), ".sus");
|
|
|
|
while ((fh = RpcOpen(buffT, O_RDONLY | O_BINARY)) == -1) {
|
|
|
|
if (errno == ENOENT)
|
|
|
|
if (fChange = changeDisk(buffT)) {
|
|
if (fChange == DISKCHANGED && buffT[1] == ':')
|
|
buffT[0] = pCopyDrive->v.pVal[0];
|
|
|
|
continue;
|
|
}
|
|
|
|
terminate("Can't open setup file: %s", buffT);
|
|
}
|
|
|
|
cb = RpcLseek(fh, 0L, 2);
|
|
if (cb > 0xffff)
|
|
terminate("Setup file over 64K\n");
|
|
|
|
RpcLseek(fh, 0L, 0);
|
|
|
|
/* check to see if the script is compressed */
|
|
|
|
if ((cbRead = readFar(fh, pCopyBuff, COPYBUF_MAX)) > sizeof(FH) &&
|
|
_fmemcmp(((FH far *)pCopyBuff)->rgMagic, magicVal, cbMagic) == 0) {
|
|
|
|
pInBuff = pCopyBuff + sizeof(FH);
|
|
pInBuffEnd = pCopyBuff + cbRead;
|
|
|
|
pOutBuff = pInBuffEnd;
|
|
pOutBuffEnd = pCopyBuff2 + COPYBUF_MAX;
|
|
|
|
pST->cbFile = cbExpanded = ((FH far *)pCopyBuff)->cb;
|
|
pST->pBuff = pST->pBuffCur = fmemory(pST->cbFile);
|
|
|
|
if (pST->cbFile > pOutBuffEnd - pOutBuff)
|
|
terminate("Script file too big for compression\n");
|
|
|
|
unpack();
|
|
|
|
_fmemcpy(pST->pBuff, pInBuffEnd, pST->cbFile);
|
|
}
|
|
else {
|
|
|
|
pST->cbFile = cb;
|
|
pST->pBuff = pST->pBuffCur = fmemory((int) cb);
|
|
_fmemcpy(pST->pBuff, pCopyBuff, cbRead);
|
|
readFar(fh, pST->pBuff+cbRead, (int) cb-cbRead);
|
|
|
|
}
|
|
RpcClose(fh);
|
|
}
|
|
|
|
|
|
|
|
/* open an file for input
|
|
*
|
|
* Inputs
|
|
* name of file
|
|
* Returns
|
|
*
|
|
****************************************************************************/
|
|
|
|
int pascal openFile(pName, mode)
|
|
pSZ pName;
|
|
int mode;
|
|
{
|
|
static pSZ lastName;
|
|
|
|
if (pName)
|
|
lastName = pName;
|
|
else
|
|
goto prompt;
|
|
|
|
while ((fhFrom = RpcOpen(lastName, mode, S_IWRITE | S_IREAD )) == -1) {
|
|
|
|
if (errno == ENOENT)
|
|
prompt:
|
|
if (changeDisk(lastName))
|
|
continue;
|
|
|
|
terminate("Can't open file: %s", lastName);
|
|
}
|
|
|
|
return(fhFrom);
|
|
}
|
|
|
|
/* copyFile - a copy from one place to another
|
|
*
|
|
* Inputs
|
|
* Source and desinstation files
|
|
*
|
|
****************************************************************************/
|
|
|
|
copyFile(pFrom, pTo)
|
|
pSZ pFrom;
|
|
pSZ pTo;
|
|
{
|
|
UINT cbRead;
|
|
FH far *pFH;
|
|
|
|
|
|
fhTo = openFile(pTo, O_CREAT | O_TRUNC| O_WRONLY | O_BINARY);
|
|
openFile(pFrom, O_RDONLY | O_BINARY);
|
|
|
|
outStat("Copying file to %s", pTo);
|
|
|
|
/* check to see if the files is compressed */
|
|
|
|
if ((cbRead = readFar(fhFrom, pCopyBuff, COPYBUF_MAX)) > sizeof(FH) &&
|
|
_fmemcmp(((FH far *)pCopyBuff)->rgMagic, magicVal, cbMagic) == 0) {
|
|
|
|
pInBuff = pCopyBuff + sizeof(FH);
|
|
pInBuffEnd = pCopyBuff + cbRead;
|
|
pOutBuff = pCopyBuff2;
|
|
pOutBuffEnd = pCopyBuff2 + COPYBUF_MAX;
|
|
|
|
cbExpanded = ((FH far *)pCopyBuff)->cb;
|
|
cPartFile = 1;
|
|
|
|
unpack();
|
|
writeOutBuff(0);
|
|
}
|
|
else {
|
|
|
|
do {
|
|
writeFar(fhTo, pCopyBuff, cbRead);
|
|
} while ((cbRead = readFar(fhFrom, pCopyBuff, COPYBUF_MAX)));
|
|
}
|
|
|
|
setCreateDate(fhFrom, fhTo);
|
|
RpcClose(fhFrom);
|
|
RpcClose(fhTo);
|
|
}
|
|
|
|
#define notEof() (cbOut < cbExpanded)
|
|
#define readChar() (pInBuff < pInBuffEnd)? *pInBuff++: readInBuff()
|
|
#define writeChar(c) if (pOutBuff < pOutBuffEnd) *pOutBuff++=c; else writeOutBuff(c);
|
|
|
|
|
|
char FAST readInBuff(void)
|
|
{
|
|
int cbRead;
|
|
Bool fNewOpen = FALSE;
|
|
|
|
pInBuff = pCopyBuff;
|
|
|
|
while (!(cbRead = readFar(fhFrom, pCopyBuff, COPYBUF_MAX))) {
|
|
|
|
// change disks
|
|
|
|
RpcClose(fhFrom);
|
|
openFile(NIL, O_RDONLY | O_BINARY);
|
|
fNewOpen++;
|
|
}
|
|
|
|
if (fNewOpen) { /* check for valide continued file */
|
|
|
|
if (memcmp(pInBuff, magicVal, cbMagic-1) != 0 ||
|
|
pInBuff[7] != ++cPartFile)
|
|
|
|
terminate("Wrong part of multi disk file");
|
|
|
|
pInBuff += cbMagic;
|
|
}
|
|
|
|
pInBuffEnd = pCopyBuff + cbRead;
|
|
|
|
return(*pInBuff++);
|
|
}
|
|
|
|
int FAST writeOutBuff(char c)
|
|
{
|
|
writeFar(fhTo, pCopyBuff2, pOutBuff - pCopyBuff2);
|
|
pOutBuff = pCopyBuff2;
|
|
*pOutBuff++ = c;
|
|
}
|
|
|
|
#define cbIndex 2 /* encode string into position and length */
|
|
#define cBufMax 4096 /* size of ring buffer */
|
|
#define cStrMax (16 + cbIndex) /* upper limit for match_length */
|
|
UCHAR ringBuf[cBufMax+cStrMax-1]; /* ring buffer of size cBufMax, with extra cStrMax-1 bytes
|
|
to facilitate string comparison */
|
|
|
|
#ifdef cVERSION
|
|
|
|
unpack(void) /* Just the reverse of Encode(). */
|
|
{
|
|
int i, cb, oStart;
|
|
register int iBufCur;
|
|
unsigned char c;
|
|
unsigned int flags;
|
|
long cbOut;
|
|
|
|
memset(ringBuf, ' ', cBufMax - cStrMax);
|
|
iBufCur = cBufMax - cStrMax;
|
|
flags = 0;
|
|
cbOut = 0;
|
|
|
|
while(notEof()) {
|
|
|
|
c = readChar();
|
|
|
|
/* high order byte counts the # bits used in the low order byte */
|
|
|
|
if (((flags >>= 1) & 0x100) == 0) {
|
|
|
|
flags = c | 0xff00; /* set bit mask describing the next 8 bytes */
|
|
c = readChar();
|
|
}
|
|
if (flags & 1) {
|
|
|
|
/* just store the literal character into the buffer */
|
|
|
|
writeChar(c);
|
|
cbOut++;
|
|
ringBuf[iBufCur++] = c;
|
|
iBufCur &= cBufMax - 1;
|
|
|
|
} else {
|
|
|
|
/* extract the buffer offset and count to unpack */
|
|
|
|
cb = readChar();
|
|
|
|
oStart = (cb & 0xf0) << 4 | c;
|
|
cb = (cb & 0x0f) + cbIndex;
|
|
|
|
for (i = 0; i <= cb; i++) {
|
|
|
|
c = ringBuf[(oStart + i) & (cBufMax - 1)];
|
|
writeChar(c);
|
|
cbOut++;
|
|
ringBuf[iBufCur++] = c;
|
|
iBufCur &= cBufMax - 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/* getline - read another line into the global line buffer
|
|
*
|
|
* Inputs
|
|
* current TS & buffers
|
|
* Returns
|
|
*
|
|
****************************************************************************/
|
|
Bool getline ()
|
|
{
|
|
char far *pFrom;
|
|
register UCHAR *pTo, c;
|
|
UINT cbLeft;
|
|
|
|
pTo = pLineCur = lineBuff;
|
|
pFrom = pSTCur->pBuffCur;
|
|
cbLeft = pSTCur->cbFile - (UINT) ((long) pFrom - (long) pSTCur->pBuff);
|
|
|
|
if (!cbLeft)
|
|
return(FALSE);
|
|
|
|
while (cbLeft != 0) {
|
|
|
|
c = *pFrom++;
|
|
cbLeft--;
|
|
|
|
if (! (c&0x80) && isLineEnd(c)) {
|
|
if (cbLeft && isLineEnd(*pFrom)) {
|
|
cbLeft--;
|
|
pFrom++;
|
|
}
|
|
break;
|
|
}
|
|
*pTo++ = c;
|
|
}
|
|
*pTo = NIL;
|
|
pSTCur->pBuffCur = pFrom;
|
|
pSTCur->lineCur++;
|
|
tokenPeek = NIL;
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
|
|
/* centerOut/outStat/lineOut - output text to the screen
|
|
*
|
|
* Inputs
|
|
* text to output
|
|
* Returns
|
|
*
|
|
****************************************************************************/
|
|
|
|
void pascal centerOut(atLine, pText)
|
|
int atLine;
|
|
pSZ pText;
|
|
{
|
|
int cb;
|
|
|
|
cb = strlen(pText);
|
|
textOut(atLine, (80 - cb) / 2, pText);
|
|
}
|
|
|
|
void outStat(format, a1, a2, a3, a4) /* output message at status line */
|
|
pSZ format;
|
|
{
|
|
char buffT[160];
|
|
|
|
sprintf(buffT, format, a1, a2, a3, a4);
|
|
buffT[80] = NIL;
|
|
|
|
textOut(cCrtLineMax, 1, buffT);
|
|
fillCrt(cCrtLineMax, strlen(buffT)+1, cCrtLineMax, 81, defCrtAttr, ' ');
|
|
}
|
|
|
|
void pascal lineOut(pLine) /* plain message, but with scrolling */
|
|
pSZ pLine;
|
|
{
|
|
if (curCrtLine > cCrtLineMax-1) { /* need to scroll up */
|
|
curCrtLine = cCrtLineMax-1;
|
|
scrollUp();
|
|
}
|
|
textOut(curCrtLine++, 1, pLine);
|
|
}
|
|
|
|
|
|
/* getInput - get user input into a buffer
|
|
*
|
|
* Inputs
|
|
* Line, column to get input
|
|
* Symbol table to return value
|
|
* Returns
|
|
*
|
|
****************************************************************************/
|
|
|
|
void pascal getInput(row, column, pSY)
|
|
int row;
|
|
int column;
|
|
SY *pSY;
|
|
{
|
|
char buffT[TOKEN_MAX];
|
|
int cb;
|
|
pSZ pT;
|
|
char aChar[2];
|
|
|
|
buffT[0] = NIL;
|
|
aChar[1] = NIL;
|
|
|
|
if (pSY->type == charSYT) {
|
|
|
|
strcpy(buffT, pSY->v.pVal);
|
|
free(pSY->v.pVal);
|
|
}
|
|
|
|
defCrtAttr--;
|
|
textOut(row, column, buffT);
|
|
|
|
cb = strlen(buffT);
|
|
pT = buffT + cb;
|
|
|
|
while((aChar[0] = RpcGetch()) != '\r') {
|
|
|
|
if (aChar[0] == '\b') {
|
|
if (cb) {
|
|
cb--;
|
|
pT--;
|
|
textOut(row, column+cb, " ");
|
|
moveTo(row, column+cb);
|
|
}
|
|
}
|
|
else {
|
|
textOut(row, column+cb, aChar);
|
|
cb++;
|
|
*pT++ = aChar[0];
|
|
}
|
|
}
|
|
*pT = NIL;
|
|
pSY->type = charSYT;
|
|
pSY->v.pVal = newStr(buffT);
|
|
|
|
defCrtAttr++;
|
|
}
|
|
|
|
|
|
/* changeDisk - ask the user to change disks
|
|
*
|
|
* Inputs
|
|
* What your were looking for
|
|
* Returns
|
|
* FALSE - If you should give up
|
|
* TRUE - If you should try again
|
|
* DISKCHAcBufMaxGED - If you should try again with a different disk drive
|
|
*
|
|
****************************************************************************/
|
|
|
|
Bool pascal changeDisk(pcBufMaxame)
|
|
pSZ pcBufMaxame;
|
|
{
|
|
char buffT[TOKEN_MAX], buffFile[80];
|
|
char lastVolId[20];
|
|
|
|
strcpy(lastVolId, volId);
|
|
|
|
outStat("Insert disk `%s': \x11\xc4\xd9 to continue, Esc to change drive",
|
|
pVolId->v.pVal);
|
|
|
|
strcpy(buffT, pCopyDrive->v.pVal);
|
|
|
|
if (RpcGetch() == 0x1b){
|
|
lineOut((char *) strcat( strcpy(buffFile, "Searching for file: "), pcBufMaxame) );
|
|
dispatcher("dialog simplePath,drive,\"Enter new source drive (and path): \"");
|
|
}
|
|
|
|
outStat("");
|
|
volIDFet();
|
|
|
|
if (RpcStrcmpi(buffT, pCopyDrive->v.pVal))
|
|
|
|
return (DISKCHANGED);
|
|
|
|
if (RpcStrcmpi(lastVolId, volId))
|
|
return (TRUE);
|
|
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
/* printf/sprintf - minie printf for use
|
|
*
|
|
|
|
* control string with only %s & %d
|
|
*
|
|
* Scaled down printf function that doesn't drag in the whole
|
|
*
|
|
****************************************************************************/
|
|
|
|
int confd = 1;
|
|
|
|
|
|
#define putc(c) *pOut++ = c;
|
|
|
|
char outBuff[120];
|
|
char *pOut = outBuff;
|
|
|
|
pSZ sprintf(pBuff, a, b)
|
|
char *pBuff;
|
|
{
|
|
pOut = pBuff;
|
|
format(a, &b);
|
|
*pOut = NIL;
|
|
return(pBuff);
|
|
}
|
|
|
|
printf(a, b)
|
|
{
|
|
pOut = outBuff;
|
|
format(a, &b);
|
|
write(1, outBuff, pOut - outBuff);
|
|
}
|
|
|
|
format(format, pParms)
|
|
register char *format;
|
|
register char *pParms;
|
|
{
|
|
|
|
while(*format){
|
|
|
|
switch(*format){
|
|
|
|
case '%':
|
|
|
|
switch(*++format){
|
|
|
|
case 'd':
|
|
{
|
|
char T[10];
|
|
|
|
RpcItoa(*(int *)pParms, T, 10);
|
|
|
|
puts(T);
|
|
|
|
pParms += sizeof(int);
|
|
break;
|
|
}
|
|
|
|
case 's':
|
|
puts(*(char **)pParms);
|
|
pParms += sizeof(char *);
|
|
break;
|
|
}
|
|
break;
|
|
|
|
case '\n':
|
|
putc('\r');
|
|
|
|
default:
|
|
putc(*format);
|
|
}
|
|
|
|
format++;
|
|
}
|
|
}
|
|
|
|
|
|
puts(pString)
|
|
register char *pString;
|
|
{
|
|
while(*pString){
|
|
|
|
if (*pString == '\n')
|
|
putc('\r');
|
|
|
|
putc(*pString++);
|
|
}
|
|
}
|