1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * FILE: lib/rtl/message.c 5 * PURPOSE: Message table functions 6 * PROGRAMMERS: Eric Kohl 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include <rtl.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* FUNCTIONS *****************************************************************/ 17 18 /* 19 * @implemented 20 */ 21 NTSTATUS 22 NTAPI 23 RtlFindMessage( 24 IN PVOID BaseAddress, 25 IN ULONG Type, 26 IN ULONG Language, 27 IN ULONG MessageId, 28 OUT PMESSAGE_RESOURCE_ENTRY* MessageResourceEntry) 29 { 30 LDR_RESOURCE_INFO ResourceInfo; 31 PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry; 32 PMESSAGE_RESOURCE_DATA MessageTable; 33 NTSTATUS Status; 34 ULONG EntryOffset = 0, IdOffset = 0; 35 PMESSAGE_RESOURCE_ENTRY MessageEntry; 36 ULONG i; 37 38 DPRINT("RtlFindMessage()\n"); 39 40 ResourceInfo.Type = Type; 41 ResourceInfo.Name = 1; 42 ResourceInfo.Language = Language; 43 44 Status = LdrFindResource_U(BaseAddress, 45 &ResourceInfo, 46 RESOURCE_DATA_LEVEL, 47 &ResourceDataEntry); 48 if (!NT_SUCCESS(Status)) 49 { 50 return Status; 51 } 52 53 DPRINT("ResourceDataEntry: %p\n", ResourceDataEntry); 54 55 Status = LdrAccessResource(BaseAddress, 56 ResourceDataEntry, 57 (PVOID*)&MessageTable, 58 NULL); 59 if (!NT_SUCCESS(Status)) 60 { 61 return Status; 62 } 63 64 DPRINT("MessageTable: %p\n", MessageTable); 65 66 DPRINT("NumberOfBlocks %lu\n", MessageTable->NumberOfBlocks); 67 for (i = 0; i < MessageTable->NumberOfBlocks; i++) 68 { 69 DPRINT("LoId 0x%08lx HiId 0x%08lx Offset 0x%08lx\n", 70 MessageTable->Blocks[i].LowId, 71 MessageTable->Blocks[i].HighId, 72 MessageTable->Blocks[i].OffsetToEntries); 73 } 74 75 for (i = 0; i < MessageTable->NumberOfBlocks; i++) 76 { 77 if ((MessageId >= MessageTable->Blocks[i].LowId) && 78 (MessageId <= MessageTable->Blocks[i].HighId)) 79 { 80 EntryOffset = MessageTable->Blocks[i].OffsetToEntries; 81 IdOffset = MessageId - MessageTable->Blocks[i].LowId; 82 break; 83 } 84 85 if (MessageId < MessageTable->Blocks[i].LowId) 86 { 87 return STATUS_MESSAGE_NOT_FOUND; 88 } 89 } 90 91 if (MessageTable->NumberOfBlocks <= i) 92 { 93 return STATUS_MESSAGE_NOT_FOUND; 94 } 95 96 MessageEntry = (PMESSAGE_RESOURCE_ENTRY) 97 ((PUCHAR)MessageTable + MessageTable->Blocks[i].OffsetToEntries); 98 99 DPRINT("EntryOffset 0x%08lx\n", EntryOffset); 100 DPRINT("IdOffset 0x%08lx\n", IdOffset); 101 102 DPRINT("MessageEntry: %p\n", MessageEntry); 103 for (i = 0; i < IdOffset; i++) 104 { 105 MessageEntry = (PMESSAGE_RESOURCE_ENTRY) 106 ((PUCHAR)MessageEntry + (ULONG)MessageEntry->Length); 107 } 108 109 if (MessageEntry->Flags == 0) 110 { 111 DPRINT("AnsiText: %s\n", MessageEntry->Text); 112 } 113 else 114 { 115 DPRINT("UnicodeText: %S\n", (PWSTR)MessageEntry->Text); 116 } 117 118 if (MessageResourceEntry != NULL) 119 { 120 *MessageResourceEntry = MessageEntry; 121 } 122 123 return STATUS_SUCCESS; 124 } 125 126 /* 127 * @unimplemented 128 */ 129 NTSTATUS 130 NTAPI 131 RtlFormatMessageEx( 132 IN PWSTR Message, 133 IN ULONG MaxWidth OPTIONAL, 134 IN BOOLEAN IgnoreInserts, 135 IN BOOLEAN ArgumentsAreAnsi, 136 IN BOOLEAN ArgumentsAreAnArray, 137 IN va_list* Arguments, 138 OUT PWSTR Buffer, 139 IN ULONG BufferSize, 140 OUT PULONG ReturnLength OPTIONAL, 141 IN ULONG Flags) 142 { 143 DPRINT1("RtlFormatMessage(%S, %lu, %s, %s, %s, %p, %p, %lu, %p, %lx)\n", 144 Message, MaxWidth, IgnoreInserts ? "TRUE" : "FALSE", ArgumentsAreAnsi ? "TRUE" : "FALSE", 145 ArgumentsAreAnArray ? "TRUE" : "FALSE", Arguments, Buffer, BufferSize, 146 ReturnLength, Flags); 147 148 UNIMPLEMENTED; 149 return STATUS_NOT_IMPLEMENTED; 150 } 151 152 /********************************************************************** 153 * RtlFormatMessage (NTDLL.@) 154 * 155 * Formats a message (similar to sprintf). 156 * 157 * PARAMS 158 * Message [I] Message to format. 159 * MaxWidth [I] Maximum width in characters of each output line (optional). 160 * IgnoreInserts [I] Whether to copy the message without processing inserts. 161 * ArgumentsAreAnsi [I] Whether Arguments may have ANSI strings. 162 * ArgumentsAreAnArray [I] Whether Arguments is actually an array rather than a va_list *. 163 * Arguments [I] 164 * Buffer [O] Buffer to store processed message in. 165 * BufferSize [I] Size of Buffer (in bytes). 166 * ReturnLength [O] Size of the formatted message (in bytes; optional). 167 * 168 * RETURNS 169 * NTSTATUS code. 170 * 171 * @implemented 172 */ 173 NTSTATUS 174 NTAPI 175 RtlFormatMessage( 176 IN PWSTR Message, 177 IN ULONG MaxWidth OPTIONAL, 178 IN BOOLEAN IgnoreInserts, 179 IN BOOLEAN ArgumentsAreAnsi, 180 IN BOOLEAN ArgumentsAreAnArray, 181 IN va_list* Arguments, 182 OUT PWSTR Buffer, 183 IN ULONG BufferSize, 184 OUT PULONG ReturnLength OPTIONAL) 185 { 186 /* Call the extended API */ 187 return RtlFormatMessageEx(Message, 188 MaxWidth, 189 IgnoreInserts, 190 ArgumentsAreAnsi, 191 ArgumentsAreAnArray, 192 Arguments, 193 Buffer, 194 BufferSize, 195 ReturnLength, 196 0); 197 } 198 199 /* EOF */ 200