~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/dlls/kernel32/format_msg.c

Version: ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~ [ wine-1.0-rc5 ] ~ [ wine-1.0-rc4 ] ~ [ wine-1.0-rc3 ] ~ [ wine-1.0-rc2 ] ~ [ wine-1.0-rc1 ] ~ [ wine-0.9.61 ] ~ [ wine-0.9.60 ] ~ [ wine-0.9.59 ] ~ [ wine-0.9.58 ] ~ [ wine-0.9.57 ] ~ [ wine-0.9.56 ] ~ [ wine-0.9.55 ] ~ [ wine-0.9.54 ] ~ [ wine-0.9.53 ] ~ [ wine-0.9.52 ] ~ [ wine-0.9.51 ] ~ [ wine-0.9.50 ] ~ [ wine-0.9.49 ] ~ [ wine-0.9.48 ] ~ [ wine-0.9.47 ] ~ [ wine-0.9.46 ] ~ [ wine-0.9.45 ] ~ [ wine-0.9.44 ] ~ [ wine-0.9.43 ] ~ [ wine-0.9.42 ] ~ [ wine-0.9.41 ] ~ [ wine-0.9.40 ] ~ [ wine-0.9.39 ] ~ [ wine-0.9.38 ] ~ [ wine-0.9.37 ] ~ [ wine-0.9.36 ] ~ [ wine-0.9.35 ] ~ [ wine-0.9.34 ] ~ [ wine-0.9.33 ] ~ [ wine-0.9.32 ] ~ [ wine-0.9.31 ] ~ [ wine-0.9.30 ] ~ [ wine-0.9.29 ] ~ [ wine-0.9.28 ] ~ [ wine-0.9.27 ] ~ [ wine-0.9.26 ] ~ [ wine-0.9.25 ] ~ [ wine-0.9.24 ] ~ [ wine-0.9.23 ] ~ [ wine-0.9.22 ] ~ [ wine-0.9.21 ] ~ [ wine-0.9.20 ] ~ [ wine-0.9.19 ] ~ [ wine-0.9.18 ] ~ [ wine-0.9.17 ] ~ [ wine-0.9.16 ] ~ [ wine-0.9.15 ] ~ [ wine-0.9.14 ] ~ [ wine-0.9.13 ] ~ [ wine-0.9.12 ] ~ [ wine-0.9.11 ] ~ [ wine-0.9.10 ] ~ [ wine-0.9.9 ] ~ [ wine-0.9.8 ] ~ [ wine-0.9.7 ] ~ [ wine-0.9.6 ] ~ [ wine-0.9.5 ] ~ [ wine-0.9.4 ] ~ [ wine-0.9.3 ] ~ [ wine-0.9.2 ] ~ [ wine-0.9.1 ] ~ [ wine-0.9 ] ~ [ wine20050930 ] ~ [ wine20050830 ] ~ [ wine20050725 ] ~ [ wine20050628 ] ~ [ wine20050524 ] ~ [ wine20050419 ] ~ [ wine20050310 ] ~ [ wine20050211 ] ~ [ wine20050111 ] ~ [ wine20041201 ] ~ [ wine20041019 ] ~ [ wine20040914 ] ~ [ wine20040813 ] ~ [ wine20040716 ] ~ [ wine20040615 ] ~ [ wine20040505 ] ~ [ wine20040408 ] ~ [ wine20040309 ] ~ [ wine20040213 ] ~ [ wine20040121 ] ~ [ wine20031212 ] ~ [ wine20031118 ] ~ [ wine20031016 ] ~ [ wine20030911 ] ~ [ wine20030813 ] ~ [ wine20030709 ] ~ [ wine20030618 ] ~ [ wine20030508 ] ~ [ wine20030408 ] ~ [ wine20030318 ] ~ [ wine20030219 ] ~ [ wine20030115 ] ~ [ wine20021219 ] ~ [ wine20021125 ] ~ [ wine20021031 ] ~ [ wine20021007 ] ~ [ wine20020904 ] ~ [ wine20020804 ] ~ [ wine20020710 ] ~ [ wine20020605 ] ~ [ wine20020509 ] ~ [ wine20020411 ] ~ [ wine20020310 ] ~ [ wine20020228 ] ~ [ wine20011226 ] ~ [ wine20011108 ] ~ [ wine20011004 ] ~ [ wine20010824 ] ~ [ wine20010731 ] ~ [ wine20010629 ] ~ [ wine20010510 ] ~ [ wine20010418 ] ~ [ wine20010326 ] ~ [ wine20010305 ] ~ [ wine20010216 ] ~ [ wine20010112 ] ~ [ wine20001222 ] ~ [ wine20001202 ] ~ [ wine20001026 ] ~ [ wine20001002 ] ~ [ wine20000909 ] ~ [ wine20000821 ] ~ [ wine20000801 ] ~ [ wine20000716 ] ~ [ wine20000326 ] ~ [ wine20000227 ] ~ [ wine20000130 ] ~ [ wine20000109 ] ~

  1 /*
  2  * FormatMessage implementation
  3  *
  4  * Copyright 1996 Marcus Meissner
  5  *
  6  * This library is free software; you can redistribute it and/or
  7  * modify it under the terms of the GNU Lesser General Public
  8  * License as published by the Free Software Foundation; either
  9  * version 2.1 of the License, or (at your option) any later version.
 10  *
 11  * This library is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 14  * Lesser General Public License for more details.
 15  *
 16  * You should have received a copy of the GNU Lesser General Public
 17  * License along with this library; if not, write to the Free Software
 18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 19  */
 20 
 21 #include "config.h"
 22 
 23 #include <stdarg.h>
 24 #include <stdio.h>
 25 #include <string.h>
 26 
 27 #include "ntstatus.h"
 28 #define WIN32_NO_STATUS
 29 #include "windef.h"
 30 #include "winbase.h"
 31 #include "winerror.h"
 32 #include "winternl.h"
 33 #include "winuser.h"
 34 #include "winnls.h"
 35 #include "wine/unicode.h"
 36 #include "kernel_private.h"
 37 #include "wine/debug.h"
 38 
 39 WINE_DEFAULT_DEBUG_CHANNEL(resource);
 40 
 41 
 42 /* Messages...used by FormatMessage (KERNEL32.something)
 43  *
 44  * They can be specified either directly or using a message ID and
 45  * loading them from the resource.
 46  *
 47  * The resourcedata has following format:
 48  * start:
 49  * 0: DWORD nrofentries
 50  * nrofentries * subentry:
 51  *      0: DWORD firstentry
 52  *      4: DWORD lastentry
 53  *      8: DWORD offset from start to the stringentries
 54  *
 55  * (lastentry-firstentry) * stringentry:
 56  * 0: WORD len (0 marks end)    [ includes the 4 byte header length ]
 57  * 2: WORD flags
 58  * 4: CHAR[len-4]
 59  *      (stringentry i of a subentry refers to the ID 'firstentry+i')
 60  *
 61  * Yes, ANSI strings in win32 resources. Go figure.
 62  */
 63 
 64 static const WCHAR PCNTFMTWSTR[] = { '%','%','%','s',0 };
 65 static const WCHAR FMTWSTR[] = { '%','s',0 };
 66 
 67 /**********************************************************************
 68  *      load_messageW           (internal)
 69  */
 70 static LPWSTR load_messageW( HMODULE module, UINT id, WORD lang )
 71 {
 72     const MESSAGE_RESOURCE_ENTRY *mre;
 73     WCHAR *buffer;
 74 
 75     TRACE("module = %p, id = %08x\n", module, id );
 76 
 77     if (!module) module = GetModuleHandleW( NULL );
 78     if (RtlFindMessage( module, RT_MESSAGETABLE, lang, id, &mre ) != STATUS_SUCCESS) return NULL;
 79 
 80     if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
 81     {
 82         int len = (strlenW( (const WCHAR *)mre->Text ) + 1) * sizeof(WCHAR);
 83         if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
 84         memcpy( buffer, mre->Text, len );
 85     }
 86     else
 87     {
 88         int len = MultiByteToWideChar( CP_ACP, 0, (const char *)mre->Text, -1, NULL, 0 );
 89         if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
 90         MultiByteToWideChar( CP_ACP, 0, (const char*)mre->Text, -1, buffer, len );
 91     }
 92     TRACE("returning %s\n", wine_dbgstr_w(buffer));
 93     return buffer;
 94 }
 95 
 96 
 97 /**********************************************************************
 98  *      load_messageA           (internal)
 99  */
100 static LPSTR load_messageA( HMODULE module, UINT id, WORD lang )
101 {
102     const MESSAGE_RESOURCE_ENTRY *mre;
103     char *buffer;
104 
105     TRACE("module = %p, id = %08x\n", module, id );
106 
107     if (!module) module = GetModuleHandleW( NULL );
108     if (RtlFindMessage( module, RT_MESSAGETABLE, lang, id, &mre ) != STATUS_SUCCESS) return NULL;
109 
110     if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
111     {
112         int len = WideCharToMultiByte( CP_ACP, 0, (const WCHAR *)mre->Text, -1, NULL, 0, NULL, NULL );
113         if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
114         WideCharToMultiByte( CP_ACP, 0, (const WCHAR *)mre->Text, -1, buffer, len, NULL, NULL );
115     }
116     else
117     {
118         int len = strlen((const char*)mre->Text) + 1;
119         if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
120         memcpy( buffer, mre->Text, len );
121     }
122     TRACE("returning %s\n", wine_dbgstr_a(buffer));
123     return buffer;
124 }
125 
126 
127 /***********************************************************************
128  *           FormatMessageA   (KERNEL32.@)
129  * FIXME: missing wrap,
130  */
131 DWORD WINAPI FormatMessageA(
132         DWORD   dwFlags,
133         LPCVOID lpSource,
134         DWORD   dwMessageId,
135         DWORD   dwLanguageId,
136         LPSTR   lpBuffer,
137         DWORD   nSize,
138         va_list* _args )
139 {
140     LPDWORD args=(LPDWORD)_args;
141     DWORD ret = 0;
142 #if defined(__i386__) || defined(__sparc__)
143 /* This implementation is completely dependent on the format of the va_list on x86 CPUs */
144     LPSTR       target,t;
145     DWORD       talloced;
146     LPSTR       from,f;
147     DWORD       width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
148     BOOL    eos = FALSE;
149     CHAR        ch;
150 
151     TRACE("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
152           dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
153     if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
154         &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
155            || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
156 
157     if (!lpBuffer)
158     {
159         SetLastError(ERROR_NOT_ENOUGH_MEMORY);
160         return 0;
161     }
162 
163     if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
164         FIXME("line wrapping (%u) not supported.\n", width);
165     from = NULL;
166     if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
167     {
168         from = HeapAlloc( GetProcessHeap(), 0, strlen((LPCSTR)lpSource)+1 );
169         strcpy( from, (LPCSTR)lpSource );
170     }
171     else {
172         from = NULL;
173         if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
174             from = load_messageA( (HMODULE)lpSource, dwMessageId, dwLanguageId );
175         if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
176             from = load_messageA( kernel32_handle, dwMessageId, dwLanguageId );
177 
178         if (!from)
179         {
180             SetLastError (ERROR_RESOURCE_LANG_NOT_FOUND);
181             return 0;
182         }
183     }
184     target      = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
185     t   = target;
186     talloced= 100;
187 
188 #define ADD_TO_T(c) do { \
189         *t++=c;\
190         if ((DWORD)(t-target) == talloced) {\
191             target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
192             t = target+talloced;\
193             talloced*=2;\
194       }\
195 } while (0)
196 
197     if (from) {
198         f=from;
199         if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
200             while (*f && !eos)
201                 ADD_TO_T(*f++);
202         }
203         else {
204             while (*f && !eos) {
205                 if (*f=='%') {
206                     int insertnr;
207                     char *fmtstr,*x,*lastf;
208                     DWORD *argliststart;
209 
210                     fmtstr = NULL;
211                     lastf = f;
212                     f++;
213                     if (!*f) {
214                         ADD_TO_T('%');
215                         continue;
216                     }
217                     switch (*f) {
218                     case '1':case '2':case '3':case '4':case '5':
219                     case '6':case '7':case '8':case '9':
220                         insertnr=*f-'';
221                         switch (f[1]) {
222                         case '':case '1':case '2':case '3':
223                         case '4':case '5':case '6':case '7':
224                         case '8':case '9':
225                             f++;
226                             insertnr=insertnr*10+*f-'';
227                             f++;
228                             break;
229                         default:
230                             f++;
231                             break;
232                         }
233                         if (*f=='!') {
234                             f++;
235                             if (NULL!=(x=strchr(f,'!'))) {
236                                 *x='\0';
237                                 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
238                                 sprintf(fmtstr,"%%%s",f);
239                                 f=x+1;
240                             } else {
241                                 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
242                                 sprintf(fmtstr,"%%%s",f);
243                                 f+=strlen(f); /*at \0*/
244                             }
245                         } else {
246                             if(!args) break;
247                             fmtstr = HeapAlloc(GetProcessHeap(),0,3);
248                             strcpy( fmtstr, "%s" );
249                         }
250                         if (args) {
251                             int sz;
252                             LPSTR b;
253 
254                             if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
255                                 argliststart=args+insertnr-1;
256                             else
257                                 argliststart=(*(DWORD**)args)+insertnr-1;
258 
259                                 /* FIXME: precision and width components are not handled correctly */
260                             if ( (strcmp(fmtstr, "%ls") == 0) || (strcmp(fmtstr,"%S") == 0) ) {
261                                 sz = WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, NULL, 0, NULL, NULL);
262                                 b = HeapAlloc(GetProcessHeap(), 0, sz);
263                                 WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, b, sz, NULL, NULL);
264                             } else {
265                                 b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 1000);
266                                 /* CMF - This makes a BIG assumption about va_list */
267                                 TRACE("A BIG assumption\n");
268                                 vsnprintf(b, sz, fmtstr, (va_list) argliststart);
269                             }
270                             for (x=b; *x; x++) ADD_TO_T(*x);
271 
272                             HeapFree(GetProcessHeap(),0,b);
273                         } else {
274                                 /* NULL args - copy formatstr
275                                  * (probably wrong)
276                                  */
277                             while ((lastf<f)&&(*lastf)) {
278                                 ADD_TO_T(*lastf++);
279                             }
280                         }
281                         HeapFree(GetProcessHeap(),0,fmtstr);
282                         break;
283                     case 'n':
284                         ADD_TO_T('\r');
285                         ADD_TO_T('\n');
286                         f++;
287                         break;
288                     case '':
289                         eos = TRUE;
290                         f++;
291                         break;
292                     default:
293                         ADD_TO_T(*f++);
294                         break;
295                     }
296                 } else {
297                     ch = *f;
298                     f++;
299                     if (ch == '\r') {
300                         if (*f == '\n')
301                             f++;
302                         if(width)
303                             ADD_TO_T(' ');
304                         else
305                         {
306                             ADD_TO_T('\r');
307                             ADD_TO_T('\n');
308                         }
309                     } else {
310                         if (ch == '\n')
311                         {
312                             if(width)
313                                 ADD_TO_T(' ');
314                             else
315                             {
316                                 ADD_TO_T('\r');
317                                 ADD_TO_T('\n');
318                             }
319                         }
320                         else
321                             ADD_TO_T(ch);
322                     }
323                 }
324             }
325         }
326         *t='\0';
327     }
328     talloced = strlen(target)+1;
329     if (nSize && talloced<nSize) {
330         target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
331     }
332     TRACE("-- %s\n",debugstr_a(target));
333     if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
334         *((LPVOID*)lpBuffer) = LocalAlloc(LMEM_ZEROINIT,max(nSize, talloced));
335         memcpy(*(LPSTR*)lpBuffer,target,talloced);
336     } else {
337         lstrcpynA(lpBuffer,target,nSize);
338     }
339     HeapFree(GetProcessHeap(),0,target);
340     HeapFree(GetProcessHeap(),0,from);
341     ret = (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ? strlen(*(LPSTR*)lpBuffer) : strlen(lpBuffer);
342 #endif /* __i386__ */
343     TRACE("-- returning %d\n", ret);
344     return ret;
345 }
346 #undef ADD_TO_T
347 
348 
349 /***********************************************************************
350  *           FormatMessageW   (KERNEL32.@)
351  */
352 DWORD WINAPI FormatMessageW(
353         DWORD   dwFlags,
354         LPCVOID lpSource,
355         DWORD   dwMessageId,
356         DWORD   dwLanguageId,
357         LPWSTR  lpBuffer,
358         DWORD   nSize,
359         va_list* _args )
360 {
361     LPDWORD args=(LPDWORD)_args;
362 #if defined(__i386__) || defined(__sparc__)
363 /* This implementation is completely dependent on the format of the va_list on x86 CPUs */
364     LPWSTR target,t;
365     DWORD talloced;
366     LPWSTR from,f;
367     DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
368     BOOL eos = FALSE;
369     WCHAR ch;
370 
371     TRACE("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
372           dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
373     if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
374         &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
375            || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
376 
377     if (!lpBuffer)
378     {
379         SetLastError(ERROR_INVALID_PARAMETER);
380         return 0;
381     }
382 
383     if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
384         FIXME("line wrapping not supported.\n");
385     from = NULL;
386     if (dwFlags & FORMAT_MESSAGE_FROM_STRING) {
387         from = HeapAlloc( GetProcessHeap(), 0, (strlenW((LPCWSTR)lpSource) + 1) *
388             sizeof(WCHAR) );
389         strcpyW( from, (LPCWSTR)lpSource );
390     }
391     else {
392         from = NULL;
393         if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
394             from = load_messageW( (HMODULE)lpSource, dwMessageId, dwLanguageId );
395         if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
396             from = load_messageW( kernel32_handle, dwMessageId, dwLanguageId );
397 
398         if (!from)
399         {
400             SetLastError (ERROR_RESOURCE_LANG_NOT_FOUND);
401             return 0;
402         }
403     }
404     target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100 * sizeof(WCHAR) );
405     t = target;
406     talloced= 100;
407 
408 #define ADD_TO_T(c)  do {\
409     *t++=c;\
410     if ((DWORD)(t-target) == talloced) {\
411         target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2*sizeof(WCHAR));\
412         t = target+talloced;\
413         talloced*=2;\
414     } \
415 } while (0)
416 
417     if (from) {
418         f=from;
419         if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
420             while (*f && !eos)
421                 ADD_TO_T(*f++);
422         }
423         else {
424             while (*f && !eos) {
425                 if (*f=='%') {
426                     int insertnr;
427                     WCHAR *fmtstr,*sprintfbuf,*x;
428                     DWORD *argliststart;
429 
430                     fmtstr = NULL;
431                     f++;
432                     if (!*f) {
433                         ADD_TO_T('%');
434                         continue;
435                     }
436 
437                     switch (*f) {
438                     case '1':case '2':case '3':case '4':case '5':
439                     case '6':case '7':case '8':case '9':
440                         insertnr=*f-'';
441                         switch (f[1]) {
442                         case '':case '1':case '2':case '3':
443                         case '4':case '5':case '6':case '7':
444                         case '8':case '9':
445                             f++;
446                             insertnr=insertnr*10+*f-'';
447                             f++;
448                             break;
449                         default:
450                             f++;
451                             break;
452                         }
453                         if (*f=='!') {
454                             f++;
455                             if (NULL!=(x=strchrW(f,'!'))) {
456                                 *x='\0';
457                                 fmtstr=HeapAlloc( GetProcessHeap(), 0,(strlenW(f)+2)*sizeof(WCHAR));
458                                 sprintfW(fmtstr,PCNTFMTWSTR,f);
459                                 f=x+1;
460                             } else {
461                                 fmtstr=HeapAlloc(GetProcessHeap(),0,(strlenW(f)+2)*sizeof(WCHAR));
462                                 sprintfW(fmtstr,PCNTFMTWSTR,f);
463                                 f+=strlenW(f); /*at \0*/
464                             }
465                         } else {
466                             if(!args) break;
467                             fmtstr = HeapAlloc( GetProcessHeap(),0,3*sizeof(WCHAR));
468                             strcpyW( fmtstr, FMTWSTR );
469                         }
470                         if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
471                             argliststart=args+insertnr-1;
472                         else
473                             argliststart=(*(DWORD**)args)+insertnr-1;
474 
475                         if (fmtstr[strlenW(fmtstr)-1]=='s' && argliststart[0]) {
476                             DWORD xarr[3];
477 
478                             xarr[0]=*(argliststart+0);
479                             /* possible invalid pointers */
480                             xarr[1]=*(argliststart+1);
481                             xarr[2]=*(argliststart+2);
482                             sprintfbuf=HeapAlloc(GetProcessHeap(),0,(strlenW((LPWSTR)argliststart[0])*2+1)*sizeof(WCHAR));
483 
484                             /* CMF - This makes a BIG assumption about va_list */
485                             vsprintfW(sprintfbuf, fmtstr, (va_list) xarr);
486                         } else {
487                             sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
488 
489                             /* CMF - This makes a BIG assumption about va_list */
490                             vsprintfW(sprintfbuf, fmtstr, (va_list) argliststart);
491                         }
492                         x=sprintfbuf;
493                         while (*x) {
494                             ADD_TO_T(*x++);
495                         }
496                         HeapFree(GetProcessHeap(),0,sprintfbuf);
497                         HeapFree(GetProcessHeap(),0,fmtstr);
498                         break;
499                     case 'n':
500                         ADD_TO_T('\r');
501                         ADD_TO_T('\n');
502                         f++;
503                         break;
504                     case '':
505                         eos = TRUE;
506                         f++;
507                         break;
508                     default:
509                         ADD_TO_T(*f++);
510                         break;
511                     }
512                 } else {
513                     ch = *f;
514                     f++;
515                     if (ch == '\r') {
516                         if (*f == '\n')
517                             f++;
518                         if(width)
519                             ADD_TO_T(' ');
520                         else
521                         {
522                             ADD_TO_T('\r');
523                             ADD_TO_T('\n');
524                         }
525                     } else {
526                         if (ch == '\n')
527                         {
528                             if(width)
529                                 ADD_TO_T(' ');
530                             else
531                             {
532                                 ADD_TO_T('\r');
533                                 ADD_TO_T('\n');
534                             }
535                         }
536                         else
537                             ADD_TO_T(ch);
538                     }
539                 }
540             }
541         }
542         *t='\0';
543     }
544     talloced = strlenW(target)+1;
545     if (nSize && talloced<nSize)
546         target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize*sizeof(WCHAR));
547     if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
548         /* nSize is the MINIMUM size */
549         DWORD len = strlenW(target) + 1;
550         *((LPVOID*)lpBuffer) = LocalAlloc(LMEM_ZEROINIT,len*sizeof(WCHAR));
551         strcpyW(*(LPWSTR*)lpBuffer, target);
552     }
553     else lstrcpynW(lpBuffer, target, nSize);
554 
555     HeapFree(GetProcessHeap(),0,target);
556     HeapFree(GetProcessHeap(),0,from);
557     TRACE("ret=%s\n", wine_dbgstr_w((dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
558         *(LPWSTR*)lpBuffer : lpBuffer));
559     return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
560         strlenW(*(LPWSTR*)lpBuffer):
561             strlenW(lpBuffer);
562 #else
563     return 0;
564 #endif /* __i386__ */
565 }
566 #undef ADD_TO_T
567 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.