|
|
/*++
Copyright (c) 1998 Microsoft Corporation
Module Name:
utilities.h
Abstract:
SIS Groveler general utilities include file
Authors:
Cedric Krumbein, 1998
Environment:
User Mode
Revision History:
--*/
/************************ General-purpose definitions ************************/
typedef DWORDLONG Signature; typedef LONGLONG PerfTime;
#define Clear(OBJECT) \
memset(&(OBJECT), 0, sizeof(OBJECT))
#define IsSet(EVENT) \
((EVENT) != NULL && WaitForSingleObject(EVENT, 0) == WAIT_OBJECT_0)
#define IsReset(EVENT) \
((EVENT) != NULL && WaitForSingleObject(EVENT, 0) == WAIT_TIMEOUT)
#define ROTATE_LEFT(DATA, NUM_BITS) \
((DATA) << (NUM_BITS) | (DATA) >> (sizeof(DATA)*8 - (NUM_BITS)))
#define ROTATE_RIGHT(DATA, NUM_BITS) \
((DATA) >> (NUM_BITS) | (DATA) << (sizeof(DATA)*8 - (NUM_BITS)))
/************************ Utility function prototypes ************************/
#define PERF_TIME_TO_MSEC(VALUE) PerformanceTimeToMSec(VALUE)
#define PERF_TIME_TO_USEC(VALUE) PerformanceTimeToUSec(VALUE)
PerfTime GetPerformanceTime();
DWORD PerformanceTimeToMSec(PerfTime timeInterval);
LONGLONG PerformanceTimeToUSec(PerfTime timeInterval);
DWORDLONG GetTime();
TCHAR *PrintTime(TCHAR *string, DWORDLONG time);
DWORDLONG GetFileID(const TCHAR *fileName);
BOOL GetCSIndex(HANDLE fileHandle, CSID *csIndex);
//
// A class to handle arbitrary length pathnames, as returned by NtQueryInformationFile()
//
class TFileName {
public: ULONG nameLenMax; // maximum length of name
ULONG nameLen; // actual length of name (not including NULL terminator)
TCHAR *name; // file name (ptr to nameInfo->FileName)
FILE_NAME_INFORMATION *nameInfo; // required by NtQueryInformationFile
ULONG nameInfoSize; // sizeof nameInfo buffer
TFileName(void) : nameLenMax(0), nameLen(0), name(NULL), nameInfo(NULL), nameInfoSize(0) {}
~TFileName() { if (nameInfo) delete[] nameInfo; }
void resize(int size = 900) { if (nameInfo) delete[] nameInfo;
allocBuf(size); }
void append(const TCHAR *s, int c = -1) { int slen; int n;
if (0 == c || NULL == s) return;
slen = _tcslen(s);
if (-1 == c) n = slen; else n = min(slen, c);
// If the combined size of the two strings is larger than our buffer,
// realloc the buffer.
if (nameLen + n + 1 > nameLenMax) { FILE_NAME_INFORMATION *ni = nameInfo;
allocBuf(nameLen + n + 1 + 512);
if (ni) { _tcsncpy(name, ni->FileName, nameLen); delete[] ni; } }
_tcsncpy(&name[nameLen], s, n); nameLen += n; name[nameLen] = _T('\0'); }
void assign(const TCHAR *s, int c = -1) { if (nameLenMax > 0) { nameLen = 0; name[0] = _T('\0'); } append(s, c); }
private:
// Allocate a buffer for nameInfo of the specified size. Note that name will
// point into this buffer.
void allocBuf(int size) { ASSERT(size >= 0);
nameLenMax = size; nameLen = 0;
if (size > 0) { nameInfoSize = size * sizeof(TCHAR) + sizeof(ULONG);
nameInfo = (PFILE_NAME_INFORMATION) new BYTE[nameInfoSize + sizeof FILE_NAME_INFORMATION]; // conservative size
ASSERT(nameInfo); // new_handler should raise exception on out of memory
ASSERT((((ULONG_PTR) nameInfo) % sizeof(ULONG)) == 0); // make sure alignment is correct
name = (TCHAR *) nameInfo->FileName; name[0] = _T('\0');
ASSERT(((UINT_PTR) &nameInfo->FileName[size] - (UINT_PTR) nameInfo) == nameInfoSize); } else { nameInfo = NULL; name = NULL; nameInfoSize = 0; } } };
BOOL GetFileName( HANDLE fileHandle, TFileName *tFileName);
BOOL GetFileName( HANDLE volumeHandle, DWORDLONG fileID, TFileName *tFileName);
TCHAR *GetCSName(CSID *csIndex);
VOID FreeCSName(TCHAR *rpcStr);
Signature Checksum( const VOID *buffer, DWORD bufferLen, DWORDLONG offset, Signature firstWord);
/*********************** Hash table class declaration ************************/
#define TABLE_MIN_LOAD 4
#define TABLE_MAX_LOAD 5
#define TABLE_RANDOM_CONSTANT 314159269
#define TABLE_RANDOM_PRIME 1000000007
#define TABLE_DIR_SIZE 256
#define TABLE_SEGMENT_BITS 8
#define TABLE_SEGMENT_SIZE (1U << TABLE_SEGMENT_BITS)
#define TABLE_SEGMENT_MASK (TABLE_SEGMENT_SIZE - 1U)
class Table {
private:
struct TableEntry { TableEntry *prevEntry, *nextEntry, *prevChain, *nextChain;
DWORD hashValue, keyLen;
VOID *data; } *firstEntry, *lastEntry;
DWORD numBuckets, dirSize, expandIndex, level, numEntries;
struct TableSegment { TableEntry *slot[TABLE_SEGMENT_SIZE]; } **directory;
DWORD Hash(const VOID *key, DWORD keyLen) const;
DWORD BucketNum(DWORD hashValue) const;
VOID Expand();
VOID Contract();
public:
Table();
~Table();
BOOL Put( VOID *data, DWORD keyLen);
VOID *Get(const VOID *key, DWORD keyLen, BOOL erase = FALSE);
VOID *GetFirst(DWORD *keyLen = NULL, BOOL erase = TRUE);
DWORD Number() const; };
/************************** FIFO class declaration ***************************/
class FIFO {
private:
struct FIFOEntry { FIFOEntry *next; DWORD size; VOID *data; } *head, *tail;
DWORD numEntries;
public:
FIFO();
~FIFO();
VOID Put(VOID *data);
VOID *Get();
DWORD Number() const; };
/************************** LIFO class declaration ***************************/
class LIFO {
private:
struct LIFOEntry { LIFOEntry *next; DWORD size; VOID *data; } *top;
DWORD numEntries;
public:
LIFO();
~LIFO();
VOID Put(VOID *data);
VOID *Get();
DWORD Number() const; };
BOOL GetParentName(const TCHAR *fileName, TFileName *parentName);
|