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

Last change on this file since 46 was 46, checked in by sandervl, 26 years ago

* empty log message *

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