ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

copy.c
Go to the documentation of this file.
00001 /*
00002  *  COPY.C -- copy internal command.
00003  *
00004  *
00005  *  History:
00006  *
00007  *    01-Aug-98 (Rob Lake z63rrl@morgan.ucs.mun.ca)
00008  *        started
00009  *
00010  *    13-Aug-1998 (John P. Price)
00011  *        fixed memory leak problem in copy function.
00012  *        fixed copy function so it would work with wildcards in the source
00013  *
00014  *    13-Dec-1998 (Eric Kohl)
00015  *        Added COPY command to CMD.
00016  *
00017  *    26-Jan-1998 (Eric Kohl)
00018  *        Replaced CRT io functions by Win32 io functions.
00019  *
00020  *    27-Oct-1998 (Eric Kohl)
00021  *        Disabled prompting when used in batch mode.
00022  *
00023  *    03-Apr-2005 (Magnus Olsen) <magnus@greatlord.com>)
00024  *        Remove all hardcode string to En.rc
00025  *
00026  *    13-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
00027  *        Rewrite to clean up copy and support wildcard.
00028  *
00029  *    20-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
00030  *        Add touch syntax.  "copy arp.exe+,,"
00031  *        Copy command is now completed.
00032  */
00033 
00034 #include <precomp.h>
00035 
00036 #ifdef INCLUDE_CMD_COPY
00037 
00038 enum
00039 {
00040     COPY_ASCII       = 0x001,   /* /A  */
00041     COPY_DECRYPT     = 0x004,   /* /D  */
00042     COPY_VERIFY      = 0x008,   /* /V  : Dummy, Never will be Impleneted */
00043     COPY_SHORTNAME   = 0x010,   /* /N  : Dummy, Never will be Impleneted */
00044     COPY_NO_PROMPT   = 0x020,   /* /Y  */
00045     COPY_PROMPT      = 0x040,   /* /-Y */
00046     COPY_RESTART     = 0x080,   /* /Z  */
00047     COPY_BINARY      = 0x100,   /* /B  */
00048 };
00049 
00050 INT
00051 copy(TCHAR source[MAX_PATH],
00052      TCHAR dest[MAX_PATH],
00053      INT append,
00054      DWORD lpdwFlags,
00055      BOOL bTouch)
00056 {
00057     FILETIME srctime,NewFileTime;
00058     HANDLE hFileSrc;
00059     HANDLE hFileDest;
00060     LPBYTE buffer;
00061     DWORD  dwAttrib;
00062     DWORD  dwRead;
00063     DWORD  dwWritten;
00064     BOOL   bEof = FALSE;
00065     TCHAR TrueDest[MAX_PATH];
00066     TCHAR TempSrc[MAX_PATH];
00067     TCHAR * FileName;
00068     SYSTEMTIME CurrentTime;
00069 
00070     /* Check Breaker */
00071     if(CheckCtrlBreak(BREAK_INPUT))
00072         return 0;
00073 
00074     TRACE ("checking mode\n");
00075 
00076     if(bTouch)
00077     {
00078         hFileSrc = CreateFile (source, GENERIC_WRITE, FILE_SHARE_READ,
00079             NULL, OPEN_EXISTING, 0, NULL);
00080         if (hFileSrc == INVALID_HANDLE_VALUE)
00081         {
00082             ConOutResPrintf(STRING_COPY_ERROR1, source);
00083             nErrorLevel = 1;
00084             return 0;
00085         }
00086 
00087         GetSystemTime(&CurrentTime);
00088         SystemTimeToFileTime(&CurrentTime, &NewFileTime);
00089         if(SetFileTime(hFileSrc,(LPFILETIME) NULL, (LPFILETIME) NULL, &NewFileTime))
00090         {
00091             CloseHandle(hFileSrc);
00092             nErrorLevel = 1;
00093             return 1;
00094 
00095         }
00096         else
00097         {
00098             CloseHandle(hFileSrc);
00099             return 0;
00100         }
00101     }
00102 
00103     dwAttrib = GetFileAttributes (source);
00104 
00105     hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ,
00106         NULL, OPEN_EXISTING, 0, NULL);
00107     if (hFileSrc == INVALID_HANDLE_VALUE)
00108     {
00109         ConOutResPrintf(STRING_COPY_ERROR1, source);
00110         nErrorLevel = 1;
00111         return 0;
00112     }
00113 
00114     TRACE ("getting time\n");
00115 
00116     GetFileTime (hFileSrc, &srctime, NULL, NULL);
00117 
00118     TRACE ("copy: flags has %s\n",
00119         lpdwFlags & COPY_ASCII ? "ASCII" : "BINARY");
00120 
00121     /* Check to see if /D or /Z are true, if so we need a middle
00122        man to copy the file too to allow us to use CopyFileEx later */
00123     if(lpdwFlags & COPY_DECRYPT)
00124     {
00125         GetEnvironmentVariable(_T("TEMP"),TempSrc,MAX_PATH);
00126         _tcscat(TempSrc,_T("\\"));
00127         FileName = _tcsrchr(source,_T('\\'));
00128         FileName++;
00129         _tcscat(TempSrc,FileName);
00130         /* This is needed to be on the end to prevent an error
00131            if the user did "copy /D /Z foo bar then it would be copied
00132            too %TEMP%\foo here and when %TEMP%\foo when it sets it up
00133            for COPY_RESTART, this would mean it is copying to itself
00134            which would error when it tried to open the handles for ReadFile
00135            and WriteFile */
00136         _tcscat(TempSrc,_T(".decrypt"));
00137         if(!CopyFileEx(source, TempSrc, NULL, NULL, FALSE, COPY_FILE_ALLOW_DECRYPTED_DESTINATION))
00138         {
00139             nErrorLevel = 1;
00140             return 0;
00141         }
00142         _tcscpy(source, TempSrc);
00143     }
00144 
00145 
00146     if(lpdwFlags & COPY_RESTART)
00147     {
00148         _tcscpy(TrueDest, dest);
00149         GetEnvironmentVariable(_T("TEMP"),dest,MAX_PATH);
00150         _tcscat(dest,_T("\\"));
00151         FileName = _tcsrchr(TrueDest,_T('\\'));
00152         FileName++;
00153         _tcscat(dest,FileName);
00154     }
00155 
00156 
00157     if (!IsExistingFile (dest))
00158     {
00159         TRACE ("opening/creating\n");
00160         hFileDest =
00161             CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
00162     }
00163     else if (!append)
00164     {
00165         TRACE ("SetFileAttributes (%s, FILE_ATTRIBUTE_NORMAL);\n", debugstr_aw(dest));
00166         SetFileAttributes (dest, FILE_ATTRIBUTE_NORMAL);
00167 
00168         TRACE ("DeleteFile (%s);\n", debugstr_aw(dest));
00169         DeleteFile (dest);
00170 
00171         hFileDest = CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
00172     }
00173     else
00174     {
00175         LONG lFilePosHigh = 0;
00176 
00177         if (!_tcscmp (dest, source))
00178         {
00179             CloseHandle (hFileSrc);
00180             return 0;
00181         }
00182 
00183         TRACE ("opening/appending\n");
00184         SetFileAttributes (dest, FILE_ATTRIBUTE_NORMAL);
00185 
00186         hFileDest =
00187             CreateFile (dest, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
00188 
00189         /* Move to end of file to start writing */
00190         SetFilePointer (hFileDest, 0, &lFilePosHigh,FILE_END);
00191     }
00192 
00193 
00194     if (hFileDest == INVALID_HANDLE_VALUE)
00195     {
00196         CloseHandle (hFileSrc);
00197         ConOutResPuts(STRING_ERROR_PATH_NOT_FOUND);
00198         nErrorLevel = 1;
00199         return 0;
00200     }
00201 
00202     /* A page-aligned buffer usually give more speed */
00203     buffer = (LPBYTE)VirtualAlloc(NULL, BUFF_SIZE, MEM_COMMIT, PAGE_READWRITE);
00204     if (buffer == NULL)
00205     {
00206         CloseHandle (hFileDest);
00207         CloseHandle (hFileSrc);
00208         ConOutResPuts(STRING_ERROR_OUT_OF_MEMORY);
00209         nErrorLevel = 1;
00210         return 0;
00211     }
00212 
00213     do
00214     {
00215         ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL);
00216         if (lpdwFlags & COPY_ASCII)
00217         {
00218             LPBYTE pEof = memchr(buffer, 0x1A, dwRead);
00219             if (pEof != NULL)
00220             {
00221                 bEof = TRUE;
00222                 dwRead = pEof-buffer+1;
00223                 break;
00224             }
00225         }
00226 
00227         if (dwRead == 0)
00228             break;
00229 
00230         WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL);
00231         if (dwWritten != dwRead || CheckCtrlBreak(BREAK_INPUT))
00232         {
00233             ConOutResPuts(STRING_COPY_ERROR3);
00234 
00235             VirtualFree (buffer, 0, MEM_RELEASE);
00236             CloseHandle (hFileDest);
00237             CloseHandle (hFileSrc);
00238             nErrorLevel = 1;
00239             return 0;
00240         }
00241     }
00242     while (!bEof);
00243 
00244     TRACE ("setting time\n");
00245     SetFileTime (hFileDest, &srctime, NULL, NULL);
00246 
00247     if ((lpdwFlags & COPY_ASCII) && !bEof)
00248     {
00249         /* we're dealing with ASCII files! */
00250         buffer[0] = 0x1A;
00251         TRACE ("appending ^Z\n");
00252         WriteFile (hFileDest, buffer, sizeof(CHAR), &dwWritten, NULL);
00253     }
00254 
00255     VirtualFree (buffer, 0, MEM_RELEASE);
00256     CloseHandle (hFileDest);
00257     CloseHandle (hFileSrc);
00258 
00259     TRACE ("setting mode\n");
00260     SetFileAttributes (dest, dwAttrib);
00261 
00262     /* Now finish off the copy if needed with CopyFileEx */
00263     if(lpdwFlags & COPY_RESTART)
00264     {
00265         if(!CopyFileEx(dest, TrueDest, NULL, NULL, FALSE, COPY_FILE_RESTARTABLE))
00266         {
00267             nErrorLevel = 1;
00268             DeleteFile(dest);
00269             return 0;
00270         }
00271         /* Take care of file in the temp folder */
00272         DeleteFile(dest);
00273 
00274     }
00275 
00276     if(lpdwFlags & COPY_DECRYPT)
00277         DeleteFile(TempSrc);
00278 
00279     return 1;
00280 }
00281 
00282 
00283 static INT CopyOverwrite (LPTSTR fn)
00284 {
00285     /*ask the user if they want to override*/
00286     INT res;
00287     ConOutResPrintf(STRING_COPY_HELP1, fn);
00288     res = FilePromptYNA (0);
00289     return res;
00290 }
00291 
00292 /* The following lines of copy were written by someone else
00293 (most likely Eric Kohl) and it was taken from ren.c */
00294 static void
00295 BuildFileName(
00296     LPTSTR pszSource,
00297     LPTSTR pszTarget,
00298     LPTSTR pszOutput)
00299 {
00300     /* build destination file name */
00301     while (*pszTarget != 0)
00302     {
00303         if (*pszTarget == _T('*'))
00304         {
00305             pszTarget++;
00306             while ((*pszSource != 0) && (*pszSource != *pszTarget))
00307             {
00308                 *pszOutput++ = *pszSource++;
00309             }
00310         }
00311         else if (*pszTarget == _T('?'))
00312         {
00313             pszTarget++;
00314             if (*pszSource != 0)
00315             {
00316                 *pszOutput++ = *pszSource++;
00317             }
00318         }
00319         else
00320         {
00321             *pszOutput++ = *pszTarget++;
00322             if (*pszSource != 0)
00323                 pszSource++;
00324         }
00325     }
00326 
00327     *pszOutput = 0;
00328 }
00329 
00330 INT cmd_copy(LPTSTR param)
00331 {
00332     LPTSTR *arg;
00333     INT argc, i, nFiles, nOverwrite = 0, nSrc = -1, nDes = -1;
00334     /* this is the path up to the folder of the src and dest ie C:\windows\ */
00335     TCHAR szDestPath[MAX_PATH];
00336     TCHAR szSrcPath[MAX_PATH];
00337     DWORD dwFlags = 0;
00338     /* If this is the type of copy where we are adding files */
00339     BOOL bAppend = FALSE;
00340     WIN32_FIND_DATA findBuffer;
00341     HANDLE hFile = NULL;
00342     BOOL bTouch = FALSE;
00343     /* Used when something like "copy c*.exe d*.exe" during the process of
00344        figuring out the new name */
00345     /* Pointer to keep track of how far through the append input(file1+file2+file3) we are */
00346     TCHAR  * appendPointer = _T("\0");
00347     /* The full path to src and dest.  This has drive letter, folders, and filename */
00348     TCHAR tmpDestPath[MAX_PATH];
00349     TCHAR tmpSrcPath[MAX_PATH];
00350     /* A bool on weather or not the destination name will be taking from the input */
00351     BOOL bSrcName = FALSE;
00352     /* Seems like a waste but it is a pointer used to copy from input to PreserveName */
00353     TCHAR * UseThisName;
00354     /* for CMDCOPY env */
00355     TCHAR *evar;
00356     int size;
00357     TCHAR * szTouch;
00358     BOOL bHasWildcard, bDone = FALSE, bMoreFiles = FALSE;
00359     BOOL bMultipleSource = FALSE, bMultipleDest = FALSE;
00360 
00361 
00362     /* Show help/usage info */
00363     if (!_tcsncmp(param, _T("/?"), 2))
00364     {
00365         ConOutResPaging(TRUE, STRING_COPY_HELP2);
00366         return 0;
00367     }
00368 
00369     nErrorLevel = 0;
00370 
00371     /* Get the envor value if it exists */
00372     evar = cmd_alloc(512 * sizeof(TCHAR));
00373     if (evar == NULL)
00374         size = 0;
00375     else
00376         size = GetEnvironmentVariable (_T("COPYCMD"), evar, 512);
00377 
00378     if (size > 512)
00379     {
00380         evar = cmd_realloc(evar,size * sizeof(TCHAR) );
00381         if (evar!=NULL)
00382             size = GetEnvironmentVariable (_T("COPYCMD"), evar, size);
00383         else
00384             size=0;
00385     }
00386 
00387     /* check see if we did get any env variable */
00388     if (size != 0)
00389     {
00390         int t = 0;
00391 
00392         /* scan and set the flags */
00393         for (t = 0; t < size; t++)
00394         {
00395             if (_tcsncicmp(_T("/A"),&evar[t],2) == 0)
00396             {
00397                 dwFlags |=COPY_ASCII;
00398                 t++;
00399             }
00400             else if (_tcsncicmp(_T("/B"),&evar[t],2) == 0)
00401             {
00402                 dwFlags |= COPY_BINARY;
00403                 t++;
00404             }
00405             else if (_tcsncicmp(_T("/D"),&evar[t],2) == 0)
00406             {
00407                 dwFlags |= COPY_DECRYPT;
00408                 t++;
00409             }
00410             else if (_tcsncicmp(_T("/V"),&evar[t],2) == 0)
00411             {
00412                 dwFlags |= COPY_VERIFY;
00413                 t++;
00414             }
00415             else if (_tcsncicmp(_T("/N"),&evar[t],2) == 0)
00416             {
00417                 dwFlags |= COPY_SHORTNAME;
00418                 t++;
00419             }
00420             else if (_tcsncicmp(_T("/Y"),&evar[t],2) == 0)
00421             {
00422                 dwFlags |= COPY_NO_PROMPT;
00423                 t++;
00424             }
00425             else if (_tcsncicmp(_T("/-Y"),&evar[t],3) == 0)
00426             {
00427                 dwFlags |= COPY_PROMPT;
00428                 t+=2;
00429             }
00430             else if (_tcsncicmp(_T("/Z"),&evar[t],2) == 0)
00431             {
00432                 dwFlags |= COPY_PROMPT;
00433                 t++;
00434             }
00435         }
00436     }
00437     cmd_free(evar);
00438 
00439 
00440     /* Split the user input into array */
00441     arg = split(param, &argc, FALSE, TRUE);
00442     nFiles = argc;
00443 
00444     /* Read switches and count files */
00445     for (i = 0; i < argc; i++)
00446     {
00447         if (*arg[i] == _T('/'))
00448         {
00449             if (_tcslen(arg[i]) >= 2)
00450             {
00451                 switch (_totupper(arg[i][1]))
00452                 {
00453                     case _T('A'):
00454                         dwFlags |= COPY_ASCII;
00455                         break;
00456 
00457                     case _T('B'):
00458                         dwFlags |= COPY_BINARY;
00459                         break;
00460 
00461                     case _T('D'):
00462                         dwFlags |= COPY_DECRYPT;
00463                         break;
00464 
00465                     case _T('V'):
00466                         dwFlags |= COPY_VERIFY;
00467                         break;
00468 
00469                     case _T('N'):
00470                         dwFlags |= COPY_SHORTNAME;
00471                         break;
00472 
00473                     case _T('Y'):
00474                         dwFlags |= COPY_NO_PROMPT;
00475                         dwFlags &= ~COPY_PROMPT;
00476                         break;
00477 
00478                     case _T('-'):
00479                         if(_tcslen(arg[i]) >= 3)
00480                             if(_totupper(arg[i][2]) == _T('Y'))
00481                             {
00482                                 dwFlags &= ~COPY_NO_PROMPT;
00483                                 dwFlags |= COPY_PROMPT;
00484                             }
00485 
00486                             break;
00487 
00488                     case _T('Z'):
00489                         dwFlags |= COPY_RESTART;
00490                         break;
00491 
00492                     default:
00493                         /* Invalid switch */
00494                         ConOutResPrintf(STRING_ERROR_INVALID_SWITCH, _totupper(arg[i][1]));
00495                         nErrorLevel = 1;
00496                         freep (arg);
00497                         return 1;
00498                         break;
00499                 }
00500             }
00501             /* If it was a switch, subtract from total arguments */
00502             nFiles--;
00503         }
00504         else
00505         {
00506             /* If it isn't a switch then it is the source or destination */
00507             if (nSrc == -1)
00508             {
00509                 nSrc = i;
00510             }
00511             else if (*arg[i] == _T('+'))
00512             {
00513                 /* Next file should be appended */
00514                 bMoreFiles = TRUE;
00515                 nFiles -= 1;
00516             }
00517             else if (bMoreFiles)
00518             {
00519                 /* Add this file to the source string
00520                    this way we can do all checks
00521                     directly on source string later on */
00522                 TCHAR * ptr;
00523                 int length = (_tcslen(arg[nSrc]) + _tcslen(arg[i]) + 2) * sizeof(TCHAR);
00524                 ptr = cmd_alloc(length);
00525                 if (ptr)
00526                 {
00527                     _tcscpy(ptr, arg[nSrc]);
00528                     _tcscat(ptr, _T("|"));
00529                     _tcscat(ptr, arg[i]);
00530                     cmd_free(arg[nSrc]);
00531                     arg[nSrc] = ptr;
00532                     nFiles -= 1;
00533                 }
00534 
00535                 bMoreFiles = FALSE;
00536             }
00537             else if(nDes == -1)
00538             {
00539                 nDes = i;
00540             }
00541         }
00542     }
00543 
00544     /* keep quiet within batch files */
00545     if (bc != NULL)
00546     {
00547         dwFlags |= COPY_NO_PROMPT;
00548         dwFlags &= ~COPY_PROMPT;
00549     }
00550 
00551     if (nFiles < 1)
00552     {
00553         /* There are not enough files, there has to be at least 1 */
00554         ConOutResPuts(STRING_ERROR_REQ_PARAM_MISSING);
00555         freep(arg);
00556         return 1;
00557     }
00558 
00559     if (nFiles > 2)
00560     {
00561         /* There are too many file names in command */
00562         ConErrResPrintf(STRING_ERROR_TOO_MANY_PARAMETERS,_T(""));
00563         nErrorLevel = 1;
00564         freep(arg);
00565         return 1;
00566     }
00567 
00568     if ((_tcschr(arg[nSrc], _T('|')) != NULL) ||
00569         (_tcschr(arg[nSrc], _T('*')) != NULL) ||
00570         (_tcschr(arg[nSrc], _T('?')) != NULL) ||
00571         IsExistingDirectory(arg[nSrc]))
00572     {
00573         bMultipleSource = TRUE;
00574     }
00575 
00576     /* Reusing the number of files variable */
00577     nFiles = 0;
00578 
00579     /* Check if no destination argument is passed */
00580     if (nDes == -1)
00581     {
00582         /* If no destination was entered then just use
00583         the current directory as the destination */
00584         GetCurrentDirectory(MAX_PATH, szDestPath);
00585     }
00586     else
00587     {
00588         /* Check if the destination is 'x:' */
00589         if ((arg[nDes][1] == _T(':')) && (arg[nDes][2] == _T('\0')))
00590         {
00591             GetRootPath(arg[nDes], szDestPath, MAX_PATH);
00592         }
00593         else
00594         {
00595             /* If the user entered two file names then form the full string path */
00596             GetFullPathName(arg[nDes], MAX_PATH, szDestPath, NULL);
00597         }
00598 
00599         /* Make sure there is an ending slash to the path if the dest is a folder */
00600         if ((_tcschr(szDestPath, _T('*')) == NULL) &&
00601             IsExistingDirectory(szDestPath))
00602         {
00603             bMultipleDest = TRUE;
00604             if (szDestPath[_tcslen(szDestPath) -  1] != _T('\\'))
00605                 _tcscat(szDestPath, _T("\\"));
00606         }
00607 
00608         /* Check if the destination uses wildcards */
00609         if ((_tcschr(arg[nDes], _T('*')) != NULL) ||
00610             (_tcschr(arg[nDes], _T('?')) != NULL))
00611         {
00612             bMultipleDest = TRUE;
00613         }
00614     }
00615 
00616     if (nDes != -1) /* you can only append files when there is a destination */
00617     {
00618         if (bMultipleSource && !bMultipleDest)
00619         {
00620             /* We have multiple source files, but not multiple destination
00621                files. This means we are appending the soruce files. */
00622             bAppend = TRUE;
00623             if (_tcschr(arg[nSrc], _T('|')) != NULL)
00624                 appendPointer = arg[nSrc];
00625         }
00626     }
00627 
00628     /* Save the name the user entered */
00629     UseThisName = _tcsrchr(szDestPath,_T('\\'));
00630     if (UseThisName)
00631     {
00632         /* Split the name from the path */
00633         *UseThisName++ = _T('\0');
00634 
00635         /* Check if the dest path ends with '\*' or '\' */
00636         if (((UseThisName[0] == _T('*')) && (UseThisName[1] == _T('\0'))) ||
00637             (UseThisName[0] == _T('\0')))
00638         {
00639             /* In this case we will be using the same name as the source file
00640             for the destination file because destination is a folder */
00641             bSrcName = TRUE;
00642             UseThisName = NULL;
00643         }
00644     }
00645     else
00646     {
00647         /* Something's seriously wrong! */
00648         UseThisName = szDestPath;
00649     }
00650 
00651     do
00652     {
00653         /* Get the full string of the path to the source file */
00654         if (_tcschr(arg[nSrc], _T('|')) != NULL)
00655         {
00656             /* Reset the source path */
00657             szSrcPath[0] = _T('\0');
00658 
00659             /* Loop through the source file name and copy all
00660             the chars one at a time until it gets too + */
00661             while(TRUE)
00662             {
00663                 if (appendPointer[0] == _T('|'))
00664                 {
00665                     /* Skip the | and go to the next file name */
00666                     appendPointer++;
00667                     break;
00668                 }
00669                 else if (appendPointer[0] == _T('\0'))
00670                 {
00671                     bDone = TRUE;
00672                     break;
00673                 }
00674 
00675                 _tcsncat(szSrcPath, appendPointer, 1);
00676                 appendPointer++;
00677             }
00678 
00679             if (_tcschr(arg[nSrc], _T(',')) != NULL)
00680             {
00681                 /* Only time there is a , in the source is when they are using touch
00682                    Cant have a destination and can only have on ,, at the end of the string
00683                     Cant have more then one file name */
00684                 szTouch = _tcsstr(arg[nSrc], _T("|"));
00685                 if (_tcsncmp(szTouch,_T("|,,\0"), 4) || (nDes != -1))
00686                 {
00687                     ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT,arg[nSrc]);
00688                     nErrorLevel = 1;
00689                     freep (arg);
00690                     return 1;
00691                 }
00692                 bTouch = TRUE;
00693                 bDone = TRUE;
00694             }
00695         }
00696         else
00697         {
00698             bDone = TRUE;
00699             _tcscpy(szSrcPath, arg[nSrc]);
00700         }
00701 
00702         /* "x:" is not a valid source path format. */
00703         if ((szSrcPath[1] == _T(':')) && (szSrcPath[2] == _T('\0')))
00704         {
00705             ConOutPrintf(_T("%s\n"), szSrcPath);
00706             ConOutFormatMessage(ERROR_FILE_NOT_FOUND, szSrcPath);
00707             nErrorLevel = 1;
00708             break;
00709         }
00710 
00711 
00712         /* From this point on, we can assume that the shortest path is 3 letters long
00713         and that would be [DriveLetter]:\ */
00714 
00715         /* Check if the path has a wildcard */
00716         bHasWildcard = (_tcschr(szSrcPath, _T('*')) != NULL);
00717 
00718         /* If there is no * in the path name and it is a folder then we will
00719            need to add a wildcard to the pathname so FindFirstFile comes up
00720            with all the files in that folder */
00721         if (!bHasWildcard && IsExistingDirectory(szSrcPath))
00722         {
00723             /* If it doesnt have a \ at the end already then on needs to be added */
00724             if (szSrcPath[_tcslen(szSrcPath) -  1] != _T('\\'))
00725                 _tcscat(szSrcPath, _T("\\"));
00726             _tcscat(szSrcPath, _T("*"));
00727             bHasWildcard = TRUE;
00728         }
00729 
00730         /* If the path ends with '\' add a wildcard at the end */
00731         if (szSrcPath[_tcslen(szSrcPath) -  1] == _T('\\'))
00732         {
00733             _tcscat(szSrcPath, _T("*"));
00734             bHasWildcard = TRUE;
00735         }
00736 
00737         /* Get a list of all the files */
00738         hFile = FindFirstFile(szSrcPath, &findBuffer);
00739 
00740         /* If it couldnt open the file handle, print out the error */
00741         if (hFile == INVALID_HANDLE_VALUE)
00742         {
00743             /* only print source name when more then one file */
00744             if (bMultipleSource)
00745                 ConOutPrintf(_T("%s\n"), szSrcPath);
00746 
00747             ConOutFormatMessage(GetLastError(), szSrcPath);
00748             freep(arg);
00749             nErrorLevel = 1;
00750             return 1;
00751         }
00752 
00753         /* Strip the paths back to the folder they are in */
00754         for (i = (_tcslen(szSrcPath) -  1); i > -1; i--)
00755             if (szSrcPath[i] != _T('\\'))
00756                 szSrcPath[i] = _T('\0');
00757             else
00758                 break;
00759 
00760         do
00761         {
00762             /* Check Breaker */
00763             if (CheckCtrlBreak(BREAK_INPUT))
00764             {
00765                 freep(arg);
00766                 return 1;
00767             }
00768 
00769             /* Set the override to yes each new file */
00770             nOverwrite = 1;
00771 
00772             /* Ignore the . and .. files */
00773             if (!_tcscmp(findBuffer.cFileName, _T("."))  ||
00774                 !_tcscmp(findBuffer.cFileName, _T("..")) ||
00775                 findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
00776             {
00777                 continue;
00778             }
00779 
00780             /* Copy the base folder over to a tmp string */
00781             _tcscpy(tmpDestPath, szDestPath);
00782             _tcscat(tmpDestPath, _T("\\"));
00783 
00784             /* Can't put a file into a folder that isnt there */
00785             if (_tcscmp(tmpDestPath, _T("\\\\.\\")) &&
00786                 !IsExistingDirectory(tmpDestPath))
00787             {
00788                 ConOutFormatMessage(GetLastError(), szSrcPath);
00789                 freep(arg);
00790                 nErrorLevel = 1;
00791                 return 1;
00792             }
00793 
00794             /* Copy over the destination path name */
00795             if (bSrcName)
00796                 _tcscat(tmpDestPath, findBuffer.cFileName);
00797             else
00798             {
00799                 /* If there is no wildcard you can use the name the user entered */
00800                 if ((_tcschr(UseThisName, _T('*')) == NULL) &&
00801                     (_tcschr(UseThisName, _T('?')) == NULL))
00802                 {
00803                     _tcscat(tmpDestPath, UseThisName);
00804                 }
00805                 else
00806                 {
00807                     TCHAR DoneFile[MAX_PATH];
00808 
00809                     BuildFileName(findBuffer.cFileName,
00810                                   UseThisName,
00811                                   DoneFile);
00812 
00813 
00814                     /* Add the filename to the tmp string path */
00815                     _tcscat(tmpDestPath, DoneFile);
00816                 }
00817             }
00818 
00819             /* Build the string path to the source file */
00820             _tcscpy(tmpSrcPath,szSrcPath);
00821             _tcscat (tmpSrcPath, findBuffer.cFileName);
00822 
00823             /* Check to see if the file is the same file */
00824             if(!bTouch && !_tcscmp(tmpSrcPath, tmpDestPath))
00825             {
00826                 ConOutResPrintf(STRING_COPY_ERROR2);
00827 
00828                 nErrorLevel = 1;
00829                 break;
00830             }
00831 
00832             /* only print source name when more then one file */
00833             if (bMultipleSource)
00834                 ConOutPrintf(_T("%s\n"), tmpSrcPath);
00835 
00836             /* Handle any overriding / prompting that needs to be done */
00837             if (((!(dwFlags & COPY_NO_PROMPT) && IsExistingFile (tmpDestPath)) || dwFlags & COPY_PROMPT) && !bTouch)
00838                 nOverwrite = CopyOverwrite(tmpDestPath);
00839             if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
00840                 continue;
00841             if (nOverwrite == PROMPT_ALL || (nOverwrite == PROMPT_YES && bAppend))
00842                 dwFlags |= COPY_NO_PROMPT;
00843 
00844             /* Tell weather the copy was successful or not */
00845             if(copy(tmpSrcPath,tmpDestPath, bAppend, dwFlags, bTouch))
00846             {
00847                 nFiles++;
00848                 //LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
00849             }
00850             else
00851             {
00852                 /* print out the error message */
00853                 ConOutResPrintf(STRING_COPY_ERROR3);
00854                 ConOutFormatMessage (GetLastError(), szSrcPath);
00855                 nErrorLevel = 1;
00856             }
00857 
00858         /* Loop through all wildcard files */
00859         } while (FindNextFile(hFile, &findBuffer));
00860 
00861     /* Loop through all files in src string with a + */
00862     } while(!bDone);
00863 
00864     /* print out the number of files copied */
00865     ConOutResPrintf(STRING_COPY_FILE, bAppend ? 1 : nFiles);
00866 
00867     if (hFile) FindClose(hFile);
00868 
00869     if (arg != NULL)
00870         freep(arg);
00871 
00872     return 0;
00873 }
00874 
00875 #endif /* INCLUDE_CMD_COPY */

Generated on Sun May 27 2012 04:18:11 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.