1. Request for help; A dir cmd (C-001655)

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.

new topic     » topic index » view message » categorize

2. Re: Request for help; A dir cmd (C-001655)

A small correction; It isn't a requirement that Win32Lib must be used.

Kenneth / ZNorQ

new topic     » goto parent     » topic index » view message » categorize

3. Re: Request for help; A dir cmd (C-001655)

znorq2 said...

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; 
} 

new topic     » goto parent     » topic index » view message » categorize

4. Re: Request for help; A dir cmd (C-001655)

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

new topic     » goto parent     » topic index » view message » categorize

5. Re: Request for help; A dir cmd (C-001655)

I've already wrapped most of the code Derek posted into Euphoria for win_dir. smile

-Greg

new topic     » goto parent     » topic index » view message » categorize

6. Re: Request for help; A dir cmd (C-001655)

ghaberek said...

I've already wrapped most of the code Derek posted into Euphoria for win_dir. smile

-Greg

Rgr - think I recognize that library. I'll check it out.

Thanks again, Gents. ;)

Kenneth / ZNorQ

new topic     » goto parent     » topic index » view message » categorize

7. Re: Request for help; A dir cmd (C-001655)

ghaberek said...

I've already wrapped most of the code Derek posted into Euphoria for win_dir. smile

-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

new topic     » goto parent     » topic index » view message » categorize

8. Re: Request for help; A dir cmd (C-001655)

znorq2 said...

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. blink

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. grin

Although I remember that when writing this, I was thinking this method should just be the way Euphoria performs its internal dir() function anyway... getlost

-Greg

new topic     » goto parent     » topic index » view message » categorize

9. Re: Request for help; A dir cmd (C-001655)

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

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu