ReactOS 0.4.16-dev-338-g34e76ad
copy.c
Go to the documentation of this file.
1/*
2 * COPY.C -- copy internal command.
3 *
4 *
5 * History:
6 *
7 * 01-Aug-98 (Rob Lake z63rrl@morgan.ucs.mun.ca)
8 * started
9 *
10 * 13-Aug-1998 (John P. Price)
11 * fixed memory leak problem in copy function.
12 * fixed copy function so it would work with wildcards in the source
13 *
14 * 13-Dec-1998 (Eric Kohl)
15 * Added COPY command to CMD.
16 *
17 * 26-Jan-1998 (Eric Kohl)
18 * Replaced CRT io functions by Win32 io functions.
19 *
20 * 27-Oct-1998 (Eric Kohl)
21 * Disabled prompting when used in batch mode.
22 *
23 * 03-Apr-2005 (Magnus Olsen <magnus@greatlord.com>)
24 * Remove all hardcode string to En.rc
25 *
26 * 13-Jul-2005 (Brandon Turner <turnerb7@msu.edu>)
27 * Rewrite to clean up copy and support wildcard.
28 *
29 * 20-Jul-2005 (Brandon Turner <turnerb7@msu.edu>)
30 * Add touch syntax. "copy arp.exe+,,"
31 * Copy command is now completed.
32 */
33
34#include "precomp.h"
35
36#ifdef INCLUDE_CMD_COPY
37
38enum
39{
40 COPY_ASCII = 0x001, /* /A */
41 COPY_DECRYPT = 0x004, /* /D */
42 COPY_VERIFY = 0x008, /* /V : Dummy, Never will be Implemented */
43 COPY_SHORTNAME = 0x010, /* /N : Dummy, Never will be Implemented */
44 COPY_NO_PROMPT = 0x020, /* /Y */
45 COPY_PROMPT = 0x040, /* /-Y */
46 COPY_RESTART = 0x080, /* /Z */
47 COPY_BINARY = 0x100, /* /B */
48};
49
50INT
53 INT append,
54 DWORD lpdwFlags,
55 BOOL bTouch)
56{
57 FILETIME srctime,NewFileTime;
58 HANDLE hFileSrc;
59 HANDLE hFileDest;
61 DWORD dwAttrib;
62 DWORD dwRead;
63 DWORD dwWritten;
64 BOOL bEof = FALSE;
65 TCHAR TrueDest[MAX_PATH];
66 TCHAR TempSrc[MAX_PATH];
68 SYSTEMTIME CurrentTime;
69
70 /* Check Breaker */
72 return 0;
73
74 TRACE ("checking mode\n");
75
76 if (bTouch)
77 {
80 if (hFileSrc == INVALID_HANDLE_VALUE)
81 {
83 nErrorLevel = 1;
84 return 0;
85 }
86
87 GetSystemTime(&CurrentTime);
88 SystemTimeToFileTime(&CurrentTime, &NewFileTime);
89 if (SetFileTime(hFileSrc,(LPFILETIME) NULL, (LPFILETIME) NULL, &NewFileTime))
90 {
91 CloseHandle(hFileSrc);
92 nErrorLevel = 1;
93 return 1;
94
95 }
96 else
97 {
98 CloseHandle(hFileSrc);
99 return 0;
100 }
101 }
102
103 dwAttrib = GetFileAttributes (source);
104
106 NULL, OPEN_EXISTING, 0, NULL);
107 if (hFileSrc == INVALID_HANDLE_VALUE)
108 {
110 nErrorLevel = 1;
111 return 0;
112 }
113
114 TRACE ("getting time\n");
115
116 GetFileTime (hFileSrc, &srctime, NULL, NULL);
117
118 TRACE ("copy: flags has %s\n",
119 lpdwFlags & COPY_ASCII ? "ASCII" : "BINARY");
120
121 /* Check to see if /D or /Z are true, if so we need a middle
122 man to copy the file too to allow us to use CopyFileEx later */
123 if (lpdwFlags & COPY_DECRYPT)
124 {
125 GetEnvironmentVariable(_T("TEMP"),TempSrc,MAX_PATH);
126 _tcscat(TempSrc,_T("\\"));
127 FileName = _tcsrchr(source,_T('\\'));
128 FileName++;
129 _tcscat(TempSrc,FileName);
130 /* This is needed to be on the end to prevent an error
131 if the user did "copy /D /Z foo bar then it would be copied
132 too %TEMP%\foo here and when %TEMP%\foo when it sets it up
133 for COPY_RESTART, this would mean it is copying to itself
134 which would error when it tried to open the handles for ReadFile
135 and WriteFile */
136 _tcscat(TempSrc,_T(".decrypt"));
138 {
139 CloseHandle (hFileSrc);
140 nErrorLevel = 1;
141 return 0;
142 }
143 _tcscpy(source, TempSrc);
144 }
145
146
147 if (lpdwFlags & COPY_RESTART)
148 {
149 _tcscpy(TrueDest, dest);
151 _tcscat(dest,_T("\\"));
152 FileName = _tcsrchr(TrueDest,_T('\\'));
153 FileName++;
155 }
156
157
158 if (!IsExistingFile (dest))
159 {
160 TRACE ("opening/creating\n");
161 hFileDest =
163 }
164 else if (!append)
165 {
166 TRACE ("SetFileAttributes (%s, FILE_ATTRIBUTE_NORMAL);\n", debugstr_aw(dest));
168
169 TRACE ("DeleteFile (%s);\n", debugstr_aw(dest));
171
172 hFileDest = CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
173 }
174 else
175 {
176 LONG lFilePosHigh = 0;
177
178 if (!_tcscmp (dest, source))
179 {
180 CloseHandle (hFileSrc);
181 return 0;
182 }
183
184 TRACE ("opening/appending\n");
186
187 hFileDest =
189
190 /* Move to end of file to start writing */
191 SetFilePointer (hFileDest, 0, &lFilePosHigh,FILE_END);
192 }
193
194
195 if (hFileDest == INVALID_HANDLE_VALUE)
196 {
197 CloseHandle (hFileSrc);
199 nErrorLevel = 1;
200 return 0;
201 }
202
203 /* A page-aligned buffer usually give more speed */
205 if (buffer == NULL)
206 {
207 CloseHandle (hFileDest);
208 CloseHandle (hFileSrc);
210 nErrorLevel = 1;
211 return 0;
212 }
213
214 do
215 {
216 ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL);
217 if (lpdwFlags & COPY_ASCII)
218 {
219 LPBYTE pEof = memchr(buffer, 0x1A, dwRead);
220 if (pEof != NULL)
221 {
222 bEof = TRUE;
223 dwRead = pEof-buffer+1;
224 break;
225 }
226 }
227
228 if (dwRead == 0)
229 break;
230
231 WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL);
232 if (dwWritten != dwRead || CheckCtrlBreak(BREAK_INPUT))
233 {
235
237 CloseHandle (hFileDest);
238 CloseHandle (hFileSrc);
239 nErrorLevel = 1;
240 return 0;
241 }
242 }
243 while (!bEof);
244
245 TRACE ("setting time\n");
246 SetFileTime (hFileDest, &srctime, NULL, NULL);
247
248 if ((lpdwFlags & COPY_ASCII) && !bEof)
249 {
250 /* we're dealing with ASCII files! */
251 buffer[0] = 0x1A;
252 TRACE ("appending ^Z\n");
253 WriteFile (hFileDest, buffer, sizeof(CHAR), &dwWritten, NULL);
254 }
255
257 CloseHandle (hFileDest);
258 CloseHandle (hFileSrc);
259
260 TRACE ("setting mode\n");
261 /* For MS-DOS backwards-compatibility, always remove the read-only attribute */
263
264 /* Now finish off the copy if needed with CopyFileEx */
265 if (lpdwFlags & COPY_RESTART)
266 {
268 {
269 nErrorLevel = 1;
271 return 0;
272 }
273 /* Take care of file in the temp folder */
275
276 }
277
278 if (lpdwFlags & COPY_DECRYPT)
279 DeleteFile(TempSrc);
280
281 return 1;
282}
283
284
286{
287 /*ask the user if they want to override*/
288 INT res;
290 res = FilePromptYNA (0);
291 return res;
292}
293
294/* The following lines of copy were written by someone else
295(most likely Eric Kohl) and it was taken from ren.c */
296static void
298 LPTSTR pszSource,
299 LPTSTR pszTarget,
300 LPTSTR pszOutput)
301{
302 /* build destination file name */
303 while (*pszTarget != 0)
304 {
305 if (*pszTarget == _T('*'))
306 {
307 pszTarget++;
308 while ((*pszSource != 0) && (*pszSource != *pszTarget))
309 {
310 *pszOutput++ = *pszSource++;
311 }
312 }
313 else if (*pszTarget == _T('?'))
314 {
315 pszTarget++;
316 if (*pszSource != 0)
317 {
318 *pszOutput++ = *pszSource++;
319 }
320 }
321 else
322 {
323 *pszOutput++ = *pszTarget++;
324 if (*pszSource != 0)
325 pszSource++;
326 }
327 }
328
329 *pszOutput = 0;
330}
331
333{
334 LPTSTR *arg;
335 INT argc, i, nFiles, nOverwrite = 0, nSrc = -1, nDes = -1;
336 /* this is the path up to the folder of the src and dest ie C:\windows\ */
337 TCHAR szDestPath[MAX_PATH];
338 TCHAR szSrcPath[MAX_PATH];
339 DWORD dwFlags = 0;
340 /* If this is the type of copy where we are adding files */
341 BOOL bAppend = FALSE;
342 WIN32_FIND_DATA findBuffer;
343 HANDLE hFile = NULL;
344 BOOL bTouch = FALSE;
345 /* Pointer to keep track of how far through the append input(file1+file2+file3) we are */
346 TCHAR * appendPointer = _T("\0");
347 /* The full path to src and dest. This has drive letter, folders, and filename */
348 TCHAR tmpDestPath[MAX_PATH];
349 TCHAR tmpSrcPath[MAX_PATH];
350 /* A bool to know whether or not the destination name will be taken from the input */
351 BOOL bSrcName = FALSE;
352 /* Seems like a waste but it is a pointer used to copy from input to PreserveName */
353 TCHAR * UseThisName;
354 /* for CMDCOPY env */
355 TCHAR *evar;
356 int size;
357 TCHAR * szTouch;
358 BOOL bHasWildcard, bDone = FALSE, bMoreFiles = FALSE;
359 /* Used for something like "copy c*.exe d*.exe" */
360 BOOL bMultipleSource = FALSE, bMultipleDest = FALSE;
361
362
363 /* Show help/usage info */
364 if (!_tcsncmp(param, _T("/?"), 2))
365 {
367 return 0;
368 }
369
370 nErrorLevel = 0;
371
372 /* Get the env variable value if it exists */
373 evar = cmd_alloc(512 * sizeof(TCHAR));
374 if (evar == NULL)
375 size = 0;
376 else
377 size = GetEnvironmentVariable (_T("COPYCMD"), evar, 512);
378
379 if (size > 512)
380 {
381 TCHAR *old_evar = evar;
382 evar = cmd_realloc(evar,size * sizeof(TCHAR) );
383 if (evar!=NULL)
384 size = GetEnvironmentVariable (_T("COPYCMD"), evar, size);
385 else
386 {
387 size=0;
388 evar = old_evar;
389 }
390 }
391
392 /* check see if we did get any env variable */
393 if (size != 0)
394 {
395 int t = 0;
396
397 /* scan and set the flags */
398 for (t = 0; t < size; t++)
399 {
400 if (_tcsncicmp(_T("/A"),&evar[t],2) == 0)
401 {
403 t++;
404 }
405 else if (_tcsncicmp(_T("/B"),&evar[t],2) == 0)
406 {
408 t++;
409 }
410 else if (_tcsncicmp(_T("/D"),&evar[t],2) == 0)
411 {
413 t++;
414 }
415 else if (_tcsncicmp(_T("/V"),&evar[t],2) == 0)
416 {
418 t++;
419 }
420 else if (_tcsncicmp(_T("/N"),&evar[t],2) == 0)
421 {
423 t++;
424 }
425 else if (_tcsncicmp(_T("/Y"),&evar[t],2) == 0)
426 {
428 t++;
429 }
430 else if (_tcsncicmp(_T("/-Y"),&evar[t],3) == 0)
431 {
433 t+=2;
434 }
435 else if (_tcsncicmp(_T("/Z"),&evar[t],2) == 0)
436 {
438 t++;
439 }
440 }
441 }
442 cmd_free(evar);
443
444
445 /* Split the user input into array */
446 arg = split(param, &argc, FALSE, TRUE);
447 nFiles = argc;
448
449 /* Read switches and count files */
450 for (i = 0; i < argc; i++)
451 {
452 if (*arg[i] == _T('/'))
453 {
454 if (_tcslen(arg[i]) >= 2)
455 {
456 switch (_totupper(arg[i][1]))
457 {
458 case _T('A'):
460 break;
461
462 case _T('B'):
464 break;
465
466 case _T('D'):
468 break;
469
470 case _T('V'):
472 break;
473
474 case _T('N'):
476 break;
477
478 case _T('Y'):
480 dwFlags &= ~COPY_PROMPT;
481 break;
482
483 case _T('-'):
484 if (_tcslen(arg[i]) >= 3)
485 {
486 if (_totupper(arg[i][2]) == _T('Y'))
487 {
488 dwFlags &= ~COPY_NO_PROMPT;
490 }
491 }
492
493 break;
494
495 case _T('Z'):
497 break;
498
499 default:
500 /* Invalid switch */
502 nErrorLevel = 1;
503 freep (arg);
504 return 1;
505 break;
506 }
507 }
508 /* If it was a switch, subtract from total arguments */
509 nFiles--;
510 }
511 else
512 {
513 /* If it isn't a switch then it is the source or destination */
514 if (nSrc == -1)
515 {
516 nSrc = i;
517 }
518 else if (*arg[i] == _T('+'))
519 {
520 /* Next file should be appended */
521 bMoreFiles = TRUE;
522 nFiles -= 1;
523 }
524 else if (bMoreFiles)
525 {
526 /* Add this file to the source string
527 this way we can do all checks
528 directly on source string later on */
529 TCHAR * ptr;
530 int length = (_tcslen(arg[nSrc]) + _tcslen(arg[i]) + 2) * sizeof(TCHAR);
532 if (ptr)
533 {
534 _tcscpy(ptr, arg[nSrc]);
535 _tcscat(ptr, _T("|"));
536 _tcscat(ptr, arg[i]);
537 cmd_free(arg[nSrc]);
538 arg[nSrc] = ptr;
539 nFiles -= 1;
540 }
541
542 bMoreFiles = FALSE;
543 }
544 else if (nDes == -1)
545 {
546 nDes = i;
547 }
548 }
549 }
550
551 /* keep quiet within batch files */
552 if (bc != NULL)
553 {
555 dwFlags &= ~COPY_PROMPT;
556 }
557
558 if (nFiles < 1)
559 {
560 /* There are not enough files, there has to be at least 1 */
562 freep(arg);
563 return 1;
564 }
565
566 if (nFiles > 2)
567 {
568 /* There are too many file names in command */
570 nErrorLevel = 1;
571 freep(arg);
572 return 1;
573 }
574
575 if ((_tcschr(arg[nSrc], _T('|')) != NULL) ||
576 (_tcschr(arg[nSrc], _T('*')) != NULL) ||
577 (_tcschr(arg[nSrc], _T('?')) != NULL) ||
579 {
580 bMultipleSource = TRUE;
581 }
582
583 /* Reuse the number of files variable */
584 nFiles = 0;
585
586 /* Check if no destination argument is passed */
587 if (nDes == -1)
588 {
589 /* If no destination was entered then just use
590 the current directory as the destination */
591 GetCurrentDirectory(ARRAYSIZE(szDestPath), szDestPath);
592 }
593 else
594 {
595 /* Check if the destination is 'x:' */
596 if ((arg[nDes][1] == _T(':')) && (arg[nDes][2] == _T('\0')))
597 {
598 GetRootPath(arg[nDes], szDestPath, ARRAYSIZE(szDestPath));
599 }
600 else
601 {
602 /* If the user entered two file names then form the full string path */
603 GetFullPathName(arg[nDes], ARRAYSIZE(szDestPath), szDestPath, NULL);
604 }
605
606 /* Make sure there is an ending slash to the path if the dest is a folder */
607 if ((_tcschr(szDestPath, _T('*')) == NULL) &&
608 IsExistingDirectory(szDestPath))
609 {
610 bMultipleDest = TRUE;
611 if (szDestPath[_tcslen(szDestPath) - 1] != _T('\\'))
612 _tcscat(szDestPath, _T("\\"));
613 }
614
615 /* Check if the destination uses wildcards */
616 if ((_tcschr(arg[nDes], _T('*')) != NULL) ||
617 (_tcschr(arg[nDes], _T('?')) != NULL))
618 {
619 bMultipleDest = TRUE;
620 }
621 }
622
623 if (nDes != -1) /* Append files only when there is a destination */
624 {
625 if (bMultipleSource && !bMultipleDest)
626 {
627 /* We have multiple source files, but not multiple destination
628 files. This means we are appending the source files. */
629 bAppend = TRUE;
630 if (_tcschr(arg[nSrc], _T('|')) != NULL)
631 appendPointer = arg[nSrc];
632 }
633 }
634
635 /* Save the name the user entered */
636 UseThisName = _tcsrchr(szDestPath,_T('\\'));
637 if (UseThisName)
638 {
639 /* Split the name from the path */
640 *UseThisName++ = _T('\0');
641
642 /* Check if the dest path ends with '\*' or '\' */
643 if (((UseThisName[0] == _T('*')) && (UseThisName[1] == _T('\0'))) ||
644 (UseThisName[0] == _T('\0')))
645 {
646 /* In this case we will be using the same name as the source file
647 for the destination file because destination is a folder */
648 bSrcName = TRUE;
649 UseThisName = NULL;
650 }
651 }
652 else
653 {
654 /* Something's seriously wrong! */
655 UseThisName = szDestPath;
656 }
657
658 do
659 {
660 /* Get the full string of the path to the source file */
661 if (_tcschr(arg[nSrc], _T('|')) != NULL)
662 {
663 /* Reset the source path */
664 szSrcPath[0] = _T('\0');
665
666 /* Loop through the source file name and copy all
667 the chars one at a time until we reach the separator */
668 while(TRUE)
669 {
670 if (appendPointer[0] == _T('|'))
671 {
672 /* Skip the | and go to the next file name */
673 appendPointer++;
674 break;
675 }
676 else if (appendPointer[0] == _T('\0'))
677 {
678 bDone = TRUE;
679 break;
680 }
681
682 _tcsncat(szSrcPath, appendPointer, 1);
683 appendPointer++;
684 }
685
686 if (_tcschr(arg[nSrc], _T(',')) != NULL)
687 {
688 /* Only time there is a , in the source is when they are using touch
689 Cant have a destination and can only have on ,, at the end of the string
690 Cant have more than one file name */
691 szTouch = _tcsstr(arg[nSrc], _T("|"));
692 if (_tcsncmp(szTouch,_T("|,,\0"), 4) || (nDes != -1))
693 {
695 nErrorLevel = 1;
696 freep (arg);
697 return 1;
698 }
699 bTouch = TRUE;
700 bDone = TRUE;
701 }
702 }
703 else
704 {
705 bDone = TRUE;
706 _tcscpy(szSrcPath, arg[nSrc]);
707 }
708
709 /* "x:" is not a valid source path format. */
710 if ((szSrcPath[1] == _T(':')) && (szSrcPath[2] == _T('\0')))
711 {
712 ConOutPrintf(_T("%s\n"), szSrcPath);
714 nErrorLevel = 1;
715 break;
716 }
717
718
719 /* From this point on, we can assume that the shortest path is
720 3 letters long and that would be [DriveLetter]:\ */
721
722 /* Check if the path has a wildcard */
723 bHasWildcard = (_tcschr(szSrcPath, _T('*')) != NULL);
724
725 /* If there is no * in the path name and it is a folder then we will
726 need to add a wildcard to the pathname so FindFirstFile comes up
727 with all the files in that folder */
728 if (!bHasWildcard && IsExistingDirectory(szSrcPath))
729 {
730 /* If it doesnt have a \ at the end already then on needs to be added */
731 if (szSrcPath[_tcslen(szSrcPath) - 1] != _T('\\'))
732 _tcscat(szSrcPath, _T("\\"));
733 _tcscat(szSrcPath, _T("*"));
734 bHasWildcard = TRUE;
735 }
736
737 /* If the path ends with '\' add a wildcard at the end */
738 if (szSrcPath[_tcslen(szSrcPath) - 1] == _T('\\'))
739 {
740 _tcscat(szSrcPath, _T("*"));
741 bHasWildcard = TRUE;
742 }
743
744 /* Get a list of all the files */
745 hFile = FindFirstFile(szSrcPath, &findBuffer);
746
747 /* If we could not open the file handle, print out the error */
749 {
750 /* only print source name when more than one file */
751 if (bMultipleSource)
752 ConOutPrintf(_T("%s\n"), szSrcPath);
753
754 ConOutFormatMessage(GetLastError(), szSrcPath);
755 freep(arg);
756 nErrorLevel = 1;
757 return 1;
758 }
759
760 /* Strip the paths back to the folder they are in */
761 for (i = (_tcslen(szSrcPath) - 1); i > -1; i--)
762 {
763 if (szSrcPath[i] != _T('\\'))
764 szSrcPath[i] = _T('\0');
765 else
766 break;
767 }
768
769 do
770 {
771 /* Check Breaker */
773 {
775 freep(arg);
776 return 1;
777 }
778
779 /* Set the override to yes each new file */
780 nOverwrite = 1;
781
782 /* Ignore the . and .. files */
783 if (!_tcscmp(findBuffer.cFileName, _T(".")) ||
784 !_tcscmp(findBuffer.cFileName, _T("..")) ||
785 findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
786 {
787 continue;
788 }
789
790 /* Copy the base folder over to a tmp string */
791 _tcscpy(tmpDestPath, szDestPath);
792 _tcscat(tmpDestPath, _T("\\"));
793
794 /* Can't put a file into a folder that isn't there */
795 if (_tcscmp(tmpDestPath, _T("\\\\.\\")) &&
796 !IsExistingDirectory(tmpDestPath))
797 {
799 ConOutFormatMessage(GetLastError(), szSrcPath);
800 freep(arg);
801 nErrorLevel = 1;
802 return 1;
803 }
804
805 /* Copy over the destination path name */
806 if (bSrcName)
807 _tcscat(tmpDestPath, findBuffer.cFileName);
808 else
809 {
810 /* If there is no wildcard, use the name the user entered */
811 if ((_tcschr(UseThisName, _T('*')) == NULL) &&
812 (_tcschr(UseThisName, _T('?')) == NULL))
813 {
814 _tcscat(tmpDestPath, UseThisName);
815 }
816 else
817 {
818 TCHAR DoneFile[MAX_PATH];
819
820 BuildFileName(findBuffer.cFileName,
821 UseThisName,
822 DoneFile);
823
824
825 /* Add the filename to the tmp string path */
826 _tcscat(tmpDestPath, DoneFile);
827 }
828 }
829
830 /* Build the string path to the source file */
831 _tcscpy(tmpSrcPath,szSrcPath);
832 _tcscat (tmpSrcPath, findBuffer.cFileName);
833
834 /* Check to see if the file is the same file */
835 if (!bTouch && !_tcscmp(tmpSrcPath, tmpDestPath))
836 {
838
839 nErrorLevel = 1;
840 break;
841 }
842
843 /* only print source name when more than one file */
844 if (bMultipleSource)
845 ConOutPrintf(_T("%s\n"), tmpSrcPath);
846
847 /* Handle any overriding / prompting that needs to be done */
848 if (((!(dwFlags & COPY_NO_PROMPT) && IsExistingFile (tmpDestPath)) || dwFlags & COPY_PROMPT) && !bTouch)
849 nOverwrite = CopyOverwrite(tmpDestPath);
850 if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
851 continue;
852 if (nOverwrite == PROMPT_ALL || (nOverwrite == PROMPT_YES && bAppend))
854
855 /* Tell whether the copy was successful or not */
856 if (copy(tmpSrcPath,tmpDestPath, bAppend, dwFlags, bTouch))
857 {
858 nFiles++;
859 }
860 else
861 {
862 /* print out the error message */
864 ConOutFormatMessage (GetLastError(), szSrcPath);
865 nErrorLevel = 1;
866 }
867
868 /* Loop through all wildcard files */
869 } while (FindNextFile(hFile, &findBuffer));
870
872
873 /* Loop through all files in src string with a + */
874 } while (!bDone);
875
876 /* print out the number of files copied */
877 ConOutResPrintf(STRING_COPY_FILE, bAppend ? 1 : nFiles);
878
879 if (arg != NULL)
880 freep(arg);
881
882 return 0;
883}
884
885#endif /* INCLUDE_CMD_COPY */
static int argc
Definition: ServiceArgs.c:12
#define STRING_ERROR_INVALID_PARAM_FORMAT
Definition: resource.h:5
#define STRING_ERROR_OUT_OF_MEMORY
Definition: resource.h:26
#define STRING_COPY_ERROR1
Definition: resource.h:23
#define STRING_COPY_ERROR3
Definition: resource.h:24
PBATCH_CONTEXT bc
Definition: batch.c:67
INT nErrorLevel
Definition: cmd.c:158
BOOL CheckCtrlBreak(INT)
Definition: misc.c:146
#define BREAK_INPUT
Definition: cmd.h:36
VOID ConOutResPaging(BOOL StartPaging, UINT resID)
Definition: console.c:178
#define ConOutPrintf(szStr,...)
Definition: console.h:41
#define ConErrResPrintf(uID,...)
Definition: console.h:50
@ COPY_VERIFY
Definition: copy.c:42
@ COPY_RESTART
Definition: copy.c:46
@ COPY_SHORTNAME
Definition: copy.c:43
@ COPY_NO_PROMPT
Definition: copy.c:44
@ COPY_DECRYPT
Definition: copy.c:41
@ COPY_BINARY
Definition: copy.c:47
@ COPY_PROMPT
Definition: copy.c:45
@ COPY_ASCII
Definition: copy.c:40
INT copy(TCHAR source[MAX_PATH], TCHAR dest[MAX_PATH], INT append, DWORD lpdwFlags, BOOL bTouch)
Definition: copy.c:51
static INT CopyOverwrite(LPTSTR fn)
Definition: copy.c:285
static void BuildFileName(LPTSTR pszSource, LPTSTR pszTarget, LPTSTR pszOutput)
Definition: copy.c:297
INT cmd_copy(LPTSTR param)
Definition: copy.c:332
#define debugstr_aw
Definition: precomp.h:44
#define STRING_COPY_HELP2
Definition: resource.h:95
#define STRING_COPY_ERROR2
Definition: resource.h:43
#define STRING_COPY_FILE
Definition: resource.h:210
#define STRING_ERROR_INVALID_SWITCH
Definition: resource.h:6
#define STRING_ERROR_PATH_NOT_FOUND
Definition: resource.h:8
#define STRING_ERROR_TOO_MANY_PARAMETERS
Definition: resource.h:7
#define STRING_COPY_HELP1
Definition: resource.h:94
#define STRING_ERROR_REQ_PARAM_MISSING
Definition: resource.h:10
static VOID freep(LPSTR *p)
Definition: cmdcons.c:98
static LPSTR * split(LPSTR s, LPINT args)
Definition: cmdcons.c:163
#define cmd_realloc(ptr, size)
Definition: cmddbg.h:30
#define cmd_free(ptr)
Definition: cmddbg.h:31
#define cmd_alloc(size)
Definition: cmddbg.h:29
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI SetFileTime(IN HANDLE hFile, CONST FILETIME *lpCreationTime OPTIONAL, CONST FILETIME *lpLastAccessTime OPTIONAL, CONST FILETIME *lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:948
BOOL WINAPI GetFileTime(IN HANDLE hFile, OUT LPFILETIME lpCreationTime OPTIONAL, OUT LPFILETIME lpLastAccessTime OPTIONAL, OUT LPFILETIME lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:896
BOOL WINAPI FindClose(HANDLE hFindFile)
Definition: find.c:502
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
BOOL WINAPI SystemTimeToFileTime(IN CONST SYSTEMTIME *lpSystemTime, OUT LPFILETIME lpFileTime)
Definition: time.c:158
VOID WINAPI GetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
Definition: time.c:327
struct _FileName FileName
Definition: fatprocs.h:897
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLdouble GLdouble t
Definition: gl.h:2047
GLsizeiptr size
Definition: glext.h:5919
GLuint res
Definition: glext.h:9613
GLuint buffer
Definition: glext.h:5915
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
GLfloat param
Definition: glext.h:5796
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define _tcscmp
Definition: tchar.h:1424
#define _tcscat
Definition: tchar.h:622
#define _tcscpy
Definition: tchar.h:623
#define _tcsncmp
Definition: tchar.h:1428
#define _tcsncicmp
Definition: tchar.h:1429
#define _tcsncat
Definition: tchar.h:1408
#define _totupper
Definition: tchar.h:1509
#define _tcschr
Definition: tchar.h:1406
static void append(struct dump_context *dc, const void *data, unsigned size)
Definition: minidump.c:397
#define memchr(s, c, n)
Definition: mkisofs.h:875
#define _tcsrchr
Definition: utility.h:116
#define CREATE_ALWAYS
Definition: disk.h:72
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
static PVOID ptr
Definition: dispmode.c:27
static char * dest
Definition: rtl.c:135
_In_ HANDLE hFile
Definition: mswsock.h:90
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define MEM_RELEASE
Definition: nt_native.h:1316
#define GENERIC_WRITE
Definition: nt_native.h:90
#define MEM_COMMIT
Definition: nt_native.h:1313
long LONG
Definition: pedump.c:60
BOOL IsExistingDirectory(IN LPCTSTR pszPath)
Definition: util.c:104
BOOL IsExistingFile(IN LPCTSTR pszPath)
Definition: util.c:98
INT GetRootPath(IN LPCTSTR InPath, OUT LPTSTR OutPath, IN INT size)
Definition: util.c:21
#define ConOutResPrintf(uID,...)
Definition: replace.h:31
#define PROMPT_YES
Definition: replace.h:21
#define ConOutFormatMessage(MessageId,...)
Definition: replace.h:34
#define BUFF_SIZE
Definition: replace.h:26
#define ConOutResPuts(uID)
Definition: replace.h:28
INT FilePromptYNA(UINT resID)
Definition: util.c:110
#define PROMPT_NO
Definition: replace.h:20
#define PROMPT_ALL
Definition: replace.h:22
#define PROMPT_BREAK
Definition: replace.h:23
#define TRACE(s)
Definition: solgame.cpp:4
unsigned char * LPBYTE
Definition: typedefs.h:53
int32_t INT
Definition: typedefs.h:58
#define _T(x)
Definition: vfdio.h:22
static GLenum _GLUfuncptr fn
Definition: wgl_font.c:159
LPVOID NTAPI VirtualAlloc(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD flAllocationType, IN DWORD flProtect)
Definition: virtmem.c:65
BOOL NTAPI VirtualFree(IN LPVOID lpAddress, IN SIZE_T dwSize, IN DWORD dwFreeType)
Definition: virtmem.c:119
#define GetEnvironmentVariable
Definition: winbase.h:3839
#define FILE_END
Definition: winbase.h:115
#define COPY_FILE_RESTARTABLE
Definition: winbase.h:232
#define CopyFileEx
Definition: winbase.h:3767
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GetFileAttributes
Definition: winbase.h:3840
#define SetFileAttributes
Definition: winbase.h:3934
#define DeleteFile
Definition: winbase.h:3789
#define COPY_FILE_ALLOW_DECRYPTED_DESTINATION
Definition: winbase.h:234
#define FindNextFile
Definition: winbase.h:3813
#define FindFirstFile
Definition: winbase.h:3807
#define CreateFile
Definition: winbase.h:3774
#define GetCurrentDirectory
Definition: winbase.h:3830
#define GetFullPathName
Definition: winbase.h:3846
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
void * arg
Definition: msvc.h:10
char TCHAR
Definition: xmlstorage.h:189
CHAR * LPTSTR
Definition: xmlstorage.h:192
#define _tcsstr
Definition: xmlstorage.h:199
#define _tcslen
Definition: xmlstorage.h:198
char CHAR
Definition: xmlstorage.h:175