xref: /reactos/sdk/lib/rtl/message.c (revision c2c66aff)
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
RtlFindMessage(IN PVOID BaseAddress,IN ULONG Type,IN ULONG Language,IN ULONG MessageId,OUT PMESSAGE_RESOURCE_ENTRY * MessageResourceEntry)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
RtlFormatMessageEx(IN PWSTR Message,IN ULONG MaxWidth OPTIONAL,IN BOOLEAN IgnoreInserts,IN BOOLEAN ArgumentsAreAnsi,IN BOOLEAN ArgumentsAreAnArray,IN va_list * Arguments,OUT PWSTR Buffer,IN ULONG BufferSize,OUT PULONG ReturnLength OPTIONAL,IN ULONG Flags)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
RtlFormatMessage(IN PWSTR Message,IN ULONG MaxWidth OPTIONAL,IN BOOLEAN IgnoreInserts,IN BOOLEAN ArgumentsAreAnsi,IN BOOLEAN ArgumentsAreAnArray,IN va_list * Arguments,OUT PWSTR Buffer,IN ULONG BufferSize,OUT PULONG ReturnLength OPTIONAL)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