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

📄 copy.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 *  COPY.C -- copy internal command.
 *
 *
 *  History:
 *
 *    01-Aug-98 (Rob Lake z63rrl@morgan.ucs.mun.ca)
 *        started
 *
 *    13-Aug-1998 (John P. Price)
 *        fixed memory leak problem in copy function.
 *        fixed copy function so it would work with wildcards in the source
 *
 *    13-Dec-1998 (Eric Kohl)
 *        Added COPY command to CMD.
 *
 *    26-Jan-1998 (Eric Kohl)
 *        Replaced CRT io functions by Win32 io functions.
 *
 *    27-Oct-1998 (Eric Kohl)
 *        Disabled prompting when used in batch mode.
 *
 *    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.
 *
 *    20-Jul-2005 (Brandon Turner) <turnerb7@msu.edu>)
 *        Add touch syntax.  "copy arp.exe+,,"
 *        Copy command is now completed.
 */
 
#include <precomp.h>
 
#ifdef INCLUDE_CMD_COPY
 
enum
{
	COPY_ASCII       = 0x001,   /* /A  */
	COPY_DECRYPT     = 0x004,   /* /D  */
	COPY_VERIFY      = 0x008,   /* /V  : Dummy, Never will be Impleneted */
	COPY_SHORTNAME   = 0x010,   /* /N  : Dummy, Never will be Impleneted */
	COPY_NO_PROMPT   = 0x020,   /* /Y  */
	COPY_PROMPT      = 0x040,   /* /-Y */
	COPY_RESTART     = 0x080,   /* /Z  */
	COPY_BINARY      = 0x100,   /* /B  */
};
 
#define BUFF_SIZE 16384         /* 16k = max buffer size */
 
 
INT 
copy (TCHAR source[MAX_PATH], 
	  TCHAR dest[MAX_PATH], 
	  INT append, 
	  DWORD lpdwFlags, 
	  BOOL bTouch)
{
	TCHAR szMsg[RC_STRING_MAX_SIZE];
	FILETIME srctime,NewFileTime;
	HANDLE hFileSrc;
	HANDLE hFileDest;
	LPBYTE buffer;
	DWORD  dwAttrib;
	DWORD  dwRead;
	DWORD  dwWritten;
	BOOL   bEof = FALSE;
	TCHAR TrueDest[MAX_PATH];
	TCHAR TempSrc[MAX_PATH];
	TCHAR * FileName;
	SYSTEMTIME CurrentTime;
 
	/* Check Breaker */
	if(CheckCtrlBreak(BREAK_INPUT))
		return 0;

#ifdef _DEBUG
	DebugPrintf (_T("checking mode\n"));
#endif
 
	if(bTouch)
	{
	hFileSrc = CreateFile (source, GENERIC_WRITE, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, 0, NULL);
	if (hFileSrc == INVALID_HANDLE_VALUE)
	{
		LoadString(CMD_ModuleHandle, STRING_COPY_ERROR1, szMsg, RC_STRING_MAX_SIZE);
		ConOutPrintf(szMsg, source);
        nErrorLevel = 1;
		return 0;
	}

		GetSystemTime(&CurrentTime);
		SystemTimeToFileTime(&CurrentTime, &NewFileTime);
		if(SetFileTime(hFileSrc,(LPFILETIME) NULL, (LPFILETIME) NULL, &NewFileTime))
		{
			CloseHandle(hFileSrc);
			nErrorLevel = 1;
			return 1;

		}
		else
		{
			CloseHandle(hFileSrc);
			return 0;
		}
	}

	dwAttrib = GetFileAttributes (source);
 
	hFileSrc = CreateFile (source, GENERIC_READ, FILE_SHARE_READ,
		NULL, OPEN_EXISTING, 0, NULL);
	if (hFileSrc == INVALID_HANDLE_VALUE)
	{
		LoadString(CMD_ModuleHandle, STRING_COPY_ERROR1, szMsg, RC_STRING_MAX_SIZE);
		ConOutPrintf(szMsg, source);
        nErrorLevel = 1;
		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 & COPY_ASCII ? "ASCII" : "BINARY");
#endif
 
	/* Check to see if /D or /Z are true, if so we need a middle
	   man to copy the file too to allow us to use CopyFileEx later */
	if(lpdwFlags & COPY_DECRYPT)
	{
		GetEnvironmentVariable(_T("TEMP"),TempSrc,MAX_PATH);
		_tcscat(TempSrc,_T("\\"));
		FileName = _tcsrchr(source,_T('\\'));
		FileName++;
		_tcscat(TempSrc,FileName);
		/* This is needed to be on the end to prevent an error
		   if the user did "copy /D /Z foo bar then it would be copied
		   too %TEMP%\foo here and when %TEMP%\foo when it sets it up
		   for COPY_RESTART, this would mean it is copying to itself
		   which would error when it tried to open the handles for ReadFile
		   and WriteFile */
		_tcscat(TempSrc,_T(".decrypt"));
		if(!CopyFileEx(source, TempSrc, NULL, NULL, FALSE, COPY_FILE_ALLOW_DECRYPTED_DESTINATION))
		{
		   nErrorLevel = 1;
		   return 0;
		}
		_tcscpy(source, TempSrc);
	}


	if(lpdwFlags & COPY_RESTART)
	{
		_tcscpy(TrueDest, dest);
		GetEnvironmentVariable(_T("TEMP"),dest,MAX_PATH);
		_tcscat(dest,_T("\\"));
		FileName = _tcsrchr(TrueDest,_T('\\'));
		FileName++;
		_tcscat(dest,FileName);
	}


	if (!IsExistingFile (dest))
	{
#ifdef _DEBUG
		DebugPrintf (_T("opening/creating\n"));
#endif
		hFileDest =
			CreateFile (dest, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL);
	}
	else if (!append)
	{
		if (!_tcscmp (dest, source))
		{
			LoadString(CMD_ModuleHandle, STRING_COPY_ERROR2, szMsg, RC_STRING_MAX_SIZE);
			ConOutPrintf(szMsg, source);
 
			CloseHandle (hFileSrc);
            nErrorLevel = 1;
			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);
	}
	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)
	{
		CloseHandle (hFileSrc);
		ConOutResPuts(STRING_ERROR_PATH_NOT_FOUND);
        nErrorLevel = 1;
		return 0;
	}

	/* A page-aligned buffer usually give more speed */
	buffer = (LPBYTE)VirtualAlloc(NULL, BUFF_SIZE, MEM_COMMIT, PAGE_READWRITE);
	if (buffer == NULL)
	{
		CloseHandle (hFileDest);
		CloseHandle (hFileSrc);
		ConOutResPuts(STRING_ERROR_OUT_OF_MEMORY);
        nErrorLevel = 1;
		return 0;
	}
 
	do
	{

		ReadFile (hFileSrc, buffer, BUFF_SIZE, &dwRead, NULL);
		if (lpdwFlags & COPY_ASCII)
		{
			LPBYTE pEof = memchr(buffer, 0x1A, dwRead);
			if (pEof != NULL)
			{
				bEof = TRUE;
				dwRead = pEof-buffer+1;
				break;
			}
		}
 
		if (dwRead == 0)
			break;
 
		WriteFile (hFileDest, buffer, dwRead, &dwWritten, NULL);
		if (dwWritten != dwRead || CheckCtrlBreak(BREAK_INPUT))
		{
			ConOutResPuts(STRING_COPY_ERROR3);
 
			cmd_free (buffer);
			CloseHandle (hFileDest);
			CloseHandle (hFileSrc);
			nErrorLevel = 1;
			return 0;
		}
	}
	while (!bEof);
 
#ifdef _DEBUG
	DebugPrintf (_T("setting time\n"));
#endif
	SetFileTime (hFileDest, &srctime, NULL, NULL);
 
	if ((lpdwFlags & COPY_ASCII) && !bEof)
	{
		/* we're dealing with ASCII files! */
		buffer[0] = 0x1A;
#ifdef _DEBUG
		DebugPrintf (_T("appending ^Z\n"));
#endif
		WriteFile (hFileDest, buffer, sizeof(CHAR), &dwWritten, NULL);
	}
 
	VirtualFree (buffer, 0, MEM_RELEASE);
	CloseHandle (hFileDest);
	CloseHandle (hFileSrc);
 
#ifdef _DEBUG
	DebugPrintf (_T("setting mode\n"));
#endif
	SetFileAttributes (dest, dwAttrib);
 
	/* Now finish off the copy if needed with CopyFileEx */
	if(lpdwFlags & COPY_RESTART)
	{
		if(!CopyFileEx(dest, TrueDest, NULL, NULL, FALSE, COPY_FILE_RESTARTABLE))
		{
		   nErrorLevel = 1;
		   DeleteFile(dest);
           return 0;			
		}
		/* Take care of file in the temp folder */
		DeleteFile(dest);

	}

	if(lpdwFlags & COPY_DECRYPT)
	   DeleteFile(TempSrc);

	return 1;
}
 
 
static INT CopyOverwrite (LPTSTR fn)
{
	/*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 (_T(""));
	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;
	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 */
	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];
   /* for CMDCOPY env */
   TCHAR *evar;
   int size;
	TCHAR * szTouch;
	BOOL bDone = 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)
  {
    evar = cmd_realloc(evar,size * sizeof(TCHAR) );
    if (evar!=NULL)
    {             
      size = GetEnvironmentVariable (_T("COPYCMD"), evar, size);
      }
    else 
    {
      size=0;
    }
  }

  /* 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;

⌨️ 快捷键说明

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