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.
312 lines
6.9 KiB
312 lines
6.9 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)
|
|
|
|
extern void TrimTrailingChar(PWCHAR name,WCHAR ch);
|
|
|
|
PerfTime GetPerformanceTime();
|
|
|
|
DWORD PerformanceTimeToMSec(PerfTime timeInterval);
|
|
|
|
LONGLONG PerformanceTimeToUSec(PerfTime timeInterval);
|
|
|
|
DWORDLONG GetTime();
|
|
|
|
TCHAR *PrintTime(TCHAR *string,
|
|
DWORDLONG time);
|
|
|
|
DWORDLONG GetFileID(const TCHAR *volName,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 (in chars)
|
|
ULONG nameLen; // actual length of name (not including NULL terminator) in chars
|
|
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) {
|
|
(void)StringCchCopy(name, nameLenMax, ni->FileName);
|
|
delete[] ni;
|
|
}
|
|
}
|
|
|
|
(void)StringCchCat(name, nameLenMax, s);
|
|
nameLen += n;
|
|
ASSERT(nameLen <= wcslen(name));
|
|
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);
|