source: trunk/src/kernel32/message.cpp@ 17

Last change on this file since 17 was 17, checked in by phaller, 26 years ago

Code cleanup #1 for build, mainly addresses linkage problems

File size: 20.8 KB
Line 
1/* $Id: message.cpp,v 1.2 1999-05-31 22:08:11 phaller Exp $ */
2
3/*
4 *
5 * Project Odin Software License can be found in LICENSE.TXT
6 *
7 */
8/*
9 * Win32 message API functions for OS/2
10 *
11 * Copyright 1998 Sander van Leeuwen (ported WINE code)
12 *
13 * Original WINE code (loader\resource.c)
14 *
15 * Resources
16 *
17 * Copyright 1993 Robert J. Amstadt
18 * Copyright 1995 Alexandre Julliard
19 */
20#include <os2win.h>
21#include <stdlib.h>
22#include <stdio.h>
23#include <string.h>
24#include <stdarg.h>
25#include "unicode.h"
26#include "misc.h"
27
28
29//******************************************************************************
30//******************************************************************************
31int LoadMessageA(HINSTANCE instance, UINT id, WORD lang,
32 LPSTR buffer, int buflen )
33{
34 HGLOBAL hmem;
35 HRSRC hrsrc;
36 BYTE *p;
37 int nrofentries,i,slen;
38 struct _subentry {
39 DWORD firstentry;
40 DWORD lastentry;
41 DWORD offset;
42 } *se;
43 struct _stringentry {
44 WORD len;
45 WORD unknown;
46 CHAR str[1];
47 } *stre;
48
49 /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/
50 hrsrc = FindResourceA(instance,(LPCSTR)1,(LPCSTR)RT_MESSAGELISTA);
51 if (!hrsrc) return 0;
52 hmem = LoadResource(instance, hrsrc);
53 if (!hmem) return 0;
54
55 p = (BYTE *)LockResource(hmem);
56 nrofentries = *(DWORD*)p;
57 stre = NULL;
58 se = (struct _subentry*)(p+4);
59 for (i=nrofentries;i--;) {
60 if ((id>=se->firstentry) && (id<=se->lastentry)) {
61 stre = (struct _stringentry*)(p+se->offset);
62 id -= se->firstentry;
63 break;
64 }
65 se++;
66 }
67 if (!stre)
68 return 0;
69 for (i=id;i--;) {
70 if (!(slen=stre->len))
71 return 0;
72 stre = (struct _stringentry*)(((char*)stre)+slen);
73 }
74 slen=stre->len;
75
76 i = min(buflen - 1, slen);
77 if (buffer == NULL)
78 return slen; /* different to LoadString */
79 if (i>0) {
80 strncpy(buffer,stre->str,i);
81 buffer[i]=0;
82 } else {
83 if (buflen>1) {
84 buffer[0]=0;
85 return 0;
86 }
87 }
88 return i;
89}
90
91/**********************************************************************
92 * LoadMessage32W (internal)
93 */
94int LoadMessageW(HINSTANCE instance, UINT id, WORD lang,
95 LPWSTR buffer, int buflen )
96{
97 INT retval;
98 LPSTR buffer2 = NULL;
99 if (buffer) buffer2 = (char *)HeapAlloc(GetProcessHeap(), 0, buflen );
100 retval = LoadMessageA(instance,id,lang,buffer2,buflen);
101 if (buffer)
102 {
103 AsciiToUnicode(buffer2, buffer);
104 HeapFree(GetProcessHeap(), 0, buffer2);
105 }
106 return retval;
107}
108
109#if 1
110/***********************************************************************
111 * FormatMessage32A (KERNEL32.138)
112 * FIXME: missing wrap,FROM_SYSTEM message-loading,
113 */
114DWORD WIN32API FormatMessageA(
115 DWORD dwFlags,
116 LPCVOID lpSource,
117 DWORD dwMessageId,
118 DWORD dwLanguageId,
119 LPSTR lpBuffer,
120 DWORD nSize,
121 LPDWORD args /* va_list *args */
122) {
123 LPSTR target,t;
124 DWORD talloced;
125 LPSTR from,f;
126 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
127 DWORD nolinefeed = 0;
128
129 dprintf(("FormatMessageA\n"));
130
131 from = NULL;
132 if (dwFlags & FORMAT_MESSAGE_FROM_STRING) {
133 from = (char *)HeapAlloc(GetProcessHeap(),0, strlen((char *)lpSource)+1);
134 UnicodeToAscii((LPWSTR)lpSource, from);
135 }
136 if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
137 from = (char *)HeapAlloc(GetProcessHeap(),0,200 );
138 sprintf(from,"Systemmessage, messageid = 0x%08lx\n",dwMessageId);
139 }
140 if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
141 int bufsize;
142
143 dwMessageId &= 0xFFFF;
144 bufsize=LoadMessageA(0,dwMessageId,dwLanguageId,NULL,100);
145 if (bufsize) {
146 from = (char *)HeapAlloc(GetProcessHeap(), 0, bufsize + 1 );
147 LoadMessageA(0,dwMessageId,dwLanguageId,from,bufsize+1);
148 }
149 }
150 target = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
151 t = target;
152 talloced= 100;
153
154#define ADD_TO_T(c) \
155 *t++=c;\
156 if (t-target == talloced) {\
157 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
158 t = target+talloced;\
159 talloced*=2;\
160 }
161
162 if (from) {
163 f=from;
164 while (*f) {
165 if (*f=='%') {
166 int insertnr;
167 char *fmtstr,*sprintfbuf,*x,*lastf;
168 DWORD *argliststart;
169
170 fmtstr = NULL;
171 lastf = f;
172 f++;
173 if (!*f) {
174 ADD_TO_T('%');
175 continue;
176 }
177 switch (*f) {
178 case '1':case '2':case '3':case '4':case '5':
179 case '6':case '7':case '8':case '9':
180 insertnr=*f-'0';
181 switch (f[1]) {
182 case '0':case '1':case '2':case '3':
183 case '4':case '5':case '6':case '7':
184 case '8':case '9':
185 f++;
186 insertnr=insertnr*10+*f-'0';
187 f++;
188 break;
189 default:
190 f++;
191 break;
192 }
193 if (*f=='!') {
194 f++;
195 if (NULL!=(x=strchr(f,'!'))) {
196 *x='\0';
197 fmtstr=(char *)HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
198 sprintf(fmtstr,"%%%s",f);
199 f=x+1;
200 } else {
201 fmtstr=(char *)HeapAlloc(GetProcessHeap(),0,strlen(f));
202 sprintf(fmtstr,"%%%s",f);
203 f+=strlen(f); /*at \0*/
204 }
205 } else
206 fmtstr=strdup("%s");
207 if (args) {
208 if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
209 argliststart=args+insertnr-1;
210 else
211 argliststart=(*(DWORD**)args)+insertnr-1;
212
213 if (fmtstr[strlen(fmtstr)]=='s')
214 sprintfbuf=(char *)HeapAlloc(GetProcessHeap(),0,strlen((LPSTR)argliststart[0])+1);
215 else
216 sprintfbuf=(char *)HeapAlloc(GetProcessHeap(),0,100);
217
218 /* CMF - This makes a BIG assumption about va_list */
219 vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
220 x=sprintfbuf;
221 while (*x) {
222 ADD_TO_T(*x++);
223 }
224 HeapFree(GetProcessHeap(),0,sprintfbuf);
225 } else {
226 /* NULL args - copy formatstr
227 * (probably wrong)
228 */
229 while (lastf<f) {
230 ADD_TO_T(*lastf++);
231 }
232 }
233 HeapFree(GetProcessHeap(),0,fmtstr);
234 break;
235 case 'n':
236 /* FIXME: perhaps add \r too? */
237 ADD_TO_T('\n');
238 f++;
239 break;
240 case '0':
241 nolinefeed=1;
242 f++;
243 break;
244 default:ADD_TO_T(*f++)
245 break;
246
247 }
248 } else {
249 ADD_TO_T(*f++)
250 }
251 }
252 *t='\0';
253 }
254 if (!nolinefeed && t[-1]!='\n')
255 ADD_TO_T('\n');
256 talloced = strlen(target)+1;
257 if (nSize && talloced<nSize) {
258 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
259 }
260 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
261 /* nSize is the MINIMUM size */
262 *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc(GMEM_ZEROINIT,talloced);
263 memcpy(*(LPSTR*)lpBuffer,target,talloced);
264 } else
265 strncpy(lpBuffer,target,nSize);
266 HeapFree(GetProcessHeap(),0,target);
267 if (from) HeapFree(GetProcessHeap(),0,from);
268 dprintf(("FormatMessageA returned %s\n",
269 (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
270 *(LPSTR*)lpBuffer:
271 lpBuffer));
272 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
273 strlen(*(LPSTR*)lpBuffer):
274 strlen(lpBuffer);
275}
276#undef ADD_TO_T
277
278/***********************************************************************
279 * FormatMessage32W (KERNEL32.138)
280 */
281DWORD WIN32API FormatMessageW(
282 DWORD dwFlags,
283 LPCVOID lpSource,
284 DWORD dwMessageId,
285 DWORD dwLanguageId,
286 LPWSTR lpBuffer,
287 DWORD nSize,
288 LPDWORD args /* va_list *args */
289) {
290 LPSTR target,t;
291 DWORD talloced;
292 LPSTR from,f;
293 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
294 DWORD nolinefeed = 0;
295
296 dprintf(("FormatMessageW\n"));
297
298 from = NULL;
299 if (dwFlags & FORMAT_MESSAGE_FROM_STRING) {
300 from = (char *)HeapAlloc(GetProcessHeap(),0, UniStrlen((UniChar*)lpSource)+1);
301 UnicodeToAscii((LPWSTR)lpSource, from);
302 }
303 if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
304 /* gather information from system message tables ... */
305 from = (char *)HeapAlloc( GetProcessHeap(),0,200 );
306 sprintf(from,"Systemmessage, messageid = 0x%08lx\n",dwMessageId);
307 }
308 if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
309 int bufsize;
310
311 dwMessageId &= 0xFFFF;
312 bufsize=LoadMessageW(0,dwMessageId,dwLanguageId,NULL,100);
313 if (bufsize)
314 {
315 from = (char *)HeapAlloc( GetProcessHeap(), 0, bufsize + 1 );
316 LoadMessageW(0,dwMessageId,dwLanguageId,(LPWSTR)from,bufsize+1);
317 }
318 }
319 target = (char *)HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100 );
320 t = target;
321 talloced= 100;
322
323#define ADD_TO_T(c) \
324 *t++=c;\
325 if (t-target == talloced) {\
326 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
327 t = target+talloced;\
328 talloced*=2;\
329 }
330
331 if (from) {
332 f=from;
333 while (*f) {
334 if (*f=='%') {
335 int insertnr;
336 char *fmtstr,*sprintfbuf,*x;
337 DWORD *argliststart;
338
339 fmtstr = NULL;
340 f++;
341 if (!*f) {
342 ADD_TO_T('%');
343 continue;
344 }
345 switch (*f) {
346 case '1':case '2':case '3':case '4':case '5':
347 case '6':case '7':case '8':case '9':
348 insertnr=*f-'0';
349 switch (f[1]) {
350 case '0':case '1':case '2':case '3':
351 case '4':case '5':case '6':case '7':
352 case '8':case '9':
353 f++;
354 insertnr=insertnr*10+*f-'0';
355 f++;
356 break;
357 default:
358 f++;
359 break;
360 }
361 if (*f=='!') {
362 f++;
363 if (NULL!=(x=strchr(f,'!')))
364 {
365 *x='\0';
366 fmtstr=(char *)HeapAlloc( GetProcessHeap(), 0, strlen(f)+2);
367 sprintf(fmtstr,"%%%s",f);
368 f=x+1;
369 } else {
370 fmtstr=(char *)HeapAlloc(GetProcessHeap(),0,strlen(f));
371 sprintf(fmtstr,"%%%s",f);
372 f+=strlen(f); /*at \0*/
373 }
374 } else
375 fmtstr=strdup("%s");
376 if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
377 argliststart=args+insertnr-1;
378 else
379 argliststart=(*(DWORD**)args)+insertnr-1;
380
381 if (fmtstr[strlen(fmtstr)]=='s') {
382 DWORD xarr[3];
383
384 xarr[0]=(DWORD)strdup((char *)(*(argliststart+0)));
385 /* possible invalid pointers */
386 xarr[1]=*(argliststart+1);
387 xarr[2]=*(argliststart+2);
388 sprintfbuf = (char *)(char *)HeapAlloc(GetProcessHeap(),0,UniStrlen((UniChar*)argliststart[0])*2+1);
389
390 /* CMF - This makes a BIG assumption about va_list */
391 vsprintf(sprintfbuf, fmtstr, (va_list) xarr);
392 } else {
393 sprintfbuf = (char *)HeapAlloc(GetProcessHeap(),0,100);
394
395 /* CMF - This makes a BIG assumption about va_list */
396 vsprintf(sprintfbuf, fmtstr, (va_list) argliststart);
397 }
398 x=sprintfbuf;
399 while (*x) {
400 ADD_TO_T(*x++);
401 }
402 HeapFree(GetProcessHeap(),0,sprintfbuf);
403 HeapFree(GetProcessHeap(),0,fmtstr);
404 break;
405 case 'n':
406 /* FIXME: perhaps add \r too? */
407 ADD_TO_T('\n');
408 f++;
409 break;
410 case '0':
411 nolinefeed=1;
412 f++;
413 break;
414 default:ADD_TO_T(*f++)
415 break;
416
417 }
418 } else {
419 ADD_TO_T(*f++)
420 }
421 }
422 *t='\0';
423 }
424 if (!nolinefeed && t[-1]!='\n')
425 ADD_TO_T('\n');
426 talloced = strlen(target)+1;
427 if (nSize && talloced<nSize)
428 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
429 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
430 /* nSize is the MINIMUM size */
431 *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc(GMEM_ZEROINIT,talloced*2+2);
432 AsciiToUnicode(target, *(LPWSTR*)lpBuffer);
433 }
434 else AsciiToUnicode(target, lpBuffer);
435
436 dprintf(("FormatMessageW returned %s\n", target));
437
438 HeapFree(GetProcessHeap(),0,target);
439 if (from) HeapFree(GetProcessHeap(),0,from);
440 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
441 UniStrlen((UniChar*)*lpBuffer):
442 UniStrlen((UniChar*)lpBuffer);
443}
444#else
445//******************************************************************************
446//DWORD dwFlags; /* source and processing options */
447//LPCVOID lpSource; /* address of message source */
448//DWORD dwMessageId; /* requested message identifier */
449//DWORD dwLanguageId; /* language identifier for requested message */
450//LPTSTR lpBuffer; /* address of message buffer */
451//DWORD nSize; /* maximum size of message buffer */
452//va_list * Arguments; /* address of array of message inserts */
453//******************************************************************************
454DWORD WIN32API FormatMessageA(DWORD dwFlags, LPCVOID lpSource,
455 DWORD dwMessageId, DWORD dwLanguageId,
456 LPTSTR lpBuffer, DWORD nSize, va_list *Arguments)
457{
458 char *msgBuffer;
459
460 dprintf(("FormatMessageA Not Implemented\n"));
461
462 if(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
463 msgBuffer = (char *)LocalAlloc(LMEM_FIXED, nSize);
464 *(DWORD *)lpBuffer = (DWORD)msgBuffer;
465 }
466 else msgBuffer = lpBuffer;
467
468 if(nSize >= 40) {
469 //SvL: I always wanted to do this :)
470 strncpy(msgBuffer, "Windows Error 666: Reserved for future mistakes\n", 40);
471 }
472 else *msgBuffer = 0;
473 return(strlen(msgBuffer));
474}
475//******************************************************************************
476//******************************************************************************
477DWORD WIN32API FormatMessageW(DWORD dwFlags, LPCVOID lpSource,
478 DWORD dwMessageId, DWORD dwLanguageId,
479 LPWSTR lpBuffer, DWORD nSize, va_list *Arguments)
480{
481 WCHAR *msgBuffer;
482
483 dprintf(("FormatMessageW Not Implemented\n"));
484
485 if(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
486 msgBuffer = (WCHAR *)LocalAlloc(LMEM_FIXED, nSize*sizeof(USHORT));
487 *(DWORD *)lpBuffer = (DWORD)msgBuffer;
488 }
489 else msgBuffer = lpBuffer;
490
491 if(nSize >= 40) {
492 //SvL: I always wanted to do this :)
493 AsciiToUnicode("Windows Error 666: Reserved for future mistakes\n", msgBuffer);
494 }
495 else *msgBuffer = 0;
496 return(UniStrlen((UniChar*)msgBuffer));
497}
498//******************************************************************************
499//******************************************************************************
500#endif
Note: See TracBrowser for help on using the repository browser.