Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Execution/Platform/Windows/Exception.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#include "Stroika/Foundation/StroikaPreComp.h"
5
6#if qStroika_Foundation_Common_Platform_Windows
7#include <Windows.h>
8
9#include <shellapi.h>
10#include <winerror.h>
11#include <wininet.h> // for error codes
12#else
13#error "WINDOWS REQUIRED FOR THIS MODULE"
14#endif
15
18#include "Stroika/Foundation/Common/Common.h"
19#include "Stroika/Foundation/Containers/Common.h"
21#include "Stroika/Foundation/Execution/TimeOutException.h"
22#if qStroika_Foundation_Common_Platform_Windows
23#include "HRESULTErrorException.h"
24#endif
26
27#include "Exception.h"
28
29using namespace Stroika::Foundation;
31using namespace Stroika::Foundation::Debug;
32using namespace Stroika::Foundation::Execution;
33using namespace Stroika::Foundation::Execution::Platform;
35
36// for InternetGetConnectedState
37#if _MSC_VER
38#pragma comment(lib, "Wininet.lib")
39#endif
40
41namespace {
42 inline SDKString Win32Error2String_ (DWORD win32Err)
43 {
44 switch (win32Err) {
45 case ERROR_NOT_ENOUGH_MEMORY:
46 return SDKSTR ("Not enough memory to complete that operation (ERROR_NOT_ENOUGH_MEMORY)");
47 case ERROR_OUTOFMEMORY:
48 return SDKSTR ("Not enough memory to complete that operation (ERROR_OUTOFMEMORY)");
49 case WSAEADDRNOTAVAIL:
50 return SDKSTR ("Socket address not available (WSAEADDRNOTAVAIL)");
51 }
52 if (INTERNET_ERROR_BASE <= win32Err and win32Err < INTERNET_ERROR_BASE + INTERNET_ERROR_LAST) {
53 switch (win32Err) {
54 case ERROR_INTERNET_INVALID_URL:
55 return SDKSTR ("ERROR_INTERNET_INVALID_URL");
56 case ERROR_INTERNET_CANNOT_CONNECT:
57 return SDKSTR ("Failed to connect to internet URL (ERROR_INTERNET_CANNOT_CONNECT)");
58 case ERROR_INTERNET_NAME_NOT_RESOLVED:
59 return SDKSTR ("ERROR_INTERNET_NAME_NOT_RESOLVED");
60 case ERROR_INTERNET_INCORRECT_HANDLE_STATE:
61 return SDKSTR ("ERROR_INTERNET_INCORRECT_HANDLE_STATE");
62 case ERROR_INTERNET_TIMEOUT:
63 return SDKSTR ("Operation timed out (ERROR_INTERNET_TIMEOUT)");
64 case ERROR_INTERNET_CONNECTION_ABORTED:
65 return SDKSTR ("ERROR_INTERNET_CONNECTION_ABORTED");
66 case ERROR_INTERNET_CONNECTION_RESET:
67 return SDKSTR ("ERROR_INTERNET_CONNECTION_RESET");
68 case ERROR_HTTP_INVALID_SERVER_RESPONSE:
69 return SDKSTR ("Invalid Server Response (ERROR_HTTP_INVALID_SERVER_RESPONSE)");
70 case ERROR_INTERNET_PROTOCOL_NOT_FOUND: {
71 DWORD r = 0;
72 if (::InternetGetConnectedState (&r, 0) and (r & INTERNET_CONNECTION_OFFLINE) == 0) {
73 return SDKSTR ("ERROR_INTERNET_PROTOCOL_NOT_FOUND");
74 }
75 else {
76 return SDKSTR ("ERROR_INTERNET_PROTOCOL_NOT_FOUND (offline mode)");
77 }
78 }
79 default: {
80 TCHAR buf[1024];
81 (void)::_stprintf_s (buf, SDKSTR ("INTERNET error code: %d"), win32Err);
82 return buf;
83 }
84 }
85 }
86 TCHAR* lpMsgBuf = nullptr;
87 if (not::FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
88 win32Err, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
89 reinterpret_cast<TCHAR*> (&lpMsgBuf), 0, nullptr)) {
90 return CString::Format (SDKSTR ("Win32 error# %d"), static_cast<DWORD> (win32Err));
91 }
92 SDKString result = lpMsgBuf;
93 ::LocalFree (lpMsgBuf);
94 return CString::Trim (result);
95 }
96}
97
98/*
99 ********************************************************************************
100 ***************************** ThrowIfShellExecError ****************************
101 ********************************************************************************
102 */
104{
107 int errCode = reinterpret_cast<int> (r);
108 DISABLE_COMPILER_MSC_WARNING_END (4311)
109 DISABLE_COMPILER_MSC_WARNING_END (4302)
110 if (errCode <= 32) {
111 DbgTrace ("ThrowIfShellExecError (0x{:x}) - throwing exception"_f, errCode);
112 switch (errCode) {
113 case 0:
114 Execution::ThrowSystemErrNo (ERROR_NOT_ENOUGH_MEMORY); // The operating system is out of memory or resources.
115 case ERROR_FILE_NOT_FOUND:
116 Execution::ThrowSystemErrNo (ERROR_FILE_NOT_FOUND); // The specified file was not found.
117 case ERROR_PATH_NOT_FOUND:
118 Execution::ThrowSystemErrNo (ERROR_PATH_NOT_FOUND); // The specified path was not found.
119 case ERROR_BAD_FORMAT:
120 Execution::ThrowSystemErrNo (ERROR_BAD_FORMAT); // The .exe file is invalid (non-Microsoft Win32� .exe or error in .exe image).
121 case SE_ERR_ACCESSDENIED:
122 Execution::Throw (SystemErrorException{E_ACCESSDENIED, HRESULT_error_category ()}); // The operating system denied access to the specified file.
123 case SE_ERR_ASSOCINCOMPLETE:
124 Execution::ThrowSystemErrNo (ERROR_NO_ASSOCIATION); // The file name association is incomplete or invalid.
125 case SE_ERR_DDEBUSY:
126 Execution::ThrowSystemErrNo (ERROR_DDE_FAIL); // The Dynamic Data Exchange (DDE) transaction could not be completed because other DDE transactions were being processed.
127 case SE_ERR_DDEFAIL:
128 Execution::ThrowSystemErrNo (ERROR_DDE_FAIL); // The DDE transaction failed.
129 case SE_ERR_DDETIMEOUT:
130 Execution::ThrowSystemErrNo (ERROR_DDE_FAIL); // The DDE transaction could not be completed because the request timed out.
131 case SE_ERR_DLLNOTFOUND:
132 Execution::ThrowSystemErrNo (ERROR_DLL_NOT_FOUND); // The specified dynamic-link library (DLL) was not found.
133 //case SE_ERR_FNF: throw (Platform::Windows::Exception (ERROR_FILE_NOT_FOUND)); // The specified file was not found.
134 case SE_ERR_NOASSOC:
135 Execution::ThrowSystemErrNo (ERROR_NO_ASSOCIATION); // There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable.
136 case SE_ERR_OOM:
137 Execution::ThrowSystemErrNo (ERROR_NOT_ENOUGH_MEMORY); // There was not enough memory to complete the operation.
138 //case SE_ERR_PNF: throw (Platform::Windows::Exception (ERROR_PATH_NOT_FOUND)); // The specified path was not found.
139 case SE_ERR_SHARE:
140 Execution::ThrowSystemErrNo (ERROR_INVALID_SHARENAME); //
141 default: {
142 // Not sure what error to report here...
143 Execution::ThrowSystemErrNo (ERROR_NO_ASSOCIATION);
144 }
145 }
146 }
147}
148
149/*
150 ********************************************************************************
151 *********** Execution::RegisterDefaultHandler_invalid_parameter ****************
152 ********************************************************************************
153 */
154namespace {
155 /*
156 * Because of Microsoft's new secure-runtime-lib - we must provide a handler to catch errors (shouldn't occur - but in case.
157 * We treat these largely like ASSERTION errors, but then translate them into a THROW of an exception - since that is
158 * probably more often the right thing todo.
159 */
160 void invalid_parameter_handler_ ([[maybe_unused]] const wchar_t* expression, [[maybe_unused]] const wchar_t* function,
161 [[maybe_unused]] const wchar_t* file, [[maybe_unused]] unsigned int line, [[maybe_unused]] uintptr_t pReserved)
162 {
164 L"invalid_parameter_handler", L"Func='{}', expr='{}', file='{}', line={}."_f, function, expression, file, line)};
165 Assert (false);
166 Execution::ThrowSystemErrNo (ERROR_INVALID_PARAMETER);
167 }
168}
170{
171 (void)_set_invalid_parameter_handler (invalid_parameter_handler_);
172}
#define DbgTrace
Definition Trace.h:309
#define Stroika_Foundation_Debug_OptionalizeTraceArgs(...)
Definition Trace.h:270
basic_string< SDKChar > SDKString
Definition SDKString.h:38
void Throw(T &&e2Throw)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...
Definition Throw.inl:43