-
Notifications
You must be signed in to change notification settings - Fork 0
/
fswin.lua
84 lines (73 loc) · 2.28 KB
/
fswin.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
-- The file is in public domain
-- nyfair ([email protected])
local ffi = require 'ffi'
ffi.cdef[[
#pragma pack(push)
#pragma pack(1)
struct WIN32_FIND_DATAW {
uint32_t dwFileWttributes;
uint64_t ftCreationTime;
uint64_t ftLastAccessTime;
uint64_t ftLastWriteTime;
uint32_t dwReserved[4];
char cFileName[520];
char cAlternateFileName[28];
};
#pragma pack(pop)
void* FindFirstFileW(const char* pattern, struct WIN32_FIND_DATAW* fd);
bool FindNextFileW(void* ff, struct WIN32_FIND_DATAW* fd);
bool FindClose(void* ff);
bool CreateDirectoryW(const char* dst, void*);
bool MoveFileW(const char* src, const char* dst);
bool DeleteFileW(const char* dst);
int MultiByteToWideChar(unsigned int CodePage, uint32_t dwFlags, const char* lpMultiByteStr,
int cbMultiByte, const char* lpWideCharStr, int cchWideChar);
int WideCharToMultiByte(unsigned int CodePage, uint32_t dwFlags, const char* lpWideCharStr,
int cchWideChar, const char* lpMultiByteStr, int cchMultiByte,
const char* default, int* used);
]]
local WIN32_FIND_DATA = ffi.typeof('struct WIN32_FIND_DATAW')
local INVALID_HANDLE = ffi.cast('void*', -1)
function u2w(str, code)
local size = ffi.C.MultiByteToWideChar(code or 65001, 0, str, #str, nil, 0)
local buf = ffi.new("char[?]", size * 2 + 2)
ffi.C.MultiByteToWideChar(code or 65001, 0, str, #str, buf, size * 2)
return buf
end
function w2u(wstr, code)
local size = ffi.C.WideCharToMultiByte(code or 65001, 0, wstr, -1, nil, 0, nil, nil)
local buf = ffi.new("char[?]", size + 1)
size = ffi.C.WideCharToMultiByte(code or 65001, 0, wstr, -1, buf, size, nil, nil)
return ffi.string(buf)
end
function ls(pattern)
local fd = ffi.new(WIN32_FIND_DATA)
local tFiles = {}
if pattern == nil then
pattern = './*'
end
local hFile = ffi.C.FindFirstFileW(u2w(pattern), fd)
if hFile ~= INVALID_HANDLE then
ffi.gc(hFile, ffi.C.FindClose)
repeat
fn = w2u(fd.cFileName)
if fn ~= '.' and fn ~= '..' then
table.insert(tFiles, fn)
end
until not ffi.C.FindNextFileW(hFile, fd)
ffi.C.FindClose(ffi.gc(hFile, nil))
end
return tFiles
end
function md(dst)
ffi.C.CreateDirectoryW(u2w(dst), nil)
end
function rm(dst)
ffi.C.DeleteFileW(u2w(dst))
end
function mv(src, dst)
ffi.C.MoveFileW(u2w(src), u2w(dst))
end
function a2u(src, code)
return w2u(u2w(src, code or 0))
end