📄 dir.c
字号:
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, ¶ms, &entries, &stFlags))
{
nErrorLevel = 1;
goto cleanup;
}
/* read the parameters */
if (!DirReadParam(rest, ¶ms, &entries, &stFlags) || CheckCtrlBreak(BREAK_INPUT))
{
nErrorLevel = 1;
goto cleanup;
}
/* default to current directory */
if(entries == 0) {
if(!add_entry(&entries, ¶ms, _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 + -