#include #include #include #define BINPLACE_MAX_FULL_PATH 4096 // must match value in binplace.c extern BOOL fVerbose; // imported from binplace.c BOOL PlaceFileMatch( IN LPCSTR FullFileName, IN OUT LPSTR PlaceFileEntry, // May be modified by env. var expansion OUT LPSTR PlaceFileClass, // assumed CHAR[BINPLACE_MAX_FULL_PATH] OUT LPSTR *PlaceFileNewName ) // Returns TRUE if the filename matches the placefile entry. // On TRUE return, PlaceFileNewName points to location within // PlaceFileEntry. On FALSE return, PlaceFileClass and PlaceFileNewName are undefined. { const CHAR *pchEntryOrig; // Point to current parse pos of PlaceFileEntry CHAR szEntryExp[BINPLACE_MAX_FULL_PATH]; // Holds fileEntry after environment expansion PCHAR pchEntryExp, pchEntryExpEnd; // Point to current pos and end of EntryExp PCHAR pchVarStart; // Points into EntryExp: where an env. expansion should start replacing LPCSTR pszEnvVar; const CHAR *pchEntryFnEnd; // Stores the end of the filename const CHAR *pchFn; // Stores the current position within the filename PCHAR pch; PCHAR pchClass; // Current position within PlaceFileClass // Check for early-exit opportunities if( !PlaceFileEntry || !FullFileName || !PlaceFileClass || PlaceFileEntry[0]==';' || // It is a full-line comment PlaceFileEntry[0]=='\0' // Blank line ) { return FALSE; } // *** // *** Expand any environment variables in PlaceFileEntry (result goes back into PlaceFileEntry) // *** pchEntryExp = szEntryExp; pchEntryExpEnd = pchEntryExp + (sizeof(szEntryExp)/sizeof(szEntryExp[0])) - 1; pchVarStart = NULL; // Indicates that I haven't passed the starting % of an env. var. // Skip over leading whitespace for( pchEntryOrig = PlaceFileEntry; *pchEntryOrig==' ' || *pchEntryOrig=='\t'; pchEntryOrig++ ) {} // StrCopy with environment variable replacement while(*pchEntryOrig && pchEntryExpPlaceFileEntry && pchFn > FullFileName) { pchEntryOrig--; pchFn--; if('*' == *pchEntryOrig) { // Wildcard for this portion if(*(pchEntryOrig+1)!='\\' && *(pchEntryOrig+1)!='/') { // Invalid: "dir\*abc\filename" // This also catches the invalid "dir\*" (wildcard invalid for filename). if (fVerbose) { fprintf( stdout, "BINPLACE : warning BNP0000: No wildcard in filename or mixed wildcard/text in class name: \"%s\"\n", PlaceFileEntry ) ; } return FALSE; } pchEntryOrig--; // Skip over the * if( pchEntryOrig <= PlaceFileEntry || // Can't start with wildcard ("*\dir\filename"). ('\\'!=*pchEntryOrig && '/'!=*pchEntryOrig) // No partial wildcard ("dir\abc*\filename"). ) { if (fVerbose) { fprintf( stdout, "BINPLACE : warning BNP0000: No wildcard at start of path or mixed wildcard/text in class name: \"%s\"\n", PlaceFileEntry ) ; } return FALSE; } while(pchFn > FullFileName && *pchFn != '\\' && *pchFn != '/') // Skip wildcarded directory name pchFn--; // Both pchFn and pchEntryOrig are now on a slash. } else { if(toupper(*pchFn) != toupper(*pchEntryOrig)) { if( // Mismatch ok only on forward/backward slashes. !(*pchFn == '/' || *pchFn == '\\') || !(*pchEntryOrig == '/' || *pchEntryOrig == '\\') ) { return FALSE; // Names don't match - exit } } } } // Did we match? Conditions to be met: // pchEntryOrig==PlaceFileEntry (match pattern completely consumed) // pchFn==FullFileName (full file name completely consumed, perverse case) OR *pchFn==slash (normal case). if( pchEntryOrig != PlaceFileEntry || (pchFn != FullFileName && *(pchFn-1) !='/' && *(pchFn-1) != '\\') ) { return FALSE; } // *** // *** Its a match. Set output variables accordingly. // *** // Skip to next whitespace (to skip over NewName, if present). for( pchEntryOrig = pchEntryFnEnd; // This is 1 past the end of the filename (saved previously) *pchEntryOrig!=0 && *pchEntryOrig!=' ' && *pchEntryOrig!='\t'; pchEntryOrig++ ) {} // Skip over whitespace before the class name for( ; // Already set *pchEntryOrig==' ' || *pchEntryOrig=='\t'; pchEntryOrig++ ) {} // pchEntryOrig is now at the start of the class name. Copy till an invalid char is reached. pchClass = PlaceFileClass; while(*pchEntryOrig!=0 && *pchEntryOrig!=' ' && *pchEntryOrig!='\t' && *pchEntryOrig!='!') { *pchClass++ = *pchEntryOrig++; } *pchClass = 0; // NULL terminate if(pchClass == PlaceFileClass) { // No class name specified! if (fVerbose) { fprintf( stdout, "BINPLACE : warning BNP0000: No class name in entry \"%s\"\n", PlaceFileEntry ) ; } return FALSE; } if (PlaceFileNewName != NULL) { *PlaceFileNewName = strchr(PlaceFileEntry,'!'); if(*PlaceFileNewName) { *(*PlaceFileNewName)++ = 0; // Set the '!' to NULL, and skip past it to the Newname. } } return TRUE; }