www.pudn.com > helpview.zip > Openfile.c, change:1997-10-15,size:11407b


/* 
  
Copyright 1997 Willows Software, Inc.  
 
This library is free software; you can redistribute it and/or 
modify it under the terms of the GNU Library General Public License as 
published by the Free Software Foundation; either version 2 of the 
License, or (at your option) any later version. 
 
This library is distributed in the hope that it will be useful, 
but WITHOUT ANY WARRANTY; without even the implied warranty of 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
Library General Public License for more details. 
 
You should have received a copy of the GNU Library General Public 
License along with this library; see the file COPYING.LIB.  If 
not, write to the Free Software Foundation, Inc., 675 Mass Ave, 
Cambridge, MA 02139, USA. 
 
*/ 
 
/*************************************************************************************** 
* 
* General File Functions 
* 
* Author: Paul E. Kissel 
* 
***************************************************************************************/ 
 
/************************************* 
* 
*  System Includes 
* 
**************************************/ 
#include <io.h> 
#include <fcntl.h> 
#include <direct.h> 
#include <string.h> 
#include <stdlib.h> 
 
 
/*********************************** 
** 
**  App. Includes 
** 
***********************************/ 
#include "general.h" 
#include "openfile.h" 
 
 
/************************************* 
* 
*  Private Defines 
* 
**************************************/ 
 
/* EnumFiles() callback function. */ 
typedef BOOL ( CALLBACK * FILESENUMPROC )( char * szFilePath, LPARAM lParam ); 
 
#define AUTOEXEC_PATH_DELIMITER  ';' 
#define EXTENSION_CHAR_SEPARATOR '.' 
 
 
/************************************* 
* 
*  Private Functions 
* 
**************************************/ 
static BOOL FindFilesPath( char * szHelpFileName, char * szPathBuffer ); 
static BOOL CALLBACK EnumFilesProc( char * szFilePath, LPARAM lParam ); 
static BOOL EnumFiles( char * szWildName, FILESENUMPROC EnumFilesProc, LPARAM lParam, BOOL Yield ); 
 
 
 
/*************************************************** 
* 
* Mimics the OpenFile() function but using only 
* Window95 approved calls. 
* 
****************************************************/ 
int OpenFileForReading( char * szFilePath, char * szFoundFilePath ) 
{ 
  BOOL bReturn; 
 
  /*  
  ** Get the complete path for the file if one's not supplied.  
  ** This is something that OpenFile did very nicely and something 
  ** that we still need since we are OFTEN expected to find the 
  ** right help file. 
  */ 
  bReturn = FindFilesPath( szFilePath, szFoundFilePath ); 
  if( bReturn == FALSE )  
  { 
    /* Error. */ 
    return( -1 ); 
  } 
   
  /* Open the file. */ 
  return( _open( szFoundFilePath, _O_BINARY | _O_RDONLY ) ); 
} 
 
 
 
/*************************************************** 
* 
* If a path is given, just copy the file's path to  
* the szPathBuffer. 
* 
* If a path is not given, locate the file 
* in the current directory, WINDOWS, WINDOWS\SYSTEM, 
* and PATH= directories.  If we find the file, 
* copy the file's path to the szPathBuffer. 
* 
* 
****************************************************/ 
static BOOL FindFilesPath( char * szHelpFileName, char * szPathBuffer ) 
{ 
  char * szPathSep;      /* A path separator token ( e.g. '\' ). */ 
   
   
  /* 
  ** First, we'll see if the file's path 
  ** is a path.  If it contains a path 
  ** separator token ( e.g. '\') then we 
  ** consider it a path. 
  */ 
   
  /* See the path separator in path. */ 
  szPathSep = strrchr( szHelpFileName, DIR_SEP_CHAR );  
 
  /* Found a separator in path. */ 
  if( szPathSep != NULL ) 
  { 
    /* Copy the path into the buffer. */ 
    strcpy( szPathBuffer, szHelpFileName ); 
   
    /* Success. */ 
    return( TRUE ); 
  } 
   
   
  /* 
  ** Next, we'll see if we can the specified file. 
  ** If we find it, we'll copy its name into the 
  ** buffer that was passed in. 
  */ 
   
  /* Clear the szPathBuffer. */ 
  *szPathBuffer = '\0'; 
   
  /* Try to find the file and get its full path. */ 
  EnumFiles( szHelpFileName, EnumFilesProc, (LPARAM) szPathBuffer, FALSE ); 
 
  /* Didn't find file. */ 
  if( *szPathBuffer == '\0' ) return FALSE; 
 
 
  /* Success. */ 
  return( TRUE ); 
} 
 
 
/************************************* 
* 
*  EnumFiles() callback function 
*  we have defined to receive a  
*  found file's full path. 
* 
**************************************/ 
static BOOL CALLBACK EnumFilesProc( char * szFilePath, LPARAM lParam ) 
{ 
  char * szSavePath; 
 
 
  /* Get lParam data structure. */ 
  szSavePath = (char *) lParam; 
   
  /* Save full path. */ 
  strcpy( szSavePath, szFilePath ); 
 
  /* Stop enumerating. */ 
  return FALSE; 
} 
 
 
/************************************* 
* 
*  Search for a file in the following places: 
*  - Current dir. 
*  - /WINDOWS  
*  - /WINDOWS/SYSTEM 
*  - All directories listed in the system's $PATH$ variable. 
* 
*  Call EnumFilesProc() if a matching file is found. 
* 
**************************************/ 
static BOOL EnumFiles( char * szWildName, FILESENUMPROC EnumFilesProc, LPARAM lParam, BOOL Yield ) 
{ 
  char szWinDir[_MAX_PATH]; 
  char szWinSysDir[_MAX_PATH]; 
  char szCurrentDir[_MAX_PATH]; 
 
  char szDir[_MAX_PATH]; 
  char szFilePath[_MAX_PATH]; 
  char szPathCopyBuffer[_MAX_PATH]; 
 
  char * szPathCopy; 
  char * szPath; 
  char * szNextPath; 
 
  struct _finddata_t FileInfo; 
  long hFileFind; 
 
  int nPhase, nResult; 
 
  BOOL bCallBack; 
   
  MSG Msg;              // Storage for messages pulled from windows message 
                        // queue.    
                         
 
  /* Each phase equates to a different search path. */ 
     
  for( nPhase = 1; nPhase < 5; nPhase ++ ) 
  { 
    /* If we should let other applications execute. */ 
    if( Yield ) 
    { 
      while ( PeekMessage( &Msg, NULL, 0, 0, PM_REMOVE ) ) 
      { 
        TranslateMessage( &Msg ); 
        DispatchMessage( &Msg ); 
      } 
    } 
     
    switch( nPhase ) 
    { 
      /* PHASE 1: use current directory.  */ 
      case 1:  
        getcwd( szDir, _MAX_PATH ); 
        strcpy( szCurrentDir, szDir ); 
        break; 
 
      /* PHASE 2: use windows directory */ 
      case 2:  
        GetWindowsDirectory( szDir, _MAX_PATH); 
        strcpy( szWinDir, szDir ); 
        break; 
 
      /* PHASE 3: use windows\system directory */ 
      case 3:  
        GetSystemDirectory( szDir, _MAX_PATH); 
        strcpy( szWinSysDir, szDir ); 
        break; 
    }  
 
 
    /* For Phases #1 - #3. */ 
    if( nPhase < 4 ) 
    { 
      /* Build full path for search directory and wild name of file. */ 
      strcpy( szFilePath, szDir ); 
      strcat( szFilePath, DIR_SEP_STR ); 
      strcat( szFilePath, szWildName ); 
 
      /* Find the first file. */ 
      hFileFind = _findfirst( szFilePath, &FileInfo ); 
      if( hFileFind != -1 ) 
      { 
        strcpy( szFilePath, szDir ); 
        strcat( szFilePath, DIR_SEP_STR ); 
        strcat( szFilePath, FileInfo.name ); 
         
        /* Call EnumFilesProc() callback function. */ 
        bCallBack = ( *EnumFilesProc )( szFilePath, lParam );  
         
        /* Does callback tell us to quit. */ 
        if( !bCallBack ) 
        { 
          _findclose( hFileFind ); 
          return TRUE; 
        } 
 
        /* Find next matching file. */ 
        while( _findnext( hFileFind, &FileInfo ) != -1 ) 
        { 
          strcpy( szFilePath, szDir ); 
          strcat( szFilePath, DIR_SEP_STR ); 
          strcat( szFilePath, FileInfo.name ); 
           
          /* Call EnumFilesProc() callback function. */ 
          bCallBack = ( *EnumFilesProc )( szFilePath, lParam );  
           
          /* Does callback tell us to quit. */ 
          if( !bCallBack ) 
          { 
            _findclose( hFileFind ); 
            return TRUE; 
          } 
        } 
         
        /* Stop search. */ 
        _findclose( hFileFind ); 
      } 
    } 
 
 
    /* For Phase #4 - Use PATH. */ 
    else 
    { 
      /* Is there a WIN_PATH set? */ 
      szPath = getenv("WIN_PATH"); 
       
      /* If no WIN_PATH set, use standard PATH variable. */ 
      if( szPath == NULL ) szPath = getenv( "PATH" ); 
     
      /* If we have some path to search. */ 
      if( szPath != 0) 
      { 
        /* Make a copy of the path so that we can change with the copy. */ 
        lstrcpy( (LPSTR) szPathCopyBuffer, (LPSTR) szPath ); 
        szPathCopy = szPathCopyBuffer; 
         
        /* Walk the path... */ 
        for( szNextPath = szPathCopy; szNextPath && *szNextPath; szNextPath = szPathCopy)  
        { 
          /* If we should let other applications execute. */ 
          if( Yield ) 
          { 
            while ( PeekMessage( &Msg, NULL, 0, 0, PM_REMOVE ) ) 
            { 
              TranslateMessage( &Msg ); 
              DispatchMessage( &Msg ); 
            } 
          } 
           
          /* Get the next element in the path and terminate it */ 
          szPathCopy = strchr( szNextPath, AUTOEXEC_PATH_DELIMITER ); 
          if( szPathCopy ) 
          { 
            *szPathCopy = 0;  /* End the current part. */ 
            szPathCopy++;     /* Point to the next one. */ 
          } 
     
          /* If it's a directory that we've already visited - skip search. */ 
          nResult = stricmp( szNextPath, szWinDir );   /* \Windows dir. */ 
          if( nResult == 0 ) continue; 
          nResult = stricmp( szNextPath, szWinSysDir );   /* \Windows\System dir. */ 
          if( nResult == 0 ) continue; 
          nResult = stricmp( szNextPath, szCurrentDir );   /* Original dir. */ 
          if( nResult == 0 ) continue; 
 
          /* Build full path for search directory and wild name of file. */ 
          strcpy( szFilePath, szNextPath ); 
          strcat( szFilePath, DIR_SEP_STR ); 
          strcat( szFilePath, szWildName ); 
 
          /* Find the first file. */ 
          hFileFind = _findfirst( szFilePath, &FileInfo ); 
          if( hFileFind != -1 ) 
          { 
            strcpy( szFilePath, szNextPath ); 
            strcat( szFilePath, DIR_SEP_STR ); 
            strcat( szFilePath, FileInfo.name ); 
 
            /* Call EnumFilesProc() callback function. */ 
            bCallBack = ( *EnumFilesProc )( szFilePath, lParam );  
             
            /* Does callback tell us to quit. */ 
            if( !bCallBack ) 
            { 
              _findclose( hFileFind ); 
              return TRUE; 
            } 
 
            /* Find next matching file. */ 
            while( _findnext( hFileFind, &FileInfo ) != -1 ) 
            { 
              strcpy( szFilePath, szNextPath ); 
              strcat( szFilePath, DIR_SEP_STR ); 
              strcat( szFilePath, FileInfo.name ); 
           
              /* Call EnumFilesProc() callback function. */ 
              bCallBack = ( *EnumFilesProc )( szFilePath, lParam );  
               
              /* Does callback tell us to quit. */ 
              if( !bCallBack ) 
              { 
                _findclose( hFileFind ); 
                return TRUE; 
              } 
            }  
          } 
         
          /* Stop search. */ 
          _findclose( hFileFind ); 
        } 
      } 
    } 
  } /* for loop. */ 
   
   
  /* Return success. */ 
  return( TRUE ); 
}