1
0
forked from mirrors/0ad

fix error propagation/avoid SetLastError pollution

This was SVN commit r9411.
This commit is contained in:
janwas
2011-05-03 13:46:35 +00:00
parent cccd6849a7
commit cce3bebe0c
10 changed files with 53 additions and 20 deletions
+1
View File
@@ -130,6 +130,7 @@ STATUS_DEFINE(ERR, TIMED_OUT, L"Timed out", -1);
STATUS_DEFINE(ERR, REENTERED, L"Single-call function was reentered", -1);
STATUS_DEFINE(ERR, CORRUPTED, L"File/memory data is corrupted", -1);
STATUS_DEFINE(ERR, VERSION, L"Version mismatch", -1);
STATUS_DEFINE(ERR, ABORTED, L"Operation aborted", -1);
STATUS_DEFINE(ERR, INVALID_PARAM, L"Invalid function argument", EINVAL);
STATUS_DEFINE(ERR, INVALID_HANDLE, L"Invalid Handle (argument)", -1);
+2 -1
View File
@@ -251,7 +251,7 @@ extern Status StatusFromErrno();
{\
const Status status_ = (expression);\
if(status_ < 0)\
DEBUG_WARN_ERR(status_);\
DEBUG_WARN_ERR(status_);\
}\
while(0)
@@ -375,6 +375,7 @@ namespace ERR
const Status REENTERED = -100012;
const Status CORRUPTED = -100013;
const Status VERSION = -100014;
const Status ABORTED = -100015;
// function arguments
const Status INVALID_PARAM = -100020;
+10
View File
@@ -251,7 +251,11 @@ static void StartDriver(const OsPath& driverPathname)
{
const SC_HANDLE hSCM = OpenServiceControlManager();
if(!hSCM)
{
ENSURE(GetLastError() == ERROR_ACCESS_DENIED);
SetLastError(0);
return;
}
SC_HANDLE hService = OpenServiceW(hSCM, AKEN_NAME, SERVICE_ALL_ACCESS);
@@ -328,6 +332,8 @@ static OsPath DriverPathname()
static Status Init()
{
WinScopedPreserveLastError s;
if(wutil_HasCommandLineArgument(L"-wNoMahaf"))
return ERR::NOT_SUPPORTED; // NOWARN
@@ -340,7 +346,11 @@ static Status Init()
const DWORD shareMode = 0;
hAken = CreateFileW(L"\\\\.\\Aken", GENERIC_READ, shareMode, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if(hAken == INVALID_HANDLE_VALUE)
{
ENSURE(GetLastError() == ERROR_FILE_NOT_FOUND);
SetLastError(0);
return ERR::INVALID_HANDLE; // NOWARN (happens often due to security restrictions)
}
}
return INFO::OK;
+5 -9
View File
@@ -333,16 +333,12 @@ public:
Status Poll(DirWatchNotifications& notifications)
{
POLL_AGAIN:
DWORD bytesTransferred; ULONG_PTR key; OVERLAPPED* ovl;
for(;;) // skip notifications of canceled watches
{
const Status ret = PollCompletionPort(hIOCP, 0, bytesTransferred, key, ovl);
if(ret == INFO::OK)
break;
if(GetLastError() == ERROR_OPERATION_ABORTED)
continue; // watch was canceled - ignore
return ret;
}
const Status ret = PollCompletionPort(hIOCP, 0, bytesTransferred, key, ovl);
if(ret == ERR::ABORTED) // watch was canceled
goto POLL_AGAIN;
RETURN_STATUS_IF_ERR(ret);
DirWatchRequest* request = (DirWatchRequest*)key;
request->RetrieveNotifications(notifications);
+3 -1
View File
@@ -30,7 +30,7 @@
#include <process.h> // _beginthreadex
#include "lib/sysdep/cpu.h"
#include "lib/sysdep/os/win/win.h"
#include "lib/sysdep/os/win/wutil.h"
#include "lib/sysdep/os/win/winit.h"
#include "lib/sysdep/acpi.h"
#include "lib/bits.h"
@@ -261,6 +261,8 @@ static unsigned __stdcall UpdateThread(void* UNUSED(data))
static inline Status InitUpdateThread()
{
WinScopedPreserveLastError s; // CreateEvent
// make sure our interval isn't too long
// (counterBits can be 64 => Bit() would overflow => calculate period/2)
const double period_2 = Bit<u64>(counterBits-1) / nominalFrequency;
+6 -4
View File
@@ -20,13 +20,15 @@ Status PollCompletionPort(HANDLE hIOCP, DWORD timeout, DWORD& bytesTransferred,
if(hIOCP == 0)
return ERR::INVALID_HANDLE; // NOWARN (happens if called before the first Attach)
WinScopedPreserveLastError s;
bytesTransferred = 0;
key = 0;
ovl = 0;
if(GetQueuedCompletionStatus(hIOCP, &bytesTransferred, &key, &ovl, timeout))
return INFO::OK;
if(GetLastError() == WAIT_TIMEOUT)
return ERR::AGAIN; // NOWARN (nothing pending)
else
return ERR::FAIL; // NOWARN (let caller decide what to do)
const Status ret = StatusFromWin();
if(ret == ERR::AGAIN || ret == ERR::ABORTED) // avoid polluting last error
SetLastError(0);
return StatusFromWin(); // NOWARN (let caller decide what to do)
}
@@ -156,8 +156,10 @@ struct wdirent* wreaddir(WDIR* d)
{
if(!FindNextFileW(d->hFind, &d->findData))
{
if(GetLastError() != ERROR_NO_MORE_FILES) // an actual error occurred
WARN_IF_ERR(StatusFromWin());
if(GetLastError() == ERROR_NO_MORE_FILES)
SetLastError(0);
else // unexpected error
DEBUG_WARN_ERR(StatusFromWin());
return 0; // end of directory or error
}
}
+8 -3
View File
@@ -1485,6 +1485,8 @@ static void RedirectStdout()
if(wutil_IsValidHandle(GetStdHandle(STD_OUTPUT_HANDLE)))
return;
WinScopedPreserveLastError s; // ChangeExtension
// this code may be included in multiple executables sharing the same
// directory, so include the executable's name in the filename. use its
// full path since the current directory is unreliable.
@@ -1495,9 +1497,12 @@ static void RedirectStdout()
// that means stdout isn't associated with a lowio handle; _close is
// called with fd = -1. oh well, there's nothing we can do.
FILE* f = 0;
// (return value ignored - it indicates 'file already exists' even
// if f is valid)
(void)_wfreopen_s(&f, OsString(pathname).c_str(), L"wt", stdout);
errno_t ret = _wfreopen_s(&f, OsString(pathname).c_str(), L"wt", stdout);
// (ignore return value - it might indicate 'file already exists' even
// if f is valid, which is what actually counts)
UNUSED2(ret);
if(GetLastError() == ERROR_ALREADY_EXISTS)
SetLastError(0);
// executable directory (probably Program Files) is read-only for
// non-Administrators. we can't pick another directory because
// ah_log_dir might not be valid until the app's init has run,
+1
View File
@@ -390,6 +390,7 @@ Status sys_get_module_filename(void* addr, OsPath& pathname)
OsPath sys_ExecutablePathname()
{
WinScopedPreserveLastError s;
OsPath pathname;
ENSURE(GetModulePathname(0, pathname) == INFO::OK);
return pathname;
+13
View File
@@ -145,7 +145,10 @@ Status StatusFromWin()
case ERROR_PROC_NOT_FOUND:
return ERR::NO_SYS;
case ERROR_BUSY:
case WAIT_TIMEOUT:
return ERR::AGAIN;
case ERROR_OPERATION_ABORTED:
return ERR::ABORTED;
case ERROR_FILE_NOT_FOUND:
return ERR::VFS_FILE_NOT_FOUND;
case ERROR_PATH_NOT_FOUND:
@@ -289,6 +292,8 @@ static void GetDirectories()
wchar_t path[MAX_PATH]; // mandated by SHGetFolderPathW
const HRESULT ret = SHGetFolderPathW(hwnd, CSIDL_APPDATA, token, 0, path);
ENSURE(SUCCEEDED(ret));
if(GetLastError() == ERROR_NO_TOKEN) // avoid polluting last error
SetLastError(0);
appdataPath = new(wutil_Allocate(sizeof(OsPath))) OsPath(path);
}
}
@@ -340,6 +345,14 @@ static void FreeUser32Dll()
static void EnableLowFragmentationHeap()
{
if(IsDebuggerPresent())
{
// and the debug heap isn't explicitly disabled,
char* var = getenv("_NO_DEBUG_HEAP");
if(!var || var[0] != '1')
return; // we can't enable the LFH
}
#if WINVER >= 0x0501
WUTIL_FUNC(pHeapSetInformation, BOOL, (HANDLE, HEAP_INFORMATION_CLASS, void*, size_t));
WUTIL_IMPORT_KERNEL32(HeapSetInformation, pHeapSetInformation);