/*++ Header file for reparse point stress test Modification History: 08/18/97 anandn created --*/ // // include system headers.. // #include #include #include #include #include #include #include #include #include #include #include #include #include #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);