mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-06 08:10:02 +00:00
AK: Add Error::from_windows_error(void)
Also slightly improve Error::from_windows_error(int)
This commit is contained in:
parent
c7fe7b09a5
commit
870cce9d11
Notes:
github-actions[bot]
2025-02-06 02:28:57 +00:00
Author: https://github.com/stasoid
Commit: 870cce9d11
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3166
Reviewed-by: https://github.com/ADKaster ✅
Reviewed-by: https://github.com/gmta
5 changed files with 40 additions and 34 deletions
50
AK/Error.cpp
50
AK/Error.cpp
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
|
* Copyright (c) 2023, Liav A. <liavalb@hotmail.co.il>
|
||||||
* Copyright (c) 2023, Cameron Youell <cameronyouell@gmail.com>
|
* Copyright (c) 2023, Cameron Youell <cameronyouell@gmail.com>
|
||||||
* Copyright (c) 2024, stasoid <stasoid@yahoo.com>
|
* Copyright (c) 2024-2025, stasoid <stasoid@yahoo.com>
|
||||||
*
|
*
|
||||||
* SPDX-License-Identifier: BSD-2-Clause
|
* SPDX-License-Identifier: BSD-2-Clause
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,8 @@
|
||||||
# include <AK/ByteString.h>
|
# include <AK/ByteString.h>
|
||||||
# include <AK/HashMap.h>
|
# include <AK/HashMap.h>
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
|
// Comment to prevent clang-format from including windows.h too late
|
||||||
|
# include <winbase.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
@ -21,31 +23,39 @@ Error Error::from_string_view_or_print_error_and_return_errno(StringView string_
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AK_OS_WINDOWS
|
#ifdef AK_OS_WINDOWS
|
||||||
Error Error::from_windows_error(DWORD code)
|
Error Error::from_windows_error(u64 code)
|
||||||
{
|
{
|
||||||
static HashMap<DWORD, ByteString> windows_errors;
|
thread_local HashMap<u64, ByteString> s_windows_errors;
|
||||||
|
|
||||||
auto string = windows_errors.get(code);
|
auto string = s_windows_errors.get(code);
|
||||||
if (string.has_value()) {
|
if (string.has_value())
|
||||||
return Error::from_string_view(string->view());
|
return Error::from_string_view(string->view());
|
||||||
} else {
|
|
||||||
char* message = nullptr;
|
|
||||||
auto size = FormatMessageA(
|
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
||||||
nullptr,
|
|
||||||
code,
|
|
||||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
|
||||||
(LPSTR)&message,
|
|
||||||
0,
|
|
||||||
nullptr);
|
|
||||||
|
|
||||||
if (size == 0)
|
char* message = nullptr;
|
||||||
return Error::from_string_view_or_print_error_and_return_errno("Unknown error"sv, code);
|
auto size = FormatMessage(
|
||||||
|
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
nullptr,
|
||||||
|
static_cast<DWORD>(code),
|
||||||
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
reinterpret_cast<LPSTR>(&message),
|
||||||
|
0,
|
||||||
|
nullptr);
|
||||||
|
|
||||||
windows_errors.set(code, { message, size });
|
if (size == 0) {
|
||||||
LocalFree(message);
|
static char buffer[128];
|
||||||
return from_windows_error(code);
|
(void)snprintf(buffer, _countof(buffer), "Error 0x%08lX while getting text of error 0x%08llX", GetLastError(), code);
|
||||||
|
return Error::from_string_view({ buffer, _countof(buffer) });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto& string_in_map = s_windows_errors.ensure(code, [message, size] { return ByteString { message, size }; });
|
||||||
|
LocalFree(message);
|
||||||
|
return Error::from_string_view(string_in_map.view());
|
||||||
|
}
|
||||||
|
|
||||||
|
// This can be used both for generic Windows errors and for winsock errors because WSAGetLastError is forwarded to GetLastError.
|
||||||
|
Error Error::from_windows_error()
|
||||||
|
{
|
||||||
|
return from_windows_error(GetLastError());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <AK/StringView.h>
|
#include <AK/StringView.h>
|
||||||
#include <AK/Try.h>
|
|
||||||
#include <AK/Variant.h>
|
#include <AK/Variant.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
|
||||||
#ifdef AK_OS_WINDOWS
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace AK {
|
namespace AK {
|
||||||
|
|
||||||
|
@ -29,7 +24,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef AK_OS_WINDOWS
|
#ifdef AK_OS_WINDOWS
|
||||||
static Error from_windows_error(DWORD code);
|
static Error from_windows_error(u64 code);
|
||||||
|
static Error from_windows_error();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// NOTE: For calling this method from within kernel code, we will simply print
|
// NOTE: For calling this method from within kernel code, we will simply print
|
||||||
|
|
|
@ -30,7 +30,7 @@ ErrorOr<NonnullRefPtr<AnonymousBufferImpl>> AnonymousBufferImpl::create(size_t s
|
||||||
{
|
{
|
||||||
HANDLE map_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, size >> 31 >> 1, size & 0xFFFFFFFF, NULL);
|
HANDLE map_handle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, size >> 31 >> 1, size & 0xFFFFFFFF, NULL);
|
||||||
if (!map_handle)
|
if (!map_handle)
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
|
|
||||||
return create((int)(intptr_t)map_handle, size);
|
return create((int)(intptr_t)map_handle, size);
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ ErrorOr<NonnullRefPtr<AnonymousBufferImpl>> AnonymousBufferImpl::create(int fd,
|
||||||
{
|
{
|
||||||
void* ptr = MapViewOfFile((HANDLE)(intptr_t)fd, FILE_MAP_ALL_ACCESS, 0, 0, size);
|
void* ptr = MapViewOfFile((HANDLE)(intptr_t)fd, FILE_MAP_ALL_ACCESS, 0, 0, size);
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
|
|
||||||
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousBufferImpl(fd, size, ptr));
|
return adopt_nonnull_ref_or_enomem(new (nothrow) AnonymousBufferImpl(fd, size, ptr));
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,7 @@ ErrorOr<Process> Process::spawn(ProcessSpawnOptions const& options)
|
||||||
&process_info);
|
&process_info);
|
||||||
|
|
||||||
if (!result)
|
if (!result)
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
|
|
||||||
CloseHandle(process_info.hThread);
|
CloseHandle(process_info.hThread);
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ ErrorOr<String> Process::get_name()
|
||||||
|
|
||||||
DWORD length = GetModuleFileNameW(NULL, path, MAX_PATH);
|
DWORD length = GetModuleFileNameW(NULL, path, MAX_PATH);
|
||||||
if (!length)
|
if (!length)
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
|
|
||||||
return String::from_utf16(Utf16View { { (u16*)path, length } });
|
return String::from_utf16(Utf16View { { (u16*)path, length } });
|
||||||
}
|
}
|
||||||
|
@ -150,11 +150,11 @@ ErrorOr<int> Process::wait_for_termination()
|
||||||
{
|
{
|
||||||
auto result = WaitForSingleObject(m_handle, INFINITE);
|
auto result = WaitForSingleObject(m_handle, INFINITE);
|
||||||
if (result == WAIT_FAILED)
|
if (result == WAIT_FAILED)
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
|
|
||||||
DWORD exit_code = 0;
|
DWORD exit_code = 0;
|
||||||
if (!GetExitCodeProcess(m_handle, &exit_code))
|
if (!GetExitCodeProcess(m_handle, &exit_code))
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
|
|
||||||
return exit_code;
|
return exit_code;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ ErrorOr<int> open(StringView path, int options, mode_t mode)
|
||||||
if (::stat(sz_path, &st) == 0 && (st.st_mode & S_IFDIR)) {
|
if (::stat(sz_path, &st) == 0 && (st.st_mode & S_IFDIR)) {
|
||||||
HANDLE dir_handle = CreateFile(sz_path, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
HANDLE dir_handle = CreateFile(sz_path, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
|
||||||
if (dir_handle == INVALID_HANDLE_VALUE)
|
if (dir_handle == INVALID_HANDLE_VALUE)
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
int dir_fd = _open_osfhandle((intptr_t)dir_handle, 0);
|
int dir_fd = _open_osfhandle((intptr_t)dir_handle, 0);
|
||||||
if (dir_fd != -1)
|
if (dir_fd != -1)
|
||||||
return dir_fd;
|
return dir_fd;
|
||||||
|
@ -84,7 +84,7 @@ ErrorOr<void> ftruncate(int fd, off_t length)
|
||||||
return result.release_error();
|
return result.release_error();
|
||||||
|
|
||||||
if (SetEndOfFile((HANDLE)_get_osfhandle(fd)) == 0)
|
if (SetEndOfFile((HANDLE)_get_osfhandle(fd)) == 0)
|
||||||
return Error::from_windows_error(GetLastError());
|
return Error::from_windows_error();
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue