xcopy.c 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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. #include <windows.h>
  19. #include "wine/test.h"
  20. static DWORD runcmd(const char* cmd)
  21. {
  22. STARTUPINFOA si = {sizeof(STARTUPINFOA)};
  23. PROCESS_INFORMATION pi;
  24. char* wcmd;
  25. DWORD rc;
  26. /* Create a writable copy for CreateProcessA() */
  27. wcmd = HeapAlloc(GetProcessHeap(), 0, strlen(cmd) + 1);
  28. strcpy(wcmd, cmd);
  29. /* On Windows 2003 and older, xcopy.exe fails if stdin is not a console
  30. * handle, even with '/I /Y' options.
  31. */
  32. rc = CreateProcessA(NULL, wcmd, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
  33. HeapFree(GetProcessHeap(), 0, wcmd);
  34. if (!rc)
  35. return 260;
  36. rc = WaitForSingleObject(pi.hProcess, 5000);
  37. if (rc == WAIT_OBJECT_0)
  38. GetExitCodeProcess(pi.hProcess, &rc);
  39. else
  40. TerminateProcess(pi.hProcess, 1);
  41. CloseHandle(pi.hThread);
  42. CloseHandle(pi.hProcess);
  43. return rc;
  44. }
  45. static void test_date_format(void)
  46. {
  47. DWORD rc;
  48. rc = runcmd("xcopy /D:20-01-2000 xcopy1 xcopytest");
  49. ok(rc == 4, "xcopy /D:d-m-y test returned rc=%u\n", rc);
  50. ok(GetFileAttributesA("xcopytest\\xcopy1") == INVALID_FILE_ATTRIBUTES,
  51. "xcopy should not have created xcopytest\\xcopy1\n");
  52. rc = runcmd("xcopy /D:01-20-2000 xcopy1 xcopytest");
  53. ok(rc == 0, "xcopy /D:m-d-y test failed rc=%u\n", rc);
  54. ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
  55. "xcopy did not create xcopytest\\xcopy1\n");
  56. DeleteFileA("xcopytest\\xcopy1");
  57. rc = runcmd("xcopy /D:1-20-2000 xcopy1 xcopytest");
  58. ok(rc == 0, "xcopy /D:m-d-y test failed rc=%u\n", rc);
  59. ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
  60. "xcopy did not create xcopytest\\xcopy1\n");
  61. DeleteFileA("xcopytest\\xcopy1");
  62. }
  63. static void test_parms_syntax(void)
  64. {
  65. DWORD rc;
  66. rc = runcmd("xcopy /H/D:20-01-2000 xcopy1 xcopytest");
  67. ok(rc == 4, "xcopy /H/D:d-m-y test returned rc=%u\n", rc);
  68. ok(GetFileAttributesA("xcopytest\\xcopy1") == INVALID_FILE_ATTRIBUTES,
  69. "xcopy should not have created xcopytest\\xcopy1\n");
  70. rc = runcmd("xcopy /D:01-20-2000/H xcopy1 xcopytest");
  71. ok(rc == 0, "xcopy /H/D:m-d-y test failed rc=%u\n", rc);
  72. ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
  73. "xcopy did not create xcopytest\\xcopy1\n");
  74. DeleteFileA("xcopytest\\xcopy1");
  75. /* The following test is commented out as under wine it generates
  76. a recursively deep directory tree (todo_wine)
  77. rc = runcmd("xcopy /D:1-20-2000/E xcopy1 xcopytest");
  78. ok(rc == 0, "xcopy /D:m-d-y/E test failed rc=%u\n", rc);
  79. ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
  80. "xcopy did not create xcopytest\\xcopy1\n");
  81. DeleteFileA("xcopytest\\xcopy1"); */
  82. rc = runcmd("xcopy /D/S xcopytest xcopytest2\\");
  83. ok(rc == 0, "xcopy /D/S test failed rc=%u\n", rc);
  84. ok(GetFileAttributesA("xcopytest2") == INVALID_FILE_ATTRIBUTES,
  85. "xcopy copied empty directory incorrectly\n");
  86. rc = runcmd("xcopy /D/S/E xcopytest xcopytest2\\");
  87. ok(rc == 0, "xcopy /D/S/E test failed rc=%u\n", rc);
  88. ok(GetFileAttributesA("xcopytest2") != INVALID_FILE_ATTRIBUTES,
  89. "xcopy failed to copy empty directory\n");
  90. RemoveDirectoryA("xcopytest2");
  91. }
  92. static void test_keep_attributes(void)
  93. {
  94. DWORD rc;
  95. SetFileAttributesA("xcopy1", FILE_ATTRIBUTE_READONLY);
  96. rc = runcmd("xcopy xcopy1 xcopytest");
  97. ok(rc == 0, "xcopy failed to copy read only file\n");
  98. ok((GetFileAttributesA("xcopytest\\xcopy1") & FILE_ATTRIBUTE_READONLY) != FILE_ATTRIBUTE_READONLY,
  99. "xcopy should not have copied file permissions\n");
  100. SetFileAttributesA("xcopytest\\xcopy1", FILE_ATTRIBUTE_NORMAL);
  101. DeleteFileA("xcopytest\\xcopy1");
  102. rc = runcmd("xcopy /K xcopy1 xcopytest");
  103. ok(rc == 0, "xcopy failed to copy read only file with /k\n");
  104. ok((GetFileAttributesA("xcopytest\\xcopy1") & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY,
  105. "xcopy did not keep file permissions\n");
  106. SetFileAttributesA("xcopytest\\xcopy1", FILE_ATTRIBUTE_NORMAL);
  107. DeleteFileA("xcopytest\\xcopy1");
  108. SetFileAttributesA("xcopy1", FILE_ATTRIBUTE_NORMAL);
  109. }
  110. START_TEST(xcopy)
  111. {
  112. char tmpdir[MAX_PATH];
  113. HANDLE hfile;
  114. GetTempPathA(MAX_PATH, tmpdir);
  115. SetCurrentDirectoryA(tmpdir);
  116. trace("%s\n", tmpdir);
  117. CreateDirectoryA("xcopytest", NULL);
  118. hfile = CreateFileA("xcopy1", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
  119. FILE_ATTRIBUTE_NORMAL, NULL);
  120. ok(hfile != INVALID_HANDLE_VALUE, "Failed to create xcopy1 file\n");
  121. if (hfile == INVALID_HANDLE_VALUE)
  122. {
  123. skip("skipping xcopy tests\n");
  124. return;
  125. }
  126. CloseHandle(hfile);
  127. test_date_format();
  128. test_parms_syntax();
  129. test_keep_attributes();
  130. DeleteFileA("xcopy1");
  131. RemoveDirectoryA("xcopytest");
  132. }