#include "precomp.h" #pragma hdrstop /*++ Copyright (c) 1991 Microsoft Corporation Module Name: inf_rt2.c Abstract: INF file runtime field interpreter. A given string is interpreted as a tokenized field and an output buffer containing the result is constructed. Author: Ted Miller (tedm) 10-Spetember-1991 --*/ /* Input stuff */ LPBYTE Interpret_Inputp; #define GETTOKEN() (*Interpret_Inputp++) #define PEEKTOKEN() (*Interpret_Inputp) #define UNGETTOKEN(t) (*(--Interpret_Inputp) = t) #define VERIFY_SIZE(s) \ if ( SpaceLeftInFieldBuffer < (s) ) { \ GrowBuffer(s); \ } /* end input stuff */ /* Output stuff */ #define MAX_FIELD_LENGTH 4096 PUCHAR InterpretedFieldBuffer; UINT SpaceLeftInFieldBuffer; UINT BufferSize; PUCHAR Interpret_OutputLoc; /* end output stuff */ SZ Interpret_GetField(VOID); BOOL DoVariable(VOID); BOOL DoListFromSectionNthItem(VOID); BOOL DoFieldAddressor(VOID); BOOL DoAppendItemToList(VOID); BOOL DoNthItemFromList(VOID); BOOL DoLocateItemInList(VOID); BOOL DoList(VOID); BOOL DoString(BYTE StringToken); /* Run time error field */ GRC grcRTLastError = grcOkay; VOID GrowBuffer(UINT Size); SZ APIENTRY InterpretField( SZ Field ) { SZ ReturnString, InputSave = Interpret_Inputp; Interpret_Inputp = Field; ReturnString = Interpret_GetField(); Interpret_Inputp = InputSave; return(ReturnString); } SZ Interpret_GetField( VOID ) { LPSTR OldOutputBuffer = InterpretedFieldBuffer; LPSTR OldInterpretLoc = Interpret_OutputLoc; UINT OldSpaceLeft = SpaceLeftInFieldBuffer; LPSTR ReturnString = NULL; BYTE Token; if((InterpretedFieldBuffer = SAlloc(SpaceLeftInFieldBuffer = MAX_FIELD_LENGTH)) == NULL) { grcRTLastError = grcOutOfMemory; return(NULL); } BufferSize = MAX_FIELD_LENGTH; Interpret_OutputLoc = InterpretedFieldBuffer; VERIFY_SIZE(1); SpaceLeftInFieldBuffer--; // leave space for terminating NUL while((Token = GETTOKEN()) && (Token != TOKEN_COMMA) && (Token != TOKEN_SPACE) && (Token != TOKEN_RIGHT_PAREN) && (Token != TOKEN_LIST_END)) { if(IS_STRING_TOKEN(Token)) { if(!DoString(Token)) { SFree(InterpretedFieldBuffer); goto Cleanup; } } else { switch(Token) { case TOKEN_VARIABLE: if(!DoVariable()) { SFree(InterpretedFieldBuffer); goto Cleanup; } break; case TOKEN_LIST_FROM_SECTION_NTH_ITEM: if(!DoListFromSectionNthItem()) { SFree(InterpretedFieldBuffer); goto Cleanup; } break; case TOKEN_FIELD_ADDRESSOR: if(!DoFieldAddressor()) { SFree(InterpretedFieldBuffer); goto Cleanup; } break; case TOKEN_APPEND_ITEM_TO_LIST: if(!DoAppendItemToList()) { SFree(InterpretedFieldBuffer); goto Cleanup; } break; case TOKEN_NTH_ITEM_FROM_LIST: if(!DoNthItemFromList()) { SFree(InterpretedFieldBuffer); goto Cleanup; } break; case TOKEN_LOCATE_ITEM_IN_LIST: if(!DoLocateItemInList()) { SFree(InterpretedFieldBuffer); goto Cleanup; } break; case TOKEN_LIST_START: if(!DoList()) { SFree(InterpretedFieldBuffer); goto Cleanup; } break; default: #if DBG { char str[100]; wsprintf(str,"Bogus token: %u",Token); MessBoxSzSz("Interpret_GetField",str); } #endif break; } // switch } // if-else } // while /* The following is because we want the routines DoOperator() and DoList() (below) to have access to their terminators. */ if((Token == TOKEN_RIGHT_PAREN) || (Token == TOKEN_LIST_END)) { UNGETTOKEN(Token); } Assert((LONG)SpaceLeftInFieldBuffer >= 0); // space provided for above *Interpret_OutputLoc = NUL; ReturnString = SRealloc(InterpretedFieldBuffer, BufferSize - SpaceLeftInFieldBuffer ); Assert(ReturnString); // buffer was shrinking; Cleanup: Interpret_OutputLoc = OldInterpretLoc; InterpretedFieldBuffer = OldOutputBuffer; SpaceLeftInFieldBuffer = OldSpaceLeft; return(ReturnString); } /* This routine gets the fields of an operator into an rgsz. */ RGSZ DoOperator( UINT FieldCount ) { UINT x; RGSZ rgsz; Assert(FieldCount); if((rgsz = (RGSZ)SAlloc((FieldCount+1)*sizeof(SZ))) == NULL) { grcRTLastError = grcOutOfMemory; return(NULL); } rgsz[FieldCount] = NULL; for(x=0; x<FieldCount-1; x++) { if((rgsz[x] = Interpret_GetField()) == NULL) { FFreeRgsz(rgsz); return(NULL); } if(PEEKTOKEN() == TOKEN_RIGHT_PAREN) { FFreeRgsz(rgsz); grcRTLastError = grcNotOkay; return(NULL); } } if((rgsz[FieldCount-1] = Interpret_GetField()) == NULL) { FFreeRgsz(rgsz); return(NULL); } Assert(PEEKTOKEN() != NUL); if(GETTOKEN() != TOKEN_RIGHT_PAREN) { // skips ) FFreeRgsz(rgsz); grcRTLastError = grcNotOkay; return(NULL); } return(rgsz); } BOOL DoVariable( VOID ) { RGSZ rgsz; SZ SymbolValue; UINT x,SymbolValueLength; BOOL rc = TRUE; if((rgsz = DoOperator(1)) == NULL) { return(FALSE); } if((SymbolValue = SzFindSymbolValueInSymTab(rgsz[0])) == NULL) { SymbolValue = ""; } SymbolValueLength = lstrlen(SymbolValue); VERIFY_SIZE(SymbolValueLength); if(SpaceLeftInFieldBuffer >= SymbolValueLength) { SpaceLeftInFieldBuffer -= SymbolValueLength; for(x=0; x<SymbolValueLength; x++) { *Interpret_OutputLoc++ = *SymbolValue++; } } else { grcRTLastError = grcNotOkay; rc = FALSE; } FFreeRgsz(rgsz); return(rc); } BOOL DoListFromSectionNthItem( VOID ) { RGSZ rgsz,rgszList = NULL; UINT LineCount,n,x,LineNo; BOOL rc = FALSE; SZ List,ListSave; if((rgsz = DoOperator(2)) == NULL) { return(FALSE); } grcRTLastError = grcNotOkay; n = atoi(rgsz[1]); LineCount = CKeysFromInfSection(rgsz[0],TRUE); if((rgszList = (RGSZ)SAlloc((LineCount+1)*sizeof(SZ))) != NULL) { LineNo = FindInfSectionLine(rgsz[0]); for(x=0; x<LineCount; x++) { LineNo = FindNextLineFromInf(LineNo); Assert(LineNo != -1); rgszList[x] = SzGetNthFieldFromInfLine(LineNo,n); } rgszList[LineCount] = NULL; if((List = SzListValueFromRgsz(rgszList)) != NULL) { ListSave = List; x = lstrlen(List); VERIFY_SIZE(x); if(SpaceLeftInFieldBuffer >= x) { SpaceLeftInFieldBuffer -= x; for(n=0; n<x; n++) { *Interpret_OutputLoc++ = *List++; } grcRTLastError = grcOkay; rc = TRUE; } SFree(ListSave); } else { grcRTLastError = grcOutOfMemory; } } else { grcRTLastError = grcOutOfMemory; } if(rgszList != NULL) { FFreeRgsz(rgszList); } FFreeRgsz(rgsz); return(rc); } BOOL DoFieldAddressor( VOID ) { RGSZ rgsz; UINT x,n; SZ Result,ResultSave; BOOL rc = FALSE; if((rgsz = DoOperator(3)) == NULL) { return(FALSE); } grcRTLastError = grcNotOkay; n = atoi(rgsz[2]); // rgsz[0] has section, rgsz[1] has key if((Result = SzGetNthFieldFromInfSectionKey(rgsz[0],rgsz[1],n)) != NULL) { ResultSave = Result; n = lstrlen(Result); VERIFY_SIZE(n); if(SpaceLeftInFieldBuffer >= n) { SpaceLeftInFieldBuffer -= n; for(x=0; x<n; x++) { *Interpret_OutputLoc++ = *Result++; } grcRTLastError = grcOkay; rc = TRUE; } SFree(ResultSave); } FFreeRgsz(rgsz); return(rc); } BOOL DoAppendItemToList( VOID ) { RGSZ rgsz,rgszList1,rgszList2; UINT RgszSize,x,y; SZ ListValue,ListTemp; if((rgsz = DoOperator(2)) == NULL) { return(FALSE); } // rgsz[0] has list, rgsz[1] has item if((rgszList1 = RgszFromSzListValue(rgsz[0])) == NULL) { FFreeRgsz(rgsz); grcRTLastError = grcOutOfMemory; return(FALSE); } for (RgszSize = 0; rgszList1[RgszSize] != NULL; RgszSize++) { ; } if ((rgszList2 = (RGSZ)SRealloc(rgszList1, (RgszSize+2)*sizeof(SZ) )) == NULL) { FFreeRgsz(rgszList1); FFreeRgsz(rgsz); grcRTLastError = grcOutOfMemory; return(FALSE); } rgszList2[RgszSize] = SzDupl(rgsz[1]); rgszList2[RgszSize+1] = NULL; ListValue = SzListValueFromRgsz(rgszList2); FFreeRgsz(rgszList2); if(ListValue == NULL) { FFreeRgsz(rgsz); grcRTLastError = grcOutOfMemory; return(FALSE); } x = lstrlen(ListValue); VERIFY_SIZE(x); if(x > SpaceLeftInFieldBuffer) { SFree(ListValue); FFreeRgsz(rgsz); grcRTLastError = grcNotOkay; return(FALSE); } ListTemp = ListValue; for(y=0; y<x; y++) { *Interpret_OutputLoc++ = *ListTemp++; } SpaceLeftInFieldBuffer -= x; SFree(ListValue); FFreeRgsz(rgsz); return(TRUE); } BOOL DoNthItemFromList( VOID ) { RGSZ rgsz, rgszList = NULL; UINT n,x,y,ListSize; PUCHAR Item; BOOL rc = FALSE; if((rgsz = DoOperator(2)) == NULL) { return(FALSE); } grcRTLastError = grcNotOkay; n = atoi(rgsz[1]); if((rgszList = RgszFromSzListValue(rgsz[0])) != NULL) { for(ListSize=0; rgszList[ListSize]; ListSize++) { ; } // count list items if(!n || (n > ListSize)) { Item = ""; } else { Item = rgszList[n-1]; } x = lstrlen(Item); VERIFY_SIZE(x); if(SpaceLeftInFieldBuffer >= x) { SpaceLeftInFieldBuffer -= x; for(y=0; y<x; y++) { *Interpret_OutputLoc++ = *Item++; } grcRTLastError = grcOkay; rc = TRUE; } } else { grcRTLastError = grcOutOfMemory; } if(rgszList != NULL) { FFreeRgsz(rgszList); } FFreeRgsz(rgsz); return(rc); } BOOL DoLocateItemInList( // 1-based, 0 if not found VOID ) { RGSZ rgsz,rgszList; UINT Item = 0, x,y; BOOL rc = FALSE; char szItem[25]; // arbitrary length char *szItemTemp; if((rgsz = DoOperator(2)) == NULL) { return(FALSE); } grcRTLastError = grcNotOkay; // rgsz[0] has list, rgsz[1] has item to locate if((rgszList = RgszFromSzListValue(rgsz[0])) != NULL) { for(x=0; rgszList[x]; x++) { if(!lstrcmpi(rgsz[1],rgszList[x])) { Item = x+1; break; } } FFreeRgsz(rgszList); wsprintf(szItem,"%u",Item); x = lstrlen(szItem); VERIFY_SIZE(x); if( x <= SpaceLeftInFieldBuffer) { SpaceLeftInFieldBuffer -= x; szItemTemp = szItem; for(y=0; y<x; y++) { *Interpret_OutputLoc++ = *szItemTemp++; } rc = TRUE; grcRTLastError = grcOkay; } } else { grcRTLastError = grcOutOfMemory; } FFreeRgsz(rgsz); return(rc); } BOOL DoList( VOID ) { RGSZ rgsz; LPVOID r; UINT RgszSize; UINT ItemCount; UINT ListLength,x; SZ List,ListSave; BOOL rc; if((rgsz = (RGSZ)SAlloc(10 * sizeof(SZ))) == NULL) { grcRTLastError = grcOutOfMemory; return(FALSE); } RgszSize = 10; ItemCount = 1; // reserve space for the NULL entry while(PEEKTOKEN() != TOKEN_LIST_END) { if(ItemCount == RgszSize) { if((r = SRealloc(rgsz, (RgszSize + 10) * sizeof(SZ) ) ) == NULL) { rgsz[ItemCount-1] = NULL; // for FFreeRgsz FFreeRgsz(rgsz); grcRTLastError = grcOutOfMemory; return(FALSE); } RgszSize += 10; rgsz = r; } if((rgsz[ItemCount-1] = Interpret_GetField()) == NULL) { FFreeRgsz(rgsz); return(FALSE); } ItemCount++; } EvalAssert(GETTOKEN() == TOKEN_LIST_END); // skip list end Assert(ItemCount <= RgszSize); rgsz[ItemCount-1] = NULL; // space for this reserved above rgsz = (RGSZ)SRealloc(rgsz,ItemCount * sizeof(SZ)); Assert(rgsz); // it was shrinking List = SzListValueFromRgsz(rgsz); FFreeRgsz(rgsz); if(List == NULL) { grcRTLastError = grcOutOfMemory; return(FALSE); } ListLength = lstrlen(List); ListSave = List; VERIFY_SIZE(ListLength); if(SpaceLeftInFieldBuffer >= ListLength) { SpaceLeftInFieldBuffer -= ListLength; for(x=0; x<ListLength; x++) { *Interpret_OutputLoc++ = *List++; } rc = TRUE; } else { grcRTLastError = grcNotOkay; rc = FALSE; } SFree(ListSave); return(rc); } BOOL DoString( BYTE StringToken ) { USHORT StringLength; UINT x; Assert(IS_STRING_TOKEN(StringToken)); if(StringToken < TOKEN_STRING) { // test for short string StringLength = (USHORT)StringToken - (USHORT)TOKEN_SHORT_STRING; } else if (StringToken == TOKEN_STRING) { // test for regular string StringLength = (USHORT)GETTOKEN() + (USHORT)100; } else { // long string Assert(StringToken == TOKEN_LONG_STRING); StringLength = (USHORT)GETTOKEN() << 8; StringLength |= (USHORT)GETTOKEN(); } VERIFY_SIZE( StringLength ); if(SpaceLeftInFieldBuffer >= StringLength) { SpaceLeftInFieldBuffer -= StringLength; for(x=0; x<StringLength; x++) { *Interpret_OutputLoc++ = GETTOKEN(); } } else { grcRTLastError = grcNotOkay; return(FALSE); } return(TRUE); } VOID GrowBuffer( UINT Size ) { while ( SpaceLeftInFieldBuffer < Size ) { // // Reallocate buffer // PUCHAR p; UINT Offset = Interpret_OutputLoc - InterpretedFieldBuffer; p = (PUCHAR)SRealloc( InterpretedFieldBuffer, BufferSize + MAX_FIELD_LENGTH); if ( p ) { InterpretedFieldBuffer = p; Interpret_OutputLoc = InterpretedFieldBuffer + Offset; SpaceLeftInFieldBuffer += MAX_FIELD_LENGTH; BufferSize += MAX_FIELD_LENGTH; } else { break; } } }