[APITESTS] Use StringCbPrintfA instead of sprintf
[reactos.git] / modules / 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 "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 }