Windows NT 4.0 source code leak
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

4 years ago
  1. /* Setup Instatllation Program
  2. * (C) Copyright 1987 by Microsoft
  3. * Written By Steven Zeck
  4. *
  5. * All the generic I/O functions are defined here.
  6. *************************************************************************/
  7. #include "core.h"
  8. #include <fcntl.h>
  9. #include <io.h>
  10. #include <errno.h>
  11. #include <sys\types.h>
  12. #include <sys\stat.h>
  13. #include <crtapi.h>
  14. #define FAST
  15. //#define FAST _fastcall
  16. int FAST writeOutBuff(char c);
  17. int _cdecl _far _fmemcmp(const void far *, const void far *, int);
  18. int _cdecl _far _fmemcpy(const void far *, const void far *, int);
  19. long cbExpanded;
  20. FARB pInBuff, pInBuffEnd;
  21. FARB pOutBuff, pOutBuffEnd;
  22. int fhFrom, fhTo;
  23. char cPartFile; // file part of multi disk file
  24. /* loadFile - load a file into far memory
  25. *
  26. * Inputs
  27. * The global ST
  28. * Returns
  29. *
  30. ****************************************************************************/
  31. loadFile (pST)
  32. ST *pST;
  33. {
  34. int fChange, cbRead;
  35. int fh;
  36. long cb;
  37. char buffT[TOKEN_MAX];
  38. strcat (strcpy(buffT, pST->fileName), ".sus");
  39. while ((fh = RpcOpen(buffT, O_RDONLY | O_BINARY)) == -1) {
  40. if (errno == ENOENT)
  41. if (fChange = changeDisk(buffT)) {
  42. if (fChange == DISKCHANGED && buffT[1] == ':')
  43. buffT[0] = pCopyDrive->v.pVal[0];
  44. continue;
  45. }
  46. terminate("Can't open setup file: %s", buffT);
  47. }
  48. cb = RpcLseek(fh, 0L, 2);
  49. if (cb > 0xffff)
  50. terminate("Setup file over 64K\n");
  51. RpcLseek(fh, 0L, 0);
  52. /* check to see if the script is compressed */
  53. if ((cbRead = readFar(fh, pCopyBuff, COPYBUF_MAX)) > sizeof(FH) &&
  54. _fmemcmp(((FH far *)pCopyBuff)->rgMagic, magicVal, cbMagic) == 0) {
  55. pInBuff = pCopyBuff + sizeof(FH);
  56. pInBuffEnd = pCopyBuff + cbRead;
  57. pOutBuff = pInBuffEnd;
  58. pOutBuffEnd = pCopyBuff2 + COPYBUF_MAX;
  59. pST->cbFile = cbExpanded = ((FH far *)pCopyBuff)->cb;
  60. pST->pBuff = pST->pBuffCur = fmemory(pST->cbFile);
  61. if (pST->cbFile > pOutBuffEnd - pOutBuff)
  62. terminate("Script file too big for compression\n");
  63. unpack();
  64. _fmemcpy(pST->pBuff, pInBuffEnd, pST->cbFile);
  65. }
  66. else {
  67. pST->cbFile = cb;
  68. pST->pBuff = pST->pBuffCur = fmemory((int) cb);
  69. _fmemcpy(pST->pBuff, pCopyBuff, cbRead);
  70. readFar(fh, pST->pBuff+cbRead, (int) cb-cbRead);
  71. }
  72. RpcClose(fh);
  73. }
  74. /* open an file for input
  75. *
  76. * Inputs
  77. * name of file
  78. * Returns
  79. *
  80. ****************************************************************************/
  81. int pascal openFile(pName, mode)
  82. pSZ pName;
  83. int mode;
  84. {
  85. static pSZ lastName;
  86. if (pName)
  87. lastName = pName;
  88. else
  89. goto prompt;
  90. while ((fhFrom = RpcOpen(lastName, mode, S_IWRITE | S_IREAD )) == -1) {
  91. if (errno == ENOENT)
  92. prompt:
  93. if (changeDisk(lastName))
  94. continue;
  95. terminate("Can't open file: %s", lastName);
  96. }
  97. return(fhFrom);
  98. }
  99. /* copyFile - a copy from one place to another
  100. *
  101. * Inputs
  102. * Source and desinstation files
  103. *
  104. ****************************************************************************/
  105. copyFile(pFrom, pTo)
  106. pSZ pFrom;
  107. pSZ pTo;
  108. {
  109. UINT cbRead;
  110. FH far *pFH;
  111. fhTo = openFile(pTo, O_CREAT | O_TRUNC| O_WRONLY | O_BINARY);
  112. openFile(pFrom, O_RDONLY | O_BINARY);
  113. outStat("Copying file to %s", pTo);
  114. /* check to see if the files is compressed */
  115. if ((cbRead = readFar(fhFrom, pCopyBuff, COPYBUF_MAX)) > sizeof(FH) &&
  116. _fmemcmp(((FH far *)pCopyBuff)->rgMagic, magicVal, cbMagic) == 0) {
  117. pInBuff = pCopyBuff + sizeof(FH);
  118. pInBuffEnd = pCopyBuff + cbRead;
  119. pOutBuff = pCopyBuff2;
  120. pOutBuffEnd = pCopyBuff2 + COPYBUF_MAX;
  121. cbExpanded = ((FH far *)pCopyBuff)->cb;
  122. cPartFile = 1;
  123. unpack();
  124. writeOutBuff(0);
  125. }
  126. else {
  127. do {
  128. writeFar(fhTo, pCopyBuff, cbRead);
  129. } while ((cbRead = readFar(fhFrom, pCopyBuff, COPYBUF_MAX)));
  130. }
  131. setCreateDate(fhFrom, fhTo);
  132. RpcClose(fhFrom);
  133. RpcClose(fhTo);
  134. }
  135. #define notEof() (cbOut < cbExpanded)
  136. #define readChar() (pInBuff < pInBuffEnd)? *pInBuff++: readInBuff()
  137. #define writeChar(c) if (pOutBuff < pOutBuffEnd) *pOutBuff++=c; else writeOutBuff(c);
  138. char FAST readInBuff(void)
  139. {
  140. int cbRead;
  141. Bool fNewOpen = FALSE;
  142. pInBuff = pCopyBuff;
  143. while (!(cbRead = readFar(fhFrom, pCopyBuff, COPYBUF_MAX))) {
  144. // change disks
  145. RpcClose(fhFrom);
  146. openFile(NIL, O_RDONLY | O_BINARY);
  147. fNewOpen++;
  148. }
  149. if (fNewOpen) { /* check for valide continued file */
  150. if (memcmp(pInBuff, magicVal, cbMagic-1) != 0 ||
  151. pInBuff[7] != ++cPartFile)
  152. terminate("Wrong part of multi disk file");
  153. pInBuff += cbMagic;
  154. }
  155. pInBuffEnd = pCopyBuff + cbRead;
  156. return(*pInBuff++);
  157. }
  158. int FAST writeOutBuff(char c)
  159. {
  160. writeFar(fhTo, pCopyBuff2, pOutBuff - pCopyBuff2);
  161. pOutBuff = pCopyBuff2;
  162. *pOutBuff++ = c;
  163. }
  164. #define cbIndex 2 /* encode string into position and length */
  165. #define cBufMax 4096 /* size of ring buffer */
  166. #define cStrMax (16 + cbIndex) /* upper limit for match_length */
  167. UCHAR ringBuf[cBufMax+cStrMax-1]; /* ring buffer of size cBufMax, with extra cStrMax-1 bytes
  168. to facilitate string comparison */
  169. #ifdef cVERSION
  170. unpack(void) /* Just the reverse of Encode(). */
  171. {
  172. int i, cb, oStart;
  173. register int iBufCur;
  174. unsigned char c;
  175. unsigned int flags;
  176. long cbOut;
  177. memset(ringBuf, ' ', cBufMax - cStrMax);
  178. iBufCur = cBufMax - cStrMax;
  179. flags = 0;
  180. cbOut = 0;
  181. while(notEof()) {
  182. c = readChar();
  183. /* high order byte counts the # bits used in the low order byte */
  184. if (((flags >>= 1) & 0x100) == 0) {
  185. flags = c | 0xff00; /* set bit mask describing the next 8 bytes */
  186. c = readChar();
  187. }
  188. if (flags & 1) {
  189. /* just store the literal character into the buffer */
  190. writeChar(c);
  191. cbOut++;
  192. ringBuf[iBufCur++] = c;
  193. iBufCur &= cBufMax - 1;
  194. } else {
  195. /* extract the buffer offset and count to unpack */
  196. cb = readChar();
  197. oStart = (cb & 0xf0) << 4 | c;
  198. cb = (cb & 0x0f) + cbIndex;
  199. for (i = 0; i <= cb; i++) {
  200. c = ringBuf[(oStart + i) & (cBufMax - 1)];
  201. writeChar(c);
  202. cbOut++;
  203. ringBuf[iBufCur++] = c;
  204. iBufCur &= cBufMax - 1;
  205. }
  206. }
  207. }
  208. }
  209. #endif
  210. /* getline - read another line into the global line buffer
  211. *
  212. * Inputs
  213. * current TS & buffers
  214. * Returns
  215. *
  216. ****************************************************************************/
  217. Bool getline ()
  218. {
  219. char far *pFrom;
  220. register UCHAR *pTo, c;
  221. UINT cbLeft;
  222. pTo = pLineCur = lineBuff;
  223. pFrom = pSTCur->pBuffCur;
  224. cbLeft = pSTCur->cbFile - (UINT) ((long) pFrom - (long) pSTCur->pBuff);
  225. if (!cbLeft)
  226. return(FALSE);
  227. while (cbLeft != 0) {
  228. c = *pFrom++;
  229. cbLeft--;
  230. if (! (c&0x80) && isLineEnd(c)) {
  231. if (cbLeft && isLineEnd(*pFrom)) {
  232. cbLeft--;
  233. pFrom++;
  234. }
  235. break;
  236. }
  237. *pTo++ = c;
  238. }
  239. *pTo = NIL;
  240. pSTCur->pBuffCur = pFrom;
  241. pSTCur->lineCur++;
  242. tokenPeek = NIL;
  243. return(TRUE);
  244. }
  245. /* centerOut/outStat/lineOut - output text to the screen
  246. *
  247. * Inputs
  248. * text to output
  249. * Returns
  250. *
  251. ****************************************************************************/
  252. void pascal centerOut(atLine, pText)
  253. int atLine;
  254. pSZ pText;
  255. {
  256. int cb;
  257. cb = strlen(pText);
  258. textOut(atLine, (80 - cb) / 2, pText);
  259. }
  260. void outStat(format, a1, a2, a3, a4) /* output message at status line */
  261. pSZ format;
  262. {
  263. char buffT[160];
  264. sprintf(buffT, format, a1, a2, a3, a4);
  265. buffT[80] = NIL;
  266. textOut(cCrtLineMax, 1, buffT);
  267. fillCrt(cCrtLineMax, strlen(buffT)+1, cCrtLineMax, 81, defCrtAttr, ' ');
  268. }
  269. void pascal lineOut(pLine) /* plain message, but with scrolling */
  270. pSZ pLine;
  271. {
  272. if (curCrtLine > cCrtLineMax-1) { /* need to scroll up */
  273. curCrtLine = cCrtLineMax-1;
  274. scrollUp();
  275. }
  276. textOut(curCrtLine++, 1, pLine);
  277. }
  278. /* getInput - get user input into a buffer
  279. *
  280. * Inputs
  281. * Line, column to get input
  282. * Symbol table to return value
  283. * Returns
  284. *
  285. ****************************************************************************/
  286. void pascal getInput(row, column, pSY)
  287. int row;
  288. int column;
  289. SY *pSY;
  290. {
  291. char buffT[TOKEN_MAX];
  292. int cb;
  293. pSZ pT;
  294. char aChar[2];
  295. buffT[0] = NIL;
  296. aChar[1] = NIL;
  297. if (pSY->type == charSYT) {
  298. strcpy(buffT, pSY->v.pVal);
  299. free(pSY->v.pVal);
  300. }
  301. defCrtAttr--;
  302. textOut(row, column, buffT);
  303. cb = strlen(buffT);
  304. pT = buffT + cb;
  305. while((aChar[0] = RpcGetch()) != '\r') {
  306. if (aChar[0] == '\b') {
  307. if (cb) {
  308. cb--;
  309. pT--;
  310. textOut(row, column+cb, " ");
  311. moveTo(row, column+cb);
  312. }
  313. }
  314. else {
  315. textOut(row, column+cb, aChar);
  316. cb++;
  317. *pT++ = aChar[0];
  318. }
  319. }
  320. *pT = NIL;
  321. pSY->type = charSYT;
  322. pSY->v.pVal = newStr(buffT);
  323. defCrtAttr++;
  324. }
  325. /* changeDisk - ask the user to change disks
  326. *
  327. * Inputs
  328. * What your were looking for
  329. * Returns
  330. * FALSE - If you should give up
  331. * TRUE - If you should try again
  332. * DISKCHAcBufMaxGED - If you should try again with a different disk drive
  333. *
  334. ****************************************************************************/
  335. Bool pascal changeDisk(pcBufMaxame)
  336. pSZ pcBufMaxame;
  337. {
  338. char buffT[TOKEN_MAX], buffFile[80];
  339. char lastVolId[20];
  340. strcpy(lastVolId, volId);
  341. outStat("Insert disk `%s': \x11\xc4\xd9 to continue, Esc to change drive",
  342. pVolId->v.pVal);
  343. strcpy(buffT, pCopyDrive->v.pVal);
  344. if (RpcGetch() == 0x1b){
  345. lineOut((char *) strcat( strcpy(buffFile, "Searching for file: "), pcBufMaxame) );
  346. dispatcher("dialog simplePath,drive,\"Enter new source drive (and path): \"");
  347. }
  348. outStat("");
  349. volIDFet();
  350. if (RpcStrcmpi(buffT, pCopyDrive->v.pVal))
  351. return (DISKCHANGED);
  352. if (RpcStrcmpi(lastVolId, volId))
  353. return (TRUE);
  354. return(FALSE);
  355. }
  356. /* printf/sprintf - minie printf for use
  357. *
  358. * control string with only %s & %d
  359. *
  360. * Scaled down printf function that doesn't drag in the whole
  361. *
  362. ****************************************************************************/
  363. int confd = 1;
  364. #define putc(c) *pOut++ = c;
  365. char outBuff[120];
  366. char *pOut = outBuff;
  367. pSZ sprintf(pBuff, a, b)
  368. char *pBuff;
  369. {
  370. pOut = pBuff;
  371. format(a, &b);
  372. *pOut = NIL;
  373. return(pBuff);
  374. }
  375. printf(a, b)
  376. {
  377. pOut = outBuff;
  378. format(a, &b);
  379. write(1, outBuff, pOut - outBuff);
  380. }
  381. format(format, pParms)
  382. register char *format;
  383. register char *pParms;
  384. {
  385. while(*format){
  386. switch(*format){
  387. case '%':
  388. switch(*++format){
  389. case 'd':
  390. {
  391. char T[10];
  392. RpcItoa(*(int *)pParms, T, 10);
  393. puts(T);
  394. pParms += sizeof(int);
  395. break;
  396. }
  397. case 's':
  398. puts(*(char **)pParms);
  399. pParms += sizeof(char *);
  400. break;
  401. }
  402. break;
  403. case '\n':
  404. putc('\r');
  405. default:
  406. putc(*format);
  407. }
  408. format++;
  409. }
  410. }
  411. puts(pString)
  412. register char *pString;
  413. {
  414. while(*pString){
  415. if (*pString == '\n')
  416. putc('\r');
  417. putc(*pString++);
  418. }
  419. }