Merge branch 'ntfs_rebase'
[reactos.git] / modules / rostests / apitests / ntdll / NtWriteFile.c
1 /*
2 * PROJECT: ReactOS API tests
3 * LICENSE: LGPLv2.1+ - See COPYING.LIB in the top level directory
4 * PURPOSE: Test for NtWriteFile
5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org>
6 */
7
8 #include "precomp.h"
9
10 static
11 BOOL
12 Is64BitSystem(VOID)
13 {
14 #ifdef _WIN64
15 return TRUE;
16 #else
17 NTSTATUS Status;
18 ULONG_PTR IsWow64;
19
20 Status = NtQueryInformationProcess(NtCurrentProcess(),
21 ProcessWow64Information,
22 &IsWow64,
23 sizeof(IsWow64),
24 NULL);
25 if (NT_SUCCESS(Status))
26 {
27 return IsWow64 != 0;
28 }
29
30 return FALSE;
31 #endif
32 }
33
34 static
35 ULONG
36 SizeOfMdl(VOID)
37 {
38 return Is64BitSystem() ? 48 : 28;
39 }
40
41 START_TEST(NtWriteFile)
42 {
43 NTSTATUS Status;
44 HANDLE FileHandle;
45 UNICODE_STRING FileName = RTL_CONSTANT_STRING(L"\\SystemRoot\\ntdll-apitest-NtWriteFile-test.bin");
46 PVOID Buffer;
47 SIZE_T BufferSize;
48 LARGE_INTEGER ByteOffset;
49 OBJECT_ATTRIBUTES ObjectAttributes;
50 IO_STATUS_BLOCK IoStatus;
51 FILE_DISPOSITION_INFORMATION DispositionInfo;
52 ULONG TooLargeDataSize = (MAXUSHORT + 1 - SizeOfMdl()) / sizeof(ULONG_PTR) * PAGE_SIZE; // 0x3FF9000 on x86
53 ULONG LargeMdlMaxDataSize = TooLargeDataSize - PAGE_SIZE;
54
55 trace("System is %d bits, Size of MDL: %lu\n", Is64BitSystem() ? 64 : 32, SizeOfMdl());
56 trace("Max MDL data size: 0x%lx bytes\n", LargeMdlMaxDataSize);
57
58 ByteOffset.QuadPart = 0;
59
60 Buffer = NULL;
61 BufferSize = TooLargeDataSize;
62 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
63 &Buffer,
64 0,
65 &BufferSize,
66 MEM_RESERVE | MEM_COMMIT,
67 PAGE_READONLY);
68 if (!NT_SUCCESS(Status))
69 {
70 skip("Failed to allocate memory, status %lx\n", Status);
71 return;
72 }
73
74 InitializeObjectAttributes(&ObjectAttributes,
75 &FileName,
76 OBJ_CASE_INSENSITIVE,
77 NULL,
78 NULL);
79 Status = NtCreateFile(&FileHandle,
80 FILE_WRITE_DATA | DELETE | SYNCHRONIZE,
81 &ObjectAttributes,
82 &IoStatus,
83 NULL,
84 0,
85 0,
86 FILE_SUPERSEDE,
87 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT |
88 FILE_NO_INTERMEDIATE_BUFFERING,
89 NULL,
90 0);
91 ok_hex(Status, STATUS_SUCCESS);
92
93 /* non-cached, max size -- succeeds */
94 Status = NtWriteFile(FileHandle,
95 NULL,
96 NULL,
97 NULL,
98 &IoStatus,
99 Buffer,
100 LargeMdlMaxDataSize - PAGE_SIZE,
101 &ByteOffset,
102 NULL);
103 ok_hex(Status, STATUS_SUCCESS);
104
105 /* non-cached, max size -- succeeds */
106 Status = NtWriteFile(FileHandle,
107 NULL,
108 NULL,
109 NULL,
110 &IoStatus,
111 Buffer,
112 LargeMdlMaxDataSize,
113 &ByteOffset,
114 NULL);
115 ok_hex(Status, STATUS_SUCCESS);
116
117 /* non-cached, too large -- fails to allocate MDL
118 * Note: this returns STATUS_SUCCESS on Win7 -- higher MDL size limit */
119 Status = NtWriteFile(FileHandle,
120 NULL,
121 NULL,
122 NULL,
123 &IoStatus,
124 Buffer,
125 LargeMdlMaxDataSize + PAGE_SIZE,
126 &ByteOffset,
127 NULL);
128 ok_hex(Status, STATUS_INSUFFICIENT_RESOURCES);
129
130 /* non-cached, unaligned -- fails with invalid parameter */
131 Status = NtWriteFile(FileHandle,
132 NULL,
133 NULL,
134 NULL,
135 &IoStatus,
136 Buffer,
137 LargeMdlMaxDataSize + 1,
138 &ByteOffset,
139 NULL);
140 ok_hex(Status, STATUS_INVALID_PARAMETER);
141
142 DispositionInfo.DeleteFile = TRUE;
143 Status = NtSetInformationFile(FileHandle,
144 &IoStatus,
145 &DispositionInfo,
146 sizeof(DispositionInfo),
147 FileDispositionInformation);
148 ok_hex(Status, STATUS_SUCCESS);
149 Status = NtClose(FileHandle);
150 ok_hex(Status, STATUS_SUCCESS);
151
152 Status = NtCreateFile(&FileHandle,
153 FILE_WRITE_DATA | DELETE | SYNCHRONIZE,
154 &ObjectAttributes,
155 &IoStatus,
156 NULL,
157 0,
158 0,
159 FILE_SUPERSEDE,
160 FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
161 NULL,
162 0);
163 ok_hex(Status, STATUS_SUCCESS);
164
165 /* cached: succeeds with arbitrary length */
166 Status = NtWriteFile(FileHandle,
167 NULL,
168 NULL,
169 NULL,
170 &IoStatus,
171 Buffer,
172 LargeMdlMaxDataSize,
173 &ByteOffset,
174 NULL);
175 ok_hex(Status, STATUS_SUCCESS);
176
177 Status = NtWriteFile(FileHandle,
178 NULL,
179 NULL,
180 NULL,
181 &IoStatus,
182 Buffer,
183 LargeMdlMaxDataSize + 1,
184 &ByteOffset,
185 NULL);
186 ok_hex(Status, STATUS_SUCCESS);
187
188 Status = NtWriteFile(FileHandle,
189 NULL,
190 NULL,
191 NULL,
192 &IoStatus,
193 Buffer,
194 TooLargeDataSize,
195 &ByteOffset,
196 NULL);
197 ok_hex(Status, STATUS_SUCCESS);
198
199 DispositionInfo.DeleteFile = TRUE;
200 Status = NtSetInformationFile(FileHandle,
201 &IoStatus,
202 &DispositionInfo,
203 sizeof(DispositionInfo),
204 FileDispositionInformation);
205 ok_hex(Status, STATUS_SUCCESS);
206 Status = NtClose(FileHandle);
207 ok_hex(Status, STATUS_SUCCESS);
208
209 Status = NtFreeVirtualMemory(NtCurrentProcess(),
210 &Buffer,
211 &BufferSize,
212 MEM_RELEASE);
213 ok_hex(Status, STATUS_SUCCESS);
214 }