/** * \file os_reg.c * \brief Returns true if the given file exists on the file system. * \author Copyright (c) 2002-2016 Jason Perkins and the Premake project */ #include "premake.h" #if PLATFORM_WINDOWS typedef struct RegKeyInfo { HKEY key; HKEY subkey; char * value; } RegKeyInfo; HKEY getRegistryKey(const char **path) { if (_strnicmp(*path, "HKCU:", 5) == 0) { *path += 5; return HKEY_CURRENT_USER; } if (_strnicmp(*path, "HKLM:", 5) == 0) { *path += 5; return HKEY_LOCAL_MACHINE; } if (_strnicmp(*path, "HKCR:", 5) == 0) { *path += 5; return HKEY_CLASSES_ROOT; } if (_strnicmp(*path, "HKU:", 4) == 0) { *path += 4; return HKEY_USERS; } if (_strnicmp(*path, "HKCC:", 5) == 0) { *path += 5; return HKEY_CURRENT_CONFIG; } // unsupported or invalid key prefix return NULL; } static HKEY getSubkey(HKEY key, const char **path) { HKEY subkey; size_t length; char *subpath; const char *value; char hasValue; if (key == NULL) return NULL; // skip the initial path separator if ((*path)[0] == '\\') (*path)++; // make a copy of the subkey path that excludes the value name (if present) value = strrchr(*path, '\\'); hasValue = value ? value[1] : 0; if (hasValue) { length = (size_t)(value - *path); subpath = (char *)malloc(length + 1); strncpy(subpath, *path, length); subpath[length] = 0; } // no value separator means we should check the default value else { subpath = (char *)*path; length = strlen(subpath); } // open the key for reading if (RegOpenKeyExA(key, subpath, 0, KEY_READ, &subkey) != ERROR_SUCCESS) subkey = NULL; // free the subpath if one was allocated if (hasValue) free(subpath); *path += length; return subkey; } static char * getValue(HKEY key, const char * name) { DWORD length; char * value; if (key == NULL || name == NULL) return NULL; // skip the initial path separator if (name[0] == '\\') name++; // query length of value if (RegQueryValueExA(key, name, NULL, NULL, NULL, &length) != ERROR_SUCCESS) return NULL; // allocate room for the value and fetch it value = (char *)malloc((size_t)length + 1); if (RegQueryValueExA(key, name, NULL, NULL, (LPBYTE)value, &length) != ERROR_SUCCESS) { free(value); return NULL; } value[length] = 0; return value; } static void fetchKeyInfo(struct RegKeyInfo *info, const char *path) { info->key = getRegistryKey(&path); info->subkey = getSubkey(info->key, &path); info->value = getValue(info->subkey, path); } static void releaseKeyInfo(struct RegKeyInfo *info) { free(info->value); RegCloseKey(info->subkey); } int os_getWindowsRegistry(lua_State *L) { RegKeyInfo info; fetchKeyInfo(&info, luaL_checkstring(L, 1)); lua_pushstring(L, info.value); releaseKeyInfo(&info); return 1; } #else int os_getWindowsRegistry(lua_State *L) { lua_pushnil(L); return 1; } #endif