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

📄 dir.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
					error_parameter_format((TCHAR)_totupper (*Line));
					return FALSE;
				}
				break;
			case _T('T'):	/* Switch parameters for /T (time field) */

				/* Ok a switch parameter was given */
				lpFlags->stTimeField.bParSetted = TRUE;

				if (cCurChar == _T(':'))
					/* =V= dead command, used to make the "if" work */
					cCurChar = cCurChar;
				else if(cCurUChar == _T('C'))
					lpFlags->stTimeField.eTimeField= TF_CREATIONDATE ;
				else if(cCurUChar == _T('A'))
					lpFlags->stTimeField.eTimeField= TF_LASTACCESSEDDATE ;
				else if(cCurUChar == _T('W'))
					lpFlags->stTimeField.eTimeField= TF_MODIFIEDDATE  ;
				else
				{
					error_parameter_format((TCHAR)_totupper (*Line));
					return FALSE;
				}
				break;
			case _T('O'):	/* Switch parameters for /O (order) */
				/* Ok a switch parameter was given */
				lpFlags->stOrderBy.bParSetted = TRUE;

				if (cCurChar == _T(':'))
					/* <== dead command, used to make the "if" work */
					cCurChar = cCurChar;
				else if(cCurChar == _T('-'))
					bPNegative = TRUE;
				else if(cCurUChar == _T('N'))
				{
					if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
					lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
					lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_NAME;
				}
				else if(cCurUChar == _T('S'))
				{
					if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
					lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
					lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_SIZE;
				}
				else if(cCurUChar == _T('G'))
				{
					if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
					lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
					lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_DIRECTORY;
				}
				else if(cCurUChar == _T('E'))
				{
					if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
					lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
					lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_EXTENSION;
				}
				else if(cCurUChar == _T('D'))
				{
					if (lpFlags->stOrderBy.sCriteriaCount < 3) lpFlags->stOrderBy.sCriteriaCount++;
					lpFlags->stOrderBy.bCriteriaRev[lpFlags->stOrderBy.sCriteriaCount - 1] = bPNegative;
					lpFlags->stOrderBy.eCriteria[lpFlags->stOrderBy.sCriteriaCount - 1] = ORDER_TIME;
				}

				else
				{
					error_parameter_format((TCHAR)_totupper (*Line));
					return FALSE;
				}


			}
			/* We check if we calculated the negative value and realese the flag */
			if ((cCurChar != _T('-')) && bPNegative)
				bPNegative = FALSE;
		}

		Line++;
	}
	/* Terminate the parameters */
	if(ptrStart && ptrEnd)
	{
		temp = cmd_alloc((ptrEnd - ptrStart + 2) * sizeof(TCHAR));
		if(!temp)
			return FALSE;
		memcpy(temp, ptrStart, (ptrEnd - ptrStart + 1) * sizeof(TCHAR));
		temp[(ptrEnd - ptrStart + 1)] = _T('\0');
		if(!add_entry(entries, params, temp))
		{
			cmd_free(temp);
			freep(*params);
			return FALSE;
		}

		cmd_free(temp);

		ptrStart = NULL;
		ptrEnd = NULL;
	}

	/* Calculate the switches with no switch paramater  */
	if (!(lpFlags->stAttribs.bParSetted))
	{
		lpFlags->stAttribs.dwAttribVal = 0L;
		lpFlags->stAttribs.dwAttribMask = lpFlags->stAttribs.dwAttribVal;
	}
	if (!(lpFlags->stOrderBy.bParSetted))
	{
		lpFlags->stOrderBy.sCriteriaCount = 1;
		lpFlags->stOrderBy.eCriteria[0] = ORDER_NAME;
		lpFlags->stOrderBy.bCriteriaRev[0] = FALSE;
	}
	if (!(lpFlags->stOrderBy.bParSetted))
		lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE ;

	/* Calculate the unsetted switches (the "-" prefixed)*/
	if (lpFlags->stAttribs.bUnSet)
	{
		lpFlags->stAttribs.bUnSet = FALSE;
		lpFlags->stAttribs.dwAttribVal = 0L;
		lpFlags->stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
	}
	if (lpFlags->stOrderBy.bUnSet)
	{
		lpFlags->stOrderBy.bUnSet = FALSE;
		lpFlags->stOrderBy.sCriteriaCount = 0;
	}
	if (lpFlags->stTimeField.bUnSet )
	{
		lpFlags->stTimeField.bUnSet = FALSE;
		lpFlags->stTimeField.eTimeField = TF_MODIFIEDDATE;
	}
	return TRUE;
}


/*
 * PrintDirectoryHeader
 *
 * print the header for the dir command
 */
static BOOL
PrintDirectoryHeader(LPTSTR szPath, LPDIRSWITCHFLAGS lpFlags)
{
  TCHAR szMsg[RC_STRING_MAX_SIZE];
  TCHAR szFullDir[MAX_PATH];
  TCHAR szRootName[MAX_PATH];
  TCHAR szVolName[80];
  LPTSTR pszFilePart;
  DWORD dwSerialNr;

  if (lpFlags->bBareFormat)
    return TRUE;

  if (GetFullPathName(szPath, sizeof(szFullDir) / sizeof(TCHAR), szFullDir, &pszFilePart) == 0)
    {
      ErrorMessage(GetLastError(), _T("Failed to build full directory path"));
      return FALSE;
    }

  if (pszFilePart != NULL)
      *pszFilePart = _T('\0');

  /* get the media ID of the drive */
  if (!GetVolumePathName(szFullDir, szRootName, sizeof(szRootName) / sizeof(TCHAR)) ||
      !GetVolumeInformation(szRootName, szVolName, 80, &dwSerialNr,
			    NULL, NULL, NULL, 0))
    {
      return(TRUE);
    }

  /* print drive info */
  if (szVolName[0] != _T('\0'))
    {
      LoadString(CMD_ModuleHandle, STRING_DIR_HELP2, szMsg, RC_STRING_MAX_SIZE);
      //needs to have first paramter as TRUE because
	  //this is the first output and need to clear the static
	  if(lpFlags->bPause)
		 ConOutPrintfPaging(TRUE,szMsg, szRootName[0], szVolName);
	  else
		 ConOutPrintf(szMsg, szRootName[0], szVolName);
		 
    }
  else
    {
      LoadString(CMD_ModuleHandle, STRING_DIR_HELP3, szMsg, RC_STRING_MAX_SIZE);
	if(lpFlags->bPause)
		 ConOutPrintfPaging(TRUE,szMsg, szRootName[0]);
	else
		 ConOutPrintf(szMsg, szRootName[0]);
    }

  /* print the volume serial number if the return was successful */
  LoadString(CMD_ModuleHandle, STRING_DIR_HELP4, (LPTSTR) szMsg, RC_STRING_MAX_SIZE);
  if(lpFlags->bPause)
	 ConOutPrintfPaging(FALSE,szMsg,
               HIWORD(dwSerialNr),
               LOWORD(dwSerialNr));
  else
	 ConOutPrintf(szMsg,
               HIWORD(dwSerialNr),
               LOWORD(dwSerialNr));


  return TRUE;
}


/*
 * convert
 *
 * insert commas into a number
 *
 */
#if 0
static INT
ConvertULong (ULONG num, LPTSTR des, INT len)
{
	TCHAR temp[32];
	INT c = 0;
	INT n = 0;

	if (num == 0)
	{
		des[0] = _T('0');
		des[1] = _T('\0');
		n = 1;
	}
	else
	{
		temp[31] = 0;
		while (num > 0)
		{
			if (((c + 1) % (nNumberGroups + 1)) == 0)
				temp[30 - c++] = cThousandSeparator;
			temp[30 - c++] = (TCHAR)(num % 10) + _T('0');
			num /= 10;
		}

		for (n = 0; n <= c; n++)
			des[n] = temp[31 - c + n];
	}

	return n;
}
#endif

static VOID
DirPrintFileDateTime(TCHAR *lpDate,
                     TCHAR *lpTime,
                     LPWIN32_FIND_DATA lpFile,
                     LPDIRSWITCHFLAGS lpFlags)
{
	FILETIME ft;
	SYSTEMTIME dt;
	TCHAR szDate[30];
	TCHAR szTime[30];
	WORD wYear;

	/* Select the right time field */
	switch (lpFlags->stTimeField.eTimeField)
	{
		case TF_CREATIONDATE:
			if (!FileTimeToLocalFileTime(&lpFile->ftCreationTime, &ft))
				return;
			FileTimeToSystemTime(&ft, &dt);
			break;

		case TF_LASTACCESSEDDATE :
			if (!FileTimeToLocalFileTime(&lpFile->ftLastAccessTime, &ft))
				return;
			FileTimeToSystemTime(&ft, &dt);
			break;

		case TF_MODIFIEDDATE:
			if (!FileTimeToLocalFileTime(&lpFile->ftLastWriteTime, &ft))
				return;
			FileTimeToSystemTime(&ft, &dt);
			break;
	}

	/* Format date */
	wYear = (lpFlags->b4Digit) ? dt.wYear : dt.wYear%100;
	switch (nDateFormat)
	{
		case 0: /* mmddyy */
		default:
			_stprintf (szDate, _T("%02d%c%02d%c%0*d"),
					dt.wMonth, cDateSeparator,
					dt.wDay, cDateSeparator,
					lpFlags->b4Digit?4:2, wYear);
			break;

		case 1: /* ddmmyy */
			_stprintf (szDate, _T("%02d%c%02d%c%0*d"),
					dt.wDay, cDateSeparator, dt.wMonth,
					cDateSeparator,lpFlags->b4Digit?4:2, wYear);
			break;

		case 2: /* yymmdd */
			_stprintf (szDate, _T("%0*d%c%02d%c%02d"),
					lpFlags->b4Digit?4:2, wYear, cDateSeparator,
					dt.wMonth, cDateSeparator, dt.wDay);
			break;
	}
	/* Format Time */
	switch (nTimeFormat)
	{
		case 0: /* 12 hour format */
		default:
			_stprintf (szTime,_T("  %02d%c%02u%c"),
					(dt.wHour == 0 ? 12 : (dt.wHour <= 12 ? dt.wHour : dt.wHour - 12)),
					cTimeSeparator,
					 dt.wMinute, (dt.wHour <= 11 ? _T('a') : _T('p')));
			break;

		case 1: /* 24 hour format */
			_stprintf (szTime, _T("  %02d%c%02u"),
					dt.wHour, cTimeSeparator, dt.wMinute);
			break;
	}
	/* Copy results */
	_tcscpy(lpDate, szDate);
	_tcscpy(lpTime, szTime);
}


static VOID
GetUserDiskFreeSpace(LPCTSTR lpRoot,
		     PULARGE_INTEGER lpFreeSpace)
{
  PGETFREEDISKSPACEEX pGetFreeDiskSpaceEx;
  HINSTANCE hInstance;
  DWORD dwSecPerCl;
  DWORD dwBytPerSec;
  DWORD dwFreeCl;
  DWORD dwTotCl;
  ULARGE_INTEGER TotalNumberOfBytes, TotalNumberOfFreeBytes;

  lpFreeSpace->QuadPart = 0;

  hInstance = LoadLibrary(_T("KERNEL32"));
  if (hInstance != NULL)
    {
      pGetFreeDiskSpaceEx = (PGETFREEDISKSPACEEX)GetProcAddress(hInstance,
#ifdef _UNICODE
					                        "GetDiskFreeSpaceExW");
#else
				                                "GetDiskFreeSpaceExA");
#endif
      if (pGetFreeDiskSpaceEx != NULL)
	{
	  if (pGetFreeDiskSpaceEx(lpRoot, lpFreeSpace, &TotalNumberOfBytes, &TotalNumberOfFreeBytes) == TRUE)
	    return;
	}
      FreeLibrary(hInstance);
    }

  GetDiskFreeSpace(lpRoot,
		   &dwSecPerCl,
		   &dwBytPerSec,
		   &dwFreeCl,
		   &dwTotCl);

  lpFreeSpace->QuadPart = dwSecPerCl * dwBytPerSec * dwFreeCl;
}


/*
 * print_summary: prints dir summary
 * Added by Rob Lake 06/17/98 to compact code
 * Just copied Tim's Code and patched it a bit
 *
 */
static INT
PrintSummary(LPTSTR szPath,
	     ULONG ulFiles,
	     ULONG ulDirs,
	     ULARGE_INTEGER u64Bytes,
	     LPDIRSWITCHFLAGS lpFlags,
	     BOOL TotalSummary)
{
	TCHAR szMsg[RC_STRING_MAX_SIZE];
	TCHAR szBuffer[64];
	ULARGE_INTEGER uliFree;


	/* Here we check if we didn't find anything */
	if (!(ulFiles + ulDirs))
	{
		if (!lpFlags->bRecursive || (TotalSummary && lpFlags->bRecursive))
			error_file_not_found();
		return 1;
	}


	/* In bare format we don't print results */
	if (lpFlags->bBareFormat)
		return 0;

	/* Print recursive specific results */
	
    /* Take this code offline to fix /S does not print duoble info */
   if (TotalSummary && lpFlags->bRecursive)
   {
      ConvertULargeInteger(u64Bytes, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator);
      LoadString(CMD_ModuleHandle, STRING_DIR_HELP5, szMsg, RC_STRING_MAX_SIZE);
      if(lpFlags->bPause)
         ConOutPrintfPaging(FALSE,szMsg,ulFiles, szBuffer);
      else
         ConOutPrintf(szMsg,ulFiles, szBuffer);
   }
   else
   {
      /* Print File Summary */
      /* Condition to print summary is:
      If we are not in bare format and if we have results! */
      ConvertULargeInteger(u64Bytes, szBuffer, 20, lpFlags->bTSeperator);
      LoadString(CMD_ModuleHandle, STRING_DIR_HELP8, szMsg, RC_STRING_MAX_SIZE);
      if(lpFlags->bPause)
         ConOutPrintfPaging(FALSE,szMsg,ulFiles, szBuffer);
      else
         ConOutPrintf(szMsg,ulFiles, szBuffer);
   }

	/* Print total directories and freespace */
	if (!lpFlags->bRecursive || (TotalSummary && lpFlags->bRecursive))
	{
		GetUserDiskFreeSpace(szPath, &uliFree);
		ConvertULargeInteger(uliFree, szBuffer, sizeof(szBuffer), lpFlags->bTSeperator);
		LoadString(CMD_ModuleHandle, STRING_DIR_HELP6, (LPTSTR) szMsg, RC_STRING_MAX_SIZE);
		if(lpFlags->bPause)
			ConOutPrintfPaging(FALSE,szMsg,ulDirs, szBuffer);
		else
			ConOutPrintf(szMsg,ulDirs, szBuffer);
	}

	return 0;
}

/*
 * getExt
 *
 * Get the extension of a filename
 */
TCHAR* getExt(const TCHAR* file)
{
        static TCHAR *NoExt = _T("");
        TCHAR* lastdot = _tcsrchr(file, _T('.'));
	return (lastdot != NULL ? lastdot + 1 : NoExt);
}

/*
 * getName
 *
 * Get the name of the file without extension
 */
static LPTSTR 
getName(const TCHAR* file, TCHAR * dest)
{
	int iLen;
	LPTSTR end;

	/* Check for "." and ".." folders */
	if ((_tcscmp(file, _T(".")) == 0) ||
	    (_tcscmp(file, _T("..")) == 0))
	{
		_tcscpy(dest,file);
		return dest;
	}

	end = _tcsrchr(file, _T('.'));
	if (!end)
		iLen = _tcslen(file);
	else
		iLen = (end - file);


	_tcsncpy(dest, file, iLen);
	*(dest + iLen) = _T('\0');

	return dest;
}


/*
 *  DirPrintNewList

⌨️ 快捷键说明

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