Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

522 lines
12 KiB

/*++
Copyright (c) 1995 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
--*/
# ifndef _TSUNAMIP_HXX_
# define _TSUNAMIP_HXX_
/************************************************************
* Include Headers
************************************************************/
# include <tsunami.hxx>
extern "C" {
# include <string.h>
};
# include <tsmemp.hxx>
# include <dbgmacro.hxx>
# include <globals.hxx>
/************************************************************
* Type Definitions
************************************************************/
struct _CACHE_OBJECT;
//
// Memory allocation related structures
//
typedef struct {
//
// This the size of the memory allocated by the cache
//
ULONG cbSize;
BOOL IsCached;
struct _CACHE_OBJECT * pCache;
PUSER_FREE_ROUTINE pfnFreeRoutine;
} BLOB_HEADER, * PBLOB_HEADER;
#define BLOB_IS_OR_WAS_CACHED( pvBlob ) \
( (((PBLOB_HEADER)pvBlob)-1)->IsCached )
#define BLOB_IS_EJECTATE( pvBlob ) \
( IsListEmpty(&(((PBLOB_HEADER)pvBlob)-1)->pCache->BinList) )
#define BLOB_IS_OR_WAS_CACHED( pvBlob ) \
( (((PBLOB_HEADER)pvBlob)-1)->IsCached )
#define BLOB_IS_EJECTATE( pvBlob ) \
( IsListEmpty(&(((PBLOB_HEADER)pvBlob)-1)->pCache->BinList) )
#define BLOB_GET_SVC_ID( pvBlob ) \
( (((PBLOB_HEADER)pvBlob)-1)->pCache->dwService )
#define BLOB_IS_UNC( pvBlob ) \
( (((PBLOB_HEADER)pvBlob)-1)->pCache->wszPath[1] == L'\\' )
//
// Cache Related Private Structures
//
typedef DWORD HASH_TYPE;
typedef struct _CACHE_OBJECT {
DWORD Signature;
LIST_ENTRY BinList;
LIST_ENTRY MruList;
LIST_ENTRY DirChangeList;
PBLOB_HEADER pbhBlob;
ULONG references;
DWORD TTL;
HASH_TYPE hash;
ULONG cchLength;
ULONG iDemux;
DWORD dwService;
//
// This contains the size of the user allocated portion of this blob
//
ULONG UserValue;
WCHAR wszPath[ MAX_PATH + 1];
} CACHE_OBJECT, *PCACHE_OBJECT;
//
// HASH_TO_BIN can return a range of 0 to HASH_VALUE (inclusive)
//
#define HASH_VALUE 113
#define HASH_TO_BIN( hash ) ( ((hash)%(HASH_VALUE)))
#define MAX_BINS (HASH_VALUE+1)
#define CACHE_OBJ_SIGNATURE 0x48434143 // 'CACH'
#define RESERVED_DEMUX_START 0x80000000
#define RESERVED_DEMUX_DIRECTORY_LISTING ( RESERVED_DEMUX_START + 1 )
#define RESERVED_DEMUX_ATOMIC_DIRECTORY_GUARD ( RESERVED_DEMUX_START + 2 )
#define RESERVED_DEMUX_OPEN_FILE ( RESERVED_DEMUX_START + 3 )
//
// 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
typedef struct {
CRITICAL_SECTION CriticalSection;
LIST_ENTRY Items[ MAX_BINS ];
LIST_ENTRY MruList;
ULONG MemoryInUse;
} CACHE_TABLE, *PCACHE_TABLE;
extern CACHE_TABLE CacheTable;
extern DWORD cCachedUNCHandles;
//
// Disables Tsunami Caching
//
extern BOOL DisableTsunamiCaching;
//
// Allows us to mask the invalid flags
//
extern DWORD TsValidCreateFileOptions;
//
// function prototypes
//
BOOL
Cache_Initialize(
IN DWORD CacheSize
);
HASH_TYPE
CalculateHashAndLengthOfPathName(
PCWSTR pwszPathName,
PULONG pcbLength
);
BOOL
DeCache(
PCACHE_OBJECT pCacheObject,
BOOL fLockCacheTable = TRUE
);
VOID
TsDereferenceCacheObj(
PCACHE_OBJECT pCacheObject
);
//
// This function converts a service ID into an index for statistics
// gathering
//
inline
DWORD
MaskIndex( DWORD dwService )
{
if ( dwService <= LAST_PERF_CTR_SVC )
return dwService - 1;
else
return CACHE_STATS_UNUSED_INDEX;
}
#define INC_COUNTER( dwServiceId, CounterName ) \
InterlockedIncrement( (LONG *)&Configuration.Stats[MaskIndex(dwServiceId)].CounterName )
#define DEC_COUNTER( dwServiceId, CounterName ) \
InterlockedDecrement( (LONG *)&Configuration.Stats[MaskIndex(dwServiceId)].CounterName )
//
// Open File Handles related functions
//
BOOL DisposeOpenFileInfo( PVOID pvOldBlock );
//
// Virtual roots related data and structures.
//
extern LIST_ENTRY listVirtualRoots;
extern CRITICAL_SECTION csVirtualRoots;
extern HANDLE heventNewItem;
typedef struct {
DWORD Signature;
LIST_ENTRY list;
BOOLEAN fDeleted; // Waiting for the APC to
// complete before freeing
LONG cRef;
BOOLEAN bCachingAllowed;
DWORD dwID; // Unique owner ID
DWORD dwError;
DWORD dwFileSystem;
DWORD dwAccessMask;
DWORD cchRoot;
WCHAR pszRoot[ MAX_LENGTH_VIRTUAL_ROOT + 1 ];
DWORD cchRootA;
CHAR pszRootA[ MAX_LENGTH_VIRTUAL_ROOT + 1 ];
CHAR pszAddressA[ MAX_LENGTH_ROOT_ADDR + 1 ];
WCHAR pszAddress[ MAX_LENGTH_ROOT_ADDR + 1 ];
DWORD cchDirectory;
WCHAR pszDirectory[ MAX_PATH + 1 ];
BYTE cchDirectoryA;
CHAR pszDirectoryA[ MAX_PATH + 1 ];
WCHAR pszAccountName[ UNLEN + 1 ];
HANDLE hImpersonationToken;
} VIRTUAL_ROOT_MAPPING, *PVIRTUAL_ROOT_MAPPING;
#define VIRT_ROOT_SIGNATURE 0x544F4F52 // 'ROOT'
VOID
DereferenceRootMapping(IN OUT VIRTUAL_ROOT_MAPPING * pVrm);
//
// Directory Change Manager Functions
//
extern HANDLE g_hChangeWaitThread;
DWORD
WINAPI
ChangeWaitThread(
PVOID pvParam
);
typedef struct {
HANDLE hDirectoryFile;
BOOL fOnSystemNotifyList;
// Handle been added to Notify Change Dir?
LIST_ENTRY listCacheObjects;
HANDLE hEventCompletion; // Completion event handle
OVERLAPPED Overlapped;
FILE_NOTIFY_INFORMATION NotifyInfo;
WCHAR szPathNameBuffer[ MAX_PATH + 32 ];
} DIRECTORY_CACHING_INFO, *PDIRECTORY_CACHING_INFO;
typedef struct {
PLIST_ENTRY plistVirtualRoots;
HANDLE heventStopWaiting;
HANDLE heventNewItem;
} WAIT_THREAD_ARGS, *PWAIT_THREAD_ARGS;
BOOL
DirectoryChangeManager_Initialize(
HANDLE heventQuitEvent,
HANDLE heventNewItem
);
BOOL
DirectoryChangeManager_NewItem(
PCACHE_OBJECT pCacheObject
);
VOID
DirectoryChangeManager_RemoveItem(
PCACHE_OBJECT pCacheObject
);
BOOL
DirectoryChangeManager_AddRoot(
PVIRTUAL_ROOT_MAPPING pVrm
);
BOOL
ScheduleDecache(
DIRECTORY_CACHING_INFO * pDci
);
//
// 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:
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;
#ifdef UNICODE
# define TsGetDirectoryInfo TsGetDirectoryInfoW
#else /* UNICODE */
# define TsGetDirectoryInfo TsGetDirectoryInfoA
#endif /* UNICODE */
#define ATX_PRINTF( x ) { char buff[256]; wsprintf x; OutputDebugString( buff ); }
extern
dllexp
BOOL
TsGetDirectoryListingA
(
IN const TSVC_CACHE &TSvcCache,
IN PCSTR pszDirectoryName,
IN HANDLE ListingUser,
OUT PTS_DIRECTORY_HEADER* ppDirectoryHeader
);
extern
dllexp
BOOL
TsGetDirectoryListingW
(
IN const TSVC_CACHE &TSvcCache,
IN PCWSTR pwszDirectoryName,
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);
//
// Little helper function for taking a cache object off the relevant lists
// The return code indicates if the cache object was on any lists indicating
// it hadn't been decached yet.
//
inline
BOOL
RemoveCacheObjFromLists(
PCACHE_OBJECT pCacheObject,
BOOL fLockCacheTable
)
{
BOOL fOnLists = TRUE;
if ( fLockCacheTable )
EnterCriticalSection( &CacheTable.CriticalSection );
//
// Remove the cache object from the cache table list, if it hasn't
// already been so removed.
//
if ( !IsListEmpty( &pCacheObject->BinList ) )
{
RemoveEntryList( &pCacheObject->BinList );
InitializeListHead( &pCacheObject->BinList );
RemoveEntryList( &pCacheObject->MruList );
DirectoryChangeManager_RemoveItem( pCacheObject );
}
else
{
fOnLists = FALSE;
}
if ( fLockCacheTable )
LeaveCriticalSection( &CacheTable.CriticalSection );
return fOnLists;
}
#pragma hdrstop
# endif // _TSUNAMIP_HXX_
/************************ End of File ***********************/