home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 February / CHIP_2_98.iso / software / pelne / optionp / iis4_07.cab / openf.c2 < prev    next >
Text File  |  1997-10-25  |  10KB  |  405 lines

  1. /*++
  2.  
  3.    Copyright    (c)    1995-1997    Microsoft Corporation
  4.  
  5.    Module  Name :
  6.  
  7.       openf.c
  8.  
  9.    Abstract:
  10.  
  11.       This module implements a simple open file handle cache
  12.  
  13.    Project:
  14.  
  15.        ISAPI Extensions Sample DLL
  16.  
  17.    Functions Exported:
  18.  
  19.  
  20.    Note:
  21.       THIS IS NOT ROBUST for REAL WORLD.
  22.       I wrote this for testing the ISAPI Async IO processing.
  23.  
  24. --*/
  25.  
  26.  
  27. /************************************************************
  28.  *     Include Headers
  29.  ************************************************************/
  30.  
  31. # include "openf.h"
  32.  
  33.  
  34. /************************************************************
  35.  *     Type definitions and Globals
  36.  ************************************************************/
  37.  
  38. //
  39. // internal data structure for maintaining the list of open file handles.
  40. //
  41.  
  42. typedef struct _OPEN_FILE {
  43.     
  44.     HANDLE  hFile;
  45.     struct _OPEN_FILE * pNext;
  46.     LONG    nHits;
  47.     LONG    nRefs;
  48.     CHAR    rgchFile[MAX_PATH+1];
  49.  
  50. } OPEN_FILE, * LPOPEN_FILE;
  51.  
  52.  
  53. LPOPEN_FILE g_pOpenFiles = NULL;
  54. CRITICAL_SECTION g_csOpenFiles;
  55. BOOL g_fIsNt = TRUE;
  56.  
  57. //
  58. // Set up global variables containing the flags for CreateFile
  59. //  The flags can be masked for Windows 95 system
  60. //
  61.  
  62. DWORD  g_dwCreateFileShareMode = 
  63.          (FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE);
  64.  
  65. DWORD  g_dwCreateFileFlags = 
  66.          (FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_OVERLAPPED);
  67.  
  68. /************************************************************
  69.  *    Functions 
  70.  ************************************************************/
  71.  
  72.  
  73. DWORD
  74. InitFileHandleCache(VOID)
  75. /*++
  76.  
  77.   This function initializes the file handle cache.
  78.   It should be called at the initialization time.
  79.  
  80.   Arguments:
  81.     None
  82.   
  83.   Returns:
  84.     Win32 error code. NO_ERROR indicates that the call succeeded.
  85. --*/
  86. {
  87.     OSVERSIONINFO  osInfo;
  88.     
  89.     InitializeCriticalSection( &g_csOpenFiles);
  90.  
  91.     //
  92.     // obtain the platform type to find out how to open the file
  93.     //
  94.  
  95.     osInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  96.  
  97.     if ( GetVersionEx( &osInfo ) ) {
  98.         g_fIsNt = (osInfo.dwPlatformId == VER_PLATFORM_WIN32_NT);
  99.     }
  100.  
  101.     if ( !g_fIsNt) {
  102.  
  103.         //
  104.         // Reset the flags appropriately so that Windows 95 will be happy
  105.         //
  106.  
  107.         g_dwCreateFileShareMode = (FILE_SHARE_READ | FILE_SHARE_WRITE);
  108.         g_dwCreateFileFlags     = (FILE_FLAG_SEQUENTIAL_SCAN);
  109.     }
  110.  
  111.     return (NO_ERROR);
  112.  
  113. } // InitFileHandleCache()
  114.  
  115.  
  116.  
  117.  
  118. DWORD
  119. CleanupFileHandleCache(VOID)
  120. {
  121.     LPOPEN_FILE  pFileScan;
  122.  
  123.     while ( g_pOpenFiles != NULL) {
  124.  
  125.         pFileScan = g_pOpenFiles;
  126.         g_pOpenFiles = g_pOpenFiles->pNext;
  127.  
  128.         if ( pFileScan->hFile != INVALID_HANDLE_VALUE) {
  129.  
  130.             CloseHandle( pFileScan->hFile);
  131.         }
  132.  
  133.         LocalFree( pFileScan);
  134.     }
  135.  
  136.     DeleteCriticalSection( &g_csOpenFiles);
  137.  
  138.     return (NO_ERROR);
  139. } // CleanupFileHandleCache()
  140.  
  141.  
  142.  
  143.  
  144. HANDLE
  145. FcOpenFile(IN EXTENSION_CONTROL_BLOCK * pecb, IN LPCSTR pszFile)
  146. /*++
  147.  
  148.  FcOpenFile()
  149.  
  150.  Description:
  151.    This function opens the file specified in the 'pszFile'. 
  152.    If the file name starts with a '/' we use the ECB to map 
  153.    the given path into a physical file path.
  154.  
  155.  Arguments:
  156.   pecb - pointer to the ECB block
  157.   pszFile - pointer to file name
  158.  
  159.  Returns:
  160.    valid File handle on success
  161. --*/
  162. {
  163.     LPOPEN_FILE  pFileScan;
  164.     HANDLE hFile = INVALID_HANDLE_VALUE;
  165.  
  166.     EnterCriticalSection( &g_csOpenFiles);
  167.  
  168.     for ( pFileScan =  g_pOpenFiles; 
  169.          NULL != pFileScan; 
  170.          pFileScan = pFileScan->pNext) {
  171.  
  172.         if ( 0 == lstrcmpi( pFileScan->rgchFile, pszFile)) {
  173.  
  174.             //
  175.             //  there is a file match. 
  176.             //
  177.  
  178.             break;
  179.         }
  180.  
  181.     } // for
  182.  
  183.  
  184.     if ( NULL == pFileScan) {
  185.  
  186.         //
  187.         // File was not found. Create a new file handle
  188.         //
  189.  
  190.         CHAR   rgchFileName[ MAX_PATH]; // local copy
  191.         LPCSTR pszInputPath = pszFile;
  192.         
  193.         lstrcpyn( rgchFileName, pszFile, MAX_PATH);
  194.         if ( *pszFile == '/') { 
  195.  
  196.             DWORD cbSize = sizeof(rgchFileName);
  197.             BOOL  fRet;
  198.  
  199.             // reset the file pointer, so subsequent use will fail
  200.             pszFile = NULL;
  201.  
  202.             //
  203.             // Using the ECB map the Virtual path to the Physical path
  204.             //
  205.  
  206.             fRet = pecb->ServerSupportFunction( pecb->ConnID,
  207.                                                 HSE_REQ_MAP_URL_TO_PATH,
  208.                                                 rgchFileName,
  209.                                                 &cbSize, NULL);
  210.             
  211.             if (fRet) {
  212.                 // we got the mapping. Use it.
  213.                 pszFile = rgchFileName;
  214.             }
  215.         }   
  216.  
  217.         if ( NULL != pszFile) {
  218.             pFileScan = LocalAlloc( LPTR, sizeof( *pFileScan));
  219.  
  220.             if ( NULL != pFileScan) {
  221.                 
  222.                 SECURITY_ATTRIBUTES sa;
  223.                 
  224.                 sa.nLength              = sizeof(sa);
  225.                 sa.lpSecurityDescriptor = NULL;
  226.                 sa.bInheritHandle       = FALSE;
  227.                 
  228.                 pFileScan->hFile = 
  229.                     CreateFile( pszFile,
  230.                                 GENERIC_READ,
  231.                                 g_dwCreateFileShareMode,
  232.                                 &sa,
  233.                                 OPEN_EXISTING,
  234.                                 g_dwCreateFileFlags,
  235.                                 NULL );
  236.                 
  237.                 if ( INVALID_HANDLE_VALUE == pFileScan->hFile) {
  238.                     
  239.                     LocalFree( pFileScan);
  240.                     pFileScan = NULL;
  241.                 } else {
  242.                     
  243.                     // insert this into the list at the top
  244.                     lstrcpyn( pFileScan->rgchFile, pszInputPath, MAX_PATH);
  245.                     pFileScan->pNext = g_pOpenFiles;
  246.                     g_pOpenFiles = pFileScan;
  247.                     pFileScan->nRefs = 1;
  248.                     pFileScan->nHits = 0;
  249.                 }
  250.             }
  251.         }
  252.     }
  253.  
  254.     if ( NULL != pFileScan) {
  255.  
  256.         hFile = pFileScan->hFile;
  257.         pFileScan->nHits++;
  258.         pFileScan->nRefs++;
  259.     }
  260.  
  261.     LeaveCriticalSection( &g_csOpenFiles);
  262.  
  263.     return (hFile);
  264.  
  265. } // FcOpenFile()
  266.  
  267.  
  268.  
  269. DWORD
  270. FcCloseFile(IN HANDLE hFile)
  271. {
  272.     LPOPEN_FILE  pFileScan;
  273.     DWORD dwError = NO_ERROR;
  274.  
  275.     EnterCriticalSection( &g_csOpenFiles);
  276.  
  277.     //
  278.     // Look for the handle and decrement the ref count.
  279.     // 
  280.     for ( pFileScan =  g_pOpenFiles; 
  281.          NULL != pFileScan; 
  282.          pFileScan = pFileScan->pNext) {
  283.  
  284.         if ( hFile == pFileScan->hFile) {
  285.  
  286.             //
  287.             //  there is a file match. 
  288.             //
  289.  
  290.             pFileScan->nRefs--;
  291.  
  292.             //
  293.             // BUGBUG: There is no freeing of the file when Ref hits '0' :(
  294.             //
  295.  
  296.             break;
  297.         }
  298.  
  299.     } // for
  300.  
  301.  
  302.     if ( NULL == pFileScan) {
  303.         //
  304.         // file handle not found
  305.         //
  306.         dwError = ( ERROR_INVALID_HANDLE);
  307.     }
  308.  
  309.     LeaveCriticalSection( &g_csOpenFiles);
  310.  
  311.  
  312.     return ( dwError);
  313.  
  314. } // FcCloseFile()
  315.  
  316.  
  317.  
  318.  
  319. BOOL
  320. FcReadFromFile(
  321.                IN  HANDLE hFile,
  322.                OUT CHAR * pchBuffer,
  323.                IN  DWORD  dwBufferSize,
  324.                OUT LPDWORD  pcbRead,
  325.                IN OUT LPOVERLAPPED  pov
  326.                )
  327. /*++
  328.   Description:
  329.     Reads contents of file [hFile] from the specified offset in the overlapped 
  330.     structure. The contents are read into the buffer supplied.
  331.  
  332.   Arguments:
  333.     hFile        - handle for the File from which to read data
  334.     pchBuffer    - pointer to the buffer into which the data is to be read
  335.     dwBufferSize - DWORD containing the max size of the buffer supplied
  336.     pcbRead      - number of bytes read from the file
  337.     pov          - pointer to an overlapped structure that contains the 
  338.                      offset from where to read the contents. The
  339.                      overlapped structure also is used for Overlapped
  340.                      IO in NT.
  341.  
  342.   Notes:
  343.    This function automatically handles both Windows 95 and NT
  344.    
  345.  
  346.   Returns:
  347.     TRUE on success and FALSE if there is a failure.
  348.     Use GetLastError() to get the last error code on failure.
  349. --*/
  350. {
  351.     BOOL fRet = TRUE;
  352.  
  353.     *pcbRead = 0;
  354.     
  355.     if ( !g_fIsNt ) {
  356.         //
  357.         // Windows95 does not support Overlapped IO.
  358.         //  So we shall thunk it out and use Synchronous IO
  359.         //
  360.         
  361.         fRet = ( 
  362.                 SetFilePointer( hFile, 
  363.                                 pov->Offset,
  364.                                 NULL,
  365.                                 FILE_BEGIN) &&
  366.                 ReadFile( hFile,
  367.                           pchBuffer,
  368.                           dwBufferSize,
  369.                           pcbRead,
  370.                           NULL
  371.                           )
  372.                 );
  373.     } else {
  374.         
  375.         ResetEvent( pov->hEvent);
  376.  
  377.         fRet = TRUE;
  378.  
  379.         // read data from file
  380.         if (!ReadFile(hFile,
  381.                       pchBuffer,
  382.                       dwBufferSize,
  383.                       pcbRead,
  384.                       pov
  385.                       )) {
  386.             
  387.             DWORD err = GetLastError();
  388.  
  389.             if ( (err != ERROR_IO_PENDING) || 
  390.                  !GetOverlappedResult( hFile, pov, pcbRead, TRUE) ) {
  391.                 
  392.                 fRet = FALSE;
  393.             }
  394.         }
  395.     }
  396.  
  397.     if ( fRet ) {
  398.         pov->Offset += *pcbRead;
  399.     }
  400.  
  401.     return ( fRet );
  402. } // FcReadFromFile()
  403.  
  404. /************************ End of File ***********************/
  405.