Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add UTF8_STRING support #175

Merged
merged 1 commit into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 63 additions & 1 deletion inc/usersim/rtl.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ typedef struct _UNICODE_STRING
} UNICODE_STRING, *PUNICODE_STRING;
typedef const UNICODE_STRING* PCUNICODE_STRING;

typedef STRING UTF8_STRING;
typedef PSTRING PUTF8_STRING;

#define DECLARE_CONST_UNICODE_STRING(_var, _string) \
const WCHAR _var##_buffer[] = _string; \
__pragma(warning(push)) __pragma(warning(disable : 4221)) __pragma(warning(disable : 4204)) \
Expand All @@ -145,6 +148,65 @@ _IRQL_requires_max_(DISPATCH_LEVEL) _At_(destination_string->Buffer, _Post_equal
USERSIM_API VOID NTAPI
RtlInitUnicodeString(_Out_ PUNICODE_STRING destination_string, _In_opt_z_ __drv_aliasesMem PCWSTR source_string);

_IRQL_requires_max_(DISPATCH_LEVEL)
USERSIM_API
VOID
NTAPI
RtlInitUTF8String(
_Out_ PUTF8_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem const char* SourceString
);

_IRQL_requires_max_(PASSIVE_LEVEL)
USERSIM_API
VOID
NTAPI
RtlFreeUnicodeString(
_Inout_ _At_(UnicodeString->Buffer, _Frees_ptr_opt_)
PUNICODE_STRING UnicodeString
);

_When_(AllocateDestinationString,
_At_(DestinationString->MaximumLength,
_Out_range_(<=, (SourceString->MaximumLength / sizeof(WCHAR)))))
_When_(!AllocateDestinationString,
_At_(DestinationString->Buffer, _Const_)
_At_(DestinationString->MaximumLength, _Const_))
_IRQL_requires_max_(PASSIVE_LEVEL)
_When_(AllocateDestinationString, _Must_inspect_result_)
USERSIM_API
NTSTATUS
NTAPI
RtlUnicodeStringToUTF8String(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUTF8_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);

_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlUTF8StringToUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PUTF8_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);

_IRQL_requires_max_(PASSIVE_LEVEL)
USERSIM_API
void
NTAPI
RtlFreeUTF8String(
_Inout_ _At_(utf8String->Buffer, _Frees_ptr_opt_)
PUTF8_STRING utf8String
);

typedef struct _OBJECT_ATTRIBUTES
{
ULONG Length;
Expand All @@ -167,4 +229,4 @@ USERSIM_API __analysis_noreturn void
RtlAssertCPP(
_In_ PVOID void_failed_assertion, _In_ PVOID void_file_name, _In_ ULONG line_number, _In_opt_ PSTR mutable_message);

#endif
#endif
26 changes: 26 additions & 0 deletions tests/rtl_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,4 +83,30 @@ TEST_CASE("RtlInitUnicodeString", "[rtl]")
REQUIRE(unicode_string.Buffer == buffer);
REQUIRE(unicode_string.Length == 8);
REQUIRE(unicode_string.MaximumLength == 10);
}

TEST_CASE("RtlUnicodeStringToUTF8String", "[rtl]")
{
UNICODE_STRING unicode_string = {0};
RtlInitUnicodeString(&unicode_string, L"test");
UTF8_STRING utf8_string = {0};
REQUIRE(RtlUnicodeStringToUTF8String(&utf8_string, &unicode_string, TRUE) == STATUS_SUCCESS);
REQUIRE(utf8_string.Buffer != nullptr);
REQUIRE(utf8_string.Length == 4);
REQUIRE(utf8_string.MaximumLength == 5);
REQUIRE(strcmp(utf8_string.Buffer, "test") == 0);
RtlFreeUTF8String(&utf8_string);
}

TEST_CASE("RtlUTF8StringToUnicodeString", "[rtl]")
{
UTF8_STRING utf8_string = {0};
RtlInitUTF8String(&utf8_string, "test");
UNICODE_STRING unicode_string = {0};
REQUIRE(RtlUTF8StringToUnicodeString(&unicode_string, &utf8_string, TRUE) == STATUS_SUCCESS);
REQUIRE(unicode_string.Buffer != nullptr);
REQUIRE(unicode_string.Length == 8);
REQUIRE(unicode_string.MaximumLength == 10);
REQUIRE(wcscmp(unicode_string.Buffer, L"test") == 0);
RtlFreeUnicodeString(&unicode_string);
}