Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

309 lines
6.2 KiB

/*++
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);