aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--c/data.cpp69
-rw-r--r--c/main.cpp2
-rw-r--r--c/win.cpp86
-rw-r--r--c/win.h26
4 files changed, 122 insertions, 61 deletions
diff --git a/c/data.cpp b/c/data.cpp
index 771e6fb..e260209 100644
--- a/c/data.cpp
+++ b/c/data.cpp
@@ -6,46 +6,45 @@
#include <libxml/xpath.h>
#include "data.h"
+#include "win.h"
struct InternetFile
{
- InternetFile(const wchar_t* url);
- ~InternetFile();
- DWORD Read(void* buf, DWORD cb);
- HINTERNET hi;
- HINTERNET hiUrl;
-};
+ InternetFile(const wchar_t* url)
+ {
+ hi = InternetOpen(L"Episode Browser",
+ INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr,
+ /*INTERNET_FLAG_ASYNC*/0);
+ if (!hi)
+ throw Win32Error{};
+
+ hiUrl = InternetOpenUrl(hi, url,
+ nullptr, 0, INTERNET_FLAG_NO_UI, 0);
+ if (!hiUrl) {
+ DWORD e = GetLastError();
+ InternetCloseHandle(hi);
+ throw InternetError(e);
+ }
+ }
-InternetFile::InternetFile(const wchar_t* url)
-{
- hi = InternetOpen(L"Episode Browser",
- INTERNET_OPEN_TYPE_DIRECT, nullptr, nullptr,
- /*INTERNET_FLAG_ASYNC*/0);
- if (!hi)
- throw Win32Error{};
-
- hiUrl = InternetOpenUrl(hi, url,
- nullptr, 0, INTERNET_FLAG_NO_UI, 0);
- if (!hiUrl) {
+ ~InternetFile()
+ {
+ InternetCloseHandle(hiUrl);
InternetCloseHandle(hi);
- throw Win32Error{};
}
-}
-InternetFile::~InternetFile()
-{
- InternetCloseHandle(hiUrl);
- InternetCloseHandle(hi);
-}
+ DWORD Read(void* buf, DWORD cb)
+ {
+ DWORD cbRead;
+ if (InternetReadFile(hiUrl, buf, cb, &cbRead))
+ return cbRead;
+ else
+ throw InternetError{};
+ }
-DWORD InternetFile::Read(void* buf, DWORD cb)
-{
- DWORD cbRead;
- if (InternetReadFile(hiUrl, buf, cb, &cbRead))
- return cbRead;
- else
- throw Win32Error{};
-}
+ HINTERNET hi;
+ HINTERNET hiUrl;
+};
template <auto F, typename T>
struct XmlPtr
@@ -98,8 +97,8 @@ void FetchData()
{
LIBXML_TEST_VERSION;
- InternetFile inf{L"https://www.detectiveconanworld.com/wiki/Anime"};
- //InternetFile inf{L"file://C:/Users/John/Desktop/dcw.html"};
+ InternetFile inf(L"https://www.detectiveconanworld.com/wiki/Anime");
+ //InternetFile inf(L"file://C:/Users/John/Desktop/dcw.html");
char buf[1024];
HtmlParserCtxtPtr ctxt = htmlCreatePushParserCtxt(nullptr, nullptr,
@@ -167,6 +166,6 @@ void WaitFetchData(bool* bDone) noexcept
*bDone = true;
} catch (...) {
*bDone = true;
- ShowException(L"Remote data could not be fetched due to %s: %s", L"Error", MB_ICONWARNING);
+ ShowException(L"Remote data could not be fetched due to an error: %s", L"Error", MB_ICONWARNING);
}
}
diff --git a/c/main.cpp b/c/main.cpp
index 73a89d4..0e6c839 100644
--- a/c/main.cpp
+++ b/c/main.cpp
@@ -81,7 +81,7 @@ static void UpdateTheme();
void OnTerminate() noexcept
{
- ShowException(L"Episode Browser was terminated due to %s: %s", L"Fatal Error", MB_ICONERROR);
+ ShowException(L"Episode Browser was terminated due to an error: %s", L"Fatal Error", MB_ICONERROR);
_Exit(1);
}
diff --git a/c/win.cpp b/c/win.cpp
index c7ce7ec..601f82c 100644
--- a/c/win.cpp
+++ b/c/win.cpp
@@ -2,6 +2,7 @@
#include <string>
#include <SWI-Prolog.h>
#include <windows.h>
+#include <wininet.h>
#include "pl.h"
#include "util.h"
@@ -84,24 +85,29 @@ int EBMessageBox(const std::wstring_view text, const std::wstring_view caption,
void ShowException(const wchar_t* const fmt, const wchar_t* const title, const UINT uType) noexcept
{
- const wchar_t* what = L"an exception";
- WcharPtr why;
-
try {
std::rethrow_exception(std::current_exception());
} catch (const term_t& t) {
- what = L"a Prolog exception";
- try { why = PlString(t); } catch (...) {}
- } catch (const Win32Error& e) {
- what = L"a Windows error";
- try { why = WcharPtr::Copy(e.What()); } catch (...) {}
+ WcharPtr what = PlString(t);
+ std::wstring msg(wcslen(fmt)+wcslen(what), 0);
+ Swprintf(msg, fmt, static_cast<wchar_t*>(what));
+ EBMessageBox(msg, title, uType);
+ } catch (const WideException& e) {
+ std::wstring msg(wcslen(fmt)+wcslen(e.What()), 0);
+ Swprintf(msg, fmt, e.What());
+ EBMessageBox(msg, title, uType);
} catch (const std::exception& e) {
- try { why = WcharPtr::FromNarrow(e.what()); } catch (...) {}
- } catch (...) {}
+ auto what = WcharPtr::FromNarrow(e.what());
+ std::wstring msg(wcslen(fmt)+wcslen(what), 0);
+ Swprintf(msg, fmt, static_cast<wchar_t*>(what));
+ EBMessageBox(msg, title, uType);
+ } catch (...) {
+ const wchar_t* what = L"an unknown error occurred";
+ std::wstring msg(wcslen(fmt)+wcslen(what), 0);
+ Swprintf(msg, fmt, what);
+ EBMessageBox(msg, title, uType);
+ }
- std::wstring msg(wcslen(fmt)+wcslen(what)+wcslen(why), 0);
- Swprintf(msg, fmt, what, static_cast<wchar_t*>(why));
- EBMessageBox(msg, title, uType);
}
int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept
@@ -118,9 +124,6 @@ int GetRelativeCursorPos(const HWND hWnd, POINT* const pt) noexcept
return 1;
}
-Win32Error::Win32Error() noexcept
- : code(GetLastError()) {}
-
Win32Error::Win32Error(const DWORD code) noexcept
: code(code) {}
@@ -136,25 +139,66 @@ const char* Win32Error::what() const noexcept
{
if (!m_szMsg)
FormatMessageA(
- FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr,
+ FORMAT_MESSAGE_ALLOCATE_BUFFER
+ |FORMAT_MESSAGE_FROM_SYSTEM
+ |FORMAT_MESSAGE_FROM_HMODULE
+ |FORMAT_MESSAGE_IGNORE_INSERTS,
+ GetModuleHandle(L"wininet.dll"),
code,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(char*)&m_szMsg,
0, nullptr);
- return m_szMsg;
+ return m_szMsg? m_szMsg: "An unknown error occurred";
}
const wchar_t* Win32Error::What() const noexcept
{
if (!m_wszMsg)
FormatMessage(
- FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
- nullptr,
+ FORMAT_MESSAGE_ALLOCATE_BUFFER
+ |FORMAT_MESSAGE_FROM_SYSTEM
+ |FORMAT_MESSAGE_FROM_HMODULE
+ |FORMAT_MESSAGE_IGNORE_INSERTS,
+ GetModuleHandle(L"wininet.dll"),
code,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
(wchar_t*)&m_wszMsg,
0, nullptr);
+ return m_wszMsg? m_wszMsg: L"An unknown error occurred";
+}
+
+InternetError::InternetError(DWORD codeSystem)
+{
+ if (codeSystem != ERROR_INTERNET_EXTENDED_ERROR)
+ throw Win32Error{codeSystem};
+
+ DWORD len, cch;
+ InternetGetLastResponseInfo(&code, nullptr, &len);
+
+ cch = len+1;
+ m_szMsg = new char[cch];
+ if (!InternetGetLastResponseInfoA(&code, m_szMsg, &cch))
+ throw Win32Error{};
+
+ cch = len+1;
+ m_wszMsg = new wchar_t[cch];
+ if (!InternetGetLastResponseInfo(&code, m_wszMsg, &len))
+ throw Win32Error{};
+}
+
+InternetError::~InternetError()
+{
+ delete m_szMsg;
+ delete m_wszMsg;
+}
+
+const char* InternetError::what() const noexcept
+{
+ return m_szMsg;
+}
+
+const wchar_t* InternetError::What() const noexcept
+{
return m_wszMsg;
}
diff --git a/c/win.h b/c/win.h
index ab5cf05..f5bda59 100644
--- a/c/win.h
+++ b/c/win.h
@@ -16,14 +16,32 @@ int GetRelativeCursorPos(HWND hWnd, POINT* pt) noexcept;
/* Cached values from GetSystemMetrics. */
template <int I> auto Metric = GetSystemMetrics(I);
+struct WideException : public std::exception
+{
+ virtual const char* what() const noexcept = 0;
+ virtual const wchar_t* What() const noexcept = 0;
+};
+
/* Exception for Windows API errors. */
-struct Win32Error : public std::exception
+struct Win32Error : public WideException
{
- Win32Error() noexcept;
- Win32Error(DWORD code) noexcept;
+ Win32Error(DWORD code = GetLastError()) noexcept;
~Win32Error() noexcept;
const char* what() const noexcept override;
- const wchar_t* What() const noexcept;
+ const wchar_t* What() const noexcept override;
+ DWORD code;
+private:
+ char* m_szMsg = nullptr;
+ wchar_t* m_wszMsg = nullptr;
+};
+
+/* Exception for extended Wininet errors. */
+struct InternetError : public WideException
+{
+ InternetError(DWORD codeSystem = GetLastError());
+ ~InternetError() noexcept;
+ const char* what() const noexcept override;
+ const wchar_t* What() const noexcept override;
DWORD code;
private:
char* m_szMsg = nullptr;