1 /* 2 * PROJECT: ReactOS Tests 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: tunneltest.c 5 * PURPOSE: Usermode tunnel cache testing 6 * PROGRAMMERS: Pierre Schweitzer (pierre@reactos.org) 7 * NOTES: Based on indications from: http://support.microsoft.com/?kbid=172190 8 */ 9 10 #include <stdio.h> 11 #include <windef.h> 12 #include <winternl.h> 13 #include <winbase.h> 14 #define RTL_CONSTANT_STRING(s) { sizeof(s)-sizeof((s)[0]), sizeof(s), s } 15 16 const UNICODE_STRING FatName = RTL_CONSTANT_STRING(L"FAT"); 17 const UNICODE_STRING Fat32Name = RTL_CONSTANT_STRING(L"FAT32"); 18 const UNICODE_STRING NtfsName = RTL_CONSTANT_STRING(L"NTFS"); 19 20 int wmain(int argc, WCHAR * argv[]) 21 { 22 WCHAR TempPath[MAX_PATH + 1]; 23 WCHAR CopyPath[MAX_PATH + 1]; 24 WCHAR RootPath[] = {'A', ':', '\\', '\0'}; 25 WCHAR FileSystemName[sizeof("FAT32")]; /* Max we should hold - fail otherwise, we don't care */ 26 UNICODE_STRING FSName; 27 WCHAR File1[] = {'\\', 'f', 'i', 'l', 'e', '1', '\0'}; 28 WCHAR File2[] = {'\\', 'f', 'i', 'l', 'e', '2', '\0'}; 29 ULONG FilePos; 30 HANDLE hFile; 31 FILETIME FileTime, File1Time; 32 33 /* Get temp path in which will work */ 34 if (GetTempPathW(sizeof(TempPath) / sizeof(TempPath[0]), TempPath) == 0) 35 { 36 fprintf(stderr, "Failed to get temp path\n"); 37 return GetLastError(); 38 } 39 40 /* Assume it's X:\ something */ 41 RootPath[0] = TempPath[0]; 42 43 /* Get information about the volume */ 44 if (GetVolumeInformationW(RootPath, NULL, 0, NULL, NULL, NULL, FileSystemName, sizeof(FileSystemName) / sizeof(FileSystemName[0])) == 0) 45 { 46 fprintf(stderr, "Failed to get volume info\n"); 47 return GetLastError(); 48 } 49 50 /* Convert to string */ 51 RtlInitUnicodeString(&FSName, FileSystemName); 52 53 /* Bail out if that's not FAT or NTFS */ 54 if (RtlCompareUnicodeString(&FSName, &FatName, FALSE) != 0 && 55 RtlCompareUnicodeString(&FSName, &Fat32Name, FALSE) != 0 && 56 RtlCompareUnicodeString(&FSName, &NtfsName, FALSE) != 0) 57 { 58 fprintf(stderr, "!(FAT, FAT32, NTFS): \'%S\'\n", FSName.Buffer); 59 return 0; 60 } 61 62 /* Ensure we can store complete path - no overrun */ 63 FilePos = wcslen(TempPath); 64 if (FilePos > MAX_PATH - sizeof(File2) / sizeof(WCHAR)) 65 { 66 fprintf(stderr, "Files won't fit\n"); 67 return 0; 68 } 69 70 /* Create first file */ 71 wcscat(TempPath, File1); 72 hFile = CreateFileW(TempPath, 0, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 73 if (hFile == INVALID_HANDLE_VALUE) 74 { 75 fprintf(stderr, "Failed to create file1\n"); 76 return GetLastError(); 77 } 78 79 /* Get its creation timestamp. It will be our reference */ 80 /* Get it in FileTime because file1 will renamed to file */ 81 if (GetFileTime(hFile, &FileTime, NULL, NULL) == FALSE) 82 { 83 fprintf(stderr, "Failed to read creation time\n"); 84 CloseHandle(hFile); 85 return GetLastError(); 86 } 87 88 CloseHandle(hFile); 89 90 /* Wait a least 10ms (resolution of FAT) */ 91 /* XXX: Increased to 1s for ReactOS... */ 92 Sleep(1000); 93 94 /* Create second file */ 95 /* Remove old file from buffer */ 96 TempPath[FilePos - 1] = 0; 97 wcscat(TempPath, File2); 98 hFile = CreateFileW(TempPath, 0, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 99 if (hFile == INVALID_HANDLE_VALUE) 100 { 101 fprintf(stderr, "Failed to create file2\n"); 102 return GetLastError(); 103 } 104 CloseHandle(hFile); 105 106 /* Rename file1 to file */ 107 TempPath[FilePos] = 0; 108 wcscat(TempPath, File1); 109 wcscpy(CopyPath, TempPath); 110 /* Remove number for dest */ 111 CopyPath[wcslen(TempPath) - 1] = 0; 112 if (MoveFileW(TempPath, CopyPath) == 0) 113 { 114 fprintf(stderr, "Failed to rename file1\n"); 115 return GetLastError(); 116 } 117 118 /* Rename file2 to file1 */ 119 wcscpy(CopyPath, TempPath); 120 /* Change 1 to 2 */ 121 CopyPath[wcslen(TempPath) - 1] = L'2'; 122 if (MoveFileW(CopyPath, TempPath) == 0) 123 { 124 fprintf(stderr, "Failed to rename file2\n"); 125 return GetLastError(); 126 } 127 128 /* Open file1 and get its creation time */ 129 hFile = CreateFileW(TempPath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); 130 if (hFile == INVALID_HANDLE_VALUE) 131 { 132 fprintf(stderr, "Failed to open file1\n"); 133 return GetLastError(); 134 } 135 if (GetFileTime(hFile, &File1Time, NULL, NULL) == FALSE) 136 { 137 fprintf(stderr, "Failed to read creation time\n"); 138 CloseHandle(hFile); 139 return GetLastError(); 140 } 141 CloseHandle(hFile); 142 143 /* Delete files */ 144 CopyPath[wcslen(TempPath) - 1] = 0; 145 DeleteFileW(TempPath); 146 DeleteFileW(CopyPath); 147 148 /* Compare both, they have to be strictly identical */ 149 if (RtlCompareMemory(&FileTime, &File1Time, sizeof(FILETIME)) == sizeof(FILETIME)) 150 { 151 fprintf(stdout, "Tunnel cache in action\n"); 152 return 0; 153 } 154 155 fprintf(stdout, "Tunnel cache NOT in action\n"); 156 return 0; 157 } 158