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