371 lines
5.8 KiB
C
371 lines
5.8 KiB
C
|
/*++
|
||
|
|
||
|
Header file for reparse point stress test
|
||
|
|
||
|
Modification History:
|
||
|
|
||
|
08/18/97 anandn created
|
||
|
|
||
|
--*/
|
||
|
|
||
|
|
||
|
//
|
||
|
// include system headers..
|
||
|
//
|
||
|
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#include <ntioapi.h>
|
||
|
|
||
|
#include <windows.h>
|
||
|
#include <winioctl.h>
|
||
|
#include <winbase.h>
|
||
|
#include <wtypes.h>
|
||
|
#include <winver.h>
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <time.h>
|
||
|
#include <math.h>
|
||
|
|
||
|
#define THREAD __declspec(thread) //thread local storage
|
||
|
|
||
|
|
||
|
typedef ULONG TAG; // define a datatype for Tag
|
||
|
|
||
|
#define NO_GLE ERROR_SUCCESS
|
||
|
|
||
|
#define NO_TAG_SET IO_REPARSE_TAG_RESERVED_ZERO
|
||
|
|
||
|
#define FILE_CLOSED INVALID_HANDLE_VALUE
|
||
|
|
||
|
|
||
|
//
|
||
|
// #def all our constants..
|
||
|
//
|
||
|
|
||
|
|
||
|
#define FIRST_USER_TAG (0x02) // first user tag
|
||
|
|
||
|
#define MAX_USER_TAG ((TAG) 0xFFFF) // max tag settable by user
|
||
|
|
||
|
#define MAX_ULONGLONG (~(ULONGLONG) 0)
|
||
|
|
||
|
#define MAX_ULONG (~(ULONG) 0)
|
||
|
|
||
|
#define PAGE_SIZE (0x1000) // system page size
|
||
|
|
||
|
#define LINE_LENGTH 80 // 80 chars in a line
|
||
|
|
||
|
#define FS_NAME_SIZE 20 // max size for a FS name.eg:"NTFS","FAT" etc..
|
||
|
|
||
|
#define DRV_NAME_SIZE 2 // size of drive name string eg: "c:"
|
||
|
|
||
|
#define MAX_DRIVES 26 // maximum number of drive letters
|
||
|
|
||
|
#define MAX_DELAY 50 // maximum delay time in msecs
|
||
|
|
||
|
|
||
|
|
||
|
#define MAX_TEST_FILES (1000)
|
||
|
#define MIN_TEST_FILES (50)
|
||
|
|
||
|
#define CHAR_CODES "."
|
||
|
|
||
|
//
|
||
|
// number of check values for data verification..
|
||
|
//
|
||
|
|
||
|
#define NUM_CHECK_BYTES 5
|
||
|
|
||
|
|
||
|
//
|
||
|
// logging options
|
||
|
//
|
||
|
|
||
|
#define LOG_OPTIONS ( TLS_REFRESH | TLS_SEV2 | TLS_WARN | TLS_PASS | \
|
||
|
TLS_MONITOR | TLS_VARIATION | \
|
||
|
TLS_SYSTEM | TLS_INFO )
|
||
|
|
||
|
#define LOG_INFO(m) LogMessage( m, TLS_INFO, NO_GLE );
|
||
|
#define LOG_WARN(m) LogMessage( m, TLS_WARN, NO_GLE );
|
||
|
#define LOG_SEV2(m) LogMessage( m, TLS_SEV2, NO_GLE );
|
||
|
|
||
|
#define LOG_INFO_GLE(m) LogMessage( m, TLS_INFO, GetLastError() );
|
||
|
#define LOG_WARN_GLE(m) LogMessage( m, TLS_WARN, GetLastError() );
|
||
|
#define LOG_SEV2_GLE(m) LogMessage( m, TLS_SEV2, GetLastError() );
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// SZE returns the number of elements in an array
|
||
|
//
|
||
|
|
||
|
#define SZE(a) (sizeof(a)/sizeof(a[0]))
|
||
|
|
||
|
|
||
|
//
|
||
|
// Loops over each value in table passed in
|
||
|
// WARNING: Assumption here is x is root name of both global array and
|
||
|
// index variable. i.e. if x is foo, ifoo is index and gafoo is gloabl
|
||
|
// array being looped over
|
||
|
//
|
||
|
|
||
|
#define FOR_EACH(x) for ( i##x = 0; i##x < SZE(ga##x); i##x++ )
|
||
|
|
||
|
|
||
|
//
|
||
|
// exception code raised for sev2 logging
|
||
|
//
|
||
|
|
||
|
#define EXCEPTION_CODE_SEV2 (0xE0000002)
|
||
|
|
||
|
|
||
|
//
|
||
|
// raise a severity2 exception
|
||
|
//
|
||
|
|
||
|
#define RAISE_EXCEPTION_SEV2 RaiseException( EXCEPTION_CODE_SEV2, 0,0,0);
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// free a pointer if not null
|
||
|
//
|
||
|
|
||
|
#define FREE(ptr) if (NULL != (ptr)) { \
|
||
|
free( ptr ); \
|
||
|
ptr = NULL; \
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// few sleep times..
|
||
|
//
|
||
|
|
||
|
#define FIVE_SECS 5000
|
||
|
#define TWO_SECS 2000
|
||
|
#define ONE_SECS 1000
|
||
|
|
||
|
|
||
|
enum TESTFILE_STATUS { FILE_LOCKED, FILE_FREE };
|
||
|
enum TESTFILE_TYPE { ITS_A_FILE, ITS_A_DIR };
|
||
|
|
||
|
//
|
||
|
// the Options struct is filled from command line arguments
|
||
|
//
|
||
|
|
||
|
typedef struct {
|
||
|
|
||
|
CHAR szProgramName[MAX_PATH + 1]; // name of test program (ie argv[0])
|
||
|
CHAR Drive; // drive to test
|
||
|
CHAR szTestDir[MAX_PATH + 1]; // test dir to use on specified drive
|
||
|
|
||
|
DWORD dwMaxTestFiles;
|
||
|
DWORD dwMinTestFiles;
|
||
|
|
||
|
} OPTIONS, *POPTIONS;
|
||
|
|
||
|
|
||
|
//
|
||
|
// Central struc that holds info for a test file..
|
||
|
//
|
||
|
|
||
|
struct TESTFILE_INFO_NODE {
|
||
|
WORD wFileStatus;
|
||
|
HANDLE hFile;
|
||
|
TAG RPTag;
|
||
|
USHORT usDataBuffSize;
|
||
|
BYTE CheckBytes[NUM_CHECK_BYTES];
|
||
|
struct TESTFILE_INFO_NODE* pNext;
|
||
|
WCHAR FileName[1];
|
||
|
};
|
||
|
|
||
|
|
||
|
typedef struct TESTFILE_INFO_NODE TESTFILE_INFO_NODE;
|
||
|
|
||
|
typedef TESTFILE_INFO_NODE* PTESTFILE_INFO_NODE;
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// function prototypes
|
||
|
//
|
||
|
|
||
|
|
||
|
VOID
|
||
|
ParseArgs(INT argc, CHAR* argv[], POPTIONS pOptions);
|
||
|
|
||
|
|
||
|
VOID
|
||
|
PrintUsage( CHAR szProgramName[], CHAR szErrorString[] );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
Initialize( OPTIONS Options );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
Stress( OPTIONS Options );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
Cleanup( OPTIONS Options );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
ExceptionHandler( DWORD dwExceptionCode );
|
||
|
|
||
|
|
||
|
HANDLE
|
||
|
GetNewHandleIfClosed( PTESTFILE_INFO_NODE pNode );
|
||
|
|
||
|
|
||
|
DWORD WINAPI
|
||
|
CreateFileThread( LPVOID lpvThreadParam );
|
||
|
|
||
|
|
||
|
DWORD WINAPI
|
||
|
CloseOrDeleteFileThread( LPVOID lpvThreadParam );
|
||
|
|
||
|
|
||
|
DWORD WINAPI
|
||
|
RPSetThread( LPVOID lpvThreadParam );
|
||
|
|
||
|
|
||
|
DWORD WINAPI
|
||
|
RPGetThread( LPVOID lpvThreadParam );
|
||
|
|
||
|
|
||
|
DWORD WINAPI
|
||
|
RPDelThread( LPVOID lpvThreadParam );
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RPSet(PTESTFILE_INFO_NODE pNode,
|
||
|
TAG RPTag, PUCHAR pDataBuff, USHORT usDataBuffSize);
|
||
|
|
||
|
BOOL
|
||
|
RPGet(CHAR szFileName[], BYTE **ppOutBuff);
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
RPDel( PTESTFILE_INFO_NODE pNode );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
SelectAndLockRandomNode( TESTFILE_INFO_NODE **ppNode, CHAR s[] );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
ReleaseNodeLock( PTESTFILE_INFO_NODE pNode );
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
AddToTestFileList( HANDLE hFile, CHAR szFileName[] );
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
DeleteFromTestFileList( PTESTFILE_INFO_NODE pNode );
|
||
|
|
||
|
|
||
|
TAG
|
||
|
GetTagToSet( VOID );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
DumpBuff( PBYTE pData, WORD wSize );
|
||
|
|
||
|
VOID
|
||
|
GenerateTempFileName( LPSTR lpFileName );
|
||
|
|
||
|
|
||
|
HANDLE
|
||
|
CreateRPFile( CHAR szFileName[] );
|
||
|
|
||
|
|
||
|
HANDLE
|
||
|
OpenHandleToVolume(CHAR szVolName[]);
|
||
|
|
||
|
|
||
|
BOOL
|
||
|
IsFileSysNtfs(CHAR szVolRoot[]);
|
||
|
|
||
|
|
||
|
VOID
|
||
|
StartLogSession(CHAR szProgName[]);
|
||
|
|
||
|
|
||
|
VOID
|
||
|
EndLogSession(DWORD dwExitCode);
|
||
|
|
||
|
|
||
|
ULONG
|
||
|
HiPart(ULONGLONG n);
|
||
|
|
||
|
|
||
|
ULONG
|
||
|
LoPart(ULONGLONG n);
|
||
|
|
||
|
|
||
|
VOID
|
||
|
LogMessage( CHAR szLogMsg[], ULONG dwLevel, DWORD gle );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
LogAtLevel( CHAR szOutMsg[], ULONG dwLevel );
|
||
|
|
||
|
|
||
|
|
||
|
VOID
|
||
|
GenerateReparsePoints( VOID );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
SetReparsePoint( CHAR szFileName[],
|
||
|
TAG Tag,
|
||
|
UCHAR szData[] );
|
||
|
|
||
|
TAG
|
||
|
GetTagToSet( VOID );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
GetReparsePoint( VOID );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
DeleteReparsePoint( VOID );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
PrintError(char szWhatFailed[], int flag);
|
||
|
|
||
|
|
||
|
HANDLE
|
||
|
RPOpen (LPSTR szFileName, LPSTR szOption );
|
||
|
|
||
|
|
||
|
VOID
|
||
|
SzToWsz ( OUT WCHAR *Unicode,
|
||
|
IN char *Ansi ) ;
|
||
|
|
||
|
|
||
|
VOID
|
||
|
WszToSz ( OUT char *Ansi,
|
||
|
IN WCHAR *Unicode );
|
||
|
|
||
|
|
||
|
NTSTATUS OpenObject (
|
||
|
WCHAR *pwszFile,
|
||
|
ULONG CreateOptions,
|
||
|
ULONG DesiredAccess,
|
||
|
ULONG ShareAccess,
|
||
|
ULONG CreateDisposition,
|
||
|
IO_STATUS_BLOCK *IoStatusBlock,
|
||
|
HANDLE *ObjectHandle);
|
||
|
|
||
|
|