home *** CD-ROM | disk | FTP | other *** search
- /*++
-
- Copyright (c) 1995-1997 Microsoft Corporation
-
- Module Name :
-
- openf.c
-
- Abstract:
-
- This module implements a simple open file handle cache
-
- Project:
-
- ISAPI Extensions Sample DLL
-
- Functions Exported:
-
-
- Note:
- THIS IS NOT ROBUST for REAL WORLD.
- I wrote this for testing the ISAPI Async IO processing.
-
- --*/
-
-
- /************************************************************
- * Include Headers
- ************************************************************/
-
- # include "openf.h"
-
-
- /************************************************************
- * Type definitions and Globals
- ************************************************************/
-
- //
- // internal data structure for maintaining the list of open file handles.
- //
-
- typedef struct _OPEN_FILE {
-
- HANDLE hFile;
- struct _OPEN_FILE * pNext;
- LONG nHits;
- LONG nRefs;
- CHAR rgchFile[MAX_PATH+1];
-
- } OPEN_FILE, * LPOPEN_FILE;
-
-
- LPOPEN_FILE g_pOpenFiles = NULL;
- CRITICAL_SECTION g_csOpenFiles;
- BOOL g_fIsNt = TRUE;
-
- //
- // Set up global variables containing the flags for CreateFile
- // The flags can be masked for Windows 95 system
- //
-
- DWORD g_dwCreateFileShareMode =
- (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
-
- DWORD g_dwCreateFileFlags =
- (FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED);
-
- /************************************************************
- * Functions
- ************************************************************/
-
-
- DWORD
- InitFileHandleCache(VOID)
- /*++
-
- This function initializes the file handle cache.
- It should be called at the initialization time.
-
- Arguments:
- None
-
- Returns:
- Win32 error code. NO_ERROR indicates that the call succeeded.
- --*/
- {
- OSVERSIONINFO osInfo;
-
- InitializeCriticalSection( &g_csOpenFiles);
-
- //
- // obtain the platform type to find out how to open the file
- //
-
- osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
- if ( GetVersionEx( &osInfo ) ) {
- g_fIsNt = (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
- }
-
- if ( !g_fIsNt) {
-
- //
- // Reset the flags appropriately so that Windows 95 will be happy
- //
-
- g_dwCreateFileShareMode = (FILE_SHARE_READ | FILE_SHARE_WRITE);
- g_dwCreateFileFlags = (FILE_FLAG_SEQUENTIAL_SCAN);
- }
-
- return (NO_ERROR);
-
- } // InitFileHandleCache()
-
-
-
-
- DWORD
- CleanupFileHandleCache(VOID)
- {
- LPOPEN_FILE pFileScan;
-
- while ( g_pOpenFiles != NULL) {
-
- pFileScan = g_pOpenFiles;
- g_pOpenFiles = g_pOpenFiles->pNext;
-
- if ( pFileScan->hFile != INVALID_HANDLE_VALUE) {
-
- CloseHandle( pFileScan->hFile);
- }
-
- LocalFree( pFileScan);
- }
-
- DeleteCriticalSection( &g_csOpenFiles);
-
- return (NO_ERROR);
- } // CleanupFileHandleCache()
-
-
-
-
- HANDLE
- FcOpenFile(IN EXTENSION_CONTROL_BLOCK * pecb, IN LPCSTR pszFile)
- /*++
-
- FcOpenFile()
-
- Description:
- This function opens the file specified in the 'pszFile'.
- If the file name starts with a '/' we use the ECB to map
- the given path into a physical file path.
-
- Arguments:
- pecb - pointer to the ECB block
- pszFile - pointer to file name
-
- Returns:
- valid File handle on success
- --*/
- {
- LPOPEN_FILE pFileScan;
- HANDLE hFile = INVALID_HANDLE_VALUE;
-
- EnterCriticalSection( &g_csOpenFiles);
-
- for ( pFileScan = g_pOpenFiles;
- NULL != pFileScan;
- pFileScan = pFileScan->pNext) {
-
- if ( 0 == lstrcmpi( pFileScan->rgchFile, pszFile)) {
-
- //
- // there is a file match.
- //
-
- break;
- }
-
- } // for
-
-
- if ( NULL == pFileScan) {
-
- //
- // File was not found. Create a new file handle
- //
-
- CHAR rgchFileName[ MAX_PATH]; // local copy
- LPCSTR pszInputPath = pszFile;
-
- lstrcpyn( rgchFileName, pszFile, MAX_PATH);
- if ( *pszFile == '/') {
-
- DWORD cbSize = sizeof(rgchFileName);
- BOOL fRet;
-
- // reset the file pointer, so subsequent use will fail
- pszFile = NULL;
-
- //
- // Using the ECB map the Virtual path to the Physical path
- //
-
- fRet = pecb->ServerSupportFunction( pecb->ConnID,
- HSE_REQ_MAP_URL_TO_PATH,
- rgchFileName,
- &cbSize, NULL);
-
- if (fRet) {
- // we got the mapping. Use it.
- pszFile = rgchFileName;
- }
- }
-
- if ( NULL != pszFile) {
- pFileScan = LocalAlloc( LPTR, sizeof( *pFileScan));
-
- if ( NULL != pFileScan) {
-
- SECURITY_ATTRIBUTES sa;
-
- sa.nLength = sizeof(sa);
- sa.lpSecurityDescriptor = NULL;
- sa.bInheritHandle = FALSE;
-
- pFileScan->hFile =
- CreateFile( pszFile,
- GENERIC_READ,
- g_dwCreateFileShareMode,
- &sa,
- OPEN_EXISTING,
- g_dwCreateFileFlags,
- NULL );
-
- if ( INVALID_HANDLE_VALUE == pFileScan->hFile) {
-
- LocalFree( pFileScan);
- pFileScan = NULL;
- } else {
-
- // insert this into the list at the top
- lstrcpyn( pFileScan->rgchFile, pszInputPath, MAX_PATH);
- pFileScan->pNext = g_pOpenFiles;
- g_pOpenFiles = pFileScan;
- pFileScan->nRefs = 1;
- pFileScan->nHits = 0;
- }
- }
- }
- }
-
- if ( NULL != pFileScan) {
-
- hFile = pFileScan->hFile;
- pFileScan->nHits++;
- pFileScan->nRefs++;
- }
-
- LeaveCriticalSection( &g_csOpenFiles);
-
- return (hFile);
-
- } // FcOpenFile()
-
-
-
- DWORD
- FcCloseFile(IN HANDLE hFile)
- {
- LPOPEN_FILE pFileScan;
- DWORD dwError = NO_ERROR;
-
- EnterCriticalSection( &g_csOpenFiles);
-
- //
- // Look for the handle and decrement the ref count.
- //
- for ( pFileScan = g_pOpenFiles;
- NULL != pFileScan;
- pFileScan = pFileScan->pNext) {
-
- if ( hFile == pFileScan->hFile) {
-
- //
- // there is a file match.
- //
-
- pFileScan->nRefs--;
-
- //
- // BUGBUG: There is no freeing of the file when Ref hits '0' :(
- //
-
- break;
- }
-
- } // for
-
-
- if ( NULL == pFileScan) {
- //
- // file handle not found
- //
- dwError = ( ERROR_INVALID_HANDLE);
- }
-
- LeaveCriticalSection( &g_csOpenFiles);
-
-
- return ( dwError);
-
- } // FcCloseFile()
-
-
-
-
- BOOL
- FcReadFromFile(
- IN HANDLE hFile,
- OUT CHAR * pchBuffer,
- IN DWORD dwBufferSize,
- OUT LPDWORD pcbRead,
- IN OUT LPOVERLAPPED pov
- )
- /*++
- Description:
- Reads contents of file [hFile] from the specified offset in the overlapped
- structure. The contents are read into the buffer supplied.
-
- Arguments:
- hFile - handle for the File from which to read data
- pchBuffer - pointer to the buffer into which the data is to be read
- dwBufferSize - DWORD containing the max size of the buffer supplied
- pcbRead - number of bytes read from the file
- pov - pointer to an overlapped structure that contains the
- offset from where to read the contents. The
- overlapped structure also is used for Overlapped
- IO in NT.
-
- Notes:
- This function automatically handles both Windows 95 and NT
-
-
- Returns:
- TRUE on success and FALSE if there is a failure.
- Use GetLastError() to get the last error code on failure.
- --*/
- {
- BOOL fRet = TRUE;
-
- *pcbRead = 0;
-
- if ( !g_fIsNt ) {
- //
- // Windows95 does not support Overlapped IO.
- // So we shall thunk it out and use Synchronous IO
- //
-
- fRet = (
- SetFilePointer( hFile,
- pov->Offset,
- NULL,
- FILE_BEGIN) &&
- ReadFile( hFile,
- pchBuffer,
- dwBufferSize,
- pcbRead,
- NULL
- )
- );
- } else {
-
- ResetEvent( pov->hEvent);
-
- fRet = TRUE;
-
- // read data from file
- if (!ReadFile(hFile,
- pchBuffer,
- dwBufferSize,
- pcbRead,
- pov
- )) {
-
- DWORD err = GetLastError();
-
- if ( (err != ERROR_IO_PENDING) ||
- !GetOverlappedResult( hFile, pov, pcbRead, TRUE) ) {
-
- fRet = FALSE;
- }
- }
- }
-
- if ( fRet ) {
- pov->Offset += *pcbRead;
- }
-
- return ( fRet );
- } // FcReadFromFile()
-
- /************************ End of File ***********************/
-