From e611b132f9b8abe35b362e5870b74bce94a1e58e Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 16 May 2020 20:51:50 -0700 Subject: initial commit --- private/ntos/rtl/message.c | 460 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 460 insertions(+) create mode 100644 private/ntos/rtl/message.c (limited to 'private/ntos/rtl/message.c') diff --git a/private/ntos/rtl/message.c b/private/ntos/rtl/message.c new file mode 100644 index 000000000..825fc95c6 --- /dev/null +++ b/private/ntos/rtl/message.c @@ -0,0 +1,460 @@ +/*++ + +Copyright (c) 1991 Microsoft Corporation + +Module Name: + + message.c + +Abstract: + + Message table resource accessing functions + +Author: + + Steve Wood (stevewo) 10-Sep-1991 + +Revision History: + +--*/ + +#include "ntrtlp.h" +#include "string.h" +#include "stdio.h" + +#if defined(ALLOC_PRAGMA) && defined(NTOS_KERNEL_RUNTIME) +#pragma alloc_text(PAGE,RtlFindMessage) +#endif + +NTSTATUS +RtlFindMessage( + IN PVOID DllHandle, + IN ULONG MessageTableId, + IN ULONG MessageLanguageId, + IN ULONG MessageId, + OUT PMESSAGE_RESOURCE_ENTRY *MessageEntry + ) +{ + NTSTATUS Status; + ULONG NumberOfBlocks; + ULONG EntryIndex; + PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; + PMESSAGE_RESOURCE_DATA MessageData; + PMESSAGE_RESOURCE_BLOCK MessageBlock; + PCHAR s; + ULONG ResourceIdPath[ 3 ]; + + RTL_PAGED_CODE(); + + ResourceIdPath[ 0 ] = MessageTableId; + ResourceIdPath[ 1 ] = 1; + ResourceIdPath[ 2 ] = MessageLanguageId; + + Status = LdrpSearchResourceSection_U( DllHandle, + ResourceIdPath, + 3, + FALSE, + (PVOID *)&ResourceDataEntry + ); + if (!NT_SUCCESS( Status )) { + return( Status ); + } + + Status = LdrpAccessResourceData( DllHandle, + ResourceDataEntry, + (PVOID *)&MessageData, + NULL + ); + if (!NT_SUCCESS( Status )) { + return( Status ); + } + + NumberOfBlocks = MessageData->NumberOfBlocks; + MessageBlock = &MessageData->Blocks[ 0 ]; + while (NumberOfBlocks--) { + if (MessageId >= MessageBlock->LowId && + MessageId <= MessageBlock->HighId + ) { + s = (PCHAR)MessageData + MessageBlock->OffsetToEntries; + EntryIndex = MessageId - MessageBlock->LowId; + while (EntryIndex--) { + s += ((PMESSAGE_RESOURCE_ENTRY)s)->Length; + } + + *MessageEntry = (PMESSAGE_RESOURCE_ENTRY)s; + return( STATUS_SUCCESS ); + } + + MessageBlock++; + } + + return( STATUS_MESSAGE_NOT_FOUND ); +} + +#ifndef NTOS_KERNEL_RUNTIME + +#define MAX_INSERTS 200 + +NTSTATUS +RtlFormatMessage( + IN PWSTR MessageFormat, + IN ULONG MaximumWidth OPTIONAL, + IN BOOLEAN IgnoreInserts, + IN BOOLEAN ArgumentsAreAnsi, + IN BOOLEAN ArgumentsAreAnArray, + IN va_list *Arguments, + OUT PWSTR Buffer, + IN ULONG Length, + OUT PULONG ReturnLength OPTIONAL + ) +{ + ULONG Column; + int cchRemaining, cchWritten; + PULONG ArgumentsArray = (PULONG)Arguments; + ULONG rgInserts[ MAX_INSERTS ], cSpaces; + ULONG MaxInsert, CurInsert; + ULONG PrintParameterCount; + ULONG PrintParameter1; + ULONG PrintParameter2; + WCHAR PrintFormatString[ 32 ]; + BOOLEAN DefaultedFormatString; + WCHAR c; + PWSTR s, s1; + PWSTR lpDst, lpDstBeg, lpDstLastSpace; + + cchRemaining = Length / sizeof( WCHAR ); + lpDst = Buffer; + MaxInsert = 0; + lpDstLastSpace = NULL; + Column = 0; + s = MessageFormat; + while (*s != UNICODE_NULL) { + if (*s == L'%') { + s++; + lpDstBeg = lpDst; + if (*s >= L'1' && *s <= L'9') { + CurInsert = *s++ - L'0'; + if (*s >= L'0' && *s <= L'9') { + CurInsert = (CurInsert * 10) + (*s++ - L'0'); + if (*s >= L'0' && *s <= L'9') { + CurInsert = (CurInsert * 10) + (*s++ - L'0'); + if (*s >= L'0' && *s <= L'9') { + return( STATUS_INVALID_PARAMETER ); + } + } + } + CurInsert -= 1; + + PrintParameterCount = 0; + if (*s == L'!') { + DefaultedFormatString = FALSE; + s1 = PrintFormatString; + *s1++ = L'%'; + s++; + while (*s != L'!') { + if (*s != UNICODE_NULL) { + if (s1 >= &PrintFormatString[ 31 ]) { + return( STATUS_INVALID_PARAMETER ); + } + + if (*s == L'*') { + if (PrintParameterCount++ > 1) { + return( STATUS_INVALID_PARAMETER ); + } + } + + *s1++ = *s++; + } + else { + return( STATUS_INVALID_PARAMETER ); + } + } + + s++; + *s1 = UNICODE_NULL; + } + else { + DefaultedFormatString = TRUE; + wcscpy( PrintFormatString, L"%s" ); + s1 = PrintFormatString + wcslen( PrintFormatString ); + } + + if (IgnoreInserts) { + if (!wcscmp( PrintFormatString, L"%s" )) { + cchWritten = _snwprintf( lpDst, + cchRemaining, + L"%%%u", + CurInsert+1 + ); + } + else { + cchWritten = _snwprintf( lpDst, + cchRemaining, + L"%%%u!%s!", + CurInsert+1, + &PrintFormatString[ 1 ] + ); + } + } + else + if (ARGUMENT_PRESENT( Arguments )) { + if ((CurInsert+PrintParameterCount) >= MAX_INSERTS) { + return( STATUS_INVALID_PARAMETER ); + } + + if (ArgumentsAreAnsi) { + if (s1[ -1 ] == L'c' && s1[ -2 ] != L'h' + && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') { + wcscpy( &s1[ -1 ], L"hc" ); + } + else + if (s1[ -1 ] == L's' && s1[ -2 ] != L'h' + && s1[ -2 ] != L'w' && s1[ -2 ] != L'l') { + wcscpy( &s1[ -1 ], L"hs" ); + } + else if (s1[ -1 ] == L'S') { + s1[ -1 ] = L's'; + } + else if (s1[ -1 ] == L'C') { + s1[ -1 ] = L'c'; + } + } + + while (CurInsert >= MaxInsert) { + if (ArgumentsAreAnArray) { + rgInserts[ MaxInsert++ ] = *((PULONG)Arguments)++; + } + else { + rgInserts[ MaxInsert++ ] = va_arg(*Arguments, ULONG); + } + } + + s1 = (PWSTR)rgInserts[ CurInsert ]; + PrintParameter1 = 0; + PrintParameter2 = 0; + if (PrintParameterCount > 0) { + if (ArgumentsAreAnArray) { + PrintParameter1 = rgInserts[ MaxInsert++ ] = *((PULONG)Arguments)++; + } + else { + PrintParameter1 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG ); + } + + if (PrintParameterCount > 1) { + if (ArgumentsAreAnArray) { + PrintParameter2 = rgInserts[ MaxInsert++ ] = *((PULONG)Arguments)++; + } + else { + PrintParameter2 = rgInserts[ MaxInsert++ ] = va_arg( *Arguments, ULONG ); + } + } + } + + cchWritten = _snwprintf( lpDst, + cchRemaining, + PrintFormatString, + s1, + PrintParameter1, + PrintParameter2 + ); + } + else { + return( STATUS_INVALID_PARAMETER ); + } + + if ((cchRemaining -= cchWritten) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + lpDst += cchWritten; + } + else + if (*s == L'0') { + break; + } + else + if (!*s) { + return( STATUS_INVALID_PARAMETER ); + } + else + if (*s == L'r') { + if ((cchRemaining -= 1) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + *lpDst++ = L'\r'; + s++; + lpDstBeg = NULL; + } + else + if (*s == L'n') { + if ((cchRemaining -= 2) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + *lpDst++ = L'\r'; + *lpDst++ = L'\n'; + s++; + lpDstBeg = NULL; + } + else + if (*s == L't') { + if ((cchRemaining -= 1) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + if (Column % 8) { + Column = (Column + 7) & ~7; + } + else { + Column += 8; + } + + lpDstLastSpace = lpDst; + *lpDst++ = L'\t'; + s++; + } + else + if (*s == L'b') { + if ((cchRemaining -= 1) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + lpDstLastSpace = lpDst; + *lpDst++ = L' '; + s++; + } + else + if (IgnoreInserts) { + if ((cchRemaining -= 2) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + *lpDst++ = L'%'; + *lpDst++ = *s++; + } + else { + if ((cchRemaining -= 1) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + *lpDst++ = *s++; + } + + if (lpDstBeg == NULL) { + lpDstLastSpace = NULL; + Column = 0; + } + else { + Column += lpDst - lpDstBeg; + } + } + else { + c = *s++; + if (c == L'\r' || c == L'\n') { + if ((c == L'\n' && *s == L'\r') || + (c == L'\r' && *s == L'\n') + ) { + s++; + } + + if (MaximumWidth != 0) { + lpDstLastSpace = lpDst; + c = L' '; + } + else { + c = L'\n'; + } + } + + + if (c == L'\n') { + if ((cchRemaining -= 2) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + *lpDst++ = L'\r'; + *lpDst++ = L'\n'; + lpDstLastSpace = NULL; + Column = 0; + } + else { + if ((cchRemaining -= 1) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + if (c == L' ') { + lpDstLastSpace = lpDst; + } + + *lpDst++ = c; + Column += 1; + } + } + + if (MaximumWidth != 0 && + MaximumWidth != 0xFFFFFFFF && + Column >= MaximumWidth + ) { + if (lpDstLastSpace != NULL) { + lpDstBeg = lpDstLastSpace; + while (*lpDstBeg == L' ' || *lpDstBeg == L'\t') { + lpDstBeg += 1; + if (lpDstBeg == lpDst) { + break; + } + } + while (lpDstLastSpace > Buffer) { + if (lpDstLastSpace[ -1 ] == L' ' || lpDstLastSpace[ -1 ] == L'\t') { + lpDstLastSpace -= 1; + } + else { + break; + } + } + + cSpaces = lpDstBeg - lpDstLastSpace; + if (cSpaces == 1) { + if ((cchRemaining -= 1) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + } + else + if (cSpaces > 2) { + cchRemaining += (cSpaces - 2); + } + + memmove( lpDstLastSpace + 2, + lpDstBeg, + (lpDst - lpDstBeg) * sizeof( WCHAR ) + ); + *lpDstLastSpace++ = L'\r'; + *lpDstLastSpace++ = L'\n'; + Column = lpDst - lpDstBeg; + lpDst = lpDstLastSpace + Column; + lpDstLastSpace = NULL; + } + else { + if ((cchRemaining -= 2) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + *lpDst++ = L'\r'; + *lpDst++ = L'\n'; + lpDstLastSpace = NULL; + Column = 0; + } + } + } + + if ((cchRemaining -= 1) <= 0) { + return STATUS_BUFFER_OVERFLOW; + } + + *lpDst++ = '\0'; + if ( ARGUMENT_PRESENT(ReturnLength) ) { + *ReturnLength = (lpDst - Buffer) * sizeof( WCHAR ); + } + return( STATUS_SUCCESS ); +} +#endif -- cgit v1.2.3