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

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

Add: added cvs variable $Id$ to the source files.

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