[ros-diffs] [gschneider] 44386: [kernel32] - Update FormatMessageA/W to current Wine sources, rename the file to better reflect the content - Fixes the failing kernel32 format_msg tests

gschneider at svn.reactos.org gschneider at svn.reactos.org
Thu Dec 3 19:57:57 CET 2009


Author: gschneider
Date: Thu Dec  3 19:57:57 2009
New Revision: 44386

URL: http://svn.reactos.org/svn/reactos?rev=44386&view=rev
Log:
[kernel32]
- Update FormatMessageA/W to current Wine sources, rename the file to better reflect the content
- Fixes the failing kernel32 format_msg tests

Added:
    trunk/reactos/dll/win32/kernel32/misc/format_msg.c   (with props)
Removed:
    trunk/reactos/dll/win32/kernel32/misc/errormsg.c
Modified:
    trunk/reactos/dll/win32/kernel32/kernel32.rbuild

Modified: trunk/reactos/dll/win32/kernel32/kernel32.rbuild
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/kernel32.rbuild?rev=44386&r1=44385&r2=44386&view=diff
==============================================================================
--- trunk/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/kernel32.rbuild [iso-8859-1] Thu Dec  3 19:57:57 2009
@@ -77,8 +77,8 @@
 		<file>dllmain.c</file>
 		<file>env.c</file>
 		<file>error.c</file>
-		<file>errormsg.c</file>
 		<file>fold.c</file>
+		<file>format_msg.c</file>
 		<file>handle.c</file>
 		<file>lang.c</file>
 		<file>ldr.c</file>

Removed: trunk/reactos/dll/win32/kernel32/misc/errormsg.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/errormsg.c?rev=44385&view=auto
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/errormsg.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/misc/errormsg.c (removed)
@@ -1,668 +1,0 @@
-/* $Id$
- *
- * reactos/lib/kernel32/misc/errormsg.c
- * Wine calls this file now as kernel/format_msg.c
- *
- */
-/*
- * FormatMessage implementation
- *
- * Copyright 1996 Marcus Meissner
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#include <k32.h>
-
-#define NDEBUG
-
-#include <debug.h>
-#include "wine/unicode.h"
-
-#define TRACE DPRINT
-#define FIXME DPRINT
-
-static const WCHAR PCNTFMTWSTR[] = { '%','%','%','s',0 };
-static const WCHAR FMTWSTR[] = { '%','s',0 };
-static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
-
-/* strdup macros */
-/* DO NOT USE IT!!  it will go away soon */
-
-__inline static LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str )
-{
-    LPSTR ret;
-    INT len;
-
-    if (!str) return NULL;
-    len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
-    ret = RtlAllocateHeap(RtlGetProcessHeap(), flags, len );
-    if(ret) WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
-    return ret;
-}
-
-/* Messages...used by FormatMessage32* (KERNEL32.something)
- *
- * They can be specified either directly or using a message ID and
- * loading them from the resource.
- *
- * The resourcedata has following format:
- * start:
- * 0: DWORD nrofentries
- * nrofentries * subentry:
- *      0: DWORD firstentry
- *      4: DWORD lastentry
- *      8: DWORD offset from start to the stringentries
- *
- * (lastentry-firstentry) * stringentry:
- * 0: WORD len (0 marks end)    [ includes the 4 byte header length ]
- * 2: WORD flags
- * 4: CHAR[len-4]
- *      (stringentry i of a subentry refers to the ID 'firstentry+i')
- *
- * Yes, ANSI strings in win32 resources. Go figure.
- */
-
-/**********************************************************************
- *	load_messageW		(internal)
- */
-static LPWSTR load_messageW( HMODULE module, UINT id, WORD lang )
-{
-    PRTL_MESSAGE_RESOURCE_ENTRY mre;
-    WCHAR *buffer;
-    NTSTATUS Status;
-
-    TRACE("module = %p, id = %08x\n", module, id );
-
-    if (!module) module = GetModuleHandleW( NULL );
-    Status = RtlFindMessage( module, (ULONG) RT_MESSAGETABLE, lang, id, &mre );
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastError( RtlNtStatusToDosError(Status) );
-        return NULL;
-    }
-
-    if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
-    {
-        int len = (strlenW( (const WCHAR *)mre->Text ) + 1) * sizeof(WCHAR);
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
-        memcpy( buffer, mre->Text, len );
-    }
-    else
-    {
-        int len = MultiByteToWideChar( CP_ACP, 0, (const char *)mre->Text, -1, NULL, 0 );
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
-        MultiByteToWideChar( CP_ACP, 0, (const char*)mre->Text, -1, buffer, len );
-    }
-    //TRACE("returning %s\n", wine_dbgstr_w(buffer));
-    return buffer;
-}
-
-
-/**********************************************************************
- *      load_messageA           (internal)
- */
-
-static LPSTR load_messageA( HMODULE module, UINT id, WORD lang )
-{
-    PRTL_MESSAGE_RESOURCE_ENTRY mre;
-    char *buffer;
-    NTSTATUS Status;
-
-    TRACE("module = %p, id = %08x\n", module, id );
-
-    if (!module) module = GetModuleHandleW( NULL );
-    Status = RtlFindMessage( module, (ULONG) RT_MESSAGETABLE, lang, id, &mre );
-    if (!NT_SUCCESS(Status))
-    {
-        SetLastError( RtlNtStatusToDosError(Status) );
-        return NULL;
-    }
-
-    if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
-    {
-        int len = WideCharToMultiByte( CP_ACP, 0, (const WCHAR *)mre->Text, -1, NULL, 0, NULL, NULL );
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
-        WideCharToMultiByte( CP_ACP, 0, (const WCHAR *)mre->Text, -1, buffer, len, NULL, NULL );
-    }
-    else
-    {
-        int len = strlen((const char*)mre->Text) + 1;
-        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
-        memcpy( buffer, mre->Text, len );
-    }
-    //TRACE("returning %s\n", wine_dbgstr_a(buffer));
-    return buffer;
-}
-
-
-/***********************************************************************
- *           FormatMessageA   (KERNEL32.@)
- * FIXME: missing wrap,
- *
- * @implemented
- */
-DWORD WINAPI FormatMessageA(
-	DWORD	dwFlags,
-	LPCVOID	lpSource,
-	DWORD	dwMessageId,
-	DWORD	dwLanguageId,
-	LPSTR	lpBuffer,
-	DWORD	nSize,
-	va_list* _args )
-{
-    LPDWORD args=(LPDWORD)_args;
-    HMODULE kernel32_handle = GetModuleHandleW(kernel32W);
-
-#if defined(__i386__) || defined(__sparc__)
-/* This implementation is completely dependent on the format of the va_list on x86 CPUs */
-    LPSTR	target,t;
-    DWORD	talloced;
-    LPSTR	from,f;
-    DWORD	width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
-    BOOL    eos = FALSE;
-    CHAR	ch;
-
-    TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
-          dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
-    if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
-        &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
-           || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
-
-    if (!lpBuffer)
-    {
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
-    }
-
-    if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
-        FIXME("line wrapping (%lu) not supported.\n", width);
-    from = NULL;
-    if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
-    {
-        from = HeapAlloc( GetProcessHeap(), 0, strlen((LPCSTR)lpSource)+1 );
-        if (from == NULL)
-        {
-            return 0;
-        }
-        strcpy( from, (LPCSTR)lpSource );
-    }
-    else {
-        from = NULL;
-        if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
-            from = load_messageA( (HMODULE)lpSource, dwMessageId, (WORD)dwLanguageId );
-        if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
-            from = load_messageA( kernel32_handle, dwMessageId, (WORD)dwLanguageId );
-
-        if (!from)
-        {
-            return 0;
-        }
-    }
-    target	= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
-    if(target == NULL)
-    {
-        HeapFree(GetProcessHeap(),0,from);
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
-    }
-    t	= target;
-    talloced= 100;
-
-#define ADD_TO_T(c) do { \
-        *t++=c;\
-        if (t-target == talloced) {\
-            target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
-            t = target+talloced;\
-            talloced*=2;\
-      }\
-} while (0)
-
-    if (from) {
-        f=from;
-        if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
-            while (*f && !eos)
-                ADD_TO_T(*f++);
-        }
-        else {
-            while (*f && !eos) {
-                if (*f=='%') {
-                    int insertnr;
-                    char *fmtstr,*x,*lastf;
-                    DWORD *argliststart;
-
-                    fmtstr = NULL;
-                    lastf = f;
-                    f++;
-                    if (!*f) {
-                        ADD_TO_T('%');
-                        continue;
-                    }
-                    switch (*f) {
-                    case '1':case '2':case '3':case '4':case '5':
-                    case '6':case '7':case '8':case '9':
-                        insertnr=*f-'0';
-                        switch (f[1]) {
-                        case '0':case '1':case '2':case '3':
-                        case '4':case '5':case '6':case '7':
-                        case '8':case '9':
-                            f++;
-                            insertnr=insertnr*10+*f-'0';
-                            f++;
-                            break;
-                        default:
-                            f++;
-                            break;
-                        }
-                        if (*f=='!') {
-                            f++;
-                            if (NULL!=(x=strchr(f,'!'))) {
-                                *x='\0';
-                                fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
-                                if(fmtstr == NULL)
-                                {
-                                    HeapFree(GetProcessHeap(),0,from);
-                                    HeapFree(GetProcessHeap(),0,target);
-                                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                                    return 0;
-                                }
-                                sprintf(fmtstr,"%%%s",f);
-                                f=x+1;
-                            } else {
-                                fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2);
-                                if(fmtstr == NULL)
-                                {
-                                    HeapFree(GetProcessHeap(),0,from);
-                                    HeapFree(GetProcessHeap(),0,target);
-                                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                                    return 0;
-                                }
-                                sprintf(fmtstr,"%%%s",f);
-                                f+=strlen(f); /*at \0*/
-                            }
-                        } else {
-                            if(!args) break;
-                            fmtstr = HeapAlloc(GetProcessHeap(),0,3);
-                            if(fmtstr == NULL)
-                            {
-                                HeapFree(GetProcessHeap(),0,from);
-                                HeapFree(GetProcessHeap(),0,target);
-                                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                                return 0;
-                            }
-                            strcpy( fmtstr, "%s" );
-                        }
-                        if (args) {
-                            int sz;
-                            LPSTR b;
-
-                            if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
-                                argliststart=args+insertnr-1;
-                            else
-                                argliststart=(*(DWORD**)args)+insertnr-1;
-
-                            b = NULL;
-                            sz = 0;
-                            do {
-                                if (b) {
-                                    HeapFree(GetProcessHeap(), 0, b);
-                                }
-                                sz += 256;
-                                b = HeapAlloc(GetProcessHeap(), 0, sz);
-                                /* CMF - This makes a BIG assumption about va_list */
-                            } while (0 > _vsnprintf(b, sz, fmtstr, (va_list) argliststart));
-                            x=b;
-                            while(*x)
-                                ADD_TO_T(*x++);
-
-                            HeapFree(GetProcessHeap(),0,b);
-                        } else {
-                                /* NULL args - copy formatstr
-                                 * (probably wrong)
-                                 */
-                            while ((lastf<f)&&(*lastf)) {
-                                ADD_TO_T(*lastf++);
-                            }
-                        }
-                        HeapFree(GetProcessHeap(),0,fmtstr);
-                        break;
-                    case 'n':
-                        ADD_TO_T('\r');
-                        ADD_TO_T('\n');
-                        f++;
-                        break;
-                    case '0':
-                        eos = TRUE;
-                        f++;
-                        break;
-                    default:
-                        ADD_TO_T(*f++);
-                        break;
-                    }
-                } else {
-                    ch = *f;
-                    f++;
-                    if (ch == '\r') {
-                        if (*f == '\n')
-                            f++;
-                        if(width)
-                            ADD_TO_T(' ');
-                        else
-                        {
-                            ADD_TO_T('\r');
-                            ADD_TO_T('\n');
-                        }
-                    } else {
-                        if (ch == '\n')
-                        {
-                            if(width)
-                                ADD_TO_T(' ');
-                            else
-                            {
-                                ADD_TO_T('\r');
-                                ADD_TO_T('\n');
-                            }
-                        }
-                        else
-                            ADD_TO_T(ch);
-                    }
-                }
-            }
-        }
-        *t='\0';
-    }
-    talloced = strlen(target)+1;
-    if (nSize && talloced<nSize) {
-        target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
-    }
-    //TRACE("-- %s\n",debugstr_a(target));
-    if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
-        *((LPVOID*)lpBuffer) = (LPVOID)LocalAlloc(LMEM_ZEROINIT,max(nSize, talloced));
-        memcpy(*(LPSTR*)lpBuffer,target,talloced);
-    } else {
-        lstrcpynA(lpBuffer,target,nSize);
-    }
-    HeapFree(GetProcessHeap(),0,target);
-    HeapFree(GetProcessHeap(),0,from);
-    TRACE("-- returning %d\n", (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?  strlen(*(LPSTR*)lpBuffer):strlen(lpBuffer));
-    return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
-        strlen(*(LPSTR*)lpBuffer):
-            strlen(lpBuffer);
-#else
-    return 0;
-#endif /* __i386__ */
-}
-#undef ADD_TO_T
-
-/***********************************************************************
- *           FormatMessageW   (KERNEL32.@)
- *
- * @implemented
- */
-DWORD WINAPI FormatMessageW(
-	DWORD	dwFlags,
-	LPCVOID	lpSource,
-	DWORD	dwMessageId,
-	DWORD	dwLanguageId,
-	LPWSTR	lpBuffer,
-	DWORD	nSize,
-	va_list* _args )
-{
-    HMODULE kernel32_handle = GetModuleHandleW(kernel32W);
-    LPDWORD args=(LPDWORD)_args;
-#if defined(__i386__) || defined(__sparc__)
-/* This implementation is completely dependent on the format of the va_list on x86 CPUs */
-    LPWSTR target,t;
-    DWORD talloced,len;
-    LPWSTR from,f;
-    DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
-    BOOL eos = FALSE;
-    WCHAR ch;
-
-    TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n",
-          dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
-    if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
-        &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
-           || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
-
-    if (!lpBuffer)
-    {
-        SetLastError(ERROR_INVALID_PARAMETER);
-        return 0;
-    }
-
-    if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
-        FIXME("line wrapping not supported.\n");
-    from = NULL;
-    if (dwFlags & FORMAT_MESSAGE_FROM_STRING) {
-        from = HeapAlloc( GetProcessHeap(), 0, (strlenW((LPCWSTR)lpSource) + 1) *
-            sizeof(WCHAR) );
-        if(from == NULL)
-        {
-            SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-            return 0;
-        }
-        strcpyW( from, (LPCWSTR)lpSource );
-    }
-    else {
-        from = NULL;
-        if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
-            from = load_messageW( (HMODULE)lpSource, dwMessageId, (WORD)dwLanguageId );
-        if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
-            from = load_messageW( kernel32_handle, dwMessageId,(WORD)dwLanguageId );
-
-        if (!from)
-        {
-            return 0;
-        }
-    }
-
-    target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100 * sizeof(WCHAR) );
-    if(target == NULL)
-    {
-        HeapFree(GetProcessHeap(),0,from);
-        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-        return 0;
-    }
-    t = target;
-    talloced= 100;
-
-#define ADD_TO_T(c)  do {\
-    *t++=c;\
-    if (t-target == talloced) {\
-        target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2*sizeof(WCHAR));\
-        t = target+talloced;\
-        talloced*=2;\
-    } \
-} while (0)
-
-    if (from) {
-        f=from;
-        if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
-            while (*f && !eos)
-                ADD_TO_T(*f++);
-        }
-        else {
-            while (*f && !eos) {
-                if (*f=='%') {
-                    int insertnr;
-                    WCHAR *fmtstr,*sprintfbuf,*x,*lastf;
-                    DWORD *argliststart;
-
-                    fmtstr = NULL;
-                    lastf = f;
-                    f++;
-                    if (!*f) {
-                        ADD_TO_T('%');
-                        continue;
-                    }
-
-                    switch (*f) {
-                    case '1':case '2':case '3':case '4':case '5':
-                    case '6':case '7':case '8':case '9':
-                        insertnr=*f-'0';
-                        switch (f[1]) {
-                        case '0':case '1':case '2':case '3':
-                        case '4':case '5':case '6':case '7':
-                        case '8':case '9':
-                            f++;
-                            insertnr=insertnr*10+*f-'0';
-                            f++;
-                            break;
-                        default:
-                            f++;
-                            break;
-                        }
-                        if (*f=='!') {
-                            f++;
-                            if (NULL!=(x=strchrW(f,'!'))) {
-                                *x='\0';
-                                fmtstr=HeapAlloc( GetProcessHeap(), 0,(strlenW(f)+2)*sizeof(WCHAR));
-                                if(fmtstr == NULL)
-                                {
-                                    HeapFree(GetProcessHeap(),0,from);
-                                    HeapFree(GetProcessHeap(),0,target);
-                                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                                    return 0;
-                                }
-                                sprintfW(fmtstr,PCNTFMTWSTR,f);
-                                f=x+1;
-                            } else {
-                                fmtstr=HeapAlloc(GetProcessHeap(),0,(strlenW(f)+2)*sizeof(WCHAR));
-                                if(fmtstr == NULL)
-                                {
-                                    HeapFree(GetProcessHeap(),0,from);
-                                    HeapFree(GetProcessHeap(),0,target);
-                                    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                                    return 0;
-                                }
-                                sprintfW(fmtstr,PCNTFMTWSTR,f);
-                                f+=strlenW(f); /*at \0*/
-                            }
-                        } else {
-                            if(!args) break;
-                            fmtstr = HeapAlloc( GetProcessHeap(),0,3*sizeof(WCHAR));
-                            if(fmtstr == NULL)
-                            {
-                                HeapFree(GetProcessHeap(),0,from);
-                                HeapFree(GetProcessHeap(),0,target);
-                                SetLastError(ERROR_NOT_ENOUGH_MEMORY);
-                                return 0;
-                            }
-                            strcpyW( fmtstr, FMTWSTR );
-                        }
-
-                        if (args) {
-                            if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
-                                argliststart=args+insertnr-1;
-                            else
-                                argliststart=(*(DWORD**)args)+insertnr-1;
-
-                            len = 0;
-                            sprintfbuf = NULL;
-                            do {
-                                if (sprintfbuf) {
-                                    HeapFree(GetProcessHeap(),0,sprintfbuf);
-                                }
-                                len += 256;
-                                sprintfbuf=HeapAlloc(GetProcessHeap(),0,len*sizeof(WCHAR));
-                                /* CMF - This makes a BIG assumption about va_list */
-                            } while (0 > _vsnwprintf(sprintfbuf, len, fmtstr, (va_list) argliststart));
-                            x=sprintfbuf;
-                            while (*x) {
-                                ADD_TO_T(*x++);
-                            }
-                            HeapFree(GetProcessHeap(),0,sprintfbuf);
-
-                        } else {
-                                /* NULL args - copy formatstr
-                                 * (probably wrong)
-                                 */
-                            while ((lastf<f)&&(*lastf)) {
-                                ADD_TO_T(*lastf++);
-                            }
-                        }
-
-                        HeapFree(GetProcessHeap(),0,fmtstr);
-                        break;
-                    case 'n':
-                        ADD_TO_T('\r');
-                        ADD_TO_T('\n');
-                        f++;
-                        break;
-                    case '0':
-                        eos = TRUE;
-                        f++;
-                        break;
-                    default:
-                        ADD_TO_T(*f++);
-                        break;
-                    }
-                } else {
-                    ch = *f;
-                    f++;
-                    if (ch == '\r') {
-                        if (*f == '\n')
-                            f++;
-                        if(width)
-                            ADD_TO_T(' ');
-                        else
-                        {
-                            ADD_TO_T('\r');
-                            ADD_TO_T('\n');
-                        }
-                    } else {
-                        if (ch == '\n')
-                        {
-                            if(width)
-                                ADD_TO_T(' ');
-                            else
-                            {
-                                ADD_TO_T('\r');
-                                ADD_TO_T('\n');
-                            }
-                        }
-                        else
-                            ADD_TO_T(ch);
-                    }
-                }
-            }
-        }
-        *t='\0';
-    }
-    talloced = strlenW(target)+1;
-    if (nSize && talloced<nSize)
-        target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize*sizeof(WCHAR));
-    if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
-        /* nSize is the MINIMUM size */
-        DWORD len = strlenW(target) + 1;
-        *((LPVOID*)lpBuffer) = LocalAlloc(LMEM_ZEROINIT,len*sizeof(WCHAR));
-        strcpyW(*(LPWSTR*)lpBuffer, target);
-    }
-    else lstrcpynW(lpBuffer, target, nSize);
-
-    HeapFree(GetProcessHeap(),0,target);
-    HeapFree(GetProcessHeap(),0,from);
-    //TRACE("ret=%s\n", wine_dbgstr_w((dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
-      //  *(LPWSTR*)lpBuffer : lpBuffer));
-    return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
-        strlenW(*(LPWSTR*)lpBuffer):
-            strlenW(lpBuffer);
-#else
-    return 0;
-#endif /* __i386__ */
-}
-#undef ADD_TO_T
-

Added: trunk/reactos/dll/win32/kernel32/misc/format_msg.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/misc/format_msg.c?rev=44386&view=auto
==============================================================================
--- trunk/reactos/dll/win32/kernel32/misc/format_msg.c (added)
+++ trunk/reactos/dll/win32/kernel32/misc/format_msg.c [iso-8859-1] Thu Dec  3 19:57:57 2009
@@ -1,0 +1,757 @@
+/*
+ * FormatMessage implementation
+ *
+ * Copyright 1996 Marcus Meissner
+ * Copyright 2009 Alexandre Julliard
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <k32.h>
+
+#define NDEBUG
+
+#include <debug.h>
+#include "wine/unicode.h"
+
+struct format_args
+{
+    ULONG_PTR    *args;
+    __ms_va_list *list;
+    int           last;
+};
+
+static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2',0};
+
+/* Messages used by FormatMessage
+ *
+ * They can be specified either directly or using a message ID and
+ * loading them from the resource.
+ *
+ * The resourcedata has following format:
+ * start:
+ * 0: DWORD nrofentries
+ * nrofentries * subentry:
+ *	0: DWORD firstentry
+ *	4: DWORD lastentry
+ *      8: DWORD offset from start to the stringentries
+ *
+ * (lastentry-firstentry) * stringentry:
+ * 0: WORD len (0 marks end)	[ includes the 4 byte header length ]
+ * 2: WORD flags
+ * 4: CHAR[len-4]
+ * 	(stringentry i of a subentry refers to the ID 'firstentry+i')
+ *
+ * Yes, ANSI strings in win32 resources. Go figure.
+ */
+
+static const WCHAR PCNTFMTWSTR[] = { '%','%','%','s',0 };
+static const WCHAR FMTWSTR[] = { '%','s',0 };
+
+/**********************************************************************
+ *	load_messageW		(internal)
+ */
+static LPWSTR load_messageW( HMODULE module, UINT id, WORD lang )
+{
+    PRTL_MESSAGE_RESOURCE_ENTRY mre;
+    WCHAR *buffer;
+    NTSTATUS status;
+
+    DPRINT("module = %p, id = %08x\n", module, id );
+
+    if (!module) module = GetModuleHandleW( NULL );
+    if ((status = RtlFindMessage( module, (ULONG)RT_MESSAGETABLE, lang, id, &mre )) != STATUS_SUCCESS)
+    {
+        SetLastError( RtlNtStatusToDosError(status) );
+        return NULL;
+    }
+
+    if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
+    {
+        int len = (strlenW( (const WCHAR *)mre->Text ) + 1) * sizeof(WCHAR);
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
+        memcpy( buffer, mre->Text, len );
+    }
+    else
+    {
+        int len = MultiByteToWideChar( CP_ACP, 0, (const char *)mre->Text, -1, NULL, 0 );
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
+        MultiByteToWideChar( CP_ACP, 0, (const char*)mre->Text, -1, buffer, len );
+    }
+    DPRINT("returning %S\n", buffer);
+    return buffer;
+}
+
+
+/**********************************************************************
+ *	load_messageA		(internal)
+ */
+static LPSTR load_messageA( HMODULE module, UINT id, WORD lang )
+{
+    PRTL_MESSAGE_RESOURCE_ENTRY mre;
+    char *buffer;
+    NTSTATUS status;
+
+    DPRINT("module = %p, id = %08x\n", module, id );
+
+    if (!module) module = GetModuleHandleW( NULL );
+    if ((status = RtlFindMessage( module, (ULONG)RT_MESSAGETABLE, lang, id, &mre )) != STATUS_SUCCESS)
+    {
+        SetLastError( RtlNtStatusToDosError(status) );
+        return NULL;
+    }
+
+    if (mre->Flags & MESSAGE_RESOURCE_UNICODE)
+    {
+        int len = WideCharToMultiByte( CP_ACP, 0, (const WCHAR *)mre->Text, -1, NULL, 0, NULL, NULL );
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
+        WideCharToMultiByte( CP_ACP, 0, (const WCHAR *)mre->Text, -1, buffer, len, NULL, NULL );
+    }
+    else
+    {
+        int len = strlen((const char*)mre->Text) + 1;
+        if (!(buffer = HeapAlloc( GetProcessHeap(), 0, len ))) return NULL;
+        memcpy( buffer, mre->Text, len );
+    }
+    DPRINT("returning %s\n", buffer);
+    return buffer;
+}
+
+
+/**********************************************************************
+ *	get_arg    (internal)
+ */
+static ULONG_PTR get_arg( int nr, DWORD flags, struct format_args *args )
+{
+    if (nr == -1) nr = args->last + 1;
+    if (args->list)
+    {
+        if (!args->args) args->args = HeapAlloc( GetProcessHeap(), 0, 99 * sizeof(ULONG_PTR) );
+        while (nr > args->last)
+            args->args[args->last++] = va_arg( *args->list, ULONG_PTR );
+    }
+    if (nr > args->last) args->last = nr;
+    return args->args[nr - 1];
+}
+
+
+/**********************************************************************
+ *	format_insertA    (internal)
+ */
+static LPCSTR format_insertA( int insert, LPCSTR format, DWORD flags,
+                              struct format_args *args, LPSTR *result )
+{
+    char *astring = NULL, *p, fmt[256];
+    ULONG_PTR arg;
+    int size;
+
+    if (*format != '!')  /* simple string */
+    {
+        char *str = (char *)get_arg( insert, flags, args );
+        *result = HeapAlloc( GetProcessHeap(), 0, strlen(str) + 1 );
+        strcpy( *result, str );
+        return format;
+    }
+
+    format++;
+    p = fmt;
+    *p++ = '%';
+
+    while (*format == '0' ||
+           *format == '+' ||
+           *format == '-' ||
+           *format == ' ' ||
+           *format == '*' ||
+           *format == '#')
+    {
+        if (*format == '*')
+        {
+            p += sprintf( p, "%lu", get_arg( insert, flags, args ));
+            insert = -1;
+            format++;
+        }
+        else *p++ = *format++;
+    }
+    while (isdigit(*format)) *p++ = *format++;
+
+    if (*format == '.')
+    {
+        *p++ = *format++;
+        if (*format == '*')
+        {
+            p += sprintf( p, "%lu", get_arg( insert, flags, args ));
+            insert = -1;
+            format++;
+        }
+        else
+            while (isdigit(*format)) *p++ = *format++;
+    }
+
+    /* replicate MS bug: drop an argument when using va_list with width/precision */
+    if (insert == -1 && args->list) args->last--;
+    arg = get_arg( insert, flags, args );
+
+    /* check for wide string format */
+    if ((format[0] == 'l' && format[1] == 's') ||
+        (format[0] == 'l' && format[1] == 'S') ||
+        (format[0] == 'w' && format[1] == 's') ||
+        (format[0] == 'S'))
+    {
+        DWORD len = WideCharToMultiByte( CP_ACP, 0, (WCHAR *)arg, -1, /*FIXME*/
+                                         NULL, 0, NULL, NULL );
+        astring = HeapAlloc( GetProcessHeap(), 0, len );
+        WideCharToMultiByte( CP_ACP, 0, (WCHAR *)arg, -1, astring, len, NULL, NULL );
+        arg = (ULONG_PTR)astring;
+        *p++ = 's';
+    }
+    /* check for wide character format */
+    else if ((format[0] == 'l' && format[1] == 'c') ||
+             (format[0] == 'l' && format[1] == 'C') ||
+             (format[0] == 'w' && format[1] == 'c') ||
+             (format[0] == 'C'))
+    {
+        WCHAR ch = arg;
+        DWORD len = WideCharToMultiByte( CP_ACP, 0, &ch, 1, NULL, 0, NULL, NULL );
+        astring = HeapAlloc( GetProcessHeap(), 0, len + 1 );
+        WideCharToMultiByte( CP_ACP, 0, &ch, 1, astring, len, NULL, NULL );
+        astring[len] = 0;
+        arg = (ULONG_PTR)astring;
+        *p++ = 's';
+    }
+    /* check for ascii string format */
+    else if ((format[0] == 'h' && format[1] == 's') ||
+             (format[0] == 'h' && format[1] == 'S'))
+    {
+        *p++ = 's';
+    }
+    /* check for ascii character format */
+    else if ((format[0] == 'h' && format[1] == 'c') ||
+             (format[0] == 'h' && format[1] == 'C'))
+    {
+        *p++ = 'c';
+    }
+    /* FIXME: handle I64 etc. */
+    else while (*format && *format != '!') *p++ = *format++;
+
+    *p = 0;
+    size = 256;
+    for (;;)
+    {
+        char *ret = HeapAlloc( GetProcessHeap(), 0, size );
+        int needed = snprintf( ret, size, fmt, arg );
+        if (needed == -1 || needed >= size)
+        {
+            HeapFree( GetProcessHeap(), 0, ret );
+            size = max( needed + 1, size * 2 );
+        }
+        else
+        {
+            *result = ret;
+            break;
+        }
+    }
+
+    while (*format && *format != '!') format++;
+    if (*format == '!') format++;
+
+    HeapFree( GetProcessHeap(), 0, astring );
+    return format;
+}
+
+
+/**********************************************************************
+ *	format_insertW    (internal)
+ */
+static LPCWSTR format_insertW( int insert, LPCWSTR format, DWORD flags,
+                               struct format_args *args, LPWSTR *result )
+{
+    static const WCHAR fmt_lu[] = {'%','l','u',0};
+    WCHAR *wstring = NULL, *p, fmt[256];
+    ULONG_PTR arg;
+    int size;
+
+    if (*format != '!')  /* simple string */
+    {
+        WCHAR *str = (WCHAR *)get_arg( insert, flags, args );
+        *result = HeapAlloc( GetProcessHeap(), 0, (strlenW(str) + 1) * sizeof(WCHAR) );
+        strcpyW( *result, str );
+        return format;
+    }
+
+    format++;
+    p = fmt;
+    *p++ = '%';
+
+    while (*format == '0' ||
+           *format == '+' ||
+           *format == '-' ||
+           *format == ' ' ||
+           *format == '*' ||
+           *format == '#')
+    {
+        if (*format == '*')
+        {
+            p += sprintfW( p, fmt_lu, get_arg( insert, flags, args ));
+            insert = -1;
+            format++;
+        }
+        else *p++ = *format++;
+    }
+    while (isdigitW(*format)) *p++ = *format++;
+
+    if (*format == '.')
+    {
+        *p++ = *format++;
+        if (*format == '*')
+        {
+            p += sprintfW( p, fmt_lu, get_arg( insert, flags, args ));
+            insert = -1;
+            format++;
+        }
+        else
+            while (isdigitW(*format)) *p++ = *format++;
+    }
+
+    /* replicate MS bug: drop an argument when using va_list with width/precision */
+    if (insert == -1 && args->list) args->last--;
+    arg = get_arg( insert, flags, args );
+
+    /* check for ascii string format */
+    if ((format[0] == 'h' && format[1] == 's') ||
+        (format[0] == 'h' && format[1] == 'S') ||
+        (format[0] == 'S'))
+    {
+        DWORD len = MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, /*FIXME*/ NULL, 0 );
+        wstring = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, (char *)arg, -1, wstring, len );
+        arg = (ULONG_PTR)wstring;
+        *p++ = 's';
+    }
+    /* check for ascii character format */
+    else if ((format[0] == 'h' && format[1] == 'c') ||
+             (format[0] == 'h' && format[1] == 'C') ||
+             (format[0] == 'C'))
+    {
+        char ch = arg;
+        wstring = HeapAlloc( GetProcessHeap(), 0, 2 * sizeof(WCHAR) );
+        MultiByteToWideChar( CP_ACP, 0, &ch, 1, wstring, 1 );
+        wstring[1] = 0;
+        arg = (ULONG_PTR)wstring;
+        *p++ = 's';
+    }
+    /* check for wide string format */
+    else if ((format[0] == 'l' && format[1] == 's') ||
+             (format[0] == 'l' && format[1] == 'S') ||
+             (format[0] == 'w' && format[1] == 's'))
+    {
+        *p++ = 's';
+    }
+    /* check for wide character format */
+    else if ((format[0] == 'l' && format[1] == 'c') ||
+             (format[0] == 'l' && format[1] == 'C') ||
+             (format[0] == 'w' && format[1] == 'c'))
+    {
+        *p++ = 'c';
+    }
+    /* FIXME: handle I64 etc. */
+    else while (*format && *format != '!') *p++ = *format++;
+
+    *p = 0;
+    size = 256;
+    for (;;)
+    {
+        WCHAR *ret = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) );
+        int needed = snprintfW( ret, size, fmt, arg );
+        if (needed == -1 || needed >= size)
+        {
+            HeapFree( GetProcessHeap(), 0, ret );
+            size = max( needed + 1, size * 2 );
+        }
+        else
+        {
+            *result = ret;
+            break;
+        }
+    }
+
+    while (*format && *format != '!') format++;
+    if (*format == '!') format++;
+
+    HeapFree( GetProcessHeap(), 0, wstring );
+    return format;
+}
+
+
+/***********************************************************************
+ *           FormatMessageA   (KERNEL32.@)
+ * FIXME: missing wrap,
+ */
+DWORD WINAPI FormatMessageA(
+	DWORD	dwFlags,
+	LPCVOID	lpSource,
+	DWORD	dwMessageId,
+	DWORD	dwLanguageId,
+	LPSTR	lpBuffer,
+	DWORD	nSize,
+	__ms_va_list* args )
+{
+    struct format_args format_args;
+    DWORD ret = 0;
+    LPSTR	target,t;
+    DWORD	talloced;
+    LPSTR	from;
+    LPCSTR f;
+    DWORD	width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
+    BOOL    eos = FALSE;
+    CHAR	ch;
+    HMODULE kernel32_handle = GetModuleHandleW(kernel32W);
+
+    DPRINT("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
+          dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
+    if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
+        &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
+           || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
+
+    if (!lpBuffer)
+    {
+        SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+        return 0;
+    }
+
+    if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
+    {
+        format_args.args = (ULONG_PTR *)args;
+        format_args.list = NULL;
+        format_args.last = 0;
+    }
+    else
+    {
+        format_args.args = NULL;
+        format_args.list = args;
+        format_args.last = 0;
+    }
+
+    if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
+        DPRINT1("FIXME: line wrapping (%u) not supported.\n", width);
+    from = NULL;
+    if (dwFlags & FORMAT_MESSAGE_FROM_STRING)
+    {
+        from = HeapAlloc( GetProcessHeap(), 0, strlen(lpSource) + 1 );
+        strcpy( from, lpSource );
+    }
+    else {
+        from = NULL;
+        if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
+            from = load_messageA( (HMODULE)lpSource, dwMessageId, dwLanguageId );
+        if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
+            from = load_messageA( kernel32_handle, dwMessageId, dwLanguageId );
+        if (!from) return 0;
+    }
+    target	= HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100);
+    t	= target;
+    talloced= 100;
+
+#define ADD_TO_T(c) do { \
+        *t++=c;\
+        if ((DWORD)(t-target) == talloced) {\
+            target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\
+            t = target+talloced;\
+            talloced*=2;\
+      }\
+} while (0)
+
+    if (from) {
+        f=from;
+        if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
+            while (*f && !eos)
+                ADD_TO_T(*f++);
+        }
+        else {
+            while (*f && !eos) {
+                if (*f=='%') {
+                    int insertnr;
+                    char *str,*x;
+
+                    f++;
+                    if (!*f) {
+                        ADD_TO_T('%');
+                        continue;
+                    }
+                    switch (*f) {
+                    case '1':case '2':case '3':case '4':case '5':
+                    case '6':case '7':case '8':case '9':
+                        insertnr=*f-'0';
+                        switch (f[1]) {
+                        case '0':case '1':case '2':case '3':
+                        case '4':case '5':case '6':case '7':
+                        case '8':case '9':
+                            f++;
+                            insertnr=insertnr*10+*f-'0';
+                            f++;
+                            break;
+                        default:
+                            f++;
+                            break;
+                        }
+                        f = format_insertA( insertnr, f, dwFlags, &format_args, &str );
+                        for (x = str; *x; x++) ADD_TO_T(*x);
+                        HeapFree( GetProcessHeap(), 0, str );
+                        break;
+                    case 'n':
+                        ADD_TO_T('\r');
+                        ADD_TO_T('\n');
+                        f++;
+                        break;
+                    case '0':
+                        eos = TRUE;
+                        f++;
+                        break;
+                    default:
+                        ADD_TO_T(*f++);
+                        break;
+                    }
+                } else {
+                    ch = *f;
+                    f++;
+                    if (ch == '\r') {
+                        if (*f == '\n')
+                            f++;
+                        if(width)
+                            ADD_TO_T(' ');
+                        else
+                        {
+                            ADD_TO_T('\r');
+                            ADD_TO_T('\n');
+                        }
+                    } else {
+                        if (ch == '\n')
+                        {
+                            if(width)
+                                ADD_TO_T(' ');
+                            else
+                            {
+                                ADD_TO_T('\r');
+                                ADD_TO_T('\n');
+                            }
+                        }
+                        else
+                            ADD_TO_T(ch);
+                    }
+                }
+            }
+        }
+        *t='\0';
+    }
+    talloced = strlen(target)+1;
+    if (nSize && talloced<nSize) {
+        target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize);
+    }
+    DPRINT("-- %S\n", target);
+    if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
+        *((LPVOID*)lpBuffer) = LocalAlloc(LMEM_ZEROINIT,max(nSize, talloced));
+        memcpy(*(LPSTR*)lpBuffer,target,talloced);
+    } else {
+        lstrcpynA(lpBuffer,target,nSize);
+    }
+    HeapFree(GetProcessHeap(),0,target);
+    HeapFree(GetProcessHeap(),0,from);
+    if (!(dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)) HeapFree( GetProcessHeap(), 0, format_args.args );
+    ret = (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ? strlen(*(LPSTR*)lpBuffer) : strlen(lpBuffer);
+    DPRINT("-- returning %d\n", ret);
+    return ret;
+}
+#undef ADD_TO_T
+
+
+/***********************************************************************
+ *           FormatMessageW   (KERNEL32.@)
+ */
+DWORD WINAPI FormatMessageW(
+	DWORD	dwFlags,
+	LPCVOID	lpSource,
+	DWORD	dwMessageId,
+	DWORD	dwLanguageId,
+	LPWSTR	lpBuffer,
+	DWORD	nSize,
+	__ms_va_list* args )
+{
+    struct format_args format_args;
+    LPWSTR target,t;
+    DWORD talloced;
+    LPWSTR from;
+    LPCWSTR f;
+    DWORD width = dwFlags & FORMAT_MESSAGE_MAX_WIDTH_MASK;
+    BOOL eos = FALSE;
+    WCHAR ch;
+    HMODULE kernel32_handle = GetModuleHandleW(kernel32W);
+
+    DPRINT("(0x%x,%p,%d,0x%x,%p,%d,%p)\n",
+          dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args);
+    if ((dwFlags & FORMAT_MESSAGE_FROM_STRING)
+        &&((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM)
+           || (dwFlags & FORMAT_MESSAGE_FROM_HMODULE))) return 0;
+
+    if (!lpBuffer)
+    {
+        SetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    if (dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)
+    {
+        format_args.args = (ULONG_PTR *)args;
+        format_args.list = NULL;
+        format_args.last = 0;
+    }
+    else
+    {
+        format_args.args = NULL;
+        format_args.list = args;
+        format_args.last = 0;
+    }
+
+    if (width && width != FORMAT_MESSAGE_MAX_WIDTH_MASK)
+        DPRINT1("FIXME: line wrapping not supported.\n");
+    from = NULL;
+    if (dwFlags & FORMAT_MESSAGE_FROM_STRING) {
+        from = HeapAlloc( GetProcessHeap(), 0, (strlenW(lpSource) + 1) *
+            sizeof(WCHAR) );
+        strcpyW( from, lpSource );
+    }
+    else {
+        from = NULL;
+        if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE)
+            from = load_messageW( (HMODULE)lpSource, dwMessageId, dwLanguageId );
+        if (!from && (dwFlags & FORMAT_MESSAGE_FROM_SYSTEM))
+            from = load_messageW( kernel32_handle, dwMessageId, dwLanguageId );
+        if (!from) return 0;
+    }
+    target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100 * sizeof(WCHAR) );
+    t = target;
+    talloced= 100;
+
+#define ADD_TO_T(c)  do {\
+    *t++=c;\
+    if ((DWORD)(t-target) == talloced) {\
+        target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2*sizeof(WCHAR));\
+        t = target+talloced;\
+        talloced*=2;\
+    } \
+} while (0)
+
+    if (from) {
+        f=from;
+        if (dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS) {
+            while (*f && !eos)
+                ADD_TO_T(*f++);
+        }
+        else {
+            while (*f && !eos) {
+                if (*f=='%') {
+                    int insertnr;
+                    WCHAR *str,*x;
+
+                    f++;
+                    if (!*f) {
+                        ADD_TO_T('%');
+                        continue;
+                    }
+
+                    switch (*f) {
+                    case '1':case '2':case '3':case '4':case '5':
+                    case '6':case '7':case '8':case '9':
+                        insertnr=*f-'0';
+                        switch (f[1]) {
+                        case '0':case '1':case '2':case '3':
+                        case '4':case '5':case '6':case '7':
+                        case '8':case '9':
+                            f++;
+                            insertnr=insertnr*10+*f-'0';
+                            f++;
+                            break;
+                        default:
+                            f++;
+                            break;
+                        }
+                        f = format_insertW( insertnr, f, dwFlags, &format_args, &str );
+                        for (x = str; *x; x++) ADD_TO_T(*x);
+                        HeapFree( GetProcessHeap(), 0, str );
+                        break;
+                    case 'n':
+                        ADD_TO_T('\r');
+                        ADD_TO_T('\n');
+                        f++;
+                        break;
+                    case '0':
+                        eos = TRUE;
+                        f++;
+                        break;
+                    default:
+                        ADD_TO_T(*f++);
+                        break;
+                    }
+                } else {
+                    ch = *f;
+                    f++;
+                    if (ch == '\r') {
+                        if (*f == '\n')
+                            f++;
+                        if(width)
+                            ADD_TO_T(' ');
+                        else
+                        {
+                            ADD_TO_T('\r');
+                            ADD_TO_T('\n');
+                        }
+                    } else {
+                        if (ch == '\n')
+                        {
+                            if(width)
+                                ADD_TO_T(' ');
+                            else
+                            {
+                                ADD_TO_T('\r');
+                                ADD_TO_T('\n');
+                            }
+                        }
+                        else
+                            ADD_TO_T(ch);
+                    }
+                }
+            }
+        }
+        *t='\0';
+    }
+    talloced = strlenW(target)+1;
+    if (nSize && talloced<nSize)
+        target = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,nSize*sizeof(WCHAR));
+    if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) {
+        /* nSize is the MINIMUM size */
+        DWORD len = strlenW(target) + 1;
+        *((LPVOID*)lpBuffer) = LocalAlloc(LMEM_ZEROINIT,len*sizeof(WCHAR));
+        strcpyW(*(LPWSTR*)lpBuffer, target);
+    }
+    else lstrcpynW(lpBuffer, target, nSize);
+
+    HeapFree(GetProcessHeap(),0,target);
+    HeapFree(GetProcessHeap(),0,from);
+    if (!(dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY)) HeapFree( GetProcessHeap(), 0, format_args.args );
+    DPRINT("ret=%S\n", (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
+        *(LPWSTR*)lpBuffer : lpBuffer);
+    return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ?
+        strlenW(*(LPWSTR*)lpBuffer):
+            strlenW(lpBuffer);
+}
+#undef ADD_TO_T

Propchange: trunk/reactos/dll/win32/kernel32/misc/format_msg.c
------------------------------------------------------------------------------
    svn:eol-style = native




More information about the Ros-diffs mailing list