ReactOS 0.4.15-dev-7887-g64a59a1
xcopy.c
Go to the documentation of this file.
1/*
2 * Copyright 2013 Francois Gouget
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include <windows.h>
20
21#include "wine/test.h"
22
23
24static DWORD runcmd(const char* cmd)
25{
26 STARTUPINFOA si = {sizeof(STARTUPINFOA)};
28 char* wcmd;
29 DWORD rc;
30
31 /* Create a writable copy for CreateProcessA() */
32 wcmd = HeapAlloc(GetProcessHeap(), 0, strlen(cmd) + 1);
33 strcpy(wcmd, cmd);
34
35 /* On Windows 2003 and older, xcopy.exe fails if stdin is not a console
36 * handle, even with '/I /Y' options.
37 */
39 HeapFree(GetProcessHeap(), 0, wcmd);
40 if (!rc)
41 return 260;
42
43 rc = WaitForSingleObject(pi.hProcess, 5000);
44 if (rc == WAIT_OBJECT_0)
45 GetExitCodeProcess(pi.hProcess, &rc);
46 else
47 TerminateProcess(pi.hProcess, 1);
48 CloseHandle(pi.hThread);
49 CloseHandle(pi.hProcess);
50
51 return rc;
52}
53
54static void test_date_format(void)
55{
56 DWORD rc;
57
58 rc = runcmd("xcopy /D:20-01-2000 xcopy1 xcopytest");
59 ok(rc == 4, "xcopy /D:d-m-y test returned rc=%u\n", rc);
60 ok(GetFileAttributesA("xcopytest\\xcopy1") == INVALID_FILE_ATTRIBUTES,
61 "xcopy should not have created xcopytest\\xcopy1\n");
62
63 rc = runcmd("xcopy /D:01-20-2000 xcopy1 xcopytest");
64 ok(rc == 0, "xcopy /D:m-d-y test failed rc=%u\n", rc);
65 ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
66 "xcopy did not create xcopytest\\xcopy1\n");
67 DeleteFileA("xcopytest\\xcopy1");
68
69 rc = runcmd("xcopy /D:1-20-2000 xcopy1 xcopytest");
70 ok(rc == 0, "xcopy /D:m-d-y test failed rc=%u\n", rc);
71 ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
72 "xcopy did not create xcopytest\\xcopy1\n");
73 DeleteFileA("xcopytest\\xcopy1");
74}
75
76static void test_parms_syntax(void)
77{
78 DWORD rc;
79
80 rc = runcmd("xcopy /H/D:20-01-2000 xcopy1 xcopytest");
81 ok(rc == 4, "xcopy /H/D:d-m-y test returned rc=%u\n", rc);
82 ok(GetFileAttributesA("xcopytest\\xcopy1") == INVALID_FILE_ATTRIBUTES,
83 "xcopy should not have created xcopytest\\xcopy1\n");
84
85 rc = runcmd("xcopy /D:01-20-2000/H xcopy1 xcopytest");
86 ok(rc == 0, "xcopy /H/D:m-d-y test failed rc=%u\n", rc);
87 ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
88 "xcopy did not create xcopytest\\xcopy1\n");
89 DeleteFileA("xcopytest\\xcopy1");
90
91 /* The following test is commented out as under wine it generates
92 a recursively deep directory tree (todo_wine)
93 rc = runcmd("xcopy /D:1-20-2000/E xcopy1 xcopytest");
94 ok(rc == 0, "xcopy /D:m-d-y/E test failed rc=%u\n", rc);
95 ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
96 "xcopy did not create xcopytest\\xcopy1\n");
97 DeleteFileA("xcopytest\\xcopy1"); */
98
99 rc = runcmd("xcopy /D/S xcopytest xcopytest2\\");
100 ok(rc == 0, "xcopy /D/S test failed rc=%u\n", rc);
102 "xcopy copied empty directory incorrectly\n");
103
104 rc = runcmd("xcopy /D/S/E xcopytest xcopytest2\\");
105 ok(rc == 0, "xcopy /D/S/E test failed rc=%u\n", rc);
107 "xcopy failed to copy empty directory\n");
108 RemoveDirectoryA("xcopytest2");
109}
110
111static void test_keep_attributes(void)
112{
113 DWORD rc;
114
116
117 rc = runcmd("xcopy xcopy1 xcopytest");
118 ok(rc == 0, "xcopy failed to copy read only file\n");
120 "xcopy should not have copied file permissions\n");
121 SetFileAttributesA("xcopytest\\xcopy1", FILE_ATTRIBUTE_NORMAL);
122 DeleteFileA("xcopytest\\xcopy1");
123
124 rc = runcmd("xcopy /K xcopy1 xcopytest");
125 ok(rc == 0, "xcopy failed to copy read only file with /k\n");
127 "xcopy did not keep file permissions\n");
128 SetFileAttributesA("xcopytest\\xcopy1", FILE_ATTRIBUTE_NORMAL);
129 DeleteFileA("xcopytest\\xcopy1");
130
132
133 }
134
136{
137 char tmpdir[MAX_PATH];
138 HANDLE hfile;
139
142 trace("%s\n", tmpdir);
143
144 CreateDirectoryA("xcopytest", NULL);
145 hfile = CreateFileA("xcopy1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
147 ok(hfile != INVALID_HANDLE_VALUE, "Failed to create xcopy1 file\n");
148 if (hfile == INVALID_HANDLE_VALUE)
149 {
150 skip("skipping xcopy tests\n");
151 return;
152 }
153 CloseHandle(hfile);
154
158
159 DeleteFileA("xcopy1");
160 RemoveDirectoryA("xcopytest");
161}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strcpy(char *DstString, const char *SrcString)
Definition: utclib.c:388
#define trace
Definition: atltest.h:70
#define ok(value,...)
Definition: atltest.h:57
#define skip(...)
Definition: atltest.h:64
#define START_TEST(x)
Definition: atltest.h:75
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
BOOL WINAPI DeleteFileA(IN LPCSTR lpFileName)
Definition: delete.c:24
BOOL WINAPI RemoveDirectoryA(IN LPCSTR lpPathName)
Definition: dir.c:714
BOOL WINAPI CreateDirectoryA(IN LPCSTR lpPathName, IN LPSECURITY_ATTRIBUTES lpSecurityAttributes)
Definition: dir.c:37
BOOL WINAPI SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes)
Definition: fileinfo.c:776
DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName)
Definition: fileinfo.c:636
BOOL WINAPI SetCurrentDirectoryA(IN LPCSTR lpPathName)
Definition: path.c:2206
DWORD WINAPI GetTempPathA(IN DWORD nBufferLength, OUT LPSTR lpBuffer)
Definition: path.c:2054
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4741
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1532
unsigned long DWORD
Definition: ntddk_ex.h:95
#define CREATE_ALWAYS
Definition: disk.h:72
static refpint_t pi[]
Definition: server.c:96
static void test_parms_syntax(void)
Definition: xcopy.c:76
static DWORD runcmd(const char *cmd)
Definition: xcopy.c:24
static void test_keep_attributes(void)
Definition: xcopy.c:111
static void test_date_format(void)
Definition: xcopy.c:54
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define GENERIC_WRITE
Definition: nt_native.h:90
static char tmpdir[MAX_PATH]
Definition: shlexec.c:52
Definition: ftp_var.h:139
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
struct _STARTUPINFOA STARTUPINFOA
#define WAIT_OBJECT_0
Definition: winbase.h:406
#define CREATE_NEW_CONSOLE
Definition: winbase.h:180