Skip to content
This repository has been archived by the owner on Jul 12, 2024. It is now read-only.

Commit

Permalink
feat: support std::std::error_code
Browse files Browse the repository at this point in the history
feat: impl FormatMessage
  • Loading branch information
MiroKaku committed May 24, 2022
1 parent 684c787 commit 74e23d4
Show file tree
Hide file tree
Showing 20 changed files with 1,173 additions and 747 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "veil"]
path = veil
url = https://github.com/MiroKaku/Veil.git
4 changes: 2 additions & 2 deletions src/errno.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ int __cdecl __acrt_errno_from_os_error(unsigned long const oserrno)
}
}

#if WDK_NTDDI_VERSION < 0x0A00000A /*NTDDI_WIN10_FE*/
#if (WDK_NTDDI_VERSION < 0x0A00000A /*NTDDI_WIN10_FE*/)
// These safely set and get the value of the calling thread's errno
errno_t __cdecl _set_errno(_In_ int const value)
{
Expand All @@ -147,6 +147,7 @@ errno_t __cdecl _get_errno(_Out_ int* const result)
*result = errno;
return 0;
}
#endif // (WDK_NTDDI_VERSION < 0x0A00000A /*NTDDI_WIN10_FE*/)

// These safely set and get the value of the calling thread's doserrno
errno_t __cdecl _set_doserrno(_In_ unsigned long const value)
Expand All @@ -163,7 +164,6 @@ errno_t __cdecl _get_doserrno(_Out_ unsigned long* const result)
*result = _doserrno;
return 0;
}
#endif


// These return pointers to the calling thread's errno and doserrno values,
Expand Down
6 changes: 3 additions & 3 deletions src/i386/exsup.asm
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@
;***
;exsup.asm
;
; Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
; Copyright (c) 1993-2001, Microsoft Corporation. All rights reserved.
;
;Purpose:
; Exception handling for i386. This file contains those routines
; common to both C8.0 and C9.0.
; Exception handling for i386. This file contains those routines
; common to both C8.0 and C9.0.
;
;*******************************************************************************

Expand Down
216 changes: 216 additions & 0 deletions src/message.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
/*
* PROJECT: Universal C++ RunTime (UCXXRT)
* FILE: message.cpp
* DATA: 2022/05/22
*
* PURPOSE: Universal C++ RunTime
*
* LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
*
* DEVELOPER: MiroKaku (miro.kaku AT Outlook.com)
*/

EXTERN_C NTSTATUS NTAPI RtlFindAndFormatMessage(
_In_ UINT32 Flags,
_In_opt_ LPCVOID Source,
_In_ UINT32 MessageId,
_In_ UINT32 LanguageId,
_Out_ LPWSTR Buffer,
_Inout_ UINT32* Size,
_In_opt_ va_list* Arguments
)
{
NTSTATUS Status = STATUS_SUCCESS;
PVOID AllocatedBuffer = nullptr;

ANSI_STRING AnsiMessage{};
UNICODE_STRING UnicodeMessage{};

do
{
/* If this is a Win32 error wrapped as an OLE HRESULT then unwrap it */
if (((MessageId & 0xffff0000) == 0x80070000) &&
BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_SYSTEM) &&
!BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_HMODULE) &&
!BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_STRING))
{
MessageId &= 0x0000ffff;
}

if (Buffer == nullptr)
{
Status = STATUS_INVALID_PARAMETER;
break;
}

if (Flags & FORMAT_MESSAGE_ALLOCATE_BUFFER)
{
*(PVOID*)Buffer = nullptr;
}

PVOID DllHandle = nullptr;
ULONG MaximumWidth = 0ul;
PWSTR MessageFormat = nullptr;
PMESSAGE_RESOURCE_ENTRY MessageEntry = nullptr;

__try
{
PVOID BaseDllHandle = ucxxrt::PsSystemDllBase;

MaximumWidth = Flags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
if (MaximumWidth == FORMAT_MESSAGE_MAX_WIDTH_MASK)
{
MaximumWidth = ULONG_MAX;
}

if (BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_STRING))
{
MessageFormat = (PWSTR)Source;
}
else
{
if (BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_HMODULE))
{
if (Source == nullptr)
{
DllHandle = BaseDllHandle;
}
else
{
DllHandle = (LPVOID)Source;
}
}
else if (BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_SYSTEM))
{
DllHandle = BaseDllHandle;
}
else
{
Status = STATUS_INVALID_PARAMETER;
break;
}

Status = RtlFindMessage(
DllHandle,
PtrToUlong(RT_MESSAGETABLE),
LanguageId,
MessageId,
&MessageEntry);

if (Status == STATUS_MESSAGE_NOT_FOUND)
{
if (BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_HMODULE) &&
BooleanFlagOn(Flags, FORMAT_MESSAGE_FROM_SYSTEM))
{
DllHandle = BaseDllHandle;
ClearFlag(Flags, FORMAT_MESSAGE_FROM_HMODULE);

Status = RtlFindMessage(
DllHandle,
PtrToUlong(RT_MESSAGETABLE),
LanguageId,
MessageId,
&MessageEntry);
}
}

if (!NT_SUCCESS(Status))
{
break;
}

if (!BooleanFlagOn(MessageEntry->Flags, MESSAGE_RESOURCE_UNICODE))
{
RtlInitAnsiString(&AnsiMessage, (PCSZ)MessageEntry->Text);
Status = RtlAnsiStringToUnicodeString(&UnicodeMessage, &AnsiMessage, TRUE);
if (!NT_SUCCESS(Status))
{
break;
}

MessageFormat = UnicodeMessage.Buffer;
}
else
{
MessageFormat = (PWSTR)MessageEntry->Text;
}
}

auto WrittenSize = 256ul;
bool IgnoreInserts = BooleanFlagOn(Flags, FORMAT_MESSAGE_IGNORE_INSERTS);
bool ArgumentsAreAnAnsi = BooleanFlagOn(Flags, FORMAT_MESSAGE_ARGUMENT_ANSI);
bool ArgumentsAreAnArray = BooleanFlagOn(Flags, FORMAT_MESSAGE_ARGUMENT_ARRAY);

do
{
if (AllocatedBuffer)
{
free(AllocatedBuffer);
}

AllocatedBuffer = malloc(WrittenSize);
if (AllocatedBuffer == nullptr)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}

Status = RtlFormatMessage(
MessageFormat,
MaximumWidth,
IgnoreInserts,
ArgumentsAreAnAnsi,
ArgumentsAreAnArray,
Arguments,
(PWSTR)AllocatedBuffer,
WrittenSize,
&WrittenSize);
if (NT_SUCCESS(Status))
{
break;
}

if (Status != STATUS_BUFFER_OVERFLOW)
{
break;
}

WrittenSize += 256;

} while (true);

if (!NT_SUCCESS(Status))
{
break;
}

if (BooleanFlagOn(Flags, FORMAT_MESSAGE_ALLOCATE_BUFFER))
{
*(PVOID*)Buffer = AllocatedBuffer;
AllocatedBuffer = nullptr;
}
else if ((WrittenSize / sizeof(WCHAR)) > *Size)
{
Status = STATUS_BUFFER_TOO_SMALL;
break;
}
else
{
RtlMoveMemory(Buffer, AllocatedBuffer, WrittenSize);
}

*Size = (WrittenSize - sizeof(WCHAR)) / sizeof(WCHAR);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
Status = GetExceptionCode();
break;
}

} while (false);

free(AllocatedBuffer);
RtlFreeUnicodeString(&UnicodeMessage);

return Status;
}
Loading

0 comments on commit 74e23d4

Please sign in to comment.