1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Test for PrivMoveFileIdentityW 5 * PROGRAMMER: Pierre Schweitzer <pierre@reactos.org> 6 */ 7 8 #include "precomp.h" 9 10 #include <ndk/iofuncs.h> 11 12 static const WCHAR FileName[] = L"TestFile.xxx"; 13 static const CHAR FileNameA[] = "TestFile.xxx"; 14 static const WCHAR FileName2[] = L"TestFile2.xxx"; 15 16 static BOOL (WINAPI * pPrivMoveFileIdentityW)(LPCWSTR, LPCWSTR, DWORD); 17 18 static 19 BOOL 20 QueryFileInfo( 21 LPCWSTR File, 22 PFILE_BASIC_INFORMATION FileBasicInfo, 23 PFILE_STANDARD_INFORMATION FileStandardInfo) 24 { 25 HANDLE hFile; 26 IO_STATUS_BLOCK IoStatusBlock; 27 NTSTATUS Status; 28 29 hFile = CreateFileW(File, FILE_READ_ATTRIBUTES | SYNCHRONIZE, 30 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 31 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_SYNCHRONOUS_IO_NONALERT, 32 NULL); 33 if (hFile == INVALID_HANDLE_VALUE) 34 { 35 return FALSE; 36 } 37 38 Status = NtQueryInformationFile(hFile, &IoStatusBlock, FileBasicInfo, 39 sizeof(FILE_BASIC_INFORMATION), FileBasicInformation); 40 if (!NT_SUCCESS(Status)) 41 { 42 CloseHandle(hFile); 43 return FALSE; 44 } 45 46 Status = NtQueryInformationFile(hFile, &IoStatusBlock, FileStandardInfo, 47 sizeof(FILE_STANDARD_INFORMATION), FileStandardInformation); 48 49 CloseHandle(hFile); 50 return NT_SUCCESS(Status); 51 } 52 53 static 54 VOID 55 TestPrivMoveFileIdentityW(VOID) 56 { 57 FILE_BASIC_INFORMATION FileBasicInfo; 58 FILE_STANDARD_INFORMATION FileStandardInfo; 59 LARGE_INTEGER CreationTime, EndOfFile; 60 HANDLE hDest; 61 WCHAR Self[MAX_PATH]; 62 OFSTRUCT ReOpen; 63 64 DeleteFileW(FileName); 65 DeleteFileW(FileName2); 66 67 if (GetModuleFileNameW(NULL, Self, MAX_PATH) == 0) 68 { 69 win_skip("Failed finding self\n"); 70 return; 71 } 72 73 if (!QueryFileInfo(Self, &FileBasicInfo, &FileStandardInfo)) 74 { 75 win_skip("Failed querying self\n"); 76 return; 77 } 78 79 CreationTime = FileBasicInfo.CreationTime; 80 EndOfFile = FileStandardInfo.EndOfFile; 81 82 Sleep(150); 83 84 hDest = CreateFileW(FileName, GENERIC_WRITE | SYNCHRONIZE, 85 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 86 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_SYNCHRONOUS_IO_NONALERT, 87 NULL); 88 if (hDest == INVALID_HANDLE_VALUE) 89 { 90 win_skip("Failed creating new\n"); 91 return; 92 } 93 94 CloseHandle(hDest); 95 96 ok(QueryFileInfo(FileName, &FileBasicInfo, &FileStandardInfo) == TRUE, "QueryFileInfo returned FALSE\n"); 97 ok(FileBasicInfo.CreationTime.QuadPart != CreationTime.QuadPart, "Equal creation times\n"); 98 ok(FileStandardInfo.EndOfFile.QuadPart == 0LL, "File wasn't created empty: %I64d\n", FileStandardInfo.EndOfFile.QuadPart); 99 SetLastError(0xdeadbeef); 100 ok(pPrivMoveFileIdentityW(Self, FileName, 0) == FALSE, "PrivMoveFileIdentityW succeed\n"); 101 ok(GetLastError() == ERROR_SHARING_VIOLATION, "Last error: %#lx\n", GetLastError()); 102 ok(QueryFileInfo(FileName, &FileBasicInfo, &FileStandardInfo) == TRUE, "QueryFileInfo returned FALSE\n"); 103 ok(FileBasicInfo.CreationTime.QuadPart != CreationTime.QuadPart, "Equal creation times\n"); 104 ok(FileStandardInfo.EndOfFile.QuadPart == 0LL, "File wasn't created empty: %I64d\n", FileStandardInfo.EndOfFile.QuadPart); 105 SetLastError(0xdeadbeef); 106 ok(pPrivMoveFileIdentityW(Self, FileName, 2) == TRUE, "PrivMoveFileIdentityW failed with %#lx\n", GetLastError()); 107 ok(QueryFileInfo(FileName, &FileBasicInfo, &FileStandardInfo) == TRUE, "QueryFileInfo returned FALSE\n"); 108 ok(FileBasicInfo.CreationTime.QuadPart == CreationTime.QuadPart, "Creation time didn't change\n"); 109 ok(FileStandardInfo.EndOfFile.QuadPart == 0LL, "File not empty anymore: %I64d\n", FileStandardInfo.EndOfFile.QuadPart); 110 ok(QueryFileInfo(Self, &FileBasicInfo, &FileStandardInfo) == TRUE, "QueryFileInfo returned FALSE\n"); 111 ok(FileBasicInfo.CreationTime.QuadPart == CreationTime.QuadPart, "Creation time changed\n"); 112 ok(FileStandardInfo.EndOfFile.QuadPart == EndOfFile.QuadPart, "File size changed: %I64d\n", FileStandardInfo.EndOfFile.QuadPart); 113 114 hDest = CreateFileW(FileName2, GENERIC_WRITE | SYNCHRONIZE, 115 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, 116 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_SYNCHRONOUS_IO_NONALERT, 117 NULL); 118 if (hDest == INVALID_HANDLE_VALUE) 119 { 120 win_skip("Failed creating new\n"); 121 return; 122 } 123 124 CloseHandle(hDest); 125 126 ok(QueryFileInfo(FileName2, &FileBasicInfo, &FileStandardInfo) == TRUE, "QueryFileInfo returned FALSE\n"); 127 ok(FileBasicInfo.CreationTime.QuadPart != CreationTime.QuadPart, "Equal creation times\n"); 128 SetLastError(0xdeadbeef); 129 ok(pPrivMoveFileIdentityW(FileName, FileName2, 3) == TRUE, "PrivMoveFileIdentityW failed with %#lx\n", GetLastError()); 130 ok(QueryFileInfo(FileName2, &FileBasicInfo, &FileStandardInfo) == TRUE, "QueryFileInfo returned FALSE\n"); 131 ok(FileBasicInfo.CreationTime.QuadPart == CreationTime.QuadPart, "Creation time didn't change\n"); 132 ok(OpenFile(FileNameA, &ReOpen, OF_EXIST) == HFILE_ERROR, "Source file still exists\n"); 133 134 DeleteFileW(FileName2); 135 DeleteFileW(FileName); 136 } 137 138 START_TEST(PrivMoveFileIdentityW) 139 { 140 HMODULE hKern = GetModuleHandleA("kernel32.dll"); 141 pPrivMoveFileIdentityW = (void *)GetProcAddress(hKern, "PrivMoveFileIdentityW"); 142 143 TestPrivMoveFileIdentityW(); 144 } 145