⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmd.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 4 页
字号:
#endif
	}
	else if (hOldConOut != INVALID_HANDLE_VALUE)
	{
		/* Restore original stdout */
		HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE);
		SetStdHandle (STD_OUTPUT_HANDLE, hOldConOut);
		if (hOldConOut != hOut)
			CloseHandle (hOut);
		hOldConOut = INVALID_HANDLE_VALUE;
	}

	/* redirect STDERR */
	if (err[0])
	{
		/* Final output to here */
		HANDLE hFile;
		SECURITY_ATTRIBUTES sa = {sizeof(SECURITY_ATTRIBUTES), NULL, TRUE};

		if (!_tcscmp (err, out))
		{
#ifdef _DEBUG
			DebugPrintf (_T("Stdout and stderr will use the same file!!\n"));
#endif
			DuplicateHandle (GetCurrentProcess (),
			                 GetStdHandle (STD_OUTPUT_HANDLE),
			                 GetCurrentProcess (),
			                 &hFile, 0, TRUE, DUPLICATE_SAME_ACCESS);
		}
		else
		{
			hFile = CreateFile (err,
			                    GENERIC_WRITE,
			                    FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE,
			                    &sa,
			                    (nRedirFlags & ERROR_APPEND) ? OPEN_ALWAYS : CREATE_ALWAYS,
			                    FILE_ATTRIBUTE_NORMAL | FILE_FLAG_WRITE_THROUGH,
			                    NULL);
			if (hFile == INVALID_HANDLE_VALUE)
			{
				LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
				ConErrPrintf(szMsg, err);
				return;
			}
		}

		if (!SetStdHandle (STD_ERROR_HANDLE, hFile))
		{
			LoadString(CMD_ModuleHandle, STRING_CMD_ERROR3, szMsg, RC_STRING_MAX_SIZE);
			ConErrPrintf(szMsg, err);
			return;
		}

		if (nRedirFlags & ERROR_APPEND)
		{
			LONG lHighPos = 0;

			if (GetFileType (hFile) == FILE_TYPE_DISK)
				SetFilePointer (hFile, 0, &lHighPos, FILE_END);
		}
#ifdef _DEBUG
		DebugPrintf (_T("Error redirected to: %s\n"), err);
#endif
	}
	else if (hOldConErr != INVALID_HANDLE_VALUE)
	{
		/* Restore original stderr */
		HANDLE hErr = GetStdHandle (STD_ERROR_HANDLE);
		SetStdHandle (STD_ERROR_HANDLE, hOldConErr);
		if (hOldConErr != hErr)
			CloseHandle (hErr);
		hOldConErr = INVALID_HANDLE_VALUE;
	}

	if(bc)
		bNewBatch = FALSE;
#endif

	/* process final command */
	DoCommand (s);

#ifdef FEATURE_REDIRECTION
	if(bNewBatch && bc)
		AddBatchRedirection(in, out, err);
	/* close old stdin file */
#if 0  /* buggy implementation */
	SetStdHandle (STD_INPUT_HANDLE, hOldConIn);
	if ((hFile[0] != INVALID_HANDLE_VALUE) &&
		(hFile[0] != hOldConIn))
	{
		/* delete old stdin file, if it is a real file */
		CloseHandle (hFile[0]);
		hFile[0] = INVALID_HANDLE_VALUE;
		DeleteFile (szFileName[0]);
		*szFileName[0] = _T('\0');
	}

	/* Restore original STDIN */
	if (hOldConIn != INVALID_HANDLE_VALUE)
	{
		HANDLE hIn = GetStdHandle (STD_INPUT_HANDLE);
		SetStdHandle (STD_INPUT_HANDLE, hOldConIn);
		if (hOldConIn != hIn)
			CloseHandle (hIn);
		hOldConIn = INVALID_HANDLE_VALUE;
	}
	else
	{
#ifdef _DEBUG
		DebugPrintf (_T("Can't restore STDIN! Is invalid!!\n"), out);
#endif
	}
#endif  /* buggy implementation */


	if (hOldConIn != INVALID_HANDLE_VALUE)
	{
		HANDLE hIn = GetStdHandle (STD_INPUT_HANDLE);
		SetStdHandle (STD_INPUT_HANDLE, hOldConIn);
		if (hIn == INVALID_HANDLE_VALUE)
		{
#ifdef _DEBUG
			DebugPrintf (_T("Previous STDIN is invalid!!\n"));
#endif
		}
		else
		{
			if (GetFileType (hIn) == FILE_TYPE_DISK)
			{
				if (hFile[0] == hIn)
				{
					CloseHandle (hFile[0]);
					hFile[0] = INVALID_HANDLE_VALUE;
					DeleteFile (szFileName[0]);
					*szFileName[0] = _T('\0');
				}
				else
				{
#ifdef _DEBUG
					DebugPrintf (_T("hFile[0] and hIn dont match!!!\n"));
#endif
				}
			}
		}
	}


	/* Restore original STDOUT */
	if (hOldConOut != INVALID_HANDLE_VALUE)
	{
		HANDLE hOut = GetStdHandle (STD_OUTPUT_HANDLE);
		SetStdHandle (STD_OUTPUT_HANDLE, hOldConOut);
		if (hOldConOut != hOut)
			CloseHandle (hOut);
		hOldConOut = INVALID_HANDLE_VALUE;
	}

	/* Restore original STDERR */
	if (hOldConErr != INVALID_HANDLE_VALUE)
	{
		HANDLE hErr = GetStdHandle (STD_ERROR_HANDLE);
		SetStdHandle (STD_ERROR_HANDLE, hOldConErr);
		if (hOldConErr != hErr)
			CloseHandle (hErr);
		hOldConErr = INVALID_HANDLE_VALUE;
	}
#endif /* FEATURE_REDIRECTION */
}

BOOL
GrowIfNecessary ( UINT needed, LPTSTR* ret, UINT* retlen )
{
	if ( *ret && needed < *retlen )
		return TRUE;
	*retlen = needed;
	if ( *ret )
		free ( *ret );
	*ret = (LPTSTR)malloc ( *retlen * sizeof(TCHAR) );
	if ( !*ret )
		SetLastError ( ERROR_OUTOFMEMORY );
	return *ret != NULL;
}

LPCTSTR
GetEnvVarOrSpecial ( LPCTSTR varName )
{
	static LPTSTR ret = NULL;
	static UINT retlen = 0;
	UINT size;

	size = GetEnvironmentVariable ( varName, ret, retlen );
	if ( size > retlen )
	{
		if ( !GrowIfNecessary ( size, &ret, &retlen ) )
			return NULL;
		size = GetEnvironmentVariable ( varName, ret, retlen );
	}
	if ( size )
		return ret;

	/* env var doesn't exist, look for a "special" one */
	/* %CD% */
	if (_tcsicmp(varName,_T("cd")) ==0)
	{
		size = GetCurrentDirectory ( retlen, ret );
		if ( size > retlen )
		{
			if ( !GrowIfNecessary ( size, &ret, &retlen ) )
				return NULL;
			size = GetCurrentDirectory ( retlen, ret );
		}
		if ( !size )
			return NULL;
		return ret;
	}
	/* %TIME% */
	else if (_tcsicmp(varName,_T("time")) ==0)
	{
		SYSTEMTIME t;
		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
			return NULL;
		GetSystemTime(&t);
		_sntprintf ( ret, retlen, _T("%02d%c%02d%c%02d%c%02d"),
			t.wHour, cTimeSeparator, t.wMinute, cTimeSeparator,
			t.wSecond, cDecimalSeparator, t.wMilliseconds / 10);
		return ret;
	}
	/* %DATE% */
	else if (_tcsicmp(varName,_T("date")) ==0)
	{
		LPTSTR tmp;

		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
			return NULL;
		size = GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, _T("ddd"), ret, retlen );
		/* TODO FIXME - test whether GetDateFormat() can return a value indicating the buffer wasn't big enough */
		if ( !size )
			return NULL;
		tmp = ret + _tcslen(ret);
		*tmp++ = _T(' ');
		size = GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, NULL, NULL, tmp, retlen-(tmp-ret));
		/* TODO FIXME - test whether GetDateFormat() can return a value indicating the buffer wasn't big enough */
		if ( !size )
			return NULL;
		return ret;
	}

	/* %RANDOM% */
	else if (_tcsicmp(varName,_T("random")) ==0)
	{
		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
			return NULL;
		/* Get random number */
		_itot(rand(),ret,10);
		return ret;
	}

	/* %CMDCMDLINE% */
	else if (_tcsicmp(varName,_T("cmdcmdline")) ==0)
	{
		return GetCommandLine();
	}

	/* %CMDEXTVERSION% */
	else if (_tcsicmp(varName,_T("cmdextversion")) ==0)
	{
		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
			return NULL;
		/* Set version number to 2 */
		_itot(2,ret,10);
		return ret;
	}

	/* %ERRORLEVEL% */
	else if (_tcsicmp(varName,_T("errorlevel")) ==0)
	{
		if ( !GrowIfNecessary ( MAX_PATH, &ret, &retlen ) )
			return NULL;
		_itot(nErrorLevel,ret,10);
		return ret;
	}

	GrowIfNecessary(_tcslen(varName) + 2, &ret, &retlen);
	_stprintf(ret,_T("%%%s%%"),varName);
	return ret; /* not found - return orginal string */
}

LPCTSTR
GetParsedEnvVar ( LPCTSTR varName, UINT* varNameLen, BOOL ModeSetA )
{
	static LPTSTR ret = NULL;
	static UINT retlen = 0;
	LPTSTR p, tmp;
	UINT size;

	if ( varNameLen )
		*varNameLen = 0;
	SetLastError(0);
	if ( *varName++ != '%' )
		return NULL;
	switch ( *varName )
	{
	case _T('0'):
	case _T('1'):
	case _T('2'):
	case _T('3'):
	case _T('4'):
	case _T('5'):
	case _T('6'):
	case _T('7'):
	case _T('8'):
	case _T('9'):
		if ((tmp = FindArg (*varName - _T('0'))))
		{
			if ( varNameLen )
				*varNameLen = 2;
			if ( !*tmp )
				return _T("");
			if ( !GrowIfNecessary ( _tcslen(tmp)+1, &ret, &retlen ) )
				return NULL;
			_tcscpy ( ret, tmp );
			return ret;
		}
		if ( !GrowIfNecessary ( 3, &ret, &retlen ) )
			return NULL;
		ret[0] = _T('%');
		ret[1] = *varName;
		ret[2] = 0;
		if ( varNameLen )
			*varNameLen = 2;
		return ret;
   
    case _T('*'):
        if(bc == NULL)
        {
            //
            // No batch file to see here, move along
            //
            if ( !GrowIfNecessary ( 3, &ret, &retlen ) )
                return NULL;
            ret[0] = _T('%');
            ret[1] = _T('*');
            ret[2] = 0;
            if ( varNameLen )
                *varNameLen = 2;
            return ret;
        }

        //
        // Copy over the raw params(not including the batch file name
        //
        if ( !GrowIfNecessary ( _tcslen(bc->raw_params)+1, &ret, &retlen ) )
            return NULL;
        if ( varNameLen )
            *varNameLen = 2;
        _tcscpy ( ret, bc->raw_params );
        return ret;

	case _T('%'):
		if ( !GrowIfNecessary ( 2, &ret, &retlen ) )
			return NULL;
		ret[0] = _T('%');
		ret[1] = 0;
		if ( varNameLen )
			*varNameLen = 2;
		return ret;

	case _T('?'):
		/* TODO FIXME 10 is only max size for 32-bit */
		if ( !GrowIfNecessary ( 11, &ret, &retlen ) )
			return NULL;
		_sntprintf ( ret, retlen, _T("%u"), nErrorLevel);
		ret[retlen-1] = 0;
		if ( varNameLen )
			*varNameLen = 2;
		return ret;
	}
	if ( ModeSetA )
	{
		/* HACK for set/a */
		if ( !GrowIfNecessary ( 2, &ret, &retlen ) )
			return NULL;
		ret[0] = _T('%');
		ret[1] = 0;
		if ( varNameLen )
			*varNameLen = 1;
		return ret;
	}
	p = _tcschr ( varName, _T('%') );
	if ( !p )
	{
		SetLastError ( ERROR_INVALID_PARAMETER );
		return NULL;
	}
	size = p-varName;
	if ( varNameLen )
		*varNameLen = size + 2;
	p = alloca ( (size+1) * sizeof(TCHAR) );
	memmove ( p, varName, size * sizeof(TCHAR) );
	p[size] = 0;
	varName = p;
	return GetEnvVarOrSpecial ( varName );
}


/*
 * do the prompt/input/process loop
 *
 */

static INT
ProcessInput (BOOL bFlag)
{
	TCHAR commandline[CMDLINE_LENGTH];
	TCHAR readline[CMDLINE_LENGTH];
	LPTSTR ip;
	LPTSTR cp;
	LPCTSTR tmp;
	BOOL bEchoThisLine;
	BOOL bModeSetA;
        BOOL bIsBatch;

	do
	{
		/* if no batch input then... */
		if (!(ip = ReadBatchLine (&bEchoThisLine)))
		{
			if (bFlag)
				return nErrorLevel;

			ReadCommand (readline, CMDLINE_LENGTH);
			ip = readline;
			bEchoThisLine = FALSE;
            bIsBatch = FALSE;
		}
        else
        {
            bIsBatch = TRUE;
        }

		/* skip leading blanks */
		while ( _istspace(*ip) )
			++ip;

		cp = commandline;
		bModeSetA = FALSE;
		while (*ip)
		{
			if ( *ip == _T('%') )
			{
				UINT envNameLen;
				LPCTSTR envVal = GetParsedEnvVar ( ip, &envNameLen, bModeSetA );
				if ( envVal )
				{
					ip += envNameLen;
					cp = _stpcpy ( cp, envVal );
				}
			}

			if (_istcntrl (*ip))
				*ip = _T(' ');
			*cp++ = *ip++;

			/* HACK HACK HACK check whether bModeSetA needs to be toggled */
			*cp = 0;
			tmp = commandline;
			tmp += _tcsspn(tmp,_T(" \t"));
			/* first we find and skip and pre-redirections... */
			while (( tmp ) &&
				( _tcschr(_T("<>"),*tmp)
				|| !_tcsncmp(tmp,_T("1>"),2)
				|| !_tcsncmp(tmp,_T("2>"),2) ))
			{
				if ( _istdigit(*tmp) )
					tmp += 2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -