Пример #1
0
static VOID
PrintDiskInfo (LPTSTR szDisk)
{
    TCHAR szMsg[RC_STRING_MAX_SIZE];
    TCHAR szRootPath[4] = _T("A:\\");
    TCHAR szDrive[2] = _T("A");
    TCHAR szVolume[64];
    TCHAR szSerial[10];
    TCHAR szTotal[40];
    TCHAR szUsed[40];
    TCHAR szFree[40];
    DWORD dwSerial;
    ULONGLONG uliSize;
    DWORD dwSecPerCl;
    DWORD dwBytPerSec;
    DWORD dwFreeCl;
    DWORD dwTotCl;

    if (_tcslen (szDisk) < 2 || szDisk[1] != _T(':'))
    {
        ConErrResPrintf(STRING_FREE_ERROR1);
        return;
    }

    szRootPath[0] = szDisk[0];
    szDrive[0] = _totupper (szRootPath[0]);

    if (!GetVolumeInformation (szRootPath, szVolume, 64, &dwSerial,
                               NULL, NULL, NULL, 0))
    {
        LoadString(CMD_ModuleHandle, STRING_FREE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
        ConErrPrintf(_T("%s %s:\n"), szMsg, szDrive);
        return;
    }

    if (szVolume[0] == _T('\0'))
    {

        LoadString(CMD_ModuleHandle, STRING_FREE_ERROR2, szMsg, RC_STRING_MAX_SIZE);
        _tcscpy (szVolume, szMsg);
    }

    _stprintf (szSerial,
               _T("%04X-%04X"),
               HIWORD(dwSerial),
               LOWORD(dwSerial));

    if (!GetDiskFreeSpace (szRootPath, &dwSecPerCl,
                           &dwBytPerSec, &dwFreeCl, &dwTotCl))
    {
        LoadString(CMD_ModuleHandle, STRING_FREE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
        ConErrPrintf(_T("%s %s:\n"), szMsg, szDrive);
        return;
    }

    uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)dwTotCl;
    ConvertULargeInteger(uliSize, szTotal, 40, TRUE);

    uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)(dwTotCl - dwFreeCl);
    ConvertULargeInteger(uliSize, szUsed, 40, TRUE);

    uliSize = dwSecPerCl * dwBytPerSec * (ULONGLONG)dwFreeCl;
    ConvertULargeInteger(uliSize, szFree, 40, TRUE);

    ConOutResPrintf(STRING_FREE_HELP1, szDrive, szVolume, szSerial, szTotal, szUsed, szFree);
}
Пример #2
0
static DWORD
DeleteFiles(LPTSTR FileName, DWORD* dwFlags, DWORD dwAttrFlags)
{
        TCHAR szFullPath[MAX_PATH];
        TCHAR szFileName[MAX_PATH];
        LPTSTR pFilePart;
        HANDLE hFile;
        WIN32_FIND_DATA f;
        BOOL bExclusion;
        INT res;
        DWORD dwFiles = 0;

        _tcscpy(szFileName, FileName);

        if(_tcschr (szFileName, _T('*')) == NULL &&
	   IsExistingDirectory (szFileName))
        {
	        /* If it doesnt have a \ at the end already then on needs to be added */
		if(szFileName[_tcslen(szFileName) -  1] != _T('\\'))
                        _tcscat (szFileName, _T("\\"));
                /* Add a wildcard after the \ */
                _tcscat (szFileName, _T("*"));
        }

	if(!_tcscmp (szFileName, _T("*")) ||
           !_tcscmp (szFileName, _T("*.*")) ||
           (szFileName[_tcslen(szFileName) -  2] == _T('\\') && szFileName[_tcslen(szFileName) -  1] == _T('*')))
        {
                /* well, the user wants to delete everything but if they didnt yes DEL_YES, DEL_QUIET, or DEL_PROMPT
	           then we are going to want to make sure that in fact they want to do that.  */

		if (!((*dwFlags & DEL_YES) || (*dwFlags & DEL_QUIET) || (*dwFlags & DEL_PROMPT)))
	        {
        	        res = FilePromptYNA (STRING_DEL_HELP2);
		        if ((res == PROMPT_NO) || (res == PROMPT_BREAK))
			        return 0x80000000;
		        if(res == PROMPT_ALL)
			        *dwFlags |= DEL_YES;
	        }
	}

        GetFullPathName (szFileName,
                         MAX_PATH,
                         szFullPath,
                         &pFilePart);

        hFile = FindFirstFile(szFullPath, &f);
        if (hFile != INVALID_HANDLE_VALUE)
        {
                do
                {
					bExclusion = FALSE;

					/*if it is going to be excluded by - no need to check attrs*/
					if(*dwFlags & DEL_ATTRIBUTES && !bExclusion)
					{

						/*save if file attr check if user doesnt care about that attr anyways*/
					 if(dwAttrFlags & ATTR_ARCHIVE && !(f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE))
				        bExclusion = TRUE;
					 if(dwAttrFlags & ATTR_HIDDEN && !(f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
				        bExclusion = TRUE;
					 if(dwAttrFlags & ATTR_SYSTEM && !(f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM))
				        bExclusion = TRUE;
					 if(dwAttrFlags & ATTR_READ_ONLY && !(f.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			            bExclusion = TRUE;
		             if(dwAttrFlags & ATTR_N_ARCHIVE && (f.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE))
			            bExclusion = TRUE;
		             if(dwAttrFlags & ATTR_N_HIDDEN && (f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN))
			            bExclusion = TRUE;
		             if(dwAttrFlags & ATTR_N_SYSTEM && (f.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM))
			            bExclusion = TRUE;
		             if(dwAttrFlags & ATTR_N_READ_ONLY && (f.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
			            bExclusion = TRUE;
					}
					if(bExclusion)
						continue;

					/* ignore directories */
					if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		                continue;


					_tcscpy (pFilePart, f.cFileName);

					/* We cant delete ourselves */
					if(!_tcscmp (CMDPath,szFullPath))
						continue;


					TRACE("Full filename: %s\n", debugstr_aw(szFullPath));

					/* ask for deleting */
					if (*dwFlags & DEL_PROMPT)
					{
		                ConErrResPrintf(STRING_DEL_ERROR5, szFullPath);

		                res = FilePromptYN (STRING_DEL_ERROR6);

		                if ((res == PROMPT_NO) || (res == PROMPT_BREAK))
		                {
								 nErrorLevel = 0;
			                continue;
		                }
	                }

	                /*user cant ask it to be quiet and tell you what it did*/
	                if (!(*dwFlags & DEL_QUIET) && !(*dwFlags & DEL_TOTAL))
	                {
		                ConErrResPrintf(STRING_DEL_ERROR7, szFullPath);
	                }

	                /* delete the file */
	                if(*dwFlags & DEL_NOTHING)
		                continue;

	                if(RemoveFile (szFullPath, *dwFlags, &f))
		                dwFiles++;
					else
                        {
							ErrorMessage (GetLastError(), _T(""));
//                                FindClose(hFile);
//                                return -1;
						}
                }
                while (FindNextFile (hFile, &f));
				FindClose (hFile);
        } 
		else error_sfile_not_found(szFullPath);
        return dwFiles;
}
Пример #3
0
VOID error_invalid_switch (TCHAR ch)
{
	ConErrResPrintf(STRING_ERROR_INVALID_SWITCH, ch);
  nErrorLevel = 1;
}
Пример #4
0
VOID error_too_many_parameters (LPTSTR s)
{
	ConErrResPrintf(STRING_ERROR_TOO_MANY_PARAMETERS, s);
  nErrorLevel = 1;
}
Пример #5
0
VOID error_invalid_parameter_format (LPTSTR s)
{
	ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, s);
  nErrorLevel = 1;
}
Пример #6
0
VOID error_parameter_format(TCHAR ch)
{
	ConErrResPrintf(STRING_ERROR_PARAMETERF_ERROR, ch);
  nErrorLevel = 1;
}
Пример #7
0
INT cmd_set (LPTSTR param)
{
	LPTSTR p;
	LPTSTR lpEnv;
	LPTSTR lpOutput;

	if ( !_tcsncmp (param, _T("/?"), 2) )
	{
		ConOutResPaging(TRUE,STRING_SET_HELP);
		return 0;
	}

	param = (LPTSTR)skip_ws(param);

	/* if no parameters, show the environment */
	if (param[0] == _T('\0'))
	{
		lpEnv = (LPTSTR)GetEnvironmentStrings ();
		if (lpEnv)
		{
			lpOutput = lpEnv;
			while (*lpOutput)
			{
				if (*lpOutput != _T('='))
					ConOutPuts(lpOutput);
				lpOutput += _tcslen(lpOutput) + 1;
			}
			FreeEnvironmentStrings (lpEnv);
		}

		return 0;
	}

	/* the /A does *NOT* have to be followed by a whitespace */
	if ( !_tcsnicmp (param, _T("/A"), 2) )
	{
		BOOL Success;
		StripQuotes(param);
		Success = seta_eval ( skip_ws(param+2) );
		if(!Success)
		{
			/*might seem random but this is what windows xp does */
			nErrorLevel = 9165;
		}
		return !Success;
	}

	if (!_tcsnicmp(param, _T("/P"), 2))
	{
		TCHAR value[1023];
		param = GetQuotedString((LPTSTR)skip_ws(param + 2));
		p = _tcschr(param, _T('='));
		if (!p)
		{
			ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
			nErrorLevel = 1;
			return 1;
		}

		*p++ = _T('\0');
		ConOutPrintf(_T("%s"), GetQuotedString(p));
		ConInString(value, 1023);

		if (!*value || !SetEnvironmentVariable(param, value))
		{
			nErrorLevel = 1;
			return 1;
		}
		return 0;
	}

	param = GetQuotedString(param);

	p = _tcschr (param, _T('='));
	if (p)
	{
		/* set or remove environment variable */
		if (p == param)
		{
			/* handle set =val case */
			ConErrResPuts(STRING_SYNTAX_COMMAND_INCORRECT);
			nErrorLevel = 1;
			return 1;
		}

		*p++ = _T('\0');
		if (!SetEnvironmentVariable(param, *p ? p : NULL))
		{
			nErrorLevel = 1;
			return 1;
		}
	}
	else
	{
		/* display all environment variable with the given prefix */
		BOOL bFound = FALSE;

		while (_istspace(*param) || *param == _T(',') || *param == _T(';'))
			param++;

		p = _tcsrchr(param, _T(' '));
		if (!p)
			p = param + _tcslen(param);
		*p = _T('\0');

		lpEnv = GetEnvironmentStrings();
		if (lpEnv)
		{
			lpOutput = lpEnv;
			while (*lpOutput)
			{
				if (!_tcsnicmp(lpOutput, param, p - param))
				{
					ConOutPuts(lpOutput);
					bFound = TRUE;
				}
				lpOutput += _tcslen(lpOutput) + 1;
			}
			FreeEnvironmentStrings(lpEnv);
		}

		if (!bFound)
		{
			ConErrResPrintf (STRING_PATH_ERROR, param);
			nErrorLevel = 1;
			return 1;
		}
	}

	return 0;
}
Пример #8
0
VOID error_bad_command (LPTSTR s)
{
	ConErrResPrintf(STRING_ERROR_BADCOMMAND, s);
	nErrorLevel = 9009;
}
Пример #9
0
INT
CommandChoice (LPTSTR param)
{
    LPTSTR lpOptions;
    TCHAR Options[6];
    LPTSTR lpText    = NULL;
    BOOL   bNoPrompt = FALSE;
    BOOL   bCaseSensitive = FALSE;
    BOOL   bTimeout = FALSE;
    INT    nTimeout = 0;
    TCHAR  cDefault = _T('\0');
    INPUT_RECORD ir;
    LPTSTR p, np;
    LPTSTR *arg;
    INT    argc;
    INT    i;
    INT    val;

    INT GCret;
    TCHAR Ch;
    DWORD amount,clk;

    LoadString(CMD_ModuleHandle, STRING_CHOICE_OPTION, Options, 4);
    lpOptions = Options;

    if (_tcsncmp (param, _T("/?"), 2) == 0)
    {
        ConOutResPaging(TRUE,STRING_CHOICE_HELP);
        return 0;
    }

    /* retrieve text */
    p = param;

    while (TRUE)
    {
        if (*p == _T('\0'))
            break;

        if (*p != _T('/'))
        {
            lpText = p;
            break;
        }
        np = _tcschr (p, _T(' '));
        if (!np)
            break;
        p = np + 1;
    }

    /* build parameter array */
    arg = split (param, &argc, FALSE);

    /* evaluate arguments */
    if (argc > 0)
    {
        for (i = 0; i < argc; i++)
        {
            if (_tcsnicmp (arg[i], _T("/c"), 2) == 0)
            {
                if (arg[i][2] == _T(':'))
                    lpOptions = &arg[i][3];
                else
                    lpOptions = &arg[i][2];

                if (_tcslen (lpOptions) == 0)
                {
                    ConErrResPuts(STRING_CHOICE_ERROR);
                    freep (arg);
                    return 1;
                }
            }
            else if (_tcsnicmp (arg[i], _T("/n"), 2) == 0)
            {
                bNoPrompt = TRUE;
            }
            else if (_tcsnicmp (arg[i], _T("/s"), 2) == 0)
            {
                bCaseSensitive = TRUE;
            }
            else if (_tcsnicmp (arg[i], _T("/t"), 2) == 0)
            {
                LPTSTR s;

                if (arg[i][2] == _T(':'))
                {
                    cDefault = arg[i][3];
                    s = &arg[i][4];
                }
                else
                {
                    cDefault = arg[i][2];
                    s = &arg[i][3];
                }

                if (*s != _T(','))
                {
                    ConErrResPuts(STRING_CHOICE_ERROR_TXT);
                    freep (arg);
                    return 1;
                }

                s++;
                nTimeout = _ttoi(s);
                bTimeout = TRUE;
            }
            else if (arg[i][0] == _T('/'))
            {
                ConErrResPrintf(STRING_CHOICE_ERROR_OPTION, arg[i]);
                freep (arg);
                return 1;
            }
        }
    }

    /* print text */
    if (lpText)
        ConOutPrintf (_T("%s"), lpText);

    /* print options */
    if (bNoPrompt == FALSE)
    {
        ConOutPrintf (_T("[%c"), lpOptions[0]);

        for (i = 1; (unsigned)i < _tcslen (lpOptions); i++)
            ConOutPrintf (_T(",%c"), lpOptions[i]);

        ConOutPrintf (_T("]?"));
    }

    ConInFlush ();

    if(!bTimeout)
    {
        while (TRUE)
        {
            ConInKey (&ir);

            val = IsKeyInString (lpOptions,
#ifdef _UNICODE
                                 ir.Event.KeyEvent.uChar.UnicodeChar,
#else
                                 ir.Event.KeyEvent.uChar.AsciiChar,
#endif
                                 bCaseSensitive);

            if (val >= 0)
            {
                ConOutPrintf (_T("%c\n"), lpOptions[val]);

                nErrorLevel = val + 1;

                break;
            }

            Beep (440, 50);
        }

        freep (arg);
        TRACE ("ErrorLevel: %d\n", nErrorLevel);
        return 0;
    }

    clk = GetTickCount ();
    amount = nTimeout*1000;

loop:
    GCret = GetCharacterTimeout (&Ch, amount - (GetTickCount () - clk));

    switch (GCret)
    {
    case GC_TIMEOUT:
        TRACE ("GC_TIMEOUT\n");
        TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
        break;

    case GC_NOKEY:
        TRACE ("GC_NOKEY\n");
        TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
        goto loop;

    case GC_KEYREAD:
        TRACE ("GC_KEYREAD\n");
        TRACE ("elapsed %d msecs\n", GetTickCount () - clk);
        TRACE ("read %c", Ch);
        if ((val=IsKeyInString(lpOptions,Ch,bCaseSensitive))==-1)
        {
            Beep (440, 50);
            goto loop;
        }
        cDefault=Ch;
        break;
    }

    TRACE ("exiting wait loop after %d msecs\n",
           GetTickCount () - clk);

    val = IsKeyInString (lpOptions, cDefault, bCaseSensitive);
    ConOutPrintf (_T("%c\n"), lpOptions[val]);

    nErrorLevel = val + 1;

    freep (arg);

    TRACE ("ErrorLevel: %d\n", nErrorLevel);

    return 0;
}
Пример #10
0
INT cmd_type (LPTSTR param)
{
	TCHAR  buff[256];
	HANDLE hFile, hConsoleOut;
	DWORD  dwRet;
	INT    argc,i;
	LPTSTR *argv;
	LPTSTR errmsg;
	BOOL bPaging = FALSE;
	BOOL bFirstTime = TRUE;

	hConsoleOut=GetStdHandle (STD_OUTPUT_HANDLE);

	if (!_tcsncmp (param, _T("/?"), 2))
	{
		ConOutResPaging(TRUE,STRING_TYPE_HELP1);
		return 0;
	}

	if (!*param)
	{
		error_req_param_missing ();
		return 1;
	}

	argv = split (param, &argc, TRUE);

	for(i = 0; i < argc; i++)
	{
		if(*argv[i] == _T('/') && _tcslen(argv[i]) >= 2 && _totupper(argv[i][1]) == _T('P'))
		{
			bPaging = TRUE;
		}
	}

	for (i = 0; i < argc; i++)
	{
		if (_T('/') == argv[i][0] && _totupper(argv[i][1]) != _T('P'))
		{
			ConErrResPrintf(STRING_TYPE_ERROR1, argv[i] + 1);
			continue;
		}

    	nErrorLevel = 0;

		hFile = CreateFile(argv[i],
			GENERIC_READ,
			FILE_SHARE_READ,NULL,
			OPEN_EXISTING,
			FILE_ATTRIBUTE_NORMAL,NULL);

		if(hFile == INVALID_HANDLE_VALUE)
		{
			FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
			               FORMAT_MESSAGE_IGNORE_INSERTS |
			               FORMAT_MESSAGE_FROM_SYSTEM,
			               NULL,
			               GetLastError(),
			               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
			               (LPTSTR) &errmsg,
			               0,
			               NULL);
			ConErrPrintf (_T("%s - %s"), argv[i], errmsg);
			LocalFree (errmsg);
			nErrorLevel = 1;
			continue;
		}

		if (bPaging)
		{
			while (FileGetString (hFile, buff, sizeof(buff) / sizeof(TCHAR)))
			{
				if (ConOutPrintfPaging(bFirstTime, _T("%s"), buff) == 1)
				{
					bCtrlBreak = FALSE;
					CloseHandle(hFile);
					freep(argv);
					return 0;
				}
				bFirstTime = FALSE;
			}
		}
		else
		{
			while (ReadFile(hFile, buff, sizeof(buff), &dwRet, NULL) && dwRet > 0)
			{
				WriteFile(hConsoleOut, buff, dwRet, &dwRet, NULL);
				if (bCtrlBreak)
				{
					bCtrlBreak = FALSE;
					CloseHandle(hFile);
					freep(argv);
					return 0;
				}
			}
		}

		CloseHandle(hFile);
	}

	freep (argv);

	return 0;
}
Пример #11
0
INT CommandChcp (LPTSTR param)
{
	LPTSTR *arg;
	INT    args;
	UINT uNewCodePage;

	/* print help */
	if (!_tcsncmp (param, _T("/?"), 2))
	{
		ConOutResPaging(TRUE,STRING_CHCP_HELP);
		return 0;
	}

	nErrorLevel = 0;

	/* get parameters */
	arg = split (param, &args, FALSE);

	if (args == 0)
	{
		/* display active code page number */
		ConErrResPrintf(STRING_CHCP_ERROR1, InputCodePage);
		freep (arg);
		return 0;
	}

	if (args >= 2)
	{
		/* too many parameters */
		ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, param);
		nErrorLevel = 1;
		freep (arg);
		return 1;
	}

	uNewCodePage = (UINT)_ttoi(arg[0]);

	if (uNewCodePage == 0)
	{
		ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT, arg[0]);
		freep (arg);
		nErrorLevel = 1;
		return 1;
	}

	if (!SetConsoleCP(uNewCodePage))
	{
		ConErrResPuts(STRING_CHCP_ERROR4);
	}
	else
	{

		SetConsoleOutputCP (uNewCodePage);
		InitLocale ();
		InputCodePage= GetConsoleCP();
	}

	freep (arg);

	return 0;
}
Пример #12
0
BOOL
PerformRedirection(REDIRECTION *RedirList)
{
	REDIRECTION *Redir;
	LPTSTR Filename;
	HANDLE hNew;
	UINT DupNumber;
	static SECURITY_ATTRIBUTES SecAttr = { sizeof(SECURITY_ATTRIBUTES), NULL, TRUE };

	/* Some parameters used for read, write, and append, respectively */
	static const DWORD dwAccess[] = {
		GENERIC_READ, 
		GENERIC_WRITE,
		GENERIC_WRITE
	};
	static const DWORD dwShareMode[] = {
		FILE_SHARE_READ | FILE_SHARE_WRITE,
		FILE_SHARE_READ,
		FILE_SHARE_READ
	};
	static const DWORD dwCreationDisposition[] = {
		OPEN_EXISTING,
		CREATE_ALWAYS,
		OPEN_ALWAYS
	};

	for (Redir = RedirList; Redir; Redir = Redir->Next)
	{
		Filename = DoDelayedExpansion(Redir->Filename);
		if (!Filename)
			goto redir_error;
		StripQuotes(Filename);

		if (*Filename == _T('&'))
		{
			DupNumber = Filename[1] - _T('0');
			if (DupNumber >= 10 ||
			    !DuplicateHandle(GetCurrentProcess(),
			                     GetHandle(DupNumber),
			                     GetCurrentProcess(),
			                     &hNew,
			                     0,
			                     TRUE,
			                     DUPLICATE_SAME_ACCESS))
			{
				hNew = INVALID_HANDLE_VALUE;
			}
		}
		else
		{
			hNew = CreateFile(Filename,
			                  dwAccess[Redir->Type],
			                  dwShareMode[Redir->Type],
			                  &SecAttr,
			                  dwCreationDisposition[Redir->Type],
			                  0,
			                  NULL);
		}

		if (hNew == INVALID_HANDLE_VALUE)
		{
			ConErrResPrintf(Redir->Type == REDIR_READ ? STRING_CMD_ERROR1 : STRING_CMD_ERROR3,
			                Filename);
			cmd_free(Filename);
redir_error:
			/* Undo all the redirections before this one */
			UndoRedirection(RedirList, Redir);
			return FALSE;
		}

		if (Redir->Type == REDIR_APPEND)
			SetFilePointer(hNew, 0, NULL, FILE_END);
		Redir->OldHandle = GetHandle(Redir->Number);
		SetHandle(Redir->Number, hNew);

		TRACE("%d redirected to: %s\n", Redir->Number, debugstr_aw(Filename));
		cmd_free(Filename);
	}
	return TRUE;
}
Пример #13
0
INT cmd_copy(LPTSTR param)
{
    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 = NULL;
    BOOL bTouch = FALSE;
    /* Used when something like "copy c*.exe d*.exe" during the process of
       figuring out the new name */
    /* 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;
    /* for CMDCOPY env */
    TCHAR *evar;
    int size;
    TCHAR * szTouch;
    BOOL bHasWildcard, bDone = FALSE, bMoreFiles = FALSE;
    BOOL bMultipleSource = FALSE, bMultipleDest = FALSE;


    /* Show help/usage info */
    if (!_tcsncmp(param, _T("/?"), 2))
    {
        ConOutResPaging(TRUE, STRING_COPY_HELP2);
        return 0;
    }

    nErrorLevel = 0;

    /* Get the envor value if it exists */
    evar = cmd_alloc(512 * sizeof(TCHAR));
    if (evar == NULL)
        size = 0;
    else
        size = GetEnvironmentVariable (_T("COPYCMD"), evar, 512);

    if (size > 512)
    {
        TCHAR *old_evar = evar;
        evar = cmd_realloc(evar,size * sizeof(TCHAR) );
        if (evar!=NULL)
            size = GetEnvironmentVariable (_T("COPYCMD"), evar, size);
        else
        {
            size=0;
            evar = old_evar;
        }
    }

    /* check see if we did get any env variable */
    if (size != 0)
    {
        int t = 0;

        /* scan and set the flags */
        for (t = 0; t < size; t++)
        {
            if (_tcsncicmp(_T("/A"),&evar[t],2) == 0)
            {
                dwFlags |=COPY_ASCII;
                t++;
            }
            else if (_tcsncicmp(_T("/B"),&evar[t],2) == 0)
            {
                dwFlags |= COPY_BINARY;
                t++;
            }
            else if (_tcsncicmp(_T("/D"),&evar[t],2) == 0)
            {
                dwFlags |= COPY_DECRYPT;
                t++;
            }
            else if (_tcsncicmp(_T("/V"),&evar[t],2) == 0)
            {
                dwFlags |= COPY_VERIFY;
                t++;
            }
            else if (_tcsncicmp(_T("/N"),&evar[t],2) == 0)
            {
                dwFlags |= COPY_SHORTNAME;
                t++;
            }
            else if (_tcsncicmp(_T("/Y"),&evar[t],2) == 0)
            {
                dwFlags |= COPY_NO_PROMPT;
                t++;
            }
            else if (_tcsncicmp(_T("/-Y"),&evar[t],3) == 0)
            {
                dwFlags |= COPY_PROMPT;
                t+=2;
            }
            else if (_tcsncicmp(_T("/Z"),&evar[t],2) == 0)
            {
                dwFlags |= COPY_PROMPT;
                t++;
            }
        }
    }
    cmd_free(evar);


    /* Split the user input into array */
    arg = split(param, &argc, FALSE, TRUE);
    nFiles = argc;

    /* Read switches and count files */
    for (i = 0; i < argc; i++)
    {
        if (*arg[i] == _T('/'))
        {
            if (_tcslen(arg[i]) >= 2)
            {
                switch (_totupper(arg[i][1]))
                {
                    case _T('A'):
                        dwFlags |= COPY_ASCII;
                        break;

                    case _T('B'):
                        dwFlags |= COPY_BINARY;
                        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:
                        /* Invalid switch */
                        ConOutResPrintf(STRING_ERROR_INVALID_SWITCH, _totupper(arg[i][1]));
                        nErrorLevel = 1;
                        freep (arg);
                        return 1;
                        break;
                }
            }
            /* If it was a switch, subtract from total arguments */
            nFiles--;
        }
        else
        {
            /* If it isn't a switch then it is the source or destination */
            if (nSrc == -1)
            {
                nSrc = i;
            }
            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]) + 2) * sizeof(TCHAR);
                ptr = cmd_alloc(length);
                if (ptr)
                {
                    _tcscpy(ptr, arg[nSrc]);
                    _tcscat(ptr, _T("|"));
                    _tcscat(ptr, arg[i]);
                    cmd_free(arg[nSrc]);
                    arg[nSrc] = ptr;
                    nFiles -= 1;
                }

                bMoreFiles = FALSE;
            }
            else if (nDes == -1)
            {
                nDes = i;
            }
        }
    }

    /* keep quiet within batch files */
    if (bc != NULL)
    {
        dwFlags |= COPY_NO_PROMPT;
        dwFlags &= ~COPY_PROMPT;
    }

    if (nFiles < 1)
    {
        /* There are not enough files, there has to be at least 1 */
        ConOutResPuts(STRING_ERROR_REQ_PARAM_MISSING);
        freep(arg);
        return 1;
    }

    if (nFiles > 2)
    {
        /* There are too many file names in command */
        ConErrResPrintf(STRING_ERROR_TOO_MANY_PARAMETERS,_T(""));
        nErrorLevel = 1;
        freep(arg);
        return 1;
    }

    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);
    }
    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;
    }

    do
    {
        /* Get the full string of the path to the source file */
        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 (appendPointer[0] == _T('|'))
                {
                    /* Skip the | and go to the next file name */
                    appendPointer++;
                    break;
                }
                else if (appendPointer[0] == _T('\0'))
                {
                    bDone = TRUE;
                    break;
                }

                _tcsncat(szSrcPath, appendPointer, 1);
                appendPointer++;
            }

            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))
                {
                    ConErrResPrintf(STRING_ERROR_INVALID_PARAM_FORMAT,arg[nSrc]);
                    nErrorLevel = 1;
                    freep (arg);
                    return 1;
                }
                bTouch = TRUE;
                bDone = TRUE;
            }
        }
        else
        {
            bDone = TRUE;
            _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]:\ */

        /* 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("\\"));
            _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);

        /* 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('\\'))
                szSrcPath[i] = _T('\0');
            else
                break;

        do
        {
            /* Check Breaker */
            if (CheckCtrlBreak(BREAK_INPUT))
            {
                FindClose(hFile);
                freep(arg);
                return 1;
            }

            /* Set the override to yes each new file */
            nOverwrite = 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);
            _tcscat(tmpDestPath, _T("\\"));

            /* Can't put a file into a folder that isn't there */
            if (_tcscmp(tmpDestPath, _T("\\\\.\\")) &&
                !IsExistingDirectory(tmpDestPath))
            {
                FindClose(hFile);
                ConOutFormatMessage(GetLastError(), szSrcPath);
                freep(arg);
                nErrorLevel = 1;
                return 1;
            }

            /* Copy over the destination path name */
            if (bSrcName)
                _tcscat(tmpDestPath, findBuffer.cFileName);
            else
            {
                /* If there is no wildcard you can use the name the user entered */
                if ((_tcschr(UseThisName, _T('*')) == NULL) &&
                    (_tcschr(UseThisName, _T('?')) == NULL))
                {
                    _tcscat(tmpDestPath, UseThisName);
                }
                else
                {
                    TCHAR DoneFile[MAX_PATH];

                    BuildFileName(findBuffer.cFileName,
                                  UseThisName,
                                  DoneFile);


                    /* Add the filename to the tmp string path */
                    _tcscat(tmpDestPath, DoneFile);
                }
            }

            /* Build the string path to the source file */
            _tcscpy(tmpSrcPath,szSrcPath);
            _tcscat (tmpSrcPath, findBuffer.cFileName);

            /* Check to see if the file is the same file */
            if (!bTouch && !_tcscmp(tmpSrcPath, tmpDestPath))
            {
                ConOutResPrintf(STRING_COPY_ERROR2);

                nErrorLevel = 1;
                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)
                nOverwrite = CopyOverwrite(tmpDestPath);
            if (nOverwrite == PROMPT_NO || nOverwrite == PROMPT_BREAK)
                continue;
            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++;
                //LoadString(CMD_ModuleHandle, STRING_MOVE_ERROR1, szMsg, RC_STRING_MAX_SIZE);
            }
            else
            {
                /* print out the error message */
                ConOutResPrintf(STRING_COPY_ERROR3);
                ConOutFormatMessage (GetLastError(), szSrcPath);
                nErrorLevel = 1;
            }

        /* Loop through all wildcard files */
        } 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, bAppend ? 1 : nFiles);

    if (hFile) FindClose(hFile);

    if (arg != NULL)
        freep(arg);

    return 0;
}