wchar.lua 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. local ffi = require("ffi")
  2. ffi.cdef[[
  3. typedef unsigned int UINT;
  4. typedef unsigned int DWORD;
  5. typedef unsigned short WORD;
  6. typedef unsigned short WCHAR;
  7. typedef unsigned short wchar_t;
  8. typedef void FILE;
  9. typedef void* HANDLE;
  10. typedef bool BOOL;
  11. ]]
  12. ffi.cdef[[
  13. int MultiByteToWideChar(UINT CodePage, DWORD dwFlags, const char* lpMultiByteStr, int cbMultiByte, wchar_t* lpWideCharStr , int cchWideChar);
  14. int WideCharToMultiByte(UINT CodePage, DWORD dwFlags, wchar_t* lpWideCharStr , int cchWideChar, char* lpMultiByteStr, int cbMultiByte, char* lpDefaultChar, bool* lpUsedDefaultChar);
  15. ]]
  16. function towchar(strb)
  17. local osize = #strb + 1
  18. local strw = ffi.new("wchar_t["..osize.."]")
  19. ffi.C.MultiByteToWideChar(65001, 0, strb, -1, strw, osize)
  20. return strw
  21. end
  22. function fromwchar(strw)
  23. local osize = ffi.sizeof(strw)*4 + 1
  24. local strb = ffi.new("char["..osize.."]")
  25. ffi.C.WideCharToMultiByte(65001, 0, strw, -1, strb, osize, ffi.cast("char*", 0), ffi.cast("bool*", 0))
  26. return ffi.string(strb)
  27. end
  28. ffi.cdef("int _wsystem(wchar_t* command)")
  29. function execw(cmd)
  30. local cmdw = towchar(cmd)
  31. ffi.C._wsystem(cmdw)
  32. end
  33. ffi.cdef[[
  34. FILE* _wpopen(wchar_t* command, wchar_t* mode);
  35. wchar_t* fgetws (wchar_t* str, int numChars, FILE* stream);
  36. int feof (FILE* stream);
  37. int _pclose(FILE* stream);
  38. ]]
  39. function rexecw(cmd)
  40. cmd = cmd.." 2>&1" -- pipe stderr to stdout
  41. local cmdw = towchar(cmd)
  42. local modew = towchar("r")
  43. local file = ffi.C._wpopen(cmdw, modew)
  44. local stro = ""
  45. local buffer = ffi.new("wchar_t[256]")
  46. while ffi.C.feof(file)==0 do
  47. ffi.C.fgetws(buffer, 256, file)
  48. local str = fromwchar(buffer)
  49. stro = stro..str
  50. end
  51. ffi.C._pclose(file)
  52. return stro
  53. end
  54. ffi.cdef("bool SetCurrentDirectoryW(wchar_t* lpPathName)")
  55. function cdw(dir)
  56. local dirw = towchar(dir)
  57. ffi.C.SetCurrentDirectoryW(dirw)
  58. end
  59. ffi.cdef[[
  60. typedef struct _FILETIME {
  61. DWORD dwLowDateTime;
  62. DWORD dwHighDateTime;
  63. } FILETIME, *PFILETIME, *LPFILETIME;
  64. typedef struct _WIN32_FIND_DATAW {
  65. DWORD dwFileAttributes;
  66. FILETIME ftCreationTime;
  67. FILETIME ftLastAccessTime;
  68. FILETIME ftLastWriteTime;
  69. DWORD nFileSizeHigh;
  70. DWORD nFileSizeLow;
  71. DWORD dwReserved0;
  72. DWORD dwReserved1;
  73. WCHAR cFileName[0x00000104];
  74. WCHAR cAlternateFileName[14];
  75. DWORD dwFileType;
  76. DWORD dwCreatorType;
  77. WORD wFinderFlags;
  78. } WIN32_FIND_DATAW, *PWIN32_FIND_DATAW, *LPWIN32_FIND_DATAW;
  79. HANDLE FindFirstFileW(wchar_t* lpFileName, LPWIN32_FIND_DATAW lpFindFileData);
  80. BOOL FindNextFileW (HANDLE hFindFile , LPWIN32_FIND_DATAW lpFindFileData);
  81. ]]
  82. function findfilesw(dir)
  83. local dirw = towchar(dir)
  84. local infos = {}
  85. local finfo = ffi.new("WIN32_FIND_DATAW")
  86. local hfind = ffi.C.FindFirstFileW(dirw, finfo)
  87. while true do
  88. table.insert(infos, finfo)
  89. finfo = ffi.new("WIN32_FIND_DATAW")
  90. local next = ffi.C.FindNextFileW(hfind, finfo)
  91. if not next then break end
  92. end
  93. return infos
  94. end
  95. function findfilenamesw(dir)
  96. local names = {}
  97. local infos = findfilesw(dir)
  98. for _, info in ipairs(infos) do
  99. if bit.band(info.dwFileAttributes, 0x10)==0 then -- if not a directory
  100. table.insert(names, fromwchar(info.cFileName))
  101. end
  102. end
  103. return names
  104. end
  105. function findfilenamesanddirsw(dir)
  106. local names = {}
  107. local infos = findfilesw(dir)
  108. for _, info in ipairs(infos) do
  109. if bit.band(info.dwFileAttributes, 0x10)==0 then -- if not a directory
  110. table.insert(names, fromwchar(info.cFileName))
  111. else
  112. local fn = fromwchar(info.cFileName)
  113. if fn~="." and fn~=".." then
  114. table.insert(names, fn.."/")
  115. end
  116. end
  117. end
  118. return names
  119. end