Author: tkreuzer Date: Sat Apr 14 20:57:38 2012 New Revision: 56346
URL: http://svn.reactos.org/svn/reactos?rev=56346&view=rev Log: [CMD] Fix several bugs in the copy command: - "x:" is not a valid source path (see bug #5709) - when appending files using "+", cmd must distinguish between + as operator and + as part of the source file, when being put in "". For that reason the tokenizer was modified to make + a seperate token, which is replaced with | when creating the string of multiple files (since + is a valid file character) - ? was not correctly handled when passed in the output file name - factor out the code to create the file name from wildcards and make it readable (no, p, q, r are NOT reasonable variable names!) - Move code out of the loop that doesn't belong there - Make sure the file names are printed when multiple files are copied or appended - write the count of written files (which is 1 when appending), not source files after the copy process is done - Remove an excessive newline when writing strings with ConPuts() - Improve readability a bit
Modified: trunk/reactos/base/shell/cmd/cmd.c trunk/reactos/base/shell/cmd/console.c trunk/reactos/base/shell/cmd/copy.c trunk/reactos/base/shell/cmd/misc.c trunk/reactos/base/shell/cmd/type.c
Modified: trunk/reactos/base/shell/cmd/cmd.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/cmd.c?rev=56... ============================================================================== --- trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/cmd.c [iso-8859-1] Sat Apr 14 20:57:38 2012 @@ -1536,15 +1536,15 @@
if (RegOpenKeyEx(hkeyRoot, _T("SOFTWARE\Microsoft\Command Processor"), - 0, - KEY_READ, + 0, + KEY_READ, &hkey ) == ERROR_SUCCESS) { - if(RegQueryValueEx(hkey, + if(RegQueryValueEx(hkey, _T("AutoRun"), - 0, - 0, - (LPBYTE)autorun, + 0, + 0, + (LPBYTE)autorun, &len) == ERROR_SUCCESS) { if (*autorun) @@ -1749,10 +1749,10 @@ if (!*ptr) { /* If neither /C or /K was given, display a simple version string */ - ConOutResPrintf(STRING_REACTOS_VERSION, + ConOutResPrintf(STRING_REACTOS_VERSION, _T(KERNEL_RELEASE_STR), _T(KERNEL_VERSION_BUILD_STR)); - ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.")); + ConOutPuts(_T("(C) Copyright 1998-") _T(COPYRIGHT_YEAR) _T(" ReactOS Team.\n")); }
if (AutoRun)
Modified: trunk/reactos/base/shell/cmd/console.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/console.c?re... ============================================================================== --- trunk/reactos/base/shell/cmd/console.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/console.c [iso-8859-1] Sat Apr 14 20:57:38 2012 @@ -166,7 +166,6 @@ VOID ConPuts(LPTSTR szText, DWORD nStdHandle) { ConWrite(szText, _tcslen(szText), nStdHandle); - ConWrite(_T("\r\n"), 2, nStdHandle); }
VOID ConOutResPaging(BOOL NewPage, UINT resID)
Modified: trunk/reactos/base/shell/cmd/copy.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/copy.c?rev=5... ============================================================================== --- trunk/reactos/base/shell/cmd/copy.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/copy.c [iso-8859-1] Sat Apr 14 20:57:38 2012 @@ -48,11 +48,11 @@ };
INT -copy (TCHAR source[MAX_PATH], - TCHAR dest[MAX_PATH], - INT append, - DWORD lpdwFlags, - BOOL bTouch) +copy(TCHAR source[MAX_PATH], + TCHAR dest[MAX_PATH], + INT append, + DWORD lpdwFlags, + BOOL bTouch) { FILETIME srctime,NewFileTime; HANDLE hFileSrc; @@ -289,8 +289,45 @@ return res; }
- -INT cmd_copy (LPTSTR param) +/* The following lines of copy were written by someone else +(most likely Eric Kohl) and it was taken from ren.c */ +static void +BuildFileName( + LPTSTR pszSource, // original + LPTSTR pszTarget, // template + LPTSTR pszOutput) // taget +{ + /* build destination file name */ + while (*pszTarget != 0) + { + if (*pszTarget == _T('*')) + { + pszTarget++; + while ((*pszSource != 0) && (*pszSource != *pszTarget)) + { + *pszOutput++ = *pszSource++; + } + } + else if (*pszTarget == _T('?')) + { + pszTarget++; + if (*pszSource != 0) + { + *pszOutput++ = *pszSource++; + } + } + else + { + *pszOutput++ = *pszTarget++; + if (*pszSource != 0) + pszSource++; + } + } + + *pszOutput = 0; +} + +INT cmd_copy(LPTSTR param) { LPTSTR *arg; INT argc, i, nFiles, nOverwrite = 0, nSrc = -1, nDes = -1; @@ -301,11 +338,10 @@ /* If this is the type of copy where we are adding files */ BOOL bAppend = FALSE; WIN32_FIND_DATA findBuffer; - HANDLE hFile; + HANDLE hFile = NULL; BOOL bTouch = FALSE; /* 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 */ @@ -315,17 +351,16 @@ 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]; /* for CMDCOPY env */ TCHAR *evar; int size; TCHAR * szTouch; - BOOL bDone = FALSE; + BOOL bHasWildcard, bDone = FALSE, bMoreFiles = FALSE; + BOOL bMultipleSource = FALSE, bMultipleDest = FALSE;
/* Show help/usage info */ - if (!_tcsncmp (param, _T("/?"), 2)) + if (!_tcsncmp(param, _T("/?"), 2)) { ConOutResPaging(TRUE, STRING_COPY_HELP2); return 0; @@ -350,11 +385,12 @@ }
/* check see if we did get any env variable */ - if (size !=0) - { - int t=0; + if (size != 0) + { + int t = 0; + /* scan and set the flags */ - for (t=0;t<size;t++) + for (t = 0; t < size; t++) { if (_tcsncicmp(_T("/A"),&evar[t],2) == 0) { @@ -402,9 +438,8 @@
/* Split the user input into array */ - arg = split (param, &argc, FALSE); + arg = split(param, &argc, FALSE); nFiles = argc; -
/* Read switches and count files */ for (i = 0; i < argc; i++) @@ -469,28 +504,35 @@ else { /* If it isn't a switch then it is the source or destination */ - if(nSrc == -1) + if (nSrc == -1) { nSrc = i; } - else if(*arg[i] == _T('+') || *arg[i] == _T(',')) - { - /* Add these onto the source string + else if (*arg[i] == _T('+')) + { + /* Next file should be appended */ + bMoreFiles = TRUE; + nFiles -= 1; + } + else if (bMoreFiles) + { + /* Add this file to the source string this way we can do all checks directly on source string later on */ TCHAR * ptr; - int length = (_tcslen(arg[nSrc]) +_tcslen(arg[i]) + _tcslen(arg[i+1]) + 1) * sizeof(TCHAR); + int length = (_tcslen(arg[nSrc]) + _tcslen(arg[i]) + 2) * sizeof(TCHAR); ptr = cmd_alloc(length); if (ptr) { _tcscpy(ptr, arg[nSrc]); + _tcscat(ptr, _T("|")); _tcscat(ptr, arg[i]); - _tcscat(ptr, arg[i+1]); cmd_free(arg[nSrc]); arg[nSrc] = ptr; - i++; - nFiles -= 2; + nFiles -= 1; } + + bMoreFiles = FALSE; } else if(nDes == -1) { @@ -501,100 +543,149 @@
/* keep quiet within batch files */ if (bc != NULL) - { + { dwFlags |= COPY_NO_PROMPT; dwFlags &= ~COPY_PROMPT; - } - - if(nFiles < 1) + } + + if (nFiles < 1) { /* There are not enough files, there has to be at least 1 */ ConOutResPuts(STRING_ERROR_REQ_PARAM_MISSING); - freep (arg); + freep(arg); return 1; }
- if(nFiles > 2) + if (nFiles > 2) { /* There are too many file names in command */ ConErrResPrintf(STRING_ERROR_TOO_MANY_PARAMETERS,_T("")); nErrorLevel = 1; - freep (arg); + freep(arg); return 1; }
- if (nDes != -1) /* you can only append files when there is a destination */ - { - if(((_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]))) - )) - { - /* 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]; - } + if ((_tcschr(arg[nSrc], _T('|')) != NULL) || + (_tcschr(arg[nSrc], _T('*')) != NULL) || + (_tcschr(arg[nSrc], _T('?')) != NULL) || + IsExistingDirectory(arg[nSrc])) + { + bMultipleSource = TRUE; }
/* Reusing the number of files variable */ nFiles = 0;
+ /* Check if no destination argument is passed */ + if (nDes == -1) + { + /* If no destination was entered then just use + the current directory as the destination */ + GetCurrentDirectory(MAX_PATH, szDestPath); + printf("szDestPath = %S\n", szDestPath); + } + else + { + /* Check if the destination is 'x:' */ + if ((arg[nDes][1] == _T(':')) && (arg[nDes][2] == _T('\0'))) + { + GetRootPath(arg[nDes], szDestPath, MAX_PATH); + } + else + { + /* If the user entered two file names then form the full string path */ + GetFullPathName(arg[nDes], MAX_PATH, szDestPath, NULL); + } + + /* Make sure there is an ending slash to the path if the dest is a folder */ + if ((_tcschr(szDestPath, _T('*')) == NULL) && + IsExistingDirectory(szDestPath)) + { + bMultipleDest = TRUE; + if (szDestPath[_tcslen(szDestPath) - 1] != _T('\')) + _tcscat(szDestPath, _T("\")); + } + + /* Check if the destination uses wildcards */ + if ((_tcschr(arg[nDes], _T('*')) != NULL) || + (_tcschr(arg[nDes], _T('?')) != NULL)) + { + bMultipleDest = TRUE; + } + } + + if (nDes != -1) /* you can only append files when there is a destination */ + { + if (bMultipleSource && !bMultipleDest) + { + /* We have multiple source files, but not multiple destination + files. This means we are appending the soruce files. */ + bAppend = TRUE; + if (_tcschr(arg[nSrc], _T('|')) != NULL) + appendPointer = arg[nSrc]; + } + } + + /* Save the name the user entered */ + UseThisName = _tcsrchr(szDestPath,_T('\')); + if (UseThisName) + { + /* Split the name from the path */ + *UseThisName++ = _T('\0'); + + /* Check if the dest path ends with '*' or '' */ + if (((UseThisName[0] == _T('*')) && (UseThisName[1] == _T('\0'))) || + (UseThisName[0] == _T('\0'))) + { + /* In this case we will be using the same name as the source file + for the destination file because destination is a folder */ + bSrcName = TRUE; + UseThisName = NULL; + } + } + else + { + /* Something's seriously wrong! */ + UseThisName = szDestPath; + printf("\n##########\n\n"); + } + do { - /* Set up the string that is the path to the destination */ - if(nDes != -1) - { - if(_tcslen(arg[nDes]) == 2 && arg[nDes][1] == _T(':')) - { - GetRootPath(arg[nDes],szDestPath,MAX_PATH); - } - else - /* If the user entered two file names then form the full string path */ - GetFullPathName (arg[nDes], MAX_PATH, szDestPath, NULL); - } - else - { - /* If no destination was entered then just use - the current directory as the destination */ - GetCurrentDirectory (MAX_PATH, szDestPath); - } - /* Get the full string of the path to the source file */ - if(_tcschr (arg[nSrc], _T('+')) != NULL) - { - _tcscpy(tmpName,_T("\0")); + if (_tcschr(arg[nSrc], _T('|')) != NULL) + { + /* Reset the source path */ + szSrcPath[0] = _T('\0'); + /* Loop through the source file name and copy all the chars one at a time until it gets too + */ while(TRUE) { - if(!_tcsncmp (appendPointer,_T("+"),1) || !_tcsncmp (appendPointer,_T("\0"),1)) + if (appendPointer[0] == _T('|')) { - /* Now that the pointer is on the + we - need to go to the start of the next filename */ - if(!_tcsncmp (appendPointer,_T("+"),1)) - appendPointer++; - else - bDone = TRUE; + /* Skip the | and go to the next file name */ + appendPointer++; break; } - - _tcsncat(tmpName,appendPointer,1); + else if (appendPointer[0] == _T('\0')) + { + bDone = TRUE; + break; + } + + _tcsncat(szSrcPath, appendPointer, 1); appendPointer++; } - - /* Finish the string off with a null char */ - _tcsncat(tmpName,_T("\0"),1); - - if(_tcschr (arg[nSrc], _T(',')) != NULL) +printf("szSrcPath = %S\n\n", szSrcPath); + + if (_tcschr(arg[nSrc], _T(',')) != NULL) { /* Only time there is a , in the source is when they are using touch Cant have a destination and can only have on ,, at the end of the string Cant have more then one file name */ - szTouch = _tcsstr (arg[nSrc], _T("+")); - if(_tcsncmp (szTouch,_T("+,,\0"),4) || nDes != -1) + szTouch = _tcsstr(arg[nSrc], _T("|")); + if (_tcsncmp(szTouch,_T("|,,\0"), 4) || (nDes != -1)) { ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT,arg[nSrc]); nErrorLevel = 1; @@ -608,175 +699,123 @@ else { bDone = TRUE; - _tcscpy(tmpName, arg[nSrc]); - } - - /* Get full path or root names */ - if(_tcslen(tmpName) == 2 && tmpName[1] == _T(':')) - { - GetRootPath(tmpName,szSrcPath,MAX_PATH); - } - else - { - /* Get the full path to first file in the string of file names */ - GetFullPathName (tmpName, MAX_PATH, szSrcPath, NULL); - - /* We got a device path of form \.\x */ - /* FindFirstFile cannot handle this, therefore use the short path */ - if (szSrcPath[0] == _T('\') && szSrcPath[1] == _T('\') && - szSrcPath[2] == _T('.') && szSrcPath[3] == _T('\')) - { - _tcscpy(szSrcPath, tmpName); - } - } + _tcscpy(szSrcPath, arg[nSrc]); + } + + /* "x:" is not a valid source path format. */ + if ((szSrcPath[1] == _T(':')) && (szSrcPath[2] == _T('\0'))) + { + ConOutPrintf(_T("%s\n"), szSrcPath); + ConOutFormatMessage(ERROR_FILE_NOT_FOUND, szSrcPath); + nErrorLevel = 1; + break; + } +
/* 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)) + /* Check if the path has a wildcard */ + bHasWildcard = (_tcschr(szSrcPath, _T('*')) != NULL); + + /* 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 (!bHasWildcard && IsExistingDirectory(szSrcPath)) { /* 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("*")); - } - /* Make sure there is an ending slash to the path if the dest is a folder */ - if(_tcschr (szDestPath, _T('*')) == NULL && - IsExistingDirectory(szDestPath)) - { - if(szDestPath[_tcslen(szDestPath) - 1] != _T('\')) - _tcscat (szDestPath, _T("\")); + if (szSrcPath[_tcslen(szSrcPath) - 1] != _T('\')) + _tcscat(szSrcPath, _T("\")); + _tcscat(szSrcPath, _T("*")); + bHasWildcard = TRUE; + } + + /* If the path ends with '' add a wildcard at the end */ + if (szSrcPath[_tcslen(szSrcPath) - 1] == _T('\')) + { + _tcscat(szSrcPath, _T("*")); + bHasWildcard = TRUE; }
/* Get a list of all the files */ - hFile = FindFirstFile (szSrcPath, &findBuffer); - - /* We need to figure out what the name of the file in the is going to be */ - if((szDestPath[_tcslen(szDestPath) - 1] == _T('*') && szDestPath[_tcslen(szDestPath) - 2] == _T('\')) || - szDestPath[_tcslen(szDestPath) - 1] == _T('\')) - { - /* In this case we will be using the same name as the source file - for the destination file because destination is a folder */ - bSrcName = TRUE; - } - else - { - /* Save the name the user entered */ - UseThisName = _tcsrchr(szDestPath,_T('\')); - UseThisName++; - _tcscpy(PreserveName,UseThisName); + hFile = FindFirstFile(szSrcPath, &findBuffer); + + /* If it couldnt open the file handle, print out the error */ + if (hFile == INVALID_HANDLE_VALUE) + { + /* only print source name when more then one file */ + if (bMultipleSource) + ConOutPrintf(_T("%s\n"), szSrcPath); + + ConOutFormatMessage(GetLastError(), szSrcPath); + freep(arg); + nErrorLevel = 1; + return 1; }
/* Strip the paths back to the folder they are in */ - for(i = (_tcslen(szSrcPath) - 1); i > -1; i--) - if(szSrcPath[i] != _T('\')) + for (i = (_tcslen(szSrcPath) - 1); i > -1; i--) + if (szSrcPath[i] != _T('\')) szSrcPath[i] = _T('\0'); else break;
- for(i = (_tcslen(szDestPath) - 1); i > -1; i--) - if(szDestPath[i] != _T('\')) - szDestPath[i] = _T('\0'); - else - break; - do { /* Check Breaker */ - if(CheckCtrlBreak(BREAK_INPUT)) + if (CheckCtrlBreak(BREAK_INPUT)) { freep(arg); return 1; } + /* Set the override to yes each new file */ nOverwrite = 1;
- /* If it couldnt open the file handle, print out the error */ - if(hFile == INVALID_HANDLE_VALUE) - { - ConOutFormatMessage (GetLastError(), szSrcPath); - freep (arg); + /* Ignore the . and .. files */ + if (!_tcscmp(findBuffer.cFileName, _T(".")) || + !_tcscmp(findBuffer.cFileName, _T("..")) || + findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + continue; + } + + /* Copy the base folder over to a tmp string */ + _tcscpy(tmpDestPath, szDestPath); + _tcscat(tmpDestPath, _T("\")); + + /* Can't put a file into a folder that isnt there */ + if (_tcscmp(tmpDestPath, _T("\\.\")) && + !IsExistingDirectory(tmpDestPath)) + { + ConOutFormatMessage(GetLastError(), szSrcPath); + freep(arg); nErrorLevel = 1; return 1; }
- /* Ignore the . and .. files */ - if(!_tcscmp (findBuffer.cFileName, _T(".")) || - !_tcscmp (findBuffer.cFileName, _T(".."))|| - findBuffer.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) - continue; - - /* Copy the base folder over to a tmp string */ - _tcscpy(tmpDestPath,szDestPath); - - /* Can't put a file into a folder that isnt there */ - if(_tcscmp (szDestPath, _T("\\.\")) && !IsExistingDirectory(szDestPath)) - { - ConOutFormatMessage (GetLastError (), szSrcPath); - freep (arg); - nErrorLevel = 1; - return 1; - } /* Copy over the destination path name */ - if(bSrcName) - _tcscat (tmpDestPath, findBuffer.cFileName); + if (bSrcName) + _tcscat(tmpDestPath, findBuffer.cFileName); else { /* If there is no wildcard you can use the name the user entered */ - if(_tcschr (PreserveName, _T('*')) == NULL) + if ((_tcschr(UseThisName, _T('*')) == NULL) && + (_tcschr(UseThisName, _T('?')) == NULL)) { - _tcscat (tmpDestPath, PreserveName); + _tcscat(tmpDestPath, UseThisName); } else { - /* The following lines of copy were written by someone else - (most likely Eric Khoul) and it was taken from ren.c */ - LPTSTR p,q,r; TCHAR DoneFile[MAX_PATH]; - /* build destination file name */ - p = findBuffer.cFileName; - q = PreserveName; - r = DoneFile; - while(*q != 0) - { - if (*q == '*') - { - q++; - while (*p != 0 && *p != *q) - { - *r = *p; - p++; - r++; - } - } - else if (*q == '?') - { - q++; - if (*p != 0) - { - *r = *p; - p++; - r++; - } - } - else - { - *r = *q; - if (*p != 0) - p++; - q++; - r++; - } - } - *r = 0; + + BuildFileName(findBuffer.cFileName, + UseThisName, + DoneFile); + + /* Add the filename to the tmp string path */ - _tcscat (tmpDestPath, DoneFile); + _tcscat(tmpDestPath, DoneFile); } }
@@ -785,7 +824,7 @@ _tcscat (tmpSrcPath, findBuffer.cFileName);
/* Check to see if the file is the same file */ - if(!bTouch && !_tcscmp (tmpSrcPath, tmpDestPath)) + if(!bTouch && !_tcscmp(tmpSrcPath, tmpDestPath)) { ConOutResPrintf(STRING_COPY_ERROR2);
@@ -793,21 +832,22 @@ break; }
+ /* only print source name when more then one file */ + if (bMultipleSource) + ConOutPrintf(_T("%s\n"), tmpSrcPath); + /* Handle any overriding / prompting that needs to be done */ - if(((!(dwFlags & COPY_NO_PROMPT) && IsExistingFile (tmpDestPath)) || dwFlags & COPY_PROMPT) && !bTouch) + if (((!(dwFlags & COPY_NO_PROMPT) && IsExistingFile (tmpDestPath)) || dwFlags & COPY_PROMPT) && !bTouch) nOverwrite = CopyOverwrite(tmpDestPath); - if(nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK) + if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK) continue; - if(nOverwrite == PROMPT_ALL || (nOverwrite == PROMPT_YES && bAppend)) + if (nOverwrite == PROMPT_ALL || (nOverwrite == PROMPT_YES && bAppend)) dwFlags |= COPY_NO_PROMPT;
/* Tell weather the copy was successful or not */ if(copy(tmpSrcPath,tmpDestPath, bAppend, dwFlags, bTouch)) { nFiles++; - /* only print source name when more then one file */ - if(_tcschr (arg[nSrc], _T('+')) != NULL || _tcschr (arg[nSrc], _T('*')) != NULL) - ConOutPrintf(_T("%s\n"),findBuffer.cFileName); //LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR1, szMsg, RC_STRING_MAX_SIZE); } else @@ -819,15 +859,15 @@ }
/* Loop through all wildcard files */ - } while(FindNextFile (hFile, &findBuffer)); + } while (FindNextFile(hFile, &findBuffer));
/* Loop through all files in src string with a + */ } while(!bDone);
/* print out the number of files copied */ - ConOutResPrintf(STRING_COPY_FILE, nFiles); - - FindClose(hFile); + ConOutResPrintf(STRING_COPY_FILE, bAppend ? 1 : nFiles); + + if (hFile) FindClose(hFile);
if (arg != NULL) freep(arg);
Modified: trunk/reactos/base/shell/cmd/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/misc.c?rev=5... ============================================================================== --- trunk/reactos/base/shell/cmd/misc.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/misc.c [iso-8859-1] Sat Apr 14 20:57:38 2012 @@ -294,7 +294,7 @@ BOOL bQuoted = FALSE;
/* skip leading spaces */ - while (*s && (_istspace (*s) || _istcntrl (*s))) + while (*s && (_istspace(*s) || _istcntrl(*s))) ++s;
start = s; @@ -304,10 +304,25 @@ ++s;
/* skip to next word delimiter or start of next option */ - while (_istprint(*s) && (bQuoted || (!_istspace(*s) && *s != _T('/')))) + while (_istprint(*s)) { /* if quote (") then set bQuoted */ bQuoted ^= (*s == _T('"')); + + /* Check if we have unquoted text */ + if (!bQuoted) + { + /* check for separators */ + if (_istspace(*s) || + (*s == _T('/')) || + (*s == _T('+'))) + { + /* Make length at least one character */ + if (s == start) s++; + break; + } + } + ++s; }
@@ -322,7 +337,7 @@ memcpy (q, start, len * sizeof (TCHAR)); q[len] = _T('\0'); StripQuotes(q); - if (expand_wildcards && _T('/') != *start && + if (expand_wildcards && (_T('/') != *start) && (NULL != _tcschr(q, _T('*')) || NULL != _tcschr(q, _T('?')))) { if (! expand(&ac, &arg, q))
Modified: trunk/reactos/base/shell/cmd/type.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/base/shell/cmd/type.c?rev=5... ============================================================================== --- trunk/reactos/base/shell/cmd/type.c [iso-8859-1] (original) +++ trunk/reactos/base/shell/cmd/type.c [iso-8859-1] Sat Apr 14 20:57:38 2012 @@ -128,6 +128,7 @@ } }
+ ConOutPrintf(_T("\n")); CloseHandle(hFile); }