Release 970202
[wine/multimedia.git] / misc / lstr.c
blob5ea450912947508fc20e682e24213af6318ad587
1 /*
2 * String functions
4 * Copyright 1993 Yngvi Sigurjonsson (yngvi@hafro.is)
5 * Copyright 1996 Marcus Meissner
6 */
8 #include <stdio.h>
9 #include <stdarg.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <ctype.h>
14 #include "windows.h"
15 #include "winnt.h" /* HEAP_ macros */
16 #include "heap.h"
17 #include "ldt.h"
18 #include "module.h"
19 #include "stddebug.h"
20 #include "debug.h"
22 #define ToUpper(c) toupper(c)
23 #define ToLower(c) tolower(c)
26 /* Funny to divide them between user and kernel. */
28 /* IsCharAlpha USER 433 */
29 BOOL16 IsCharAlpha16(CHAR ch)
31 return isalpha(ch); /* This is probably not right for NLS */
34 /* IsCharAlphanumeric USER 434 */
35 BOOL16 IsCharAlphanumeric16(CHAR ch)
37 return isalnum(ch);
40 /* IsCharUpper USER 435 */
41 BOOL16 IsCharUpper16(CHAR ch)
43 return isupper(ch);
46 /* IsCharLower USER 436 */
47 BOOL16 IsCharLower16(CHAR ch)
49 return islower(ch);
52 /***********************************************************************
53 * AnsiUpper16 (USER.431)
55 SEGPTR AnsiUpper16( SEGPTR strOrChar )
57 /* I am not sure if the locale stuff works with toupper, but then again
58 I am not sure if the Linux libc locale stuffs works at all */
60 /* uppercase only one char if strOrChar < 0x10000 */
61 if (HIWORD(strOrChar))
63 char *s;
64 for (s = PTR_SEG_TO_LIN(strOrChar); *s; s++) *s = toupper(*s);
65 return strOrChar;
67 else return (SEGPTR)ToUpper( (int)strOrChar );
71 /***********************************************************************
72 * AnsiUpperBuff16 (USER.437)
74 UINT16 AnsiUpperBuff16( LPSTR str, UINT16 len )
76 UINT32 count = len ? len : 65536;
77 for (; count; count--, str++) *str = toupper(*str);
78 return len;
81 /***********************************************************************
82 * AnsiLower16 (USER.432)
84 SEGPTR AnsiLower16( SEGPTR strOrChar )
86 /* I am not sure if the locale stuff works with toupper, but then again
87 I am not sure if the Linux libc locale stuffs works at all */
89 /* lowercase only one char if strOrChar < 0x10000 */
90 if (HIWORD(strOrChar))
92 char *s;
93 for (s = PTR_SEG_TO_LIN( strOrChar ); *s; s++) *s = tolower( *s );
94 return strOrChar;
96 else return (SEGPTR)tolower( (int)strOrChar );
100 /***********************************************************************
101 * AnsiLowerBuff16 (USER.438)
103 UINT16 AnsiLowerBuff16( LPSTR str, UINT16 len )
105 UINT32 count = len ? len : 65536;
106 for (; count; count--, str++) *str = tolower(*str);
107 return len;
111 /***********************************************************************
112 * AnsiNext16 (USER.472)
114 SEGPTR AnsiNext16(SEGPTR current)
116 return (*(char *)PTR_SEG_TO_LIN(current)) ? current + 1 : current;
120 /***********************************************************************
121 * AnsiPrev16 (USER.473)
123 SEGPTR AnsiPrev16( SEGPTR start, SEGPTR current )
125 return (current == start) ? start : current - 1;
129 /***********************************************************************
130 * OutputDebugString (KERNEL.115)
132 void OutputDebugString( LPCSTR str )
134 char *module;
135 char *p, *buffer = HeapAlloc( GetProcessHeap(), 0, strlen(str)+1 );
136 /* Remove CRs */
137 for (p = buffer; *str; str++) if (*str != '\r') *p++ = *str;
138 *p = '\0';
139 if ((p > buffer) && (p[-1] == '\n')) p[1] = '\0'; /* Remove trailing \n */
140 module = MODULE_GetModuleName( GetExePtr(GetCurrentTask()) );
141 fprintf( stderr, "OutputDebugString: %s says '%s'\n",
142 module ? module : "???", buffer );
143 HeapFree( GetProcessHeap(), 0, buffer );
147 /***********************************************************************
148 * CharNext32A (USER32.28)
150 LPSTR CharNext32A( LPCSTR ptr )
152 if (!*ptr) return (LPSTR)ptr;
153 if (IsDBCSLeadByte32( *ptr )) return (LPSTR)(ptr + 2);
154 return (LPSTR)(ptr + 1);
158 /***********************************************************************
159 * CharNextEx32A (USER32.29)
161 LPSTR CharNextEx32A( WORD codepage, LPCSTR ptr, DWORD flags )
163 if (!*ptr) return (LPSTR)ptr;
164 if (IsDBCSLeadByteEx( codepage, *ptr )) return (LPSTR)(ptr + 2);
165 return (LPSTR)(ptr + 1);
169 /***********************************************************************
170 * CharNextExW (USER32.30)
172 LPWSTR CharNextEx32W(WORD codepage,LPCWSTR x,DWORD flags)
174 /* FIXME: add DBCS / codepage stuff */
175 if (*x) return (LPWSTR)(x+1);
176 else return (LPWSTR)x;
179 /***********************************************************************
180 * CharNextW (USER32.31)
182 LPWSTR CharNext32W(LPCWSTR x)
184 if (*x) return (LPWSTR)(x+1);
185 else return (LPWSTR)x;
188 /***********************************************************************
189 * CharPrev32A (USER32.32)
191 LPSTR CharPrev32A( LPCSTR start, LPCSTR ptr )
193 while (*start && (start < ptr))
195 LPCSTR next = CharNext32A( start );
196 if (next > ptr) break;
197 start = next;
199 return (LPSTR)start;
203 /***********************************************************************
204 * CharPrevEx32A (USER32.33)
206 LPSTR CharPrevEx32A( WORD codepage, LPCSTR start, LPCSTR ptr, DWORD flags )
208 while (*start && (start < ptr))
210 LPCSTR next = CharNextEx32A( codepage, start, flags );
211 if (next > ptr) break;
212 start = next;
214 return (LPSTR)start;
218 /***********************************************************************
219 * CharPrevExW (USER32.34)
221 LPWSTR CharPrevEx32W(WORD codepage,LPCWSTR start,LPCWSTR x,DWORD flags)
223 /* FIXME: add DBCS / codepage stuff */
224 if (x>start) return (LPWSTR)(x-1);
225 else return (LPWSTR)x;
228 /***********************************************************************
229 * CharPrevW (USER32.35)
231 LPWSTR CharPrev32W(LPCWSTR start,LPCWSTR x)
233 if (x>start) return (LPWSTR)(x-1);
234 else return (LPWSTR)x;
237 /***********************************************************************
238 * CharLowerA (USER32.24)
239 * FIXME: handle current locale
241 LPSTR CharLower32A(LPSTR x)
243 LPSTR s;
245 if (HIWORD(x))
247 s=x;
248 while (*s)
250 *s=tolower(*s);
251 s++;
253 return x;
255 else return (LPSTR)tolower(LOWORD(x));
258 /***********************************************************************
259 * CharLowerBuffA (USER32.25)
260 * FIXME: handle current locale
262 DWORD CharLowerBuff32A(LPSTR x,DWORD buflen)
264 DWORD done=0;
266 while (*x && (buflen--))
268 *x=tolower(*x);
269 x++;
270 done++;
272 return done;
275 /***********************************************************************
276 * CharLowerBuffW (USER32.26)
277 * FIXME: handle current locale
279 DWORD CharLowerBuff32W(LPWSTR x,DWORD buflen)
281 DWORD done=0;
283 while (*x && (buflen--))
285 *x=tolower(*x);
286 x++;
287 done++;
289 return done;
292 /***********************************************************************
293 * CharLowerW (USER32.27)
294 * FIXME: handle current locale
296 LPWSTR CharLower32W(LPWSTR x)
298 if (HIWORD(x))
300 LPWSTR s = x;
301 while (*s)
303 *s=tolower(*s);
304 s++;
306 return x;
308 else return (LPWSTR)tolower(LOWORD(x));
311 /***********************************************************************
312 * CharUpper32A (USER32.40)
313 * FIXME: handle current locale
315 LPSTR CharUpper32A(LPSTR x)
317 if (HIWORD(x))
319 LPSTR s = x;
320 while (*s)
322 *s=toupper(*s);
323 s++;
325 return x;
327 else return (LPSTR)toupper(LOWORD(x));
330 /***********************************************************************
331 * CharUpperBuffA (USER32.41)
332 * FIXME: handle current locale
334 DWORD CharUpperBuff32A(LPSTR x,DWORD buflen)
336 DWORD done=0;
338 while (*x && (buflen--))
340 *x=toupper(*x);
341 x++;
342 done++;
344 return done;
347 /***********************************************************************
348 * CharUpperBuffW (USER32.42)
349 * FIXME: handle current locale
351 DWORD CharUpperBuff32W(LPWSTR x,DWORD buflen)
353 DWORD done=0;
355 while (*x && (buflen--))
357 *x=toupper(*x);
358 x++;
359 done++;
361 return done;
364 /***********************************************************************
365 * CharUpperW (USER32.43)
366 * FIXME: handle current locale
368 LPWSTR CharUpper32W(LPWSTR x)
370 if (HIWORD(x))
372 LPWSTR s = x;
373 while (*s)
375 *s=toupper(*s);
376 s++;
378 return x;
380 else return (LPWSTR)toupper(LOWORD(x));
383 /***********************************************************************
384 * IsCharAlphaA (USER32.330)
385 * FIXME: handle current locale
387 BOOL32 IsCharAlpha32A(CHAR x)
389 return isalpha(x);
392 /***********************************************************************
393 * IsCharAlphaNumericA (USER32.331)
394 * FIXME: handle current locale
396 BOOL32 IsCharAlphaNumeric32A(CHAR x)
398 return isalnum(x);
401 /***********************************************************************
402 * IsCharAlphaNumericW (USER32.332)
403 * FIXME: handle current locale
405 BOOL32 IsCharAlphaNumeric32W(WCHAR x)
407 return isalnum(x);
410 /***********************************************************************
411 * IsCharAlphaW (USER32.333)
412 * FIXME: handle current locale
414 BOOL32 IsCharAlpha32W(WCHAR x)
416 return isalpha(x);
419 /***********************************************************************
420 * IsCharLower32A (USER32.334)
421 * FIXME: handle current locale
423 BOOL32 IsCharLower32A(CHAR x)
425 return islower(x);
428 /***********************************************************************
429 * IsCharLower32W (USER32.335)
430 * FIXME: handle current locale
432 BOOL32 IsCharLower32W(WCHAR x)
434 return islower(x);
437 /***********************************************************************
438 * IsCharUpper32A (USER32.336)
439 * FIXME: handle current locale
441 BOOL32 IsCharUpper32A(CHAR x)
443 return isupper(x);
446 /***********************************************************************
447 * IsCharUpper32W (USER32.337)
448 * FIXME: handle current locale
450 BOOL32 IsCharUpper32W(WCHAR x)
452 return isupper(x);
455 /***********************************************************************
456 * FormatMessageA (KERNEL32.138) Library Version
457 * FIXME: missing wrap,FROM_SYSTEM message-loading,
459 DWORD
460 FormatMessage32A(
461 DWORD dwFlags,
462 LPCVOID lpSource,
463 DWORD dwMessageId,
464 DWORD dwLanguageId,
465 LPSTR lpBuffer,
466 DWORD nSize,
467 LPDWORD args /* va_list *args */
469 LPSTR target,t;
470 DWORD talloced;
471 LPSTR from,f;
472 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
473 DWORD nolinefeed = 0;
475 dprintf_resource(stddeb,
476 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
477 dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args
479 if (width)
480 fprintf(stdnimp," - line wrapping not supported.\n");
481 from = NULL;
482 if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
483 from = HEAP_strdupA( GetProcessHeap(), 0, (LPSTR)lpSource);
484 if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
485 /* gather information from system message tables ... */
486 fprintf(stdnimp," - FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
488 if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
489 INT32 bufsize;
491 dwMessageId &= 0xFFFF;
492 bufsize=LoadMessage32A(0,dwMessageId,dwLanguageId,NULL,100);
493 if (bufsize) {
494 from = HeapAlloc( GetProcessHeap(), 0, bufsize + 1 );
495 LoadMessage32A(0,dwMessageId,dwLanguageId,from,bufsize+1);
498 target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
499 t = target;
500 talloced= 100;
502 #define ADD_TO_T(c) \
503 *t++=c;\
504 if (t-target == talloced) {\
505 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
506 t = target+talloced;\
507 talloced*=2;\
510 if (from) {
511 f=from;
512 while (*f) {
513 if (*f=='%') {
514 int insertnr;
515 char *fmtstr,*sprintfbuf,*x;
516 DWORD *argliststart;
518 fmtstr = NULL;
519 f++;
520 if (!*f) {
521 ADD_TO_T('%');
522 continue;
524 switch (*f) {
525 case '1':case '2':case '3':case '4':case '5':
526 case '6':case '7':case '8':case '9':
527 insertnr=*f-'0';
528 switch (f[1]) {
529 case '0':case '1':case '2':case '3':
530 case '4':case '5':case '6':case '7':
531 case '8':case '9':
532 f++;
533 insertnr=insertnr*10+*f-'0';
534 f++;
535 break;
536 default:
537 f++;
538 break;
540 if (*f=='!') {
541 f++;
542 if (NULL!=(x=strchr(f,'!'))) {
543 *x='\0';
544 fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
545 sprintf(fmtstr,"%%%s",f);
546 f=x+1;
548 } else
549 fmtstr=HEAP_strdupA(GetProcessHeap(),0,"%s");
550 if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
551 argliststart=args+insertnr-1;
552 else
553 /* FIXME: not sure that this is
554 * correct for unix-c-varargs.
556 argliststart=((DWORD*)&args)+insertnr-1;
558 if (fmtstr[strlen(fmtstr)]=='s')
559 sprintfbuf=HeapAlloc(GetProcessHeap(),0,strlen((LPSTR)argliststart[0])+1);
560 else
561 sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
562 vsprintf(sprintfbuf,fmtstr,argliststart);
563 x=sprintfbuf;
564 while (*x) {
565 ADD_TO_T(*x++);
567 HeapFree(GetProcessHeap(),0,sprintfbuf);
568 HeapFree(GetProcessHeap(),0,fmtstr);
569 break;
570 case 'n':
571 /* FIXME: perhaps add \r too? */
572 ADD_TO_T('\n');
573 f++;
574 break;
575 case '0':
576 nolinefeed=1;
577 f++;
578 break;
579 default:ADD_TO_T(*f++)
580 break;
583 } else {
584 ADD_TO_T(*f++)
587 *t='\0';
589 if (!nolinefeed && t[-1]!='\n')
590 ADD_TO_T('\n');
591 talloced = strlen(target)+1;
592 if (nSize && talloced<nSize) {
593 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
595 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
596 /* nSize is the MINIMUM size */
597 *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc32(GMEM_ZEROINIT,talloced);
598 memcpy(*(LPSTR*)lpBuffer,target,talloced);
599 } else
600 strncpy(lpBuffer,target,nSize);
601 HeapFree(GetProcessHeap(),0,target);
602 if (from) HeapFree(GetProcessHeap(),0,from);
603 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
604 strlen(*(LPSTR*)lpBuffer):
605 strlen(lpBuffer);
607 #undef ADD_TO_T
609 /***********************************************************************
610 * FormatMessageA (KERNEL32.138) Emulator Version
612 DWORD
613 WIN32_FormatMessage32A(DWORD *args) {
614 DWORD dwFlags = args[0];
615 LPCVOID lpSource = (LPCVOID)args[1];
616 DWORD dwMessageId = args[2];
617 DWORD dwLanguageId = args[3];
618 LPSTR lpBuffer = (LPSTR)args[4];
619 DWORD nSize = args[5];
620 DWORD *xargs;
622 /* convert possible varargs to an argument array look-a-like */
624 if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) {
625 xargs=(DWORD*)args[6];
626 } else {
627 /* args[6] is a pointer to a pointer to the start of
628 * a list of arguments.
630 if (args[6])
631 xargs=(DWORD*)(((DWORD*)args[6])[0]);
632 else
633 xargs=NULL;
634 dwFlags|=FORMAT_MESSAGE_ARGUMENT_ARRAY;
636 return FormatMessage32A(
637 dwFlags,
638 lpSource,
639 dwMessageId,
640 dwLanguageId,
641 lpBuffer,
642 nSize,
643 xargs
647 DWORD
648 FormatMessage32W(
649 DWORD dwFlags,
650 LPCVOID lpSource,
651 DWORD dwMessageId,
652 DWORD dwLanguageId,
653 LPWSTR lpBuffer,
654 DWORD nSize,
655 LPDWORD args /* va_list *args */
657 LPSTR target,t;
658 DWORD talloced;
659 LPSTR from,f;
660 DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
661 DWORD nolinefeed = 0;
663 dprintf_resource(stddeb,
664 "FormatMessage32A(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
665 dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args
667 if (width)
668 fprintf(stdnimp," - line wrapping not supported.\n");
669 from = NULL;
670 if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
671 from = HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR)lpSource);
672 if (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) {
673 /* gather information from system message tables ... */
674 fprintf(stdnimp," - FORMAT_MESSAGE_FROM_SYSTEM not implemented.\n");
676 if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) {
677 INT32 bufsize;
679 dwMessageId &= 0xFFFF;
680 bufsize=LoadMessage32A(0,dwMessageId,dwLanguageId,NULL,100);
681 if (bufsize)
683 from = HeapAlloc( GetProcessHeap(), 0, bufsize + 1 );
684 LoadMessage32A(0,dwMessageId,dwLanguageId,from,bufsize+1);
687 target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100 );
688 t = target;
689 talloced= 100;
691 #define ADD_TO_T(c) \
692 *t++=c;\
693 if (t-target == talloced) {\
694 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
695 t = target+talloced;\
696 talloced*=2;\
699 if (from) {
700 f=from;
701 while (*f) {
702 if (*f=='%') {
703 int insertnr;
704 char *fmtstr,*sprintfbuf,*x;
705 DWORD *argliststart;
707 fmtstr = NULL;
708 f++;
709 if (!*f) {
710 ADD_TO_T('%');
711 continue;
713 switch (*f) {
714 case '1':case '2':case '3':case '4':case '5':
715 case '6':case '7':case '8':case '9':
716 insertnr=*f-'0';
717 switch (f[1]) {
718 case '0':case '1':case '2':case '3':
719 case '4':case '5':case '6':case '7':
720 case '8':case '9':
721 f++;
722 insertnr=insertnr*10+*f-'0';
723 f++;
724 break;
725 default:
726 f++;
727 break;
729 if (*f=='!') {
730 f++;
731 if (NULL!=(x=strchr(f,'!')))
733 *x='\0';
734 fmtstr=HeapAlloc( GetProcessHeap(), 0, strlen(f)+2);
735 sprintf(fmtstr,"%%%s",f);
736 f=x+1;
738 } else
739 fmtstr=HEAP_strdupA( GetProcessHeap(),0,"%s");
740 if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
741 argliststart=args+insertnr-1;
742 else
743 /* FIXME: not sure that this is
744 * correct for unix-c-varargs.
746 argliststart=((DWORD*)&args)+insertnr-1;
748 if (fmtstr[strlen(fmtstr)]=='s') {
749 DWORD xarr[3];
751 xarr[0]=(DWORD)HEAP_strdupWtoA(GetProcessHeap(),0,(LPWSTR)(*(argliststart+0)));
752 /* possible invalid pointers */
753 xarr[1]=*(argliststart+1);
754 xarr[2]=*(argliststart+2);
755 sprintfbuf=HeapAlloc(GetProcessHeap(),0,lstrlen32W((LPWSTR)argliststart[0])*2+1);
756 vsprintf(sprintfbuf,fmtstr,xarr);
757 } else {
758 sprintfbuf=HeapAlloc(GetProcessHeap(),0,100);
759 vsprintf(sprintfbuf,fmtstr,argliststart);
761 x=sprintfbuf;
762 while (*x) {
763 ADD_TO_T(*x++);
765 HeapFree(GetProcessHeap(),0,sprintfbuf);
766 HeapFree(GetProcessHeap(),0,fmtstr);
767 break;
768 case 'n':
769 /* FIXME: perhaps add \r too? */
770 ADD_TO_T('\n');
771 f++;
772 break;
773 case '0':
774 nolinefeed=1;
775 f++;
776 break;
777 default:ADD_TO_T(*f++)
778 break;
781 } else {
782 ADD_TO_T(*f++)
785 *t='\0';
787 if (!nolinefeed && t[-1]!='\n')
788 ADD_TO_T('\n');
789 talloced = strlen(target)+1;
790 if (nSize && talloced<nSize)
791 target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
792 if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
793 /* nSize is the MINIMUM size */
794 *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc32(GMEM_ZEROINIT,talloced*2+2);
795 lstrcpynAtoW(*(LPWSTR*)lpBuffer,target,talloced);
796 } else
797 lstrcpynAtoW(lpBuffer,target,nSize);
798 HeapFree(GetProcessHeap(),0,target);
799 if (from) HeapFree(GetProcessHeap(),0,from);
800 return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
801 lstrlen32W(*(LPWSTR*)lpBuffer):
802 lstrlen32W(lpBuffer);
804 #undef ADD_TO_T
806 /***********************************************************************
807 * FormatMessageA (KERNEL32.138) Emulator Version
809 DWORD
810 WIN32_FormatMessage32W(DWORD *args) {
811 DWORD dwFlags = args[0];
812 LPCVOID lpSource = (LPCVOID)args[1];
813 DWORD dwMessageId = args[2];
814 DWORD dwLanguageId = args[3];
815 LPWSTR lpBuffer = (LPWSTR)args[4];
816 DWORD nSize = args[5];
817 DWORD *xargs;
819 /* convert possible varargs to an argument array look-a-like */
821 if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY) {
822 xargs=(DWORD*)args[6];
823 } else {
824 /* args[6] is a pointer to a pointer to the start of
825 * a list of arguments.
827 if (args[6])
828 xargs=(DWORD*)(((DWORD*)args[6])[0]);
829 else
830 xargs=NULL;
831 dwFlags|=FORMAT_MESSAGE_ARGUMENT_ARRAY;
833 return FormatMessage32W(
834 dwFlags,
835 lpSource,
836 dwMessageId,
837 dwLanguageId,
838 lpBuffer,
839 nSize,
840 xargs