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

📄 dir.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 4 页
字号:
				u64File2.HighPart = lpFile2->ftLastWriteTime.dwHighDateTime ;
				break;
			}

			/* In case that differnce is too big for a long */
			if (u64File1.QuadPart < u64File2.QuadPart)
				iComp = -1;
			else if (u64File1.QuadPart > u64File2.QuadPart)
				iComp = 1;
			else
				iComp = 0;
			break;
		}

		/* Reverse if desired */
		if (lpFlags->stOrderBy.bCriteriaRev[i])
			iComp *= -1;

		/* If that criteria was enough for distinguishing
		   the files/dirs,there is no need to calculate the others*/
		if (iComp != 0) break;
	}

	/* Translate the value of iComp to boolean */
	if (iComp > 0)
		return TRUE;
	else
		return FALSE;
}

/*
 * QsortFiles
 *
 * Sort files by the order criterias using quicksort method
 */
static VOID
QsortFiles(LPWIN32_FIND_DATA ptrArray[],	/* [IN/OUT] The array with file info pointers */
	   int i,				/* [IN]     The index of first item in array */
	   int j,				/* [IN]     The index to last item in array */
	   LPDIRSWITCHFLAGS lpFlags)		/* [IN]     The flags that we will use to sort */
{
	LPWIN32_FIND_DATA lpTemp;	/* A temporary pointer */
	int First, Last, Temp;
	BOOL Way;

	if (i < j)
	{
		First = i;
		Last = j;
		Way = TRUE;
		while (i != j)
		{
			if (Way == CompareFiles(ptrArray[i], ptrArray[j], lpFlags))
			{
				/* Swap the pointers of the array */
				lpTemp = ptrArray[i];
				ptrArray[i]= ptrArray[j];
				ptrArray[j] = lpTemp;

				/* Swap the indexes for inverting sorting */
				Temp = i;
				i = j;
				j =Temp;

				Way = !Way;
			}

			j += (!Way - Way);
		}

		QsortFiles(ptrArray,First, i-1, lpFlags);
		QsortFiles(ptrArray,i+1,Last, lpFlags);
	}
}



/*
 * DirList
 *
 * The functions that does everything except for printing results
 */
static INT
DirList(LPTSTR szPath,			/* [IN] The path that dir starts */
		LPDIRSWITCHFLAGS lpFlags)	/* [IN] The flags of the listing */
{
	HANDLE hSearch;							/* The handle of the search */
	HANDLE hRecSearch;						/* The handle for searching recursivly */
	WIN32_FIND_DATA wfdFileInfo;			/* The info of file that found */
	LPWIN32_FIND_DATA * ptrFileArray;		/* An array of pointers with all the files */
	PDIRFINDLISTNODE ptrStartNode;	/* The pointer to the first node */
	PDIRFINDLISTNODE ptrNextNode;	/* A pointer used for relatives refernces */
TCHAR szFullPath[MAX_PATH];				/* The full path that we are listing with trailing \ */
TCHAR szSubPath[MAX_PATH];
LPTSTR pszFilePart;
DWORD dwCount;							/* A counter of files found in directory */
DWORD dwCountFiles;						/* Counter for files */
DWORD dwCountDirs;						/* Counter for directories */
ULARGE_INTEGER u64CountBytes;			/* Counter for bytes */
ULARGE_INTEGER u64Temp;					/* A temporary counter */

	/* Initialize Variables */
	ptrStartNode = NULL;
	ptrNextNode = NULL;
	dwCount = 0;
	dwCountFiles = 0;
	dwCountDirs = 0;
	u64CountBytes.QuadPart = 0;

	/* Create szFullPath */
	if (GetFullPathName(szPath, sizeof(szFullPath) / sizeof(TCHAR), szFullPath, &pszFilePart) == 0)
	{
		_tcscpy (szFullPath, szPath);
		if (szFullPath[_tcslen(szFullPath) - 1] != _T('\\'))
			_tcscat (szFullPath, _T("\\"));
		pszFilePart = NULL;
	}

	/* If no wildcard or file was specified and this is a directory, then
	   display all files in it */
	wfdFileInfo.dwFileAttributes = GetFileAttributes(szFullPath);
	if (wfdFileInfo.dwFileAttributes != INVALID_FILE_ATTRIBUTES &&
	    (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
	{
		_tcscat(szFullPath, _T("\\*"));
	}

	/* Prepare the linked list, first node is allocated */
	ptrStartNode = cmd_alloc(sizeof(DIRFINDLISTNODE));
	if (ptrStartNode == NULL)
	{
#ifdef _DEBUG
		ConErrPrintf(_T("DEBUG: Cannot allocate memory for ptrStartNode!\n"));
#endif
		return 1;	/* Error cannot allocate memory for 1st object */
	}
	ptrNextNode = ptrStartNode;

	/* Collect the results for the current folder */
	hSearch = FindFirstFile(szFullPath, &wfdFileInfo);
	do
	{
		if (hSearch != INVALID_HANDLE_VALUE)
		{
			/* Here we filter all the specified attributes */
			if ((wfdFileInfo.dwFileAttributes & lpFlags->stAttribs.dwAttribMask )
				== (lpFlags->stAttribs.dwAttribMask & lpFlags->stAttribs.dwAttribVal ))
			{
				ptrNextNode->ptrNext = cmd_alloc(sizeof(DIRFINDLISTNODE));
				if (ptrNextNode->ptrNext == NULL)
				{
#ifdef _DEBUG
					ConErrPrintf(_T("DEBUG: Cannot allocate memory for ptrNextNode->ptrNext!\n"));
#endif
					while (ptrStartNode)
					{
						ptrNextNode = ptrStartNode->ptrNext;
						cmd_free(ptrStartNode);
						ptrStartNode = ptrNextNode;
						dwCount --;
					}
					return 1;
				}

				/* If cmd_alloc fails we go to next file in hope it works,
				   without braking the linked list! */
				if (ptrNextNode->ptrNext)
				{
					/* Copy the info of search at linked list */
					memcpy(&ptrNextNode->ptrNext->stFindInfo,
					       &wfdFileInfo,
					       sizeof(WIN32_FIND_DATA));

					/* If lower case is selected do it here */
					if (lpFlags->bLowerCase)
					{
						_tcslwr(ptrNextNode->ptrNext->stFindInfo.cAlternateFileName);
						_tcslwr(ptrNextNode->ptrNext->stFindInfo.cFileName);
					}

					/* Continue at next node at linked list */
					ptrNextNode = ptrNextNode->ptrNext;
					dwCount ++;

					/* Grab statistics */
					if (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
					{
						/* Directory */
						dwCountDirs++;
					}
					else
					{
						/* File */
						dwCountFiles++;
						u64Temp.HighPart = wfdFileInfo.nFileSizeHigh;
						u64Temp.LowPart = wfdFileInfo.nFileSizeLow;
						u64CountBytes.QuadPart += u64Temp.QuadPart;
					}
				}
			}
		}
	}while(FindNextFile(hSearch, &wfdFileInfo));
	FindClose(hSearch);

	/* Terminate list */
	ptrNextNode->ptrNext = NULL;

	/* Calculate and allocate space need for making an array of pointers */
	ptrFileArray = cmd_alloc(sizeof(LPWIN32_FIND_DATA) * dwCount);
	if (ptrFileArray == NULL)
	{
#ifdef _DEBUG
		ConErrPrintf(_T("DEBUG: Cannot allocate memory for ptrFileArray!\n"));
#endif
		while (ptrStartNode)
		{
			ptrNextNode = ptrStartNode->ptrNext;
			cmd_free(ptrStartNode);
			ptrStartNode = ptrNextNode;
			dwCount --;
		}		
		return 1;
	}

	/*
	 * Create an array of pointers from the linked list
	 * this will be used to sort and print data, rather than the list
	 */
	ptrNextNode = ptrStartNode;
	dwCount = 0;
	while (ptrNextNode->ptrNext)
	{
		*(ptrFileArray + dwCount) = &ptrNextNode->ptrNext->stFindInfo;
		ptrNextNode = ptrNextNode->ptrNext;
		dwCount++;
	}

	/* Sort Data if requested*/
	if (lpFlags->stOrderBy.sCriteriaCount > 0)
		QsortFiles(ptrFileArray, 0, dwCount-1,lpFlags);

	/* Print Data */
	DirPrintFiles(ptrFileArray, dwCount, szFullPath, lpFlags);

	if (lpFlags->bRecursive)
	{
		PrintSummary(szFullPath,
			dwCountFiles,
			dwCountDirs,
			u64CountBytes,
			lpFlags,
			FALSE);
	}

	/* Free array */
	cmd_free(ptrFileArray);
	if (CheckCtrlBreak(BREAK_INPUT))
		return 1;


	/* Add statistics to recursive statistics*/
	recurse_dir_cnt += dwCountDirs;
	recurse_file_cnt += dwCountFiles;
	recurse_bytes.QuadPart += u64CountBytes.QuadPart;

	/* Do the recursive job if requested
	   the recursive is be done on ALL(indepent of their attribs)
	   directoried of the current one.*/
	if (lpFlags->bRecursive)
	{
		/* The new search is involving any *.* file */
		if (pszFilePart != NULL)
		{
			memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR));
			szSubPath[pszFilePart - szFullPath] = _T('\0');
		}
		else
			_tcscpy(szSubPath, szFullPath);

		_tcscat(szSubPath, _T("*.*"));

		hRecSearch = FindFirstFile (szSubPath, &wfdFileInfo);
		do
		{
			if (hRecSearch != INVALID_HANDLE_VALUE)
			{
				/* We search for directories other than "." and ".." */
				if ((_tcsicmp(wfdFileInfo.cFileName, _T(".")) != 0) &&
				    (_tcsicmp(wfdFileInfo.cFileName, _T("..")) != 0 ) &&
				    (wfdFileInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
				{
					/* Concat the path and the directory to do recursive */
					if (pszFilePart != NULL)
					{
						memcpy(szSubPath, szFullPath, (pszFilePart - szFullPath) * sizeof(TCHAR));
						szSubPath[pszFilePart - szFullPath] = _T('\0');
					}
					else
						_tcscpy(szSubPath, szFullPath);

					_tcscat(szSubPath, wfdFileInfo.cFileName);
					_tcscat(szSubPath, _T("\\"));
					if (pszFilePart != NULL)
						_tcscat(szSubPath, pszFilePart);

					/* We do the same for the folder */
					if (DirList(szSubPath, lpFlags) != 0)
					{
						return 1;
					}
				}
			}
		}while(FindNextFile(hRecSearch,&wfdFileInfo));
		FindClose(hRecSearch);
	}

	/* Free linked list */
	while (ptrStartNode)
	{
		ptrNextNode = ptrStartNode->ptrNext;
		cmd_free(ptrStartNode);
		ptrStartNode = ptrNextNode;
		dwCount --;
	}

	return 0;
}



/*
 * dir
 *
 * internal dir command
 */
INT 
CommandDir(LPTSTR first, LPTSTR rest)
{
	TCHAR	dircmd[256];	/* A variable to store the DIRCMD enviroment variable */
	TCHAR	path[MAX_PATH];
	TCHAR	prev_volume[MAX_PATH];
	LPTSTR*	params = NULL;
	LPTSTR	pszFilePart;
	INT		entries = 0;
	UINT	loop = 0;
	DIRSWITCHFLAGS stFlags;
	INT	ret = 1;
	BOOL ChangedVolume;

	/* Initialize Switch Flags < Default switches are setted here!> */
	stFlags.b4Digit = TRUE;
	stFlags.bBareFormat = FALSE;
	stFlags.bLowerCase = FALSE;
	stFlags.bNewLongList = TRUE;
	stFlags.bPause = FALSE;
	stFlags.bRecursive = FALSE;
	stFlags.bShortName = FALSE;
	stFlags.bTSeperator = TRUE;
	stFlags.bUser = FALSE;
	stFlags.bWideList = FALSE;
	stFlags.bWideListColSort = FALSE;
	stFlags.stTimeField.eTimeField = TF_MODIFIEDDATE;
	stFlags.stTimeField.bUnSet = FALSE;
	stFlags.stAttribs.dwAttribMask = FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM;
	stFlags.stAttribs.dwAttribVal = 0L;
	stFlags.stAttribs.bUnSet = FALSE;
	stFlags.stOrderBy.sCriteriaCount = 0;
	stFlags.stOrderBy.bUnSet = FALSE;

	nErrorLevel = 0;

	/* read the parameters from the DIRCMD environment variable */
	if (GetEnvironmentVariable (_T("DIRCMD"), dircmd, 256))
		if (!DirReadParam(dircmd, &params, &entries, &stFlags))
		{
			nErrorLevel = 1;
			goto cleanup;
		}

	/* read the parameters */
	if (!DirReadParam(rest, &params, &entries, &stFlags) || CheckCtrlBreak(BREAK_INPUT))
	{
		nErrorLevel = 1;
		goto cleanup;
	}

	/* default to current directory */
	if(entries == 0) {
		if(!add_entry(&entries, &params, _T("*"))) {
			nErrorLevel = 1;
			goto cleanup;
		}
	}

	prev_volume[0] = _T('\0');

	for(loop = 0; loop < entries; loop++)
	{
		if (CheckCtrlBreak(BREAK_INPUT))
		{
			nErrorLevel = 1;
			goto cleanup;
		}

		recurse_dir_cnt = 0L;
		recurse_file_cnt = 0L;
		recurse_bytes.QuadPart = 0;

	/* <Debug :>
	   Uncomment this to show the final state of switch flags*/
	#ifdef _DEBUG
		{
			int i;
			ConOutPrintf(_T("Attributes mask/value %x/%x\n"),stFlags.stAttribs.dwAttribMask,stFlags.stAttribs.dwAttribVal  );
			ConOutPrintf(_T("(B) Bare format : %i\n"), stFlags.bBareFormat );
			ConOutPrintf(_T("(C) Thousand : %i\n"), stFlags.bTSeperator );
			ConOutPrintf(_T("(W) Wide list : %i\n"), stFlags.bWideList );
			ConOutPrintf(_T("(D) Wide list sort by column : %i\n"), stFlags.bWideListColSort );
			ConOutPrintf(_T("(L) Lowercase : %i\n"), stFlags.bLowerCase );
			ConOutPrintf(_T("(N) New : %i\n"), stFlags.bNewLongList );
			ConOutPrintf(_T("(O) Order : %i\n"), stFlags.stOrderBy.sCriteriaCount );
			for (i =0;i<stFlags.stOrderBy.sCriteriaCount;i++)
				ConOutPrintf(_T(" Order Criteria [%i]: %i (Reversed: %i)\n"),i, stFlags.stOrderBy.eCriteria[i], stFlags.stOrderBy.bCriteriaRev[i] );
			ConOutPrintf(_T("(P) Pause : %i\n"), stFlags.bPause  );
			ConOutPrintf(_T("(Q) Owner : %i\n"), stFlags.bUser );
			ConOutPrintf(_T("(S) Recursive : %i\n"), stFlags.bRecursive );
			ConOutPrintf(_T("(T) Time field : %i\n"), stFlags.stTimeField.eTimeField );
			ConOutPrintf(_T("(X) Short names : %i\n"), stFlags.bShortName );
			ConOutPrintf(_T("Parameter : %s\n"), params[loop] );
		}
	#endif

		/* Print the drive header if the volume changed */
		ChangedVolume = TRUE;

		if (!stFlags.bBareFormat &&
		    GetVolumePathName(params[loop], path, sizeof(path) / sizeof(TCHAR)))
		{
			if (!_tcscmp(path, prev_volume))
				ChangedVolume = FALSE;
			else
				_tcscpy(prev_volume, path);
		}
		else if (GetFullPathName(params[loop], sizeof(path) / sizeof(TCHAR), path, &pszFilePart) != 0)
		{
			if (pszFilePart != NULL)
				*pszFilePart = _T('\0');
		}
		else
			_tcscpy(path, params[loop]);

		if (ChangedVolume && !stFlags.bBareFormat) {
			if (!PrintDirectoryHeader (params[loop], &stFlags)) {
				nErrorLevel = 1;
				goto cleanup;
			}
		}

		/* do the actual dir */
		if (DirList (params[loop], &stFlags))
		{
			nErrorLevel = 1;
			goto cleanup;
		}

		/* print the footer */
		PrintSummary(path,
			recurse_file_cnt,
			recurse_dir_cnt,
			recurse_bytes,
			&stFlags,
			TRUE);
	}

	ret = 0;

cleanup:
	freep(params);

	return ret;
}

#endif

/* EOF */

⌨️ 快捷键说明

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