DWORD RegLexParseAt( PREGLEX_ITEM lexHandle, HANDLE ioHandle, CHAR inC) { DWORD dwError = 0; BOOLEAN eof = FALSE; BOOLEAN bHasSecurity = FALSE; if (lexHandle->state != REGLEX_STATE_IN_QUOTE && lexHandle->state != REGLEX_STATE_IN_KEY) { /* Default value for a registry key */ lexHandle->isToken = TRUE; lexHandle->curToken.lineNum = lexHandle->parseLineNum; lexHandle->curToken.token = REGLEX_KEY_NAME_DEFAULT; lexHandle->state = REGLEX_STATE_INIT; lexHandle->curToken.valueCursor = 0; RegLexAppendChar(lexHandle, inC); /* Handle the case of @frob, i.e. "@security" */ dwError = RegIOGetChar(ioHandle, &inC, &eof); while (dwError == 0 && !eof && isalpha((int) inC)) { RegLexAppendChar(lexHandle, inC); dwError = RegIOGetChar(ioHandle, &inC, &eof); bHasSecurity = TRUE; } if (eof) { return dwError; } dwError = RegIOUnGetChar(ioHandle, NULL); if (bHasSecurity) { if (strcmp(lexHandle->curToken.pszValue, "@security") == 0) { lexHandle->eValueNameType = REGLEX_VALUENAME_SECURITY; } else { dwError = LWREG_ERROR_UNEXPECTED_TOKEN; } } } return dwError; }
DWORD RegLexParseComment( PREGLEX_ITEM lexHandle, HANDLE ioHandle, CHAR inC) { DWORD dwError = 0; BOOLEAN eof = FALSE; if (lexHandle->state == REGLEX_STATE_IN_QUOTE || lexHandle->state == REGLEX_STATE_IN_KEY) { RegLexAppendChar(lexHandle, inC); } else { do { dwError = RegIOGetChar(ioHandle, &inC, &eof); } while (dwError == 0 && !eof && inC != '\n' && inC != '\r'); if (!eof && (inC == '\n' || inC == '\r')) { dwError = RegIOUnGetChar(ioHandle, NULL); } } return dwError; }
DWORD RegLexParseDash( PREGLEX_ITEM lexHandle, HANDLE ioHandle, CHAR inC) { DWORD dwError = 0; BOOLEAN eof = FALSE; BOOLEAN isDash = FALSE; if (lexHandle->curToken.pszValue[lexHandle->curToken.valueCursor] == '-') { isDash = TRUE; } else { dwError = RegIOGetChar(ioHandle, &inC, &eof); if (inC == '\r' || inC == '\n') { isDash = TRUE; } else if (inC != '-') { RegLexAppendChar(lexHandle, '-'); RegLexAppendChar(lexHandle, inC); return dwError; } else { dwError = RegIOUnGetChar(ioHandle, NULL); isDash = TRUE; } } if (isDash && lexHandle->state != REGLEX_STATE_IN_QUOTE && lexHandle->state != REGLEX_STATE_IN_KEY && lexHandle->eValueNameType != REGLEX_VALUENAME_SECURITY) { if (lexHandle->curToken.valueCursor > 0) { dwError = RegIOUnGetChar(ioHandle, NULL); lexHandle->isToken = TRUE; lexHandle->curToken.lineNum = lexHandle->parseLineNum; } else { lexHandle->isToken = TRUE; lexHandle->curToken.lineNum = lexHandle->parseLineNum; lexHandle->curToken.token = REGLEX_DASH; lexHandle->curToken.valueCursor = 0; RegLexAppendChar(lexHandle, inC); } } else { RegLexAppendChar(lexHandle, inC); } return dwError; }
DWORD RegLexParseNewline( PREGLEX_ITEM lexHandle, HANDLE ioHandle, CHAR inC) { DWORD dwError = 0; CHAR prevC = '\0'; BOOLEAN eof = 0; if (lexHandle->state != REGLEX_STATE_IN_QUOTE) { /* * Throw out CR when not in a quoted string. CR/LF * is still handled correctly by this treatment. */ if (inC == '\r') { return dwError; } } else { /* * Count CR/LF sequence in a quoted string as a single newline. * A bare CR is maintained, but not counted as a newline. */ if (inC == '\r') { RegLexAppendChar(lexHandle, inC); dwError = RegIOGetChar(ioHandle, &inC, &eof); if (eof) { return dwError; } if (inC == '\n') { RegLexAppendChar(lexHandle, inC); lexHandle->parseLineNum++; } else { dwError = RegIOUnGetChar(ioHandle, &inC); } } } if (lexHandle->state != REGLEX_STATE_IN_QUOTE) { lexHandle->parseLineNum++; } /* Emit the final token in a BINHEX_STR sequence */ if (lexHandle->state == REGLEX_STATE_BINHEX_STR) { /* Don't care about "\\n sequence */ dwError = RegIOGetPrevChar(ioHandle, &prevC); if (dwError == ERROR_SUCCESS && prevC == '\\') { return dwError; } lexHandle->isToken = TRUE; lexHandle->curToken.lineNum = lexHandle->parseLineNum; lexHandle->curToken.token = REGLEX_HEXPAIR_END; lexHandle->state = REGLEX_STATE_INIT; return dwError; } else if (lexHandle->tokenDataType == REGLEX_REG_STRING_ARRAY) { lexHandle->isToken = TRUE; lexHandle->curToken.lineNum = lexHandle->parseLineNum; lexHandle->tokenDataType = REGLEX_FIRST; return dwError; } else if (lexHandle->state == REGLEX_STATE_DWORD) { if (lexHandle->curToken.valueCursor == 8) { lexHandle->isToken = TRUE; lexHandle->curToken.lineNum = lexHandle->parseLineNum; lexHandle->curToken.token = REGLEX_REG_DWORD; return dwError; } else { dwError = LWREG_ERROR_UNEXPECTED_TOKEN; lexHandle->curToken.lineNum = lexHandle->parseLineNum; return dwError; } } else if ((lexHandle->state == REGLEX_STATE_INIT || lexHandle->state == REGLEX_STATE_INTEGER_RANGE) && lexHandle->curToken.valueCursor > 0) { /* * This is "junk" accumulated so far, since no valid token start * has been found before the current end-of-line. */ lexHandle->isToken = TRUE; lexHandle->curToken.lineNum = lexHandle->parseLineNum - 1; lexHandle->curToken.token = REGLEX_PLAIN_TEXT; return dwError; } else { /* Syntax error case... */ /* Error needed */ } return dwError; }
DWORD RegLexParseBackslash( PREGLEX_ITEM lexHandle, HANDLE ioHandle, CHAR inC) { DWORD dwError = 0; BOOLEAN eof = FALSE; if (lexHandle->state == REGLEX_STATE_BINHEX_STR || lexHandle->tokenDataType == REGLEX_REG_STRING_ARRAY) { /* Eat line continuation character when in BINHEX state */ dwError = RegIOGetChar(ioHandle, &inC, &eof); if (eof) { return dwError; } if (inC == '\r' || inC == '\n') { lexHandle->parseLineNum++; dwError = RegIOGetChar(ioHandle, &inC, &eof); if (eof) { return dwError; } if (inC != '\r' && inC != '\n') { dwError = RegIOUnGetChar(ioHandle, NULL); } } else { dwError = RegIOUnGetChar(ioHandle, NULL); } } if (lexHandle->state == REGLEX_STATE_IN_QUOTE) { /* * Treat sequence '\C' (C=any character) as * the literal escaped character. Only handle backslashes * in this way when in quoted strings. When processing a * registry key value, this is a "bad thing" to do. * [HKEY_LOCAL_MACHINE\HARDWARE] * This processing in this case would be an escaped 'H', not * what is intended. */ dwError = RegIOGetChar(ioHandle, &inC, &eof); if (!eof) { switch(inC) { case 'n': RegLexAppendChar(lexHandle, '\n'); break; case 'r': RegLexAppendChar(lexHandle, '\r'); break; case 't': RegLexAppendChar(lexHandle, '\t'); break; case 'a': RegLexAppendChar(lexHandle, '\a'); break; case 'v': RegLexAppendChar(lexHandle, '\v'); break; case 'f': RegLexAppendChar(lexHandle, '\f'); break; case '\\': RegLexAppendChar(lexHandle, '\\'); break; case '"': RegLexAppendChar(lexHandle, '"'); break; default: RegLexAppendChar(lexHandle, '\\'); RegLexAppendChar(lexHandle, inC); break; } } } else if (lexHandle->state == REGLEX_STATE_IN_KEY) { RegLexAppendChar(lexHandle, '\\'); } else if (lexHandle->state != REGLEX_STATE_BINHEX_STR) { RegLexAppendChar(lexHandle, '\\'); } lexHandle->curToken.lineNum = lexHandle->parseLineNum; return dwError; }
DWORD RegLexGetToken( HANDLE ioHandle, PREGLEX_ITEM lexHandle, PREGLEX_TOKEN pRetToken, PBOOLEAN pEof) { DWORD dwError = 0; CHAR inC = 0; BOOLEAN eof = FALSE; BAIL_ON_INVALID_HANDLE(ioHandle); BAIL_ON_INVALID_HANDLE(lexHandle); BAIL_ON_INVALID_HANDLE(pRetToken); *pRetToken = REGLEX_FIRST; if (lexHandle->isToken && lexHandle->curToken.token != REGLEX_HEXPAIR && lexHandle->curToken.token != REGLEX_REG_BINARY) { if ( lexHandle->curToken.token == REGLEX_REG_DWORD) { lexHandle->state = (REGLEX_STATE)REGLEX_FIRST; } lexHandle->isToken = FALSE; lexHandle->curToken.token = REGLEX_FIRST; lexHandle->curToken.valueCursor = 0; } /* Return pushed back token, if one is present */ if (lexHandle->prevToken.token != REGLEX_FIRST) { lexHandle->curToken = lexHandle->prevToken; lexHandle->prevToken.token = REGLEX_FIRST; *pRetToken = lexHandle->curToken.token; return dwError; } if (lexHandle->state == REGLEX_STATE_INIT || lexHandle->curToken.token == REGLEX_HEXPAIR || lexHandle->curToken.token == REGLEX_HEXPAIR_END) { lexHandle->curToken.valueCursor = 0; } if (!lexHandle->curToken.pszValue) { /* Extra byte for string termination */ LWREG_SAFE_FREE_MEMORY(lexHandle->curToken.pszValue); dwError = RegAllocateMemory(REGLEX_DEFAULT_SZ_LEN + 1, (LW_PVOID) &lexHandle->curToken.pszValue); BAIL_ON_REG_ERROR(dwError); lexHandle->curToken.valueCursor = 0; lexHandle->curToken.valueSize = REGLEX_DEFAULT_SZ_LEN; } do { lexHandle->isToken = FALSE; dwError = RegIOGetChar(ioHandle, &inC, &eof); if (eof) { if (lexHandle->curToken.token != REGLEX_FIRST && lexHandle->curToken.valueCursor > 0) { lexHandle->isToken = TRUE; *pRetToken = lexHandle->curToken.token; } else { if (lexHandle->state == REGLEX_STATE_IN_QUOTE) { dwError = LWREG_ERROR_UNEXPECTED_TOKEN; } else if (lexHandle->state == REGLEX_STATE_IN_KEY) { lexHandle->isToken = TRUE; lexHandle->curToken.token = REGLEX_REG_KEY; lexHandle->state = REGLEX_STATE_INIT; *pRetToken = lexHandle->curToken.token; *pEof = 0; break; } *pEof = eof; } break; } dwError = lexHandle->parseFuncArray[REGLEX_CHAR_INDEX(inC)]( lexHandle, ioHandle, inC); BAIL_ON_REG_ERROR(dwError); if (lexHandle->isToken) { *pRetToken = lexHandle->curToken.token; break; } } while (dwError == ERROR_SUCCESS); cleanup: return dwError; error: goto cleanup; }