update for HEAD-2003021201
[reactos.git] / apps / tests / copymove / copymove.c
1 /*
2  * CopyFile, MoveFile and related routines test
3  */
4
5 #include <ctype.h>
6 #include <stdio.h>
7 #include <tchar.h>
8 #include <windows.h>
9
10 static TCHAR
11 FindOtherDrive()
12 {
13         DWORD drives = GetLogicalDrives();
14         BOOL found = FALSE;
15         TCHAR drive;
16         TCHAR rootdir[] = _T( "?:\\" );
17         TCHAR currentdir[MAX_PATH + 1];
18
19         if (0 != GetCurrentDirectory(MAX_PATH + 1, currentdir)) {
20                 for (drive = _T('A'); ! found && drive <= _T('Z'); drive++) {
21                         if (0 != (drives & (1 << (drive - _T('A'))))&&
22                             drive != _totupper(currentdir[0])) {
23                                 rootdir[0] = drive;
24                                 found = (DRIVE_FIXED == GetDriveType(rootdir));
25                         }
26                 }
27         }
28
29         return found ? drive - 1 : _T( ' ' );
30 }
31
32 static void
33 DeleteTestFile(LPCTSTR filename)
34 {
35         SetFileAttributes(filename, FILE_ATTRIBUTE_NORMAL);
36         DeleteFile(filename);
37 }
38
39 static void
40 CreateTestFile(LPCTSTR filename, DWORD attributes)
41 {
42         HANDLE file;
43         char buffer[4096];
44         DWORD wrote;
45         int c;
46
47         DeleteTestFile(filename);   
48         file = CreateFile(filename, 
49                           GENERIC_READ | GENERIC_WRITE, 
50                           0, 
51                           NULL, 
52                           CREATE_ALWAYS, 
53                           0, 
54                           0);
55    
56         if (INVALID_HANDLE_VALUE == file) {
57                 fprintf(stderr, "CreateFile failed with code %d\n", GetLastError());
58                 exit(1);
59         }
60         for(c = 0; c < sizeof(buffer); c++) {
61                 buffer[c] = (char) c;
62         }
63         if (! WriteFile(file, buffer, sizeof(buffer), &wrote, NULL)) {
64                 fprintf(stderr, "WriteFile failed with code %d\n", GetLastError());
65                 exit(1);
66         }
67         CloseHandle(file);
68
69         if (! SetFileAttributes(filename, attributes)) {
70                 fprintf(stderr, "SetFileAttributes failed with code %d\n", GetLastError());
71                 exit(1);
72         }
73 }
74
75 static void
76 DeleteTestDir(LPCTSTR dirname)
77 {
78         RemoveDirectory(dirname);
79 }
80
81 static void
82 CreateTestDir(LPCTSTR dirname)
83 {
84         if (! CreateDirectory(dirname, NULL)) {
85                 fprintf(stderr, "CreateDirectory failed with code %d\n", GetLastError());
86                 exit(1);
87         }
88 }
89
90 static void
91 CheckTestFile(LPCTSTR filename, DWORD attributes)
92 {
93         HANDLE file;
94         char buffer[4096];
95         DWORD read;
96         int c;
97         DWORD diskattr;
98
99         file = CreateFile(filename,
100                           GENERIC_READ,
101                           0,
102                           NULL,
103                           OPEN_EXISTING,
104                           0,
105                           0);
106
107         if (INVALID_HANDLE_VALUE == file) {
108                 fprintf(stderr, "CreateFile failed with code %d\n", GetLastError());
109                 exit(1);
110         }
111
112         if (! ReadFile(file, buffer, sizeof(buffer), &read, NULL)) {
113                 fprintf(stderr, "ReadFile failed with code %d\n", GetLastError());
114                 exit(1);
115         }
116         if (read != sizeof(buffer)) {
117                 fprintf(stderr, "Trying to read %d bytes but got %d bytes\n", sizeof(buffer), read);
118                 exit(1);
119         }
120         for(c = 0; c < sizeof(buffer); c++) {
121                 if (buffer[c] != (char) c) {
122                         fprintf(stderr, "File contents changed at position %d\n", c);
123                         exit(1);
124                 }
125         }
126
127         CloseHandle(file);
128         
129         diskattr = GetFileAttributes(filename);
130         if (INVALID_FILE_ATTRIBUTES == diskattr) {
131                 fprintf(stderr, "GetFileAttributes failed with code %d\n", GetLastError());
132                 exit(1);
133         }
134         if (diskattr != attributes) {
135                 fprintf(stderr, "Attribute mismatch, expected 0x%08x found 0x%08x\n", attributes, diskattr);
136                 exit(1);
137         }
138 }
139
140 int
141 main(int argc, char *argv[])
142 {
143         TCHAR otherdrive;
144         TCHAR otherfile[ ] = _T("?:\\other.dat");
145
146         otherdrive = FindOtherDrive();
147
148         printf("Testing simple move\n");
149         CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE);
150         DeleteTestFile(_T("end.dat"));
151         if (! MoveFile(_T("begin.dat"), _T("end.dat"))) {
152                 fprintf(stderr, "MoveFile failed with code %d\n", GetLastError());
153                 exit(1);
154         }
155         CheckTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE);
156         DeleteTestFile(_T("end.dat"));
157
158         printf("Testing move of non-existing file\n");
159         DeleteTestFile(_T("begin.dat"));
160         DeleteTestFile(_T("end.dat"));
161         if (MoveFile(_T("begin.dat"), _T("end.dat"))) {
162                 fprintf(stderr, "MoveFile succeeded but shouldn't have\n");
163                 exit(1);
164         } else if (ERROR_FILE_NOT_FOUND != GetLastError()) {
165                 fprintf(stderr, "MoveFile failed with unexpected code %d\n", GetLastError());
166                 exit(1);
167         }
168         DeleteTestFile(_T("end.dat"));
169
170 /* Not correctly implemented in ros, destination file is kept open after this */
171 #if 0
172         printf("Testing move to existing file\n");
173         CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE);
174         CreateTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE);
175         if (MoveFile(_T("begin.dat"), _T("end.dat"))) {
176                 fprintf(stderr, "MoveFile succeeded but shouldn't have\n");
177                 exit(1);
178         } else if (ERROR_ALREADY_EXISTS != GetLastError()) {
179                 fprintf(stderr, "MoveFile failed with unexpected code %d\n", GetLastError());
180                 exit(1);
181         }
182         DeleteTestFile(_T("begin.dat"));
183         DeleteTestFile(_T("end.dat"));
184 #endif
185
186 /* Not implemented yet in ros */
187 #if 0
188         printf("Testing directory move\n");
189         CreateTestDir(_T("begin"));
190         CreateTestFile(_T("begin\\file.dat"), FILE_ATTRIBUTE_NORMAL);
191         DeleteTestDir(_T("end"));
192         if (! MoveFile(_T("begin"), _T("end"))) {
193                 fprintf(stderr, "MoveFile failed with code %d\n", GetLastError());
194                 exit(1);
195         }
196         CheckTestFile(_T("end\\file.dat"), FILE_ATTRIBUTE_NORMAL);
197         DeleteTestFile(_T("end\\file.dat"));
198         DeleteTestDir(_T("end"));
199 #endif
200
201         printf("Testing file move to different directory\n");
202         CreateTestFile(_T("file.dat"), FILE_ATTRIBUTE_NORMAL);
203         CreateTestDir(_T("end"));
204         if (! MoveFile(_T("file.dat"), _T("end\\file.dat"))) {
205                 fprintf(stderr, "MoveFile failed with code %d\n", GetLastError());
206                 exit(1);
207         }
208         CheckTestFile(_T("end\\file.dat"), FILE_ATTRIBUTE_ARCHIVE);
209         DeleteTestFile(_T("end\\file.dat"));
210         DeleteTestDir(_T("end"));
211
212         printf("Testing move of read-only file\n");
213         CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_READONLY);
214         DeleteTestFile(_T("end.dat"));
215         if (! MoveFile(_T("begin.dat"), _T("end.dat"))) {
216                 fprintf(stderr, "MoveFile failed with code %d\n", GetLastError());
217                 exit(1);
218         }
219         CheckTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_READONLY);
220         DeleteTestFile(_T("end.dat"));
221
222         printf("Testing move to different drive\n");
223         if (_T(' ') != otherdrive) {
224                 otherfile[0] = otherdrive;
225                 CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE);
226                 DeleteTestFile(otherfile);
227                 if (! MoveFile(_T("begin.dat"), otherfile)) {
228                         fprintf(stderr, "MoveFile failed with code %d\n", GetLastError());
229                         exit(1);
230                 }
231                 CheckTestFile(otherfile, FILE_ATTRIBUTE_ARCHIVE);
232                 DeleteTestFile(otherfile);
233         } else {
234                 printf("  Test skipped, no other drive available\n");
235         }
236
237         printf("Testing move/overwrite of existing file\n");
238         CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE);
239         CreateTestFile(_T("end.dat"), FILE_ATTRIBUTE_ARCHIVE);
240         if (! MoveFileEx(_T("begin.dat"), _T("end.dat"), MOVEFILE_REPLACE_EXISTING)) {
241                 fprintf(stderr, "MoveFileEx failed with code %d\n", GetLastError());
242                 exit(1);
243         }
244         DeleteTestFile(_T("begin.dat"));
245         DeleteTestFile(_T("end.dat"));
246
247 /* Not (correctly) implemented in ros yet */
248 #if 0
249         printf("Testing move/overwrite of existing readonly file\n");
250         CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE);
251         CreateTestFile(_T("end.dat"), FILE_ATTRIBUTE_READONLY);
252         if (MoveFileEx(_T("begin.dat"), _T("end.dat"), MOVEFILE_REPLACE_EXISTING)) {
253                 fprintf(stderr, "MoveFileEx succeeded but shouldn't have\n");
254                 exit(1);
255         } else if (ERROR_ALREADY_EXISTS != GetLastError() &&
256                    ERROR_ACCESS_DENIED != GetLastError()) {
257                 fprintf(stderr, "MoveFileEx failed with unexpected code %d\n", GetLastError());
258                 exit(1);
259         }
260         DeleteTestFile(_T("begin.dat"));
261         DeleteTestFile(_T("end.dat"));
262 #endif
263
264 /* Not implemented in ros yet */
265 #if 0
266         printf("Testing move to different drive without COPY_ALLOWED\n");
267         if (_T(' ') != otherdrive) {
268                 otherfile[0] = otherdrive;
269                 CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE);
270                 DeleteTestFile(otherfile);
271                 if (MoveFileEx(_T("begin.dat"), otherfile, 0)) {
272                         fprintf(stderr, "MoveFileEx succeeded but shouldn't have\n");
273                         exit(1);
274                 } else if (ERROR_NOT_SAME_DEVICE != GetLastError()) {
275                         fprintf(stderr, "MoveFileEx failed with unexpected code %d\n", GetLastError());
276                         exit(1);
277                 }
278                 DeleteTestFile(otherfile);
279         } else {
280                 printf("  Test skipped, no other drive available\n");
281         }
282 #endif
283
284         printf("Testing move to different drive with COPY_ALLOWED\n");
285         if (_T(' ') != otherdrive) {
286                 otherfile[0] = otherdrive;
287                 CreateTestFile(_T("begin.dat"), FILE_ATTRIBUTE_ARCHIVE);
288                 DeleteTestFile(otherfile);
289                 if (! MoveFileEx(_T("begin.dat"), otherfile, MOVEFILE_COPY_ALLOWED)) {
290                         fprintf(stderr, "MoveFileEx failed with code %d\n", GetLastError());
291                         exit(1);
292                 }
293                 CheckTestFile(otherfile, FILE_ATTRIBUTE_ARCHIVE);
294                 DeleteTestFile(otherfile);
295         } else {
296                 printf("  Test skipped, no other drive available\n");
297         }
298
299         printf("All tests successfully completed\n");
300
301         return 0;
302 }