The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: ChillyWilly on February 14, 2010, 07:24:30 PM

Title: Getting Folder LastAccess Date
Post by: ChillyWilly on February 14, 2010, 07:24:30 PM
not sure if i have the structure right for this


.data
modified  db ""Date Modified",0
folderpath db "C:\Windows",0
FmtSysTime db "Last Modified: %d\%d\%d @ %d:%d:%d", 0

.data?
lpLastAccess db 128 dup (?)
    ftime FILETIME <>
    stime SYSTEMTIME <>



invoke CreateFile, addr folderpath, GENERIC_READ, FILE_SHARE_READ, NULL,\
                        OPEN_EXISTING, FILE_ATTRIBUTE_DIRECTORY, NULL
                  mov esi, EAX
                  invoke GetFileTime,esi,0,addr ftime,0
                  Invoke CloseHandle, esi
                  invoke FileTimeToSystemTime,addr ftime,addr stime

mov edi,offset stime
assume edi: ptr SYSTEMTIME
movzx eax, [edi]. wYear
movzx ebx, [edi]. wMonth
movzx ecx, [edi]. wDay
movzx edx, [edi]. wHour
movzx esi, [edi]. wMinute
movzx edi, [edi]. wSecond
assume edi: nothing

invoke wsprintf, addr lpLastAccess, addr FmtSysTime,\
                ecx, ebx, eax, edx, esi, edi
invoke MessageBox,0,addr lpLastAccess,addr modified,0


it results in "Last Modified: 1\1\1601 @ 0:0:0"
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 14, 2010, 07:34:46 PM
Hi Chilly Willy,

Is this working ? If not is it giving you an error or bad data ? If so what is the error code ? Or are we supposed to create a skeleton and assemble the code to find out ?

Edgar
Title: Re: Getting Folder LastAccess Date
Post by: oex on February 14, 2010, 07:37:56 PM
Quote from: ChillyWilly on February 14, 2010, 07:24:30 PM
it results in "Last Modified: 1\1\1601"

And you are sure it was modified after this?
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 14, 2010, 07:45:01 PM
Well, using wsprintf for this is the wrong way to go

stLocal SYSTEMTIME <>

szTempDate TCHAR 64 DUP (?)
szTempTime TCHAR 64 DUP (?)
szFileTime TCHAR 256 DUP (?)

fi BY_HANDLE_FILE_INFORMATION <>


invoke CreateFile,"SomeFile.txt",GENERIC_READ,NULL,NULL,OPEN_EXISTING,NULL,NULL
mov edi,eax
invoke GetFileInformationByHandle,edi,offset fi
invoke CloseHandle,edi

invoke FileTimeToSystemTime,offset fi.ftLastWriteTime,offset stLocal
invoke GetDateFormat,LOCALE_SYSTEM_DEFAULT,NULL,OFFSET stLocal,"dd MMM yyyy ",OFFSET szTempDate,64
invoke GetTimeFormat,LOCALE_SYSTEM_DEFAULT,NULL,OFFSET stLocal,"hh:mm tt",OFFSET szTempTime,64

invoke lstrcpy,OFFSET szFileTime,OFFSET szTempDate
invoke lstrcat,OFFSET szFileTime,OFFSET szTempTime


Not sure what the inline string thingy is in MASM, you'll have to add that to the format code.
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 14, 2010, 07:45:58 PM
Quote from: oex on February 14, 2010, 07:37:56 PM
Quote from: ChillyWilly on February 14, 2010, 07:24:30 PM
it results in "Last Modified: 1\1\1601"

And you are sure it was modified after this?

Think that's date 0, all members of the structure are NULL.
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 14, 2010, 08:15:05 PM
Edit : don't really need security attribute for this:

invoke CreateFile,"D:\MyFolder",GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL
push eax
invoke GetFileInformationByHandle,eax,offset fi
call CloseHandle

invoke FileTimeToSystemTime,offset fi.ftLastWriteTime ,offset stLocal
invoke GetDateFormat,LOCALE_SYSTEM_DEFAULT,NULL, OFFSET stLocal,"dd MMM yyyy ",OFFSET szTempDate,64
invoke GetTimeFormat,LOCALE_SYSTEM_DEFAULT,NULL,OFFSET stLocal,"hh:mm tt",OFFSET szTempTime,64

invoke lstrcpy,OFFSET szFileTime,OFFSET szTempDate
invoke lstrcat,OFFSET szFileTime,OFFSET szTempTime


Edgar
Title: Re: Getting Folder LastAccess Date
Post by: ChillyWilly on February 14, 2010, 11:15:02 PM
attached as a winasm project
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 14, 2010, 11:26:17 PM
Hi Chilly Willy,

The code in my last post works well. You have to use FILE_FLAG_BACKUP_SEMANTICS not FILE_ATTRIBUTE_DIRECTORY to open a folder the way you want to.

Edgar
Title: Re: Getting Folder LastAccess Date
Post by: ChillyWilly on February 14, 2010, 11:44:38 PM
modified my code a little bit and it works ,, only one problem now
Last Modified: 2\10\2010 @ 22:7:55

the time is showing in 24 hour format
how do i make the time 5:07:55 pm


invoke SendDlgItemMessage,hWin,IDC_EDIT1002,WM_GETTEXT,sizeof folderpath,addr folderpath
invoke CreateFile, addr folderpath, GENERIC_READ, FILE_SHARE_READ, NULL,\
                        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL
                       
                  mov esi, eax
                  invoke GetFileInformationByHandle,esi,offset fi
                  Invoke CloseHandle, esi
                  invoke FileTimeToSystemTime,addr fi.ftLastWriteTime,addr stime

mov edi,offset stime
assume edi: ptr SYSTEMTIME
movzx eax, [edi]. wYear
movzx ebx, [edi]. wMonth
movzx ecx, [edi]. wDay
movzx edx, [edi]. wHour
movzx esi, [edi]. wMinute
movzx edi, [edi]. wSecond
assume edi: nothing
invoke wsprintf, addr lpLastAccess, addr FmtSysTime,\
  ebx,ecx, eax, edx, esi, edi

invoke SendDlgItemMessage,hWin,IDC_EDIT1002,WM_SETTEXT,0,addr lpLastAccess
Title: Re: Getting Folder LastAccess Date
Post by: ChillyWilly on February 14, 2010, 11:57:41 PM
ok i broke down and did it your way  :lol

.386
.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc
include comctl32.inc ;windows common controls

includelib user32.lib
includelib kernel32.lib
includelib comctl32.lib ;windows common controls

DlgProc PROTO :DWORD,:DWORD,:DWORD,:DWORD

.const
IDD_MAIN equ 1000
IDB_TIME equ 1001
IDC_EDIT1 equ 1002
.data
FmtSysTime db "Last Modified: %s @ %s", 0
szTimeFormat    db "HH:mm:ss", 0
szDateFormat db "MMM dd, yyyy",0
.data?
hInstance dd ?
szTime db 128 dup (?)
szDate db 128 dup (?)
output db 256 dup (?)
folder db 128 dup (?)
systime SYSTEMTIME <>
fi BY_HANDLE_FILE_INFORMATION <>
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke InitCommonControls
invoke DialogBoxParam, hInstance, IDD_MAIN, 0, offset DlgProc, 0
invoke ExitProcess, eax


DlgProc proc hWin:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
mov eax,uMsg

.if eax == WM_INITDIALOG
invoke LoadIcon,hInstance,200
invoke SendMessage, hWin, WM_SETICON, 1, eax
.elseif eax == WM_COMMAND
mov eax,wParam
.if eax == IDB_TIME
invoke SendDlgItemMessage,hWin,IDC_EDIT1,WM_GETTEXT,sizeof folder,addr folder
invoke CreateFile, addr folder, GENERIC_READ, FILE_SHARE_READ, NULL,\
                        OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL   
                  mov esi, eax
                  invoke GetFileInformationByHandle,esi,offset fi
                  Invoke CloseHandle, esi
                  invoke FileTimeToSystemTime,addr fi.ftLastWriteTime,addr systime
                  invoke GetDateFormat,0,0, addr systime,addr szDateFormat,addr szDate,64
      invoke GetTimeFormat, 0, 0, addr systime,addr szTimeFormat,addr szTime, 20
         
          invoke wsprintf,addr output,addr FmtSysTime,addr szDate,addr szTime
invoke SendDlgItemMessage,hWin,IDC_EDIT1,WM_SETTEXT,0,addr output
.endif
.elseif eax == WM_CLOSE
invoke EndDialog, hWin, 0
.endif

xor eax,eax
ret
DlgProc endp

end start


the output now looks like:
Last Modified: Feb 10, 2010 @ 22:07:55

now the only thing i need to to convert the 24hr time "22:07:55" to "10:07:55 PM"
any advice on that?
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 15, 2010, 12:21:41 AM
Change "hh:mm tt" to "HH:mm:ss" (capital H for a 24 hour clock)

http://msdn.microsoft.com/en-us/library/dd318131%28VS.85%29.aspx

You dont need wsprintf, you can insert string data in single quotes right in the format string:

"'Last Modified:' dd MMM yyyy "

For example

.DATA
stLocal SYSTEMTIME <>
szFileTime TCHAR 256 DUP (?)
fi BY_HANDLE_FILE_INFORMATION <>

.CODE
invoke CreateFile,"D:\MyFolder",GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL
push eax
invoke GetFileInformationByHandle,eax,offset fi
call CloseHandle

invoke FileTimeToSystemTime,offset fi.ftLastWriteTime ,offset stLocal
invoke GetDateFormat,LOCALE_SYSTEM_DEFAULT,NULL, OFFSET stLocal,"'Last Modified:' MMM dd, yyyy ",OFFSET szFileTime,64
push edi
mov edi,OFFSET szFileTime
mov ecx,256
xor eax,eax
repne scasb ; scasw for Unicode
dec edi ; sub edi,2 for Unicode
invoke GetTimeFormat,LOCALE_SYSTEM_DEFAULT,NULL,OFFSET stLocal,"'@' HH:mm:ss",edi,64
pop edi


I got rid of the lstrcpy and lstrcat, they weren't really needed anyway. Much faster than wsprintf this way...

Output:
Last Modified: Jul 07, 2009 @ 03:41:37

Also, you use ESI and do not preserve it, your application will crash eventually. You are not using the handle anywhere else so you might as well use the push/call method. There are only 7 registers and you don't really need one here so why use it ?
Title: Re: Getting Folder LastAccess Date
Post by: ChillyWilly on February 15, 2010, 12:48:32 AM
using hh:mm  tt

but the result is exactly 5 hours from the time explorer says it was modified

in explorer details view it says modified 3:37 am
but my code says modified 8:37 am
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 15, 2010, 12:52:42 AM
Hi Chilly Willy,

Hint: where do you live ?

Edgar
Title: Re: Getting Folder LastAccess Date
Post by: ChillyWilly on February 15, 2010, 12:55:45 AM
ah i got it , i need to use FileTimeToLocalFileTime before i call FileTimeToSystemTime
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 15, 2010, 01:06:32 AM
So here's my final version Chilly Willy,

Sorry about the inline strings but its just easier that way...

ftime FILETIME <?>
stLocal SYSTEMTIME <?>
szFileTime TCHAR 256 DUP (?)
fi BY_HANDLE_FILE_INFORMATION <?>


invoke CreateFile,"D:\MyFolder",GENERIC_READ,NULL,NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL
push eax
invoke GetFileInformationByHandle,eax,offset fi
call CloseHandle

invoke FileTimeToLocalFileTime,offset fi.ftLastWriteTime ,offset ftime
invoke FileTimeToSystemTime,offset ftime ,offset stLocal
invoke GetDateFormat,LOCALE_SYSTEM_DEFAULT,NULL, OFFSET stLocal,"'Last Modified:' MMM dd, yyyy ",OFFSET szFileTime,64
push edi
mov edi,OFFSET szFileTime
mov ecx,256
xor eax,eax
repne scasb
dec edi
invoke GetTimeFormat,LOCALE_SYSTEM_DEFAULT,NULL,OFFSET stLocal,"'@' h:mm:ss",edi,64
pop edi


No wsprintf, no extraneous register usage, preserves EDI (which is required) and formats the string how you want (I had misunderstood your 24Hr thing). Also since your using AM/PM I have removed the leading zero from the time.

Output:
Last Modified: Jul 06, 2009 @ 8:41 PM
Title: Re: Getting Folder LastAccess Date
Post by: sinsi on February 15, 2010, 01:11:02 AM
Any reason for using CreateFile instead of FindFirstFile?
Title: Re: Getting Folder LastAccess Date
Post by: donkey on February 15, 2010, 01:27:13 AM
Quote from: sinsi on February 15, 2010, 01:11:02 AM
Any reason for using CreateFile instead of FindFirstFile?

Either work  just as effectively, in this case it really makes no difference. I just used CreateFile because Chilly Willy did.

ftime FILETIME <?>
stLocal SYSTEMTIME <?>
szFileTime TCHAR 256 DUP (?)
wfd WIN32_FIND_DATA <?>


invoke FindFirstFile,"D:\MyFolder",OFFSET wfd
invoke FindClose,eax

invoke FileTimeToLocalFileTime,offset wfd.ftLastWriteTime ,offset ftime
invoke FileTimeToSystemTime,offset ftime ,offset stLocal
invoke GetDateFormat,LOCALE_SYSTEM_DEFAULT,NULL, OFFSET stLocal,"'Last Modified:' MMM dd, yyyy ",OFFSET szFileTime,64
push edi
mov edi,OFFSET szFileTime
mov ecx,256
xor eax,eax
repne scasw
dec edi
dec edi
invoke GetTimeFormat,LOCALE_SYSTEM_DEFAULT,NULL,OFFSET stLocal,"'@' h:mm tt",edi,64
pop edi


Title: Re: Getting Folder LastAccess Date
Post by: oex on April 03, 2010, 01:50:57 PM
QuoteNote:  In rare cases, file information on NTFS file systems may not be current at the time you call this function. To be assured of getting the current file information, call the GetFileInformationByHandle function.

http://msdn.microsoft.com/en-us/library/aa364418(VS.85).aspx

I think this applies.... fyi