Announcement

Collapse
No announcement yet.

How to get the date and time of creation of a file

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Stuart McLachlan
    replied
    Originally posted by Joseph Cote View Post
    Ah, that did it. I missed that method when reading through the help for powertime objects. Thank you.
    Post #3 uses it. See last line.

    "Note: Times displayed are local times, remove the pt.ToLocalTime lines to display as UTC"

    Help -> Dir$ is however confusing. It has a strange comment in the example code:

    t contains the file creation time in a localized format.

    There are two things wrong with that.
    1. It implies that it is local time.
    2. t contains a QUAD value, Nothing "localizable" about a QUAD. The fact that the string methods of a PowerTime are locale aware is a different thing entirely.

    Leave a comment:


  • Joseph Cote
    replied
    Ah, that did it. I missed that method when reading through the help for powertime objects. Thank you.

    Leave a comment:


  • Rod Macia
    replied
    joseph,
    its probably the time zone difference

    you can add

    t.FileTime = d.CreationTime
    t.ToLocalTime

    to the code you listed to get it in local time

    Leave a comment:


  • Joseph Cote
    replied
    Hi folks, I'm trying exactly this and the values being returned are NOT the same values I see in Windows Explorer (Using CC 6)

    Code:
    FUNCTION GetCreateDate(x AS STRING) AS STRING
    LOCAL f AS STRING
    LOCAL d AS DIRDATA
    LOCAL t AS IPOWERTIME
    t = CLASS "PowerTime"
    f = DIR$(x TO d)
    t.FileTime = d.CreationTime
    
    FUNCTION = FORMAT$(t.year,"0000") + FORMAT$(t.month,"00") + FORMAT$(t.day,"00") _
    + "_" + FORMAT$(t.hour,"00") + FORMAT$(t.minute,"00") + FORMAT$(t.second,"00")
    DIR$ CLOSE
    
    END FUNCTION
    For the files I've tried the date seems to be OK, the time is way off, one file WinExplorer says was created at 3 pm (should return "15" for the hour, getting "23" Edit: In fact ONLY the hour is wrong. I'm using Win8.1,

    Any suggestions?

    Leave a comment:


  • Tim Lakinir
    replied
    Thank you Pierre

    Leave a comment:


  • Pierre Bellisle
    replied
    Yes you are right Dear Dr. Watson. :-)
    The added buffer to the end of the exe file is made with NUL characters.
    Except for the last 12 bytes.
    "-Bloated" 8 bytes, is added at the end as a marker for the program to know if the exe was already bloated.
    Just before "-Bloated", there is a DWORD that say the bloat size.
    This way, it is easy to know if the exe is already bloated, and to remove the bloat if needed
    or remove the current bloat to put a new one...

    Leave a comment:


  • Tim Lakinir
    replied
    Pierre, in your FUNCTION BloatFile , it looks like you are adding some 12 bytes to the back of the file with a string of "-Bloated" and some NUL$ characters
    am I right?

    Leave a comment:


  • Tim Lakinir
    replied
    Thank you Pierre , I'll give a try on this

    Leave a comment:


  • Pierre Bellisle
    replied
    Tim,
    Yep I saw some complaint about #BLOAT, 496 is destination file write error.
    Having code in the exe to bloat itself is not really possible while the program is running because the OS will prevent any file write to it.
    On easy way is, once complied, to use a program to read the exe file as binary, add dummy data to the end, and save it.

    A little demo...
    Double check everything please...

    Code:
    #COMPILE EXE '#Win 10.04#
    #DIM ALL
    #REGISTER NONE
    #INCLUDE "Win32Api.inc"
    '#RESOURCE ".pbr"
    #RESOURCE MANIFEST, 1, "XPTheme.xml"
    
    GLOBAL hDlg AS DWORD
    
    $AppName            = "Bloat file"
    %StaticFileName     = 101
    %StaticInfo         = 102
    %ButtonOpenFilename = 201
    %ButtonBloat        = 202
    %ButtonRefresh      = 203
    %EditFileName       = 301
    %EditBloat          = 302
    '______________________________________________________________________________
    
    FUNCTION FileNameGet(hOwner AS DWORD, sInitialFolder AS STRING, sFilter AS STRING, FilterIndex As LONG) AS STRING
     LOCAL OpenFileNameStruct AS OPENFILENAME
     LOCAL zFileName          AS ASCIIZ * %MAX_PATH
     LOCAL sCaption           AS STRING
     LOCAL sFilename          AS STRING
    
     IF LEN(sInitialFolder)             = 0 THEN sInitialFolder = CURDIR$
     IF LEN(sFilter)                    = 0 THEN sFilter = "All Files (*.*)" & $NUL & "*.*" & $NUL & $NUL
     OpenFileNameStruct.lStructSize     = SIZEOF(OPENFILENAME)
     OpenFileNameStruct.hWndOwner       = hOwner
     OpenFileNameStruct.lpstrFilter     = STRPTR(sFilter)
     OpenFileNameStruct.nFilterIndex    = 1 'For demo purpose
     sCaption                           = "Choose Filename"
     OpenFileNameStruct.lpstrTitle      = STRPTR(sCaption)
     OpenFileNameStruct.lpstrInitialDir = STRPTR(sInitialFolder)
     OpenFileNameStruct.lpstrFileTitle  = VARPTR(zFileName)
     OpenFileNameStruct.nMaxFileTitle   = SIZEOF(zFileName)
     sFilename                          = NUL$(%MAX_PATH)
     OpenFileNameStruct.lpstrFile       = STRPTR(sFilename)
     OpenFileNameStruct.nMaxFile        = LEN(sFilename)
     OpenFileNameStruct.Flags           = %OFN_CREATEPROMPT OR %OFN_FILEMUSTEXIST
    
     GetOpenFileName(OpenFileNameStruct)
     FilterIndex = OpenFileNameStruct.nFilterIndex
     sFilename   = RTRIM$(sFilename, $NUL)
     IF LEN(sFilename) THEN FUNCTION = sFilename 'With path
    
    END FUNCTION
    '_____________________________________________________________________________
    
    FUNCTION BloatFile(BYVAL sFileName AS STRING, BYVAL ToBloatSize AS DWORD, BYVAL Action AS LONG) AS DWORD
     LOCAL sBuffer     AS STRING
     LOCAL BloatedSize AS DWORD
     LOCAL hFile       AS DWORD
    
     ERRCLEAR
     hFile = FREEFILE
     OPEN sFileName FOR BINARY ACCESS READ SHARED AS hFile
     IF ERR THEN
       MessageBox(%HWND_DESKTOP, "Error opening file", $AppName, %MB_OK OR %MB_TOPMOST) : EXIT FUNCTION
     END IF
     SEEK hFile, 1
     GET$ hFile, LOF(hFile), sBuffer
     CLOSE hFile
    
     IF RIGHT$(sBuffer, 8) = "-Bloated" THEN
       BloatedSize = PEEK(DWORD, STRPTR(sBuffer) + LEN(sBuffer) - 12)
       FUNCTION = BloatedSize
     END IF
    
     IF Action = 1 THEN
       IF BloatedSize = 0 THEN
         IF ToBloatSize < 12 THEN
           MessageBox(%HWND_DESKTOP, "Bloat size must be 12 or more", $AppName, %MB_OK OR %MB_TOPMOST)
           EXIT FUNCTION
         END IF
       END IF
       IF ToBloatSize = BloatedSize THEN
         MessageBox(%HWND_DESKTOP, "No change in bloat size", $AppName, %MB_OK OR %MB_TOPMOST)
         EXIT FUNCTION
       END IF
       sBuffer = LEFT$(sBuffer, LEN(sBuffer)- BloatedSize)
       sBuffer = sBuffer & NUL$(ToBloatSize - 12) & MKDWD$(ToBloatSize) & "-Bloated"
       hFile = FREEFILE
       ERRCLEAR
       OPEN sFileName FOR BINARY ACCESS WRITE SHARED AS hFile
       IF ERR THEN
         MessageBox(%HWND_DESKTOP, "Error writing to file", $AppName, %MB_OK OR %MB_TOPMOST)
         EXIT FUNCTION
       END IF
       SEEK hFile, 1
       PUT$ hFile, sBuffer
       SETEOF(hFile)
       CLOSE hFile
     END IF
    
    END FUNCTION
    '_____________________________________________________________________________
    
    CALLBACK FUNCTION DlgProc
     STATIC zFileName   AS ASCIIZ * %MAX_PATH
     STATIC ToBloatSize AS DWORD
    
     SELECT CASE CBMSG
    
       CASE %WM_COMMAND
         SELECT CASE CBCTL
    
           CASE %ButtonOpenFilename
             IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
               zFileName = FileNameGet(hDlg, "", "exe Files (*.exe)" & $NUL & "*.exe" & $NUL & _
                                                 "All Files (*.*)"   & $NUL & "*.*"   & $NUL & $NUL, 1)
               IF LEN(zFileName) THEN
                 SetDlgItemText(hDlg, %EditFileName, zFileName)
                 SetDlgItemText(hDlg, %StaticInfo, "File selected")
               ELSE
                 SetDlgItemText(hDlg, %StaticInfo, "No file selected")
               END IF
             END IF
    
           CASE %ButtonRefresh
             IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
               GetDlgItemText(hDlg, %EditFileName, zFileName, SIZEOF(zFileName))
               SetDlgItemInt(hDlg, %EditBloat, BloatFile(zFileName, 0, 0), %FALSE)
               SetDlgItemText(hDlg, %StaticInfo, "Refresh done")
             END IF
    
           CASE %ButtonBloat
             IF CBCTLMSG = %BN_CLICKED OR CBCTLMSG = 1 THEN
               GetDlgItemText(hDlg, %EditFileName, zFileName, SIZEOF(zFileName))
               ToBloatSize = GetDlgItemInt(hDlg, %EditBloat, 0, %FALSE)
               BloatFile(zFileName, ToBloatSize, 01)
               SetDlgItemText(hDlg, %StaticInfo, "Bloat done")
             END IF
    
         END SELECT
    
       CASE %WM_SIZE 'Dialog size have changed
         LOCAL ClientSizeX AS LONG
         LOCAL ClientSizeY AS LONG
         IF CBWPARAM <> %SIZE_MINIMIZED THEN
           ClientSizeX = LO(WORD, CBLPARAM)
           ClientSizeY = HI(WORD, CBLPARAM)
           MoveWindow(GetDlgItem(hDlg, %EditFileName), 10, 30, ClientSizeX - 20, 20, %TRUE)
         END IF
    
      END SELECT
    
    END FUNCTION
    '_____________________________________________________________________________
    
    FUNCTION PBMAIN()
     LOCAL  sCueBannerUnicode1 AS STRING
     LOCAL hIcon               AS DWORD
    
     DIALOG FONT "Segoe UI", 9
     DIALOG NEW %HWND_DESKTOP, $AppName, , , 200, 75, _
     %WS_CAPTION OR %WS_MINIMIZEBOX OR %WS_MAXIMIZEBOX OR %WS_SIZEBOX OR %WS_SYSMENU, %WS_EX_LEFT TO hDlg
    
     hIcon = ExtractIcon(GETMODULEHANDLE(""), "Shell32.dll", 294) 'o
     SetClassLong(hDlg, %GCL_HICON, hIcon)
    
     SetClassLong(hDlg, %GCL_HICONSM, hIcon)
    
     CONTROL ADD LABEL, hDlg, %StaticFileName, "File name to bloat", 5, 5, 60, 10, %SS_CENTER
    
     CONTROL ADD TEXTBOX, hDlg, %EditFileName, "", 5, 15, 60, 10, _
     %ES_LEFT OR %ES_NOHIDESEL  OR %WS_TABSTOP, %WS_EX_LEFT OR %WS_EX_STATICEDGE
     sCueBannerUnicode1 = UCODE$("file name to bloat")
     SendMessage(GetDlgItem(hDlg, %EditFileName), %EM_SETCUEBANNER, 1, BYVAL STRPTR(sCueBannerUnicode1)) 'XP+
    
     CONTROL ADD BUTTON, hDlg, %ButtonOpenFilename, "Select file", 5, 35, 50, 15
    
     CONTROL ADD BUTTON, hDlg, %ButtonRefresh, "Refresh", 60, 35, 50, 15
    
     CONTROL ADD BUTTON, hDlg, %ButtonBloat, "Do bloat", 5, 55, 50, 15
    
     CONTROL ADD TEXTBOX, hDlg, %EditBloat, "", 60, 57, 50, 12, _
     %ES_LEFT OR %ES_NOHIDESEL OR %ES_NUMBER OR %WS_TABSTOP, %WS_EX_LEFT OR %WS_EX_STATICEDGE
     sCueBannerUnicode1 = UCODE$("bloat byte size")
     SendMessage(GetDlgItem(hDlg, %EditBloat), %EM_SETCUEBANNER, 1, BYVAL STRPTR(sCueBannerUnicode1)) 'XP+
    
     CONTROL ADD LABEL, hDlg, %StaticInfo, "-info", 115, 58, 60, 10, %SS_LEFT
    
     DIALOG SHOW MODAL hDlg CALL DlgProc
    
     DestroyIcon(hIcon)
    
    END FUNCTION
    '_____________________________________________________________________________
    '
    Last edited by Pierre Bellisle; 10 Mar 2020, 12:33 PM.

    Leave a comment:


  • Tim Lakinir
    replied
    Pierre , I have read the PB help manual but still not able to use BLOAT statement and each time, I compile with it gives an error 496 ?

    From searching this forum, some users also encounter same error 496 when they use BLOAT
    It would be useful to have some kind of BLOAT in the program as if to project an image that the program is a heavy weight and something to reckon with?

    Leave a comment:


  • Pierre Bellisle
    replied
    @ Dale,
    Yep, and no space are allowed in a twitter name.

    Leave a comment:


  • Pierre Bellisle
    replied
    Hey Tim,
    No problem, it was there just to artificially increase the file size to get an idea of file size vs the pe file size.

    Leave a comment:


  • Tim Lakinir
    replied
    Thank you Pierre

    When compile, I got error 496 and I then comment out the below statemnet and it works

    #BLOAT 1024 * 1024 * 4 'For test purpose

    Leave a comment:


  • Dale Yarker
    replied
    e-mail would be [email protected] ("@" after name )

    Leave a comment:


  • Pierre Bellisle
    replied
    It was an eMail...

    Leave a comment:


  • Dale Yarker
    replied
    (I do not twitter, so @ is inapropriate )

    Leave a comment:


  • Pierre Bellisle
    replied
    @ Dale,
    As you know, from Windows Explorer for a file propertie, you will have "Size" and "Size on disk".
    We also know that "Size on disk" is a disk cluster size multiple. And cluster are based on sector size.
    The "Size" is the real file size.
    For a .txt as example, it can be anything. 0, 1, 2,3,... whatever bytes.
    An .exe will have, due to the way it is made, a size based on many structures and parameters.

    Interesting stuff... PE Format

    Also interesting Microsoft support policy for 4K sector hard drives in Windows

    Leave a comment:


  • Pierre Bellisle
    replied
    I think original code was from Semen Matusovski and Steven Pringels,
    I cant find it on the forum, here is my version...

    Code:
    #COMPILE EXE '#Win#
    #DIM ALL
    #INCLUDE "Win32api.inc"
    
    #BLOAT  1024 * 1024 * 4 'For test purpose
    '______________________________________________________________________________
    
    FUNCTION GetExePeInfo(szExeFileName AS STRING) AS STRING
     LOCAL pImageSectionHeader AS IMAGE_SECTION_HEADER POINTER
     LOCAL pImageDosHeader     AS IMAGE_DOS_HEADER POINTER
     LOCAL pImageNtHeaders     AS IMAGE_NT_HEADERS POINTER
     LOCAL pz                  AS STRINGZ POINTER
     LOCAL sInfo               AS STRING
     LOCAL sExeData            AS STRING
     LOCAL hFile               AS DWORD
     LOCAL RawSize             AS DWORD
     LOCAL Looper              AS LONG
    
     ERRCLEAR
     hFile = FREEFILE
     OPEN szExeFileName FOR BINARY SHARED AS #hFile
     IF ERR THEN
       FUNCTION = "Can not open file" : EXIT FUNCTION
     ELSE
       GET$ #hFile, LOF(hFile), sExeData
     END IF
     sInfo = "LOF(hFile) = " & FORMAT$(LOF(hFile), "#,") & " bytes" & $CRLF & $CRLF
     CLOSE #hFile
    
     pImageDosHeader = STRPTR(sExeData)
     IF LEN(sExeData) < SIZEOF(IMAGE_DOS_HEADER) THEN
       FUNCTION = "Size error" : EXIT FUNCTION
     END IF
    
     IF @pImageDosHeader.e_magic <> %IMAGE_DOS_SIGNATURE THEN
       FUNCTION = "Magic error" : EXIT FUNCTION
     END IF
    
     IF LEN(sExeData) < @pImageDosHeader.e_lfanew + SIZEOF(IMAGE_NT_HEADERS) THEN
       FUNCTION = "Size error bis" : EXIT FUNCTION
     END IF
    
     pImageNtHeaders = pImageDosHeader + @pImageDosHeader.e_lfanew
    
     IF @pImageNtHeaders.Signature <> %IMAGE_NT_SIGNATURE THEN
       FUNCTION = "Signature error" : EXIT FUNCTION
     END IF
    
     IF (@pImageNtHeaders.FileHeader.SizeOfOptionalHeader <> SIZEOF(@pImageNtHeaders.OptionalHeader)) OR _
       (@pImageNtHeaders.OptionalHeader.Magic <> %IMAGE_NT_OPTIONAL_HDR32_MAGIC) THEN
       FUNCTION = "Optional magic error" : EXIT FUNCTION
     END IF
    
     IF @pImageNtHeaders.FileHeader.NumberOfSections < 1 THEN
       FUNCTION = "Section count error" : EXIT FUNCTION
     END IF
    
     pImageDosHeader     = STRPTR(sExeData)
     pImageNtHeaders     = pImageDosHeader + @pImageDosHeader.e_lfanew
     pImageSectionHeader = pImageNtHeaders + SIZEOF(IMAGE_NT_HEADERS)
    
     sInfo &= "Number of sections: " & FORMAT$(@pImageNtHeaders.FileHeader.NumberOfSections) & $CRLF
    
     FOR Looper = 0 TO @pImageNtHeaders.FileHeader.NumberOfSections - 1
        pz = VARPTR(@pImageSectionHeader[Looper].bName(0))
        sInfo &= @pz & "RawData :" & FORMAT$(@pImageSectionHeader[Looper].SizeOfRawData, "0,") & _
                 " bytes, Pointer to raw data: 0x" & Hex$(@pImageSectionHeader[Looper].PointerToRawData, 8) & $CRLF
       IF LEFT$(@pz, 5) = ".rloc" THEN
         rawsize = @pImageSectionHeader[Looper].PointerToRawData + _
                   @pImageSectionHeader[Looper].SizeOfRawData
         sInfo &= "Name   : " &  @pz  & $CRLF
         sInfo &= "Rawsize: " &  FORMAT$(Rawsize, "###,###") & $CRLF
       END IF
     NEXT
    
     FUNCTION = sInfo
    
    END FUNCTION
    '______________________________________________________________________________
    
    FUNCTION PBMAIN()
    
     GetExePeInfo(EXE.Full$)
     SLEEP 100 '
     MessageBox(%HWND_DESKTOP, GetExePeInfo(EXE.Full$) & $CRLF & "", "PE header", %MB_OK OR %MB_TOPMOST)
    
    END FUNCTION
    '______________________________________________________________________________
    '

    Leave a comment:


  • Tim Lakinir
    replied
    Hi Pierre, in your post#15 , what is the name of the application did you use to create those PE header results?
    It is interesting as you can see many parameters of the PE header.

    Leave a comment:


  • Dale Yarker
    replied
    I only noticed that 2nd number in post 13 was multiple of 2048, and difference between numbers was less than 2048.

    I have no other comment or opinion re this thread.

    Cheers,

    Leave a comment:

Working...
X