Key Key::subKey( int nIdx ) const { HKEY hKey; LONG lRtn = RegOpenKeyExW( m_hRootKey, m_wsPath.c_str(), 0, KEY_READ, &hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegOpenKeyExW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } // TODO: could use RegQueryInfo to get required buf size. const int knBufSize = 1000; wchar_t szSubKeyName[knBufSize]; DWORD dwBufSize = knBufSize; lRtn = RegEnumKeyExW( hKey, nIdx, szSubKeyName, &dwBufSize, NULL, NULL, NULL, NULL ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegEnumKeyEx(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } string sSubKeyFullPath = fullPath() + "\\" + wideToUtf8( szSubKeyName ); return Key( sSubKeyFullPath ); }
void Key::writeInt( const std::string& sValueName, int nData ) { HKEY hKey; LONG lRtn = RegCreateKeyExW( m_hRootKey, m_wsPath.c_str(), 0, NULL, 0, KEY_SET_VALUE, NULL, &hKey, NULL ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCreateKeyExW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } std::wstring wValueName = utf8ToWide( sValueName ); lRtn = RegSetValueExW( hKey, wValueName.c_str(), 0, REG_DWORD, reinterpret_cast<BYTE*>(&nData), sizeof(nData) ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegSetValueExW(" + wideToUtf8(m_wsPath) + ", " + sValueName + ", " + bp::conv::toString( nData ) + ") returned: " + bp::conv::toString( lRtn ) ); } lRtn = RegCloseKey( hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCloseKey(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } }
std::string Key::readString( const std::string& sValueName ) const { HKEY hKey; LONG lRtn = RegOpenKeyExW( m_hRootKey, m_wsPath.c_str(), 0, KEY_READ, &hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegOpenKeyExW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } // TODO: could use RegQueryInfo to get required buf size. const int knBufSize = 2000; BYTE szBuf[knBufSize]; DWORD dwBufSize = knBufSize; std::wstring wValueName = utf8ToWide( sValueName ); lRtn = RegQueryValueExW( hKey, wValueName.c_str(), NULL, NULL, szBuf, &dwBufSize ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegQueryValueExW(" + wideToUtf8(m_wsPath) + ", " + sValueName + ") returned: " + bp::conv::toString( lRtn ) ); } lRtn = RegCloseKey( hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCloseKey(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } std::wstring wval(reinterpret_cast<wchar_t*>( szBuf ) ); std::string rval = wideToUtf8( wval ); return rval; }
void Key::writeString( const std::string& sValueName, const std::string& sData ) { HKEY hKey; LONG lRtn = RegCreateKeyExW( m_hRootKey, m_wsPath.c_str(), 0, NULL, 0, KEY_SET_VALUE, NULL, &hKey, NULL ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCreateKeyExW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } std::wstring wData = utf8ToWide( sData ); std::wstring wValueName = utf8ToWide( sValueName ); lRtn = RegSetValueExW( hKey, wValueName.c_str(), 0, REG_SZ, reinterpret_cast<const BYTE*>(wData.c_str()), static_cast<DWORD>(wData.length() * sizeof(wchar_t)) ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegSetValueExW(" + wideToUtf8(m_wsPath) + ", " + sValueName + ", " + sData + ") returned: " + bp::conv::toString( lRtn ) ); } lRtn = RegCloseKey( hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCloseKey(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } }
Value Key::value( int nIdx ) const { HKEY hKey; LONG lRtn = RegOpenKeyExW( m_hRootKey, m_wsPath.c_str(), 0, KEY_READ, &hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegOpenKeyExW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } // TODO: could use RegQueryInfo to get required buf size. const int knBufSize = 1000; wchar_t szValName[knBufSize]; DWORD dwBufSize = knBufSize; DWORD dwType; lRtn = RegEnumValueW( hKey, nIdx, szValName, &dwBufSize, NULL, &dwType, NULL, NULL ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegEnumValueW(" + wideToUtf8(m_wsPath) + ", " + bp::conv::toString( nIdx ) + ") returned: " + bp::conv::toString( lRtn ) ); } return Value( wideToUtf8( szValName ), this, dwType ); }
void Key::create() const { HKEY hKey; LONG lRtn = RegCreateKeyExW( m_hRootKey, m_wsPath.c_str(), 0, NULL, 0, KEY_SET_VALUE, NULL, &hKey, NULL ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCreateKeyExW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } lRtn = RegCloseKey( hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCloseKey(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } }
void Key::remove() const { LONG lRtn = RegDeleteKeyW( m_hRootKey, m_wsPath.c_str() ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegDeleteKeyW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } }
// convert to utf-8, change '\\' to '/' and remove leading slash static std::string makePathStandard(LPCWSTR path) { std::string utfPath = wideToUtf8(std::wstring(path)); // change backslashes to forward slashes size_t slashPos; while ((slashPos = utfPath.find('\\')) != std::string::npos) utfPath.replace(slashPos, 1, "/"); // remove leading slash return utfPath.substr(1); }
int Key::numValues() const { HKEY hKey; LONG lRtn = RegOpenKeyExW( m_hRootKey, m_wsPath.c_str(), 0, KEY_QUERY_VALUE, &hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegOpenKeyExW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } DWORD dwNumValues; lRtn = RegQueryInfoKeyW( hKey, NULL, NULL, NULL, NULL, NULL, NULL, &dwNumValues, NULL, NULL, NULL, NULL ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegQueryInfoKeyW(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } return static_cast<int>( dwNumValues ); }
bool Key::exists() const { HKEY hKey; LONG lRtn = RegOpenKeyExW( m_hRootKey, m_wsPath.c_str(), 0, KEY_READ, &hKey ); if (lRtn != ERROR_SUCCESS) { return false; } lRtn = RegCloseKey( hKey ); if (lRtn != ERROR_SUCCESS) { BP_THROW( "RegCloseKey(" + wideToUtf8(m_wsPath) + ") returned: " + bp::conv::toString( lRtn ) ); } return true; }
// use _getcwd() instead of GetCurrentDirectory() because it updates errno char* getcwd(char* path, int max) { assert(path == NULL || max <= PATH_MAX); wchar_t wpath[PATH_MAX]; if (wchar_t *wresult = _wgetcwd(wpath, PATH_MAX)) { // Caller is allowed to pass in NULL for `path`. // In that case, we're supposed to allocate a // buffer on the caller's behalf. if (path == NULL) { max = UNI_MAX_UTF8_BYTES_PER_CODE_POINT * wcslen(wresult) + 1; path = (char *)malloc(max); if (path == NULL) { errno = ENOMEM; return NULL; } } if (wideToUtf8(wresult, path, max)) return path; } return NULL; }
static int DOKAN_CALLBACK WendyCreateFile(LPCWSTR filename, DWORD accessMode, DWORD shareMode, DWORD creationDisposition, DWORD flagsAndAttributes, PDOKAN_FILE_INFO info) { ScopeLock lock; wprintf(L"CreateFile: %s\n", filename); std::string path = makePathStandard(filename); FileSystem::FileAttributes attributes; bool exists = fs->stat(path, &attributes); // cases when the file MUST exist if (!exists && ((creationDisposition == OPEN_EXISTING) || (creationDisposition == TRUNCATE_EXISTING))) return -ERROR_PATH_NOT_FOUND; // cases when the file MUST NOT exist if (exists && (creationDisposition == CREATE_NEW)) return -ERROR_FILE_EXISTS; if (attributes.folder) { // flag as directory info->IsDirectory = TRUE; } else { // no real open if (accessMode == 0) return 0; // retrieve opening process name std::string processName = "unknown application"; HANDLE process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, info->ProcessId); if (process != NULL) { wchar_t processBaseName[256]; DWORD length = GetModuleBaseName(process, NULL, processBaseName, 255); if (length > 0) processName = wideToUtf8(processBaseName); CloseHandle(process); } std::wstring processNameWide = utf8ToWide(processName); wprintf(L"%s opened by %s\n", filename, processNameWide.c_str()); // translate access mode bool reading = false; bool writing = false; //if ((accessMode & FILE_GENERIC_READ) == FILE_GENERIC_READ) reading = true; //if ((accessMode & FILE_GENERIC_WRITE) == FILE_GENERIC_WRITE) writing = true; reading = true; if (writing) return -ERROR_ACCESS_DENIED; // open asset File *file = fs->open(path, reading, writing, false, processName); if (!file) return -ERROR_PATH_NOT_FOUND; info->Context = (ULONG64)file; // file descriptor wprintf(L"CreateFile succeeded (handle = 0x%x\n", file); } return 0; }
char* realpath(const char * name, char * resolved) { char *retname = NULL; /* SUSv3 says we must set `errno = EINVAL', and return NULL, * if `name' is passed as a NULL pointer. */ if (name == NULL) { errno = EINVAL; return NULL; } /* Otherwise, `name' must refer to a readable filesystem object, * if we are going to resolve its absolute path name. */ wchar_t wideNameBuffer[PATH_MAX]; wchar_t *wideName = wideNameBuffer; if (!utf8ToWide(name, wideName, PATH_MAX)) { errno = EINVAL; return NULL; } if (_waccess(wideName, 4) != 0) return NULL; /* If `name' didn't point to an existing entity, * then we don't get to here; we simply fall past this block, * returning NULL, with `errno' appropriately set by `access'. * * When we _do_ get to here, then we can use `_fullpath' to * resolve the full path for `name' into `resolved', but first, * check that we have a suitable buffer, in which to return it. */ if ((retname = resolved) == NULL) { /* Caller didn't give us a buffer, so we'll exercise the * option granted by SUSv3, and allocate one. * * `_fullpath' would do this for us, but it uses `malloc', and * Microsoft's implementation doesn't set `errno' on failure. * If we don't do this explicitly ourselves, then we will not * know if `_fullpath' fails on `malloc' failure, or for some * other reason, and we want to set `errno = ENOMEM' for the * `malloc' failure case. */ retname = (char *)malloc(PATH_MAX); if (retname == NULL) { errno = ENOMEM; return NULL; } } /* Otherwise, when we do have a valid buffer, * `_fullpath' should only fail if the path name is too long. */ wchar_t wideFullPathBuffer[PATH_MAX]; wchar_t *wideFullPath; if ((wideFullPath = _wfullpath(wideFullPathBuffer, wideName, PATH_MAX)) == NULL) { errno = ENAMETOOLONG; return NULL; } // Do a LongPath<->ShortPath roundtrip so that case is resolved by OS // FIXME: Check for failure size_t initialLength = wcslen(wideFullPath); GetShortPathNameW(wideFullPath, wideNameBuffer, PATH_MAX); GetLongPathNameW(wideNameBuffer, wideFullPathBuffer, initialLength + 1); // Convert back to UTF-8 if (!wideToUtf8(wideFullPathBuffer, retname, PATH_MAX)) { errno = EINVAL; return NULL; } // Force drive to be upper case if (retname[1] == ':') retname[0] = toupper(retname[0]); return retname; }
std::string Value::readString() const { return m_pParentKey->readString( wideToUtf8( m_wsName ) ); }
std::string Value::name() const { return wideToUtf8( m_wsName ); }
std::string Key::fullPath() const { return stringFromRootKey( m_hRootKey ) + "\\" + wideToUtf8( m_wsPath ); }
std::string Key::path() const { return wideToUtf8( m_wsPath ); }