CONFIG.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:17k
源码类别:

操作系统开发

开发平台:

DOS

  1. /****************************************************************/
  2. /*                                                              */
  3. /*                          config.c                            */
  4. /*                            DOS-C                             */
  5. /*                                                              */
  6. /*                config.sys Processing Functions               */
  7. /*                                                              */
  8. /*                      Copyright (c) 1996                      */
  9. /*                      Pasquale J. Villani                     */
  10. /*                      All Rights Reserved                     */
  11. /*                                                              */
  12. /* This file is part of DOS-C.                                  */
  13. /*                                                              */
  14. /* DOS-C is free software; you can redistribute it and/or       */
  15. /* modify it under the terms of the GNU General Public License  */
  16. /* as published by the Free Software Foundation; either version */
  17. /* 2, or (at your option) any later version.                    */
  18. /*                                                              */
  19. /* DOS-C is distributed in the hope that it will be useful, but */
  20. /* WITHOUT ANY WARRANTY; without even the implied warranty of   */
  21. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    */
  22. /* the GNU General Public License for more details.             */
  23. /*                                                              */
  24. /* You should have received a copy of the GNU General Public    */
  25. /* License along with DOS-C; see the file COPYING.  If not,     */
  26. /* write to the Free Software Foundation, 675 Mass Ave,         */
  27. /* Cambridge, MA 02139, USA.                                    */
  28. /****************************************************************/
  29. #include "../../hdr/portab.h"
  30. #include "globals.h"
  31. /* $Logfile:   C:/dos-c/src/kernel/config.c_v  $ */
  32. #ifdef VERSION_STRINGS
  33. static BYTE *RcsId = "$Header:   C:/dos-c/src/kernel/config.c_v   1.6   22 Jan 1998  4:09:24   patv  $";
  34. #endif
  35. /* $Log:   C:/dos-c/src/kernel/config.c_v  $
  36.  * 
  37.  *    Rev 1.6   22 Jan 1998  4:09:24   patv
  38.  * Fixed pointer problems affecting SDA
  39.  *
  40.  *    Rev 1.5   04 Jan 1998 23:15:18   patv
  41.  * Changed Log for strip utility
  42.  * 
  43.  *    Rev 1.4   04 Jan 1998 17:26:14   patv
  44.  * Corrected subdirectory bug
  45.  * 
  46.  *    Rev 1.3   16 Jan 1997 12:46:50   patv
  47.  * pre-Release 0.92 feature additions
  48.  * 
  49.  *    Rev 1.1   29 May 1996 21:03:44   patv
  50.  * bug fixes for v0.91a
  51.  * 
  52.  *    Rev 1.0   19 Feb 1996  3:22:16   patv
  53.  * Added NLS, int2f and config.sys processing
  54.  */
  55. /* $EndLog$ */
  56. #if 0
  57. #define dos_open(x,y)   _open((const char *)(x),(y))
  58. #define dos_read(x,y,z) _read((int)(x),(void *)(y),(unsigned)(z))
  59. #define dos_close       _close
  60. #endif
  61. #ifdef KDB
  62. # include <alloc.h>
  63. # define KernelAlloc(x) adjust_far((void far *)malloc((unsigned long)(x)))
  64. #endif
  65. BYTE FAR *lpBase;
  66. static BYTE FAR *lpOldLast;
  67. static COUNT nCfgLine;
  68. static COUNT nPass;
  69. static BYTE szLine[256];
  70. static BYTE szBuf[256];
  71. int     singleStep = 0;
  72. VOID Buffers(BYTE *pLine);
  73. VOID Break(BYTE *pLine);
  74. VOID Device(BYTE *pLine);
  75. VOID Files(BYTE *pLine);
  76. VOID Fcbs(BYTE *pLine);
  77. VOID Lastdrive(BYTE *pLine);
  78. VOID Country(BYTE *pLine);
  79. VOID InitPgm(BYTE *pLine);
  80. VOID Switchar(BYTE *pLine);
  81. VOID CfgFailure(BYTE *pLine);
  82. VOID Stacks(BYTE *pLine);
  83. BYTE *GetNumArg(BYTE *pLine, COUNT *pnArg);
  84. BYTE *GetStringArg(BYTE *pLine, BYTE *pszString);
  85. struct dhdr FAR *linkdev(struct dhdr FAR *dhp);
  86. UWORD 
  87. initdev (struct dhdr FAR *dhp, BYTE FAR *cmdTail);
  88. int     SkipLine(char *pLine);
  89. static VOID FAR *AlignParagraph(VOID FAR *lpPtr);
  90. #ifndef I86
  91. # define AlignParagraph(x) (x)
  92. #endif
  93. #define EOF 0x1a
  94. struct table *LookUp(struct table *p, BYTE *token);
  95. struct table
  96. {
  97. BYTE    *entry;
  98. BYTE    pass;
  99. VOID    (*func)(BYTE *pLine);
  100. };
  101. static struct table  commands[] =
  102. {
  103. {"break",       1,      Break},
  104. {"buffers",     1,      Buffers},
  105. {"command",     1,      InitPgm},
  106. {"country",     1,      Country},
  107. {"device",      2,      Device},
  108. {"fcbs",        1,      Fcbs},
  109. {"files",       1,      Files},
  110. {"lastdrive",   1,      Lastdrive },
  111. /* rem is never executed by locking out pass                    */
  112. {"rem",         0,      CfgFailure},
  113. {"shell",       1,      InitPgm},
  114. {"stacks",      1,      Stacks },
  115. {"switchar",    1,      Switchar },
  116. /* default action                                               */
  117. {"",            -1,     CfgFailure}
  118. };
  119. #ifndef KDB
  120. BYTE FAR *KernelAlloc(WORD nBytes);
  121. #endif
  122. BYTE *pLineStart;
  123. /* Do first time initialization.  Store last so that we can reset it    */
  124. /* later.                                                               */
  125. void
  126. PreConfig(void)
  127. {
  128. /* Set pass number                                              */
  129. nPass = 0;
  130. /* Initialize the base memory pointers                          */
  131. lpOldLast = lpBase = AlignParagraph((BYTE FAR *)&last);
  132. /* Begin by initializing our system buffers                     */
  133. buffers = (struct buffer FAR *)
  134. KernelAlloc(Config.cfgBuffers * sizeof(struct buffer));
  135. #ifdef DEBUG
  136. printf("Preliminary buffer allocated at 0x%04x:0x%04xn",
  137. FP_SEG(buffers), FP_OFF(buffers));
  138. #endif
  139. /* Initialize the file table                                    */
  140. f_nodes = (struct f_node FAR *)
  141. KernelAlloc(Config.cfgFiles * sizeof(struct f_node));
  142. /* sfthead = (sfttbl FAR *)&basesft; */
  143. /* FCBp = (sfttbl FAR *)&FcbSft; */
  144. FCBp = (sfttbl FAR *)
  145. KernelAlloc(sizeof(sftheader)
  146.  + Config.cfgFiles * sizeof(sft));
  147. sfthead = (sfttbl FAR *)
  148. KernelAlloc(sizeof(sftheader)
  149.  + Config.cfgFiles * sizeof(sft));
  150. #ifdef DEBUG
  151. printf("Preliminary f_node allocated at 0x%04x:0x%04xn",
  152. FP_SEG(f_nodes), FP_OFF(f_nodes));
  153. printf("Preliminary FCB table allocated at 0x%04x:0x%04xn",
  154. FP_SEG(FCBp), FP_OFF(FCBp));
  155. printf("Preliminary sft table allocated at 0x%04x:0x%04xn",
  156. FP_SEG(sfthead), FP_OFF(sfthead));
  157. #endif
  158. /* Done.  Now initialize the MCB structure                      */
  159. /* This next line is 8086 and 80x86 real mode specific          */
  160. #ifdef DEBUG
  161. printf("Preliminary  allocation completed: top at 0x%04x:0x%04xn",
  162. FP_SEG(lpBase), FP_OFF(lpBase));
  163. #endif
  164. #ifdef KDB
  165. lpBase = malloc(4096);
  166. first_mcb = FP_SEG(lpBase) + ((FP_OFF(lpBase) + 0x0f) >> 4);
  167. #else
  168. first_mcb = FP_SEG(lpBase) + ((FP_OFF(lpBase) + 0x0f) >> 4);
  169. #endif
  170. /* We expect ram_top as Kbytes, so convert to paragraphs */
  171. mcb_init((mcb FAR *)(MK_FP(first_mcb, 0)),
  172.  (ram_top << 6) - first_mcb - 1);
  173. nPass = 1;
  174. }
  175. /* Do second pass initialization.                                       */
  176. /* Also, run config.sys to load drivers.                                */
  177. void
  178. PostConfig(void)
  179. {
  180. /* Set pass number                                              */
  181. nPass = 2;
  182. /* Initialize the base memory pointers from last time.          */
  183. lpBase = AlignParagraph(lpOldLast);
  184. /* Begin by initializing our system buffers                     */
  185. buffers = (struct buffer FAR *)
  186. KernelAlloc(Config.cfgBuffers * sizeof(struct buffer));
  187. #ifdef DEBUG
  188. printf("Buffer allocated at 0x%04x:0x%04xn",
  189. FP_SEG(buffers), FP_OFF(buffers));
  190. #endif
  191. /* Initialize the file table                                    */
  192. f_nodes = (struct f_node FAR *)
  193. KernelAlloc(Config.cfgFiles * sizeof(struct f_node));
  194. /* sfthead = (sfttbl FAR *)&basesft; */
  195. /* FCBp = (sfttbl FAR *)&FcbSft; */
  196. FCBp = (sfttbl FAR *)
  197. KernelAlloc(sizeof(sftheader)
  198.  + Config.cfgFiles * sizeof(sft));
  199. sfthead = (sfttbl FAR *)
  200. KernelAlloc(sizeof(sftheader)
  201.  + Config.cfgFiles * sizeof(sft));
  202. #ifdef DEBUG
  203. printf("f_node allocated at 0x%04x:0x%04xn",
  204. FP_SEG(f_nodes), FP_OFF(f_nodes));
  205. printf("FCB table allocated at 0x%04x:0x%04xn",
  206. FP_SEG(FCBp), FP_OFF(FCBp));
  207. printf("sft table allocated at 0x%04x:0x%04xn",
  208. FP_SEG(sfthead), FP_OFF(sfthead));
  209. #endif
  210. if (Config.cfgStacks)
  211. {
  212. VOID FAR *stackBase = KernelAlloc(Config.cfgStacks * Config.cfgStackSize);
  213. init_stacks(stackBase, Config.cfgStacks, Config.cfgStackSize);
  214. #ifdef  DEBUG
  215. printf("Stacks allocated at %04x:%04xn",
  216.     FP_SEG(stackBase), FP_OFF(stackBase));
  217. #endif
  218. }
  219. #ifdef DEBUG
  220. printf("Allocation completed: top at 0x%04x:0x%04xn",
  221. FP_SEG(lpBase), FP_OFF(lpBase));
  222. #endif
  223. }
  224. /* This code must be executed after device drivers has been loaded */
  225. VOID    configDone(VOID)
  226. {
  227. COUNT   i;
  228. first_mcb = FP_SEG(lpBase) + ((FP_OFF(lpBase) + 0x0f) >> 4);
  229. /* We expect ram_top as Kbytes, so convert to paragraphs */
  230. mcb_init((mcb FAR *)(MK_FP(first_mcb, 0)),
  231.  (ram_top << 6) - first_mcb - 1);
  232. /* The standard handles should be reopened here, because
  233.    we may have loaded new console or printer drivers in CONFIG.SYS */
  234. }
  235. VOID DoConfig(VOID)
  236. {
  237. COUNT nFileDesc;
  238. COUNT nRetCode;
  239. BYTE    *pLine, *pTmp;
  240. BOOL    bEof;
  241. /* Check to see if we have a config.sys file.  If not, just     */
  242. /* exit since we don't force the user to have one.              */
  243. if((nFileDesc = dos_open((BYTE FAR *)"config.sys", 0)) < 0)
  244. {
  245. #ifdef DEBUG
  246. printf("CONFIG.SYS not foundn");
  247. #endif
  248. return;
  249. }
  250. /* Have one -- initialize.                                      */
  251. nCfgLine = 0;
  252. bEof = 0;
  253. pLine = szLine;
  254. /* Read each line into the buffer and then parse the line,      */
  255. /* do the table lookup and execute the handler for that         */
  256. /* function.                                                    */
  257. while (!bEof)
  258. {
  259. struct table *pEntry;
  260. UWORD bytesLeft = 0;
  261. if (pLine > szLine) bytesLeft = LINESIZE - (pLine - szLine);
  262. if (bytesLeft)
  263. {
  264.     fbcopy(pLine, szLine, LINESIZE - bytesLeft);
  265.     pLine = szLine + bytesLeft;
  266. }
  267. /* Read a line from config                              */
  268. /* Interrupt processing if read error or no bytes read  */
  269. if ((nRetCode = dos_read(nFileDesc, pLine, LINESIZE - bytesLeft)) <= 0) 
  270.     break;
  271. /* If the buffer was not filled completely, append a 
  272.    CTRL-Z character to mark where the file ends */
  273. if (nRetCode + bytesLeft < LINESIZE) 
  274.     szLine[nRetCode + bytesLeft] = EOF;
  275. /* Process the buffer, line by line */
  276. pLine = szLine;
  277. while (!bEof && *pLine != EOF)
  278. {
  279. for (pTmp = pLine; pTmp - szLine < LINESIZE; pTmp++)
  280. {
  281. if (*pTmp == 'r' || *pTmp == EOF) 
  282.     break;
  283. }
  284. if (pTmp - szLine >= LINESIZE)
  285.     break;
  286. if (*pTmp == EOF) 
  287.     bEof = TRUE;
  288. *pTmp = '';
  289. pLineStart = pLine;
  290. /* Skip leading white space and get verb.               */
  291. pLine = scan(pLine, szBuf);
  292. /* Translate the verb to lower case ...                 */
  293. for(pTmp = szBuf; *pTmp != ''; pTmp++)
  294. *pTmp = tolower(*pTmp);
  295. /* If the line was blank, skip it.  Otherwise, look up  */
  296. /* the verb and execute the appropriate function.       */
  297. if(*szBuf != '')
  298. {
  299. pEntry = LookUp(commands, szBuf);
  300. if(pEntry -> pass < 0 || pEntry -> pass == nPass)
  301. {        
  302. if (!singleStep || !SkipLine(pLineStart))
  303. {
  304. skipwh(pLine);
  305. if('=' != *pLine)
  306. CfgFailure(pLine);
  307. else (*(pEntry -> func))(++pLine);
  308. }
  309. }
  310. }
  311. skipLine:               nCfgLine++;
  312. pLine += strlen(pLine) + 1;
  313. }
  314. }
  315. dos_close(nFileDesc);
  316. }
  317. struct table *LookUp(struct table *p, BYTE *token)
  318. {
  319. while(*(p -> entry) != '')
  320. {
  321. if(strcmp(p -> entry, token) == 0)
  322. break;
  323. else
  324. ++p;
  325. }
  326. return p;
  327. }
  328.     
  329. BOOL    SkipLine(char *pLine)
  330. {
  331. char    kbdbuf[16];
  332. keyboard *kp = (keyboard *)kbdbuf;
  333. char    *pKbd = &kp->kb_buf[0];
  334. kp->kb_size = 12;
  335. kp->kb_count = 0;
  336. printf("%s [Y,N]?", pLine);
  337. sti(kp);
  338. pKbd = skipwh(pKbd);
  339. if (*pKbd == 'n' || *pKbd == 'N')
  340. return TRUE;        
  341.     
  342. return FALSE;
  343. }
  344. BYTE *GetNumArg(BYTE *pLine, COUNT *pnArg)
  345. {
  346. /* look for NUMBER                               */
  347. pLine = skipwh(pLine);
  348. if(!isnum(pLine))
  349. {
  350. CfgFailure(pLine);
  351. return (BYTE *)0;
  352. }
  353. return GetNumber(pLine, pnArg);
  354. }
  355. BYTE *GetStringArg(BYTE *pLine, BYTE *pszString)
  356. {
  357. /* look for STRING                               */
  358. pLine = skipwh(pLine);
  359. /* just return whatever string is there, including null         */
  360. return scan(pLine, pszString);
  361. }
  362. static VOID Buffers(BYTE *pLine)
  363. {
  364. COUNT nBuffers;
  365. /* Get the argument                                             */
  366. if(GetNumArg(pLine, &nBuffers) == (BYTE *)0)
  367. return;
  368. /* Got the value, assign either default or new value            */
  369. Config.cfgBuffers = max(Config.cfgBuffers, nBuffers);
  370. }
  371. static VOID Files(BYTE *pLine)
  372. {
  373. COUNT nFiles;
  374. /* Get the argument                                             */
  375. if(GetNumArg(pLine, &nFiles) == (BYTE *)0)
  376. return;
  377. /* Got the value, assign either default or new value            */
  378. Config.cfgFiles = max(Config.cfgFiles, nFiles);
  379. }
  380. static VOID Lastdrive(BYTE *pLine)
  381. {
  382. /* Format:   LASTDRIVE = letter         */
  383. COUNT   nFiles;
  384. BYTE    drv;
  385. pLine = skipwh(pLine);
  386. drv = *pLine & ~0x20;   
  387. if (drv < 'A' || drv > 'Z')
  388. {        
  389. CfgFailure(pLine);
  390. return;
  391. }
  392. drv -= 'A';
  393. Config.cfgLastdrive = max(Config.cfgLastdrive, drv);
  394. }
  395. static VOID Switchar(BYTE *pLine)
  396. {
  397. /* Format: SWITCHAR = character         */
  398. GetStringArg(pLine, szBuf);
  399. switchar = *szBuf;
  400. }
  401. static VOID Fcbs(BYTE *pLine)
  402. {
  403. /*  Format:     FCBS = totalFcbs [,protectedFcbs]    */
  404. if ((pLine = GetNumArg(pLine, &Config.cfgFcbs)) == 0)
  405.     return;
  406. pLine = skipwh(pLine);
  407. if (*pLine == ',')
  408.     GetNumArg(++pLine, &Config.cfgProtFcbs);
  409. if (Config.cfgProtFcbs > Config.cfgFcbs)
  410.     Config.cfgProtFcbs = Config.cfgFcbs;
  411. }
  412. static VOID Country(BYTE *pLine)
  413. {
  414. /* Format: COUNTRY = countryCode, [codePage], filename  */
  415. UWORD   ctryCode;
  416. UWORD   codePage;
  417. if ((pLine = GetNumArg(pLine, &ctryCode)) == 0)
  418.     return;
  419.     
  420. pLine = skipwh(pLine);
  421. if (*pLine == ',')
  422. {
  423. pLine = skipwh(pLine);
  424. if (*pLine == ',') 
  425. {
  426.     codePage = 0;
  427.     ++pLine;
  428. } else {
  429.     if ((pLine = GetNumArg(pLine, &codePage)) == 0)
  430. return;
  431. }
  432. pLine = skipwh(pLine);
  433. if (*pLine == ',')
  434. {
  435.     GetStringArg(++pLine, szBuf);
  436.     
  437.     if (LoadCountryInfo(szBuf, ctryCode, codePage))
  438. return;
  439. }
  440. }
  441. CfgFailure(pLine);
  442. }
  443. static VOID Stacks(BYTE *pLine)
  444. {
  445. /* Format:  STACKS = stacks [, stackSize]       */
  446. pLine = GetNumArg(pLine, &Config.cfgStacks);
  447. if (*pLine == ',')
  448.     GetNumArg(++pLine, &Config.cfgStackSize);
  449. if (Config.cfgStacks)
  450. {
  451.     if (Config.cfgStackSize < 32) Config.cfgStackSize = 32;
  452.     if (Config.cfgStackSize > 512) Config.cfgStackSize = 512;
  453.     if (Config.cfgStacks > 64) Config.cfgStacks = 64;
  454. }
  455. }
  456. static VOID InitPgm(BYTE *pLine)
  457. {
  458. /* Get the string argument that represents the new init pgm     */
  459. pLine = GetStringArg(pLine, Config.cfgInit);
  460. /* Now take whatever tail is left and add it on as a single     */
  461. /* string.                                                      */
  462. strcpy(Config.cfgInitTail, pLine);
  463. /* and add a DOS new line just to be safe                       */
  464. strcat(Config.cfgInitTail, "rn");
  465. }
  466. static VOID   Break(BYTE *pLine)
  467. {
  468. /* Format:      BREAK = (ON | OFF)      */
  469. BYTE *pTmp;
  470. GetStringArg(pLine, szBuf);
  471. break_ena = strcmp(szBuf, "OFF")? 1 : 0;
  472. }
  473. static VOID Device(BYTE *pLine)
  474. {
  475. VOID FAR *driver_ptr;
  476. BYTE *pTmp;
  477. exec_blk eb;
  478. struct dhdr FAR *dhp;
  479. struct dhdr FAR *next_dhp;
  480. UWORD dev_seg = (((ULONG)FP_SEG(lpBase) << 4) + FP_OFF(lpBase) + 0xf) >> 4;
  481. /* Get the device driver name                                   */
  482. GetStringArg(pLine, szBuf);
  483. /* The driver is loaded at the top of allocated memory.         */             
  484. /* The device driver is paragraph aligned.                      */
  485. eb.load.reloc = eb.load.load_seg = dev_seg;
  486. dhp = MK_FP(dev_seg, 0);
  487. #ifdef DEBUG
  488. printf("Loading device driver %s at segment %04xn", 
  489.        szBuf, dev_seg);
  490. #endif
  491. if (DosExec(3, &eb, szBuf) == SUCCESS)
  492. {
  493.     while(FP_OFF(dhp) != 0xFFFF)
  494.     {
  495. next_dhp = MK_FP(FP_SEG(dhp), FP_OFF(dhp -> dh_next));
  496. dhp -> dh_next = nul_dev.dh_next; 
  497. link_dhdr(&nul_dev, dhp, pLine); 
  498. dhp = next_dhp;
  499.     } 
  500. } else CfgFailure(pLine);
  501. }
  502. static VOID CfgFailure(BYTE *pLine)
  503. {
  504. BYTE *pTmp = pLineStart;
  505. printf("CONFIG.SYS error in line %dn", nCfgLine);
  506. printf(">>>%sn", pTmp);
  507. while(++pTmp != pLine)
  508. printf(" ");
  509. printf("^n");
  510. }
  511. #ifndef KDB
  512. static BYTE FAR *
  513. KernelAlloc(WORD nBytes)
  514. {
  515. BYTE FAR *lpAllocated;
  516. lpBase = AlignParagraph(lpBase);
  517. lpAllocated = lpBase;
  518. if (0x10000 - FP_OFF(lpBase) <= nBytes)
  519. {
  520. UWORD newOffs = (FP_OFF(lpBase) + nBytes) & 0xFFFF;
  521. UWORD newSeg = FP_SEG(lpBase) + 0x1000;
  522. lpBase = MK_FP(newSeg, newOffs);
  523. } else lpBase += nBytes;
  524. return lpAllocated;
  525. }
  526. #endif
  527. #ifdef I86
  528. static VOID FAR *AlignParagraph(VOID FAR *lpPtr)
  529. {
  530. ULONG lTemp;
  531. UWORD uSegVal;
  532. /* First, convert the segmented pointer to linear address */
  533. lTemp = FP_SEG(lpPtr);
  534. lTemp = (lTemp << 4) + FP_OFF(lpPtr);
  535. /* Next, round up the linear address to a paragraph boundary. */
  536. lTemp += 0x0f;
  537. lTemp &= 0xfffffff0l;
  538. /* Break it into segments.                                      */
  539. uSegVal = (UWORD)(lTemp >> 4);
  540. /* and return an adddress adjusted to the nearest paragraph     */
  541. /* boundary.                                                    */
  542. return MK_FP(uSegVal, 0);
  543. }
  544. #endif