bool HandleToFilename(HANDLE aHandle, const LARGE_INTEGER& aOffset, nsAString& aFilename) { aFilename.Truncate(); // This implementation is nice because it uses fully documented APIs that // are available on all Windows versions that we support. nsAutoHandle fileMapping(CreateFileMapping(aHandle, nullptr, PAGE_READONLY, 0, 1, nullptr)); if (!fileMapping) { return false; } ScopedMappedView view(MapViewOfFile(fileMapping, FILE_MAP_READ, aOffset.HighPart, aOffset.LowPart, 1)); if (!view) { return false; } nsAutoString mappedFilename; DWORD len = 0; SetLastError(ERROR_SUCCESS); do { mappedFilename.SetLength(mappedFilename.Length() + MAX_PATH); len = GetMappedFileNameW(GetCurrentProcess(), view, wwc(mappedFilename.BeginWriting()), mappedFilename.Length()); } while (!len && GetLastError() == ERROR_INSUFFICIENT_BUFFER); if (!len) { return false; } mappedFilename.Truncate(len); return NtPathToDosPath(mappedFilename, aFilename); }
void GUIDToString(REFGUID aGuid, nsAString& aOutString) { // This buffer length is long enough to hold a GUID string that is formatted // to include curly braces and dashes. const int kBufLenWithNul = 39; aOutString.SetLength(kBufLenWithNul); int result = StringFromGUID2(aGuid, wwc(aOutString.BeginWriting()), kBufLenWithNul); MOZ_ASSERT(result); if (result) { // Truncate the terminator aOutString.SetLength(result - 1); } }
NS_IMETHODIMP nsWindowsRegKey::ReadStringValue(const nsAString& aName, nsAString& aResult) { if (NS_WARN_IF(!mKey)) { return NS_ERROR_NOT_INITIALIZED; } DWORD type, size; const nsString& flatName = PromiseFlatString(aName); LONG rv = RegQueryValueExW(mKey, flatName.get(), 0, &type, nullptr, &size); if (rv != ERROR_SUCCESS) { return NS_ERROR_FAILURE; } // This must be a string type in order to fetch the value as a string. // We're being a bit forgiving here by allowing types other than REG_SZ. if (type != REG_SZ && type != REG_EXPAND_SZ && type != REG_MULTI_SZ) { return NS_ERROR_FAILURE; } // The buffer size must be a multiple of 2. if (size % 2 != 0) { return NS_ERROR_UNEXPECTED; } if (size == 0) { aResult.Truncate(); return NS_OK; } // |size| may or may not include the terminating null character. DWORD resultLen = size / 2; if (!aResult.SetLength(resultLen, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } nsAString::iterator begin; aResult.BeginWriting(begin); rv = RegQueryValueExW(mKey, flatName.get(), 0, &type, (LPBYTE)begin.get(), &size); if (!aResult.CharAt(resultLen - 1)) { // The string passed to us had a null terminator in the final position. aResult.Truncate(resultLen - 1); } // Expand the environment variables if needed if (type == REG_EXPAND_SZ) { const nsString& flatSource = PromiseFlatString(aResult); resultLen = ExpandEnvironmentStringsW(flatSource.get(), nullptr, 0); if (resultLen > 1) { nsAutoString expandedResult; // |resultLen| includes the terminating null character --resultLen; if (!expandedResult.SetLength(resultLen, mozilla::fallible)) { return NS_ERROR_OUT_OF_MEMORY; } nsAString::iterator begin; expandedResult.BeginWriting(begin); resultLen = ExpandEnvironmentStringsW(flatSource.get(), wwc(begin.get()), resultLen + 1); if (resultLen <= 0) { rv = ERROR_UNKNOWN_FEATURE; aResult.Truncate(); } else { rv = ERROR_SUCCESS; aResult = expandedResult; } } else if (resultLen == 1) { // It apparently expands to nothing (just a null terminator). aResult.Truncate(); } } return (rv == ERROR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE; }