1. Request for help; A dir cmd (C-001655)
- Posted by znorq2 May 04, 2009
- 1125 views
Hi,
I'm in urgent need for a directory command (Must be in Euphoria v3 / Win32Lib) that can list the following information;
- File/folder name - Owner - Accessed date
I'd like to have the output in an csv type file like this; name;owner;accessed
As it is quite urgent, I don't have the time to sit down and figure this out for my self, so I'd appreciate if any of you gentlemen/women could help me out here?
Thank you.
Kenneth / ZNorQ.
2. Re: Request for help; A dir cmd (C-001655)
- Posted by znorq2 May 04, 2009
- 1029 views
A small correction; It isn't a requirement that Win32Lib must be used.
Kenneth / ZNorQ
3. Re: Request for help; A dir cmd (C-001655)
- Posted by DerekParnell (admin) May 04, 2009
- 1054 views
Hi,
I'm in urgent need for a directory command (Must be in Euphoria v3 / Win32Lib) that can list the following information;
- File/folder name - Owner - Accessed date
I'd like to have the output in an csv type file like this; name;owner;accessed
As it is quite urgent, I don't have the time to sit down and figure this out for my self, so I'd appreciate if any of you gentlemen/women could help me out here?
Thank you.
Kenneth / ZNorQ.
To get the file names from a directory ...
#define _WIN32_WINNT 0x0501
#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <malloc.h>
#define BUFSIZE MAX_PATH
int main(int argc, char *argv[])
{
WIN32_FIND_DATA FindFileData;
HANDLE hFind = INVALID_HANDLE_VALUE;
DWORD dwError;
LPSTR DirSpec;
size_t length_of_arg;
DirSpec = (LPSTR) malloc (BUFSIZE);
// Check for command-line parameter; otherwise, print usage.
if(argc != 2)
{
printf("Usage: Test <dir>\n");
return 2;
}
// Check that the input is not larger than allowed.
StringCbLength(argv[1], BUFSIZE, &length_of_arg);
if (length_of_arg > (BUFSIZE - 2))
{
printf("Input directory is too large.\n");
return 3;
}
printf ("Target directory is %s.\n", argv[1]);
// Prepare string for use with FindFile functions. First,
// copy the string to a buffer, then append '\*' to the
// directory name.
StringCbCopyN (DirSpec, BUFSIZE, argv[1], length_of_arg+1);
StringCbCatN (DirSpec, BUFSIZE, "\\*", 3);
// Find the first file in the directory.
hFind = FindFirstFile(DirSpec, &FindFileData);
if (hFind == INVALID_HANDLE_VALUE)
{
printf ("Invalid file handle. Error is %u.\n", GetLastError());
return (-1);
}
else
{
printf ("First file name is %s.\n", FindFileData.cFileName);
// List all the other files in the directory.
while (FindNextFile(hFind, &FindFileData) != 0)
{
printf ("Next file name is %s.\n", FindFileData.cFileName);
}
dwError = GetLastError();
FindClose(hFind);
if (dwError != ERROR_NO_MORE_FILES)
{
printf ("FindNextFile error. Error is %u.\n", dwError);
return (-1);
}
}
free(DirSpec);
return (0);
}
To get the owner name and access date ...
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "accctrl.h"
#include "aclapi.h"
int main(int argc, char **argv)
{
DWORD dwRtnCode = 0;
PSID pSidOwner;
BOOL bRtnBool = TRUE;
LPTSTR AcctName, DomainName;
DWORD dwAcctName = 1, dwDomainName = 1;
SID_NAME_USE eUse = SidTypeUnknown;
HANDLE hFile;
PSECURITY_DESCRIPTOR pSD;
FILETIME CreationTime;
FILETIME LastAccessTime;
FILETIME LastWriteTime;
SYSTEMTIME AccessDT;
// Get the handle of an existing file.
hFile = CreateFile(
FileName, // TCHAR *
GENERIC_READ,
FILE_SHARE_READ,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
// Check GetLastError for CreateFile error code.
if (hFile == INVALID_HANDLE_VALUE) {
DWORD dwErrorCode = 0;
dwErrorCode = GetLastError();
_tprintf(TEXT("CreateFile error = %d\n"), dwErrorCode);
return -1;
}
dwRtnCode = GetFileTime(
hFile,
&CreationTime,
&LastAccessTime,
&LastWriteTime
);
FileTimeToSystemTime(
&LastAcessTime,
&AccesDT
);
char AccessDateString[100];
AccessDateString = sprintf("%04d/%02d/%02d %0d:%02d:%02d",
AccessDT.wYear,
AccessDT.wMonth,
AccessDT.wDay,
AccessDT.wHour;
AccessDT.wMinute,
AccessDT.wSecond
);
// Allocate memory for the SID structure.
pSidOwner = (PSID)GlobalAlloc(
GMEM_FIXED,
sizeof(PSID));
// Allocate memory for the security descriptor structure.
pSD = (PSECURITY_DESCRIPTOR)GlobalAlloc(
GMEM_FIXED,
sizeof(PSECURITY_DESCRIPTOR));
// Get the owner SID of the file.
dwRtnCode = GetSecurityInfo(
hFile,
SE_FILE_OBJECT,
OWNER_SECURITY_INFORMATION,
&pSidOwner,
NULL,
NULL,
NULL,
&pSD);
// Check GetLastError for GetSecurityInfo error condition.
if (dwRtnCode != ERROR_SUCCESS) {
DWORD dwErrorCode = 0;
dwErrorCode = GetLastError();
_tprintf(TEXT("GetSecurityInfo error = %d\n"), dwErrorCode);
return -1;
}
// First call to LookupAccountSid to get the buffer sizes.
bRtnBool = LookupAccountSid(
NULL, // local computer
pSidOwner,
AcctName,
(LPDWORD)&dwAcctName,
DomainName,
(LPDWORD)&dwDomainName,
&eUse);
// Reallocate memory for the buffers.
AcctName = (char *)GlobalAlloc(
GMEM_FIXED,
dwAcctName);
// Check GetLastError for GlobalAlloc error condition.
if (AcctName == NULL) {
DWORD dwErrorCode = 0;
dwErrorCode = GetLastError();
_tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
return -1;
}
DomainName = (char *)GlobalAlloc(
GMEM_FIXED,
dwDomainName);
// Check GetLastError for GlobalAlloc error condition.
if (DomainName == NULL) {
DWORD dwErrorCode = 0;
dwErrorCode = GetLastError();
_tprintf(TEXT("GlobalAlloc error = %d\n"), dwErrorCode);
return -1;
}
// Second call to LookupAccountSid to get the account name.
bRtnBool = LookupAccountSid(
NULL, // name of local or remote computer
pSidOwner, // security identifier
AcctName, // account name buffer
(LPDWORD)&dwAcctName, // size of account name buffer
DomainName, // domain name
(LPDWORD)&dwDomainName, // size of domain name buffer
&eUse); // SID type
// Check GetLastError for LookupAccountSid error condition.
if (bRtnBool == FALSE) {
DWORD dwErrorCode = 0;
dwErrorCode = GetLastError();
if (dwErrorCode == ERROR_NONE_MAPPED)
_tprintf(TEXT
("Account owner not found for specified SID.\n"));
else
_tprintf(TEXT("Error in LookupAccountSid.\n"));
return -1;
} else if (bRtnBool == TRUE)
// Print the account name.
_tprintf(TEXT("Account owner = %s\n"), AcctName);
return 0;
}
4. Re: Request for help; A dir cmd (C-001655)
- Posted by znorq2 May 04, 2009
- 1086 views
Ouch, that kinda seems like C to me! Thanks though, I'll see if I can make anything out of it.
That said, I did a little research on the existing dir cmd for Windows, and found that that there is a parameter (/q) which gives you the owner of the file/folder, combined with "/ta" which gives you the accessed date.
Abit crude as I got to format the output, but it gave me the result I so urgently needed.
Again, thanks, Derek - I'll see if I can compile this for future use.
Kenneth / ZNorQ
5. Re: Request for help; A dir cmd (C-001655)
- Posted by ghaberek (admin) May 04, 2009
- 1084 views
I've already wrapped most of the code Derek posted into Euphoria for win_dir.
-Greg
6. Re: Request for help; A dir cmd (C-001655)
- Posted by znorq2 May 05, 2009
- 1049 views
I've already wrapped most of the code Derek posted into Euphoria for win_dir.
-Greg
Rgr - think I recognize that library. I'll check it out.
Thanks again, Gents. ;)
Kenneth / ZNorQ
7. Re: Request for help; A dir cmd (C-001655)
- Posted by znorq2 May 06, 2009
- 1035 views
I've already wrapped most of the code Derek posted into Euphoria for win_dir.
-Greg
Hi Greg,
I've had a look through your code, and I see that it is only the "Modified date" that is returned (or am I mistaking?). I found out that with minor modifications I could get the "Created" and "Accessed" date too, but it would be nice to have this implemended in your orignal archive.
My solution is probably rather crude; that's because of my very basic knowledge of lowlevel memory handling, so I didn't want to mess too much around in your code.
What I did was to add a global integer (ZNQ_DATE_OUTPUT) that I'm using in the "format_entry()" function, where;
- 1 - Return Created date.
- 2 - Return Accessed date.
- 3 - Return Modified date.
I made sure that the global integer can't be lower than 1, nor higher than 3.
This is the changed code;
function format_entry( sequence wfd ) -- formats a proper dir() entry sequence entry object filetime, systemtime, localtime -- entry = repeat(0,9) entry[D_NAME] = wfd[9] entry[D_SIZE] = (wfd[5] * #10000) + wfd[6] entry[D_ATTRIBUTES] = format_attrib( wfd[1] ) filetime = FILETIME( wfd[ZNQ_DATE_OUTPUT+1] ) --<< Changes by ZNorQ. localtime = allocate( FILETIME_SIZE ) if c_func( xFileTimeToLocalFileTime, {filetime, localtime} ) then filetime = localtime systemtime = allocate( SYSTEMTIME_SIZE ) if c_func( xFileTimeToSystemTime, {filetime, systemtime} ) then systemtime = SYSTEMTIME( systemtime ) entry[D_YEAR] = systemtime[1] - 1900 entry[D_MONTH] = systemtime[2] entry[D_DAY] = systemtime[4] entry[D_HOUR] = systemtime[5] entry[D_MINUTE] = systemtime[6] entry[D_SECOND] = systemtime[7] end if end if return entry end function -------------------------------------------------------------------------------------- global function win_dir( sequence path ) -- returns directory information, given the name -- of a file or directory. Format returned is: -- { -- {"name1", attributes, size, year, month, day, hour, minute, second}, -- {"name2", ... }, -- } sequence attrib integer exit_code -- if (ZNQ_DATE_OUTPUT < 1) --<< Change by ZNorQ; Makes sure the integer isn't outside the legal range (1-3) or (ZNQ_DATE_OUTPUT > 3) --<< ... then ZNQ_DATE_OUTPUT = 3 --<< Defaults to "Modified" date. end if --<< ... -- if path[$] != '\\' then attrib = get_file_attrib( path ) if find( 'd', attrib ) then path &= '\\' end if end if files = {} exit_code = internal( path, gather_id, 0 ) if exit_code then return exit_code end if return files end function
Can you confirm that this is a ok enough way to do this?
Regards, Kenneth / ZNorQ
8. Re: Request for help; A dir cmd (C-001655)
- Posted by ghaberek (admin) May 06, 2009
- 990 views
Hi Greg,
I've had a look through your code, and I see that it is only the "Modified date" that is returned (or am I mistaking?). I found out that with minor modifications I could get the "Created" and "Accessed" date too, but it would be nice to have this implemended in your orignal archive.
My solution is probably rather crude; that's because of my very basic knowledge of lowlevel memory handling, so I didn't want to mess too much around in your code.
What I did was to add a global integer (ZNQ_DATE_OUTPUT) that I'm using in the "format_entry()" function, where;
- 1 - Return Created date.
- 2 - Return Accessed date.
- 3 - Return Modified date.
I made sure that the global integer can't be lower than 1, nor higher than 3.
code snipped
Can you confirm that this is a ok enough way to do this?
My code only returns the Modified Date because it's designed to be a drop-in replacement for Euphoria's own dir() function, which also returns the Modified Date.
What you did seems fine. If that works for you then go with it. Perhaps I will update that code with a win_dir_ex() function that returns extended information and/or takes additional parameters.
Although I remember that when writing this, I was thinking this method should just be the way Euphoria performs its internal dir() function anyway...
-Greg
9. Re: Request for help; A dir cmd (C-001655)
- Posted by znorq2 May 06, 2009
- 1046 views
Ok, if there isn't anything I've missed, I'll just use it as is. I could ofcourse do as you proposed to do yourself - create a new function that accepts parameters; Should be alot better. I really hate abusing global vars!
Thanks!
Kenneth / ZNorQ

