1// Licensed to the .NET Foundation under one or more agreements.
2// The .NET Foundation licenses this file to you under the MIT license.
3// See the LICENSE file in the project root for more information.
4
5/*=====================================================================
6**
7** Source: MoveFileExA.c
8**
9** Purpose: Tests the PAL implementation of the MoveFileExA function.
10**
11**
12**===================================================================*/
13
14#include <palsuite.h>
15
16
17LPSTR lpSource[4] = {
18 "src_existing.tmp",
19 "src_non-existant.tmp",
20 "src_dir_existing",
21 "src_dir_non-existant"
22 };
23LPSTR lpDestination[4]={
24 "dst_existing.tmp",
25 "dst_non-existant.tmp",
26 "dst_dir_existing",
27 "dst_dir_non-existant"
28 };
29
30LPSTR lpFiles[14] ={
31 "src_dir_existing\\test01.tmp",
32 "src_dir_existing\\test02.tmp",
33 "dst_dir_existing\\test01.tmp",
34 "dst_dir_existing\\test02.tmp",
35 "src_dir_non-existant\\test01.tmp",
36 "src_dir_non-existant\\test02.tmp",
37 "dst_existing.tmp\\test01.tmp",
38 "dst_existing.tmp\\test02.tmp",
39 "dst_non-existant.tmp\\test01.tmp",
40 "dst_non-existant.tmp\\test02.tmp",
41 "dst_dir_existing\\test01.tmp",
42 "dst_dir_existing\\test02.tmp",
43 "dst_dir_non-existant\\test01.tmp",
44 "dst_dir_non-existant\\test02.tmp"
45 };
46
47DWORD dwFlag[2] = {MOVEFILE_COPY_ALLOWED, MOVEFILE_REPLACE_EXISTING};
48
49
50
51
52int createExisting(void)
53{
54 HANDLE tempFile = NULL;
55 HANDLE tempFile2 = NULL;
56
57 /* create the src_existing file and dst_existing file */
58 tempFile = CreateFileA(lpSource[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
59 FILE_ATTRIBUTE_NORMAL, 0);
60 tempFile2 = CreateFileA(lpDestination[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
61 FILE_ATTRIBUTE_NORMAL, 0);
62 CloseHandle(tempFile2);
63 CloseHandle(tempFile);
64
65 if ((tempFile == NULL) || (tempFile2 == NULL))
66 {
67 Trace("ERROR[%ul]: couldn't create %S or %S\n", GetLastError(), lpSource[0],
68 lpDestination[0]);
69 return FAIL;
70 }
71
72 /* create the src_dir_existing and dst_dir_existing directory and files */
73 CreateDirectoryA(lpSource[2], NULL);
74
75 tempFile = CreateFileA(lpFiles[0], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
76 FILE_ATTRIBUTE_NORMAL, 0);
77 tempFile2 = CreateFileA(lpFiles[1], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
78 FILE_ATTRIBUTE_NORMAL, 0);
79 CloseHandle(tempFile2);
80 CloseHandle(tempFile);
81
82 if ((tempFile == NULL) || (tempFile2 == NULL))
83 {
84 Trace("ERROR[%ul]: couldn't create src_dir_existing\\test01.tmp\n", GetLastError());
85 return FAIL;
86 }
87
88 CreateDirectoryA(lpDestination[2], NULL);
89 tempFile = CreateFileA(lpFiles[2], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
90 FILE_ATTRIBUTE_NORMAL, 0);
91 tempFile2 = CreateFileA(lpFiles[3], GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
92 FILE_ATTRIBUTE_NORMAL, 0);
93 CloseHandle(tempFile2);
94 CloseHandle(tempFile);
95
96 if ((tempFile == NULL) || (tempFile2 == NULL))
97 {
98 Trace("ERROR[%ul]: couldn't create dst_dir_existing\\test01.tmp\n" , GetLastError());
99 return FAIL;
100 }
101 return PASS;
102
103}
104
105void removeDirectoryHelper(LPSTR dir, int location)
106{
107 DWORD dwAtt = GetFileAttributesA(dir);
108
109 if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
110 {
111 if(!RemoveDirectoryA(dir))
112 {
113 Fail("ERROR: Failed to remove Directory [%s], Error Code [%d], location [%d]\n", dir, GetLastError(), location);
114 }
115 }
116}
117
118void removeFileHelper(LPSTR pfile, int location)
119{
120 FILE *fp;
121 fp = fopen( pfile, "r");
122
123 if (fp != NULL)
124 {
125 if(fclose(fp))
126 {
127 Fail("ERROR: Failed to close the file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
128 }
129
130 if(!DeleteFileA(pfile))
131 {
132 Fail("ERROR: Failed to delete file [%s], Error Code [%d], location [%d]\n", pfile, GetLastError(), location);
133 }
134 }
135
136}
137
138void removeAll(void)
139{
140 DWORD dwAtt;
141 /* get rid of destination dirs and files */
142 removeFileHelper(lpSource[0], 11);
143 removeFileHelper(lpSource[1], 12);
144 removeFileHelper(lpFiles[0], 13);
145 removeFileHelper(lpFiles[1], 14);
146
147 removeDirectoryHelper(lpSource[2], 101);
148 removeFileHelper(lpFiles[4], 15);
149 removeFileHelper(lpFiles[5], 16);
150 removeDirectoryHelper(lpSource[3], 102);
151
152 /* get rid of destination dirs and files */
153 dwAtt = GetFileAttributesA(lpDestination[0]);
154 if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
155 {
156 removeFileHelper(lpFiles[6], 18);
157 removeFileHelper(lpFiles[7], 19);
158 removeDirectoryHelper(lpDestination[0], 103);
159 }
160 else
161 {
162 removeFileHelper(lpDestination[0], 17);
163 }
164
165 dwAtt = GetFileAttributesA(lpDestination[1]);
166 if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
167 {
168 removeFileHelper(lpFiles[8], 21);
169 removeFileHelper(lpFiles[9], 22);
170 removeDirectoryHelper(lpDestination[1], 104);
171 }
172 else
173 {
174 removeFileHelper(lpDestination[1], 19);
175 }
176
177 dwAtt = GetFileAttributesA(lpDestination[2]);
178 if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
179 {
180 removeFileHelper(lpFiles[10], 24);
181 removeFileHelper(lpFiles[11], 25);
182 removeDirectoryHelper(lpDestination[2], 105);
183 }
184 else
185 {
186 removeFileHelper(lpDestination[2], 23);
187 }
188
189 dwAtt = GetFileAttributesA(lpDestination[3]);
190 if (( dwAtt != INVALID_FILE_ATTRIBUTES ) && ( dwAtt & FILE_ATTRIBUTE_DIRECTORY) )
191 {
192 removeFileHelper(lpFiles[12], 26);
193 removeFileHelper(lpFiles[13], 27);
194 removeDirectoryHelper(lpDestination[3], 106);
195 }
196 else
197 {
198 removeFileHelper(lpDestination[3], 107);
199 }
200
201}
202
203int __cdecl main(int argc, char *argv[])
204{
205 BOOL bRc = TRUE;
206 char results[40];
207 FILE* resultsFile = NULL;
208 int i, j, k, nCounter = 0;
209 int res = FAIL;
210 char tempSource[] = {'t','e','m','p','k','.','t','m','p','\0'};
211 char tempDest[] = {'t','e','m','p','2','.','t','m','p','\0'};
212 HANDLE hFile;
213 DWORD result;
214
215 if (0 != PAL_Initialize(argc,argv))
216 {
217 return FAIL;
218 }
219
220 /* read in the expected results to compare with actual results */
221 memset (results, 0, 34);
222 resultsFile = fopen("expectedresults.txt", "r");
223 if (resultsFile == NULL)
224 {
225 Trace("MoveFileExA ERROR: Unable to open \"expectedresults.txt\"\n");
226 goto EXIT;
227 }
228
229 fgets(results, 34, resultsFile);
230 fclose(resultsFile);
231
232 nCounter = 0;
233
234
235 /* clean the slate */
236 removeAll();
237 if (createExisting() != PASS)
238 {
239 goto EXIT;
240 }
241
242 /* lpSource loop */
243 for (i = 0; i < 4; i++)
244 {
245 /* lpDestination loop */
246 for (j = 0; j < 4; j++)
247 {
248 /* dwFlag loop */
249 for (k = 0; k < 2; k++)
250 {
251
252 /* move the file to the new location */
253 bRc = MoveFileExA(lpSource[i], lpDestination[j], dwFlag[k]);
254
255 if (!(
256 ((bRc == TRUE) && (results[nCounter] == '1'))
257 ||
258 ((bRc == FALSE ) && (results[nCounter] == '0')) )
259 )
260 {
261 Trace("MoveFileExA(%s, %s, %s): Values of i[%d], j[%d], k [%d] and results[%d]=%c LastError[%d]Flag[%d]FAILED\n",
262 lpSource[i], lpDestination[j],
263 k == 1 ?
264 "MOVEFILE_REPLACE_EXISTING":"MOVEFILE_COPY_ALLOWED", i, j, k, nCounter, results[nCounter], GetLastError(), bRc);
265 goto EXIT;
266 }
267
268 /* undo the last move */
269 removeAll();
270 if (createExisting() != PASS)
271 {
272 goto EXIT;
273 }
274 nCounter++;
275 }
276 }
277 }
278
279 /* create the temp source file */
280 hFile = CreateFileA(tempSource, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
281 FILE_ATTRIBUTE_NORMAL, 0);
282
283 if( hFile == INVALID_HANDLE_VALUE )
284 {
285 Trace("MoveFileExA: CreateFile failed to "
286 "create the file correctly.\n");
287 goto EXIT;
288 }
289
290 bRc = CloseHandle(hFile);
291 if(!bRc)
292 {
293 Trace("MoveFileExA: CloseHandle failed to close the "
294 "handle correctly. yo %u\n",GetLastError());
295 goto EXIT;
296 }
297
298 /* set the file attributes to be readonly */
299 bRc = SetFileAttributesA(tempSource, FILE_ATTRIBUTE_READONLY);
300 if(!bRc)
301 {
302 Trace("MoveFileExA: SetFileAttributes failed to set file "
303 "attributes correctly. ERROR:%u\n",GetLastError());
304 goto EXIT;
305 }
306
307 /* move the file to the new location */
308 bRc = MoveFileExA(tempSource, tempDest, MOVEFILE_COPY_ALLOWED );
309 if(!bRc)
310 {
311 Trace("MoveFileExA(%S, %S, %s): GetFileAttributes "
312 "failed to get the file's attributes.\n",
313 tempSource, tempDest, "MOVEFILE_COPY_ALLOWED");
314 goto EXIT;
315 }
316
317 /* check that the newly moved file has the same file attributes
318 as the original */
319 result = GetFileAttributesA(tempDest);
320 if(result == 0)
321 {
322 Trace("MoveFileExA: GetFileAttributes failed to get "
323 "the file's attributes.\n");
324 goto EXIT;
325 }
326
327 if((result & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY)
328 {
329 Trace("MoveFileExA: GetFileAttributes failed to get "
330 "the correct file attributes.\n");
331 goto EXIT;
332 }
333
334 /* set the file attributes back to normal, to be deleted */
335 bRc = SetFileAttributesA(tempDest, FILE_ATTRIBUTE_NORMAL);
336 if(!bRc)
337 {
338 Trace("MoveFileExA: SetFileAttributes "
339 "failed to set file attributes correctly.\n");
340 goto EXIT;
341 }
342
343 /* delete the newly moved file */
344 bRc = DeleteFileA(tempDest);
345 if(!bRc)
346 {
347 Trace("MoveFileExA: DeleteFileA failed to delete the"
348 "file correctly.\n");
349 goto EXIT;
350 }
351
352 res = PASS;
353
354EXIT:
355 removeAll();
356
357 PAL_TerminateEx(res);
358 return res;
359}
360
361