📄 infparse.c
字号:
/*
* Infparse.c - Setup.inf parsing code.
* Clark Cyr, Mike Colee, Todd Laney
* Copyright (C) Microsoft, 1989
* March 15, 1989
*
* Modification History:
*
* 3/15/89 CC Clark wrote this code for control Panel. This is windows
* code.
*
* 3/20/89 MC Decided this code would work for Dos and windows portion
* of setup. take out windows specifc stuff like local alloc's
* and dialog stuff. Replace it with standard C run time calls.
*
* 3/24/89 Toddla TOTAL rewrite! nothing is the same any more.
*
* 6/29/89 MC fixed getprofilestring func to not strip quotes if more
* than one field exists.
*/
#ifdef DOSONLY
unsigned char XlateAnsi850(unsigned char c);
#endif
#include <dos.h>
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
#include "sulib.h"
#ifdef FAR_HEAP
/*** hack. to avoid realloc problems we make READ_BUFSIZE
as big as the inf file, thus avoiding any reallocs */
#define READ_BUFSIZE 27000 /* size of inf buffer */
#endif
#define TMP_BUFSIZE 1024 /* size of temp reads */
#define ISSEP(c) ((c) == '=' || (c) == ',')
#define ISWHITE(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\r')
#define ISNOISE(c) ((c) == '"')
#define EOF 26
#define QUOTE '"'
#define COMMA ','
#define SPACE ' '
#define EQUAL '='
PINF pinfDefault = NULL;
static PSTR pBuf;
static PINF pInf;
static WORD iBuf;
static WORD iInf;
/* Globaly used pointers to non-translatable text strings. */
char *pszINFFILE = "setup.inf";
extern char *pszPATH;
/* Local prototypes */
BOOL multifields(PINF);
static char GETC(int fh)
{
register WORD n;
if (!pBuf)
return EOF;
n = iBuf % TMP_BUFSIZE;
if (n == 0)
{
FREAD(fh,pBuf,TMP_BUFSIZE);
}
iBuf++;
return pBuf[n];
}
#ifdef FAR_HEAP
static void PUTC(char c)
{
if (!pInf)
return;
#ifdef DOSONLY
c = XlateAnsi850(c);
#endif
pInf[iInf++] = c;
}
#else
static void PUTC(char c)
{
register WORD n;
register PINF pInfT;
if (!pInf)
return;
n = iInf % READ_BUFSIZE;
if (n == 0)
{
n = (iInf / READ_BUFSIZE) + 1;
pInfT = REALLOC(pInf,n * READ_BUFSIZE);
if (pInfT)
{
pInf = pInfT;
}
else
{
AssertF(FALSE);
FREE(pInf);
pInf = NULL;
}
}
if (pInf)
pInf[iInf++] = c;
}
#endif
/* int infLoadFile() Load a entire INF file into memory
* comments are removed, each line is terminated
* by a \0 each section is terminated by a \0\0
* ONLY spaces inside of " " are preserved
* the end of file is marked with a ^Z
*
* RETURNS: A pointer to a block of memory containg file, NULL if failure
*
*/
PINF infLoadFile(int fh)
{
WORD len;
PINF pInfT;
register char c;
register BOOL fQuote = FALSE;
if (fh == -1)
return NULL;
len = (WORD)FSEEK(fh,0L,SEEK_END);
FSEEK(fh,0L,SEEK_SET);
pBuf = ALLOC(TMP_BUFSIZE); // temp buffer
#ifdef FAR_HEAP
pInf = FALLOC(len); // destination, at least as big as file
#else
pInf = ALLOC(READ_BUFSIZE);
#endif
iBuf = 0;
iInf = 0;
AssertF(pBuf && pInf);
if (!pBuf || !pInf)
return NULL;
while (iBuf < len)
{
c = GETC(fh);
loop:
if (iBuf >= len)
break;
switch (c)
{
case '\r': /* ignore '\r' */
break;
case '\n':
for (; ISWHITE(c); c = GETC(fh))
;
if (c != ';')
PUTC(0); /* all lines end in a \0 */
if (c == '[')
PUTC(0); /* all sections end with \0\0 */
fQuote = FALSE;
goto loop;
break;
case '\t':
case ' ':
if (fQuote)
PUTC(c);
break;
case '"':
fQuote = !fQuote;
PUTC(c);
break;
case ';':
for (; !ISEOL(c); c = GETC(fh))
;
goto loop;
break;
default:
PUTC(c);
break;
}
}
PUTC(0);
PUTC(0);
PUTC(EOF);
FREE(pBuf);
// try to shrink this block
#ifdef FAR_HEAP
// just leave pInf it's original size. don't bother shrinking it
#else
pInfT = REALLOC(pInf,iInf);
if (pInfT) // if REALLOC fails just leave pInf as is
pInf = pInfT;
#endif
AssertF(pInf);
return pInf;
}
static int near pascal
strncmpi(LPSTR pch1, LPSTR pch2, int n)
{
while (*pch1 && --n > 0 && UP_CASE(*pch1) == UP_CASE(*pch2))
*pch1++,*pch2++;
return UP_CASE(*pch1) != UP_CASE(*pch2);
}
/* PINF infOpen() takes the string held in szBasePath as the path
* to find SETUP.INF and attempts to open it. Returns
* a valid file handle is successful.
*
* RETURNS: A file pointer if successful, Null pointer in the case of
* a failure.
*
* ENTER:
* EXIT: To caller
*/
PINF FAR PASCAL infOpen(PSTR szInf)
{
char szBuf[MAXPATHLEN];
short fh;
PINF pinf;
fh = -1;
if (szInf == NULL)
szInf = pszINFFILE;
/*
* Next try to open passed parameter as is. For Dos half.
*/
if (fh == -1)
{
fh = FOPEN(szInf);
}
/*
* Next try destination path\system. for win half.
*/
if (fh == -1) {
strcpy(szBuf, szSetupPath);
catpath(szBuf, "system");
catpath(szBuf, szInf);
fh = FOPEN(szBuf);
}
/*
* Next try destination path. for initial setup.
*/
if (fh == -1) {
strcpy(szBuf, szSetupPath);
catpath(szBuf, szInf);
fh = FOPEN(szBuf);
}
/*
* May need to look on the path to find the .inf file.
*/
if ( fh == -1 ) {
_searchenv(szInf,pszPATH,szBuf);
if ( *szBuf )
fh = FOPEN(szBuf);
}
if (fh != -1)
{
pinf = infLoadFile(fh);
FCLOSE(fh);
if (pinf && !pinfDefault)
pinfDefault = pinf;
return pinf;
}
return NULL;
}
/* void CloseSetupInf()
*
* ENTER:
* EXIT: To caller
*/
void FAR PASCAL infClose(PINF pinf)
{
if (pinf == NULL)
pinf = pinfDefault;
if (pinf != NULL)
{
FFREE(pinf);
if (pinf == pinfDefault)
pinfDefault = NULL;
}
}
/* FindSection locates a section in Setup.Inf. Sections are
* assumed to be delimited by a '[' as the first
* character on a line.
*
* Arguments: pInf Pointer to SETUP.INF buffer
* pszSect PSTR to section name
*
* Return: WORD file position of the first line in the section
* 0 if section not found
*/
WORD FindSection(PINF pInf, PSTR pszSect)
{
BOOL fFound = FALSE;
short nLen = strlen(pszSect);
PINF pch;
char ch;
if (!pInf)
return 0;
pch = pInf;
while (!fFound && *pch != EOF)
{
if (*pch++ == '[')
{
fFound = !strncmpi(pszSect, pch, nLen) && pch[nLen] == ']';
}
/*
* go to the next line, dont forget to skip over \0 and \0\0
*/
while (*pch != EOF && *pch != '\0')
pch++;
while (*pch == 0)
pch++;
}
return((fFound && *pch != '[' && *pch != EOF) ? pch - pInf : 0);
}
/* char* fnGetDataString(npszData,szDataStr)
*
* Called by functions that read sections of information from setup.inf
* to obtain strings that are set equal to keywords. Example:
*
* welcome=("Hello There")
*
* This function will return a pointer to the null terminated string
* "Hello There".
*
* ENTRY:
*
* npszData : pointer to entire section taken from setup.inf
* npszDataStr : pointer to key word to look for (welcome in example above.)
*
* EXIT: retutns pointer to string if successful, NULL if failure.
*
*/
BOOL fnGetDataString(PINF npszData, PSTR szDataStr, LPSTR szBuf)
{
unsigned char *clocation;
unsigned char *pStringHead;
int len = strlen(szDataStr);
while (npszData)
{
if (!strncmpi(npszData,szDataStr,len)) // looking for correct prof.
{
npszData += len; // found !, look past prof str.
while (ISWHITE(*npszData)) // suck out the crap.
npszData++;
if (*npszData == EQUAL) // Now we have what were looking for !
{
npszData++;
if (!multifields(npszData) )
{
while (ISWHITE(*npszData) || ISNOISE(*npszData))
npszData++;
while (*npszData)
*szBuf++ = *npszData++;
/*
* remove trailing spaces, and those pesky ()'s
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -