xref: /reactos/sdk/lib/rtl/message.c (revision 8a978a17)
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