487 lines
9.7 KiB
C++
487 lines
9.7 KiB
C++
/*++
|
|
|
|
Copyright (c) 1998 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
tsunamip.hxx
|
|
|
|
Abstract:
|
|
|
|
This module defines private structures and functions for
|
|
tsunami module
|
|
|
|
Author:
|
|
|
|
Murali R. Krishnan ( MuraliK ) 13-Jan-1995
|
|
|
|
Project:
|
|
|
|
Tsuanmi Library ( caching and logging module for InternetServices)
|
|
|
|
Revision History:
|
|
|
|
MuraliK 20-Feb-1995 Added File System Types.
|
|
MuraliK 22-Jan-1996 Cache UNC Impersonation Token
|
|
MCourage 11-Dec-1997 Moved to cache2 for cache rewrite
|
|
|
|
--*/
|
|
|
|
#ifndef _TSUNAMIP_HXX_
|
|
#define _TSUNAMIP_HXX_
|
|
|
|
/************************************************************
|
|
* Include Headers
|
|
************************************************************/
|
|
|
|
|
|
# if defined ( __cplusplus)
|
|
extern "C" {
|
|
# endif
|
|
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <windows.h>
|
|
#include <basetyps.h>
|
|
#include <lmcons.h>
|
|
|
|
# if defined ( __cplusplus)
|
|
}
|
|
# endif
|
|
|
|
#include <iis64.h>
|
|
#include <inetinfo.h>
|
|
#include "iperfctr.hxx"
|
|
#include <refb.hxx>
|
|
#include "dbgutil.h"
|
|
#include <iistypes.hxx>
|
|
#include <tsvroot.hxx>
|
|
#include <tsunami.hxx>
|
|
#include <reftrace.h>
|
|
#include "tsmemp.hxx"
|
|
#include "globals.hxx"
|
|
#include "dbgmacro.hxx"
|
|
|
|
|
|
#define ENABLE_DIR_MONITOR 1
|
|
|
|
#include <dirmon.h>
|
|
|
|
|
|
//
|
|
// Setting TSUNAMI_REF_DEBUG to a non-zero value will enable reference
|
|
// count logging.
|
|
//
|
|
|
|
#if DBG
|
|
#define TSUNAMI_REF_DEBUG 1
|
|
#else // !DBG
|
|
#define TSUNAMI_REF_DEBUG 0
|
|
#endif // DBG
|
|
|
|
//
|
|
// Tracing support.
|
|
//
|
|
|
|
#if TSUNAMI_REF_DEBUG
|
|
|
|
extern PTRACE_LOG RefTraceLog;
|
|
|
|
#define TSUNAMI_TRACE( refcount, context ) \
|
|
if( RefTraceLog != NULL ) { \
|
|
WriteRefTraceLog( \
|
|
RefTraceLog, \
|
|
(refcount), \
|
|
(context) \
|
|
); \
|
|
} else
|
|
|
|
#else // !TSUNAMI_REF_DEBUG
|
|
#define TSUNAMI_TRACE( refcount, context )
|
|
#endif // TSUNAMI_REF_DEBUG
|
|
|
|
|
|
/************************************************************
|
|
* Type Definitions
|
|
************************************************************/
|
|
|
|
struct _CACHE_OBJECT;
|
|
class CBlobKey;
|
|
class CVRootDirMonitorEntry;
|
|
class CFileHashTable;
|
|
class CFileCacheStats;
|
|
class CBlobCacheStats;
|
|
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
extern DWORD TsCreateFileShareMode;
|
|
extern DWORD TsValidCreateFileOptions;
|
|
extern DWORD TsCreateFileFlags;
|
|
extern CFileHashTable * g_pFileInfoTable;
|
|
extern CFileCacheStats * g_pFileCacheStats;
|
|
extern CBlobCacheStats * g_pURICacheStats;
|
|
extern CBlobCacheStats * g_pBlobCacheStats;
|
|
extern CRITICAL_SECTION g_csUriInfo;
|
|
|
|
|
|
//
|
|
// ETag allocation related structures
|
|
//
|
|
|
|
// 3.0 seconds
|
|
#define STRONG_ETAG_DELTA 30000000
|
|
|
|
INT
|
|
FormatETag(
|
|
PCHAR pszBuffer,
|
|
const FILETIME& rft,
|
|
DWORD mdchange);
|
|
|
|
#define FORMAT_ETAG(buffer, time, mdchange) \
|
|
FormatETag(buffer, time, mdchange)
|
|
|
|
|
|
|
|
//
|
|
// bogus win95 handle
|
|
//
|
|
|
|
#define BOGUS_WIN95_DIR_HANDLE ((HANDLE)0x88888888)
|
|
|
|
//
|
|
// This is the maximum number of UNC file handles to cache. The SMB
|
|
// protocol limits the server to 2048 open files per client. Currently,
|
|
// this count includes *all* UNC connections regardles of the remote
|
|
// server
|
|
//
|
|
|
|
#define MAX_CACHED_UNC_HANDLES 1200
|
|
|
|
|
|
extern DWORD cCachedUNCHandles;
|
|
|
|
extern LARGE_INTEGER g_liFileCacheByteThreshold;
|
|
extern DWORDLONG g_dwMemCacheSize;
|
|
extern BOOL g_bEnableSequentialRead;
|
|
|
|
//
|
|
// Disables Tsunami Caching
|
|
//
|
|
|
|
extern BOOL DisableTsunamiCaching;
|
|
|
|
//
|
|
// Disables SPUD
|
|
//
|
|
|
|
extern BOOL DisableSPUD;
|
|
|
|
//
|
|
// Allows us to mask the invalid flags
|
|
//
|
|
|
|
extern DWORD TsValidCreateFileOptions;
|
|
|
|
//
|
|
// flags for create file
|
|
//
|
|
|
|
extern BOOL TsNoDirOpenSupport;
|
|
extern DWORD TsCreateFileFlags;
|
|
extern DWORD TsCreateFileShareMode;
|
|
|
|
//
|
|
// function prototypes
|
|
//
|
|
|
|
BOOL
|
|
Cache_Initialize(
|
|
IN DWORD MaxOpenFile
|
|
);
|
|
|
|
BOOL
|
|
MetaCache_Initialize(
|
|
VOID
|
|
);
|
|
|
|
BOOL
|
|
MetaCache_Terminate(
|
|
VOID
|
|
);
|
|
|
|
|
|
//
|
|
// This function converts a service ID into an index for statistics
|
|
// gathering
|
|
//
|
|
|
|
inline
|
|
DWORD
|
|
MaskIndex( DWORD dwService )
|
|
{
|
|
if ( dwService > 0 && dwService <= LAST_PERF_CTR_SVC )
|
|
return dwService - 1;
|
|
else
|
|
return CACHE_STATS_UNUSED_INDEX;
|
|
}
|
|
|
|
#define INC_COUNTER( dwServiceId, CounterName ) \
|
|
IP_INCREMENT_COUNTER( Configuration.Stats[MaskIndex(dwServiceId)].CounterName )
|
|
|
|
#define DEC_COUNTER( dwServiceId, CounterName ) \
|
|
IP_DECREMENT_COUNTER( Configuration.Stats[MaskIndex(dwServiceId)].CounterName )
|
|
|
|
#define SET_COUNTER( dwServiceId, CounterName, Val ) \
|
|
IP_SET_COUNTER( Configuration.Stats[MaskIndex(dwServiceId)].CounterName, Val )
|
|
|
|
//
|
|
// Virtual roots related data and structures.
|
|
//
|
|
|
|
extern LIST_ENTRY GlobalVRootList;
|
|
extern HANDLE g_hNewItem;
|
|
extern HANDLE g_hQuit;
|
|
|
|
|
|
typedef struct {
|
|
|
|
DWORD Signature;
|
|
|
|
BOOLEAN fUNC;
|
|
|
|
DWORD dwServiceID;
|
|
DWORD dwInstanceID;
|
|
|
|
DWORD dwFileSystem;
|
|
DWORD dwAccessMask;
|
|
HANDLE hImpersonationToken;
|
|
|
|
DWORD cchRootA;
|
|
DWORD cchDirectoryA;
|
|
|
|
CHAR pszRootA[ MAX_LENGTH_VIRTUAL_ROOT + 1 ];
|
|
CHAR pszDirectoryA[ MAX_PATH + 1 ];
|
|
CHAR pszAccountName[ UNLEN + 1 ];
|
|
|
|
CVRootDirMonitorEntry * pDME;
|
|
|
|
} VIRTUAL_ROOT_MAPPING, *PVIRTUAL_ROOT_MAPPING;
|
|
|
|
#define VIRT_ROOT_SIGNATURE 0x544F4F52 // 'ROOT'
|
|
|
|
//
|
|
// Number of times to try and get dir change notification
|
|
//
|
|
#define MAX_NOTIFICATION_FAILURES 3
|
|
|
|
#if ENABLE_DIR_MONITOR
|
|
class CVRootDirMonitorEntry : public CDirMonitorEntry
|
|
{
|
|
private:
|
|
DWORD m_cNotificationFailures;
|
|
|
|
// BOOL IORelease(VOID);
|
|
BOOL ActOnNotification(DWORD dwStatus, DWORD dwBytesWritten);
|
|
void FileChanged(const char *pszFileName, BOOL bDoFlush);
|
|
|
|
public:
|
|
CVRootDirMonitorEntry();
|
|
~CVRootDirMonitorEntry();
|
|
// BOOL Release(VOID);
|
|
BOOL Init();
|
|
};
|
|
#endif // ENABLE_DIR_MONITOR
|
|
|
|
//
|
|
// Directory Change Manager Functions
|
|
//
|
|
|
|
BOOL
|
|
DcmInitialize(
|
|
VOID
|
|
);
|
|
|
|
VOID
|
|
DcmTerminate(
|
|
VOID
|
|
);
|
|
|
|
BOOL
|
|
DcmAddRoot(
|
|
PVIRTUAL_ROOT_MAPPING pVrm
|
|
);
|
|
|
|
VOID
|
|
DcmRemoveRoot(
|
|
PVIRTUAL_ROOT_MAPPING pVrm
|
|
);
|
|
|
|
|
|
//
|
|
// Directory Listing related objects and functions
|
|
//
|
|
|
|
# define MAX_DIR_ENTRIES_PER_BLOCK (25)
|
|
|
|
typedef struct _TS_DIR_BUFFERS {
|
|
|
|
LIST_ENTRY listEntry;
|
|
int nEntries;
|
|
WIN32_FIND_DATA rgFindData[MAX_DIR_ENTRIES_PER_BLOCK];
|
|
|
|
} TS_DIR_BUFFERS, * PTS_DIR_BUFFERS;
|
|
|
|
|
|
|
|
class TS_DIRECTORY_HEADER
|
|
: public BLOB_HEADER
|
|
{
|
|
|
|
public:
|
|
TS_DIRECTORY_HEADER( VOID)
|
|
: m_hListingUser ( INVALID_HANDLE_VALUE),
|
|
m_nEntries ( 0),
|
|
m_ppFileInfo ( NULL)
|
|
{ InitializeListHead( & m_listDirectoryBuffers); }
|
|
|
|
~TS_DIRECTORY_HEADER( VOID) {}
|
|
|
|
BOOL
|
|
IsValid( VOID) const
|
|
{ return ( TRUE); }
|
|
|
|
int
|
|
QueryNumEntries( VOID) const
|
|
{ return ( m_nEntries); }
|
|
|
|
HANDLE
|
|
QueryListingUser( VOID) const
|
|
{ return ( m_hListingUser); }
|
|
|
|
|
|
const PWIN32_FIND_DATA *
|
|
QueryArrayOfFileInfoPointers(VOID) const
|
|
{ return ( m_ppFileInfo); }
|
|
|
|
PLIST_ENTRY
|
|
QueryDirBuffersListEntry( VOID)
|
|
{ return ( & m_listDirectoryBuffers); }
|
|
|
|
VOID
|
|
ReInitialize( VOID)
|
|
{
|
|
//
|
|
// this function provided to initialize, when we allocate using
|
|
// malloc or GlobalAlloc()
|
|
m_hListingUser = INVALID_HANDLE_VALUE;
|
|
m_nEntries = 0;
|
|
m_ppFileInfo = NULL;
|
|
InitializeListHead( &m_listDirectoryBuffers);
|
|
}
|
|
|
|
VOID
|
|
SetListingUser( IN HANDLE hListingUser)
|
|
{ m_hListingUser = hListingUser; }
|
|
|
|
VOID
|
|
IncrementDirEntries( VOID)
|
|
{ m_nEntries++; }
|
|
|
|
VOID
|
|
InsertBufferInTail( IN PLIST_ENTRY pEntry)
|
|
{ InsertTailList( &m_listDirectoryBuffers, pEntry); }
|
|
|
|
VOID
|
|
CleanupThis( VOID);
|
|
|
|
BOOL
|
|
ReadWin32DirListing(IN LPCSTR pszDirectoryName,
|
|
IN OUT DWORD * pcbMemUsed );
|
|
|
|
|
|
BOOL
|
|
BuildFileInfoPointers( IN OUT DWORD * pcbMemUsed );
|
|
|
|
# if DBG
|
|
|
|
VOID Print( VOID) const;
|
|
#else
|
|
|
|
VOID Print( VOID) const
|
|
{ ; }
|
|
|
|
# endif // DBG
|
|
|
|
private:
|
|
HANDLE m_hListingUser;
|
|
int m_nEntries;
|
|
|
|
// contains array of pointers indirected into buffers in m_listDirBuffers
|
|
PWIN32_FIND_DATA * m_ppFileInfo;
|
|
|
|
LIST_ENTRY m_listDirectoryBuffers; // ptr to DIR_BUFFERS
|
|
|
|
}; // class TS_DIRECTORY_HEADER
|
|
|
|
|
|
typedef TS_DIRECTORY_HEADER * PTS_DIRECTORY_HEADER;
|
|
|
|
//
|
|
// Virtual roots and directories always have their trailing slashes
|
|
// stripped. This macro is used disambiguate the "/root1/" from "/root/"
|
|
// case where "/root/" is an existing root (i.e., matching prefix).
|
|
//
|
|
|
|
extern BOOL
|
|
IsCharTermA(
|
|
IN LPCSTR lpszString,
|
|
IN INT cch
|
|
);
|
|
|
|
#define IS_CHAR_TERM_A( psz, cch ) IsCharTermA(psz,cch)
|
|
|
|
extern
|
|
dllexp
|
|
BOOL
|
|
TsGetDirectoryListing(
|
|
IN const TSVC_CACHE &TSvcCache,
|
|
IN PCSTR pszDirectoryName,
|
|
IN HANDLE ListingUser,
|
|
OUT PTS_DIRECTORY_HEADER* ppDirectoryHeader
|
|
);
|
|
|
|
extern
|
|
dllexp
|
|
BOOL
|
|
TsFreeDirectoryListing
|
|
(
|
|
IN const TSVC_CACHE & TSvcCache,
|
|
IN OUT PTS_DIRECTORY_HEADER pTsDirectoryHeader
|
|
);
|
|
|
|
extern
|
|
BOOL
|
|
SortInPlaceFileInfoPointers(
|
|
IN OUT PWIN32_FIND_DATA * prgFileInfo,
|
|
IN int nFiles,
|
|
IN PFN_CMP_WIN32_FIND_DATA pfnCompare
|
|
);
|
|
|
|
|
|
|
|
extern
|
|
BOOL
|
|
RegExpressionMatch( IN LPCSTR pszName, IN LPCSTR pszRegExp);
|
|
|
|
|
|
#pragma hdrstop
|
|
|
|
#endif // _TSUNAMIP_HXX_
|
|
|
|
|
|
|