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