#include #include #include #include #include #include #ifdef RLDOS #include "dosdefs.h" #else #include #include "windefs.h" #endif #include "restok.h" #include "commbase.h" #include "resread.h" extern UCHAR szDHW[]; // // The syssetup.dll, that has been contained Windows NT 4.00, has the largest // message strings than ever. So, we have to expand buffer size(to 20480). // #define MAX_OUT_BUFFER 20480 CHAR gt_szTextBuffer[ MAX_OUT_BUFFER]; TCHAR pt_szOutBuffer[MAX_OUT_BUFFER]; /** * * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * * **/ /*--------------------------------------------------------- * Function: GetToken * Input: fpInFile File pointer, points to the token to be read. * tToken Pointer to a token. * * * Output: fpInFile File pointer after read operation. * points to the next token in the file. * tToken The token read in from the file. Memory will have been * allocated for the token text, unless no token was read in. * * Return code: * 0 = Read token, every thing OK * 1 = Empty line or line started with # (Comment) * -1 = End of FILE * -2 = Error reading from file. * * History: * 01/93 Re-written to read in long token text strings. MHotchin * *----------------------------------------------------------*/ int GetToken( FILE *fpInFile, //... File to get token from. TOKEN *pToken) //... Buffer for token. { int chNextChar = 0; int cTextLen = 0; int rc = 0; // Read token from file. // we will want to use MyGetStr, when // tokens are in UNICODE // Strip off leading whitespace, and check // for blank lines. chNextChar = fgetc( fpInFile); while ( (chNextChar == ' ') || (chNextChar == '\t') ) { chNextChar = fgetc( fpInFile); } if ( chNextChar == EOF ) { return ( -1); } else if ( chNextChar == '\n' ) { return ( 1); } // Now we have the first non-white space // character. // Check for a comment line, and strip out the // remainder of the line if it is. else if ( chNextChar == '#' ) { fscanf( fpInFile, "%*[^\n]"); chNextChar = fgetc( fpInFile); if ( chNextChar == EOF ) { return ( -1); } else { return ( 1); } } // Now we are positioned at the first // non-whitespace character. Check it, and // read in the numbers... else if ( chNextChar != '[' ) { // Bad format? return ( -2); } if ( fscanf( fpInFile, "[%hu|%hu|%hu|%hu|%hu", &pToken->wType, &pToken->wName, &pToken->wID, &pToken->wFlag, &pToken->wReserved) != 5 ) { QuitA( IDS_ENGERR_12, (LPSTR)IDS_BADTOKID, NULL); } // Now that we have all the numbers, we can // look for the name of the token. if ( (pToken->wName == IDFLAG) || (pToken->wType == ID_RT_ERRTABLE) ) { static char szName[ TOKENSTRINGBUFFER]; int nRC = 0; nRC = fscanf( fpInFile, "|\"%[^\"]", szName); if ( nRC == EOF ) { QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKNAME, NULL); } #ifndef UNITOK #ifdef RLRES32 if (nRC) _MBSTOWCS( (TCHAR *)pToken->szName, szName, TOKENSTRINGBUFFER, lstrlenA( szName) + 1); else _MBSTOWCS( (TCHAR *)pToken->szName, "", TOKENSTRINGBUFFER, lstrlenA( szName) + 1); #else if (nRC) strcpy( pToken->szName, szName); else *pToken->szName = '\0'; #endif #else if (nRC) strcpy( pToken->szName, szName); else *pToken->szName = '\0'; #endif } else { if ( fscanf( fpInFile, "|\"%*[^\"]") != 0 ) { QuitT( IDS_ENGERR_05, (LPTSTR)IDS_NOSKIPNAME, NULL); } pToken->szName[0] = '\0'; } // Now the name has been read, and we are // positioned at the last '"' in the text // stream. Allocate memory for the token // text, and read it in. fgets( gt_szTextBuffer, sizeof(gt_szTextBuffer), fpInFile); // Now that the token text is read in, // convert it to whatever character type // we are expecting. First strip the newline! StripNewLineA( gt_szTextBuffer); cTextLen = lstrlenA( gt_szTextBuffer); if ( cTextLen < 4 ) { // Must be more than "\"]]=" in szTextBuffer return ( -2); } pToken->szText = (TCHAR *)FALLOC( MEMSIZE( cTextLen - 3)); #ifndef UNITOK #ifdef RLRES32 _MBSTOWCS( pToken->szText, gt_szTextBuffer+4, cTextLen - 3, cTextLen - 3); #else strcpy( pToken->szText, gt_szTextBuffer+4); #endif // RLRES32 #else // UNITOK strcpy( pToken->szText, gt_szTextBuffer+4); #endif // UNITOK return ( 0); } /** * * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * 01/93 Added new character count field. MHotchin * **/ int PutToken( FILE *fpOutFile, //... Token file to write to TOKEN *tToken) //... Token to be writen to the token file { WORD rc = 0; PCHAR pszBuf = NULL; ParseTokToBuf( pt_szOutBuffer, tToken); // RLFREE( tToken->szText); #ifdef RLRES32 if ( ! _WCSTOMBS( szDHW, pt_szOutBuffer, DHWSIZE, lstrlen( pt_szOutBuffer) + 1) ) { QuitT( IDS_ENGERR_26, pt_szOutBuffer, NULL); } pszBuf = szDHW; #else pszBuf = pt_szOutBuffer; #endif return fprintf( fpOutFile, "%s\n", pszBuf); } /** * Function: FindToken * Finds a token whose status bits match only where the mask is set. * * Arguments: * fpSearchFile -- search file * psTok -- pointer to the token * uMask -- status bit mask * * Returns: * string and status of found token * * Errors Codes: * 0 - token not found * 1 - token found * * History: * 01/93 Added support for var length token text strings. Previous token text * is de-allocated! MHotchin * **/ int FindToken( FILE *fpSearchFile, TOKEN *psTok, WORD wMask) { BOOL fFound = FALSE; BOOL fStartOver = TRUE; int error; int nTokensRead = 0; long lStartFilePos, lFilePos; TOKEN cTok; //... Remember where we are starting lFilePos = lStartFilePos = ftell(fpSearchFile); do { long lType11Pos = 0; do { lType11Pos = ftell( fpSearchFile); error = GetToken( fpSearchFile, &cTok); if ( error == 0 ) { //... Is this the token we are looking for? fFound = ((cTok.wType == psTok->wType) && (cTok.wName == psTok->wName) && (cTok.wID == psTok->wID) && (cTok.wFlag == psTok->wFlag) && ((WORD)(cTok.wReserved & wMask) == psTok->wReserved) && (_tcscmp( (TCHAR *)cTok.szName, (TCHAR *)psTok->szName) == 0)); } if ( ! fFound ) { //... If we were looking for another segment to //... an NT Msg Table entry, move back to the //... token we just read and quit (speedup). if ( psTok->wType == ID_RT_ERRTABLE && psTok->wFlag > 0 && error == 0 ) { if ( cTok.wType != psTok->wType || cTok.wName != psTok->wName || cTok.wID != psTok->wID || cTok.wFlag > psTok->wFlag ) { fseek( fpSearchFile, lType11Pos, SEEK_SET); RLFREE( cTok.szText); return ( FALSE); } } else if ( error >= 0 ) { lFilePos = ftell(fpSearchFile); if (error == 0) { RLFREE(cTok.szText); } } else if (error == -2) { return ( FALSE); } } } while ( ! fFound && (error >= 0) && (fStartOver || (lFilePos < lStartFilePos)) ); if ( ! fFound && (error == -1) && fStartOver ) { rewind(fpSearchFile); lFilePos = 0L; fStartOver = FALSE; } } while ( ! fFound && (lFilePos < lStartFilePos) ); //... Did we find the desired token? if ( fFound ) { //... Yes, we found it psTok->wReserved = cTok.wReserved; RLFREE( psTok->szText); psTok->szText = cTok.szText; } return ( fFound); } /** * * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * 01/93 Added support for new token text count. MHotchin * **/ void ParseBufToTok( TCHAR *szToken, TOKEN *pTok ) { TCHAR *pos; WORD bChars; if ( _stscanf( szToken, TEXT("[[%hu|%hu|%hu|%hu|%hu"), &pTok->wType, &pTok->wName, &pTok->wID, &pTok->wFlag, &pTok->wReserved) != 5 ) { QuitT( IDS_BADTOK, szToken, NULL); } if ( pTok->wName == IDFLAG || pTok->wType == ID_RT_ERRTABLE ) { //... Find Names's first char and get it's len if ( pos = _tcschr( (TCHAR *)szToken, TEXT('"')) ) { TCHAR *pStart; pStart = ++pos; bChars = 0; while ( *pos && *pos != TEXT('"') && bChars < TOKENSTRINGBUFFER - 1 ) { bChars++; pos++; } // while CopyMemory( pTok->szName, pStart, min( TOKENSTRINGBUFFER, bChars) * sizeof( TCHAR)); pTok->szName[ bChars ] = TEXT('\0'); } else { //... No token ID found QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKNAME, NULL); } } else { // Don't forget the zero termination pTok->szName[0] = TEXT('\0'); } // now do the token text pos = _tcschr ((TCHAR *)szToken, TEXT(']')); if ( pos ) { // This can be written better now that we know the text length. bChars = (WORD)lstrlen( pos); if ( bChars > 3 ) { pos += 3; bChars -= 3; pTok->szText = (TCHAR *)FALLOC( MEMSIZE( bChars + 1)); CopyMemory( pTok->szText, pos, MEMSIZE( bChars + 1)); // Don't forget the zero termination pTok->szText[ bChars] = TEXT('\0'); } else if ( bChars == 3 ) { //... Empty token text pTok->szText = (TCHAR *) FALLOC( 0); } else { //... No token ID found QuitT( IDS_ENGERR_05, (LPTSTR)IDS_INVTOKID, NULL); } } else { //... No token ID found QuitT( IDS_ENGERR_05, (LPTSTR)IDS_NOTOKID, NULL); } } /** * * * Function: * * * Arguments: * * Returns: * * Errors Codes: * * History: * **/ void ParseTokToBuf( TCHAR *szToken, TOKEN *pTok ) { *szToken = TEXT('\0'); if ( pTok != NULL) { wsprintf( szToken, TEXT("[[%hu|%hu|%hu|%hu|%hu|\"%s\"]]="), pTok->wType, pTok->wName, pTok->wID, pTok->wFlag, pTok->wReserved, pTok->szName); if (pTok->szText) lstrcat(szToken, pTok->szText); } } /** * * * Function: TokenToTextSize * This calculates the number of characters needed to hold * the text representation of a token. * * Arguments: * pTok The token to measure. * * Returns: * int The number of characters needed to hold the token, not * including a null terminator. [[%hu|%hu|%hu|%hu|%hu|\"%s\"]]=%s * * Errors Codes: * None. * * History: * 01/18/93 MHotchin Created. * **/ int TokenToTextSize( TOKEN *pTok) { int cTextLen; cTextLen = (14 + // Separators and terminator ( + 1 extra) 30); // Space for 5 numeric fields (65,535 = 6 chars) if ( pTok->szText != NULL ) { // Add space for the Token text cTextLen += MEMSIZE( lstrlen( pTok->szText) ); } cTextLen += lstrlen( pTok->szName); return ( cTextLen); }