Refactor to use TIB LastErrorValue

This commit is contained in:
2025-10-28 10:01:21 -06:00
parent 8bd15bd272
commit 9367f003c5
34 changed files with 785 additions and 745 deletions

View File

@@ -14,7 +14,7 @@ BOOL WIN_FUNC OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDL
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("OpenProcessToken(%p, %u, %p)\n", ProcessHandle, DesiredAccess, TokenHandle); DEBUG_LOG("OpenProcessToken(%p, %u, %p)\n", ProcessHandle, DesiredAccess, TokenHandle);
if (!TokenHandle) { if (!TokenHandle) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
Pin<ProcessObject> obj; Pin<ProcessObject> obj;
@@ -24,7 +24,7 @@ BOOL WIN_FUNC OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDL
obj = wibo::handles().getAs<ProcessObject>(ProcessHandle); obj = wibo::handles().getAs<ProcessObject>(ProcessHandle);
} }
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
auto token = make_pin<TokenObject>(std::move(obj), DesiredAccess); auto token = make_pin<TokenObject>(std::move(obj), DesiredAccess);

View File

@@ -5,6 +5,7 @@
#include "errors.h" #include "errors.h"
#include "handles.h" #include "handles.h"
#include "internal.h" #include "internal.h"
#include "kernel32/internal.h"
#include <algorithm> #include <algorithm>
#include <cstring> #include <cstring>
@@ -106,11 +107,11 @@ BOOL WIN_FUNC InitializeAcl(PACL pAcl, DWORD nAclLength, DWORD dwAclRevision) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("InitializeAcl(%p, %u, %u)\n", pAcl, nAclLength, dwAclRevision); DEBUG_LOG("InitializeAcl(%p, %u, %u)\n", pAcl, nAclLength, dwAclRevision);
if (!pAcl) { if (!pAcl) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (nAclLength < sizeof(ACL) || nAclLength > std::numeric_limits<WORD>::max() || (nAclLength & 0x3) != 0) { if (nAclLength < sizeof(ACL) || nAclLength > std::numeric_limits<WORD>::max() || (nAclLength & 0x3) != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
BYTE revision = static_cast<BYTE>(dwAclRevision); BYTE revision = static_cast<BYTE>(dwAclRevision);
@@ -121,7 +122,7 @@ BOOL WIN_FUNC InitializeAcl(PACL pAcl, DWORD nAclLength, DWORD dwAclRevision) {
case ACL_REVISION4: case ACL_REVISION4:
break; break;
default: default:
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
pAcl->AclRevision = revision; pAcl->AclRevision = revision;
@@ -136,7 +137,7 @@ BOOL WIN_FUNC AddAccessAllowedAce(PACL pAcl, DWORD dwAceRevision, DWORD AccessMa
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("AddAccessAllowedAce(%p, %u, 0x%x, %p)\n", pAcl, dwAceRevision, AccessMask, pSid); DEBUG_LOG("AddAccessAllowedAce(%p, %u, 0x%x, %p)\n", pAcl, dwAceRevision, AccessMask, pSid);
if (!pAcl || !pSid) { if (!pAcl || !pSid) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
BYTE revision = static_cast<BYTE>(dwAceRevision); BYTE revision = static_cast<BYTE>(dwAceRevision);
@@ -147,25 +148,25 @@ BOOL WIN_FUNC AddAccessAllowedAce(PACL pAcl, DWORD dwAceRevision, DWORD AccessMa
case ACL_REVISION4: case ACL_REVISION4:
break; break;
default: default:
wibo::lastError = ERROR_REVISION_MISMATCH; kernel32::setLastError(ERROR_REVISION_MISMATCH);
return FALSE; return FALSE;
} }
if (pAcl->AclRevision < revision) { if (pAcl->AclRevision < revision) {
wibo::lastError = ERROR_REVISION_MISMATCH; kernel32::setLastError(ERROR_REVISION_MISMATCH);
return FALSE; return FALSE;
} }
if (pAcl->AceCount == std::numeric_limits<WORD>::max()) { if (pAcl->AceCount == std::numeric_limits<WORD>::max()) {
wibo::lastError = ERROR_ALLOTTED_SPACE_EXCEEDED; kernel32::setLastError(ERROR_ALLOTTED_SPACE_EXCEEDED);
return FALSE; return FALSE;
} }
size_t capacity = pAcl->Sbz2 ? pAcl->Sbz2 : pAcl->AclSize; size_t capacity = pAcl->Sbz2 ? pAcl->Sbz2 : pAcl->AclSize;
if (capacity < sizeof(ACL)) { if (capacity < sizeof(ACL)) {
wibo::lastError = ERROR_INVALID_ACL; kernel32::setLastError(ERROR_INVALID_ACL);
return FALSE; return FALSE;
} }
size_t used = 0; size_t used = 0;
if (!computeAclUsedSize(pAcl, capacity, used)) { if (!computeAclUsedSize(pAcl, capacity, used)) {
wibo::lastError = ERROR_INVALID_ACL; kernel32::setLastError(ERROR_INVALID_ACL);
return FALSE; return FALSE;
} }
if (used > pAcl->AclSize) { if (used > pAcl->AclSize) {
@@ -175,17 +176,17 @@ BOOL WIN_FUNC AddAccessAllowedAce(PACL pAcl, DWORD dwAceRevision, DWORD AccessMa
const auto *sid = reinterpret_cast<const Sid *>(pSid); const auto *sid = reinterpret_cast<const Sid *>(pSid);
size_t sidLen = sidLength(sid); size_t sidLen = sidLength(sid);
if (sidLen == 0 || sidLen > capacity) { if (sidLen == 0 || sidLen > capacity) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return FALSE; return FALSE;
} }
size_t aceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidLen; size_t aceSize = sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidLen;
aceSize = alignToDword(aceSize); aceSize = alignToDword(aceSize);
if (aceSize > std::numeric_limits<WORD>::max()) { if (aceSize > std::numeric_limits<WORD>::max()) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return FALSE; return FALSE;
} }
if (used + aceSize > capacity) { if (used + aceSize > capacity) {
wibo::lastError = ERROR_ALLOTTED_SPACE_EXCEEDED; kernel32::setLastError(ERROR_ALLOTTED_SPACE_EXCEEDED);
return FALSE; return FALSE;
} }
auto *dest = reinterpret_cast<BYTE *>(pAcl) + used; auto *dest = reinterpret_cast<BYTE *>(pAcl) + used;
@@ -205,18 +206,18 @@ BOOL WIN_FUNC FindFirstFreeAce(PACL pAcl, LPVOID *pAce) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FindFirstFreeAce(%p, %p)\n", pAcl, pAce); DEBUG_LOG("FindFirstFreeAce(%p, %p)\n", pAcl, pAce);
if (!pAce) { if (!pAce) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*pAce = nullptr; *pAce = nullptr;
if (!pAcl) { if (!pAcl) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
size_t capacity = pAcl->Sbz2 ? pAcl->Sbz2 : pAcl->AclSize; size_t capacity = pAcl->Sbz2 ? pAcl->Sbz2 : pAcl->AclSize;
size_t used = 0; size_t used = 0;
if (!computeAclUsedSize(pAcl, capacity, used)) { if (!computeAclUsedSize(pAcl, capacity, used)) {
wibo::lastError = ERROR_INVALID_ACL; kernel32::setLastError(ERROR_INVALID_ACL);
return FALSE; return FALSE;
} }
*pAce = reinterpret_cast<BYTE *>(pAcl) + used; *pAce = reinterpret_cast<BYTE *>(pAcl) + used;
@@ -230,15 +231,15 @@ BOOL WIN_FUNC GetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor
DEBUG_LOG("GetSecurityDescriptorDacl(%p, %p, %p, %p)\n", pSecurityDescriptor, lpbDaclPresent, pDacl, DEBUG_LOG("GetSecurityDescriptorDacl(%p, %p, %p, %p)\n", pSecurityDescriptor, lpbDaclPresent, pDacl,
lpbDaclDefaulted); lpbDaclDefaulted);
if (!pSecurityDescriptor) { if (!pSecurityDescriptor) {
wibo::lastError = ERROR_INVALID_SECURITY_DESCR; kernel32::setLastError(ERROR_INVALID_SECURITY_DESCR);
return FALSE; return FALSE;
} }
if (!lpbDaclPresent) { if (!lpbDaclPresent) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) { if (pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
wibo::lastError = ERROR_INVALID_SECURITY_DESCR; kernel32::setLastError(ERROR_INVALID_SECURITY_DESCR);
return FALSE; return FALSE;
} }
BOOL hasDacl = (pSecurityDescriptor->Control & SE_DACL_PRESENT) ? TRUE : FALSE; BOOL hasDacl = (pSecurityDescriptor->Control & SE_DACL_PRESENT) ? TRUE : FALSE;
@@ -265,12 +266,12 @@ PSID_IDENTIFIER_AUTHORITY WIN_FUNC GetSidIdentifierAuthority(PSID pSid) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetSidIdentifierAuthority(%p)\n", pSid); DEBUG_LOG("GetSidIdentifierAuthority(%p)\n", pSid);
if (!pSid) { if (!pSid) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return nullptr; return nullptr;
} }
auto *sid = reinterpret_cast<Sid *>(pSid); auto *sid = reinterpret_cast<Sid *>(pSid);
if (sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { if (sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return nullptr; return nullptr;
} }
return reinterpret_cast<PSID_IDENTIFIER_AUTHORITY>(&sid->IdentifierAuthority); return reinterpret_cast<PSID_IDENTIFIER_AUTHORITY>(&sid->IdentifierAuthority);
@@ -280,12 +281,12 @@ PUCHAR WIN_FUNC GetSidSubAuthorityCount(PSID pSid) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetSidSubAuthorityCount(%p)\n", pSid); DEBUG_LOG("GetSidSubAuthorityCount(%p)\n", pSid);
if (!pSid) { if (!pSid) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return nullptr; return nullptr;
} }
auto *sid = reinterpret_cast<Sid *>(pSid); auto *sid = reinterpret_cast<Sid *>(pSid);
if (sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { if (sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return nullptr; return nullptr;
} }
return &sid->SubAuthorityCount; return &sid->SubAuthorityCount;
@@ -295,12 +296,12 @@ PDWORD WIN_FUNC GetSidSubAuthority(PSID pSid, DWORD nSubAuthority) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetSidSubAuthority(%p, %u)\n", pSid, nSubAuthority); DEBUG_LOG("GetSidSubAuthority(%p, %u)\n", pSid, nSubAuthority);
if (!pSid) { if (!pSid) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return nullptr; return nullptr;
} }
auto *sid = reinterpret_cast<Sid *>(pSid); auto *sid = reinterpret_cast<Sid *>(pSid);
if (sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES || nSubAuthority >= sid->SubAuthorityCount) { if (sid->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES || nSubAuthority >= sid->SubAuthorityCount) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return nullptr; return nullptr;
} }
return &sid->SubAuthority[nSubAuthority]; return &sid->SubAuthority[nSubAuthority];
@@ -322,12 +323,12 @@ BOOL WIN_FUNC DuplicateTokenEx(HANDLE hExistingToken, DWORD dwDesiredAccess, voi
(void)ImpersonationLevel; (void)ImpersonationLevel;
(void)TokenType; (void)TokenType;
if (!phNewToken) { if (!phNewToken) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto existing = wibo::handles().getAs<TokenObject>(hExistingToken); auto existing = wibo::handles().getAs<TokenObject>(hExistingToken);
if (!existing) { if (!existing) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
auto newToken = auto newToken =
@@ -340,13 +341,13 @@ BOOL WIN_FUNC CopySid(DWORD nDestinationSidLength, PSID pDestinationSid, PSID pS
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("CopySid(%u, %p, %p)\n", nDestinationSidLength, pDestinationSid, pSourceSid); DEBUG_LOG("CopySid(%u, %p, %p)\n", nDestinationSidLength, pDestinationSid, pSourceSid);
if (!pDestinationSid || !pSourceSid) { if (!pDestinationSid || !pSourceSid) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto *source = reinterpret_cast<Sid *>(pSourceSid); auto *source = reinterpret_cast<Sid *>(pSourceSid);
size_t required = sidLength(source); size_t required = sidLength(source);
if (required == 0 || required > nDestinationSidLength) { if (required == 0 || required > nDestinationSidLength) {
wibo::lastError = ERROR_ALLOTTED_SPACE_EXCEEDED; kernel32::setLastError(ERROR_ALLOTTED_SPACE_EXCEEDED);
return FALSE; return FALSE;
} }
std::memcpy(pDestinationSid, pSourceSid, required); std::memcpy(pDestinationSid, pSourceSid, required);
@@ -357,11 +358,11 @@ BOOL WIN_FUNC InitializeSid(PSID sid, PSID_IDENTIFIER_AUTHORITY pIdentifierAutho
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("InitializeSid(%p, %p, %u)\n", sid, pIdentifierAuthority, nSubAuthorityCount); DEBUG_LOG("InitializeSid(%p, %p, %u)\n", sid, pIdentifierAuthority, nSubAuthorityCount);
if (!sid || !pIdentifierAuthority) { if (!sid || !pIdentifierAuthority) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (nSubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { if (nSubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return FALSE; return FALSE;
} }
auto *sidStruct = reinterpret_cast<Sid *>(sid); auto *sidStruct = reinterpret_cast<Sid *>(sid);
@@ -378,13 +379,13 @@ BOOL WIN_FUNC EqualSid(PSID pSid1, PSID pSid2) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("EqualSid(%p, %p)\n", pSid1, pSid2); DEBUG_LOG("EqualSid(%p, %p)\n", pSid1, pSid2);
if (!pSid1 || !pSid2) { if (!pSid1 || !pSid2) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return FALSE; return FALSE;
} }
const auto *sid1 = reinterpret_cast<const Sid *>(pSid1); const auto *sid1 = reinterpret_cast<const Sid *>(pSid1);
const auto *sid2 = reinterpret_cast<const Sid *>(pSid2); const auto *sid2 = reinterpret_cast<const Sid *>(pSid2);
if (sid1->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES || sid2->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) { if (sid1->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES || sid2->SubAuthorityCount > SID_MAX_SUB_AUTHORITIES) {
wibo::lastError = ERROR_INVALID_SID; kernel32::setLastError(ERROR_INVALID_SID);
return FALSE; return FALSE;
} }
bool equal = bool equal =
@@ -403,12 +404,12 @@ BOOL WIN_FUNC SetKernelObjectSecurity(HANDLE Handle, SECURITY_INFORMATION Securi
DEBUG_LOG("STUB: SetKernelObjectSecurity(%p, 0x%x, %p)\n", Handle, SecurityInformation, SecurityDescriptor); DEBUG_LOG("STUB: SetKernelObjectSecurity(%p, 0x%x, %p)\n", Handle, SecurityInformation, SecurityDescriptor);
(void)SecurityInformation; (void)SecurityInformation;
if (!SecurityDescriptor) { if (!SecurityDescriptor) {
wibo::lastError = ERROR_INVALID_SECURITY_DESCR; kernel32::setLastError(ERROR_INVALID_SECURITY_DESCR);
return FALSE; return FALSE;
} }
auto obj = wibo::handles().get(Handle); auto obj = wibo::handles().get(Handle);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@@ -418,7 +419,7 @@ BOOL WIN_FUNC InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurityDescrip
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("InitializeSecurityDescriptor(%p, %u)\n", pSecurityDescriptor, dwRevision); DEBUG_LOG("InitializeSecurityDescriptor(%p, %u)\n", pSecurityDescriptor, dwRevision);
if (!pSecurityDescriptor || dwRevision != SECURITY_DESCRIPTOR_REVISION) { if (!pSecurityDescriptor || dwRevision != SECURITY_DESCRIPTOR_REVISION) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
pSecurityDescriptor->Revision = static_cast<BYTE>(dwRevision); pSecurityDescriptor->Revision = static_cast<BYTE>(dwRevision);
@@ -436,7 +437,7 @@ BOOL WIN_FUNC SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SetSecurityDescriptorDacl(%p, %u, %p, %u)\n", pSecurityDescriptor, bDaclPresent, pDacl, bDaclDefaulted); DEBUG_LOG("SetSecurityDescriptorDacl(%p, %u, %p, %u)\n", pSecurityDescriptor, bDaclPresent, pDacl, bDaclDefaulted);
if (!pSecurityDescriptor || pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) { if (!pSecurityDescriptor || pSecurityDescriptor->Revision != SECURITY_DESCRIPTOR_REVISION) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
WORD control = static_cast<WORD>(pSecurityDescriptor->Control & ~(SE_DACL_PRESENT | SE_DACL_DEFAULTED)); WORD control = static_cast<WORD>(pSecurityDescriptor->Control & ~(SE_DACL_PRESENT | SE_DACL_DEFAULTED));
@@ -459,12 +460,12 @@ BOOL WIN_FUNC GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS To
DEBUG_LOG("STUB: GetTokenInformation(%p, %u, %p, %u, %p)\n", TokenHandle, TokenInformationClass, TokenInformation, DEBUG_LOG("STUB: GetTokenInformation(%p, %u, %p, %u, %p)\n", TokenHandle, TokenInformationClass, TokenInformation,
TokenInformationLength, ReturnLength); TokenInformationLength, ReturnLength);
if (!ReturnLength) { if (!ReturnLength) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto token = wibo::handles().getAs<TokenObject>(TokenHandle); auto token = wibo::handles().getAs<TokenObject>(TokenHandle);
if (!token) { if (!token) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
*ReturnLength = 0; *ReturnLength = 0;
@@ -474,13 +475,13 @@ BOOL WIN_FUNC GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS To
DWORD required = static_cast<DWORD>(tokenUserSize + sidSize); DWORD required = static_cast<DWORD>(tokenUserSize + sidSize);
*ReturnLength = required; *ReturnLength = required;
if (!TokenInformation || TokenInformationLength < required) { if (!TokenInformation || TokenInformationLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
auto *tokenUser = reinterpret_cast<TokenUserData *>(TokenInformation); auto *tokenUser = reinterpret_cast<TokenUserData *>(TokenInformation);
auto *sid = reinterpret_cast<Sid *>(reinterpret_cast<BYTE *>(TokenInformation) + tokenUserSize); auto *sid = reinterpret_cast<Sid *>(reinterpret_cast<BYTE *>(TokenInformation) + tokenUserSize);
if (!writeLocalSystemSid(sid)) { if (!writeLocalSystemSid(sid)) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
tokenUser->User.SidPtr = sid; tokenUser->User.SidPtr = sid;
@@ -491,7 +492,7 @@ BOOL WIN_FUNC GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS To
DWORD required = sizeof(TokenStatisticsData); DWORD required = sizeof(TokenStatisticsData);
*ReturnLength = required; *ReturnLength = required;
if (!TokenInformation || TokenInformationLength < required) { if (!TokenInformation || TokenInformationLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
auto *stats = reinterpret_cast<TokenStatisticsData *>(TokenInformation); auto *stats = reinterpret_cast<TokenStatisticsData *>(TokenInformation);
@@ -507,7 +508,7 @@ BOOL WIN_FUNC GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS To
DWORD required = sizeof(DWORD); DWORD required = sizeof(DWORD);
*ReturnLength = required; *ReturnLength = required;
if (!TokenInformation || TokenInformationLength < required) { if (!TokenInformation || TokenInformationLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
*reinterpret_cast<DWORD *>(TokenInformation) = 0; // not elevated *reinterpret_cast<DWORD *>(TokenInformation) = 0; // not elevated
@@ -517,19 +518,19 @@ BOOL WIN_FUNC GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS To
DWORD required = static_cast<DWORD>(sizeof(TokenPrimaryGroupStub) + sizeof(Sid)); DWORD required = static_cast<DWORD>(sizeof(TokenPrimaryGroupStub) + sizeof(Sid));
*ReturnLength = required; *ReturnLength = required;
if (!TokenInformation || TokenInformationLength < required) { if (!TokenInformation || TokenInformationLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
auto *groupInfo = reinterpret_cast<TokenPrimaryGroupStub *>(TokenInformation); auto *groupInfo = reinterpret_cast<TokenPrimaryGroupStub *>(TokenInformation);
auto *sid = reinterpret_cast<Sid *>(reinterpret_cast<BYTE *>(TokenInformation) + sizeof(TokenPrimaryGroupStub)); auto *sid = reinterpret_cast<Sid *>(reinterpret_cast<BYTE *>(TokenInformation) + sizeof(TokenPrimaryGroupStub));
if (!writeLocalSystemSid(sid)) { if (!writeLocalSystemSid(sid)) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
groupInfo->PrimaryGroup = sid; groupInfo->PrimaryGroup = sid;
return TRUE; return TRUE;
} }
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
@@ -557,7 +558,7 @@ BOOL WIN_FUNC SetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS To
(void)TokenInformationLength; (void)TokenInformationLength;
auto token = wibo::handles().getAs<TokenObject>(TokenHandle); auto token = wibo::handles().getAs<TokenObject>(TokenHandle);
if (!token) { if (!token) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;

View File

@@ -4,6 +4,7 @@
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "internal.h" #include "internal.h"
#include "kernel32/internal.h"
#include "strutil.h" #include "strutil.h"
#include <algorithm> #include <algorithm>
@@ -90,12 +91,12 @@ BOOL WIN_FUNC LookupAccountSidW(LPCWSTR lpSystemName, PSID Sid, LPWSTR Name, LPD
DEBUG_LOG("LookupAccountSidW(%s, %p, %p, %p, %p, %p, %p)\n", systemName.c_str(), Sid, Name, cchName, DEBUG_LOG("LookupAccountSidW(%s, %p, %p, %p, %p, %p, %p)\n", systemName.c_str(), Sid, Name, cchName,
ReferencedDomainName, cchReferencedDomainName, peUse); ReferencedDomainName, cchReferencedDomainName, peUse);
if (!Sid || !cchName || !cchReferencedDomainName || !peUse) { if (!Sid || !cchName || !cchReferencedDomainName || !peUse) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto *sidStruct = reinterpret_cast<const struct Sid *>(Sid); auto *sidStruct = reinterpret_cast<const struct Sid *>(Sid);
if (!isLocalSystemSid(sidStruct)) { if (!isLocalSystemSid(sidStruct)) {
wibo::lastError = ERROR_NONE_MAPPED; kernel32::setLastError(ERROR_NONE_MAPPED);
return FALSE; return FALSE;
} }
DWORD requiredAccount = static_cast<DWORD>(wstrlen(kAccountSystem)); DWORD requiredAccount = static_cast<DWORD>(wstrlen(kAccountSystem));
@@ -103,7 +104,7 @@ BOOL WIN_FUNC LookupAccountSidW(LPCWSTR lpSystemName, PSID Sid, LPWSTR Name, LPD
if (!Name || *cchName <= requiredAccount || !ReferencedDomainName || *cchReferencedDomainName <= requiredDomain) { if (!Name || *cchName <= requiredAccount || !ReferencedDomainName || *cchReferencedDomainName <= requiredDomain) {
*cchName = requiredAccount + 1; *cchName = requiredAccount + 1;
*cchReferencedDomainName = requiredDomain + 1; *cchReferencedDomainName = requiredDomain + 1;
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
std::copy_n(kAccountSystem, requiredAccount + 1, Name); std::copy_n(kAccountSystem, requiredAccount + 1, Name);
@@ -120,7 +121,7 @@ BOOL WIN_FUNC LookupPrivilegeValueA(LPCSTR lpSystemName, LPCSTR lpName, PLUID lp
lpLuid); lpLuid);
(void)lpSystemName; // only local lookup supported (void)lpSystemName; // only local lookup supported
if (!lpName || !lpLuid) { if (!lpName || !lpLuid) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::string normalized = normalizePrivilegeName(lpName); std::string normalized = normalizePrivilegeName(lpName);
@@ -134,7 +135,7 @@ BOOL WIN_FUNC LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID
DEBUG_LOG("LookupPrivilegeValueW(%p, %p, %p)\n", lpSystemName, lpName, lpLuid); DEBUG_LOG("LookupPrivilegeValueW(%p, %p, %p)\n", lpSystemName, lpName, lpLuid);
(void)lpSystemName; // only local lookup supported (void)lpSystemName; // only local lookup supported
if (!lpName || !lpLuid) { if (!lpName || !lpLuid) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::string ansiName = wideStringToString(lpName); std::string ansiName = wideStringToString(lpName);
@@ -148,14 +149,14 @@ BOOL WIN_FUNC GetUserNameA(LPSTR lpBuffer, LPDWORD pcbBuffer) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetUserNameA(%p, %p)\n", lpBuffer, pcbBuffer); DEBUG_LOG("GetUserNameA(%p, %p)\n", lpBuffer, pcbBuffer);
if (!pcbBuffer) { if (!pcbBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
const char *name = "SYSTEM"; const char *name = "SYSTEM";
size_t needed = std::strlen(name) + 1; size_t needed = std::strlen(name) + 1;
if (!lpBuffer || *pcbBuffer < needed) { if (!lpBuffer || *pcbBuffer < needed) {
*pcbBuffer = static_cast<DWORD>(needed); *pcbBuffer = static_cast<DWORD>(needed);
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
std::memcpy(lpBuffer, name, needed); std::memcpy(lpBuffer, name, needed);
@@ -167,13 +168,13 @@ BOOL WIN_FUNC GetUserNameW(LPWSTR lpBuffer, LPDWORD pcbBuffer) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetUserNameW(%p, %p)\n", lpBuffer, pcbBuffer); DEBUG_LOG("GetUserNameW(%p, %p)\n", lpBuffer, pcbBuffer);
if (!pcbBuffer) { if (!pcbBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
size_t needed = wstrlen(kAccountSystem) + 1; size_t needed = wstrlen(kAccountSystem) + 1;
if (!lpBuffer || *pcbBuffer < needed) { if (!lpBuffer || *pcbBuffer < needed) {
*pcbBuffer = static_cast<DWORD>(needed); *pcbBuffer = static_cast<DWORD>(needed);
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
std::memcpy(lpBuffer, kAccountSystem, needed * sizeof(WCHAR)); std::memcpy(lpBuffer, kAccountSystem, needed * sizeof(WCHAR));

View File

@@ -3,6 +3,7 @@
#include "common.h" #include "common.h"
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "kernel32/internal.h"
#include "md5.h" #include "md5.h"
#define SHA1_IMPLEMENTATION #define SHA1_IMPLEMENTATION
@@ -75,7 +76,7 @@ BOOL WIN_FUNC CryptAcquireContextW(HCRYPTPROV *phProv, LPCWSTR pszContainer, LPC
// to quote the guy above me: screw them for now // to quote the guy above me: screw them for now
static int dummyProvider = 42; static int dummyProvider = 42;
if (!phProv) { if (!phProv) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*phProv = static_cast<HCRYPTPROV>(reinterpret_cast<uintptr_t>(&dummyProvider)); *phProv = static_cast<HCRYPTPROV>(reinterpret_cast<uintptr_t>(&dummyProvider));
@@ -87,13 +88,13 @@ BOOL WIN_FUNC CryptGenRandom(HCRYPTPROV hProv, DWORD dwLen, BYTE *pbBuffer) {
DEBUG_LOG("CryptGenRandom(%p)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hProv))); DEBUG_LOG("CryptGenRandom(%p)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hProv)));
(void)hProv; (void)hProv;
if (!pbBuffer || dwLen == 0) { if (!pbBuffer || dwLen == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
ssize_t ret = getrandom(pbBuffer, dwLen, 0); ssize_t ret = getrandom(pbBuffer, dwLen, 0);
if (ret < 0 || static_cast<DWORD>(ret) != dwLen) { if (ret < 0 || static_cast<DWORD>(ret) != dwLen) {
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
@@ -106,19 +107,19 @@ BOOL WIN_FUNC CryptCreateHash(HCRYPTPROV hProv, ALG_ID Algid, HCRYPTKEY hKey, DW
reinterpret_cast<void *>(static_cast<uintptr_t>(hKey)), dwFlags, phHash); reinterpret_cast<void *>(static_cast<uintptr_t>(hKey)), dwFlags, phHash);
(void)hProv; (void)hProv;
if (!phHash) { if (!phHash) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (dwFlags != 0) { if (dwFlags != 0) {
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
if (hKey != 0) { if (hKey != 0) {
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
if (Algid != CALG_MD5 && Algid != CALG_SHA1) { if (Algid != CALG_MD5 && Algid != CALG_SHA1) {
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
auto *hash = new HashObject; auto *hash = new HashObject;
@@ -137,12 +138,12 @@ BOOL WIN_FUNC CryptHashData(HCRYPTHASH hHash, const BYTE *pbData, DWORD dwDataLe
DEBUG_LOG("CryptHashData(%p, %p, %u, %u)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hHash)), pbData, DEBUG_LOG("CryptHashData(%p, %p, %u, %u)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hHash)), pbData,
dwDataLen, dwFlags); dwDataLen, dwFlags);
if (dwFlags != 0) { if (dwFlags != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto *hash = hashObjectFromHandle(hHash); auto *hash = hashObjectFromHandle(hHash);
if (!hash || (dwDataLen != 0 && !pbData)) { if (!hash || (dwDataLen != 0 && !pbData)) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (pbData && dwDataLen) { if (pbData && dwDataLen) {
@@ -160,12 +161,12 @@ BOOL WIN_FUNC CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, D
DEBUG_LOG("CryptGetHashParam(%p, %u, %p, %p, %u)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hHash)), DEBUG_LOG("CryptGetHashParam(%p, %u, %p, %p, %u)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hHash)),
dwParam, pbData, pdwDataLen, dwFlags); dwParam, pbData, pdwDataLen, dwFlags);
if (dwFlags != 0 || !pdwDataLen) { if (dwFlags != 0 || !pdwDataLen) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto *hash = hashObjectFromHandle(hHash); auto *hash = hashObjectFromHandle(hHash);
if (!hash) { if (!hash) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
switch (dwParam) { switch (dwParam) {
@@ -177,7 +178,7 @@ BOOL WIN_FUNC CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, D
} }
if (*pdwDataLen < required) { if (*pdwDataLen < required) {
*pdwDataLen = required; *pdwDataLen = required;
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
memcpy(pbData, &hash->algid, required); memcpy(pbData, &hash->algid, required);
@@ -192,12 +193,12 @@ BOOL WIN_FUNC CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, D
} }
if (*pdwDataLen < required) { if (*pdwDataLen < required) {
*pdwDataLen = required; *pdwDataLen = required;
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
DWORD size = hashSizeForAlgid(hash->algid); DWORD size = hashSizeForAlgid(hash->algid);
if (size == 0) { if (size == 0) {
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
memcpy(pbData, &size, required); memcpy(pbData, &size, required);
@@ -206,12 +207,12 @@ BOOL WIN_FUNC CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, D
} }
case HP_HASHVAL: { case HP_HASHVAL: {
if (!computeDigest(*hash)) { if (!computeDigest(*hash)) {
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
DWORD size = hashSizeForAlgid(hash->algid); DWORD size = hashSizeForAlgid(hash->algid);
if (size == 0) { if (size == 0) {
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
if (!pbData) { if (!pbData) {
@@ -220,7 +221,7 @@ BOOL WIN_FUNC CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, D
} }
if (*pdwDataLen < size) { if (*pdwDataLen < size) {
*pdwDataLen = size; *pdwDataLen = size;
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
memcpy(pbData, hash->digest, size); memcpy(pbData, hash->digest, size);
@@ -228,7 +229,7 @@ BOOL WIN_FUNC CryptGetHashParam(HCRYPTHASH hHash, DWORD dwParam, BYTE *pbData, D
return TRUE; return TRUE;
} }
default: default:
wibo::lastError = ERROR_NOT_SUPPORTED; kernel32::setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
} }
@@ -238,7 +239,7 @@ BOOL WIN_FUNC CryptDestroyHash(HCRYPTHASH hHash) {
DEBUG_LOG("CryptDestroyHash(%p)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hHash))); DEBUG_LOG("CryptDestroyHash(%p)\n", reinterpret_cast<void *>(static_cast<uintptr_t>(hHash)));
auto *hash = hashObjectFromHandle(hHash); auto *hash = hashObjectFromHandle(hHash);
if (!hash) { if (!hash) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
delete hash; delete hash;

View File

@@ -4,6 +4,7 @@
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "handles.h" #include "handles.h"
#include "kernel32/internal.h"
#include "strutil.h" #include "strutil.h"
#include <algorithm> #include <algorithm>
@@ -135,17 +136,17 @@ LSTATUS WIN_FUNC RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LP
(void)lpClass; (void)lpClass;
(void)lpSecurityAttributes; (void)lpSecurityAttributes;
if (!phkResult) { if (!phkResult) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
*phkResult = nullptr; *phkResult = nullptr;
if (Reserved != 0) { if (Reserved != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
if (dwOptions != 0) { if (dwOptions != 0) {
DEBUG_LOG("RegCreateKeyExW: unsupported options 0x%x\n", dwOptions); DEBUG_LOG("RegCreateKeyExW: unsupported options 0x%x\n", dwOptions);
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
REGSAM sanitizedAccess = samDesired & ~(KEY_WOW64_64KEY | KEY_WOW64_32KEY); REGSAM sanitizedAccess = samDesired & ~(KEY_WOW64_64KEY | KEY_WOW64_32KEY);
@@ -155,7 +156,7 @@ LSTATUS WIN_FUNC RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LP
std::lock_guard<std::mutex> lock(g_registryMutex); std::lock_guard<std::mutex> lock(g_registryMutex);
Pin<RegistryKeyObject> baseHandle = handleDataFromHKeyLocked(hKey); Pin<RegistryKeyObject> baseHandle = handleDataFromHKeyLocked(hKey);
if (!baseHandle) { if (!baseHandle) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
} }
std::u16string targetPath = baseHandle->canonicalPath; std::u16string targetPath = baseHandle->canonicalPath;
@@ -171,7 +172,7 @@ LSTATUS WIN_FUNC RegCreateKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD Reserved, LP
} }
} }
if (targetPath.empty()) { if (targetPath.empty()) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
} }
bool existed = g_existingKeys.find(targetPath) != g_existingKeys.end(); bool existed = g_existingKeys.find(targetPath) != g_existingKeys.end();
@@ -216,12 +217,12 @@ LSTATUS WIN_FUNC RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REG
std::string subKeyString = lpSubKey ? wideStringToString(lpSubKey) : std::string("(null)"); std::string subKeyString = lpSubKey ? wideStringToString(lpSubKey) : std::string("(null)");
DEBUG_LOG("RegOpenKeyExW(%p, %s, %u, 0x%x, %p)\n", hKey, subKeyString.c_str(), ulOptions, samDesired, phkResult); DEBUG_LOG("RegOpenKeyExW(%p, %s, %u, 0x%x, %p)\n", hKey, subKeyString.c_str(), ulOptions, samDesired, phkResult);
if (!phkResult) { if (!phkResult) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
*phkResult = nullptr; *phkResult = nullptr;
if ((ulOptions & ~REG_OPTION_OPEN_LINK) != 0) { if ((ulOptions & ~REG_OPTION_OPEN_LINK) != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
if (ulOptions & REG_OPTION_OPEN_LINK) { if (ulOptions & REG_OPTION_OPEN_LINK) {
@@ -235,7 +236,7 @@ LSTATUS WIN_FUNC RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REG
std::lock_guard<std::mutex> lock(g_registryMutex); std::lock_guard<std::mutex> lock(g_registryMutex);
Pin<RegistryKeyObject> baseHandle = handleDataFromHKeyLocked(hKey); Pin<RegistryKeyObject> baseHandle = handleDataFromHKeyLocked(hKey);
if (!baseHandle) { if (!baseHandle) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
} }
std::u16string targetPath = baseHandle->canonicalPath; std::u16string targetPath = baseHandle->canonicalPath;
@@ -249,11 +250,11 @@ LSTATUS WIN_FUNC RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REG
} }
} }
if (targetPath.empty()) { if (targetPath.empty()) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
} }
if (g_existingKeys.find(targetPath) == g_existingKeys.end()) { if (g_existingKeys.find(targetPath) == g_existingKeys.end()) {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
} }
if (!lpSubKey || lpSubKey[0] == 0) { if (!lpSubKey || lpSubKey[0] == 0) {
@@ -288,7 +289,7 @@ LSTATUS WIN_FUNC RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpRese
DEBUG_LOG("RegQueryValueExW(%p, %s, %p, %p, %p, %p)\n", hKey, valueName.c_str(), lpReserved, lpType, lpData, DEBUG_LOG("RegQueryValueExW(%p, %s, %p, %p, %p, %p)\n", hKey, valueName.c_str(), lpReserved, lpType, lpData,
lpcbData); lpcbData);
if (lpReserved) { if (lpReserved) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
if (lpcbData) { if (lpcbData) {
@@ -299,7 +300,7 @@ LSTATUS WIN_FUNC RegQueryValueExW(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpRese
} }
(void)hKey; (void)hKey;
(void)lpData; (void)lpData;
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return ERROR_FILE_NOT_FOUND; return ERROR_FILE_NOT_FOUND;
} }
@@ -324,7 +325,7 @@ LSTATUS WIN_FUNC RegEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD
(void)hKey; (void)hKey;
(void)dwIndex; (void)dwIndex;
if (lpReserved) { if (lpReserved) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
if (lpcchName) { if (lpcchName) {
@@ -340,7 +341,7 @@ LSTATUS WIN_FUNC RegEnumKeyExW(HKEY hKey, DWORD dwIndex, LPWSTR lpName, LPDWORD
*lpcchClass = 0; *lpcchClass = 0;
} }
(void)lpftLastWriteTime; (void)lpftLastWriteTime;
wibo::lastError = ERROR_NO_MORE_ITEMS; kernel32::setLastError(ERROR_NO_MORE_ITEMS);
return ERROR_NO_MORE_ITEMS; return ERROR_NO_MORE_ITEMS;
} }
@@ -352,7 +353,7 @@ LSTATUS WIN_FUNC RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD l
(void)hKey; (void)hKey;
(void)dwIndex; (void)dwIndex;
if (lpReserved) { if (lpReserved) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return ERROR_INVALID_PARAMETER; return ERROR_INVALID_PARAMETER;
} }
if (lpcchName) { if (lpcchName) {
@@ -368,7 +369,7 @@ LSTATUS WIN_FUNC RegEnumKeyExA(HKEY hKey, DWORD dwIndex, LPSTR lpName, LPDWORD l
*lpcchClass = 0; *lpcchClass = 0;
} }
(void)lpftLastWriteTime; (void)lpftLastWriteTime;
wibo::lastError = ERROR_NO_MORE_ITEMS; kernel32::setLastError(ERROR_NO_MORE_ITEMS);
return ERROR_NO_MORE_ITEMS; return ERROR_NO_MORE_ITEMS;
} }
@@ -380,7 +381,7 @@ LSTATUS WIN_FUNC RegCloseKey(HKEY hKey) {
} }
auto obj = wibo::handles().getAs<RegistryKeyObject>(hKey); auto obj = wibo::handles().getAs<RegistryKeyObject>(hKey);
if (!obj || obj->closed) { if (!obj || obj->closed) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;

View File

@@ -14,18 +14,34 @@ UINT g_processErrorMode = 0;
namespace kernel32 { namespace kernel32 {
void setLastErrorFromErrno() { wibo::lastError = wibo::winErrorFromErrno(errno); } DWORD getLastError() { return wibo::getThreadTibForHost()->lastErrorValue; }
void setLastError(DWORD error) { wibo::getThreadTibForHost()->lastErrorValue = error; }
void setLastErrorFromErrno() { setLastError(wibo::winErrorFromErrno(errno)); }
DWORD WIN_FUNC GetLastError() { DWORD WIN_FUNC GetLastError() {
HOST_CONTEXT_GUARD(); #ifndef NDEBUG
VERBOSE_LOG("GetLastError() -> %u\n", wibo::lastError); {
return wibo::lastError; HOST_CONTEXT_GUARD();
DEBUG_LOG("GetLastError() -> %u\n", getLastError());
}
#endif
// In guest context, fetch via TIB
DWORD err;
__asm__ __volatile__("movl %%fs:%c1, %0" : "=r"(err) : "i"(offsetof(TIB, lastErrorValue)));
return err;
} }
void WIN_FUNC SetLastError(DWORD dwErrCode) { void WIN_FUNC SetLastError(DWORD dwErrCode) {
HOST_CONTEXT_GUARD(); #ifndef NDEBUG
VERBOSE_LOG("SetLastError(%u)\n", dwErrCode); {
wibo::lastError = dwErrCode; HOST_CONTEXT_GUARD();
DEBUG_LOG("SetLastError(%u)\n", dwErrCode);
}
#endif
// In guest context, store via TIB
__asm__ __volatile__("movl %0, %%fs:%c1" : : "r"(dwErrCode), "i"(offsetof(TIB, lastErrorValue)) : "memory");
} }
void WIN_FUNC RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments, void WIN_FUNC RaiseException(DWORD dwExceptionCode, DWORD dwExceptionFlags, DWORD nNumberOfArguments,

View File

@@ -3,6 +3,7 @@
#include "common.h" #include "common.h"
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "internal.h"
namespace { namespace {
@@ -27,7 +28,7 @@ DWORD WIN_FUNC FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback) {
} }
} }
DEBUG_LOG(" -> -1\n"); DEBUG_LOG(" -> -1\n");
wibo::lastError = FLS_OUT_OF_INDEXES; setLastError(FLS_OUT_OF_INDEXES);
return FLS_OUT_OF_INDEXES; return FLS_OUT_OF_INDEXES;
} }
@@ -38,7 +39,7 @@ BOOL WIN_FUNC FlsFree(DWORD dwFlsIndex) {
g_flsValuesUsed[dwFlsIndex] = false; g_flsValuesUsed[dwFlsIndex] = false;
return TRUE; return TRUE;
} else { } else {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
} }
@@ -50,9 +51,9 @@ PVOID WIN_FUNC FlsGetValue(DWORD dwFlsIndex) {
if (dwFlsIndex < kMaxFlsValues && g_flsValuesUsed[dwFlsIndex]) { if (dwFlsIndex < kMaxFlsValues && g_flsValuesUsed[dwFlsIndex]) {
result = g_flsValues[dwFlsIndex]; result = g_flsValues[dwFlsIndex];
// See https://learn.microsoft.com/en-us/windows/win32/api/fibersapi/nf-fibersapi-flsgetvalue // See https://learn.microsoft.com/en-us/windows/win32/api/fibersapi/nf-fibersapi-flsgetvalue
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
} else { } else {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
} }
// DEBUG_LOG(" -> %p\n", result); // DEBUG_LOG(" -> %p\n", result);
return result; return result;
@@ -65,7 +66,7 @@ BOOL WIN_FUNC FlsSetValue(DWORD dwFlsIndex, PVOID lpFlsData) {
g_flsValues[dwFlsIndex] = lpFlsData; g_flsValues[dwFlsIndex] = lpFlsData;
return TRUE; return TRUE;
} else { } else {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
} }

View File

@@ -109,7 +109,7 @@ bool computeFullPath(const std::string &input, FullPathInfo &outInfo) {
std::error_code ec; std::error_code ec;
std::filesystem::path absPath = std::filesystem::absolute(hostPath, ec); std::filesystem::path absPath = std::filesystem::absolute(hostPath, ec);
if (ec) { if (ec) {
wibo::lastError = wibo::winErrorFromErrno(ec.value()); kernel32::setLastError(wibo::winErrorFromErrno(ec.value()));
return false; return false;
} }
@@ -385,7 +385,7 @@ bool collectDirectoryMatches(const std::filesystem::path &directory, const std::
outEntries.push_back(std::move(entry)); outEntries.push_back(std::move(entry));
} }
if (iterEc) { if (iterEc) {
wibo::lastError = wibo::winErrorFromErrno(iterEc.value()); kernel32::setLastError(wibo::winErrorFromErrno(iterEc.value()));
return false; return false;
} }
return true; return true;
@@ -393,12 +393,12 @@ bool collectDirectoryMatches(const std::filesystem::path &directory, const std::
template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawInput, FindData *lpFindFileData) { template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawInput, FindData *lpFindFileData) {
if (!lpFindFileData) { if (!lpFindFileData) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (rawInput.empty()) { if (rawInput.empty()) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -406,12 +406,12 @@ template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawIn
std::replace(input.begin(), input.end(), '/', '\\'); std::replace(input.begin(), input.end(), '/', '\\');
if (input.empty()) { if (input.empty()) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (!input.empty() && input.back() == '\\') { if (!input.empty() && input.back() == '\\') {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -432,12 +432,12 @@ template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawIn
} }
if (filePart.empty()) { if (filePart.empty()) {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (containsWildcardOutsideExtendedPrefix(directoryPart)) { if (containsWildcardOutsideExtendedPrefix(directoryPart)) {
wibo::lastError = ERROR_INVALID_NAME; kernel32::setLastError(ERROR_INVALID_NAME);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -450,15 +450,15 @@ template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawIn
std::error_code dirStatusEc; std::error_code dirStatusEc;
auto dirStatus = std::filesystem::status(hostDirectory, dirStatusEc); auto dirStatus = std::filesystem::status(hostDirectory, dirStatusEc);
if (dirStatusEc) { if (dirStatusEc) {
wibo::lastError = wibo::winErrorFromErrno(dirStatusEc.value()); kernel32::setLastError(wibo::winErrorFromErrno(dirStatusEc.value()));
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (dirStatus.type() == std::filesystem::file_type::not_found) { if (dirStatus.type() == std::filesystem::file_type::not_found) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (dirStatus.type() != std::filesystem::file_type::directory) { if (dirStatus.type() != std::filesystem::file_type::directory) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -470,11 +470,11 @@ template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawIn
std::error_code targetEc; std::error_code targetEc;
auto targetStatus = std::filesystem::status(targetPath, targetEc); auto targetStatus = std::filesystem::status(targetPath, targetEc);
if (targetEc) { if (targetEc) {
wibo::lastError = wibo::winErrorFromErrno(targetEc.value()); kernel32::setLastError(wibo::winErrorFromErrno(targetEc.value()));
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (targetStatus.type() == std::filesystem::file_type::not_found) { if (targetStatus.type() == std::filesystem::file_type::not_found) {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -484,7 +484,7 @@ template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawIn
entry.name = determineDisplayName(targetPath, filePart); entry.name = determineDisplayName(targetPath, filePart);
populateFindData(entry, *lpFindFileData); populateFindData(entry, *lpFindFileData);
wibo::lastError = ERROR_SUCCESS; kernel32::setLastError(ERROR_SUCCESS);
auto state = std::make_unique<FindSearchHandle>(); auto state = std::make_unique<FindSearchHandle>();
state->singleResult = true; state->singleResult = true;
@@ -496,12 +496,12 @@ template <typename FindData> HANDLE findFirstFileCommon(const std::string &rawIn
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (matches.empty()) { if (matches.empty()) {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
populateFindData(matches[0], *lpFindFileData); populateFindData(matches[0], *lpFindFileData);
wibo::lastError = ERROR_SUCCESS; kernel32::setLastError(ERROR_SUCCESS);
auto state = std::make_unique<FindSearchHandle>(); auto state = std::make_unique<FindSearchHandle>();
state->entries = std::move(matches); state->entries = std::move(matches);
@@ -540,7 +540,7 @@ bool tryOpenConsoleDevice(DWORD dwDesiredAccess, DWORD dwShareMode, DWORD dwCrea
} }
HANDLE baseHandle = files::getStdHandle(*stdHandleKind); HANDLE baseHandle = files::getStdHandle(*stdHandleKind);
if (!wibo::handles().duplicateTo(baseHandle, wibo::handles(), outHandle, dwDesiredAccess, false, 0)) { if (!wibo::handles().duplicateTo(baseHandle, wibo::handles(), outHandle, dwDesiredAccess, false, 0)) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
outHandle = INVALID_HANDLE_VALUE; outHandle = INVALID_HANDLE_VALUE;
return true; return true;
} }
@@ -554,7 +554,7 @@ namespace kernel32 {
DWORD WIN_FUNC GetFileAttributesA(LPCSTR lpFileName) { DWORD WIN_FUNC GetFileAttributesA(LPCSTR lpFileName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_FILE_ATTRIBUTES; return INVALID_FILE_ATTRIBUTES;
} }
std::filesystem::path path = files::pathFromWindows(lpFileName); std::filesystem::path path = files::pathFromWindows(lpFileName);
@@ -569,7 +569,7 @@ DWORD WIN_FUNC GetFileAttributesA(LPCSTR lpFileName) {
std::error_code ec; std::error_code ec;
auto status = std::filesystem::status(path, ec); auto status = std::filesystem::status(path, ec);
if (ec) { if (ec) {
wibo::lastError = wibo::winErrorFromErrno(ec.value()); setLastError(wibo::winErrorFromErrno(ec.value()));
return INVALID_FILE_ATTRIBUTES; return INVALID_FILE_ATTRIBUTES;
} }
@@ -582,7 +582,7 @@ DWORD WIN_FUNC GetFileAttributesA(LPCSTR lpFileName) {
case std::filesystem::file_type::not_found: case std::filesystem::file_type::not_found:
default: default:
DEBUG_LOG("File does not exist\n"); DEBUG_LOG("File does not exist\n");
wibo::lastError = ERROR_FILE_NOT_FOUND; setLastError(ERROR_FILE_NOT_FOUND);
return INVALID_FILE_ATTRIBUTES; return INVALID_FILE_ATTRIBUTES;
} }
} }
@@ -591,7 +591,7 @@ DWORD WIN_FUNC GetFileAttributesW(LPCWSTR lpFileName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetFileAttributesW -> "); DEBUG_LOG("GetFileAttributesW -> ");
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_FILE_ATTRIBUTES; return INVALID_FILE_ATTRIBUTES;
} }
std::string str = wideStringToString(lpFileName); std::string str = wideStringToString(lpFileName);
@@ -702,19 +702,19 @@ BOOL WIN_FUNC WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
#ifdef CHECK_ACCESS #ifdef CHECK_ACCESS
if ((meta.grantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) == 0) { if ((meta.grantedAccess & (FILE_WRITE_DATA | FILE_APPEND_DATA)) == 0) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("!!! DENIED: 0x%x\n", meta.grantedAccess); DEBUG_LOG("!!! DENIED: 0x%x\n", meta.grantedAccess);
return FALSE; return FALSE;
} }
#endif #endif
if (lpOverlapped == nullptr && lpNumberOfBytesWritten == nullptr) { if (lpOverlapped == nullptr && lpNumberOfBytesWritten == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -723,7 +723,7 @@ BOOL WIN_FUNC WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
} }
if (file->overlapped && lpOverlapped == nullptr) { if (file->overlapped && lpOverlapped == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -749,7 +749,7 @@ BOOL WIN_FUNC WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
if (lpNumberOfBytesWritten) { if (lpNumberOfBytesWritten) {
*lpNumberOfBytesWritten = 0; *lpNumberOfBytesWritten = 0;
} }
wibo::lastError = ERROR_IO_PENDING; setLastError(ERROR_IO_PENDING);
return FALSE; return FALSE;
} }
} }
@@ -759,7 +759,7 @@ BOOL WIN_FUNC WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWr
NTSTATUS completionStatus = STATUS_SUCCESS; NTSTATUS completionStatus = STATUS_SUCCESS;
if (io.unixError != 0) { if (io.unixError != 0) {
completionStatus = wibo::statusFromErrno(io.unixError); completionStatus = wibo::statusFromErrno(io.unixError);
wibo::lastError = wibo::winErrorFromErrno(io.unixError); setLastError(wibo::winErrorFromErrno(io.unixError));
} else if (io.reachedEnd && io.bytesTransferred == 0) { } else if (io.reachedEnd && io.bytesTransferred == 0) {
completionStatus = STATUS_END_OF_FILE; completionStatus = STATUS_END_OF_FILE;
} }
@@ -778,7 +778,7 @@ BOOL WIN_FUNC FlushFileBuffers(HANDLE hFile) {
DEBUG_LOG("FlushFileBuffers(%p)\n", hFile); DEBUG_LOG("FlushFileBuffers(%p)\n", hFile);
auto file = wibo::handles().getAs<FileObject>(hFile); auto file = wibo::handles().getAs<FileObject>(hFile);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (fsync(file->fd) != 0) { if (fsync(file->fd) != 0) {
@@ -797,19 +797,19 @@ BOOL WIN_FUNC ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
#ifdef CHECK_ACCESS #ifdef CHECK_ACCESS
if ((meta.grantedAccess & FILE_READ_DATA) == 0) { if ((meta.grantedAccess & FILE_READ_DATA) == 0) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("!!! DENIED: 0x%x\n", meta.grantedAccess); DEBUG_LOG("!!! DENIED: 0x%x\n", meta.grantedAccess);
return FALSE; return FALSE;
} }
#endif #endif
if (lpOverlapped == nullptr && lpNumberOfBytesRead == nullptr) { if (lpOverlapped == nullptr && lpNumberOfBytesRead == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -818,7 +818,7 @@ BOOL WIN_FUNC ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead
} }
if (file->overlapped && lpOverlapped == nullptr) { if (file->overlapped && lpOverlapped == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -844,7 +844,7 @@ BOOL WIN_FUNC ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead
if (lpNumberOfBytesRead) { if (lpNumberOfBytesRead) {
*lpNumberOfBytesRead = 0; *lpNumberOfBytesRead = 0;
} }
wibo::lastError = ERROR_IO_PENDING; setLastError(ERROR_IO_PENDING);
return FALSE; return FALSE;
} }
} }
@@ -854,11 +854,11 @@ BOOL WIN_FUNC ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead
NTSTATUS completionStatus = STATUS_SUCCESS; NTSTATUS completionStatus = STATUS_SUCCESS;
if (io.unixError != 0) { if (io.unixError != 0) {
completionStatus = wibo::statusFromErrno(io.unixError); completionStatus = wibo::statusFromErrno(io.unixError);
wibo::lastError = wibo::winErrorFromErrno(io.unixError); setLastError(wibo::winErrorFromErrno(io.unixError));
} else if (io.reachedEnd && io.bytesTransferred == 0) { } else if (io.reachedEnd && io.bytesTransferred == 0) {
if (file->isPipe) { if (file->isPipe) {
completionStatus = STATUS_PIPE_BROKEN; completionStatus = STATUS_PIPE_BROKEN;
wibo::lastError = ERROR_BROKEN_PIPE; setLastError(ERROR_BROKEN_PIPE);
detail::signalOverlappedEvent(file.get(), lpOverlapped, completionStatus, 0); detail::signalOverlappedEvent(file.get(), lpOverlapped, completionStatus, 0);
DEBUG_LOG("-> ERROR_BROKEN_PIPE\n"); DEBUG_LOG("-> ERROR_BROKEN_PIPE\n");
return FALSE; return FALSE;
@@ -872,7 +872,7 @@ BOOL WIN_FUNC ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead
detail::signalOverlappedEvent(file.get(), lpOverlapped, completionStatus, io.bytesTransferred); detail::signalOverlappedEvent(file.get(), lpOverlapped, completionStatus, io.bytesTransferred);
DEBUG_LOG("-> %u bytes read, error %d\n", io.bytesTransferred, io.unixError == 0 ? 0 : wibo::lastError); DEBUG_LOG("-> %u bytes read, error %d\n", io.bytesTransferred, io.unixError == 0 ? 0 : getLastError());
return io.unixError == 0; return io.unixError == 0;
} }
@@ -882,7 +882,7 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
(void)hTemplateFile; (void)hTemplateFile;
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -897,7 +897,7 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
HANDLE pipeHandle = INVALID_HANDLE_VALUE; HANDLE pipeHandle = INVALID_HANDLE_VALUE;
if (kernel32::tryCreateFileNamedPipeA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, if (kernel32::tryCreateFileNamedPipeA(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes,
dwCreationDisposition, dwFlagsAndAttributes, pipeHandle)) { dwCreationDisposition, dwFlagsAndAttributes, pipeHandle)) {
DEBUG_LOG("CreateFileA(pipe=%s) -> %p (err=%u)\n", lpFileName, pipeHandle, wibo::lastError); DEBUG_LOG("CreateFileA(pipe=%s) -> %p (err=%u)\n", lpFileName, pipeHandle, getLastError());
return pipeHandle; return pipeHandle;
} }
@@ -920,12 +920,12 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
bool isDirectory = pathExists && status.type() == std::filesystem::file_type::directory; bool isDirectory = pathExists && status.type() == std::filesystem::file_type::directory;
if ((fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && !isDirectory) { if ((fileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0 && !isDirectory) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG("-> ERROR_INVALID_PARAMETER (ENOTDIR)\n"); DEBUG_LOG("-> ERROR_INVALID_PARAMETER (ENOTDIR)\n");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (isDirectory && (!backupSemantics || deleteOnClose /* not currently implemented for dir */)) { if (isDirectory && (!backupSemantics || deleteOnClose /* not currently implemented for dir */)) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)\n"); DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)\n");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -940,7 +940,7 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
case CREATE_NEW: case CREATE_NEW:
allowCreate = true; allowCreate = true;
if (pathExists) { if (pathExists) {
wibo::lastError = ERROR_FILE_EXISTS; setLastError(ERROR_FILE_EXISTS);
DEBUG_LOG("-> ERROR_FILE_EXISTS (EEXIST)"); DEBUG_LOG("-> ERROR_FILE_EXISTS (EEXIST)");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -948,7 +948,7 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
case CREATE_ALWAYS: case CREATE_ALWAYS:
allowCreate = true; allowCreate = true;
if (isDirectory) { if (isDirectory) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)"); DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -958,26 +958,26 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
if (!pathExists) { if (!pathExists) {
allowCreate = true; allowCreate = true;
} else if (isDirectory) { } else if (isDirectory) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)"); DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
break; break;
case OPEN_EXISTING: case OPEN_EXISTING:
if (!pathExists) { if (!pathExists) {
wibo::lastError = ERROR_FILE_NOT_FOUND; setLastError(ERROR_FILE_NOT_FOUND);
DEBUG_LOG("-> ERROR_FILE_NOT_FOUND (ENOENT)"); DEBUG_LOG("-> ERROR_FILE_NOT_FOUND (ENOENT)");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
break; break;
case TRUNCATE_EXISTING: case TRUNCATE_EXISTING:
if (!pathExists) { if (!pathExists) {
wibo::lastError = ERROR_FILE_NOT_FOUND; setLastError(ERROR_FILE_NOT_FOUND);
DEBUG_LOG("-> ERROR_FILE_NOT_FOUND (ENOENT)"); DEBUG_LOG("-> ERROR_FILE_NOT_FOUND (ENOENT)");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (isDirectory) { if (isDirectory) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)"); DEBUG_LOG("-> ERROR_ACCESS_DENIED (EISDIR)");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -995,7 +995,7 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
auto normalized = auto normalized =
wibo::access::normalizeDesiredAccess(dwDesiredAccess, genericMapping, supportedMask, SYNCHRONIZE, defaultMask); wibo::access::normalizeDesiredAccess(dwDesiredAccess, genericMapping, supportedMask, SYNCHRONIZE, defaultMask);
if (normalized.deniedMask != 0) { if (normalized.deniedMask != 0) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED: denied mask 0x%x\n", normalized.deniedMask); DEBUG_LOG("-> ERROR_ACCESS_DENIED: denied mask 0x%x\n", normalized.deniedMask);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -1007,17 +1007,17 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
bool appendOnly = appendRequested && !containsAny(normalized.grantedMask, FILE_WRITE_DATA); bool appendOnly = appendRequested && !containsAny(normalized.grantedMask, FILE_WRITE_DATA);
#ifdef CHECK_ACCESS #ifdef CHECK_ACCESS
if (allowCreate && !containsAny(normalized.grantedMask, FILE_WRITE_DATA | FILE_APPEND_DATA)) { if (allowCreate && !containsAny(normalized.grantedMask, FILE_WRITE_DATA | FILE_APPEND_DATA)) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED: FILE_WRITE_DATA | FILE_APPEND_DATA required for creation"); DEBUG_LOG("-> ERROR_ACCESS_DENIED: FILE_WRITE_DATA | FILE_APPEND_DATA required for creation");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (truncateExisting && !containsAny(normalized.grantedMask, FILE_WRITE_DATA)) { if (truncateExisting && !containsAny(normalized.grantedMask, FILE_WRITE_DATA)) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED: FILE_WRITE_DATA required for truncation"); DEBUG_LOG("-> ERROR_ACCESS_DENIED: FILE_WRITE_DATA required for truncation");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (deleteOnClose && !containsAny(normalized.grantedMask, DELETE)) { if (deleteOnClose && !containsAny(normalized.grantedMask, DELETE)) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("-> ERROR_ACCESS_DENIED: DELETE required for delete-on-close"); DEBUG_LOG("-> ERROR_ACCESS_DENIED: DELETE required for delete-on-close");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -1096,7 +1096,7 @@ HANDLE WIN_FUNC CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwSh
if ((dwCreationDisposition == OPEN_ALWAYS && existedBefore) || if ((dwCreationDisposition == OPEN_ALWAYS && existedBefore) ||
(dwCreationDisposition == CREATE_ALWAYS && existedBefore)) { (dwCreationDisposition == CREATE_ALWAYS && existedBefore)) {
wibo::lastError = ERROR_ALREADY_EXISTS; setLastError(ERROR_ALREADY_EXISTS);
} }
DEBUG_LOG("-> %p (createdNew=%d, truncate=%d)\n", handle, createdNew ? 1 : 0, truncateExisting ? 1 : 0); DEBUG_LOG("-> %p (createdNew=%d, truncate=%d)\n", handle, createdNew ? 1 : 0, truncateExisting ? 1 : 0);
@@ -1109,7 +1109,7 @@ HANDLE WIN_FUNC CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("CreateFileW -> "); DEBUG_LOG("CreateFileW -> ");
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
std::string lpFileNameA = wideStringToString(lpFileName); std::string lpFileNameA = wideStringToString(lpFileName);
@@ -1120,7 +1120,7 @@ HANDLE WIN_FUNC CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
BOOL WIN_FUNC DeleteFileA(LPCSTR lpFileName) { BOOL WIN_FUNC DeleteFileA(LPCSTR lpFileName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG("DeleteFileA(NULL) -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG("DeleteFileA(NULL) -> ERROR_INVALID_PARAMETER\n");
return FALSE; return FALSE;
} }
@@ -1137,7 +1137,7 @@ BOOL WIN_FUNC DeleteFileW(LPCWSTR lpFileName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("DeleteFileW -> "); DEBUG_LOG("DeleteFileW -> ");
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::string name = wideStringToString(lpFileName); std::string name = wideStringToString(lpFileName);
@@ -1149,23 +1149,23 @@ BOOL WIN_FUNC MoveFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName) {
DEBUG_LOG("MoveFileA(%s, %s)\n", lpExistingFileName ? lpExistingFileName : "(null)", DEBUG_LOG("MoveFileA(%s, %s)\n", lpExistingFileName ? lpExistingFileName : "(null)",
lpNewFileName ? lpNewFileName : "(null)"); lpNewFileName ? lpNewFileName : "(null)");
if (!lpExistingFileName || !lpNewFileName) { if (!lpExistingFileName || !lpNewFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto fromPath = files::pathFromWindows(lpExistingFileName); auto fromPath = files::pathFromWindows(lpExistingFileName);
auto toPath = files::pathFromWindows(lpNewFileName); auto toPath = files::pathFromWindows(lpNewFileName);
std::error_code ec; std::error_code ec;
if (std::filesystem::exists(toPath, ec)) { if (std::filesystem::exists(toPath, ec)) {
wibo::lastError = ERROR_ALREADY_EXISTS; setLastError(ERROR_ALREADY_EXISTS);
return FALSE; return FALSE;
} }
if (ec) { if (ec) {
wibo::lastError = wibo::winErrorFromErrno(ec.value()); setLastError(wibo::winErrorFromErrno(ec.value()));
return FALSE; return FALSE;
} }
std::filesystem::rename(fromPath, toPath, ec); std::filesystem::rename(fromPath, toPath, ec);
if (ec) { if (ec) {
wibo::lastError = wibo::winErrorFromErrno(ec.value()); setLastError(wibo::winErrorFromErrno(ec.value()));
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@@ -1175,7 +1175,7 @@ BOOL WIN_FUNC MoveFileW(LPCWSTR lpExistingFileName, LPCWSTR lpNewFileName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("MoveFileW -> "); DEBUG_LOG("MoveFileW -> ");
if (!lpExistingFileName || !lpNewFileName) { if (!lpExistingFileName || !lpNewFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::string from = wideStringToString(lpExistingFileName); std::string from = wideStringToString(lpExistingFileName);
@@ -1188,13 +1188,13 @@ DWORD WIN_FUNC SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistan
DEBUG_LOG("SetFilePointer(%p, %ld, %p, %u)\n", hFile, static_cast<long>(lDistanceToMove), lpDistanceToMoveHigh, DEBUG_LOG("SetFilePointer(%p, %ld, %p, %u)\n", hFile, static_cast<long>(lDistanceToMove), lpDistanceToMoveHigh,
dwMoveMethod); dwMoveMethod);
if (hFile == nullptr) { if (hFile == nullptr) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return INVALID_SET_FILE_POINTER; return INVALID_SET_FILE_POINTER;
} }
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file) { if (!file) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return INVALID_SET_FILE_POINTER; return INVALID_SET_FILE_POINTER;
} }
// TODO access check // TODO access check
@@ -1210,9 +1210,9 @@ DWORD WIN_FUNC SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistan
} }
if (position < 0) { if (position < 0) {
if (errno == EINVAL) { if (errno == EINVAL) {
wibo::lastError = ERROR_NEGATIVE_SEEK; setLastError(ERROR_NEGATIVE_SEEK);
} else { } else {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
} }
return INVALID_SET_FILE_POINTER; return INVALID_SET_FILE_POINTER;
} }
@@ -1227,13 +1227,13 @@ BOOL WIN_FUNC SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLA
DWORD dwMoveMethod) { DWORD dwMoveMethod) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
if (hFile == nullptr) { if (hFile == nullptr) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file) { if (!file) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
// TODO access check // TODO access check
@@ -1249,18 +1249,18 @@ BOOL WIN_FUNC SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, PLA
} }
if (position < 0) { if (position < 0) {
if (errno == EINVAL) { if (errno == EINVAL) {
wibo::lastError = ERROR_NEGATIVE_SEEK; setLastError(ERROR_NEGATIVE_SEEK);
} else { } else {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
} }
return INVALID_SET_FILE_POINTER; return INVALID_SET_FILE_POINTER;
} }
file->filePos = position; file->filePos = position;
if (position < 0) { if (position < 0) {
if (errno == EINVAL) { if (errno == EINVAL) {
wibo::lastError = ERROR_NEGATIVE_SEEK; setLastError(ERROR_NEGATIVE_SEEK);
} else { } else {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
} }
return FALSE; return FALSE;
} }
@@ -1276,7 +1276,7 @@ BOOL WIN_FUNC SetEndOfFile(HANDLE hFile) {
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file) { if (!file) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
// TODO access check // TODO access check
@@ -1296,7 +1296,7 @@ BOOL WIN_FUNC CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecuri
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
(void)lpSecurityAttributes; (void)lpSecurityAttributes;
if (!lpPathName) { if (!lpPathName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::string path = files::pathFromWindows(lpPathName); std::string path = files::pathFromWindows(lpPathName);
@@ -1311,7 +1311,7 @@ BOOL WIN_FUNC CreateDirectoryA(LPCSTR lpPathName, LPSECURITY_ATTRIBUTES lpSecuri
BOOL WIN_FUNC RemoveDirectoryA(LPCSTR lpPathName) { BOOL WIN_FUNC RemoveDirectoryA(LPCSTR lpPathName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
if (!lpPathName) { if (!lpPathName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::string path = files::pathFromWindows(lpPathName); std::string path = files::pathFromWindows(lpPathName);
@@ -1327,7 +1327,7 @@ BOOL WIN_FUNC SetFileAttributesA(LPCSTR lpFileName, DWORD dwFileAttributes) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
(void)dwFileAttributes; (void)dwFileAttributes;
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
DEBUG_LOG("STUB: SetFileAttributesA(%s, %u)\n", lpFileName, dwFileAttributes); DEBUG_LOG("STUB: SetFileAttributesA(%s, %u)\n", lpFileName, dwFileAttributes);
@@ -1340,7 +1340,7 @@ DWORD WIN_FUNC GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh) {
// TODO access check // TODO access check
auto file = wibo::handles().getAs<FileObject>(hFile); auto file = wibo::handles().getAs<FileObject>(hFile);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
DEBUG_LOG("-> INVALID_FILE_SIZE (ERROR_INVALID_HANDLE)\n"); DEBUG_LOG("-> INVALID_FILE_SIZE (ERROR_INVALID_HANDLE)\n");
return INVALID_FILE_SIZE; return INVALID_FILE_SIZE;
} }
@@ -1367,12 +1367,12 @@ BOOL WIN_FUNC GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lp
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
#ifdef CHECK_ACCESS #ifdef CHECK_ACCESS
if ((meta.grantedAccess & FILE_READ_ATTRIBUTES) == 0) { if ((meta.grantedAccess & FILE_READ_ATTRIBUTES) == 0) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
return FALSE; return FALSE;
} }
#endif #endif
@@ -1396,7 +1396,7 @@ BOOL WIN_FUNC GetFileTime(HANDLE hFile, LPFILETIME lpCreationTime, LPFILETIME lp
}; };
if (!assignFileTime(lpCreationTime, changeTimespec(st)) || !assignFileTime(lpLastAccessTime, accessTimespec(st)) || if (!assignFileTime(lpCreationTime, changeTimespec(st)) || !assignFileTime(lpLastAccessTime, accessTimespec(st)) ||
!assignFileTime(lpLastWriteTime, modifyTimespec(st))) { !assignFileTime(lpLastWriteTime, modifyTimespec(st))) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@@ -1409,12 +1409,12 @@ BOOL WIN_FUNC SetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, const FI
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
#ifdef CHECK_ACCESS #ifdef CHECK_ACCESS
if ((meta.grantedAccess & FILE_WRITE_ATTRIBUTES) == 0) { if ((meta.grantedAccess & FILE_WRITE_ATTRIBUTES) == 0) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
return FALSE; return FALSE;
} }
#endif #endif
@@ -1436,7 +1436,7 @@ BOOL WIN_FUNC SetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, const FI
uint32_t hundreds = 0; uint32_t hundreds = 0;
if (!fileTimeToUnixParts(*lpLastAccessTime, seconds, hundreds) || if (!fileTimeToUnixParts(*lpLastAccessTime, seconds, hundreds) ||
!unixPartsToTimespec(seconds, hundreds, accessSpec)) { !unixPartsToTimespec(seconds, hundreds, accessSpec)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
} }
@@ -1445,7 +1445,7 @@ BOOL WIN_FUNC SetFileTime(HANDLE hFile, const FILETIME *lpCreationTime, const FI
uint32_t hundreds = 0; uint32_t hundreds = 0;
if (!fileTimeToUnixParts(*lpLastWriteTime, seconds, hundreds) || if (!fileTimeToUnixParts(*lpLastWriteTime, seconds, hundreds) ||
!unixPartsToTimespec(seconds, hundreds, writeSpec)) { !unixPartsToTimespec(seconds, hundreds, writeSpec)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
} }
@@ -1476,13 +1476,13 @@ BOOL WIN_FUNC GetFileInformationByHandle(HANDLE hFile, LPBY_HANDLE_FILE_INFORMAT
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetFileInformationByHandle(%p, %p)\n", hFile, lpFileInformation); DEBUG_LOG("GetFileInformationByHandle(%p, %p)\n", hFile, lpFileInformation);
if (!lpFileInformation) { if (!lpFileInformation) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
HandleMeta meta{}; HandleMeta meta{};
auto file = wibo::handles().getAs<FileObject>(hFile, &meta); auto file = wibo::handles().getAs<FileObject>(hFile, &meta);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
// TODO access check // TODO access check
@@ -1515,7 +1515,7 @@ DWORD WIN_FUNC GetFileType(HANDLE hFile) {
DEBUG_LOG("GetFileType(%p) ", hFile); DEBUG_LOG("GetFileType(%p) ", hFile);
auto file = wibo::handles().getAs<FileObject>(hFile); auto file = wibo::handles().getAs<FileObject>(hFile);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
DEBUG_LOG("-> ERROR_INVALID_HANDLE\n"); DEBUG_LOG("-> ERROR_INVALID_HANDLE\n");
return FILE_TYPE_UNKNOWN; return FILE_TYPE_UNKNOWN;
} }
@@ -1548,7 +1548,7 @@ DWORD WIN_FUNC GetFullPathNameA(LPCSTR lpFileName, DWORD nBufferLength, LPSTR lp
} }
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -1563,17 +1563,17 @@ DWORD WIN_FUNC GetFullPathNameA(LPCSTR lpFileName, DWORD nBufferLength, LPSTR lp
const auto required = static_cast<DWORD>(pathLen + 1); const auto required = static_cast<DWORD>(pathLen + 1);
if (nBufferLength == 0) { if (nBufferLength == 0) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
if (!lpBuffer) { if (!lpBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (nBufferLength < required) { if (nBufferLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
@@ -1600,7 +1600,7 @@ DWORD WIN_FUNC GetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR
} }
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -1617,17 +1617,17 @@ DWORD WIN_FUNC GetFullPathNameW(LPCWSTR lpFileName, DWORD nBufferLength, LPWSTR
const auto required = static_cast<DWORD>(wideLen); const auto required = static_cast<DWORD>(wideLen);
if (nBufferLength == 0) { if (nBufferLength == 0) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
if (!lpBuffer) { if (!lpBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (nBufferLength < required) { if (nBufferLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
@@ -1648,7 +1648,7 @@ DWORD WIN_FUNC GetShortPathNameA(LPCSTR lpszLongPath, LPSTR lpszShortPath, DWORD
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetShortPathNameA(%s)\n", lpszLongPath ? lpszLongPath : "(null)"); DEBUG_LOG("GetShortPathNameA(%s)\n", lpszLongPath ? lpszLongPath : "(null)");
if (!lpszLongPath || !lpszShortPath) { if (!lpszLongPath || !lpszShortPath) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -1656,7 +1656,7 @@ DWORD WIN_FUNC GetShortPathNameA(LPCSTR lpszLongPath, LPSTR lpszShortPath, DWORD
std::string absStr = files::pathToWindows(absPath); std::string absStr = files::pathToWindows(absPath);
DWORD required = static_cast<DWORD>(absStr.length() + 1); DWORD required = static_cast<DWORD>(absStr.length() + 1);
if (cchBuffer < required) { if (cchBuffer < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
@@ -1667,7 +1667,7 @@ DWORD WIN_FUNC GetShortPathNameA(LPCSTR lpszLongPath, LPSTR lpszShortPath, DWORD
DWORD WIN_FUNC GetShortPathNameW(LPCWSTR lpszLongPath, LPWSTR lpszShortPath, DWORD cchBuffer) { DWORD WIN_FUNC GetShortPathNameW(LPCWSTR lpszLongPath, LPWSTR lpszShortPath, DWORD cchBuffer) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
if (!lpszLongPath || !lpszShortPath) { if (!lpszLongPath || !lpszShortPath) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string longPath = wideStringToString(lpszLongPath); std::string longPath = wideStringToString(lpszLongPath);
@@ -1678,7 +1678,7 @@ DWORD WIN_FUNC GetShortPathNameW(LPCWSTR lpszLongPath, LPWSTR lpszShortPath, DWO
size_t len = wstrlen(absStrW.data()); size_t len = wstrlen(absStrW.data());
DWORD required = static_cast<DWORD>(len + 1); DWORD required = static_cast<DWORD>(len + 1);
if (cchBuffer < required) { if (cchBuffer < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
wstrncpy(lpszShortPath, absStrW.data(), len + 1); wstrncpy(lpszShortPath, absStrW.data(), len + 1);
@@ -1690,11 +1690,11 @@ UINT WIN_FUNC GetTempFileNameA(LPCSTR lpPathName, LPCSTR lpPrefixString, UINT uU
DEBUG_LOG("GetTempFileNameA(%s, %s, %u)\n", lpPathName ? lpPathName : "(null)", DEBUG_LOG("GetTempFileNameA(%s, %s, %u)\n", lpPathName ? lpPathName : "(null)",
lpPrefixString ? lpPrefixString : "(null)", uUnique); lpPrefixString ? lpPrefixString : "(null)", uUnique);
if (!lpPathName || !lpPrefixString || !lpTempFileName) { if (!lpPathName || !lpPrefixString || !lpTempFileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (strlen(lpPathName) > MAX_PATH - 14) { if (strlen(lpPathName) > MAX_PATH - 14) {
wibo::lastError = ERROR_BUFFER_OVERFLOW; setLastError(ERROR_BUFFER_OVERFLOW);
return 0; return 0;
} }
char uniqueStr[20]; char uniqueStr[20];
@@ -1732,7 +1732,7 @@ DWORD WIN_FUNC GetTempPathA(DWORD nBufferLength, LPSTR lpBuffer) {
DEBUG_LOG("GetTempPathA(%u, %p)\n", nBufferLength, lpBuffer); DEBUG_LOG("GetTempPathA(%u, %p)\n", nBufferLength, lpBuffer);
if (nBufferLength == 0 || lpBuffer == nullptr) { if (nBufferLength == 0 || lpBuffer == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
return 0; return 0;
} }
@@ -1743,7 +1743,7 @@ DWORD WIN_FUNC GetTempPathA(DWORD nBufferLength, LPSTR lpBuffer) {
} }
size_t len = strlen(path); size_t len = strlen(path);
if (len + 1 > nBufferLength) { if (len + 1 > nBufferLength) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
DEBUG_LOG(" -> ERROR_INSUFFICIENT_BUFFER\n"); DEBUG_LOG(" -> ERROR_INSUFFICIENT_BUFFER\n");
return static_cast<DWORD>(len + 1); return static_cast<DWORD>(len + 1);
} }
@@ -1758,12 +1758,12 @@ HANDLE WIN_FUNC FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileD
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FindFirstFileA(%s, %p)", lpFileName ? lpFileName : "(null)", lpFindFileData); DEBUG_LOG("FindFirstFileA(%s, %p)", lpFileName ? lpFileName : "(null)", lpFindFileData);
if (!lpFindFileData) { if (!lpFindFileData) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_PATH_NOT_FOUND; setLastError(ERROR_PATH_NOT_FOUND);
DEBUG_LOG(" -> ERROR_PATH_NOT_FOUND\n"); DEBUG_LOG(" -> ERROR_PATH_NOT_FOUND\n");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -1777,12 +1777,12 @@ HANDLE WIN_FUNC FindFirstFileW(LPCWSTR lpFileName, LPWIN32_FIND_DATAW lpFindFile
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FindFirstFileW(%p, %p)", lpFileName, lpFindFileData); DEBUG_LOG("FindFirstFileW(%p, %p)", lpFileName, lpFindFileData);
if (!lpFindFileData) { if (!lpFindFileData) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (!lpFileName) { if (!lpFileName) {
wibo::lastError = ERROR_PATH_NOT_FOUND; setLastError(ERROR_PATH_NOT_FOUND);
DEBUG_LOG(" -> ERROR_PATH_NOT_FOUND\n"); DEBUG_LOG(" -> ERROR_PATH_NOT_FOUND\n");
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -1800,32 +1800,32 @@ HANDLE WIN_FUNC FindFirstFileExA(LPCSTR lpFileName, FINDEX_INFO_LEVELS fInfoLeve
lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags); lpFindFileData, fSearchOp, lpSearchFilter, dwAdditionalFlags);
if (!lpFindFileData) { if (!lpFindFileData) {
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (!lpFileName) { if (!lpFileName) {
DEBUG_LOG(" -> ERROR_PATH_NOT_FOUND\n"); DEBUG_LOG(" -> ERROR_PATH_NOT_FOUND\n");
wibo::lastError = ERROR_PATH_NOT_FOUND; setLastError(ERROR_PATH_NOT_FOUND);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (fInfoLevelId != FindExInfoStandard) { if (fInfoLevelId != FindExInfoStandard) {
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (fSearchOp != FindExSearchNameMatch) { if (fSearchOp != FindExSearchNameMatch) {
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (lpSearchFilter) { if (lpSearchFilter) {
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if (dwAdditionalFlags != 0) { if (dwAdditionalFlags != 0) {
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -1838,7 +1838,7 @@ BOOL WIN_FUNC FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
DEBUG_LOG("FindNextFileA(%p, %p)\n", hFindFile, lpFindFileData); DEBUG_LOG("FindNextFileA(%p, %p)\n", hFindFile, lpFindFileData);
if (!lpFindFileData) { if (!lpFindFileData) {
DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG(" -> ERROR_INVALID_PARAMETER\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -1846,12 +1846,12 @@ BOOL WIN_FUNC FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData)
auto *state = lookupFindHandleLocked(hFindFile); auto *state = lookupFindHandleLocked(hFindFile);
if (!state) { if (!state) {
DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n"); DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (state->singleResult || state->nextIndex >= state->entries.size()) { if (state->singleResult || state->nextIndex >= state->entries.size()) {
DEBUG_LOG(" -> ERROR_NO_MORE_FILES\n"); DEBUG_LOG(" -> ERROR_NO_MORE_FILES\n");
wibo::lastError = ERROR_NO_MORE_FILES; setLastError(ERROR_NO_MORE_FILES);
return FALSE; return FALSE;
} }
populateFindData(state->entries[state->nextIndex++], *lpFindFileData); populateFindData(state->entries[state->nextIndex++], *lpFindFileData);
@@ -1862,7 +1862,7 @@ BOOL WIN_FUNC FindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FindNextFileW(%p, %p)\n", hFindFile, lpFindFileData); DEBUG_LOG("FindNextFileW(%p, %p)\n", hFindFile, lpFindFileData);
if (!lpFindFileData) { if (!lpFindFileData) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -1870,12 +1870,12 @@ BOOL WIN_FUNC FindNextFileW(HANDLE hFindFile, LPWIN32_FIND_DATAW lpFindFileData)
auto *state = lookupFindHandleLocked(hFindFile); auto *state = lookupFindHandleLocked(hFindFile);
if (!state) { if (!state) {
DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n"); DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (state->singleResult || state->nextIndex >= state->entries.size()) { if (state->singleResult || state->nextIndex >= state->entries.size()) {
DEBUG_LOG(" -> ERROR_NO_MORE_FILES\n"); DEBUG_LOG(" -> ERROR_NO_MORE_FILES\n");
wibo::lastError = ERROR_NO_MORE_FILES; setLastError(ERROR_NO_MORE_FILES);
return FALSE; return FALSE;
} }
populateFindData(state->entries[state->nextIndex++], *lpFindFileData); populateFindData(state->entries[state->nextIndex++], *lpFindFileData);
@@ -1887,14 +1887,14 @@ BOOL WIN_FUNC FindClose(HANDLE hFindFile) {
DEBUG_LOG("FindClose(%p)\n", hFindFile); DEBUG_LOG("FindClose(%p)\n", hFindFile);
if (hFindFile == nullptr) { if (hFindFile == nullptr) {
DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n"); DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
auto owned = detachFindHandle(hFindFile); auto owned = detachFindHandle(hFindFile);
if (!owned) { if (!owned) {
DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n"); DEBUG_LOG(" -> ERROR_INVALID_HANDLE\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;

View File

@@ -18,7 +18,7 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle,
(void)dwDesiredAccess; (void)dwDesiredAccess;
(void)dwOptions; (void)dwOptions;
if (!lpTargetHandle) { if (!lpTargetHandle) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -33,7 +33,7 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle,
if (!validateProcessHandle(hSourceProcessHandle) || !validateProcessHandle(hTargetProcessHandle)) { if (!validateProcessHandle(hSourceProcessHandle) || !validateProcessHandle(hTargetProcessHandle)) {
DEBUG_LOG("DuplicateHandle: unsupported process handle combination (source=%p target=%p)\n", DEBUG_LOG("DuplicateHandle: unsupported process handle combination (source=%p target=%p)\n",
hSourceProcessHandle, hTargetProcessHandle); hSourceProcessHandle, hTargetProcessHandle);
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@@ -53,7 +53,7 @@ BOOL WIN_FUNC DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle,
} }
if (!handles.duplicateTo(hSourceHandle, handles, *lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)) { if (!handles.duplicateTo(hSourceHandle, handles, *lpTargetHandle, dwDesiredAccess, bInheritHandle, dwOptions)) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@@ -63,7 +63,7 @@ BOOL WIN_FUNC CloseHandle(HANDLE hObject) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("CloseHandle(%p)\n", hObject); DEBUG_LOG("CloseHandle(%p)\n", hObject);
if (!wibo::handles().release(hObject)) { if (!wibo::handles().release(hObject)) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;

View File

@@ -42,14 +42,14 @@ LPVOID heapAllocFromRecord(HeapObject *record, DWORD dwFlags, SIZE_T dwBytes) {
} }
if ((record->createFlags | dwFlags) & HEAP_GENERATE_EXCEPTIONS) { if ((record->createFlags | dwFlags) & HEAP_GENERATE_EXCEPTIONS) {
DEBUG_LOG("HeapAlloc: HEAP_GENERATE_EXCEPTIONS not supported\n"); DEBUG_LOG("HeapAlloc: HEAP_GENERATE_EXCEPTIONS not supported\n");
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
const bool zeroMemory = (dwFlags & HEAP_ZERO_MEMORY) != 0; const bool zeroMemory = (dwFlags & HEAP_ZERO_MEMORY) != 0;
const SIZE_T requestSize = std::max<SIZE_T>(1, dwBytes); const SIZE_T requestSize = std::max<SIZE_T>(1, dwBytes);
void *mem = zeroMemory ? mi_heap_zalloc(record->heap, requestSize) : mi_heap_malloc(record->heap, requestSize); void *mem = zeroMemory ? mi_heap_zalloc(record->heap, requestSize) : mi_heap_malloc(record->heap, requestSize);
if (!mem) { if (!mem) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; kernel32::setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
if (isExecutableHeap(record)) { if (isExecutableHeap(record)) {
@@ -79,13 +79,13 @@ HANDLE WIN_FUNC HeapCreate(DWORD flOptions, SIZE_T dwInitialSize, SIZE_T dwMaxim
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("HeapCreate(%u, %zu, %zu)\n", flOptions, dwInitialSize, dwMaximumSize); DEBUG_LOG("HeapCreate(%u, %zu, %zu)\n", flOptions, dwInitialSize, dwMaximumSize);
if (dwMaximumSize != 0 && dwInitialSize > dwMaximumSize) { if (dwMaximumSize != 0 && dwInitialSize > dwMaximumSize) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
mi_heap_t *heap = mi_heap_new(); mi_heap_t *heap = mi_heap_new();
if (!heap) { if (!heap) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
@@ -101,7 +101,7 @@ BOOL WIN_FUNC HeapDestroy(HANDLE hHeap) {
DEBUG_LOG("HeapDestroy(%p)\n", hHeap); DEBUG_LOG("HeapDestroy(%p)\n", hHeap);
auto record = wibo::handles().getAs<HeapObject>(hHeap); auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record || !record->isOwner() || record->isProcessHeap) { if (!record || !record->isOwner() || record->isProcessHeap) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
mi_heap_destroy(record->heap); mi_heap_destroy(record->heap);
@@ -124,13 +124,13 @@ BOOL WIN_FUNC HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapI
HeapInformation, HeapInformationLength); HeapInformation, HeapInformationLength);
auto record = wibo::handles().getAs<HeapObject>(HeapHandle); auto record = wibo::handles().getAs<HeapObject>(HeapHandle);
if (!record || !record->canAccess()) { if (!record || !record->canAccess()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
switch (HeapInformationClass) { switch (HeapInformationClass) {
case HeapCompatibilityInformation: { case HeapCompatibilityInformation: {
if (!HeapInformation || HeapInformationLength < sizeof(ULONG)) { if (!HeapInformation || HeapInformationLength < sizeof(ULONG)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
record->compatibility = *static_cast<ULONG *>(HeapInformation); record->compatibility = *static_cast<ULONG *>(HeapInformation);
@@ -139,10 +139,10 @@ BOOL WIN_FUNC HeapSetInformation(HANDLE HeapHandle, HEAP_INFORMATION_CLASS HeapI
case HeapEnableTerminationOnCorruption: case HeapEnableTerminationOnCorruption:
return TRUE; return TRUE;
case HeapOptimizeResources: case HeapOptimizeResources:
wibo::lastError = ERROR_CALL_NOT_IMPLEMENTED; setLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE; return FALSE;
default: default:
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
} }
@@ -153,7 +153,7 @@ LPVOID WIN_FUNC HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) {
auto record = wibo::handles().getAs<HeapObject>(hHeap); auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record || !record->canAccess()) { if (!record || !record->canAccess()) {
VERBOSE_LOG("-> NULL\n"); VERBOSE_LOG("-> NULL\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
void *mem = heapAllocFromRecord(record.get(), dwFlags, dwBytes); void *mem = heapAllocFromRecord(record.get(), dwFlags, dwBytes);
@@ -167,7 +167,7 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
auto record = wibo::handles().getAs<HeapObject>(hHeap); auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record || !record->canAccess()) { if (!record || !record->canAccess()) {
VERBOSE_LOG("-> NULL\n"); VERBOSE_LOG("-> NULL\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
if (lpMem == nullptr) { if (lpMem == nullptr) {
@@ -177,12 +177,12 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
} }
if (!mi_is_in_heap_region(lpMem)) { if (!mi_is_in_heap_region(lpMem)) {
VERBOSE_LOG("-> NULL (not owned)\n"); VERBOSE_LOG("-> NULL (not owned)\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
if ((record->createFlags | dwFlags) & HEAP_GENERATE_EXCEPTIONS) { if ((record->createFlags | dwFlags) & HEAP_GENERATE_EXCEPTIONS) {
VERBOSE_LOG("-> NULL (exceptions unsupported)\n"); VERBOSE_LOG("-> NULL (exceptions unsupported)\n");
wibo::lastError = ERROR_NOT_SUPPORTED; setLastError(ERROR_NOT_SUPPORTED);
return nullptr; return nullptr;
} }
const bool inplaceOnly = (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY) != 0; const bool inplaceOnly = (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY) != 0;
@@ -194,7 +194,7 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
return nullptr; return nullptr;
} }
VERBOSE_LOG("-> NULL (zero size with in-place flag)\n"); VERBOSE_LOG("-> NULL (zero size with in-place flag)\n");
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
@@ -203,7 +203,7 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
if (inplaceOnly || requestSize <= oldSize) { if (inplaceOnly || requestSize <= oldSize) {
if (requestSize > oldSize) { if (requestSize > oldSize) {
VERBOSE_LOG("-> NULL (cannot grow in place)\n"); VERBOSE_LOG("-> NULL (cannot grow in place)\n");
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
VERBOSE_LOG("-> %p (in-place)\n", lpMem); VERBOSE_LOG("-> %p (in-place)\n", lpMem);
@@ -212,7 +212,7 @@ LPVOID WIN_FUNC HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dw
void *ret = mi_heap_realloc(record->heap, lpMem, requestSize); void *ret = mi_heap_realloc(record->heap, lpMem, requestSize);
if (!ret) { if (!ret) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
if (zeroMemory && requestSize > oldSize) { if (zeroMemory && requestSize > oldSize) {
@@ -236,17 +236,17 @@ SIZE_T WIN_FUNC HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem) {
auto record = wibo::handles().getAs<HeapObject>(hHeap); auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record || !record->canAccess()) { if (!record || !record->canAccess()) {
VERBOSE_LOG("-> ERROR_INVALID_HANDLE\n"); VERBOSE_LOG("-> ERROR_INVALID_HANDLE\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return static_cast<SIZE_T>(-1); return static_cast<SIZE_T>(-1);
} }
if (!lpMem) { if (!lpMem) {
VERBOSE_LOG("-> ERROR_INVALID_PARAMETER\n"); VERBOSE_LOG("-> ERROR_INVALID_PARAMETER\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return static_cast<SIZE_T>(-1); return static_cast<SIZE_T>(-1);
} }
if (!mi_is_in_heap_region(lpMem)) { if (!mi_is_in_heap_region(lpMem)) {
VERBOSE_LOG("-> ERROR_INVALID_PARAMETER (not owned)\n"); VERBOSE_LOG("-> ERROR_INVALID_PARAMETER (not owned)\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return static_cast<SIZE_T>(-1); return static_cast<SIZE_T>(-1);
} }
size_t size = mi_usable_size(lpMem); size_t size = mi_usable_size(lpMem);
@@ -263,12 +263,12 @@ BOOL WIN_FUNC HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
auto record = wibo::handles().getAs<HeapObject>(hHeap); auto record = wibo::handles().getAs<HeapObject>(hHeap);
if (!record || !record->canAccess()) { if (!record || !record->canAccess()) {
VERBOSE_LOG("-> ERROR_INVALID_HANDLE\n"); VERBOSE_LOG("-> ERROR_INVALID_HANDLE\n");
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (!mi_is_in_heap_region(lpMem)) { if (!mi_is_in_heap_region(lpMem)) {
VERBOSE_LOG("-> ERROR_INVALID_PARAMETER (not owned)\n"); VERBOSE_LOG("-> ERROR_INVALID_PARAMETER (not owned)\n");
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
mi_free(lpMem); mi_free(lpMem);

View File

@@ -176,6 +176,9 @@ void tryMarkExecutable(void *mem);
void setLastErrorFromErrno(); void setLastErrorFromErrno();
[[noreturn]] void exitInternal(DWORD exitCode); [[noreturn]] void exitInternal(DWORD exitCode);
DWORD getLastError();
void setLastError(DWORD error);
} // namespace kernel32 } // namespace kernel32
namespace detail { namespace detail {

View File

@@ -15,7 +15,7 @@ BOOL WIN_FUNC GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWO
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetOverlappedResult(%p, %p, %p, %d)\n", hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait); DEBUG_LOG("GetOverlappedResult(%p, %p, %p, %d)\n", hFile, lpOverlapped, lpNumberOfBytesTransferred, bWait);
if (!lpOverlapped) { if (!lpOverlapped) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -26,14 +26,14 @@ BOOL WIN_FUNC GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWO
std::unique_lock lk(file->m); std::unique_lock lk(file->m);
file->overlappedCv.wait(lk, [&] { return lpOverlapped->Internal != STATUS_PENDING; }); file->overlappedCv.wait(lk, [&] { return lpOverlapped->Internal != STATUS_PENDING; });
} else { } else {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
} }
const auto status = static_cast<NTSTATUS>(lpOverlapped->Internal); const auto status = static_cast<NTSTATUS>(lpOverlapped->Internal);
if (status == STATUS_PENDING) { if (status == STATUS_PENDING) {
wibo::lastError = ERROR_IO_INCOMPLETE; setLastError(ERROR_IO_INCOMPLETE);
return FALSE; return FALSE;
} }
@@ -45,7 +45,7 @@ BOOL WIN_FUNC GetOverlappedResult(HANDLE hFile, LPOVERLAPPED lpOverlapped, LPDWO
if (error == ERROR_SUCCESS) { if (error == ERROR_SUCCESS) {
return TRUE; return TRUE;
} }
wibo::lastError = error; setLastError(error);
return FALSE; return FALSE;
} }

View File

@@ -18,7 +18,7 @@ HRSRC findResourceInternal(HMODULE hModule, const wibo::ResourceIdentifier &type
std::optional<uint16_t> language) { std::optional<uint16_t> language) {
auto *exe = wibo::executableFromModule(hModule); auto *exe = wibo::executableFromModule(hModule);
if (!exe) { if (!exe) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return nullptr; return nullptr;
} }
wibo::ResourceLocation loc; wibo::ResourceLocation loc;
@@ -36,16 +36,16 @@ BOOL WIN_FUNC DisableThreadLibraryCalls(HMODULE hLibModule) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("DisableThreadLibraryCalls(%p)\n", hLibModule); DEBUG_LOG("DisableThreadLibraryCalls(%p)\n", hLibModule);
if (!hLibModule) { if (!hLibModule) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
wibo::ModuleInfo *info = wibo::moduleInfoFromHandle(hLibModule); wibo::ModuleInfo *info = wibo::moduleInfoFromHandle(hLibModule);
if (!info) { if (!info) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
if (!wibo::disableThreadNotifications(info)) { if (!wibo::disableThreadNotifications(info)) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@@ -56,7 +56,7 @@ HMODULE WIN_FUNC GetModuleHandleA(LPCSTR lpModuleName) {
DEBUG_LOG("GetModuleHandleA(%s)\n", lpModuleName); DEBUG_LOG("GetModuleHandleA(%s)\n", lpModuleName);
const auto *module = wibo::findLoadedModule(lpModuleName); const auto *module = wibo::findLoadedModule(lpModuleName);
if (!module) { if (!module) {
wibo::lastError = ERROR_MOD_NOT_FOUND; setLastError(ERROR_MOD_NOT_FOUND);
return nullptr; return nullptr;
} }
return module->handle; return module->handle;
@@ -76,12 +76,12 @@ DWORD WIN_FUNC GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetModuleFileNameA(%p, %p, %u)\n", hModule, lpFilename, nSize); DEBUG_LOG("GetModuleFileNameA(%p, %p, %u)\n", hModule, lpFilename, nSize);
if (!lpFilename) { if (!lpFilename) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
auto *info = wibo::moduleInfoFromHandle(hModule); auto *info = wibo::moduleInfoFromHandle(hModule);
if (!info) { if (!info) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string path; std::string path;
@@ -92,7 +92,7 @@ DWORD WIN_FUNC GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize
} }
DEBUG_LOG("-> %s\n", path.c_str()); DEBUG_LOG("-> %s\n", path.c_str());
if (nSize == 0) { if (nSize == 0) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
const size_t len = path.size(); const size_t len = path.size();
@@ -102,7 +102,7 @@ DWORD WIN_FUNC GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize
lpFilename[copyLen] = '\0'; lpFilename[copyLen] = '\0';
} }
if (copyLen < len) { if (copyLen < len) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return nSize; return nSize;
} }
return static_cast<DWORD>(copyLen); return static_cast<DWORD>(copyLen);
@@ -112,12 +112,12 @@ DWORD WIN_FUNC GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSiz
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetModuleFileNameW(%p, %s, %u)\n", hModule, wideStringToString(lpFilename).c_str(), nSize); DEBUG_LOG("GetModuleFileNameW(%p, %s, %u)\n", hModule, wideStringToString(lpFilename).c_str(), nSize);
if (!lpFilename) { if (!lpFilename) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
auto *info = wibo::moduleInfoFromHandle(hModule); auto *info = wibo::moduleInfoFromHandle(hModule);
if (!info) { if (!info) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string path; std::string path;
@@ -127,7 +127,7 @@ DWORD WIN_FUNC GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSiz
path = info->originalName; path = info->originalName;
} }
if (nSize == 0) { if (nSize == 0) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
auto wide = stringToWideString(path.c_str()); auto wide = stringToWideString(path.c_str());
@@ -143,7 +143,7 @@ DWORD WIN_FUNC GetModuleFileNameW(HMODULE hModule, LPWSTR lpFilename, DWORD nSiz
lpFilename[copyLen] = 0; lpFilename[copyLen] = 0;
} }
if (copyLen < len) { if (copyLen < len) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return nSize; return nSize;
} }
return static_cast<DWORD>(copyLen); return static_cast<DWORD>(copyLen);
@@ -185,17 +185,17 @@ HGLOBAL WIN_FUNC LoadResource(HMODULE hModule, HRSRC hResInfo) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("LoadResource %p %p\n", hModule, hResInfo); DEBUG_LOG("LoadResource %p %p\n", hModule, hResInfo);
if (!hResInfo) { if (!hResInfo) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return nullptr; return nullptr;
} }
auto *exe = wibo::executableFromModule(hModule); auto *exe = wibo::executableFromModule(hModule);
if (!exe || !exe->rsrcBase) { if (!exe || !exe->rsrcBase) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return nullptr; return nullptr;
} }
const auto *entry = reinterpret_cast<const wibo::ImageResourceDataEntry *>(hResInfo); const auto *entry = reinterpret_cast<const wibo::ImageResourceDataEntry *>(hResInfo);
if (!wibo::resourceEntryBelongsToExecutable(*exe, entry)) { if (!wibo::resourceEntryBelongsToExecutable(*exe, entry)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
return const_cast<void *>(exe->fromRVA<const void>(entry->offsetToData)); return const_cast<void *>(exe->fromRVA<const void>(entry->offsetToData));
@@ -211,17 +211,17 @@ DWORD WIN_FUNC SizeofResource(HMODULE hModule, HRSRC hResInfo) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SizeofResource(%p, %p)\n", hModule, hResInfo); DEBUG_LOG("SizeofResource(%p, %p)\n", hModule, hResInfo);
if (!hResInfo) { if (!hResInfo) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return 0; return 0;
} }
auto *exe = wibo::executableFromModule(hModule); auto *exe = wibo::executableFromModule(hModule);
if (!exe || !exe->rsrcBase) { if (!exe || !exe->rsrcBase) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return 0; return 0;
} }
const auto *entry = reinterpret_cast<const wibo::ImageResourceDataEntry *>(hResInfo); const auto *entry = reinterpret_cast<const wibo::ImageResourceDataEntry *>(hResInfo);
if (!wibo::resourceEntryBelongsToExecutable(*exe, entry)) { if (!wibo::resourceEntryBelongsToExecutable(*exe, entry)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
return entry->size; return entry->size;
@@ -262,7 +262,7 @@ BOOL WIN_FUNC FreeLibrary(HMODULE hLibModule) {
DEBUG_LOG("FreeLibrary(%p)\n", hLibModule); DEBUG_LOG("FreeLibrary(%p)\n", hLibModule);
auto *info = wibo::moduleInfoFromHandle(hLibModule); auto *info = wibo::moduleInfoFromHandle(hLibModule);
if (!info) { if (!info) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
wibo::freeModule(info); wibo::freeModule(info);
@@ -275,7 +275,7 @@ FARPROC WIN_FUNC GetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
const auto info = wibo::moduleInfoFromHandle(hModule); const auto info = wibo::moduleInfoFromHandle(hModule);
if (!info) { if (!info) {
DEBUG_LOG("GetProcAddress(%p) -> ERROR_INVALID_HANDLE\n", hModule); DEBUG_LOG("GetProcAddress(%p) -> ERROR_INVALID_HANDLE\n", hModule);
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
const auto proc = reinterpret_cast<uintptr_t>(lpProcName); const auto proc = reinterpret_cast<uintptr_t>(lpProcName);
@@ -288,7 +288,7 @@ FARPROC WIN_FUNC GetProcAddress(HMODULE hModule, LPCSTR lpProcName) {
} }
DEBUG_LOG("-> %p\n", result); DEBUG_LOG("-> %p\n", result);
if (!result) { if (!result) {
wibo::lastError = ERROR_PROC_NOT_FOUND; setLastError(ERROR_PROC_NOT_FOUND);
} }
return result; return result;
} }

View File

@@ -473,7 +473,7 @@ HANDLE WIN_FUNC CreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMap
uint64_t size = (static_cast<uint64_t>(dwMaximumSizeHigh) << 32) | dwMaximumSizeLow; uint64_t size = (static_cast<uint64_t>(dwMaximumSizeHigh) << 32) | dwMaximumSizeLow;
if (flProtect != PAGE_READONLY && flProtect != PAGE_READWRITE && flProtect != PAGE_WRITECOPY) { if (flProtect != PAGE_READONLY && flProtect != PAGE_READWRITE && flProtect != PAGE_WRITECOPY) {
DEBUG_LOG("CreateFileMappingA: unsupported protection 0x%x\n", flProtect); DEBUG_LOG("CreateFileMappingA: unsupported protection 0x%x\n", flProtect);
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
@@ -484,14 +484,14 @@ HANDLE WIN_FUNC CreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMap
mapping->anonymous = true; mapping->anonymous = true;
mapping->fd = -1; mapping->fd = -1;
if (size == 0) { if (size == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
mapping->maxSize = size; mapping->maxSize = size;
} else { } else {
auto file = wibo::handles().getAs<FileObject>(hFile); auto file = wibo::handles().getAs<FileObject>(hFile);
if (!file || !file->valid()) { if (!file || !file->valid()) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
int dupFd = fcntl(file->fd, F_DUPFD_CLOEXEC, 0); int dupFd = fcntl(file->fd, F_DUPFD_CLOEXEC, 0);
@@ -525,32 +525,32 @@ HANDLE WIN_FUNC CreateFileMappingW(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMap
static LPVOID mapViewOfFileInternal(Pin<MappingObject> mapping, DWORD dwDesiredAccess, uint64_t offset, static LPVOID mapViewOfFileInternal(Pin<MappingObject> mapping, DWORD dwDesiredAccess, uint64_t offset,
SIZE_T dwNumberOfBytesToMap, LPVOID baseAddress) { SIZE_T dwNumberOfBytesToMap, LPVOID baseAddress) {
if (!mapping) { if (!mapping) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
if (mapping->closed) { if (mapping->closed) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
if (mapping->anonymous && offset != 0) { if (mapping->anonymous && offset != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
size_t maxSize = mapping->maxSize; size_t maxSize = mapping->maxSize;
uint64_t length = static_cast<uint64_t>(dwNumberOfBytesToMap); uint64_t length = static_cast<uint64_t>(dwNumberOfBytesToMap);
if (length == 0) { if (length == 0) {
if (maxSize == 0 || offset > maxSize) { if (maxSize == 0 || offset > maxSize) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
length = maxSize - offset; length = maxSize - offset;
} }
if (length == 0) { if (length == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
if (maxSize != 0 && offset + length > maxSize) { if (maxSize != 0 && offset + length > maxSize) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
@@ -568,7 +568,7 @@ static LPVOID mapViewOfFileInternal(Pin<MappingObject> mapping, DWORD dwDesiredA
} }
} else { } else {
if (wantWrite && !wantCopy) { if (wantWrite && !wantCopy) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
return nullptr; return nullptr;
} }
if (wantCopy) { if (wantCopy) {
@@ -585,12 +585,12 @@ static LPVOID mapViewOfFileInternal(Pin<MappingObject> mapping, DWORD dwDesiredA
size_t offsetDelta = static_cast<size_t>(offset - static_cast<uint64_t>(alignedOffset)); size_t offsetDelta = static_cast<size_t>(offset - static_cast<uint64_t>(alignedOffset));
uint64_t requestedLength = length + offsetDelta; uint64_t requestedLength = length + offsetDelta;
if (requestedLength < length) { if (requestedLength < length) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
size_t mapLength = static_cast<size_t>(requestedLength); size_t mapLength = static_cast<size_t>(requestedLength);
if (static_cast<uint64_t>(mapLength) != requestedLength) { if (static_cast<uint64_t>(mapLength) != requestedLength) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
@@ -600,16 +600,16 @@ static LPVOID mapViewOfFileInternal(Pin<MappingObject> mapping, DWORD dwDesiredA
if (baseAddress) { if (baseAddress) {
uintptr_t baseAddr = reinterpret_cast<uintptr_t>(baseAddress); uintptr_t baseAddr = reinterpret_cast<uintptr_t>(baseAddress);
if (baseAddr == 0 || (baseAddr % kVirtualAllocationGranularity) != 0) { if (baseAddr == 0 || (baseAddr % kVirtualAllocationGranularity) != 0) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
if (offsetDelta > baseAddr) { if (offsetDelta > baseAddr) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
uintptr_t mapBaseAddr = baseAddr - offsetDelta; uintptr_t mapBaseAddr = baseAddr - offsetDelta;
if ((mapBaseAddr & (pageSize - 1)) != 0) { if ((mapBaseAddr & (pageSize - 1)) != 0) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
requestedBase = reinterpret_cast<void *>(mapBaseAddr); requestedBase = reinterpret_cast<void *>(mapBaseAddr);
@@ -625,16 +625,16 @@ static LPVOID mapViewOfFileInternal(Pin<MappingObject> mapping, DWORD dwDesiredA
if (mapBase == MAP_FAILED) { if (mapBase == MAP_FAILED) {
int err = errno; int err = errno;
if (baseAddress && (err == ENOMEM || err == EEXIST || err == EINVAL || err == EPERM)) { if (baseAddress && (err == ENOMEM || err == EEXIST || err == EINVAL || err == EPERM)) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
} else { } else {
wibo::lastError = wibo::winErrorFromErrno(err); setLastError(wibo::winErrorFromErrno(err));
} }
return nullptr; return nullptr;
} }
void *viewPtr = static_cast<uint8_t *>(mapBase) + offsetDelta; void *viewPtr = static_cast<uint8_t *>(mapBase) + offsetDelta;
if (baseAddress && viewPtr != baseAddress) { if (baseAddress && viewPtr != baseAddress) {
munmap(mapBase, mapLength); munmap(mapBase, mapLength);
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
uintptr_t viewLength = static_cast<uintptr_t>(length); uintptr_t viewLength = static_cast<uintptr_t>(length);
@@ -667,7 +667,7 @@ LPVOID WIN_FUNC MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess,
auto mapping = wibo::handles().getAs<MappingObject>(hFileMappingObject); auto mapping = wibo::handles().getAs<MappingObject>(hFileMappingObject);
if (!mapping) { if (!mapping) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
uint64_t offset = (static_cast<uint64_t>(dwFileOffsetHigh) << 32) | dwFileOffsetLow; uint64_t offset = (static_cast<uint64_t>(dwFileOffsetHigh) << 32) | dwFileOffsetLow;
@@ -682,7 +682,7 @@ LPVOID WIN_FUNC MapViewOfFileEx(HANDLE hFileMappingObject, DWORD dwDesiredAccess
auto mapping = wibo::handles().getAs<MappingObject>(hFileMappingObject); auto mapping = wibo::handles().getAs<MappingObject>(hFileMappingObject);
if (!mapping) { if (!mapping) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
uint64_t offset = (static_cast<uint64_t>(dwFileOffsetHigh) << 32) | dwFileOffsetLow; uint64_t offset = (static_cast<uint64_t>(dwFileOffsetHigh) << 32) | dwFileOffsetLow;
@@ -695,7 +695,7 @@ BOOL WIN_FUNC UnmapViewOfFile(LPCVOID lpBaseAddress) {
std::unique_lock lk(g_viewInfoMutex); std::unique_lock lk(g_viewInfoMutex);
auto it = g_viewInfo.find(reinterpret_cast<uintptr_t>(lpBaseAddress)); auto it = g_viewInfo.find(reinterpret_cast<uintptr_t>(lpBaseAddress));
if (it == g_viewInfo.end()) { if (it == g_viewInfo.end()) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
void *base = reinterpret_cast<void *>(it->second.allocationBase); void *base = reinterpret_cast<void *>(it->second.allocationBase);
@@ -713,7 +713,7 @@ BOOL WIN_FUNC FlushViewOfFile(LPCVOID lpBaseAddress, SIZE_T dwNumberOfBytesToFlu
DEBUG_LOG("FlushViewOfFile(%p, %zu)\n", lpBaseAddress, dwNumberOfBytesToFlush); DEBUG_LOG("FlushViewOfFile(%p, %zu)\n", lpBaseAddress, dwNumberOfBytesToFlush);
if (!lpBaseAddress) { if (!lpBaseAddress) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -727,13 +727,13 @@ BOOL WIN_FUNC FlushViewOfFile(LPCVOID lpBaseAddress, SIZE_T dwNumberOfBytesToFlu
std::lock_guard guard(g_viewInfoMutex); std::lock_guard guard(g_viewInfoMutex);
auto it = g_viewInfo.upper_bound(address); auto it = g_viewInfo.upper_bound(address);
if (it == g_viewInfo.begin()) { if (it == g_viewInfo.begin()) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
--it; --it;
const auto &view = it->second; const auto &view = it->second;
if (address < view.viewBase || address >= view.viewBase + view.viewLength) { if (address < view.viewBase || address >= view.viewBase + view.viewLength) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
viewBase = view.viewBase; viewBase = view.viewBase;
@@ -766,7 +766,7 @@ BOOL WIN_FUNC FlushViewOfFile(LPCVOID lpBaseAddress, SIZE_T dwNumberOfBytesToFlu
alignedEnd = mappingEnd; alignedEnd = mappingEnd;
} }
if (alignedEnd < alignedStart) { if (alignedEnd < alignedStart) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -776,7 +776,7 @@ BOOL WIN_FUNC FlushViewOfFile(LPCVOID lpBaseAddress, SIZE_T dwNumberOfBytesToFlu
} }
if (msync(reinterpret_cast<void *>(alignedStart), length, MS_SYNC) != 0) { if (msync(reinterpret_cast<void *>(alignedStart), length, MS_SYNC) != 0) {
wibo::lastError = wibo::winErrorFromErrno(errno); setLastError(wibo::winErrorFromErrno(errno));
return FALSE; return FALSE;
} }
@@ -788,14 +788,14 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
DEBUG_LOG("VirtualAlloc(%p, %zu, %u, %u)\n", lpAddress, dwSize, flAllocationType, flProtect); DEBUG_LOG("VirtualAlloc(%p, %zu, %u, %u)\n", lpAddress, dwSize, flAllocationType, flProtect);
if (dwSize == 0) { if (dwSize == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
DWORD unsupportedFlags = flAllocationType & (MEM_WRITE_WATCH | MEM_PHYSICAL | MEM_LARGE_PAGES | MEM_RESET_UNDO); DWORD unsupportedFlags = flAllocationType & (MEM_WRITE_WATCH | MEM_PHYSICAL | MEM_LARGE_PAGES | MEM_RESET_UNDO);
if (unsupportedFlags != 0) { if (unsupportedFlags != 0) {
DEBUG_LOG("VirtualAlloc unsupported flags: 0x%x\n", unsupportedFlags); DEBUG_LOG("VirtualAlloc unsupported flags: 0x%x\n", unsupportedFlags);
wibo::lastError = ERROR_NOT_SUPPORTED; setLastError(ERROR_NOT_SUPPORTED);
return nullptr; return nullptr;
} }
@@ -809,17 +809,17 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
if (reset) { if (reset) {
if (reserve || commit) { if (reserve || commit) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
if (!lpAddress) { if (!lpAddress) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
const size_t pageSize = systemPageSize(); const size_t pageSize = systemPageSize();
uintptr_t request = reinterpret_cast<uintptr_t>(lpAddress); uintptr_t request = reinterpret_cast<uintptr_t>(lpAddress);
if (addOverflows(request, static_cast<size_t>(dwSize))) { if (addOverflows(request, static_cast<size_t>(dwSize))) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
uintptr_t start = alignDown(request, pageSize); uintptr_t start = alignDown(request, pageSize);
@@ -828,7 +828,7 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
std::unique_lock lk(g_virtualAllocMutex); std::unique_lock lk(g_virtualAllocMutex);
VirtualAllocation *region = lookupRegion(start); VirtualAllocation *region = lookupRegion(start);
if (!region || !rangeWithinRegion(*region, start, length)) { if (!region || !rangeWithinRegion(*region, start, length)) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
#ifdef MADV_FREE #ifdef MADV_FREE
@@ -844,7 +844,7 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
} }
if (!reserve && !commit) { if (!reserve && !commit) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
@@ -859,24 +859,24 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
base = alignDown(request, kVirtualAllocationGranularity); base = alignDown(request, kVirtualAllocationGranularity);
size_t offset = static_cast<size_t>(request - base); size_t offset = static_cast<size_t>(request - base);
if (addOverflows(offset, static_cast<size_t>(dwSize))) { if (addOverflows(offset, static_cast<size_t>(dwSize))) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
size_t span = static_cast<size_t>(dwSize) + offset; size_t span = static_cast<size_t>(dwSize) + offset;
uintptr_t alignedSpan = alignUp(span, pageSize); uintptr_t alignedSpan = alignUp(span, pageSize);
if (alignedSpan == std::numeric_limits<uintptr_t>::max()) { if (alignedSpan == std::numeric_limits<uintptr_t>::max()) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
length = static_cast<size_t>(alignedSpan); length = static_cast<size_t>(alignedSpan);
if (length == 0 || rangeOverlapsLocked(base, length)) { if (length == 0 || rangeOverlapsLocked(base, length)) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
} else { } else {
uintptr_t aligned = alignUp(static_cast<uintptr_t>(dwSize), pageSize); uintptr_t aligned = alignUp(static_cast<uintptr_t>(dwSize), pageSize);
if (aligned == std::numeric_limits<uintptr_t>::max() || aligned == 0) { if (aligned == std::numeric_limits<uintptr_t>::max() || aligned == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
length = static_cast<size_t>(aligned); length = static_cast<size_t>(aligned);
@@ -903,7 +903,7 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
} }
if (reinterpret_cast<uintptr_t>(result) >= 0x80000000) { if (reinterpret_cast<uintptr_t>(result) >= 0x80000000) {
munmap(result, length); munmap(result, length);
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
uintptr_t actualBase = reinterpret_cast<uintptr_t>(result); uintptr_t actualBase = reinterpret_cast<uintptr_t>(result);
@@ -918,19 +918,19 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
uintptr_t request = reinterpret_cast<uintptr_t>(lpAddress); uintptr_t request = reinterpret_cast<uintptr_t>(lpAddress);
if (addOverflows(request, static_cast<size_t>(dwSize))) { if (addOverflows(request, static_cast<size_t>(dwSize))) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
uintptr_t start = alignDown(request, pageSize); uintptr_t start = alignDown(request, pageSize);
uintptr_t end = alignUp(request + static_cast<uintptr_t>(dwSize), pageSize); uintptr_t end = alignUp(request + static_cast<uintptr_t>(dwSize), pageSize);
size_t length = static_cast<size_t>(end - start); size_t length = static_cast<size_t>(end - start);
if (length == 0) { if (length == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
VirtualAllocation *region = lookupRegion(start); VirtualAllocation *region = lookupRegion(start);
if (!region || !rangeWithinRegion(*region, start, length)) { if (!region || !rangeWithinRegion(*region, start, length)) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
const size_t pageCount = length / pageSize; const size_t pageCount = length / pageSize;
@@ -939,7 +939,7 @@ LPVOID WIN_FUNC VirtualAlloc(LPVOID lpAddress, SIZE_T dwSize, DWORD flAllocation
for (size_t i = 0; i < pageCount; ++i) { for (size_t i = 0; i < pageCount; ++i) {
size_t pageIndex = ((start - region->base) / pageSize) + i; size_t pageIndex = ((start - region->base) / pageSize) + i;
if (pageIndex >= region->pageProtect.size()) { if (pageIndex >= region->pageProtect.size()) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return nullptr; return nullptr;
} }
if (region->pageProtect[pageIndex] != 0) { if (region->pageProtect[pageIndex] != 0) {
@@ -974,19 +974,19 @@ BOOL WIN_FUNC VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("VirtualFree(%p, %zu, %u)\n", lpAddress, dwSize, dwFreeType); DEBUG_LOG("VirtualFree(%p, %zu, %u)\n", lpAddress, dwSize, dwFreeType);
if (!lpAddress) { if (!lpAddress) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return FALSE; return FALSE;
} }
if ((dwFreeType & (MEM_COALESCE_PLACEHOLDERS | MEM_PRESERVE_PLACEHOLDER)) != 0) { if ((dwFreeType & (MEM_COALESCE_PLACEHOLDERS | MEM_PRESERVE_PLACEHOLDER)) != 0) {
wibo::lastError = ERROR_NOT_SUPPORTED; setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }
const bool release = (dwFreeType & MEM_RELEASE) != 0; const bool release = (dwFreeType & MEM_RELEASE) != 0;
const bool decommit = (dwFreeType & MEM_DECOMMIT) != 0; const bool decommit = (dwFreeType & MEM_DECOMMIT) != 0;
if (release == decommit) { if (release == decommit) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -999,14 +999,14 @@ BOOL WIN_FUNC VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {
if (exact == g_virtualAllocations.end()) { if (exact == g_virtualAllocations.end()) {
auto containing = findRegionIterator(base); auto containing = findRegionIterator(base);
if (dwSize != 0 && containing != g_virtualAllocations.end()) { if (dwSize != 0 && containing != g_virtualAllocations.end()) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
} else { } else {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
} }
return FALSE; return FALSE;
} }
if (dwSize != 0) { if (dwSize != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
size_t length = exact->second.size; size_t length = exact->second.size;
@@ -1022,7 +1022,7 @@ BOOL WIN_FUNC VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {
uintptr_t request = reinterpret_cast<uintptr_t>(lpAddress); uintptr_t request = reinterpret_cast<uintptr_t>(lpAddress);
auto regionIt = findRegionIterator(request); auto regionIt = findRegionIterator(request);
if (regionIt == g_virtualAllocations.end()) { if (regionIt == g_virtualAllocations.end()) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return FALSE; return FALSE;
} }
VirtualAllocation &region = regionIt->second; VirtualAllocation &region = regionIt->second;
@@ -1030,25 +1030,25 @@ BOOL WIN_FUNC VirtualFree(LPVOID lpAddress, SIZE_T dwSize, DWORD dwFreeType) {
uintptr_t end = 0; uintptr_t end = 0;
if (dwSize == 0) { if (dwSize == 0) {
if (request != region.base) { if (request != region.base) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
start = region.base; start = region.base;
end = region.base + region.size; end = region.base + region.size;
} else { } else {
if (addOverflows(request, static_cast<size_t>(dwSize))) { if (addOverflows(request, static_cast<size_t>(dwSize))) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
end = alignUp(request + static_cast<uintptr_t>(dwSize), pageSize); end = alignUp(request + static_cast<uintptr_t>(dwSize), pageSize);
} }
if (end <= start) { if (end <= start) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
size_t length = static_cast<size_t>(end - start); size_t length = static_cast<size_t>(end - start);
if (!rangeWithinRegion(region, start, length)) { if (!rangeWithinRegion(region, start, length)) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return FALSE; return FALSE;
} }
void *result = mmap(reinterpret_cast<void *>(start), length, PROT_NONE, void *result = mmap(reinterpret_cast<void *>(start), length, PROT_NONE,
@@ -1065,7 +1065,7 @@ BOOL WIN_FUNC VirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("VirtualProtect(%p, %zu, %u)\n", lpAddress, dwSize, flNewProtect); DEBUG_LOG("VirtualProtect(%p, %zu, %u)\n", lpAddress, dwSize, flNewProtect);
if (!lpAddress || dwSize == 0) { if (!lpAddress || dwSize == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -1074,32 +1074,32 @@ BOOL WIN_FUNC VirtualProtect(LPVOID lpAddress, SIZE_T dwSize, DWORD flNewProtect
uintptr_t start = alignDown(request, pageSize); uintptr_t start = alignDown(request, pageSize);
uintptr_t end = alignUp(request + static_cast<uintptr_t>(dwSize), pageSize); uintptr_t end = alignUp(request + static_cast<uintptr_t>(dwSize), pageSize);
if (end <= start) { if (end <= start) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::unique_lock lk(g_virtualAllocMutex); std::unique_lock lk(g_virtualAllocMutex);
VirtualAllocation *region = lookupRegion(start); VirtualAllocation *region = lookupRegion(start);
if (!region || !rangeWithinRegion(*region, start, static_cast<size_t>(end - start))) { if (!region || !rangeWithinRegion(*region, start, static_cast<size_t>(end - start))) {
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
return FALSE; return FALSE;
} }
const size_t firstPage = (start - region->base) / pageSize; const size_t firstPage = (start - region->base) / pageSize;
const size_t pageCount = (end - start) / pageSize; const size_t pageCount = (end - start) / pageSize;
if (pageCount == 0) { if (pageCount == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
DWORD previousProtect = region->pageProtect[firstPage]; DWORD previousProtect = region->pageProtect[firstPage];
if (previousProtect == 0) { if (previousProtect == 0) {
wibo::lastError = ERROR_NOACCESS; setLastError(ERROR_NOACCESS);
return FALSE; return FALSE;
} }
for (size_t i = 0; i < pageCount; ++i) { for (size_t i = 0; i < pageCount; ++i) {
if (region->pageProtect[firstPage + i] == 0) { if (region->pageProtect[firstPage + i] == 0) {
wibo::lastError = ERROR_NOACCESS; setLastError(ERROR_NOACCESS);
return FALSE; return FALSE;
} }
} }
@@ -1124,7 +1124,7 @@ SIZE_T WIN_FUNC VirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuff
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("VirtualQuery(%p, %p, %zu)\n", lpAddress, lpBuffer, dwLength); DEBUG_LOG("VirtualQuery(%p, %p, %zu)\n", lpAddress, lpBuffer, dwLength);
if (!lpBuffer || dwLength < sizeof(MEMORY_BASIC_INFORMATION)) { if (!lpBuffer || dwLength < sizeof(MEMORY_BASIC_INFORMATION)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n"); DEBUG_LOG("-> ERROR_INVALID_PARAMETER\n");
return 0; return 0;
} }
@@ -1134,7 +1134,7 @@ SIZE_T WIN_FUNC VirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuff
uintptr_t request = lpAddress ? reinterpret_cast<uintptr_t>(lpAddress) : 0; uintptr_t request = lpAddress ? reinterpret_cast<uintptr_t>(lpAddress) : 0;
uintptr_t pageBase = alignDown(request, pageSize); uintptr_t pageBase = alignDown(request, pageSize);
if (pageBase >= kProcessAddressLimit) { if (pageBase >= kProcessAddressLimit) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG("-> ERROR_INVALID_PARAMETER (beyond address space)\n"); DEBUG_LOG("-> ERROR_INVALID_PARAMETER (beyond address space)\n");
return 0; return 0;
} }
@@ -1153,7 +1153,7 @@ SIZE_T WIN_FUNC VirtualQuery(LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuff
return sizeof(MEMORY_BASIC_INFORMATION); return sizeof(MEMORY_BASIC_INFORMATION);
} }
wibo::lastError = ERROR_INVALID_ADDRESS; setLastError(ERROR_INVALID_ADDRESS);
DEBUG_LOG("-> ERROR_INVALID_ADDRESS\n"); DEBUG_LOG("-> ERROR_INVALID_ADDRESS\n");
return 0; return 0;
} }
@@ -1164,7 +1164,7 @@ BOOL WIN_FUNC GetProcessWorkingSetSize(HANDLE hProcess, PSIZE_T lpMinimumWorking
DEBUG_LOG("GetProcessWorkingSetSize(%p, %p, %p)\n", hProcess, lpMinimumWorkingSetSize, lpMaximumWorkingSetSize); DEBUG_LOG("GetProcessWorkingSetSize(%p, %p, %p)\n", hProcess, lpMinimumWorkingSetSize, lpMaximumWorkingSetSize);
(void)hProcess; (void)hProcess;
if (!lpMinimumWorkingSetSize || !lpMaximumWorkingSetSize) { if (!lpMinimumWorkingSetSize || !lpMaximumWorkingSetSize) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpMinimumWorkingSetSize = 32 * 1024 * 1024; // 32 MiB stub *lpMinimumWorkingSetSize = 32 * 1024 * 1024; // 32 MiB stub

View File

@@ -284,7 +284,7 @@ bool tryCreateFileNamedPipeA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
auto parsed = parsePipeName(lpFileName, parseError); auto parsed = parsePipeName(lpFileName, parseError);
if (!parsed) { if (!parsed) {
if (parseError != ERROR_SUCCESS) { if (parseError != ERROR_SUCCESS) {
wibo::lastError = parseError; setLastError(parseError);
outHandle = INVALID_HANDLE_VALUE; outHandle = INVALID_HANDLE_VALUE;
return true; return true;
} }
@@ -293,7 +293,7 @@ bool tryCreateFileNamedPipeA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
auto state = wibo::g_namespace.getAs<NamedPipeState>(parsed->namespaceKey); auto state = wibo::g_namespace.getAs<NamedPipeState>(parsed->namespaceKey);
if (!state) { if (!state) {
wibo::lastError = ERROR_FILE_NOT_FOUND; setLastError(ERROR_FILE_NOT_FOUND);
outHandle = INVALID_HANDLE_VALUE; outHandle = INVALID_HANDLE_VALUE;
return true; return true;
} }
@@ -301,14 +301,14 @@ bool tryCreateFileNamedPipeA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
DWORD acquireError = ERROR_SUCCESS; DWORD acquireError = ERROR_SUCCESS;
auto instancePin = acquireConnectableInstance(state, dwDesiredAccess, acquireError); auto instancePin = acquireConnectableInstance(state, dwDesiredAccess, acquireError);
if (!instancePin) { if (!instancePin) {
wibo::lastError = acquireError; setLastError(acquireError);
outHandle = INVALID_HANDLE_VALUE; outHandle = INVALID_HANDLE_VALUE;
return true; return true;
} }
int clientFd = instancePin->takeCompanion(); int clientFd = instancePin->takeCompanion();
if (clientFd < 0) { if (clientFd < 0) {
wibo::lastError = ERROR_PIPE_BUSY; setLastError(ERROR_PIPE_BUSY);
outHandle = INVALID_HANDLE_VALUE; outHandle = INVALID_HANDLE_VALUE;
return true; return true;
} }
@@ -319,7 +319,7 @@ bool tryCreateFileNamedPipeA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwS
auto clientObj = make_pin<FileObject>(clientFd); auto clientObj = make_pin<FileObject>(clientFd);
if (!clientObj) { if (!clientObj) {
instancePin->restoreCompanion(clientFd); instancePin->restoreCompanion(clientFd);
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
outHandle = INVALID_HANDLE_VALUE; outHandle = INVALID_HANDLE_VALUE;
return true; return true;
} }
@@ -352,7 +352,7 @@ BOOL WIN_FUNC CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRI
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("CreatePipe(%p, %p, %p, %u)\n", hReadPipe, hWritePipe, lpPipeAttributes, nSize); DEBUG_LOG("CreatePipe(%p, %p, %p, %u)\n", hReadPipe, hWritePipe, lpPipeAttributes, nSize);
if (!hReadPipe || !hWritePipe) { if (!hReadPipe || !hWritePipe) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*hReadPipe = nullptr; *hReadPipe = nullptr;
@@ -393,20 +393,20 @@ HANDLE WIN_FUNC CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMo
DWORD parseError = ERROR_SUCCESS; DWORD parseError = ERROR_SUCCESS;
std::optional<ParsedPipeName> parsed = parsePipeName(lpName, parseError); std::optional<ParsedPipeName> parsed = parsePipeName(lpName, parseError);
if (!parsed) { if (!parsed) {
wibo::lastError = (parseError == ERROR_SUCCESS) ? ERROR_INVALID_NAME : parseError; setLastError((parseError == ERROR_SUCCESS) ? ERROR_INVALID_NAME : parseError);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
constexpr DWORD kAllowedOpenFlags = PIPE_ACCESS_DUPLEX | WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY | constexpr DWORD kAllowedOpenFlags = PIPE_ACCESS_DUPLEX | WRITE_DAC | WRITE_OWNER | ACCESS_SYSTEM_SECURITY |
FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED; FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_WRITE_THROUGH | FILE_FLAG_OVERLAPPED;
if ((dwOpenMode & ~kAllowedOpenFlags) != 0) { if ((dwOpenMode & ~kAllowedOpenFlags) != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
DWORD accessMode = dwOpenMode & PIPE_ACCESS_DUPLEX; DWORD accessMode = dwOpenMode & PIPE_ACCESS_DUPLEX;
if (accessMode != PIPE_ACCESS_DUPLEX && accessMode != PIPE_ACCESS_INBOUND && accessMode != PIPE_ACCESS_OUTBOUND) { if (accessMode != PIPE_ACCESS_DUPLEX && accessMode != PIPE_ACCESS_INBOUND && accessMode != PIPE_ACCESS_OUTBOUND) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -417,11 +417,11 @@ HANDLE WIN_FUNC CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMo
constexpr DWORD kAllowedPipeModeFlags = constexpr DWORD kAllowedPipeModeFlags =
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT | PIPE_REJECT_REMOTE_CLIENTS; PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_NOWAIT | PIPE_REJECT_REMOTE_CLIENTS;
if ((dwPipeMode & ~kAllowedPipeModeFlags) != 0) { if ((dwPipeMode & ~kAllowedPipeModeFlags) != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
if ((dwPipeMode & PIPE_READMODE_MESSAGE) != 0 && (dwPipeMode & PIPE_TYPE_MESSAGE) == 0) { if ((dwPipeMode & PIPE_READMODE_MESSAGE) != 0 && (dwPipeMode & PIPE_TYPE_MESSAGE) == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -431,7 +431,7 @@ HANDLE WIN_FUNC CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMo
auto [state, isNewState] = wibo::g_namespace.getOrCreate( auto [state, isNewState] = wibo::g_namespace.getOrCreate(
parsed->namespaceKey, [&]() -> NamedPipeState * { return new NamedPipeState(parsed->key); }); parsed->namespaceKey, [&]() -> NamedPipeState * { return new NamedPipeState(parsed->key); });
if (!state) { if (!state) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -439,7 +439,7 @@ HANDLE WIN_FUNC CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMo
DWORD reserveError = ERROR_SUCCESS; DWORD reserveError = ERROR_SUCCESS;
if (!state->reserveInstance(accessMode, pipeType, nDefaultTimeOut, normalizedMaxInstances, firstInstanceFlag, if (!state->reserveInstance(accessMode, pipeType, nDefaultTimeOut, normalizedMaxInstances, firstInstanceFlag,
isNewState, reserveError)) { isNewState, reserveError)) {
wibo::lastError = reserveError; setLastError(reserveError);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
instanceReserved = true; instanceReserved = true;
@@ -459,7 +459,7 @@ HANDLE WIN_FUNC CreateNamedPipeA(LPCSTR lpName, DWORD dwOpenMode, DWORD dwPipeMo
state->releaseInstance(); state->releaseInstance();
instanceReserved = false; instanceReserved = false;
} }
wibo::lastError = err; setLastError(err);
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
}; };
@@ -532,35 +532,35 @@ BOOL WIN_FUNC ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped) {
auto pipe = wibo::handles().getAs<NamedPipeInstance>(hNamedPipe); auto pipe = wibo::handles().getAs<NamedPipeInstance>(hNamedPipe);
if (!pipe) { if (!pipe) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
const bool isOverlappedHandle = pipe->overlapped; const bool isOverlappedHandle = pipe->overlapped;
if (isOverlappedHandle && lpOverlapped == nullptr) { if (isOverlappedHandle && lpOverlapped == nullptr) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::unique_lock lock(pipe->connectMutex); std::unique_lock lock(pipe->connectMutex);
if (pipe->clientConnected) { if (pipe->clientConnected) {
wibo::lastError = ERROR_PIPE_CONNECTED; setLastError(ERROR_PIPE_CONNECTED);
return FALSE; return FALSE;
} }
if (pipe->companionFd < 0) { if (pipe->companionFd < 0) {
wibo::lastError = ERROR_PIPE_BUSY; setLastError(ERROR_PIPE_BUSY);
return FALSE; return FALSE;
} }
if (pipe->connectPending) { if (pipe->connectPending) {
wibo::lastError = ERROR_PIPE_LISTENING; setLastError(ERROR_PIPE_LISTENING);
return FALSE; return FALSE;
} }
if ((pipe->pipeMode & PIPE_NOWAIT) != 0) { if ((pipe->pipeMode & PIPE_NOWAIT) != 0) {
wibo::lastError = ERROR_PIPE_LISTENING; setLastError(ERROR_PIPE_LISTENING);
return FALSE; return FALSE;
} }
@@ -571,7 +571,7 @@ BOOL WIN_FUNC ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped) {
lpOverlapped->InternalHigh = 0; lpOverlapped->InternalHigh = 0;
kernel32::detail::resetOverlappedEvent(lpOverlapped); kernel32::detail::resetOverlappedEvent(lpOverlapped);
lock.unlock(); lock.unlock();
wibo::lastError = ERROR_IO_PENDING; setLastError(ERROR_IO_PENDING);
return FALSE; return FALSE;
} }
@@ -579,7 +579,7 @@ BOOL WIN_FUNC ConnectNamedPipe(HANDLE hNamedPipe, LPOVERLAPPED lpOverlapped) {
pipe->connectCv.wait(lock, [&]() { return pipe->clientConnected || pipe->companionFd < 0; }); pipe->connectCv.wait(lock, [&]() { return pipe->clientConnected || pipe->companionFd < 0; });
pipe->connectPending = false; pipe->connectPending = false;
if (!pipe->clientConnected) { if (!pipe->clientConnected) {
wibo::lastError = ERROR_NO_DATA; setLastError(ERROR_NO_DATA);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;

View File

@@ -80,7 +80,7 @@ LPCH WIN_FUNC GetEnvironmentStrings() {
char *buffer = static_cast<char *>(mi_malloc(bufSize)); char *buffer = static_cast<char *>(mi_malloc(bufSize));
if (!buffer) { if (!buffer) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
char *ptr = buffer; char *ptr = buffer;
@@ -113,7 +113,7 @@ LPWCH WIN_FUNC GetEnvironmentStringsW() {
uint16_t *buffer = static_cast<uint16_t *>(mi_malloc(bufSizeW * sizeof(uint16_t))); uint16_t *buffer = static_cast<uint16_t *>(mi_malloc(bufSizeW * sizeof(uint16_t)));
if (!buffer) { if (!buffer) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return nullptr; return nullptr;
} }
uint16_t *ptr = buffer; uint16_t *ptr = buffer;
@@ -137,7 +137,7 @@ BOOL WIN_FUNC FreeEnvironmentStringsA(LPCH penv) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FreeEnvironmentStringsA(%p)\n", penv); DEBUG_LOG("FreeEnvironmentStringsA(%p)\n", penv);
if (!penv) { if (!penv) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
free(penv); free(penv);
@@ -148,7 +148,7 @@ BOOL WIN_FUNC FreeEnvironmentStringsW(LPWCH penv) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FreeEnvironmentStringsW(%p)\n", penv); DEBUG_LOG("FreeEnvironmentStringsW(%p)\n", penv);
if (!penv) { if (!penv) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
free(penv); free(penv);
@@ -159,12 +159,12 @@ DWORD WIN_FUNC GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSiz
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetEnvironmentVariableA(%s, %p, %u)\n", lpName ? lpName : "(null)", lpBuffer, nSize); DEBUG_LOG("GetEnvironmentVariableA(%s, %p, %u)\n", lpName ? lpName : "(null)", lpBuffer, nSize);
if (!lpName) { if (!lpName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
const char *rawValue = getenv(lpName); const char *rawValue = getenv(lpName);
if (!rawValue) { if (!rawValue) {
wibo::lastError = ERROR_ENVVAR_NOT_FOUND; setLastError(ERROR_ENVVAR_NOT_FOUND);
return 0; return 0;
} }
std::string converted = convertEnvValueForWindows(lpName, rawValue); std::string converted = convertEnvValueForWindows(lpName, rawValue);
@@ -174,7 +174,7 @@ DWORD WIN_FUNC GetEnvironmentVariableA(LPCSTR lpName, LPSTR lpBuffer, DWORD nSiz
return len + 1; return len + 1;
} }
if (!lpBuffer) { if (!lpBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (nSize <= len) { if (nSize <= len) {
@@ -189,12 +189,12 @@ DWORD WIN_FUNC GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nS
std::string name = lpName ? wideStringToString(lpName) : std::string(); std::string name = lpName ? wideStringToString(lpName) : std::string();
DEBUG_LOG("GetEnvironmentVariableW(%s, %p, %u)\n", name.c_str(), lpBuffer, nSize); DEBUG_LOG("GetEnvironmentVariableW(%s, %p, %u)\n", name.c_str(), lpBuffer, nSize);
if (name.empty()) { if (name.empty()) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
const char *rawValue = getenv(name.c_str()); const char *rawValue = getenv(name.c_str());
if (!rawValue) { if (!rawValue) {
wibo::lastError = ERROR_ENVVAR_NOT_FOUND; setLastError(ERROR_ENVVAR_NOT_FOUND);
return 0; return 0;
} }
std::string converted = convertEnvValueForWindows(name, rawValue); std::string converted = convertEnvValueForWindows(name, rawValue);
@@ -205,7 +205,7 @@ DWORD WIN_FUNC GetEnvironmentVariableW(LPCWSTR lpName, LPWSTR lpBuffer, DWORD nS
return required; return required;
} }
if (!lpBuffer) { if (!lpBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (nSize < required) { if (nSize < required) {
@@ -219,7 +219,7 @@ BOOL WIN_FUNC SetEnvironmentVariableA(LPCSTR lpName, LPCSTR lpValue) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SetEnvironmentVariableA(%s, %s)\n", lpName ? lpName : "(null)", lpValue ? lpValue : "(null)"); DEBUG_LOG("SetEnvironmentVariableA(%s, %s)\n", lpName ? lpName : "(null)", lpValue ? lpValue : "(null)");
if (!lpName || std::strchr(lpName, '=')) { if (!lpName || std::strchr(lpName, '=')) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
int rc = 0; int rc = 0;
@@ -245,7 +245,7 @@ BOOL WIN_FUNC SetEnvironmentVariableW(LPCWSTR lpName, LPCWSTR lpValue) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SetEnvironmentVariableW -> "); DEBUG_LOG("SetEnvironmentVariableW -> ");
if (!lpName) { if (!lpName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
DEBUG_LOG("ERROR_INVALID_PARAMETER\n"); DEBUG_LOG("ERROR_INVALID_PARAMETER\n");
return FALSE; return FALSE;
} }

View File

@@ -225,14 +225,14 @@ BOOL WIN_FUNC GetProcessAffinityMask(HANDLE hProcess, PDWORD_PTR lpProcessAffini
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetProcessAffinityMask(%p, %p, %p)\n", hProcess, lpProcessAffinityMask, lpSystemAffinityMask); DEBUG_LOG("GetProcessAffinityMask(%p, %p, %p)\n", hProcess, lpProcessAffinityMask, lpSystemAffinityMask);
if (!lpProcessAffinityMask || !lpSystemAffinityMask) { if (!lpProcessAffinityMask || !lpSystemAffinityMask) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (!isPseudoCurrentProcessHandle(hProcess)) { if (!isPseudoCurrentProcessHandle(hProcess)) {
auto obj = wibo::handles().getAs<ProcessObject>(hProcess); auto obj = wibo::handles().getAs<ProcessObject>(hProcess);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
} }
@@ -256,21 +256,21 @@ BOOL WIN_FUNC SetProcessAffinityMask(HANDLE hProcess, DWORD_PTR dwProcessAffinit
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SetProcessAffinityMask(%p, 0x%lx)\n", hProcess, static_cast<unsigned long>(dwProcessAffinityMask)); DEBUG_LOG("SetProcessAffinityMask(%p, 0x%lx)\n", hProcess, static_cast<unsigned long>(dwProcessAffinityMask));
if (dwProcessAffinityMask == 0) { if (dwProcessAffinityMask == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (!isPseudoCurrentProcessHandle(hProcess)) { if (!isPseudoCurrentProcessHandle(hProcess)) {
auto obj = wibo::handles().getAs<ProcessObject>(hProcess); auto obj = wibo::handles().getAs<ProcessObject>(hProcess);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
} }
DWORD_PTR systemMask = computeSystemAffinityMask(); DWORD_PTR systemMask = computeSystemAffinityMask();
if ((dwProcessAffinityMask & systemMask) == 0 || (dwProcessAffinityMask & ~systemMask) != 0) { if ((dwProcessAffinityMask & systemMask) == 0 || (dwProcessAffinityMask & ~systemMask) != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -283,14 +283,14 @@ DWORD_PTR WIN_FUNC SetThreadAffinityMask(HANDLE hThread, DWORD_PTR dwThreadAffin
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SetThreadAffinityMask(%p, 0x%lx)\n", hThread, static_cast<unsigned long>(dwThreadAffinityMask)); DEBUG_LOG("SetThreadAffinityMask(%p, 0x%lx)\n", hThread, static_cast<unsigned long>(dwThreadAffinityMask));
if (dwThreadAffinityMask == 0) { if (dwThreadAffinityMask == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (!isPseudoCurrentThreadHandle(hThread)) { if (!isPseudoCurrentThreadHandle(hThread)) {
auto obj = wibo::handles().getAs<ThreadObject>(hThread); auto obj = wibo::handles().getAs<ThreadObject>(hThread);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
} }
@@ -301,7 +301,7 @@ DWORD_PTR WIN_FUNC SetThreadAffinityMask(HANDLE hThread, DWORD_PTR dwThreadAffin
return 0; return 0;
} }
if ((dwThreadAffinityMask & ~systemMask) != 0 || (dwThreadAffinityMask & processMask) == 0) { if ((dwThreadAffinityMask & ~systemMask) != 0 || (dwThreadAffinityMask & processMask) == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -328,7 +328,7 @@ BOOL WIN_FUNC TerminateProcess(HANDLE hProcess, UINT uExitCode) {
} }
auto process = wibo::handles().getAs<ProcessObject>(hProcess); auto process = wibo::handles().getAs<ProcessObject>(hProcess);
if (!process) { if (!process) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
std::lock_guard lk(process->m); std::lock_guard lk(process->m);
@@ -341,10 +341,10 @@ BOOL WIN_FUNC TerminateProcess(HANDLE hProcess, UINT uExitCode) {
switch (err) { switch (err) {
case ESRCH: case ESRCH:
case EPERM: case EPERM:
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
break; break;
default: default:
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
break; break;
} }
return FALSE; return FALSE;
@@ -358,7 +358,7 @@ BOOL WIN_FUNC GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetExitCodeProcess(%p, %p)\n", hProcess, lpExitCode); DEBUG_LOG("GetExitCodeProcess(%p, %p)\n", hProcess, lpExitCode);
if (!lpExitCode) { if (!lpExitCode) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (isPseudoCurrentProcessHandle(hProcess)) { if (isPseudoCurrentProcessHandle(hProcess)) {
@@ -367,7 +367,7 @@ BOOL WIN_FUNC GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode) {
} }
auto process = wibo::handles().getAs<ProcessObject>(hProcess); auto process = wibo::handles().getAs<ProcessObject>(hProcess);
if (!process) { if (!process) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
DWORD exitCode = STILL_ACTIVE; DWORD exitCode = STILL_ACTIVE;
@@ -384,10 +384,10 @@ DWORD WIN_FUNC TlsAlloc() {
VERBOSE_LOG("TlsAlloc()\n"); VERBOSE_LOG("TlsAlloc()\n");
DWORD index = wibo::tls::reserveSlot(); DWORD index = wibo::tls::reserveSlot();
if (index == wibo::tls::kInvalidTlsIndex) { if (index == wibo::tls::kInvalidTlsIndex) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; setLastError(ERROR_NOT_ENOUGH_MEMORY);
return TLS_OUT_OF_INDEXES; return TLS_OUT_OF_INDEXES;
} }
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
return index; return index;
} }
@@ -395,10 +395,10 @@ BOOL WIN_FUNC TlsFree(DWORD dwTlsIndex) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
VERBOSE_LOG("TlsFree(%u)\n", dwTlsIndex); VERBOSE_LOG("TlsFree(%u)\n", dwTlsIndex);
if (!wibo::tls::releaseSlot(dwTlsIndex)) { if (!wibo::tls::releaseSlot(dwTlsIndex)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
return TRUE; return TRUE;
} }
@@ -406,11 +406,11 @@ LPVOID WIN_FUNC TlsGetValue(DWORD dwTlsIndex) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
VERBOSE_LOG("TlsGetValue(%u)\n", dwTlsIndex); VERBOSE_LOG("TlsGetValue(%u)\n", dwTlsIndex);
if (!wibo::tls::isSlotAllocated(dwTlsIndex)) { if (!wibo::tls::isSlotAllocated(dwTlsIndex)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
void *result = wibo::tls::getValue(dwTlsIndex); void *result = wibo::tls::getValue(dwTlsIndex);
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
return result; return result;
} }
@@ -418,14 +418,14 @@ BOOL WIN_FUNC TlsSetValue(DWORD dwTlsIndex, LPVOID lpTlsValue) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
VERBOSE_LOG("TlsSetValue(%u, %p)\n", dwTlsIndex, lpTlsValue); VERBOSE_LOG("TlsSetValue(%u, %p)\n", dwTlsIndex, lpTlsValue);
if (!wibo::tls::isSlotAllocated(dwTlsIndex)) { if (!wibo::tls::isSlotAllocated(dwTlsIndex)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (!wibo::tls::setValue(dwTlsIndex, lpTlsValue)) { if (!wibo::tls::setValue(dwTlsIndex, lpTlsValue)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
return TRUE; return TRUE;
} }
@@ -435,7 +435,7 @@ DWORD WIN_FUNC ResumeThread(HANDLE hThread) {
// TODO: behavior with current thread handle? // TODO: behavior with current thread handle?
auto obj = wibo::handles().getAs<ThreadObject>(hThread); auto obj = wibo::handles().getAs<ThreadObject>(hThread);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return static_cast<DWORD>(-1); return static_cast<DWORD>(-1);
} }
DWORD previous = 0; DWORD previous = 0;
@@ -476,7 +476,7 @@ HANDLE WIN_FUNC CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dw
constexpr DWORD SUPPORTED_FLAGS = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION; constexpr DWORD SUPPORTED_FLAGS = CREATE_SUSPENDED | STACK_SIZE_PARAM_IS_A_RESERVATION;
if ((dwCreationFlags & ~SUPPORTED_FLAGS) != 0) { if ((dwCreationFlags & ~SUPPORTED_FLAGS) != 0) {
DEBUG_LOG("CreateThread: unsupported creation flags 0x%x\n", dwCreationFlags); DEBUG_LOG("CreateThread: unsupported creation flags 0x%x\n", dwCreationFlags);
wibo::lastError = ERROR_NOT_SUPPORTED; setLastError(ERROR_NOT_SUPPORTED);
return nullptr; return nullptr;
} }
@@ -504,7 +504,7 @@ HANDLE WIN_FUNC CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dw
// Clean up // Clean up
delete startData; delete startData;
detail::deref(obj.get()); detail::deref(obj.get());
wibo::lastError = wibo::winErrorFromErrno(rc); setLastError(wibo::winErrorFromErrno(rc));
return INVALID_HANDLE_VALUE; return INVALID_HANDLE_VALUE;
} }
@@ -534,7 +534,7 @@ BOOL WIN_FUNC GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetExitCodeThread(%p, %p)\n", hThread, lpExitCode); DEBUG_LOG("GetExitCodeThread(%p, %p)\n", hThread, lpExitCode);
if (!lpExitCode) { if (!lpExitCode) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (isPseudoCurrentThreadHandle(hThread)) { if (isPseudoCurrentThreadHandle(hThread)) {
@@ -543,7 +543,7 @@ BOOL WIN_FUNC GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode) {
} }
auto obj = wibo::handles().getAs<ThreadObject>(hThread); auto obj = wibo::handles().getAs<ThreadObject>(hThread);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
std::lock_guard lk(obj->m); std::lock_guard lk(obj->m);
@@ -579,13 +579,13 @@ BOOL WIN_FUNC GetThreadTimes(HANDLE hThread, FILETIME *lpCreationTime, FILETIME
DEBUG_LOG("GetThreadTimes(%p, %p, %p, %p, %p)\n", hThread, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime); DEBUG_LOG("GetThreadTimes(%p, %p, %p, %p, %p)\n", hThread, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime);
if (!lpKernelTime || !lpUserTime) { if (!lpKernelTime || !lpUserTime) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (!isPseudoCurrentThreadHandle(hThread)) { if (!isPseudoCurrentThreadHandle(hThread)) {
DEBUG_LOG("GetThreadTimes: unsupported handle %p\n", hThread); DEBUG_LOG("GetThreadTimes: unsupported handle %p\n", hThread);
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@@ -635,7 +635,7 @@ BOOL WIN_FUNC CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSE
} else { } else {
std::vector<std::string> arguments = wibo::splitCommandLine(commandLine.c_str()); std::vector<std::string> arguments = wibo::splitCommandLine(commandLine.c_str());
if (arguments.empty()) { if (arguments.empty()) {
wibo::lastError = ERROR_FILE_NOT_FOUND; setLastError(ERROR_FILE_NOT_FOUND);
return FALSE; return FALSE;
} }
application = arguments.front(); application = arguments.front();
@@ -643,14 +643,14 @@ BOOL WIN_FUNC CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSE
auto resolved = wibo::resolveExecutable(application, useSearchPath); auto resolved = wibo::resolveExecutable(application, useSearchPath);
if (!resolved) { if (!resolved) {
wibo::lastError = ERROR_FILE_NOT_FOUND; setLastError(ERROR_FILE_NOT_FOUND);
return FALSE; return FALSE;
} }
Pin<ProcessObject> obj; Pin<ProcessObject> obj;
int spawnResult = wibo::spawnWithCommandLine(*resolved, commandLine, obj); int spawnResult = wibo::spawnWithCommandLine(*resolved, commandLine, obj);
if (spawnResult != 0) { if (spawnResult != 0) {
wibo::lastError = (spawnResult == ENOENT) ? ERROR_FILE_NOT_FOUND : ERROR_ACCESS_DENIED; setLastError((spawnResult == ENOENT) ? ERROR_FILE_NOT_FOUND : ERROR_ACCESS_DENIED);
return FALSE; return FALSE;
} }

View File

@@ -3,6 +3,7 @@
#include "common.h" #include "common.h"
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "internal.h"
namespace kernel32 { namespace kernel32 {
@@ -10,7 +11,7 @@ BOOL WIN_FUNC QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
VERBOSE_LOG("STUB: QueryPerformanceCounter(%p)\n", lpPerformanceCount); VERBOSE_LOG("STUB: QueryPerformanceCounter(%p)\n", lpPerformanceCount);
if (!lpPerformanceCount) { if (!lpPerformanceCount) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpPerformanceCount = 0; *lpPerformanceCount = 0;
@@ -21,7 +22,7 @@ BOOL WIN_FUNC QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
VERBOSE_LOG("STUB: QueryPerformanceFrequency(%p)\n", lpFrequency); VERBOSE_LOG("STUB: QueryPerformanceFrequency(%p)\n", lpFrequency);
if (!lpFrequency) { if (!lpFrequency) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpFrequency = 1; *lpFrequency = 1;

View File

@@ -3,6 +3,7 @@
#include "common.h" #include "common.h"
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "internal.h"
#include "strutil.h" #include "strutil.h"
#include <cstring> #include <cstring>
@@ -78,7 +79,7 @@ BOOL WIN_FUNC GetStringTypeW(DWORD dwInfoType, LPCWCH lpSrcStr, int cchSrc, LPWO
assert(dwInfoType == 1); // CT_CTYPE1 assert(dwInfoType == 1); // CT_CTYPE1
if (!lpSrcStr || !lpCharType) { if (!lpSrcStr || !lpCharType) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -110,11 +111,11 @@ BOOL WIN_FUNC GetStringTypeA(LCID Locale, DWORD dwInfoType, LPCSTR lpSrcStr, int
(void)Locale; (void)Locale;
if (!lpSrcStr || !lpCharType) { if (!lpSrcStr || !lpCharType) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (dwInfoType != 1) { if (dwInfoType != 1) {
wibo::lastError = ERROR_NOT_SUPPORTED; setLastError(ERROR_NOT_SUPPORTED);
return FALSE; return FALSE;
} }

View File

@@ -157,11 +157,11 @@ HANDLE WIN_FUNC CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInit
}); });
if (!mu) { if (!mu) {
// Name exists but isn't a mutex // Name exists but isn't a mutex
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
HANDLE h = wibo::handles().alloc(std::move(mu), grantedAccess, handleFlags); HANDLE h = wibo::handles().alloc(std::move(mu), grantedAccess, handleFlags);
wibo::lastError = created ? ERROR_SUCCESS : ERROR_ALREADY_EXISTS; setLastError(created ? ERROR_SUCCESS : ERROR_ALREADY_EXISTS);
return h; return h;
} }
@@ -179,7 +179,7 @@ BOOL WIN_FUNC ReleaseMutex(HANDLE hMutex) {
DEBUG_LOG("ReleaseMutex(%p)\n", hMutex); DEBUG_LOG("ReleaseMutex(%p)\n", hMutex);
auto mu = wibo::handles().getAs<MutexObject>(hMutex); auto mu = wibo::handles().getAs<MutexObject>(hMutex);
if (!mu) { if (!mu) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
const pthread_t self = pthread_self(); const pthread_t self = pthread_self();
@@ -187,7 +187,7 @@ BOOL WIN_FUNC ReleaseMutex(HANDLE hMutex) {
{ {
std::lock_guard lk(mu->m); std::lock_guard lk(mu->m);
if (!mu->ownerValid || !pthread_equal(mu->owner, self) || mu->recursionCount == 0) { if (!mu->ownerValid || !pthread_equal(mu->owner, self) || mu->recursionCount == 0) {
wibo::lastError = ERROR_NOT_OWNER; setLastError(ERROR_NOT_OWNER);
return FALSE; return FALSE;
} }
if (--mu->recursionCount == 0) { if (--mu->recursionCount == 0) {
@@ -221,12 +221,12 @@ HANDLE WIN_FUNC CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManu
}); });
if (!ev) { if (!ev) {
// Name exists but isn't an event // Name exists but isn't an event
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
HANDLE h = wibo::handles().alloc(std::move(ev), grantedAccess, handleFlags); HANDLE h = wibo::handles().alloc(std::move(ev), grantedAccess, handleFlags);
DEBUG_LOG("-> %p (created=%d)\n", h, created ? 1 : 0); DEBUG_LOG("-> %p (created=%d)\n", h, created ? 1 : 0);
wibo::lastError = created ? ERROR_SUCCESS : ERROR_ALREADY_EXISTS; setLastError(created ? ERROR_SUCCESS : ERROR_ALREADY_EXISTS);
return h; return h;
} }
@@ -259,11 +259,11 @@ HANDLE WIN_FUNC CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LO
}); });
if (!sem) { if (!sem) {
// Name exists but isn't an event // Name exists but isn't an event
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return nullptr; return nullptr;
} }
HANDLE h = wibo::handles().alloc(std::move(sem), granted, hflags); HANDLE h = wibo::handles().alloc(std::move(sem), granted, hflags);
wibo::lastError = created ? ERROR_SUCCESS : ERROR_ALREADY_EXISTS; setLastError(created ? ERROR_SUCCESS : ERROR_ALREADY_EXISTS);
return h; return h;
} }
@@ -281,12 +281,12 @@ BOOL WIN_FUNC ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, PLONG lpPr
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("ReleaseSemaphore(%p, %ld, %p)\n", hSemaphore, lReleaseCount, lpPreviousCount); DEBUG_LOG("ReleaseSemaphore(%p, %ld, %p)\n", hSemaphore, lReleaseCount, lpPreviousCount);
if (lReleaseCount < 0) { if (lReleaseCount < 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
auto sem = wibo::handles().getAs<SemaphoreObject>(hSemaphore); auto sem = wibo::handles().getAs<SemaphoreObject>(hSemaphore);
if (!sem) { if (!sem) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@@ -298,7 +298,7 @@ BOOL WIN_FUNC ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, PLONG lpPr
prev = sem->count; prev = sem->count;
} }
if (sem->count > sem->maxCount - lReleaseCount) { if (sem->count > sem->maxCount - lReleaseCount) {
wibo::lastError = ERROR_TOO_MANY_POSTS; setLastError(ERROR_TOO_MANY_POSTS);
return FALSE; return FALSE;
} }
sem->count += lReleaseCount; sem->count += lReleaseCount;
@@ -323,7 +323,7 @@ BOOL WIN_FUNC SetEvent(HANDLE hEvent) {
DEBUG_LOG("SetEvent(%p)\n", hEvent); DEBUG_LOG("SetEvent(%p)\n", hEvent);
auto ev = wibo::handles().getAs<EventObject>(hEvent); auto ev = wibo::handles().getAs<EventObject>(hEvent);
if (!ev) { if (!ev) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
ev->set(); ev->set();
@@ -335,7 +335,7 @@ BOOL WIN_FUNC ResetEvent(HANDLE hEvent) {
DEBUG_LOG("ResetEvent(%p)\n", hEvent); DEBUG_LOG("ResetEvent(%p)\n", hEvent);
auto ev = wibo::handles().getAs<EventObject>(hEvent); auto ev = wibo::handles().getAs<EventObject>(hEvent);
if (!ev) { if (!ev) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
ev->reset(); ev->reset();
@@ -348,13 +348,13 @@ DWORD WIN_FUNC WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
HandleMeta meta{}; HandleMeta meta{};
Pin<> obj = wibo::handles().get(hHandle, &meta); Pin<> obj = wibo::handles().get(hHandle, &meta);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
DEBUG_LOG("-> ERROR_INVALID_HANDLE\n"); DEBUG_LOG("-> ERROR_INVALID_HANDLE\n");
return WAIT_FAILED; return WAIT_FAILED;
} }
#ifdef CHECK_ACCESS #ifdef CHECK_ACCESS
if ((meta.grantedAccess & SYNCHRONIZE) == 0) { if ((meta.grantedAccess & SYNCHRONIZE) == 0) {
wibo::lastError = ERROR_ACCESS_DENIED; setLastError(ERROR_ACCESS_DENIED);
DEBUG_LOG("!!! DENIED: 0x%x\n", meta.grantedAccess); DEBUG_LOG("!!! DENIED: 0x%x\n", meta.grantedAccess);
return WAIT_FAILED; return WAIT_FAILED;
} }
@@ -443,7 +443,7 @@ DWORD WIN_FUNC WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) {
return ok ? WAIT_OBJECT_0 : WAIT_TIMEOUT; return ok ? WAIT_OBJECT_0 : WAIT_TIMEOUT;
} }
default: default:
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return WAIT_FAILED; return WAIT_FAILED;
} }
} }
@@ -454,7 +454,7 @@ DWORD WIN_FUNC WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOO
dwMilliseconds); dwMilliseconds);
if (nCount == 0 || nCount > MAXIMUM_WAIT_OBJECTS || !lpHandles) { if (nCount == 0 || nCount > MAXIMUM_WAIT_OBJECTS || !lpHandles) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return WAIT_FAILED; return WAIT_FAILED;
} }
@@ -463,7 +463,7 @@ DWORD WIN_FUNC WaitForMultipleObjects(DWORD nCount, const HANDLE *lpHandles, BOO
HandleMeta meta{}; HandleMeta meta{};
auto obj = wibo::handles().getAs<WaitableObject>(lpHandles[i], &meta); auto obj = wibo::handles().getAs<WaitableObject>(lpHandles[i], &meta);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return WAIT_FAILED; return WAIT_FAILED;
} }
objects[i] = std::move(obj); objects[i] = std::move(obj);
@@ -556,11 +556,11 @@ BOOL WIN_FUNC InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection,
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("STUB: InitializeCriticalSectionEx(%p, %u, 0x%x)\n", lpCriticalSection, dwSpinCount, Flags); DEBUG_LOG("STUB: InitializeCriticalSectionEx(%p, %u, 0x%x)\n", lpCriticalSection, dwSpinCount, Flags);
if (!lpCriticalSection) { if (!lpCriticalSection) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (Flags & ~CRITICAL_SECTION_NO_DEBUG_INFO) { if (Flags & ~CRITICAL_SECTION_NO_DEBUG_INFO) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::memset(lpCriticalSection, 0, sizeof(*lpCriticalSection)); std::memset(lpCriticalSection, 0, sizeof(*lpCriticalSection));
@@ -572,7 +572,7 @@ BOOL WIN_FUNC InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpCritica
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("STUB: InitializeCriticalSectionAndSpinCount(%p, %u)\n", lpCriticalSection, dwSpinCount); DEBUG_LOG("STUB: InitializeCriticalSectionAndSpinCount(%p, %u)\n", lpCriticalSection, dwSpinCount);
if (!lpCriticalSection) { if (!lpCriticalSection) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::memset(lpCriticalSection, 0, sizeof(*lpCriticalSection)); std::memset(lpCriticalSection, 0, sizeof(*lpCriticalSection));
@@ -602,11 +602,11 @@ BOOL WIN_FUNC InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBO
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("STUB: InitOnceBeginInitialize(%p, %u, %p, %p)\n", lpInitOnce, dwFlags, fPending, lpContext); DEBUG_LOG("STUB: InitOnceBeginInitialize(%p, %u, %p, %p)\n", lpInitOnce, dwFlags, fPending, lpContext);
if (!lpInitOnce) { if (!lpInitOnce) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (dwFlags & ~(INIT_ONCE_CHECK_ONLY | INIT_ONCE_ASYNC)) { if (dwFlags & ~(INIT_ONCE_CHECK_ONLY | INIT_ONCE_ASYNC)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (fPending) { if (fPending) {
@@ -622,11 +622,11 @@ BOOL WIN_FUNC InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpC
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("STUB: InitOnceComplete(%p, %u, %p)\n", lpInitOnce, dwFlags, lpContext); DEBUG_LOG("STUB: InitOnceComplete(%p, %u, %p)\n", lpInitOnce, dwFlags, lpContext);
if (!lpInitOnce) { if (!lpInitOnce) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if ((dwFlags & INIT_ONCE_INIT_FAILED) && (dwFlags & INIT_ONCE_ASYNC)) { if ((dwFlags & INIT_ONCE_INIT_FAILED) && (dwFlags & INIT_ONCE_ASYNC)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
(void)lpContext; (void)lpContext;

View File

@@ -3,6 +3,7 @@
#include "common.h" #include "common.h"
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "internal.h"
#include "timeutil.h" #include "timeutil.h"
#include <cstring> #include <cstring>
@@ -194,7 +195,7 @@ BOOL WIN_FUNC GetVersionExA(LPOSVERSIONINFOA lpVersionInformation) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetVersionExA(%p)\n", lpVersionInformation); DEBUG_LOG("GetVersionExA(%p)\n", lpVersionInformation);
if (!lpVersionInformation) { if (!lpVersionInformation) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
std::memset(lpVersionInformation, 0, lpVersionInformation->dwOSVersionInfoSize); std::memset(lpVersionInformation, 0, lpVersionInformation->dwOSVersionInfoSize);

View File

@@ -2,6 +2,7 @@
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "internal.h"
#include "timeutil.h" #include "timeutil.h"
#include <cerrno> #include <cerrno>
@@ -14,22 +15,22 @@ BOOL WIN_FUNC SystemTimeToFileTime(const SYSTEMTIME *lpSystemTime, LPFILETIME lp
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SystemTimeToFileTime(%p, %p)\n", lpSystemTime, lpFileTime); DEBUG_LOG("SystemTimeToFileTime(%p, %p)\n", lpSystemTime, lpFileTime);
if (!lpSystemTime || !lpFileTime) { if (!lpSystemTime || !lpFileTime) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
int64_t seconds = 0; int64_t seconds = 0;
uint32_t hundreds = 0; uint32_t hundreds = 0;
if (!systemTimeToUnixParts(*lpSystemTime, seconds, hundreds)) { if (!systemTimeToUnixParts(*lpSystemTime, seconds, hundreds)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
FILETIME result; FILETIME result;
if (!unixPartsToFileTime(seconds, hundreds, result)) { if (!unixPartsToFileTime(seconds, hundreds, result)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (fileTimeToDuration(result) >= MAX_VALID_FILETIME) { if (fileTimeToDuration(result) >= MAX_VALID_FILETIME) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpFileTime = result; *lpFileTime = result;
@@ -40,12 +41,12 @@ BOOL WIN_FUNC FileTimeToSystemTime(const FILETIME *lpFileTime, LPSYSTEMTIME lpSy
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FileTimeToSystemTime(%p, %p)\n", lpFileTime, lpSystemTime); DEBUG_LOG("FileTimeToSystemTime(%p, %p)\n", lpFileTime, lpSystemTime);
if (!lpFileTime || !lpSystemTime) { if (!lpFileTime || !lpSystemTime) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
uint64_t ticks = fileTimeToDuration(*lpFileTime); uint64_t ticks = fileTimeToDuration(*lpFileTime);
if (ticks >= MAX_VALID_FILETIME) { if (ticks >= MAX_VALID_FILETIME) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
uint64_t daysSince1601 = ticks / TICKS_PER_DAY; uint64_t daysSince1601 = ticks / TICKS_PER_DAY;
@@ -69,45 +70,45 @@ BOOL WIN_FUNC FileTimeToLocalFileTime(const FILETIME *lpFileTime, LPFILETIME lpL
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FileTimeToLocalFileTime(%p, %p)\n", lpFileTime, lpLocalFileTime); DEBUG_LOG("FileTimeToLocalFileTime(%p, %p)\n", lpFileTime, lpLocalFileTime);
if (!lpFileTime || !lpLocalFileTime) { if (!lpFileTime || !lpLocalFileTime) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
int64_t seconds = 0; int64_t seconds = 0;
uint32_t hundreds = 0; uint32_t hundreds = 0;
if (!fileTimeToUnixParts(*lpFileTime, seconds, hundreds)) { if (!fileTimeToUnixParts(*lpFileTime, seconds, hundreds)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (seconds > static_cast<int64_t>(std::numeric_limits<time_t>::max()) || if (seconds > static_cast<int64_t>(std::numeric_limits<time_t>::max()) ||
seconds < static_cast<int64_t>(std::numeric_limits<time_t>::min())) { seconds < static_cast<int64_t>(std::numeric_limits<time_t>::min())) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
time_t unixTime = static_cast<time_t>(seconds); time_t unixTime = static_cast<time_t>(seconds);
struct tm localTm{}; struct tm localTm{};
#if defined(_POSIX_VERSION) #if defined(_POSIX_VERSION)
if (!localtime_r(&unixTime, &localTm)) { if (!localtime_r(&unixTime, &localTm)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
#else #else
struct tm *tmp = localtime(&unixTime); struct tm *tmp = localtime(&unixTime);
if (!tmp) { if (!tmp) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
localTm = *tmp; localTm = *tmp;
#endif #endif
int64_t localAsUtcSeconds = 0; int64_t localAsUtcSeconds = 0;
if (!tmToUnixSeconds(localTm, localAsUtcSeconds)) { if (!tmToUnixSeconds(localTm, localAsUtcSeconds)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
int64_t offsetSeconds = localAsUtcSeconds - seconds; int64_t offsetSeconds = localAsUtcSeconds - seconds;
int64_t localSeconds = seconds + offsetSeconds; int64_t localSeconds = seconds + offsetSeconds;
FILETIME result; FILETIME result;
if (!unixPartsToFileTime(localSeconds, hundreds, result)) { if (!unixPartsToFileTime(localSeconds, hundreds, result)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpLocalFileTime = result; *lpLocalFileTime = result;
@@ -118,12 +119,12 @@ BOOL WIN_FUNC LocalFileTimeToFileTime(const FILETIME *lpLocalFileTime, LPFILETIM
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("LocalFileTimeToFileTime(%p, %p)\n", lpLocalFileTime, lpFileTime); DEBUG_LOG("LocalFileTimeToFileTime(%p, %p)\n", lpLocalFileTime, lpFileTime);
if (!lpLocalFileTime || !lpFileTime) { if (!lpLocalFileTime || !lpFileTime) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
uint64_t ticks = fileTimeToDuration(*lpLocalFileTime); uint64_t ticks = fileTimeToDuration(*lpLocalFileTime);
if (ticks >= MAX_VALID_FILETIME) { if (ticks >= MAX_VALID_FILETIME) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
uint32_t hundredNs = static_cast<uint32_t>(ticks % HUNDRED_NS_PER_SECOND); uint32_t hundredNs = static_cast<uint32_t>(ticks % HUNDRED_NS_PER_SECOND);
@@ -144,12 +145,12 @@ BOOL WIN_FUNC LocalFileTimeToFileTime(const FILETIME *lpLocalFileTime, LPFILETIM
errno = 0; errno = 0;
time_t utcTime = mktime(&tmCopy); time_t utcTime = mktime(&tmCopy);
if (utcTime == static_cast<time_t>(-1) && errno != 0) { if (utcTime == static_cast<time_t>(-1) && errno != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
FILETIME result; FILETIME result;
if (!unixPartsToFileTime(static_cast<int64_t>(utcTime), hundredNs, result)) { if (!unixPartsToFileTime(static_cast<int64_t>(utcTime), hundredNs, result)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpFileTime = result; *lpFileTime = result;
@@ -160,7 +161,7 @@ BOOL WIN_FUNC DosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, LPFILETIME lpF
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("DosDateTimeToFileTime(%04x, %04x, %p)\n", wFatDate, wFatTime, lpFileTime); DEBUG_LOG("DosDateTimeToFileTime(%04x, %04x, %p)\n", wFatDate, wFatTime, lpFileTime);
if (!lpFileTime) { if (!lpFileTime) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
unsigned day = wFatDate & 0x1F; unsigned day = wFatDate & 0x1F;
@@ -170,7 +171,7 @@ BOOL WIN_FUNC DosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, LPFILETIME lpF
unsigned minute = (wFatTime >> 5) & 0x3F; unsigned minute = (wFatTime >> 5) & 0x3F;
unsigned hour = (wFatTime >> 11) & 0x1F; unsigned hour = (wFatTime >> 11) & 0x1F;
if (day == 0 || month == 0 || month > 12 || day > 31 || hour > 23 || minute > 59 || second > 59) { if (day == 0 || month == 0 || month > 12 || day > 31 || hour > 23 || minute > 59 || second > 59) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
struct tm tmValue{}; struct tm tmValue{};
@@ -183,7 +184,7 @@ BOOL WIN_FUNC DosDateTimeToFileTime(WORD wFatDate, WORD wFatTime, LPFILETIME lpF
tmValue.tm_isdst = -1; tmValue.tm_isdst = -1;
time_t localSeconds = mktime(&tmValue); time_t localSeconds = mktime(&tmValue);
if (localSeconds == static_cast<time_t>(-1)) { if (localSeconds == static_cast<time_t>(-1)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
uint64_t ticks = (static_cast<uint64_t>(localSeconds) + UNIX_TIME_ZERO / HUNDRED_NS_PER_SECOND) * 10000000ULL; uint64_t ticks = (static_cast<uint64_t>(localSeconds) + UNIX_TIME_ZERO / HUNDRED_NS_PER_SECOND) * 10000000ULL;
@@ -195,23 +196,23 @@ BOOL WIN_FUNC FileTimeToDosDateTime(const FILETIME *lpFileTime, LPWORD lpFatDate
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("FileTimeToDosDateTime(%p, %p, %p)\n", lpFileTime, lpFatDate, lpFatTime); DEBUG_LOG("FileTimeToDosDateTime(%p, %p, %p)\n", lpFileTime, lpFatDate, lpFatTime);
if (!lpFileTime || !lpFatDate || !lpFatTime) { if (!lpFileTime || !lpFatDate || !lpFatTime) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
uint64_t ticks = fileTimeToDuration(*lpFileTime); uint64_t ticks = fileTimeToDuration(*lpFileTime);
if (ticks < UNIX_TIME_ZERO) { if (ticks < UNIX_TIME_ZERO) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
time_t utcSeconds = static_cast<time_t>((ticks / 10000000ULL) - (UNIX_TIME_ZERO / HUNDRED_NS_PER_SECOND)); time_t utcSeconds = static_cast<time_t>((ticks / 10000000ULL) - (UNIX_TIME_ZERO / HUNDRED_NS_PER_SECOND));
struct tm tmValue{}; struct tm tmValue{};
if (!localtime_r(&utcSeconds, &tmValue)) { if (!localtime_r(&utcSeconds, &tmValue)) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
int year = tmValue.tm_year + 1900; int year = tmValue.tm_year + 1900;
if (year < 1980 || year > 2107) { if (year < 1980 || year > 2107) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
*lpFatDate = static_cast<WORD>(((year - 1980) << 9) | ((tmValue.tm_mon + 1) << 5) | tmValue.tm_mday); *lpFatDate = static_cast<WORD>(((year - 1980) << 9) | ((tmValue.tm_mon + 1) << 5) | tmValue.tm_mday);
@@ -224,7 +225,7 @@ DWORD WIN_FUNC GetTimeZoneInformation(LPTIME_ZONE_INFORMATION lpTimeZoneInformat
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetTimeZoneInformation(%p)\n", lpTimeZoneInformation); DEBUG_LOG("GetTimeZoneInformation(%p)\n", lpTimeZoneInformation);
if (!lpTimeZoneInformation) { if (!lpTimeZoneInformation) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return TIME_ZONE_ID_INVALID; return TIME_ZONE_ID_INVALID;
} }
std::memset(lpTimeZoneInformation, 0, sizeof(*lpTimeZoneInformation)); std::memset(lpTimeZoneInformation, 0, sizeof(*lpTimeZoneInformation));

View File

@@ -83,7 +83,7 @@ bool tryHandleIntegerAtomPointer(const void *ptr, ATOM &atomOut) {
} }
ATOM maybeAtom = static_cast<ATOM>(value & 0xFFFFu); ATOM maybeAtom = static_cast<ATOM>(value & 0xFFFFu);
if (maybeAtom < kMinIntegerAtom || maybeAtom > kMaxIntegerAtom) { if (maybeAtom < kMinIntegerAtom || maybeAtom > kMaxIntegerAtom) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
atomOut = 0; atomOut = 0;
return true; return true;
} }
@@ -96,7 +96,7 @@ ATOM findAtomByNormalizedKey(const std::string &normalizedKey) {
std::lock_guard lk(table.mutex); std::lock_guard lk(table.mutex);
auto it = table.stringToAtom.find(normalizedKey); auto it = table.stringToAtom.find(normalizedKey);
if (it == table.stringToAtom.end()) { if (it == table.stringToAtom.end()) {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return 0; return 0;
} }
return it->second; return it->second;
@@ -114,7 +114,7 @@ ATOM tryParseIntegerAtomString(const std::string &value, bool &handled) {
} }
handled = true; handled = true;
if (parsed < kMinIntegerAtom || parsed > kMaxIntegerAtom) { if (parsed < kMinIntegerAtom || parsed > kMaxIntegerAtom) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
return static_cast<ATOM>(parsed); return static_cast<ATOM>(parsed);
@@ -137,7 +137,7 @@ ATOM addAtomByString(const std::string &value) {
return atom; return atom;
} }
if (value.empty() || value.size() > 255) { if (value.empty() || value.size() > 255) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string normalized = stringToLower(value); std::string normalized = stringToLower(value);
@@ -153,7 +153,7 @@ ATOM addAtomByString(const std::string &value) {
} }
ATOM newAtom = allocateStringAtomLocked(table); ATOM newAtom = allocateStringAtomLocked(table);
if (newAtom == 0) { if (newAtom == 0) {
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; kernel32::setLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0; return 0;
} }
AtomData data; AtomData data;
@@ -192,7 +192,7 @@ bool tryGetCurrentDirectoryPath(std::string &outPath) {
std::error_code ec; std::error_code ec;
std::filesystem::path cwd = std::filesystem::current_path(ec); std::filesystem::path cwd = std::filesystem::current_path(ec);
if (ec) { if (ec) {
wibo::lastError = wibo::winErrorFromErrno(ec.value()); kernel32::setLastError(wibo::winErrorFromErrno(ec.value()));
return false; return false;
} }
outPath = files::pathToWindows(cwd); outPath = files::pathToWindows(cwd);
@@ -208,13 +208,13 @@ bool computeLongWindowsPath(const std::string &inputPath, std::string &longPath)
auto hostPath = files::pathFromWindows(inputPath.c_str()); auto hostPath = files::pathFromWindows(inputPath.c_str());
if (hostPath.empty()) { if (hostPath.empty()) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return false; return false;
} }
std::error_code ec; std::error_code ec;
if (!std::filesystem::exists(hostPath, ec)) { if (!std::filesystem::exists(hostPath, ec)) {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return false; return false;
} }
@@ -233,12 +233,12 @@ bool resolveDiskFreeSpaceStat(const char *rootPathName, struct statvfs &outBuf,
std::error_code ec; std::error_code ec;
hostPath = std::filesystem::current_path(ec); hostPath = std::filesystem::current_path(ec);
if (ec) { if (ec) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return false; return false;
} }
} }
if (hostPath.empty()) { if (hostPath.empty()) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return false; return false;
} }
@@ -251,7 +251,7 @@ bool resolveDiskFreeSpaceStat(const char *rootPathName, struct statvfs &outBuf,
if (!hostPath.is_absolute()) { if (!hostPath.is_absolute()) {
auto abs = std::filesystem::absolute(hostPath, ec); auto abs = std::filesystem::absolute(hostPath, ec);
if (ec) { if (ec) {
wibo::lastError = ERROR_PATH_NOT_FOUND; kernel32::setLastError(ERROR_PATH_NOT_FOUND);
return false; return false;
} }
hostPath = abs; hostPath = abs;
@@ -270,13 +270,13 @@ bool resolveDiskFreeSpaceStat(const char *rootPathName, struct statvfs &outBuf,
int savedErrno = errno; int savedErrno = errno;
if (savedErrno != ENOENT && savedErrno != ENOTDIR) { if (savedErrno != ENOENT && savedErrno != ENOTDIR) {
wibo::lastError = wibo::winErrorFromErrno(savedErrno); kernel32::setLastError(wibo::winErrorFromErrno(savedErrno));
return false; return false;
} }
std::filesystem::path parent = queryPath.parent_path(); std::filesystem::path parent = queryPath.parent_path();
if (parent == queryPath) { if (parent == queryPath) {
wibo::lastError = wibo::winErrorFromErrno(savedErrno); kernel32::setLastError(wibo::winErrorFromErrno(savedErrno));
return false; return false;
} }
if (parent.empty()) { if (parent.empty()) {
@@ -342,17 +342,17 @@ ATOM WIN_FUNC AddAtomA(LPCSTR lpString) {
} }
DEBUG_LOG("AddAtomA(%s)\n", lpString ? lpString : "<null>"); DEBUG_LOG("AddAtomA(%s)\n", lpString ? lpString : "<null>");
if (!lpString) { if (!lpString) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
size_t len = strnlen(lpString, 256); size_t len = strnlen(lpString, 256);
if (len == 0 || len >= 256) { if (len == 0 || len >= 256) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string value(lpString, len); std::string value(lpString, len);
ATOM result = addAtomByString(value); ATOM result = addAtomByString(value);
DEBUG_LOG("AddAtomA -> %u (lastError=%u)\n", result, wibo::lastError); DEBUG_LOG("AddAtomA -> %u (lastError=%u)\n", result, getLastError());
return result; return result;
} }
@@ -365,19 +365,19 @@ ATOM WIN_FUNC AddAtomW(LPCWSTR lpString) {
} }
if (!lpString) { if (!lpString) {
DEBUG_LOG("AddAtomW(<null>)\n"); DEBUG_LOG("AddAtomW(<null>)\n");
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
size_t len = wstrnlen(reinterpret_cast<const uint16_t *>(lpString), 256); size_t len = wstrnlen(reinterpret_cast<const uint16_t *>(lpString), 256);
if (len == 0 || len >= 256) { if (len == 0 || len >= 256) {
DEBUG_LOG("AddAtomW(invalid length)\n"); DEBUG_LOG("AddAtomW(invalid length)\n");
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string value = wideStringToString(reinterpret_cast<const uint16_t *>(lpString), static_cast<int>(len)); std::string value = wideStringToString(reinterpret_cast<const uint16_t *>(lpString), static_cast<int>(len));
DEBUG_LOG("AddAtomW(%s)\n", value.c_str()); DEBUG_LOG("AddAtomW(%s)\n", value.c_str());
ATOM result = addAtomByString(value); ATOM result = addAtomByString(value);
DEBUG_LOG("AddAtomW -> %u (lastError=%u)\n", result, wibo::lastError); DEBUG_LOG("AddAtomW -> %u (lastError=%u)\n", result, getLastError());
return result; return result;
} }
@@ -390,17 +390,17 @@ ATOM WIN_FUNC FindAtomA(LPCSTR lpString) {
} }
DEBUG_LOG("FindAtomA(%s)\n", lpString ? lpString : "<null>"); DEBUG_LOG("FindAtomA(%s)\n", lpString ? lpString : "<null>");
if (!lpString) { if (!lpString) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
size_t len = strnlen(lpString, 256); size_t len = strnlen(lpString, 256);
if (len == 0 || len >= 256) { if (len == 0 || len >= 256) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string value(lpString, len); std::string value(lpString, len);
ATOM result = findAtomByString(value); ATOM result = findAtomByString(value);
DEBUG_LOG("FindAtomA -> %u (lastError=%u)\n", result, wibo::lastError); DEBUG_LOG("FindAtomA -> %u (lastError=%u)\n", result, getLastError());
return result; return result;
} }
@@ -413,19 +413,19 @@ ATOM WIN_FUNC FindAtomW(LPCWSTR lpString) {
} }
if (!lpString) { if (!lpString) {
DEBUG_LOG("FindAtomW(<null>)\n"); DEBUG_LOG("FindAtomW(<null>)\n");
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
size_t len = wstrnlen(reinterpret_cast<const uint16_t *>(lpString), 256); size_t len = wstrnlen(reinterpret_cast<const uint16_t *>(lpString), 256);
if (len == 0 || len >= 256) { if (len == 0 || len >= 256) {
DEBUG_LOG("FindAtomW(invalid length)\n"); DEBUG_LOG("FindAtomW(invalid length)\n");
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string value = wideStringToString(reinterpret_cast<const uint16_t *>(lpString), static_cast<int>(len)); std::string value = wideStringToString(reinterpret_cast<const uint16_t *>(lpString), static_cast<int>(len));
DEBUG_LOG("FindAtomW(%s)\n", value.c_str()); DEBUG_LOG("FindAtomW(%s)\n", value.c_str());
ATOM result = findAtomByString(value); ATOM result = findAtomByString(value);
DEBUG_LOG("FindAtomW -> %u (lastError=%u)\n", result, wibo::lastError); DEBUG_LOG("FindAtomW -> %u (lastError=%u)\n", result, getLastError());
return result; return result;
} }
@@ -433,7 +433,7 @@ UINT WIN_FUNC GetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetAtomNameA(%u, %p, %d)\n", nAtom, lpBuffer, nSize); DEBUG_LOG("GetAtomNameA(%u, %p, %d)\n", nAtom, lpBuffer, nSize);
if (!lpBuffer || nSize <= 0) { if (!lpBuffer || nSize <= 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string value; std::string value;
@@ -445,19 +445,19 @@ UINT WIN_FUNC GetAtomNameA(ATOM nAtom, LPSTR lpBuffer, int nSize) {
std::lock_guard lk(table.mutex); std::lock_guard lk(table.mutex);
auto it = table.atomToData.find(nAtom); auto it = table.atomToData.find(nAtom);
if (it == table.atomToData.end()) { if (it == table.atomToData.end()) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
value = it->second.original; value = it->second.original;
} }
if (value.size() + 1 > static_cast<size_t>(nSize)) { if (value.size() + 1 > static_cast<size_t>(nSize)) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
std::memcpy(lpBuffer, value.c_str(), value.size()); std::memcpy(lpBuffer, value.c_str(), value.size());
lpBuffer[value.size()] = '\0'; lpBuffer[value.size()] = '\0';
UINT written = static_cast<UINT>(value.size()); UINT written = static_cast<UINT>(value.size());
DEBUG_LOG("GetAtomNameA -> %u (lastError=%u)\n", written, wibo::lastError); DEBUG_LOG("GetAtomNameA -> %u (lastError=%u)\n", written, getLastError());
return written; return written;
} }
@@ -465,7 +465,7 @@ UINT WIN_FUNC GetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetAtomNameW(%u, %p, %d)\n", nAtom, lpBuffer, nSize); DEBUG_LOG("GetAtomNameW(%u, %p, %d)\n", nAtom, lpBuffer, nSize);
if (!lpBuffer || nSize <= 0) { if (!lpBuffer || nSize <= 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string narrow; std::string narrow;
@@ -477,7 +477,7 @@ UINT WIN_FUNC GetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize) {
std::lock_guard lk(table.mutex); std::lock_guard lk(table.mutex);
auto it = table.atomToData.find(nAtom); auto it = table.atomToData.find(nAtom);
if (it == table.atomToData.end()) { if (it == table.atomToData.end()) {
wibo::lastError = ERROR_INVALID_HANDLE; kernel32::setLastError(ERROR_INVALID_HANDLE);
return 0; return 0;
} }
narrow = it->second.original; narrow = it->second.original;
@@ -485,7 +485,7 @@ UINT WIN_FUNC GetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize) {
auto wide = stringToWideString(narrow.c_str(), narrow.size()); auto wide = stringToWideString(narrow.c_str(), narrow.size());
size_t needed = wide.size(); size_t needed = wide.size();
if (needed > static_cast<size_t>(nSize)) { if (needed > static_cast<size_t>(nSize)) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
std::memcpy(lpBuffer, wide.data(), needed * sizeof(uint16_t)); std::memcpy(lpBuffer, wide.data(), needed * sizeof(uint16_t));
@@ -493,7 +493,7 @@ UINT WIN_FUNC GetAtomNameW(ATOM nAtom, LPWSTR lpBuffer, int nSize) {
lpBuffer[needed - 1] = 0; lpBuffer[needed - 1] = 0;
} }
UINT written = static_cast<UINT>(needed ? needed - 1 : 0); UINT written = static_cast<UINT>(needed ? needed - 1 : 0);
DEBUG_LOG("GetAtomNameW -> %u (lastError=%u)\n", written, wibo::lastError); DEBUG_LOG("GetAtomNameW -> %u (lastError=%u)\n", written, getLastError());
return written; return written;
} }
@@ -523,7 +523,7 @@ DWORD WIN_FUNC FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId
std::string message = std::system_category().message(static_cast<int>(dwMessageId)); std::string message = std::system_category().message(static_cast<int>(dwMessageId));
size_t length = message.length(); size_t length = message.length();
if (!lpBuffer || nSize == 0) { if (!lpBuffer || nSize == 0) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
std::strncpy(lpBuffer, message.c_str(), static_cast<size_t>(nSize)); std::strncpy(lpBuffer, message.c_str(), static_cast<size_t>(nSize));
@@ -531,7 +531,7 @@ DWORD WIN_FUNC FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId
if (static_cast<size_t>(nSize) > 0) { if (static_cast<size_t>(nSize) > 0) {
lpBuffer[nSize - 1] = '\0'; lpBuffer[nSize - 1] = '\0';
} }
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
lpBuffer[length] = '\0'; lpBuffer[length] = '\0';
@@ -545,7 +545,7 @@ DWORD WIN_FUNC FormatMessageA(DWORD dwFlags, LPCVOID lpSource, DWORD dwMessageId
if (lpBuffer && nSize > 0) { if (lpBuffer && nSize > 0) {
lpBuffer[0] = '\0'; lpBuffer[0] = '\0';
} }
wibo::lastError = ERROR_CALL_NOT_IMPLEMENTED; setLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0; return 0;
} }
@@ -571,7 +571,7 @@ BOOL WIN_FUNC SetDllDirectoryA(LPCSTR lpPathName) {
std::filesystem::path hostPath = files::pathFromWindows(lpPathName); std::filesystem::path hostPath = files::pathFromWindows(lpPathName);
if (hostPath.empty() || !std::filesystem::exists(hostPath)) { if (hostPath.empty() || !std::filesystem::exists(hostPath)) {
wibo::lastError = ERROR_PATH_NOT_FOUND; setLastError(ERROR_PATH_NOT_FOUND);
return FALSE; return FALSE;
} }
@@ -603,23 +603,23 @@ BOOL WIN_FUNC FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtensionGui
ReturnedData); ReturnedData);
if (lpExtensionGuid) { if (lpExtensionGuid) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (!ReturnedData) { if (!ReturnedData) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (dwFlags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) { if (dwFlags & ~FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
ULONG originalSize = ReturnedData->cbSize; ULONG originalSize = ReturnedData->cbSize;
if (originalSize < sizeof(ACTCTX_SECTION_KEYED_DATA)) { if (originalSize < sizeof(ACTCTX_SECTION_KEYED_DATA)) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE; return FALSE;
} }
@@ -646,7 +646,7 @@ BOOL WIN_FUNC FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtensionGui
} }
if (!matchedEntry) { if (!matchedEntry) {
wibo::lastError = ERROR_SXS_KEY_NOT_FOUND; setLastError(ERROR_SXS_KEY_NOT_FOUND);
return FALSE; return FALSE;
} }
@@ -707,13 +707,13 @@ BOOL WIN_FUNC GetComputerNameA(LPSTR lpBuffer, LPDWORD nSize) {
if (nSize) { if (nSize) {
*nSize = 0; *nSize = 0;
} }
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (*nSize < kComputerNameRequiredSize) { if (*nSize < kComputerNameRequiredSize) {
*nSize = kComputerNameRequiredSize; *nSize = kComputerNameRequiredSize;
wibo::lastError = ERROR_BUFFER_OVERFLOW; setLastError(ERROR_BUFFER_OVERFLOW);
return FALSE; return FALSE;
} }
@@ -729,13 +729,13 @@ BOOL WIN_FUNC GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize) {
if (nSize) { if (nSize) {
*nSize = 0; *nSize = 0;
} }
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (*nSize < kComputerNameRequiredSize) { if (*nSize < kComputerNameRequiredSize) {
*nSize = kComputerNameRequiredSize; *nSize = kComputerNameRequiredSize;
wibo::lastError = ERROR_BUFFER_OVERFLOW; setLastError(ERROR_BUFFER_OVERFLOW);
return FALSE; return FALSE;
} }
@@ -790,7 +790,7 @@ HLOCAL WIN_FUNC LocalAlloc(UINT uFlags, SIZE_T uBytes) {
} }
void *result = doAlloc(static_cast<UINT>(uBytes), zero); void *result = doAlloc(static_cast<UINT>(uBytes), zero);
if (!result) { if (!result) {
wibo::lastError = ERROR_NOT_SUPPORTED; setLastError(ERROR_NOT_SUPPORTED);
return nullptr; return nullptr;
} }
// Legacy Windows applications (pre-NX and DEP) may expect executable memory from LocalAlloc. // Legacy Windows applications (pre-NX and DEP) may expect executable memory from LocalAlloc.
@@ -816,7 +816,7 @@ HLOCAL WIN_FUNC LocalReAlloc(HLOCAL hMem, SIZE_T uBytes, UINT uFlags) {
} }
void *result = doRealloc(hMem, static_cast<UINT>(uBytes), zero); void *result = doRealloc(hMem, static_cast<UINT>(uBytes), zero);
if (!result && uBytes != 0) { if (!result && uBytes != 0) {
wibo::lastError = ERROR_NOT_SUPPORTED; setLastError(ERROR_NOT_SUPPORTED);
return nullptr; return nullptr;
} }
// Legacy Windows applications (pre-NX and DEP) may expect executable memory from LocalReAlloc. // Legacy Windows applications (pre-NX and DEP) may expect executable memory from LocalReAlloc.
@@ -895,7 +895,7 @@ UINT WIN_FUNC GetSystemWow64DirectoryA(LPSTR lpBuffer, UINT uSize) {
DEBUG_LOG("GetSystemWow64DirectoryA(%p, %u)\n", lpBuffer, uSize); DEBUG_LOG("GetSystemWow64DirectoryA(%p, %u)\n", lpBuffer, uSize);
(void)lpBuffer; (void)lpBuffer;
(void)uSize; (void)uSize;
wibo::lastError = ERROR_CALL_NOT_IMPLEMENTED; setLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0; return 0;
} }
@@ -904,7 +904,7 @@ UINT WIN_FUNC GetSystemWow64DirectoryW(LPWSTR lpBuffer, UINT uSize) {
DEBUG_LOG("GetSystemWow64DirectoryW(%p, %u)\n", lpBuffer, uSize); DEBUG_LOG("GetSystemWow64DirectoryW(%p, %u)\n", lpBuffer, uSize);
(void)lpBuffer; (void)lpBuffer;
(void)uSize; (void)uSize;
wibo::lastError = ERROR_CALL_NOT_IMPLEMENTED; setLastError(ERROR_CALL_NOT_IMPLEMENTED);
return 0; return 0;
} }
@@ -959,11 +959,11 @@ DWORD WIN_FUNC GetCurrentDirectoryA(DWORD nBufferLength, LPSTR lpBuffer) {
return required; return required;
} }
if (!lpBuffer) { if (!lpBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (nBufferLength < required) { if (nBufferLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
std::memcpy(lpBuffer, path.c_str(), required); std::memcpy(lpBuffer, path.c_str(), required);
@@ -984,11 +984,11 @@ DWORD WIN_FUNC GetCurrentDirectoryW(DWORD nBufferLength, LPWSTR lpBuffer) {
return required; return required;
} }
if (!lpBuffer) { if (!lpBuffer) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (nBufferLength < required) { if (nBufferLength < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
std::copy(widePath.begin(), widePath.end(), lpBuffer); std::copy(widePath.begin(), widePath.end(), lpBuffer);
@@ -999,14 +999,14 @@ int WIN_FUNC SetCurrentDirectoryA(LPCSTR lpPathName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SetCurrentDirectoryA(%s)\n", lpPathName ? lpPathName : "(null)"); DEBUG_LOG("SetCurrentDirectoryA(%s)\n", lpPathName ? lpPathName : "(null)");
if (!lpPathName) { if (!lpPathName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
auto hostPath = files::pathFromWindows(lpPathName); auto hostPath = files::pathFromWindows(lpPathName);
std::error_code ec; std::error_code ec;
std::filesystem::current_path(hostPath, ec); std::filesystem::current_path(hostPath, ec);
if (ec) { if (ec) {
wibo::lastError = wibo::winErrorFromErrno(ec.value()); setLastError(wibo::winErrorFromErrno(ec.value()));
return 0; return 0;
} }
return 1; return 1;
@@ -1016,7 +1016,7 @@ int WIN_FUNC SetCurrentDirectoryW(LPCWSTR lpPathName) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("SetCurrentDirectoryW\n"); DEBUG_LOG("SetCurrentDirectoryW\n");
if (!lpPathName) { if (!lpPathName) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string path = wideStringToString(lpPathName); std::string path = wideStringToString(lpPathName);
@@ -1027,7 +1027,7 @@ DWORD WIN_FUNC GetLongPathNameA(LPCSTR lpszShortPath, LPSTR lpszLongPath, DWORD
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetLongPathNameA(%s, %p, %u)\n", lpszShortPath ? lpszShortPath : "(null)", lpszLongPath, cchBuffer); DEBUG_LOG("GetLongPathNameA(%s, %p, %u)\n", lpszShortPath ? lpszShortPath : "(null)", lpszLongPath, cchBuffer);
if (!lpszShortPath) { if (!lpszShortPath) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -1042,11 +1042,11 @@ DWORD WIN_FUNC GetLongPathNameA(LPCSTR lpszShortPath, LPSTR lpszLongPath, DWORD
return required; return required;
} }
if (!lpszLongPath) { if (!lpszLongPath) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (cchBuffer < required) { if (cchBuffer < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
std::memcpy(lpszLongPath, longPath.c_str(), required); std::memcpy(lpszLongPath, longPath.c_str(), required);
@@ -1057,7 +1057,7 @@ DWORD WIN_FUNC GetLongPathNameW(LPCWSTR lpszShortPath, LPWSTR lpszLongPath, DWOR
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("GetLongPathNameW(%p, %p, %u)\n", lpszShortPath, lpszLongPath, cchBuffer); DEBUG_LOG("GetLongPathNameW(%p, %p, %u)\n", lpszShortPath, lpszLongPath, cchBuffer);
if (!lpszShortPath) { if (!lpszShortPath) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
std::string input = wideStringToString(lpszShortPath); std::string input = wideStringToString(lpszShortPath);
@@ -1071,11 +1071,11 @@ DWORD WIN_FUNC GetLongPathNameW(LPCWSTR lpszShortPath, LPWSTR lpszLongPath, DWOR
return required; return required;
} }
if (!lpszLongPath) { if (!lpszLongPath) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (cchBuffer < required) { if (cchBuffer < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return required; return required;
} }
std::copy(wideLong.begin(), wideLong.end(), lpszLongPath); std::copy(wideLong.begin(), wideLong.end(), lpszLongPath);

View File

@@ -77,9 +77,9 @@ PVOID WIN_FUNC DecodePointer(PVOID Ptr);
BOOL WIN_FUNC SetDllDirectoryA(LPCSTR lpPathName); BOOL WIN_FUNC SetDllDirectoryA(LPCSTR lpPathName);
BOOL WIN_FUNC FindActCtxSectionStringA(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId, BOOL WIN_FUNC FindActCtxSectionStringA(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId,
LPCSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData); LPCSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData);
BOOL WIN_FUNC FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId, BOOL WIN_FUNC FindActCtxSectionStringW(DWORD dwFlags, const GUID *lpExtensionGuid, ULONG ulSectionId,
LPCWSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData); LPCWSTR lpStringToFind, PACTCTX_SECTION_KEYED_DATA ReturnedData);
BOOL WIN_FUNC GetComputerNameA(LPSTR lpBuffer, LPDWORD nSize); BOOL WIN_FUNC GetComputerNameA(LPSTR lpBuffer, LPDWORD nSize);
BOOL WIN_FUNC GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize); BOOL WIN_FUNC GetComputerNameW(LPWSTR lpBuffer, LPDWORD nSize);

View File

@@ -50,7 +50,7 @@ BOOL WIN_FUNC GetConsoleScreenBufferInfo(HANDLE hConsoleOutput, CONSOLE_SCREEN_B
DEBUG_LOG("STUB: GetConsoleScreenBufferInfo(%p, %p)\n", hConsoleOutput, lpConsoleScreenBufferInfo); DEBUG_LOG("STUB: GetConsoleScreenBufferInfo(%p, %p)\n", hConsoleOutput, lpConsoleScreenBufferInfo);
(void)hConsoleOutput; (void)hConsoleOutput;
if (!lpConsoleScreenBufferInfo) { if (!lpConsoleScreenBufferInfo) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
lpConsoleScreenBufferInfo->dwSize = {80, 25}; lpConsoleScreenBufferInfo->dwSize = {80, 25};
@@ -71,7 +71,7 @@ BOOL WIN_FUNC WriteConsoleW(HANDLE hConsoleOutput, LPCVOID lpBuffer, DWORD nNumb
*lpNumberOfCharsWritten = 0; *lpNumberOfCharsWritten = 0;
} }
if (!lpBuffer && nNumberOfCharsToWrite != 0) { if (!lpBuffer && nNumberOfCharsToWrite != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -85,7 +85,7 @@ BOOL WIN_FUNC WriteConsoleW(HANDLE hConsoleOutput, LPCVOID lpBuffer, DWORD nNumb
return TRUE; return TRUE;
} }
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
@@ -95,7 +95,7 @@ DWORD WIN_FUNC GetConsoleTitleA(LPSTR lpConsoleTitle, DWORD nSize) {
if (lpConsoleTitle && nSize > 0) { if (lpConsoleTitle && nSize > 0) {
lpConsoleTitle[0] = '\0'; lpConsoleTitle[0] = '\0';
} }
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
return 0; return 0;
} }
@@ -105,7 +105,7 @@ DWORD WIN_FUNC GetConsoleTitleW(LPWSTR lpConsoleTitle, DWORD nSize) {
if (lpConsoleTitle && nSize > 0) { if (lpConsoleTitle && nSize > 0) {
lpConsoleTitle[0] = 0; lpConsoleTitle[0] = 0;
} }
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
return 0; return 0;
} }

View File

@@ -2,6 +2,7 @@
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "internal.h"
#include "strutil.h" #include "strutil.h"
#include <algorithm> #include <algorithm>
@@ -106,7 +107,7 @@ BOOL WIN_FUNC GetCPInfo(UINT CodePage, LPCPINFO lpCPInfo) {
(void)CodePage; (void)CodePage;
if (!lpCPInfo) { if (!lpCPInfo) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
@@ -124,7 +125,7 @@ int WIN_FUNC CompareStringA(LCID Locale, DWORD dwCmpFlags, LPCSTR lpString1, int
cchCount1, lpString2 ? lpString2 : "(null)", cchCount2); cchCount1, lpString2 ? lpString2 : "(null)", cchCount2);
(void)Locale; (void)Locale;
if (!lpString1 || !lpString2) { if (!lpString1 || !lpString2) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -147,7 +148,7 @@ int WIN_FUNC CompareStringW(LCID Locale, DWORD dwCmpFlags, LPCWCH lpString1, int
cchCount2); cchCount2);
(void)Locale; (void)Locale;
if (!lpString1 || !lpString2) { if (!lpString1 || !lpString2) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -168,7 +169,7 @@ BOOL WIN_FUNC IsValidLocale(LCID Locale, DWORD dwFlags) {
DEBUG_LOG("IsValidLocale(%u, 0x%x)\n", Locale, dwFlags); DEBUG_LOG("IsValidLocale(%u, 0x%x)\n", Locale, dwFlags);
(void)Locale; (void)Locale;
if (dwFlags != 0 && (dwFlags & ~(LCID_INSTALLED | LCID_SUPPORTED | LCID_ALTERNATE_SORTS)) != 0) { if (dwFlags != 0 && (dwFlags & ~(LCID_INSTALLED | LCID_SUPPORTED | LCID_ALTERNATE_SORTS)) != 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
@@ -186,11 +187,11 @@ int WIN_FUNC GetLocaleInfoA(LCID Locale, LCTYPE LCType, LPSTR lpLCData, int cchD
return static_cast<int>(required); return static_cast<int>(required);
} }
if (!lpLCData || cchData < 0) { if (!lpLCData || cchData < 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (static_cast<size_t>(cchData) < required) { if (static_cast<size_t>(cchData) < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
@@ -211,11 +212,11 @@ int WIN_FUNC GetLocaleInfoW(LCID Locale, LCTYPE LCType, LPWSTR lpLCData, int cch
return static_cast<int>(required); return static_cast<int>(required);
} }
if (!lpLCData || cchData < 0) { if (!lpLCData || cchData < 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
if (static_cast<size_t>(cchData) < required) { if (static_cast<size_t>(cchData) < required) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
@@ -224,16 +225,18 @@ int WIN_FUNC GetLocaleInfoW(LCID Locale, LCTYPE LCType, LPWSTR lpLCData, int cch
} }
BOOL WIN_FUNC EnumSystemLocalesA(LOCALE_ENUMPROCA lpLocaleEnumProc, DWORD dwFlags) { BOOL WIN_FUNC EnumSystemLocalesA(LOCALE_ENUMPROCA lpLocaleEnumProc, DWORD dwFlags) {
HOST_CONTEXT_GUARD(); {
DEBUG_LOG("EnumSystemLocalesA(%p, 0x%x)\n", lpLocaleEnumProc, dwFlags); HOST_CONTEXT_GUARD();
(void)dwFlags; DEBUG_LOG("EnumSystemLocalesA(%p, 0x%x)\n", lpLocaleEnumProc, dwFlags);
if (!lpLocaleEnumProc) { (void)dwFlags;
wibo::lastError = ERROR_INVALID_PARAMETER; if (!lpLocaleEnumProc) {
return FALSE; setLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
} }
// Return to guest context before callback
char localeId[] = "00000409"; // en-US char localeId[] = "00000409"; // en-US
BOOL callbackResult = lpLocaleEnumProc(localeId); return lpLocaleEnumProc(localeId);
return callbackResult;
} }
LCID WIN_FUNC GetUserDefaultLCID() { LCID WIN_FUNC GetUserDefaultLCID() {
@@ -262,7 +265,7 @@ BOOL WIN_FUNC IsDBCSLeadByteEx(UINT CodePage, BYTE TestChar) {
return FALSE; return FALSE;
}; };
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
switch (CodePage) { switch (CodePage) {
case 932: // Shift-JIS case 932: // Shift-JIS
return inRanges({{0x81, 0x9F}, {0xE0, 0xFC}}); return inRanges({{0x81, 0x9F}, {0xE0, 0xFC}});
@@ -285,14 +288,14 @@ int WIN_FUNC LCMapStringW(LCID Locale, DWORD dwMapFlags, LPCWCH lpSrcStr, int cc
DEBUG_LOG("LCMapStringW(%u, 0x%x, %p, %d, %p, %d)\n", Locale, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest); DEBUG_LOG("LCMapStringW(%u, 0x%x, %p, %d, %p, %d)\n", Locale, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest);
(void)Locale; (void)Locale;
if (!lpSrcStr || cchSrc == 0) { if (!lpSrcStr || cchSrc == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
bool nullTerminated = cchSrc < 0; bool nullTerminated = cchSrc < 0;
size_t srcLen = nullTerminated ? (wstrlen(lpSrcStr) + 1) : static_cast<size_t>(cchSrc); size_t srcLen = nullTerminated ? (wstrlen(lpSrcStr) + 1) : static_cast<size_t>(cchSrc);
if (srcLen == 0) { if (srcLen == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -300,13 +303,13 @@ int WIN_FUNC LCMapStringW(LCID Locale, DWORD dwMapFlags, LPCWCH lpSrcStr, int cc
return static_cast<int>(srcLen); return static_cast<int>(srcLen);
} }
if (cchDest < static_cast<int>(srcLen)) { if (cchDest < static_cast<int>(srcLen)) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
if (dwMapFlags & (0x00000400u | 0x00000800u)) { // LCMAP_SORTKEY | LCMAP_BYTEREV if (dwMapFlags & (0x00000400u | 0x00000800u)) { // LCMAP_SORTKEY | LCMAP_BYTEREV
DEBUG_LOG("LCMapStringW: unsupported mapping flags 0x%x\n", dwMapFlags); DEBUG_LOG("LCMapStringW: unsupported mapping flags 0x%x\n", dwMapFlags);
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -331,7 +334,7 @@ int WIN_FUNC LCMapStringA(LCID Locale, DWORD dwMapFlags, LPCCH lpSrcStr, int cch
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("LCMapStringA(%u, 0x%x, %p, %d, %p, %d)\n", Locale, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest); DEBUG_LOG("LCMapStringA(%u, 0x%x, %p, %d, %p, %d)\n", Locale, dwMapFlags, lpSrcStr, cchSrc, lpDestStr, cchDest);
if (!lpSrcStr) { if (!lpSrcStr) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
int length = cchSrc; int length = cchSrc;
@@ -344,7 +347,7 @@ int WIN_FUNC LCMapStringA(LCID Locale, DWORD dwMapFlags, LPCCH lpSrcStr, int cch
int wideResult = int wideResult =
LCMapStringW(Locale, dwMapFlags, wideSrc.data(), length, wideDest.empty() ? nullptr : wideDest.data(), cchDest); LCMapStringW(Locale, dwMapFlags, wideSrc.data(), length, wideDest.empty() ? nullptr : wideDest.data(), cchDest);
if (wideResult == 0) { if (wideResult == 0) {
wibo::lastError = ERROR_SUCCESS; setLastError(ERROR_SUCCESS);
return 0; return 0;
} }
@@ -355,7 +358,7 @@ int WIN_FUNC LCMapStringA(LCID Locale, DWORD dwMapFlags, LPCCH lpSrcStr, int cch
auto mapped = wideStringToString(wideDest.data(), wideResult); auto mapped = wideStringToString(wideDest.data(), wideResult);
size_t bytesToCopy = mapped.size() + 1; size_t bytesToCopy = mapped.size() + 1;
if (static_cast<size_t>(cchDest) < bytesToCopy) { if (static_cast<size_t>(cchDest) < bytesToCopy) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }
std::memcpy(lpDestStr, mapped.c_str(), bytesToCopy); std::memcpy(lpDestStr, mapped.c_str(), bytesToCopy);

View File

@@ -28,18 +28,18 @@ BOOL WIN_FUNC IsWow64Process(HANDLE hProcess, PBOOL Wow64Process) {
HOST_CONTEXT_GUARD(); HOST_CONTEXT_GUARD();
DEBUG_LOG("IsWow64Process(%p, %p)\n", hProcess, Wow64Process); DEBUG_LOG("IsWow64Process(%p, %p)\n", hProcess, Wow64Process);
if (!Wow64Process) { if (!Wow64Process) {
wibo::lastError = ERROR_INVALID_PARAMETER; setLastError(ERROR_INVALID_PARAMETER);
return FALSE; return FALSE;
} }
if (!isPseudoCurrentProcessHandle(hProcess)) { if (!isPseudoCurrentProcessHandle(hProcess)) {
if (!hProcess) { if (!hProcess) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
auto obj = wibo::handles().getAs<ProcessObject>(hProcess); auto obj = wibo::handles().getAs<ProcessObject>(hProcess);
if (!obj) { if (!obj) {
wibo::lastError = ERROR_INVALID_HANDLE; setLastError(ERROR_INVALID_HANDLE);
return FALSE; return FALSE;
} }
} }

View File

@@ -1,50 +1,43 @@
#include "common.h" #include "common.h"
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "kernel32/internal.h"
#include "modules.h" #include "modules.h"
#include "resources.h" #include "resources.h"
namespace user32 { namespace user32 {
constexpr uint32_t RT_STRING_ID = 6;
constexpr uintptr_t kDefaultKeyboardLayout = 0x04090409;
constexpr int UOI_FLAGS = 1;
constexpr DWORD WSF_VISIBLE = 0x0001;
struct USEROBJECTFLAGS { constexpr uint32_t RT_STRING_ID = 6;
BOOL fInherit; constexpr uintptr_t kDefaultKeyboardLayout = 0x04090409;
BOOL fReserved; constexpr int UOI_FLAGS = 1;
DWORD dwFlags; constexpr DWORD WSF_VISIBLE = 0x0001;
};
int WIN_FUNC LoadStringA(void* hInstance, unsigned int uID, char* lpBuffer, int cchBufferMax) { struct USEROBJECTFLAGS {
HOST_CONTEXT_GUARD(); BOOL fInherit;
DEBUG_LOG("LoadStringA(%p, %u, %p, %d)\n", hInstance, uID, lpBuffer, cchBufferMax); BOOL fReserved;
if (!lpBuffer || cchBufferMax <= 0) { DWORD dwFlags;
return 0; };
}
wibo::Executable *mod = wibo::executableFromModule((HMODULE) hInstance); int WIN_FUNC LoadStringA(void *hInstance, unsigned int uID, char *lpBuffer, int cchBufferMax) {
if (!mod) { HOST_CONTEXT_GUARD();
return 0; DEBUG_LOG("LoadStringA(%p, %u, %p, %d)\n", hInstance, uID, lpBuffer, cchBufferMax);
} if (!lpBuffer || cchBufferMax <= 0) {
wibo::ResourceIdentifier type = wibo::ResourceIdentifier::fromID(RT_STRING_ID); return 0;
wibo::ResourceIdentifier table = wibo::ResourceIdentifier::fromID((uID >> 4) + 1); }
wibo::ResourceLocation loc; wibo::Executable *mod = wibo::executableFromModule((HMODULE)hInstance);
if (!mod->findResource(type, table, std::nullopt, loc)) { if (!mod) {
return 0; return 0;
} }
const uint16_t *cursor = reinterpret_cast<const uint16_t *>(loc.data); wibo::ResourceIdentifier type = wibo::ResourceIdentifier::fromID(RT_STRING_ID);
const uint16_t *end = cursor + (loc.size / sizeof(uint16_t)); wibo::ResourceIdentifier table = wibo::ResourceIdentifier::fromID((uID >> 4) + 1);
unsigned int entryIndex = uID & 0x0Fu; wibo::ResourceLocation loc;
for (unsigned int i = 0; i < entryIndex; ++i) { if (!mod->findResource(type, table, std::nullopt, loc)) {
if (cursor >= end) { return 0;
return 0; }
} const uint16_t *cursor = reinterpret_cast<const uint16_t *>(loc.data);
uint16_t length = *cursor++; const uint16_t *end = cursor + (loc.size / sizeof(uint16_t));
if (cursor + length > end) { unsigned int entryIndex = uID & 0x0Fu;
return 0; for (unsigned int i = 0; i < entryIndex; ++i) {
}
cursor += length;
}
if (cursor >= end) { if (cursor >= end) {
return 0; return 0;
} }
@@ -52,136 +45,150 @@ namespace user32 {
if (cursor + length > end) { if (cursor + length > end) {
return 0; return 0;
} }
int copyLength = length; cursor += length;
if (copyLength > cchBufferMax - 1) {
copyLength = cchBufferMax - 1;
}
for (int i = 0; i < copyLength; ++i) {
lpBuffer[i] = static_cast<char>(cursor[i] & 0xFF);
}
lpBuffer[copyLength] = 0;
DEBUG_LOG("LoadStringA -> %.*s\n", copyLength, lpBuffer);
return copyLength;
} }
if (cursor >= end) {
int WIN_FUNC LoadStringW(void* hInstance, unsigned int uID, uint16_t* lpBuffer, int cchBufferMax) { return 0;
HOST_CONTEXT_GUARD();
DEBUG_LOG("LoadStringW(%p, %u, %p, %d)\n", hInstance, uID, lpBuffer, cchBufferMax);
wibo::Executable *mod = wibo::executableFromModule((HMODULE) hInstance);
if (!mod) {
return 0;
}
wibo::ResourceIdentifier type = wibo::ResourceIdentifier::fromID(RT_STRING_ID);
wibo::ResourceIdentifier table = wibo::ResourceIdentifier::fromID((uID >> 4) + 1);
wibo::ResourceLocation loc;
if (!mod->findResource(type, table, std::nullopt, loc)) {
return 0;
}
const uint16_t *cursor = reinterpret_cast<const uint16_t *>(loc.data);
const uint16_t *end = cursor + (loc.size / sizeof(uint16_t));
unsigned int entryIndex = uID & 0x0Fu;
for (unsigned int i = 0; i < entryIndex; ++i) {
if (cursor >= end) {
return 0;
}
uint16_t length = *cursor++;
if (cursor + length > end) {
return 0;
}
cursor += length;
}
if (cursor >= end) {
return 0;
}
uint16_t length = *cursor++;
if (cursor + length > end) {
return 0;
}
if (cchBufferMax == 0) {
if (lpBuffer) {
*reinterpret_cast<uint16_t **>(lpBuffer) = const_cast<uint16_t *>(cursor);
}
return length;
}
if (!lpBuffer || cchBufferMax <= 0) {
return 0;
}
int copyLength = length;
if (copyLength > cchBufferMax - 1) {
copyLength = cchBufferMax - 1;
}
for (int i = 0; i < copyLength; ++i) {
lpBuffer[i] = cursor[i];
}
lpBuffer[copyLength] = 0;
DEBUG_LOG("LoadStringW -> length %d\n", copyLength);
return copyLength;
} }
uint16_t length = *cursor++;
int WIN_FUNC MessageBoxA(void *hwnd, const char *lpText, const char *lpCaption, unsigned int uType) { if (cursor + length > end) {
HOST_CONTEXT_GUARD(); return 0;
(void)hwnd;
(void)uType;
printf("MESSAGE BOX: [%s] %s\n", lpCaption, lpText);
fflush(stdout);
return 1;
} }
int copyLength = length;
HKL WIN_FUNC GetKeyboardLayout(DWORD idThread) { if (copyLength > cchBufferMax - 1) {
HOST_CONTEXT_GUARD(); copyLength = cchBufferMax - 1;
DEBUG_LOG("GetKeyboardLayout(%u)\n", idThread);
(void)idThread;
return reinterpret_cast<HKL>(kDefaultKeyboardLayout);
} }
for (int i = 0; i < copyLength; ++i) {
HWINSTA WIN_FUNC GetProcessWindowStation() { lpBuffer[i] = static_cast<char>(cursor[i] & 0xFF);
DEBUG_LOG("GetProcessWindowStation()\n");
static int kWindowStationStub;
return reinterpret_cast<HWINSTA>(&kWindowStationStub);
}
BOOL WIN_FUNC GetUserObjectInformationA(HANDLE hObj, int nIndex, PVOID pvInfo, DWORD nLength,
LPDWORD lpnLengthNeeded) {
DEBUG_LOG("GetUserObjectInformationA(%p, %d, %p, %u, %p)\n", hObj, nIndex, pvInfo, nLength,
lpnLengthNeeded);
(void)hObj;
if (lpnLengthNeeded) {
*lpnLengthNeeded = sizeof(USEROBJECTFLAGS);
}
if (nIndex != UOI_FLAGS) {
wibo::lastError = ERROR_CALL_NOT_IMPLEMENTED;
return FALSE;
}
if (!pvInfo || nLength < sizeof(USEROBJECTFLAGS)) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER;
return FALSE;
}
auto *flags = reinterpret_cast<USEROBJECTFLAGS *>(pvInfo);
flags->fInherit = FALSE;
flags->fReserved = FALSE;
flags->dwFlags = WSF_VISIBLE;
return TRUE;
}
HWND WIN_FUNC GetActiveWindow() {
DEBUG_LOG("GetActiveWindow()\n");
return nullptr;
} }
lpBuffer[copyLength] = 0;
DEBUG_LOG("LoadStringA -> %.*s\n", copyLength, lpBuffer);
return copyLength;
} }
int WIN_FUNC LoadStringW(void *hInstance, unsigned int uID, uint16_t *lpBuffer, int cchBufferMax) {
HOST_CONTEXT_GUARD();
DEBUG_LOG("LoadStringW(%p, %u, %p, %d)\n", hInstance, uID, lpBuffer, cchBufferMax);
wibo::Executable *mod = wibo::executableFromModule((HMODULE)hInstance);
if (!mod) {
return 0;
}
wibo::ResourceIdentifier type = wibo::ResourceIdentifier::fromID(RT_STRING_ID);
wibo::ResourceIdentifier table = wibo::ResourceIdentifier::fromID((uID >> 4) + 1);
wibo::ResourceLocation loc;
if (!mod->findResource(type, table, std::nullopt, loc)) {
return 0;
}
const uint16_t *cursor = reinterpret_cast<const uint16_t *>(loc.data);
const uint16_t *end = cursor + (loc.size / sizeof(uint16_t));
unsigned int entryIndex = uID & 0x0Fu;
for (unsigned int i = 0; i < entryIndex; ++i) {
if (cursor >= end) {
return 0;
}
uint16_t length = *cursor++;
if (cursor + length > end) {
return 0;
}
cursor += length;
}
if (cursor >= end) {
return 0;
}
uint16_t length = *cursor++;
if (cursor + length > end) {
return 0;
}
if (cchBufferMax == 0) {
if (lpBuffer) {
*reinterpret_cast<uint16_t **>(lpBuffer) = const_cast<uint16_t *>(cursor);
}
return length;
}
if (!lpBuffer || cchBufferMax <= 0) {
return 0;
}
int copyLength = length;
if (copyLength > cchBufferMax - 1) {
copyLength = cchBufferMax - 1;
}
for (int i = 0; i < copyLength; ++i) {
lpBuffer[i] = cursor[i];
}
lpBuffer[copyLength] = 0;
DEBUG_LOG("LoadStringW -> length %d\n", copyLength);
return copyLength;
}
int WIN_FUNC MessageBoxA(void *hwnd, const char *lpText, const char *lpCaption, unsigned int uType) {
HOST_CONTEXT_GUARD();
(void)hwnd;
(void)uType;
printf("MESSAGE BOX: [%s] %s\n", lpCaption, lpText);
fflush(stdout);
return 1;
}
HKL WIN_FUNC GetKeyboardLayout(DWORD idThread) {
HOST_CONTEXT_GUARD();
DEBUG_LOG("GetKeyboardLayout(%u)\n", idThread);
(void)idThread;
return reinterpret_cast<HKL>(kDefaultKeyboardLayout);
}
HWINSTA WIN_FUNC GetProcessWindowStation() {
DEBUG_LOG("GetProcessWindowStation()\n");
static int kWindowStationStub;
return reinterpret_cast<HWINSTA>(&kWindowStationStub);
}
BOOL WIN_FUNC GetUserObjectInformationA(HANDLE hObj, int nIndex, PVOID pvInfo, DWORD nLength, LPDWORD lpnLengthNeeded) {
DEBUG_LOG("GetUserObjectInformationA(%p, %d, %p, %u, %p)\n", hObj, nIndex, pvInfo, nLength, lpnLengthNeeded);
(void)hObj;
if (lpnLengthNeeded) {
*lpnLengthNeeded = sizeof(USEROBJECTFLAGS);
}
if (nIndex != UOI_FLAGS) {
kernel32::setLastError(ERROR_CALL_NOT_IMPLEMENTED);
return FALSE;
}
if (!pvInfo || nLength < sizeof(USEROBJECTFLAGS)) {
kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return FALSE;
}
auto *flags = reinterpret_cast<USEROBJECTFLAGS *>(pvInfo);
flags->fInherit = FALSE;
flags->fReserved = FALSE;
flags->dwFlags = WSF_VISIBLE;
return TRUE;
}
HWND WIN_FUNC GetActiveWindow() {
DEBUG_LOG("GetActiveWindow()\n");
return nullptr;
}
} // namespace user32
static void *resolveByName(const char *name) { static void *resolveByName(const char *name) {
if (strcmp(name, "LoadStringA") == 0) return (void *) user32::LoadStringA; if (strcmp(name, "LoadStringA") == 0)
if (strcmp(name, "LoadStringW") == 0) return (void *) user32::LoadStringW; return (void *)user32::LoadStringA;
if (strcmp(name, "MessageBoxA") == 0) return (void *) user32::MessageBoxA; if (strcmp(name, "LoadStringW") == 0)
if (strcmp(name, "GetKeyboardLayout") == 0) return (void *) user32::GetKeyboardLayout; return (void *)user32::LoadStringW;
if (strcmp(name, "GetProcessWindowStation") == 0) return (void *) user32::GetProcessWindowStation; if (strcmp(name, "MessageBoxA") == 0)
if (strcmp(name, "GetUserObjectInformationA") == 0) return (void *) user32::GetUserObjectInformationA; return (void *)user32::MessageBoxA;
if (strcmp(name, "GetActiveWindow") == 0) return (void *) user32::GetActiveWindow; if (strcmp(name, "GetKeyboardLayout") == 0)
return (void *)user32::GetKeyboardLayout;
if (strcmp(name, "GetProcessWindowStation") == 0)
return (void *)user32::GetProcessWindowStation;
if (strcmp(name, "GetUserObjectInformationA") == 0)
return (void *)user32::GetUserObjectInformationA;
if (strcmp(name, "GetActiveWindow") == 0)
return (void *)user32::GetActiveWindow;
return nullptr; return nullptr;
} }

View File

@@ -2,6 +2,7 @@
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "files.h" #include "files.h"
#include "kernel32/internal.h"
#include "modules.h" #include "modules.h"
#include "resources.h" #include "resources.h"
#include "strutil.h" #include "strutil.h"
@@ -160,7 +161,7 @@ bool splitSubBlock(const std::string &subBlock, std::vector<std::string> &segmen
bool loadVersionResource(const char *fileName, std::vector<uint8_t> &buffer) { bool loadVersionResource(const char *fileName, std::vector<uint8_t> &buffer) {
if (!fileName) { if (!fileName) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return false; return false;
} }
@@ -168,14 +169,14 @@ bool loadVersionResource(const char *fileName, std::vector<uint8_t> &buffer) {
std::string hostPathStr = hostPath.string(); std::string hostPathStr = hostPath.string();
FILE *fp = std::fopen(hostPathStr.c_str(), "rb"); FILE *fp = std::fopen(hostPathStr.c_str(), "rb");
if (!fp) { if (!fp) {
wibo::lastError = ERROR_FILE_NOT_FOUND; kernel32::setLastError(ERROR_FILE_NOT_FOUND);
return false; return false;
} }
wibo::Executable executable; wibo::Executable executable;
if (!executable.loadPE(fp, false)) { if (!executable.loadPE(fp, false)) {
std::fclose(fp); std::fclose(fp);
wibo::lastError = ERROR_BAD_EXE_FORMAT; kernel32::setLastError(ERROR_BAD_EXE_FORMAT);
return false; return false;
} }
@@ -217,7 +218,7 @@ unsigned int WIN_FUNC GetFileVersionInfoA(const char *lptstrFilename, unsigned i
(void)dwHandle; (void)dwHandle;
DEBUG_LOG("GetFileVersionInfoA(%s, %u, %p)\n", lptstrFilename, dwLen, lpData); DEBUG_LOG("GetFileVersionInfoA(%s, %u, %p)\n", lptstrFilename, dwLen, lpData);
if (!lpData || dwLen == 0) { if (!lpData || dwLen == 0) {
wibo::lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return 0; return 0;
} }
@@ -226,7 +227,7 @@ unsigned int WIN_FUNC GetFileVersionInfoA(const char *lptstrFilename, unsigned i
return 0; return 0;
if (buffer.size() > dwLen) { if (buffer.size() > dwLen) {
wibo::lastError = ERROR_INSUFFICIENT_BUFFER; kernel32::setLastError(ERROR_INSUFFICIENT_BUFFER);
return 0; return 0;
} }

View File

@@ -398,7 +398,6 @@ static_assert(sizeof(TIB) >= 0x1000, "TIB too small");
namespace wibo { namespace wibo {
extern thread_local uint32_t lastError;
extern char **argv; extern char **argv;
extern int argc; extern int argc;
extern std::filesystem::path guestExecutablePath; extern std::filesystem::path guestExecutablePath;

View File

@@ -1,5 +1,6 @@
#include "common.h" #include "common.h"
#include "errors.h" #include "errors.h"
#include "kernel32/internal.h"
#include "modules.h" #include "modules.h"
#include <algorithm> #include <algorithm>
@@ -390,7 +391,7 @@ bool wibo::Executable::resolveImports() {
uint32_t *addressTable = fromRVA(dir->importAddressTable); uint32_t *addressTable = fromRVA(dir->importAddressTable);
ModuleInfo *module = loadModule(dllName); ModuleInfo *module = loadModule(dllName);
if (!module && wibo::lastError != ERROR_MOD_NOT_FOUND) { if (!module && kernel32::getLastError() != ERROR_MOD_NOT_FOUND) {
DEBUG_LOG("Failed to load import module %s\n", dllName); DEBUG_LOG("Failed to load import module %s\n", dllName);
// lastError is set by loadModule // lastError is set by loadModule
importsResolved = false; importsResolved = false;

View File

@@ -24,7 +24,6 @@
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
thread_local uint32_t wibo::lastError = 0;
char **wibo::argv; char **wibo::argv;
int wibo::argc; int wibo::argc;
std::filesystem::path wibo::guestExecutablePath; std::filesystem::path wibo::guestExecutablePath;
@@ -605,7 +604,7 @@ int main(int argc, char **argv) {
} }
// Reset last error // Reset last error
wibo::lastError = 0; kernel32::setLastError(0);
// Invoke the damn thing // Invoke the damn thing
{ {

View File

@@ -4,6 +4,7 @@
#include "context.h" #include "context.h"
#include "errors.h" #include "errors.h"
#include "files.h" #include "files.h"
#include "kernel32/internal.h"
#include "strutil.h" #include "strutil.h"
#include "tls.h" #include "tls.h"
@@ -562,7 +563,7 @@ BOOL callDllMain(wibo::ModuleInfo &info, DWORD reason, LPVOID reserved) {
} }
// Reset last error // Reset last error
wibo::lastError = ERROR_SUCCESS; kernel32::setLastError(ERROR_SUCCESS);
using DllMainFunc = BOOL(WIN_FUNC *)(HMODULE, DWORD, LPVOID); using DllMainFunc = BOOL(WIN_FUNC *)(HMODULE, DWORD, LPVOID);
auto dllMain = reinterpret_cast<DllMainFunc>(entry); auto dllMain = reinterpret_cast<DllMainFunc>(entry);
@@ -943,7 +944,7 @@ bool initializeModuleTls(ModuleInfo &module) {
size_t requiredModuleCapacity = reg->tlsModuleSlots.size(); size_t requiredModuleCapacity = reg->tlsModuleSlots.size();
if (!wibo::tls::ensureModulePointerCapacity(requiredModuleCapacity)) { if (!wibo::tls::ensureModulePointerCapacity(requiredModuleCapacity)) {
releaseModuleTlsSlot(*reg, loaderIndex); releaseModuleTlsSlot(*reg, loaderIndex);
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; kernel32::setLastError(ERROR_NOT_ENOUGH_MEMORY);
return false; return false;
} }
info.loaderIndex = loaderIndex; info.loaderIndex = loaderIndex;
@@ -958,7 +959,7 @@ bool initializeModuleTls(ModuleInfo &module) {
if (info.indexLocation) { if (info.indexLocation) {
*info.indexLocation = 0; *info.indexLocation = 0;
} }
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; kernel32::setLastError(ERROR_NOT_ENOUGH_MEMORY);
return false; return false;
} }
info.index = apiIndex; info.index = apiIndex;
@@ -1001,11 +1002,11 @@ bool initializeModuleTls(ModuleInfo &module) {
if (info.indexLocation) { if (info.indexLocation) {
*info.indexLocation = 0; *info.indexLocation = 0;
} }
wibo::lastError = ERROR_NOT_ENOUGH_MEMORY; kernel32::setLastError(ERROR_NOT_ENOUGH_MEMORY);
return false; return false;
} }
runModuleTlsCallbacks(module, TLS_PROCESS_ATTACH); runModuleTlsCallbacks(module, TLS_PROCESS_ATTACH);
wibo::lastError = ERROR_SUCCESS; kernel32::setLastError(ERROR_SUCCESS);
return true; return true;
} }
@@ -1079,7 +1080,7 @@ void notifyDllThreadAttach() {
for (wibo::ModuleInfo *info : targets) { for (wibo::ModuleInfo *info : targets) {
callDllMain(*info, DLL_THREAD_ATTACH, nullptr); callDllMain(*info, DLL_THREAD_ATTACH, nullptr);
} }
wibo::lastError = ERROR_SUCCESS; kernel32::setLastError(ERROR_SUCCESS);
} }
void notifyDllThreadDetach() { void notifyDllThreadDetach() {
@@ -1106,7 +1107,7 @@ void notifyDllThreadDetach() {
freeModuleTlsForThread(**it, tib); freeModuleTlsForThread(**it, tib);
} }
} }
wibo::lastError = ERROR_SUCCESS; kernel32::setLastError(ERROR_SUCCESS);
} }
BOOL disableThreadNotifications(ModuleInfo *info) { BOOL disableThreadNotifications(ModuleInfo *info) {
@@ -1135,7 +1136,7 @@ ModuleInfo *findLoadedModule(const char *name) {
ModuleInfo *loadModule(const char *dllName) { ModuleInfo *loadModule(const char *dllName) {
if (!dllName || *dllName == '\0') { if (!dllName || *dllName == '\0') {
lastError = ERROR_INVALID_PARAMETER; kernel32::setLastError(ERROR_INVALID_PARAMETER);
return nullptr; return nullptr;
} }
std::string requested(dllName); std::string requested(dllName);
@@ -1198,14 +1199,14 @@ ModuleInfo *loadModule(const char *dllName) {
DEBUG_LOG(" resolveImports failed for %s\n", raw->originalName.c_str()); DEBUG_LOG(" resolveImports failed for %s\n", raw->originalName.c_str());
reg.lock.lock(); reg.lock.lock();
reg->modulesByKey.erase(key); reg->modulesByKey.erase(key);
diskError = wibo::lastError; diskError = kernel32::getLastError();
return nullptr; return nullptr;
} }
if (!initializeModuleTls(*raw)) { if (!initializeModuleTls(*raw)) {
DEBUG_LOG(" initializeModuleTls failed for %s\n", raw->originalName.c_str()); DEBUG_LOG(" initializeModuleTls failed for %s\n", raw->originalName.c_str());
reg.lock.lock(); reg.lock.lock();
reg->modulesByKey.erase(key); reg->modulesByKey.erase(key);
diskError = wibo::lastError; diskError = kernel32::getLastError();
return nullptr; return nullptr;
} }
reg.lock.lock(); reg.lock.lock();
@@ -1230,7 +1231,7 @@ ModuleInfo *loadModule(const char *dllName) {
reg->pinnedModules.erase(raw); reg->pinnedModules.erase(raw);
reg->modulesByKey.erase(key); reg->modulesByKey.erase(key);
diskError = ERROR_DLL_INIT_FAILED; diskError = ERROR_DLL_INIT_FAILED;
wibo::lastError = ERROR_DLL_INIT_FAILED; kernel32::setLastError(ERROR_DLL_INIT_FAILED);
return nullptr; return nullptr;
} }
return raw; return raw;
@@ -1266,7 +1267,7 @@ ModuleInfo *loadModule(const char *dllName) {
DEBUG_LOG(" replaced builtin module %s with external copy\n", requested.c_str()); DEBUG_LOG(" replaced builtin module %s with external copy\n", requested.c_str());
return external; return external;
} else if (diskError != ERROR_MOD_NOT_FOUND) { } else if (diskError != ERROR_MOD_NOT_FOUND) {
lastError = diskError; kernel32::setLastError(diskError);
return nullptr; return nullptr;
} }
} }
@@ -1278,7 +1279,7 @@ ModuleInfo *loadModule(const char *dllName) {
DEBUG_LOG(" loaded external module %s\n", requested.c_str()); DEBUG_LOG(" loaded external module %s\n", requested.c_str());
return external; return external;
} else if (diskError != ERROR_MOD_NOT_FOUND) { } else if (diskError != ERROR_MOD_NOT_FOUND) {
lastError = diskError; kernel32::setLastError(diskError);
return nullptr; return nullptr;
} }
@@ -1299,7 +1300,7 @@ ModuleInfo *loadModule(const char *dllName) {
return builtin; return builtin;
} }
lastError = (diskError != ERROR_SUCCESS) ? diskError : ERROR_MOD_NOT_FOUND; kernel32::setLastError((diskError != ERROR_SUCCESS) ? diskError : ERROR_MOD_NOT_FOUND);
return nullptr; return nullptr;
} }

View File

@@ -2,6 +2,7 @@
#include "common.h" #include "common.h"
#include "errors.h" #include "errors.h"
#include "kernel32/internal.h"
#include "modules.h" #include "modules.h"
namespace { namespace {
@@ -146,39 +147,39 @@ bool Executable::findResource(const ResourceIdentifier &type, const ResourceIden
std::optional<uint16_t> language, ResourceLocation &out) const { std::optional<uint16_t> language, ResourceLocation &out) const {
const uint8_t *base = reinterpret_cast<const uint8_t *>(rsrcBase); const uint8_t *base = reinterpret_cast<const uint8_t *>(rsrcBase);
if (!base) { if (!base) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return false; return false;
} }
const auto *root = reinterpret_cast<const ImageResourceDirectory *>(base); const auto *root = reinterpret_cast<const ImageResourceDirectory *>(base);
const auto *typeEntry = findEntry(base, root, type, rsrcSize); const auto *typeEntry = findEntry(base, root, type, rsrcSize);
if (!typeEntry) { if (!typeEntry) {
wibo::lastError = ERROR_RESOURCE_TYPE_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_TYPE_NOT_FOUND);
return false; return false;
} }
const auto *nameDir = entryAsDirectory(base, typeEntry, rsrcSize); const auto *nameDir = entryAsDirectory(base, typeEntry, rsrcSize);
if (!nameDir) { if (!nameDir) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return false; return false;
} }
const auto *nameEntry = findEntry(base, nameDir, name, rsrcSize); const auto *nameEntry = findEntry(base, nameDir, name, rsrcSize);
if (!nameEntry) { if (!nameEntry) {
wibo::lastError = ERROR_RESOURCE_NAME_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_NAME_NOT_FOUND);
return false; return false;
} }
const auto *langDir = entryAsDirectory(base, nameEntry, rsrcSize); const auto *langDir = entryAsDirectory(base, nameEntry, rsrcSize);
if (!langDir) { if (!langDir) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return false; return false;
} }
uint16_t chosenLang = language.value_or(0); uint16_t chosenLang = language.value_or(0);
const auto *langEntry = selectLanguageEntry(langDir, language, chosenLang); const auto *langEntry = selectLanguageEntry(langDir, language, chosenLang);
if (!langEntry) { if (!langEntry) {
wibo::lastError = ERROR_RESOURCE_LANG_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_LANG_NOT_FOUND);
return false; return false;
} }
const auto *dataEntry = entryAsData(base, langEntry, rsrcSize); const auto *dataEntry = entryAsData(base, langEntry, rsrcSize);
if (!dataEntry) { if (!dataEntry) {
wibo::lastError = ERROR_RESOURCE_DATA_NOT_FOUND; kernel32::setLastError(ERROR_RESOURCE_DATA_NOT_FOUND);
return false; return false;
} }
out.dataEntry = dataEntry; out.dataEntry = dataEntry;