Brandon Turner turnerb7@msu.edu Rewrite to clean up copy and support wildcard. and alot of other small bugfix, like does not crash when a file does not exists. Modified: trunk/reactos/subsys/system/cmd/copy.c _____
Modified: trunk/reactos/subsys/system/cmd/copy.c --- trunk/reactos/subsys/system/cmd/copy.c 2005-07-14 00:27:53 UTC (rev 16560) +++ trunk/reactos/subsys/system/cmd/copy.c 2005-07-14 14:51:35 UTC (rev 16561) @@ -22,321 +22,32 @@
* * 03-Apr-2005 (Magnus Olsen) magnus@greatlord.com) * Remove all hardcode string to En.rc + * + * 13-Jul-2005 (Brandon Turner) turnerb7@msu.edu) + * Rewrite to clean up copy and support wildcard. */ - + #include <precomp.h> #include "resource.h" - + #ifdef INCLUDE_CMD_COPY - - -#define VERIFY 1 /* VERIFY Switch */ -#define BINARY 2 /* File is to be copied as BINARY */ -#define ASCII 4 /* File is to be copied as ASCII */ -#define PROMPT 8 /* Prompt before overwriting files */ -#define NPROMPT 16 /* Do not prompt before overwriting files */ -#define HELP 32 /* Help was asked for */ -#define SOURCE 128 /* File is a source */ - - -typedef struct tagFILES + +enum { - struct tagFILES *next; - TCHAR szFile[MAX_PATH]; - DWORD dwFlag; /* BINARY -xor- ASCII */ -} FILES, *LPFILES; - - -static BOOL DoSwitches (LPTSTR, LPDWORD); -static BOOL AddFile (LPFILES, TCHAR *, int *, int *, LPDWORD); -static BOOL AddFiles (LPFILES, TCHAR *, int *, int *, int *, LPDWORD); -static BOOL GetDestination (LPFILES, LPFILES); -static INT ParseCommand (LPFILES, int, TCHAR **, LPDWORD); -static VOID DeleteFileList (LPFILES); -static INT Overwrite (LPTSTR); - - -static BOOL -DoSwitches (LPTSTR arg, LPDWORD lpdwFlags) -{ - if (!_tcsicmp (arg, _T("/-Y"))) - { - *lpdwFlags |= PROMPT; - *lpdwFlags &= ~NPROMPT; - return TRUE; - } - else if (_tcslen (arg) > 2) - { - error_too_many_parameters (_T("")); - return FALSE; - } - - switch (_totupper (arg[1])) - { - case _T('V'): - *lpdwFlags |= VERIFY; - break; - - case _T('A'): - *lpdwFlags |= ASCII; - *lpdwFlags &= ~BINARY; - break; - - case _T('B'): - *lpdwFlags |= BINARY; - *lpdwFlags &= ~ASCII; - break; - - case _T('Y'): - *lpdwFlags &= ~PROMPT; - *lpdwFlags |= NPROMPT; - break; - - default: - error_invalid_switch (arg[1]); - return FALSE; - } - return TRUE; -} - - -static BOOL -AddFile (LPFILES f, TCHAR *arg, int *source, int *dest, LPDWORD flags) -{ - if (*dest) - { - error_too_many_parameters (_T("")); - return FALSE; - } - if (*source) - { - *dest = 1; - f->dwFlag = 0; - } - else - { - *source = 1; - f->dwFlag = SOURCE; - } - _tcscpy(f->szFile, arg); - f->dwFlag |= *flags & ASCII ? ASCII : BINARY; - if ((f->next = (LPFILES)malloc (sizeof (FILES))) == NULL) - { - error_out_of_memory (); - return FALSE; - } - f = f->next; - f->dwFlag = 0; - f->next = NULL; - return TRUE; -} - - -static BOOL -AddFiles (LPFILES f, TCHAR *arg, int *source, int *dest, - int *count, LPDWORD flags) -{ - TCHAR t[128]; - int j; - int k; - - if (*dest) - { - error_too_many_parameters (_T("")); - return FALSE; - } - - j = 0; - k = 0; - - while (arg[j] == _T('+')) - j++; - - while (arg[j] != _T('\0')) - { - t[k] = arg[j++]; - if (t[k] == '+' || arg[j] == _T('\0')) - { - if (!k) - continue; - if (arg[j] == _T('\0') && t[k] != _T('+')) - k++; - t[k] = _T('\0'); - *count += 1; - _tcscpy (f->szFile, t); - *source = 1; - if (*flags & ASCII) - f->dwFlag |= *flags | SOURCE | ASCII; - else - f->dwFlag |= *flags | BINARY | SOURCE; - - if ((f->next = (LPFILES)malloc (sizeof (FILES))) == NULL) - { - error_out_of_memory (); - return FALSE; - } - f = f->next; - f->next = NULL; - k = 0; - f->dwFlag = 0; - continue; - } - k++; - } - - if (arg[--j] == _T('+')) - *source = 0; - - return 1; -} - - -static BOOL -GetDestination (LPFILES f, LPFILES dest) -{ - LPFILES p = NULL; - LPFILES start = f; - - while (f->next != NULL) - { - p = f; - f = f->next; - } - - f = p; - - if ((f->dwFlag & SOURCE) == 0) - { - free (p->next); - p->next = NULL; - _tcscpy (dest->szFile, f->szFile); - dest->dwFlag = f->dwFlag; - dest->next = NULL; - f = start; - return TRUE; - } - - return FALSE; -} - - -static INT -ParseCommand (LPFILES f, int argc, TCHAR **arg, LPDWORD lpdwFlags) -{ - INT i; - INT dest; - INT source; - INT count; - TCHAR temp[128]; - dest = 0; - source = 0; - count = 0; - - - - /* hack geting pipe 1>null working */ - for (i = 0; i < argc; i++) - { - if (arg[i][0] != _T('/')) - count++; - } - if (count==3) argc=2; - /* end hack */ - - - - for (i = 0; i < argc; i++) - { - - if (arg[i][0] == _T('/')) - { - if (!DoSwitches (arg[i], lpdwFlags)) - return -1; - } - else - { - if (!_tcscmp(arg[i], _T("+"))) - source = 0; - else if (!_tcschr(arg[i], _T('+')) && source) - { - -// Make sure we have a clean workable path - - GetFullPathName( arg[i], 128, (LPTSTR) &temp, NULL); -// printf("A Input %s, Output %s\n", arg[i], temp); - - if (!AddFile(f, (TCHAR *) &temp, &source, &dest, lpdwFlags)) - return -1; - f = f->next; - count++; - } - else - { - - GetFullPathName( arg[i], 128, (LPTSTR) &temp, NULL); -// printf("B Input %s, Output %s\n", arg[i], temp); - - if (!AddFiles(f, (TCHAR *) &temp, &source, &dest, &count, lpdwFlags)) - return -1; - while (f->next != NULL) - f = f->next; - } - } - } - -#ifdef _DEBUG - DebugPrintf (_T("ParseCommand: flags has %s\n"), - *lpdwFlags & ASCII ? _T("ASCII") : _T("BINARY")); -#endif - return count; -} - - -static VOID -DeleteFileList (LPFILES f) -{ - LPFILES temp; - - while (f != NULL) - { - temp = f; - f = f->next; - free (temp); - } -} - - -static INT -Overwrite (LPTSTR fn) -{ - TCHAR inp[10]; - LPTSTR p; - TCHAR szOptions[4]; - - LoadString( CMD_ModuleHandle, STRING_COPY_OPTION, szOptions, sizeof(szOptions) / sizeof(szOptions[0]) ); - - ConOutResPuts(STRING_COPY_HELP1); - - ConInString(inp, 10); - ConOutPuts(_T("")); - - _tcsupr (inp); - for (p = inp; _istspace (*p); p++) - ; - - if (*p != szOptions[0] && *p != szOptions[2]) - return 0; - if (*p == szOptions[2]) - return 2; - - return 1; -} - - + COPY_ASCII = 0x001, /* /A */ + COPY_DECRYPT = 0x004, /* /D : Not Impleneted */ + COPY_VERIFY = 0x008, /* /V : Dummy, Never will be Impleneted */ + COPY_SHORTNAME = 0x010, /* /N : Not Impleneted */ + COPY_NO_PROMPT = 0x020, /* /Y */ + COPY_PROMPT = 0x040, /* /-Y */ + COPY_RESTART = 0x080, /* /Z : Not Impleneted */ + COPY_BINARY = 0x100, /* /B */ +}; + #define BUFF_SIZE 16384 /* 16k = max buffer size */ - - -int copy (LPTSTR source, LPTSTR dest, int append, LPDWORD lpdwFlags) + + +int copy (LPTSTR source, LPTSTR dest, int append, DWORD lpdwFlags) { TCHAR szMsg[RC_STRING_MAX_SIZE]; FILETIME srctime; @@ -348,33 +59,33 @@ DWORD dwWritten; DWORD i; BOOL bEof = FALSE; - + #ifdef _DEBUG DebugPrintf (_T("checking mode\n")); #endif - + dwAttrib = GetFileAttributes (source); - + hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ, - NULL, OPEN_EXISTING, 0, NULL); + NULL, OPEN_EXISTING, 0, NULL); if (hFileSrc == INVALID_HANDLE_VALUE) { LoadString(CMD_ModuleHandle, STRING_COPY_ERROR1, szMsg, RC_STRING_MAX_SIZE); - ConErrPrintf(szMsg, source); + ConOutPrintf(szMsg, source); return 0; } - + #ifdef _DEBUG DebugPrintf (_T("getting time\n")); #endif - + GetFileTime (hFileSrc, &srctime, NULL, NULL); - + #ifdef _DEBUG DebugPrintf (_T("copy: flags has %s\n"), - *lpdwFlags & ASCII ? "ASCII" : "BINARY"); + *lpdwFlags & ASCII ? "ASCII" : "BINARY"); #endif - + if (!IsExistingFile (dest)) { #ifdef _DEBUG @@ -388,50 +99,53 @@ if (!_tcscmp (dest, source)) { LoadString(CMD_ModuleHandle, STRING_COPY_ERROR2, szMsg, RC_STRING_MAX_SIZE); - ConErrPrintf(szMsg, source); - + ConOutPrintf(szMsg, source); + CloseHandle (hFileSrc); return 0; } - + #ifdef _DEBUG DebugPrintf (_T("SetFileAttributes (%s, FILE_ATTRIBUTE_NORMAL);\n"), dest); #endif SetFileAttributes (dest, FILE_ATTRIBUTE_NORMAL); - + #ifdef _DEBUG DebugPrintf (_T("DeleteFile (%s);\n"), dest); #endif DeleteFile (dest); - - hFileDest = - CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); + + hFileDest = CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); } else { LONG lFilePosHigh = 0; - + if (!_tcscmp (dest, source)) { CloseHandle (hFileSrc); return 0; } - + #ifdef _DEBUG DebugPrintf (_T("opening/appending\n")); #endif + SetFileAttributes (dest, FILE_ATTRIBUTE_NORMAL); + hFileDest = CreateFile (dest, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + + /* Move to end of file to start writing */ SetFilePointer (hFileDest, 0, &lFilePosHigh,FILE_END); } - - if (hFileDest == INVALID_HANDLE_VALUE) + + + if (hFileDest == INVALID_HANDLE_VALUE) { CloseHandle (hFileSrc); error_path_not_found (); return 0; } - buffer = (LPBYTE)malloc (BUFF_SIZE); if (buffer == NULL) { @@ -440,11 +154,11 @@ error_out_of_memory (); return 0; } - + do { ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL); - if (*lpdwFlags & ASCII) + if (lpdwFlags & COPY_ASCII) { for (i = 0; i < dwRead; i++) { @@ -456,15 +170,15 @@ } dwRead = i; } - + if (dwRead == 0) break; - + WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL); if (dwWritten != dwRead) { - ConErrResPuts(STRING_COPY_ERROR3); - + ConOutResPuts(STRING_COPY_ERROR3); + free (buffer); CloseHandle (hFileDest); CloseHandle (hFileSrc); @@ -472,13 +186,13 @@ } } while (dwRead && !bEof); - + #ifdef _DEBUG DebugPrintf (_T("setting time\n")); #endif SetFileTime (hFileDest, &srctime, NULL, NULL); - - if (*lpdwFlags & ASCII) + + if (lpdwFlags & COPY_ASCII) { ((LPTSTR)buffer)[0] = 0x1A; ((LPTSTR)buffer)[1] = _T('\0'); @@ -487,298 +201,448 @@ #endif WriteFile (hFileDest, buffer, sizeof(TCHAR), &dwWritten, NULL); } - + free (buffer); CloseHandle (hFileDest); CloseHandle (hFileSrc); - + #ifdef _DEBUG DebugPrintf (_T("setting mode\n")); #endif SetFileAttributes (dest, dwAttrib); - + return 1; } - - -static INT -SetupCopy (LPFILES sources, TCHAR **p, BOOL bMultiple, - TCHAR *drive_d, TCHAR *dir_d, TCHAR *file_d, - TCHAR *ext_d, int *append, LPDWORD lpdwFlags) + + +static INT Overwrite (LPTSTR fn) { - WIN32_FIND_DATA find; - TCHAR drive_s[_MAX_DRIVE]; - TCHAR dir_s[_MAX_DIR]; - TCHAR file_s[_MAX_FNAME]; - TCHAR ext_s[_MAX_EXT]; - TCHAR from_merge[_MAX_PATH]; - - LPTSTR real_source; - LPTSTR real_dest; - - INT nCopied = 0; - BOOL bAll = FALSE; - BOOL bDone; - HANDLE hFind; - TCHAR temp[128]; - -#ifdef _DEBUG - DebugPrintf (_T("SetupCopy\n")); -#endif - - real_source = (LPTSTR)malloc (MAX_PATH * sizeof(TCHAR)); - real_dest = (LPTSTR)malloc (MAX_PATH * sizeof(TCHAR)); - - if (!real_source || !real_dest) + /*ask the user if they want to override*/ + TCHAR szMsg[RC_STRING_MAX_SIZE]; + INT res; + LoadString(CMD_ModuleHandle, STRING_COPY_HELP1, szMsg, RC_STRING_MAX_SIZE); + ConOutPrintf(szMsg,fn); + res = FilePromptYNA (""); + return res; +} + + +INT cmd_copy (LPTSTR cmd, LPTSTR param) +{ + TCHAR szMsg[RC_STRING_MAX_SIZE]; + LPTSTR *arg; + INT argc, i, nFiles, nOverwrite = 0, nSrc = -1, nDes = -1; + /* this is the path up to the folder of the src and dest ie C:\windows\ */ + TCHAR szDestPath[MAX_PATH]; + TCHAR szSrcPath[MAX_PATH]; + DWORD dwFlags = 0; + /* If this is the type of copy where we are adding files */ + BOOL bAppend = FALSE; + WIN32_FIND_DATA findBuffer; + HANDLE hFile; + /* Used when something like "copy c*.exe d*.exe" during the process of + figuring out the new name */ + TCHAR tmpName[MAX_PATH] = _T(""); + /* Pointer to keep track of how far through the append input(file1+file2+file3) we are */ + TCHAR * appendPointer = _T("\0"); + /* The full path to src and dest. This has drive letter, folders, and filename */ + TCHAR tmpDestPath[MAX_PATH]; + TCHAR tmpSrcPath[MAX_PATH]; + /* A bool on weather or not the destination name will be taking from the input */ + BOOL bSrcName = FALSE; + /* Seems like a waste but it is a pointer used to copy from input to PreserveName */ + TCHAR * UseThisName; + /* Stores the name( i.e. blah.txt or blah*.txt) which later we might need */ + TCHAR PreserveName[MAX_PATH]; + + /*Show help/usage info*/ + if (!_tcsncmp (param, _T("/?"), 2)) { - error_out_of_memory (); - DeleteFileList (sources); - free (real_source); - free (real_dest); - freep (p); + ConOutResPaging(TRUE, STRING_COPY_HELP2); return 0; } - - while (sources->next != NULL) + + /*Split the user input into array*/ + arg = split (param, &argc, FALSE); + nFiles = argc; + + /*Read switches and count files*/ + for (i = 0; i < argc; i++) { - -/* Force a clean full path -*/ - GetFullPathName( sources->szFile, 128, (LPTSTR) &temp, NULL); - if (IsExistingDirectory(temp)) + if (*arg[i] == _T('/')) { - _tcscat(temp, _T("\*")); - } - - _tsplitpath (temp, drive_s, dir_s, file_s, ext_s); - - hFind = FindFirstFile ((TCHAR*)&temp, &find); - if (hFind == INVALID_HANDLE_VALUE) - { - error_file_not_found(); - freep(p); - free(real_source); - free(real_dest); - return 0; - } - - do - { - if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - goto next; - - _tmakepath(from_merge, drive_d, dir_d, file_d, ext_d); - - if (from_merge[_tcslen(from_merge) - 1] == _T('\')) - from_merge[_tcslen(from_merge) - 1] = 0; - -// printf("Merge %s, filename %s\n", from_merge, find.cFileName); - - if (IsExistingDirectory (from_merge)) + if (_tcslen(arg[i]) >= 2) { - -// printf("Merge DIR\n"); - - bMultiple = FALSE; - _tcscat (from_merge, _T("\")); - _tcscat (from_merge, find.cFileName); - } - else - bMultiple = TRUE; - - _tcscpy (real_dest, from_merge); - _tmakepath (real_source, drive_s, dir_s, find.cFileName, NULL); - -#ifdef _DEBUG - DebugPrintf(_T("copying %S -> %S (%Sappending%S)\n"), - real_source, real_dest, - *append ? _T("") : _T("not "), - sources->dwFlag & ASCII ? _T(", ASCII") : _T(", BINARY")); -#endif - - if (IsExistingFile (real_dest) && !bAll) - { - /* Don't prompt in a batch file */ - if (bc != NULL) + switch (_totupper(arg[i][1])) { - bAll = TRUE; + + case _T('A'): + dwFlags |= COPY_ASCII; + break; + + case _T('B'): + dwFlags |= COPY_DECRYPT; + break; + + case _T('D'): + dwFlags |= COPY_DECRYPT; + break; + + case _T('V'): + dwFlags |= COPY_VERIFY; + break; + + case _T('N'): + dwFlags |= COPY_SHORTNAME; + break; + + case _T('Y'): + dwFlags |= COPY_NO_PROMPT; + dwFlags &= ~COPY_PROMPT; + break; + + case _T('-'): + if(_tcslen(arg[i]) >= 3) + if(_totupper(arg[i][2]) == _T('Y')) + { + dwFlags &= ~COPY_NO_PROMPT; + dwFlags |= COPY_PROMPT; + } + + break; + + case _T('Z'): + dwFlags |= COPY_RESTART; + break; + + default: + /* invaild switch */ + error_invalid_switch(_totupper(arg[i][1])); + return 1; + break; } - else - { - int over; - - over = Overwrite (real_dest); - if (over == 2) - bAll = TRUE; - else if (over == 0) - goto next; - else if (bMultiple) - bAll = TRUE; - } } - if (copy (real_source, real_dest, *append, lpdwFlags)) - nCopied++; - next: - bDone = FindNextFile (hFind, &find); - - if (bMultiple) - *append = 1; + /*If it was a switch, subtract from total arguments*/ + nFiles--; } - while (bDone); - - FindClose (hFind); - sources = sources->next; - + else + { + /*if it isnt a switch then it is the source or destination*/ + if(nSrc == -1) + nSrc = i; + else if(nDes == -1) + nDes = i; + + } } - free (real_source); - free (real_dest); - - return nCopied; -} - - -INT cmd_copy (LPTSTR first, LPTSTR rest) -{ - TCHAR **p; - TCHAR drive_d[_MAX_DRIVE]; - TCHAR dir_d[_MAX_DIR]; - TCHAR file_d[_MAX_FNAME]; - TCHAR ext_d[_MAX_EXT]; - TCHAR szMsg[RC_STRING_MAX_SIZE]; - - int argc; - int append; - int files; - int copied; - - LPFILES sources = NULL; - LPFILES start = NULL; - FILES dest; - BOOL bMultiple; - BOOL bWildcards; - BOOL bDestFound; - DWORD dwFlags = 0; - - if (!_tcsncmp (rest, _T("/?"), 2)) + + if(nFiles < 1) { - ConOutResPaging(TRUE,STRING_COPY_HELP2); + /* There is not enough files, there has to be at least 1 */ + error_req_param_missing(); return 1; } - - p = split (rest, &argc, FALSE); - - if (argc == 0) + + if(nFiles > 2) { - error_req_param_missing (); - return 0; + /* there is too many file names in command */ + error_too_many_parameters(""); + return 1; } - - sources = (LPFILES)malloc (sizeof (FILES)); - if (!sources) + + if((nDes != -1) && + ((_tcschr (arg[nSrc], _T('+')) != NULL) || + (_tcschr (arg[nSrc], _T('*')) != NULL && _tcschr (arg[nDes], _T('*')) == NULL) || + (IsExistingDirectory (arg[nSrc]) && (_tcschr (arg[nDes], _T('*')) == NULL && !IsExistingDirectory (arg[nDes]))) + )) { - error_out_of_memory (); - return 0; + /* There is a + in the source filename, this means + that there is more then one file being put into + one file. */ + bAppend = TRUE; + if(_tcschr (arg[nSrc], _T('+')) != NULL) + appendPointer = arg[nSrc]; } - sources->next = NULL; - sources->dwFlag = 0; - - if ((files = ParseCommand (sources, argc, p, &dwFlags)) == -1) + + /* Reusing the number of files variable */ + nFiles = 0; + + do { - DeleteFileList (sources); - freep (p); - return 0; + + /* Set up the string that is the path to the destination */ + if(nDes != -1) + { + /* Check to make sure if they entered c:, if they do then GFPN + return current directory even though msdn says it will return c:\ */ + if(_tcslen(arg[nDes]) == 2) + { + if(arg[nDes][1] == _T(':')) + { + _tcscpy (szDestPath, arg[nDes]); + _tcscat (szDestPath, _T("\")); + } + } + else + /* If the user entered two file names then form the full string path*/ + GetFullPathName (arg[nDes], MAX_PATH, szDestPath, NULL); + } - else if (files == 0) + else { - error_req_param_missing(); - DeleteFileList (sources); - freep (p); - return 0; + /* If no destination was entered then just use + the current directory as the destination */ + GetCurrentDirectory (MAX_PATH, szDestPath); } - start = sources; - - bDestFound = GetDestination (sources, &dest); - if (bDestFound) + + + /* Get the full string of the path to the source file*/ + if(_tcschr (arg[nSrc], _T('+')) != NULL) { - _tsplitpath (dest.szFile, drive_d, dir_d, file_d, ext_d); - if (IsExistingDirectory (dest.szFile)) + + _tcscpy(tmpName,_T("\0")); + /* Loop through the source file name and copy all + the chars one at a time until it gets too + */ + while(TRUE) { -// printf("A szFile= %s, Dir = %s, File = %s, Ext = %s\n", dest.szFile, dir_d, file_d, ext_d); - _tcscat (dir_d, file_d); - _tcscat (dir_d, ext_d); - file_d[0] = _T('\0'); - ext_d[0] = _T('\0'); + + if(!_tcsncmp (appendPointer,_T("+"),1) || !_tcsncmp (appendPointer,_T("\0"),1)) + { + /* Now that the pointer is on the + we + need to go to the start of the next filename */ + if(!_tcsncmp (appendPointer,_T("+"),1)) + appendPointer++; + break; + } + _tcsncat(tmpName,appendPointer,1); + appendPointer++; } + /* Finish the string off with a null char */ + _tcsncat(tmpName,_T("\0"),1); + /* Check to make sure if they entered c:, if they do then GFPN + return current directory even though msdn says it will return c:\ */ + if(_tcslen(tmpName) == 2) + { + if(tmpName[1] == _T(':')) + { + _tcscpy (szSrcPath, tmpName); + _tcscat (szSrcPath, _T("\")); + } + } + else + /* Get the full path to first file in the string of file names */ + GetFullPathName (tmpName, MAX_PATH, szSrcPath, NULL); } - - if (_tcschr (dest.szFile, _T('*')) || _tcschr (dest.szFile, _T('?'))) - bWildcards = TRUE; else - bWildcards = FALSE; - - if (_tcschr(rest, _T('+'))) - bMultiple = TRUE; - else - bMultiple = FALSE; - - append = 0; - copied = 0; - - if (bDestFound && !bWildcards) { - -// _tcscpy(sources->szFile, dest.szFile); - - copied = SetupCopy (sources, p, bMultiple, drive_d, dir_d, file_d, ext_d, &append, &dwFlags); + /* Check to make sure if they entered c:, if they do then GFPN + return current directory even though msdn says it will return c:\ */ + if(_tcslen(arg[nSrc]) == 2) + { + if(arg[nSrc][1] == _T(':')) + { + _tcscpy (szSrcPath, arg[nSrc]); + _tcscat (szSrcPath, _T("\")); + } + } + else + /* Get the full path of the source file */ + GetFullPathName (arg[nSrc], MAX_PATH, szSrcPath, NULL); + } - else if (bDestFound && bWildcards) + + /* From this point on, we can assume that the shortest path is 3 letters long + and that would be [DriveLetter]:\ */ + + /* If there is no * in the path name and it is a folder + then we will need to add a wildcard to the pathname + so FindFirstFile comes up with all the files in that + folder */ + if(_tcschr (szSrcPath, _T('*')) == NULL && + IsExistingDirectory (szSrcPath)) { - ConErrResPuts(STRING_COPY_ERROR4); - - DeleteFileList (sources); - freep (p); - return 0; + /* If it doesnt have a \ at the end already then on needs to be added */ + if(szSrcPath[_tcslen(szSrcPath) - 1] != _T('\')) + _tcscat (szSrcPath, _T("\")); + /* Add a wildcard after the \ */ + _tcscat (szSrcPath, _T("*")); } - else if (!bDestFound && !bMultiple) + /* Make sure there is an ending slash to the path if the dest is a folder */ + if(_tcschr (szDestPath, _T('*')) == NULL && + IsExistingDirectory(szDestPath)) { - _tsplitpath (sources->szFile, drive_d, dir_d, file_d, ext_d); - if (IsExistingDirectory (sources->szFile)) - { -// printf("B File = %s, Ext = %s\n", file_d, ext_d); - - _tcscat (dir_d, file_d); - _tcscat (dir_d, ext_d); [truncated at 1000 lines; 203 more skipped]