static int win_CompareString(lua_State *L) { DWORD dwFlags = 0; size_t len1, len2; int result; const wchar_t *ws1 = check_utf8_string(L, 1, &len1); const wchar_t *ws2 = check_utf8_string(L, 2, &len2); const char *sLocale = luaL_optstring(L, 3, ""); const char *sFlags = luaL_optstring(L, 4, ""); LCID Locale = LOCALE_USER_DEFAULT; if(!strcmp(sLocale, "s")) Locale = LOCALE_SYSTEM_DEFAULT; else if(!strcmp(sLocale, "n")) Locale = LOCALE_NEUTRAL; if(strchr(sFlags, 'c')) dwFlags |= NORM_IGNORECASE; if(strchr(sFlags, 'k')) dwFlags |= NORM_IGNOREKANATYPE; if(strchr(sFlags, 'n')) dwFlags |= NORM_IGNORENONSPACE; if(strchr(sFlags, 's')) dwFlags |= NORM_IGNORESYMBOLS; if(strchr(sFlags, 'w')) dwFlags |= NORM_IGNOREWIDTH; if(strchr(sFlags, 'S')) dwFlags |= SORT_STRINGSORT; result = CompareStringW(Locale, dwFlags, ws1, (int)len1, ws2, (int)len2) - 2; (result == -2) ? lua_pushnil(L) : lua_pushinteger(L, result); return 1; }
static int win_wcscmp(lua_State *L) { const wchar_t *ws1 = check_utf8_string(L, 1, NULL); const wchar_t *ws2 = check_utf8_string(L, 2, NULL); int insens = lua_toboolean(L, 3); lua_pushinteger(L, (insens ? _wcsicmp : wcscmp)(ws1, ws2)); return 1; }
int rx_find_match(lua_State *L, int op_find, int is_function, int is_wide) { size_t len; FARAPIREGEXPCONTROL RegExpControl = GetRegExpControl(L); TFarRegex* fr; struct RegExpSearch data; memset(&data, 0, sizeof(data)); if (is_function) { if (is_wide) data.Text = check_utf16_string(L, 1, &len); else data.Text = check_utf8_string(L, 1, &len); fr = push_far_regex(L, RegExpControl, check_regex_pattern(L, 2, 4)); lua_replace(L, 2); } else { fr = CheckFarRegex(L, 1); if (is_wide) data.Text = check_utf16_string(L, 2, &len); else data.Text = check_utf8_string(L, 2, &len); } data.Length = len; data.Position = luaL_optinteger(L, 3, 1); if (data.Position > 0 && --data.Position > data.Length) data.Position = data.Length; if (data.Position < 0 && (data.Position += data.Length) < 0) data.Position = 0; data.Count = RegExpControl(fr->hnd, RECTL_BRACKETSCOUNT, 0, 0); data.Match = (struct RegExpMatch*)lua_newuserdata(L, data.Count*sizeof(struct RegExpMatch)); if (RegExpControl(fr->hnd, RECTL_SEARCHEX, 0, &data)) { int i, skip; if (op_find) { lua_pushinteger(L, data.Match[0].start+1); lua_pushinteger(L, data.Match[0].end); } skip = (op_find || data.Count>1) ? 1 : 0; for(i=skip; i<data.Count; i++) { if (data.Match[i].start >= 0) { if (is_wide) push_utf16_string(L, data.Text+data.Match[i].start, data.Match[i].end-data.Match[i].start); else push_utf8_string(L, data.Text+data.Match[i].start, data.Match[i].end-data.Match[i].start); } else lua_pushboolean(L, 0); } return (op_find ? 2:0) + (int)data.Count - skip; } return lua_pushnil(L), 1; }
// SetRegKey (Root, Key, ValueName, DataType, ValueData [, samDesired]) // Root: root, [string], one of "HKLM", "HKCC", "HKCR", "HKCU", "HKU" // Key: registry key, [string] // ValueName: registry value name, [string] // DataType: "string","expandstring","multistring","dword" or "binary", [string] // ValueData: registry value data, [string | number | lstring] // samDesired: access mask, [flag] ("KEY_WOW64_32KEY" or "KEY_WOW64_64KEY"; the default is 0) // Returns: // nothing. static int win_SetRegKey(lua_State *L) { HKEY hRoot = CheckHKey(L, 1); wchar_t* Key = (wchar_t*)check_utf8_string(L, 2, NULL); wchar_t* ValueName = (wchar_t*)check_utf8_string(L, 3, NULL); const char* DataType = luaL_checkstring(L, 4); REGSAM samDesired = (REGSAM) OptFlags(L, 6, 0); size_t len; BOOL result = FALSE; if(!strcmp("string", DataType)) { result=SetRegKeyStr(hRoot, Key, ValueName, (wchar_t*)check_utf8_string(L, 5, NULL), samDesired); } else if(!strcmp("dword", DataType)) { result=SetRegKeyDword(hRoot, Key, ValueName, (DWORD)luaL_checkinteger(L, 5), samDesired); } else if(!strcmp("binary", DataType)) { BYTE *data = (BYTE*)luaL_checklstring(L, 5, &len); result=SetRegKeyArr(hRoot, Key, ValueName, data, (DWORD)len, samDesired); } else if(!strcmp("expandstring", DataType)) { const wchar_t* data = check_utf8_string(L, 5, &len); HKEY hKey = CreateRegKey(hRoot, Key, samDesired); if (hKey) { result = (ERROR_SUCCESS == RegSetValueExW(hKey, ValueName, 0, REG_EXPAND_SZ, (BYTE*)data, (DWORD)((1+len)*sizeof(wchar_t)))); RegCloseKey(hKey); } } else if(!strcmp("multistring", DataType)) { const wchar_t* data = check_utf8_string(L, 5, &len); HKEY hKey = CreateRegKey(hRoot, Key, samDesired); if (hKey) { result = (ERROR_SUCCESS == RegSetValueExW(hKey, ValueName, 0, REG_MULTI_SZ, (BYTE*)data, (DWORD)((1+len)*sizeof(wchar_t)))); RegCloseKey(hKey); } } else luaL_argerror(L, 5, "unsupported value type"); lua_pushboolean(L, result==FALSE ? 0:1); return 1; }
static int win_CopyFile(lua_State *L) { const wchar_t* src = check_utf8_string(L, 1, NULL); const wchar_t* trg = check_utf8_string(L, 2, NULL); BOOL fail_if_exists = FALSE; // default = overwrite the target if(lua_gettop(L) > 2) fail_if_exists = lua_toboolean(L,3); if(CopyFileW(src, trg, fail_if_exists)) return lua_pushboolean(L, 1), 1; return SysErrorReturn(L); }
static int g_iofile(lua_State *L, int f, const wchar_t *mode) { if(!lua_isnoneornil(L, 1)) { const wchar_t *filename = lua_tostring(L, 1) ? check_utf8_string(L, 1, NULL) : NULL; if(filename) { FILE **pf = newfile(L); *pf = _wfopen(filename, mode); if(*pf == NULL) fileerror(L, 1, filename); } else { tofile(L); /* check that it's a valid file handle */ lua_pushvalue(L, 1); } lua_rawseti(L, LUA_ENVIRONINDEX, f); } /* return current value */ lua_rawgeti(L, LUA_ENVIRONINDEX, f); return 1; }
static int win_RemoveDir(lua_State *L) { if(RemoveDirectoryW(check_utf8_string(L, 1, NULL))) return lua_pushboolean(L, 1), 1; return SysErrorReturn(L); }
static int win_CreateDir(lua_State *L) { BOOL result, opt_tolerant, opt_original; const wchar_t* path = check_utf8_string(L, 1, NULL); const char* flags = ""; if (lua_type(L,2) == LUA_TSTRING) flags = lua_tostring(L,2); else if (lua_toboolean(L,2)) flags = "t"; opt_tolerant = strchr(flags,'t') != NULL; opt_original = strchr(flags,'o') != NULL; if(dir_exist(path)) { if (opt_tolerant) return lua_pushboolean(L,1), 1; return lua_pushnil(L), lua_pushliteral(L, "directory already exists"), 2; } result = opt_original ? CreateDirectoryW(path,NULL) : mkdir(path); if(result) return lua_pushboolean(L, 1), 1; return SysErrorReturn(L); }
static int win_DeleteFile(lua_State *L) { if(DeleteFileW(check_utf8_string(L, 1, NULL))) return lua_pushboolean(L, 1), 1; return SysErrorReturn(L); }
int ustring_Utf8ToOem(lua_State *L) { size_t len; const wchar_t* buf = check_utf8_string(L, 1, &len); push_oem_string(L, buf, len); return 1; }
static int win_SetEnv(lua_State *L) { const wchar_t* name = check_utf8_string(L, 1, NULL); const wchar_t* value = opt_utf8_string(L, 2, NULL); BOOL res = SetEnvironmentVariableW(name, value); return lua_pushboolean(L, res), 1; }
int ustring_Utf8ToUtf16(lua_State *L) { size_t len; const wchar_t *ws = check_utf8_string(L, 1, &len); lua_pushlstring(L, (const char*) ws, len*sizeof(wchar_t)); return 1; }
int ustring_SearchPath(lua_State *L) { const wchar_t* lpPath = opt_utf8_string(L, 1, NULL); const wchar_t* lpFileName = check_utf8_string(L, 2, NULL); const wchar_t* lpExtension = opt_utf8_string(L, 3, NULL); wchar_t buf[2048]; wchar_t* lpFilePart; DWORD result = SearchPathW( lpPath, // address of search path lpFileName, // address of filename lpExtension, // address of extension sizeof(buf)/sizeof(wchar_t), // size, in characters, of buffer buf, // address of buffer for found filename &lpFilePart // address of pointer to file component ); if(result > 0) { push_utf8_string(L, buf, -1); push_utf8_string(L, lpFilePart, -1); return 2; } return 0; }
/* ** this function has a separated environment, which defines the ** correct __close for 'popen' files */ static int io_popen(lua_State *L) { const wchar_t *filename = check_utf8_string(L, 1, NULL); const wchar_t *mode = opt_utf8_string(L, 2, L"r"); FILE **pf = newfile(L); *pf = lua_popen(L, filename, mode); return (*pf == NULL) ? pushresult(L, 0, filename) : 1; }
static int ustring_OutputDebugString(lua_State *L) { if (lua_isstring(L, 1)) OutputDebugStringW(check_utf8_string(L, 1, NULL)); else { lua_settop(L, 1); lua_getglobal(L, "tostring"); if (lua_isfunction(L, -1)) { lua_pushvalue(L, 1); if (0==lua_pcall(L, 1, 1, 0) && lua_isstring(L, -1)) OutputDebugStringW(check_utf8_string(L, -1, NULL)); } } return 0; }
int ustring_GetFileAttr(lua_State *L) { DWORD attr = GetFileAttributesW(check_utf8_string(L,1,NULL)); if(attr == 0xFFFFFFFF) lua_pushnil(L); else PushAttrString(L, attr); return 1; }
int ustring_GetFileAttr(lua_State *L) { DWORD attr = GetFileAttributesW(check_utf8_string(L,1,NULL)); if(attr == 0xFFFFFFFF) return SysErrorReturn(L); PushAttrString(L, attr); return 1; }
static int win_MoveFile(lua_State *L) { const wchar_t* src = check_utf8_string(L, 1, NULL); const wchar_t* trg = check_utf8_string(L, 2, NULL); const char* sFlags = luaL_optstring(L, 3, NULL); int flags = 0; if(sFlags) { if(strchr(sFlags, 'c')) flags |= MOVEFILE_COPY_ALLOWED; else if(strchr(sFlags, 'd')) flags |= MOVEFILE_DELAY_UNTIL_REBOOT; else if(strchr(sFlags, 'r')) flags |= MOVEFILE_REPLACE_EXISTING; else if(strchr(sFlags, 'w')) flags |= MOVEFILE_WRITE_THROUGH; } if(MoveFileExW(src, trg, flags)) return lua_pushboolean(L, 1), 1; return SysErrorReturn(L); }
static int ll_searchpath (lua_State *L) { const wchar_t *f = searchpath(L, luaL_checkstring(L, 1), check_utf8_string(L, 2, NULL), opt_utf8_string(L, 3, L"."), opt_utf8_string(L, 4, LUA_DIRSEP)); if (f != NULL) return 1; else { /* error message is on top of the stack */ lua_pushnil(L); lua_insert(L, -2); return 2; /* return nil + error message */ } }
static int ll_loadlib (lua_State *L) { const wchar_t *path = check_utf8_string(L, 1, NULL); const char *init = luaL_checkstring(L, 2); int stat = ll_loadfunc(L, path, init); if (stat == 0) /* no errors? */ return 1; /* return the loaded function */ else { /* error; error message is on stack top */ lua_pushnil(L); lua_insert(L, -2); lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); return 3; /* return nil, error message, and where */ } }
const wchar_t* check_regex_pattern (lua_State *L, int pos_pat, int pos_cflags) { const char* pat = luaL_checkstring(L, pos_pat); if (*pat != '/') { const char* cflags = pos_cflags ? luaL_optstring(L, pos_cflags, NULL) : NULL; lua_pushliteral(L, "/"); lua_pushvalue(L, pos_pat); lua_pushliteral(L, "/"); if (cflags) lua_pushvalue(L, pos_cflags); lua_concat(L, 3 + (cflags?1:0)); lua_replace(L, pos_pat); } return check_utf8_string(L, pos_pat, NULL); }
// Result = DeleteRegValue (Root, Key, ValueName [, samDesired]) // Root: [string], one of "HKLM", "HKCC", "HKCR", "HKCU", "HKU" // Key: registry key, [string] // ValueName: value name, [optional string] // samDesired: access mask, [flag] ("KEY_WOW64_32KEY" or "KEY_WOW64_64KEY"; the default is 0) // Returns: // Result: TRUE if success, FALSE if failure, [boolean] static int win_DeleteRegValue(lua_State *L) { HKEY hKey; HKEY hRoot = CheckHKey(L, 1); const wchar_t* Key = check_utf8_string(L, 2, NULL); const wchar_t* Name = opt_utf8_string(L, 3, NULL); REGSAM samDesired = (REGSAM) OptFlags(L, 4, 0) | KEY_SET_VALUE; int res = 0; if (RegOpenKeyExW(hRoot, Key, 0, samDesired, &hKey) == ERROR_SUCCESS) { res = (RegDeleteValueW(hKey, Name) == ERROR_SUCCESS); RegCloseKey(hKey); } lua_pushboolean(L, res); return 1; }
static int win_GetFileInfo(lua_State *L) { WIN32_FIND_DATAW fd; const wchar_t *fname = check_utf8_string(L, 1, NULL); HANDLE h = FindFirstFileW(fname, &fd); if(h == INVALID_HANDLE_VALUE) return SysErrorReturn(L); else { PushWinFindData(L, &fd); FindClose(h); } return 1; }
static int win_ShellExecute(lua_State *L) { HWND hwnd = lua_isuserdata(L, 1) ? lua_touserdata(L, 1) : NULL; const wchar_t* lpOperation = opt_utf8_string(L, 2, NULL); const wchar_t* lpFile = check_utf8_string(L, 3, NULL); const wchar_t* lpParameters = opt_utf8_string(L, 4, NULL); const wchar_t* lpDirectory = opt_utf8_string(L, 5, NULL); INT nShowCmd = (INT)luaL_optinteger(L, 6, SW_SHOWNORMAL); HINSTANCE hinst = ShellExecuteW( hwnd, // handle to parent window lpOperation, // pointer to string that specifies operation to perform lpFile, // pointer to filename or folder name string lpParameters, // pointer to string that specifies executable-file parameters lpDirectory, // pointer to string that specifies default directory nShowCmd // whether file is shown when opened ); lua_pushinteger(L, (INT_PTR)hinst); return 1; }
int _Gmatch(lua_State *L, int is_wide) { size_t len; const wchar_t* Text = is_wide ? check_utf16_string(L, 1, &len) : check_utf8_string(L, 1, &len); const wchar_t* pat = check_regex_pattern(L, 2, 3); FARAPIREGEXPCONTROL RegExpControl = GetRegExpControl(L); TFarRegex* fr = push_far_regex(L, RegExpControl, pat); // upvalue 1 struct RegExpSearch* pData = (struct RegExpSearch*)lua_newuserdata(L, sizeof(struct RegExpSearch)); // upvalue 2 memset(pData, 0, sizeof(struct RegExpSearch)); pData->Text = Text; pData->Position = 0; pData->Length = len; pData->Count = RegExpControl(fr->hnd, RECTL_BRACKETSCOUNT, 0, 0); /* upvalues 3 and 4 must be kept to prevent values from being garbage-collected */ pData->Match = (struct RegExpMatch*)lua_newuserdata(L, pData->Count*sizeof(struct RegExpMatch)); // upvalue 3 pData->Match[0].end = -1; lua_pushvalue(L, 1); // upvalue 4 lua_pushcclosure(L, is_wide ? regex_gmatch_closureW : regex_gmatch_closure, 4); return 1; }
// Result = DeleteRegKey (Root, Key [, samDesired]) // Root: [string], one of "HKLM", "HKCC", "HKCR", "HKCU", "HKU" // Key: registry key, [string] // samDesired: access mask, [flag] ("KEY_WOW64_32KEY" or "KEY_WOW64_64KEY"; the default is 0) // Returns: // Result: TRUE if success, FALSE if failure, [boolean] static int win_DeleteRegKey(lua_State *L) { long res; HKEY hRoot = CheckHKey(L, 1); const wchar_t* Key = check_utf8_string(L, 2, NULL); REGSAM samDesired = (REGSAM) OptFlags(L, 3, 0); FARPROC ProcAddr; HMODULE module = GetModuleHandleW(L"Advapi32.dll"); if (module && (ProcAddr = GetProcAddress(module, "RegDeleteKeyExW")) != NULL) { typedef LONG (WINAPI *pRegDeleteKeyEx)(HKEY, LPCTSTR, REGSAM, DWORD); res = ((pRegDeleteKeyEx)ProcAddr)(hRoot, Key, samDesired, 0); } else { res = RegDeleteKeyW(hRoot, Key); } return lua_pushboolean(L, res==ERROR_SUCCESS), 1; }
// os.getenv does not always work correctly, hence the following. static int win_GetEnv(lua_State *L) { const wchar_t* name = check_utf8_string(L, 1, NULL); wchar_t buf[256]; DWORD res = GetEnvironmentVariableW(name, buf, ARRSIZE(buf)); lua_pushnil(L); if(res) { if(res < ARRSIZE(buf)) push_utf8_string(L, buf, -1); else { DWORD size = res + 1; wchar_t *p = (wchar_t*)lua_newuserdata(L, size * sizeof(wchar_t)); res = GetEnvironmentVariableW(name, p, size); if(res > 0 && res < size) push_utf8_string(L, p, -1); } } return 1; }
static int io_lines(lua_State *L) { if(lua_isnoneornil(L, 1)) /* no arguments? */ { /* will iterate over default input */ lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT); return f_lines(L); } else { const wchar_t *filename = check_utf8_string(L, 1, NULL); FILE **pf = newfile(L); *pf = _wfopen(filename, L"r"); if(*pf == NULL) fileerror(L, 1, filename); aux_lines(L, lua_gettop(L), 1); return 1; } }
static int io_open(lua_State *L) { const wchar_t *filename = check_utf8_string(L, 1, NULL); const wchar_t *mode = opt_utf8_string(L, 2, L"r"); FILE **pf = newfile(L); int i = 0; /* check whether 'mode' matches '[rwa]%+?b?' */ if(!(mode[i] != L'\0' && wcschr(L"rwa", mode[i++]) != NULL && (mode[i] != L'+' || ++i) && /* skip if char is '+' */ (mode[i] != L'b' || ++i) && /* skip if char is 'b' */ (mode[i] == L'\0'))) { push_utf8_string(L, mode, -1); return luaL_error(L, "invalid mode " LUA_QS " (should match " LUA_QL("[rwa]%%+?b?") ")", lua_tostring(L, -1)); } *pf = _wfopen(filename, mode); return (*pf == NULL) ? pushresult(L, 0, filename) : 1; }
// Result = EnumRegValue (Root, Key, Index [, samDesired]) // Root: [string], one of "HKLM", "HKCC", "HKCR", "HKCU", "HKU" // Key: registry key, [string] // Index: integer // samDesired: access mask, [flag] ("KEY_WOW64_32KEY" or "KEY_WOW64_64KEY"; the default is 0) // Returns: // Result: string or nil static int win_EnumRegValue(lua_State *L) { HKEY hKey; LONG ret; HKEY hRoot = CheckHKey(L, 1); wchar_t* Key = (wchar_t*)check_utf8_string(L, 2, NULL); DWORD dwIndex = (DWORD)luaL_checkinteger(L, 3); REGSAM samDesired = (REGSAM) OptFlags(L, 4, 0) | KEY_QUERY_VALUE; wchar_t Name[512]; DWORD NameSize = ARRSIZE(Name); DWORD Type; if(RegOpenKeyExW(hRoot, Key, 0, samDesired, &hKey)!=ERROR_SUCCESS) { lua_pushnil(L); lua_pushstring(L, "RegOpenKeyExW failed."); return 2; } ret = RegEnumValue( hKey, // handle of key to query dwIndex, // index of value to query Name, // address of buffer for value string &NameSize, // address for size of value buffer NULL, // reserved &Type, // address of buffer for type code NULL, // address of buffer for value data NULL // address for size of data buffer ); RegCloseKey(hKey); if (ret == ERROR_SUCCESS) push_utf8_string(L, Name, NameSize); else lua_pushnil(L); return 1; }