Repository :
https://github.com/FarGroup/FarManager
On branch : master
Link :
https://github.com/FarGroup/FarManager/commit/b5ef796f9f69eeb983b6823369ac5ce940cd111b
>---------------------------------------------------------------
commit b5ef796f9f69eeb983b6823369ac5ce940cd111b
Author: Rohitab Batra <
roh...@rohitab.com>
Date: Sat Sep 27 15:57:36 2025 +1000
gh-611: LuaMacro plugin: Enable win.GetFileTimes/win.SetFileTimes to get/set change time (#1014)
>---------------------------------------------------------------
b5ef796f9f69eeb983b6823369ac5ce940cd111b
enc/enc_lua/luafar_manual.tsi | 10 +++---
plugins/luamacro/_globalinfo.lua | 2 +-
plugins/luamacro/changelog | 4 +++
plugins/luamacro/luafar/lf_version.h | 2 +-
plugins/luamacro/luafar/lf_win.c | 67 +++++++++++++++++++++++-------------
5 files changed, 56 insertions(+), 29 deletions(-)
diff --git a/enc/enc_lua/luafar_manual.tsi b/enc/enc_lua/luafar_manual.tsi
index b0005ad1e..49e01f9c9 100644
--- a/enc/enc_lua/luafar_manual.tsi
+++ b/enc/enc_lua/luafar_manual.tsi
@@ -9920,7 +9920,7 @@ lv=3
dt=Text
nm=win.GetFileTimes
ctime=3790916234
-mtime=3790917671
+mtime=3968140988
<article>
#_times = win.GetFileTimes (FileName)
#_
@@ -9933,12 +9933,13 @@ mtime=3790917671
#_ LastWriteTime: `bit64-userdata`
#_ LastAccessTime: `bit64-userdata`
#_ CreationTime: `bit64-userdata`
+#_ ChangeTime: `bit64-userdata`
#_
#_**Note:**
#_ All time values are expressed in 100-ns intervals elapsed since 1601-01-01,00:00:00.
#_
#_**Windows API used:**
-#_ CreateFile, GetFileTime
+#_ CreateFile, NtQueryInformationFile
#_
#_@@@
#_[bit64-userdata]: 405.html
@@ -10154,7 +10155,7 @@ lv=3
dt=Text
nm=win.SetFileTimes
ctime=3790916254
-mtime=3790917726
+mtime=3968141009
<article>
#_result = win.SetFileTimes (FileName, times)
#_
@@ -10165,6 +10166,7 @@ mtime=3790917726
#_ LastWriteTime: `bit64-userdata` or number
#_ LastAccessTime: `bit64-userdata` or number
#_ CreationTime: `bit64-userdata` or number
+#_ ChangeTime: `bit64-userdata` or number
#_
#_**Returns:**
#_ result: boolean
@@ -10173,7 +10175,7 @@ mtime=3790917726
#_ All time values are expressed in 100-ns intervals elapsed since 1601-01-01,00:00:00.
#_
#_**Windows API used:**
-#_ CreateFile, SetFileTime
+#_ CreateFile, NtSetInformationFile
#_
#_@@@
#_[bit64-userdata]: 405.html
diff --git a/plugins/luamacro/_globalinfo.lua b/plugins/luamacro/_globalinfo.lua
index d8ae27ff7..d7409860f 100644
--- a/plugins/luamacro/_globalinfo.lua
+++ b/plugins/luamacro/_globalinfo.lua
@@ -1,6 +1,6 @@
function export.GetGlobalInfo()
return {
- Version = { 3, 0, 0, 892 },
+ Version = { 3, 0, 0, 893 },
MinFarVersion = { 3, 0, 0, 6546 },
Guid = win.Uuid("4EBBEFC8-2084-4B7F-94C0-692CE136894D"),
Title = "LuaMacro",
diff --git a/plugins/luamacro/changelog b/plugins/luamacro/changelog
index e224f6445..8bd19f2cf 100644
--- a/plugins/luamacro/changelog
+++ b/plugins/luamacro/changelog
@@ -1,3 +1,7 @@
+rohitab 2025-09-27 13:33:20+10:00 - build 893
+
+1. gh-611: Enable win.GetFileTimes/win.SetFileTimes to get/set change time.
+
shmuel 2025-09-26 10:38:38+03:00 - build 892
1. LuaFAR: rename actl.Waitkey to actl.WaitKey
diff --git a/plugins/luamacro/luafar/lf_version.h b/plugins/luamacro/luafar/lf_version.h
index 5e59a2ee6..3e3c6d55d 100644
--- a/plugins/luamacro/luafar/lf_version.h
+++ b/plugins/luamacro/luafar/lf_version.h
@@ -1,3 +1,3 @@
#include <farversion.hpp>
-#define PLUGIN_BUILD 892
+#define PLUGIN_BUILD 893
diff --git a/plugins/luamacro/luafar/lf_win.c b/plugins/luamacro/luafar/lf_win.c
index 78a89ea53..6a232c642 100644
--- a/plugins/luamacro/luafar/lf_win.c
+++ b/plugins/luamacro/luafar/lf_win.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <windows.h>
#include <shellapi.h>
+#include <winternl.h>
WARNING_PUSH()
WARNING_DISABLE_MSC(4255)
@@ -858,10 +859,9 @@ int win_IsWinVersion(lua_State *L)
return 1;
}
-static void PutFileTimeToTableEx(lua_State *L, const FILETIME *FT, const char *key)
+static void PutFileTimeToTableEx(lua_State *L, const LARGE_INTEGER *FT, const char *key)
{
- INT64 FileTime = FT->dwLowDateTime + 0x100000000LL * FT->dwHighDateTime;
- bit64_pushuserdata(L, FileTime);
+ bit64_pushuserdata(L, FT->QuadPart);
lua_setfield(L, -2, key);
}
@@ -876,14 +876,23 @@ static int win_GetFileTimes(lua_State *L)
HANDLE hFile = CreateFileW(FileName,GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
- FILETIME t_create, t_access, t_write;
- if (GetFileTime(hFile, &t_create, &t_access, &t_write))
+ HMODULE hNtDll = GetModuleHandleW(L"ntdll.dll");
+ if (hNtDll)
{
- lua_createtable(L, 0, 3);
- PutFileTimeToTableEx(L, &t_create, "CreationTime");
- PutFileTimeToTableEx(L, &t_access, "LastAccessTime");
- PutFileTimeToTableEx(L, &t_write, "LastWriteTime");
- res = 1;
+ IO_STATUS_BLOCK iob;
+ FILE_BASIC_INFO fbi;
+ const int FileBasicInformation = 4;
+ typedef NTSTATUS(NTAPI* NtQueryInformationFile)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
+ NtQueryInformationFile pNtQueryInformationFile = (NtQueryInformationFile)(INT_PTR)GetProcAddress(hNtDll, "NtQueryInformationFile");
+ if (pNtQueryInformationFile && NT_SUCCESS(pNtQueryInformationFile(hFile, &iob, &fbi, sizeof(fbi), FileBasicInformation)))
+ {
+ lua_createtable(L, 0, 4);
+ PutFileTimeToTableEx(L, &fbi.CreationTime, "CreationTime");
+ PutFileTimeToTableEx(L, &fbi.LastAccessTime, "LastAccessTime");
+ PutFileTimeToTableEx(L, &fbi.LastWriteTime, "LastWriteTime");
+ PutFileTimeToTableEx(L, &fbi.ChangeTime, "ChangeTime");
+ res = 1;
+ }
}
CloseHandle(hFile);
}
@@ -893,7 +902,7 @@ static int win_GetFileTimes(lua_State *L)
return 1;
}
-static int ExtractFileTime(lua_State *L, const char *key, FILETIME* target, HANDLE hFile)
+static int ExtractFileTime(lua_State *L, const char *key, LARGE_INTEGER* target, HANDLE hFile)
{
int success = 0;
lua_getfield(L, -1, key);
@@ -902,8 +911,7 @@ static int ExtractFileTime(lua_State *L, const char *key, FILETIME* target, HAND
INT64 DateTime = check64(L, -1, &success);
if (success)
{
- target->dwLowDateTime = DateTime & 0xFFFFFFFF;
- target->dwHighDateTime = DateTime >> 32;
+ target->QuadPart = DateTime;
}
else
{
@@ -928,16 +936,29 @@ static int win_SetFileTimes(lua_State *L)
HANDLE hFile = CreateFileW(FileName,GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,flags,NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
- FILETIME t_create, t_access, t_write;
- FILETIME *p_create=NULL, *p_access=NULL, *p_write=NULL;
- lua_pushvalue(L, 2);
- if (ExtractFileTime(L, "CreationTime", &t_create, hFile))
- p_create = &t_create;
- if (ExtractFileTime(L, "LastAccessTime", &t_access, hFile))
- p_access = &t_access;
- if (ExtractFileTime(L, "LastWriteTime", &t_write, hFile))
- p_write = &t_write;
- res = (p_create||p_access||p_write) && SetFileTime(hFile,p_create,p_access,p_write);
+ HMODULE hNtDll = GetModuleHandleW(L"ntdll.dll");
+ if (hNtDll)
+ {
+ BOOL extracted = FALSE;
+ IO_STATUS_BLOCK iob;
+ FILE_BASIC_INFO fbi;
+ memset(&fbi, 0, sizeof(fbi));
+ lua_pushvalue(L, 2);
+ extracted |= ExtractFileTime(L, "CreationTime", &fbi.CreationTime, hFile);
+ extracted |= ExtractFileTime(L, "LastAccessTime", &fbi.LastAccessTime, hFile);
+ extracted |= ExtractFileTime(L, "LastWriteTime", &fbi.LastWriteTime, hFile);
+ extracted |= ExtractFileTime(L, "ChangeTime", &fbi.ChangeTime, hFile);
+ if (extracted)
+ {
+ const int FileBasicInformation = 4;
+ typedef NTSTATUS(NTAPI* NtSetInformationFile)(HANDLE FileHandle, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass);
+ NtSetInformationFile pNtSetInformationFile = (NtSetInformationFile)(INT_PTR)GetProcAddress(hNtDll, "NtSetInformationFile");
+ if (pNtSetInformationFile && NT_SUCCESS(pNtSetInformationFile(hFile, &iob, &fbi, sizeof(fbi), FileBasicInformation)))
+ {
+ res = 1;
+ }
+ }
+ }
CloseHandle(hFile);
}
}