cmd.exe: Add dir /X support (sort of...).

This commit is contained in:
Jason Edmeades 2007-03-13 20:27:45 +00:00 committed by Alexandre Julliard
parent cdb833bf33
commit 1497a2fec4
1 changed files with 79 additions and 22 deletions

View File

@ -33,7 +33,7 @@ int WCMD_dir_sort (const void *a, const void *b);
void WCMD_list_directory (char *path, int level); void WCMD_list_directory (char *path, int level);
char * WCMD_filesize64 (ULONGLONG free); char * WCMD_filesize64 (ULONGLONG free);
char * WCMD_strrev (char *buff); char * WCMD_strrev (char *buff);
static void WCMD_getfileowner(char *filename, char *owner, int ownerlen);
extern int echo_mode; extern int echo_mode;
extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH]; extern char quals[MAX_PATH], param1[MAX_PATH], param2[MAX_PATH];
@ -47,7 +47,7 @@ typedef enum _DISPLAYTIME
} DISPLAYTIME; } DISPLAYTIME;
static int file_total, dir_total, recurse, wide, bare, max_width, lower; static int file_total, dir_total, recurse, wide, bare, max_width, lower;
static int shortname; static int shortname, usernames;
static ULONGLONG byte_total; static ULONGLONG byte_total;
static DISPLAYTIME dirTime; static DISPLAYTIME dirTime;
@ -77,6 +77,7 @@ void WCMD_directory (void) {
bare = (strstr(quals, "/B") != NULL); bare = (strstr(quals, "/B") != NULL);
lower = (strstr(quals, "/L") != NULL); lower = (strstr(quals, "/L") != NULL);
shortname = (strstr(quals, "/X") != NULL); shortname = (strstr(quals, "/X") != NULL);
usernames = (strstr(quals, "/Q") != NULL);
if ((p = strstr(quals, "/T")) != NULL) { if ((p = strstr(quals, "/T")) != NULL) {
p = p + 2; p = p + 2;
@ -98,6 +99,7 @@ void WCMD_directory (void) {
/* Handle conflicting args and initialization */ /* Handle conflicting args and initialization */
if (bare || shortname) wide = FALSE; if (bare || shortname) wide = FALSE;
if (bare) shortname = FALSE; if (bare) shortname = FALSE;
if (wide) usernames = FALSE;
if (wide) { if (wide) {
if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo)) if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &consoleInfo))
@ -198,12 +200,12 @@ void WCMD_list_directory (char *search_path, int level) {
lstrcpyn (real_path, search_path, (p-search_path+2)); lstrcpyn (real_path, search_path, (p-search_path+2));
/* Load all files into an in memory structure */ /* Load all files into an in memory structure */
fd = malloc (sizeof(WIN32_FIND_DATA)); fd = HeapAlloc(GetProcessHeap(),0,sizeof(WIN32_FIND_DATA));
hff = FindFirstFile (search_path, fd); hff = FindFirstFile (search_path, fd);
if (hff == INVALID_HANDLE_VALUE) { if (hff == INVALID_HANDLE_VALUE) {
SetLastError (ERROR_FILE_NOT_FOUND); SetLastError (ERROR_FILE_NOT_FOUND);
WCMD_print_error (); WCMD_print_error ();
free (fd); HeapFree(GetProcessHeap(),0,fd);
return; return;
} }
do { do {
@ -216,7 +218,7 @@ void WCMD_list_directory (char *search_path, int level) {
if (tmpLen > widest) widest = tmpLen; if (tmpLen > widest) widest = tmpLen;
} }
fd = realloc (fd, (entry_count+1)*sizeof(WIN32_FIND_DATA)); fd = HeapReAlloc(GetProcessHeap(),0,fd,(entry_count+1)*sizeof(WIN32_FIND_DATA));
if (fd == NULL) { if (fd == NULL) {
FindClose (hff); FindClose (hff);
WCMD_output ("Memory Allocation Error"); WCMD_output ("Memory Allocation Error");
@ -235,6 +237,7 @@ void WCMD_list_directory (char *search_path, int level) {
} }
for (i=0; i<entry_count; i++) { for (i=0; i<entry_count; i++) {
char username[24];
/* /L convers all names to lower case */ /* /L convers all names to lower case */
if (lower) { if (lower) {
@ -242,6 +245,14 @@ void WCMD_list_directory (char *search_path, int level) {
while ( (*p = tolower(*p)) ) ++p; while ( (*p = tolower(*p)) ) ++p;
} }
/* /Q gets file ownership information */
if (usernames) {
p = strrchr (search_path, '\\');
lstrcpyn (string, search_path, (p-search_path+2));
lstrcat (string, (fd+i)->cFileName);
WCMD_getfileowner(string, username, sizeof(username));
}
if (dirTime == Written) { if (dirTime == Written) {
FileTimeToLocalFileTime (&(fd+i)->ftLastWriteTime, &ft); FileTimeToLocalFileTime (&(fd+i)->ftLastWriteTime, &ft);
} else if (dirTime == Access) { } else if (dirTime == Access) {
@ -283,13 +294,10 @@ void WCMD_list_directory (char *search_path, int level) {
dir_count++; dir_count++;
if (!bare) { if (!bare) {
if (shortname) { WCMD_output ("%10s %8s <DIR> ", datestring, timestring);
WCMD_output ("%10s %8s <DIR> %-13s%s\n", if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
datestring, timestring, (fd+i)->cAlternateFileName, (fd+i)->cFileName); if (usernames) WCMD_output ("%-23s", username);
} else { WCMD_output("%s\n",(fd+i)->cFileName);
WCMD_output ("%10s %8s <DIR> %s\n",
datestring, timestring, (fd+i)->cFileName);
}
} else { } else {
if (!((strcmp((fd+i)->cFileName, ".") == 0) || if (!((strcmp((fd+i)->cFileName, ".") == 0) ||
(strcmp((fd+i)->cFileName, "..") == 0))) { (strcmp((fd+i)->cFileName, "..") == 0))) {
@ -303,15 +311,11 @@ void WCMD_list_directory (char *search_path, int level) {
file_size.u.HighPart = (fd+i)->nFileSizeHigh; file_size.u.HighPart = (fd+i)->nFileSizeHigh;
byte_count.QuadPart += file_size.QuadPart; byte_count.QuadPart += file_size.QuadPart;
if (!bare) { if (!bare) {
if (shortname) { WCMD_output ("%10s %8s %10s ", datestring, timestring,
WCMD_output ("%10s %8s %10s %-13s%s\n", WCMD_filesize64(file_size.QuadPart));
datestring, timestring, if (shortname) WCMD_output ("%-13s", (fd+i)->cAlternateFileName);
WCMD_filesize64(file_size.QuadPart), (fd+i)->cAlternateFileName, (fd+i)->cFileName); if (usernames) WCMD_output ("%-23s", username);
} else { WCMD_output("%s\n",(fd+i)->cFileName);
WCMD_output ("%10s %8s %10s %s\n",
datestring, timestring,
WCMD_filesize64(file_size.QuadPart), (fd+i)->cFileName);
}
} else { } else {
WCMD_output ("%s%s\n", recurse?real_path:"", (fd+i)->cFileName); WCMD_output ("%s%s\n", recurse?real_path:"", (fd+i)->cFileName);
} }
@ -352,7 +356,7 @@ void WCMD_list_directory (char *search_path, int level) {
WCMD_list_directory (string, 1); WCMD_list_directory (string, 1);
} }
} }
free (fd); HeapFree(GetProcessHeap(),0,fd);
return; return;
} }
@ -411,3 +415,56 @@ int WCMD_dir_sort (const void *a, const void *b)
return (lstrcmpi(((const WIN32_FIND_DATA *)a)->cFileName, return (lstrcmpi(((const WIN32_FIND_DATA *)a)->cFileName,
((const WIN32_FIND_DATA *)b)->cFileName)); ((const WIN32_FIND_DATA *)b)->cFileName));
} }
/*****************************************************************************
* WCMD_getfileowner
*
* Reverse a character string in-place (strrev() is not available under unixen :-( ).
*/
void WCMD_getfileowner(char *filename, char *owner, int ownerlen) {
ULONG sizeNeeded = 0;
DWORD rc;
char name[MAXSTRING];
char domain[MAXSTRING];
/* In case of error, return empty string */
*owner = 0x00;
/* Find out how much space we need for the owner security descritpor */
GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, 0, 0, &sizeNeeded);
rc = GetLastError();
if(rc == ERROR_INSUFFICIENT_BUFFER && sizeNeeded > 0) {
LPBYTE secBuffer;
PSID pSID = NULL;
BOOL defaulted = FALSE;
ULONG nameLen = MAXSTRING;
ULONG domainLen = MAXSTRING;
SID_NAME_USE nameuse;
secBuffer = (LPBYTE) HeapAlloc(GetProcessHeap(),0,sizeNeeded * sizeof(BYTE));
if(!secBuffer) return;
/* Get the owners security descriptor */
if(!GetFileSecurity(filename, OWNER_SECURITY_INFORMATION, secBuffer,
sizeNeeded, &sizeNeeded)) {
HeapFree(GetProcessHeap(),0,secBuffer);
return;
}
/* Get the SID from the SD */
if(!GetSecurityDescriptorOwner(secBuffer, &pSID, &defaulted)) {
HeapFree(GetProcessHeap(),0,secBuffer);
return;
}
/* Convert to a username */
if (LookupAccountSid(NULL, pSID, name, &nameLen, domain, &domainLen, &nameuse)) {
snprintf(owner, ownerlen, "%s%c%s", domain, '\\', name);
}
HeapFree(GetProcessHeap(),0,secBuffer);
}
return;
}