From 7bee3f3c722c3f7adb5a81cf962e135038c97668 Mon Sep 17 00:00:00 2001 From: Steven Edwards Date: Wed, 5 Nov 2003 20:42:02 +0000 Subject: [PATCH] Nevermind. Regression found. Rolling back the last change. Jim's adaption of the WINE code was better. svn path=/trunk/; revision=6532 --- reactos/lib/kernel32/misc/errormsg.c | 479 ++++++++++++++++++--------- 1 file changed, 324 insertions(+), 155 deletions(-) diff --git a/reactos/lib/kernel32/misc/errormsg.c b/reactos/lib/kernel32/misc/errormsg.c index 8bcc1f0472c..cde8344fc51 100644 --- a/reactos/lib/kernel32/misc/errormsg.c +++ b/reactos/lib/kernel32/misc/errormsg.c @@ -1,3 +1,8 @@ +/* $Id: errormsg.c,v 1.10 2003/11/05 20:42:02 sedwards Exp $ + * + * reactos/lib/kernel32/misc/errormsg.c + * + */ /* * FormatMessage implementation * @@ -18,28 +23,59 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: errormsg.c,v 1.9 2003/11/05 20:32:07 sedwards Exp $ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS Kernel32 - * PURPOSE: Format Message - * FILE: lib/user32/controls/static.c - * PROGRAMER: Steven Edwards lib/kernel32/misc/errormsg.c - * REVISION HISTORY: 2003/11/05 Created - * NOTES: Adapted from Wine - */ - #include + +// #define NDEBUG #include #include -#include -#include -#include -/* Wine porting stuff */ +#define USE_WINE_PORT +#ifdef USE_WINE_PORT + +//#define NDEBUG +//#include + +//#define DPRINTF DPRINT +//#define ERR DPRINT +//#define SetLastError(x) +//#define WARN DPRINT #define TRACE DPRINT #define FIXME DPRINT + +//#define MAKEINTRESOURCE(i) (LPTSTR) ((DWORD) ((WORD) (i))) +//#define MAKEINTRESOURCEA(i) (LPTSTR) ((DWORD) ((WORD) (i))) +//#define MAKEINTRESOURCEW(i) (LPTSTR) ((DWORD) ((WORD) (i))) + +//#define MAKEINTRESOURCEA(i) (LPSTR)((ULONG_PTR)((WORD)(i))) +//#define MAKEINTRESOURCEW(i) (LPWSTR)((ULONG_PTR)((WORD)(i))) +//#define MAKEINTRESOURCE WINELIB_NAME_AW(MAKEINTRESOURCE) + + + +int HEAP_strdupWtoA(HANDLE hHeap, int flags, LPWSTR lpSource) +{ + return 0; +} + +/* INTERNAL */ + +//#include "config.h" + +#include +#include + +//#include "windef.h" +//#include "winbase.h" +//#include "winerror.h" +//#include "winuser.h" +//#include "winnls.h" +//#include "wine/unicode.h" +//#include "heap.h" +//#include "wine/debug.h" + +//WINE_DEFAULT_DEBUG_CHANNEL(resource); + typedef struct tagMESSAGE_RESOURCE_ENTRY { WORD Length; WORD Flags; @@ -58,39 +94,13 @@ typedef struct tagMESSAGE_RESOURCE_DATA { MESSAGE_RESOURCE_BLOCK Blocks[ 1 ]; } MESSAGE_RESOURCE_DATA,*PMESSAGE_RESOURCE_DATA; -/* These are needed so that we can call the functions from inside kernel itself */ -LPVOID WINAPI HeapAlloc( HANDLE heap, DWORD flags, SIZE_T size ) -{ - return RtlAllocateHeap( heap, flags, size ); -} - -BOOL WINAPI HeapFree( HANDLE heap, DWORD flags, LPVOID ptr ) -{ - return RtlFreeHeap( heap, flags, ptr ); -} - -LPVOID WINAPI HeapReAlloc( HANDLE heap, DWORD flags, LPVOID ptr, SIZE_T size ) -{ - return RtlReAllocateHeap( heap, flags, ptr, size ); -} - -/* 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 = HeapAlloc( heap, flags, len ); - if(ret) WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL ); - return ret; -} - -/* End of WINE porting Code */ +//#define RT_RCDATAA MAKEINTRESOURCEA(10) +//#define RT_RCDATAW MAKEINTRESOURCEW(10) +////#define RT_RCDATA WINELIB_NAME_AW(RT_RCDATA) +//#define RT_MESSAGETABLEA MAKEINTRESOURCEA(11) +//#define RT_MESSAGETABLEW MAKEINTRESOURCEW(11) +////#define RT_MESSAGETABLE WINELIB_NAME_AW(RT_MESSAGETABLE) /* Messages...used by FormatMessage32* (KERNEL32.something) * @@ -101,57 +111,85 @@ inline static LPSTR HEAP_strdupWtoA( HANDLE heap, DWORD flags, LPCWSTR str ) * start: * 0: DWORD nrofentries * nrofentries * subentry: - * 0: DWORD firstentry - * 4: DWORD lastentry + * 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 ] + * 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') + * (stringentry i of a subentry refers to the ID 'firstentry+i') * * Yes, ANSI strings in win32 resources. Go figure. */ /********************************************************************** - * load_messageA (internal) + * load_messageA (internal) */ static INT load_messageA( HMODULE instance, UINT id, WORD lang, LPSTR buffer, INT buflen ) { - const MESSAGE_RESOURCE_ENTRY *mre; - int i,slen; + HGLOBAL hmem; + HRSRC hrsrc; + PMESSAGE_RESOURCE_DATA mrd; + PMESSAGE_RESOURCE_BLOCK mrb; + PMESSAGE_RESOURCE_ENTRY mre; + int i,slen; - TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen); + //TRACE("instance = %08lx, id = %08lx, buffer = %p, length = %ld\n", (DWORD)instance, (DWORD)id, buffer, (DWORD)buflen); - //if (RtlFindMessage( instance, RT_MESSAGETABLE, lang, id, &mre ) != STATUS_SUCCESS) return 0; + /*FIXME: I am not sure about the '1' ... But I've only seen those entries*/ + hrsrc = FindResourceExW(instance,RT_MESSAGETABLEW,(LPWSTR)1,lang); + if (!hrsrc) return 0; + hmem = LoadResource( instance, hrsrc ); + if (!hmem) return 0; + mrd = (PMESSAGE_RESOURCE_DATA)LockResource(hmem); + mre = NULL; + mrb = &(mrd->Blocks[0]); + for (i=mrd->NumberOfBlocks;i--;) { + if ((id>=mrb->LowId) && (id<=mrb->HighId)) { + mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mrd)+mrb->OffsetToEntries); + id -= mrb->LowId; + break; + } + mrb++; + } + if (!mre) + return 0; + for (i=id;i--;) { + if (!mre->Length) + return 0; + mre = (PMESSAGE_RESOURCE_ENTRY)(((char*)mre)+mre->Length); + } slen=mre->Length; - TRACE(" - strlen=%d\n",slen); + //TRACE(" - strlen=%d\n",slen); i = min(buflen - 1, slen); if (buffer == NULL) - return slen; + return slen; if (i>0) { - if (mre->Flags & MESSAGE_RESOURCE_UNICODE) + if (mre->Flags & MESSAGE_RESOURCE_UNICODE) WideCharToMultiByte( CP_ACP, 0, (LPWSTR)mre->Text, -1, buffer, i, NULL, NULL ); - else - lstrcpynA(buffer, (LPSTR)mre->Text, i); - buffer[i]=0; + else + lstrcpynA(buffer, (LPSTR)mre->Text, i); + buffer[i]=0; } else { - if (buflen>1) { - buffer[0]=0; - return 0; - } + if (buflen>1) { + buffer[0]=0; + return 0; + } + } + if (buffer) { + //TRACE("'%s' copied !\n", buffer); + TRACE("'%s'\n", buffer); } - if (buffer) - TRACE("'%s' copied !\n", buffer); return i; } #if 0 /* FIXME */ /********************************************************************** - * load_messageW (internal) + * load_messageW (internal) */ static INT load_messageW( HMODULE instance, UINT id, WORD lang, LPWSTR buffer, INT buflen ) @@ -159,15 +197,15 @@ static INT load_messageW( HMODULE instance, UINT id, WORD lang, INT retval; LPSTR buffer2 = NULL; if (buffer && buflen) - buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen ); + buffer2 = HeapAlloc( GetProcessHeap(), 0, buflen ); retval = load_messageA(instance,id,lang,buffer2,buflen); if (buffer) { - if (retval) { - lstrcpynAtoW( buffer, buffer2, buflen ); - retval = strlenW( buffer ); - } - HeapFree( GetProcessHeap(), 0, buffer2 ); + if (retval) { + lstrcpynAtoW( buffer, buffer2, buflen ); + retval = lstrlenW( buffer ); + } + HeapFree( GetProcessHeap(), 0, buffer2 ); } return retval; } @@ -179,28 +217,27 @@ static INT load_messageW( HMODULE instance, UINT id, WORD lang, * FIXME: missing wrap, */ DWORD WINAPI FormatMessageA( - DWORD dwFlags, - LPCVOID lpSource, - DWORD dwMessageId, - DWORD dwLanguageId, - LPSTR lpBuffer, - DWORD nSize, - va_list* _args ) + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + LPSTR lpBuffer, + DWORD nSize, + va_list* _args ) { LPDWORD args=(LPDWORD)_args; #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; +/* This implementation is completely dependant 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; - INT bufsize; - HMODULE hmodule = (HMODULE)lpSource; - CHAR ch; + INT bufsize; + HMODULE hmodule = (HMODULE)lpSource; + CHAR ch; - TRACE("(0x%lx,%p,%ld,0x%lx,%p,%ld,%p)\n", - dwFlags,lpSource,dwMessageId,dwLanguageId,lpBuffer,nSize,args); + //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; @@ -210,7 +247,7 @@ DWORD WINAPI FormatMessageA( from = NULL; if (dwFlags & FORMAT_MESSAGE_FROM_STRING) { - from = HeapAlloc( GetProcessHeap(), 0, strlen((LPSTR)lpSource)+1 ); + from = RtlAllocateHeap(RtlGetProcessHeap(), 0, lstrlenA((LPSTR)lpSource)+1 ); strcpy( from, (LPSTR)lpSource ); } else { @@ -218,14 +255,36 @@ DWORD WINAPI FormatMessageA( if (dwFlags & FORMAT_MESSAGE_FROM_HMODULE) { - if (!hmodule) - hmodule = GetModuleHandleW(NULL); - bufsize=load_messageA(hmodule,dwMessageId,dwLanguageId,NULL,100); + bufsize=load_messageA(hmodule,dwMessageId,dwLanguageId,NULL,100); + if ((!bufsize) && (!dwLanguageId)) { + bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NULL,100); + } } if ((dwFlags & FORMAT_MESSAGE_FROM_SYSTEM) && (!bufsize)) { - hmodule = GetModuleHandleA("kernel32"); - bufsize=load_messageA(hmodule,dwMessageId,dwLanguageId,NULL,100); + hmodule = GetModuleHandleA("kernel32"); + bufsize=load_messageA(hmodule,dwMessageId,dwLanguageId,NULL,100); + if ((!bufsize) && (!dwLanguageId)) { + bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_NEUTRAL),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_NEUTRAL,SUBLANG_SYS_DEFAULT),NULL,100); + if (!bufsize) bufsize=load_messageA(hmodule,dwMessageId, + MAKELANGID(LANG_ENGLISH,SUBLANG_ENGLISH_US),NULL,100); + } } if (!bufsize) { @@ -233,17 +292,17 @@ DWORD WINAPI FormatMessageA( return 0; } - from = HeapAlloc( GetProcessHeap(), 0, bufsize + 1 ); + from = RtlAllocateHeap(RtlGetProcessHeap(), 0, bufsize + 1 ); load_messageA(hmodule,dwMessageId,dwLanguageId,from,bufsize+1); } - target = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, 100); - t = target; + target = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, 100); + t = target; talloced= 100; #define ADD_TO_T(c) do { \ *t++=c;\ if (t-target == talloced) {\ - target = (char*)HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\ + target = (char*)RtlReAllocateHeap(RtlGetProcessHeap(),HEAP_ZERO_MEMORY,target,talloced*2);\ t = target+talloced;\ talloced*=2;\ }\ @@ -289,17 +348,17 @@ DWORD WINAPI FormatMessageA( f++; if (NULL!=(x=strchr(f,'!'))) { *x='\0'; - fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2); + fmtstr=RtlAllocateHeap(RtlGetProcessHeap(),0,lstrlenA(f)+2); sprintf(fmtstr,"%%%s",f); f=x+1; } else { - fmtstr=HeapAlloc(GetProcessHeap(),0,strlen(f)+2); + fmtstr=RtlAllocateHeap(RtlGetProcessHeap(),0,lstrlenA(f)+2); sprintf(fmtstr,"%%%s",f); - f+=strlen(f); /*at \0*/ + f+=lstrlenA(f); /*at \0*/ } } else { if(!args) break; - fmtstr = HeapAlloc(GetProcessHeap(),0,3); + fmtstr = RtlAllocateHeap(RtlGetProcessHeap(),0,3); strcpy( fmtstr, "%s" ); } if (args) { @@ -314,17 +373,17 @@ DWORD WINAPI FormatMessageA( /* FIXME: precision and width components are not handled correctly */ if ( (strcmp(fmtstr, "%ls") == 0) || (strcmp(fmtstr,"%S") == 0) ) { sz = WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, NULL, 0, NULL, NULL); - b = HeapAlloc(GetProcessHeap(), 0, sz); + b = RtlAllocateHeap(RtlGetProcessHeap(), 0, sz); WideCharToMultiByte( CP_ACP, 0, *(WCHAR**)argliststart, -1, b, sz, NULL, NULL); } else { - b = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sz = 1000); + b = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, sz = 1000); /* CMF - This makes a BIG assumption about va_list */ TRACE("A BIG assumption\n"); - _vsnprintf(b, sz, fmtstr, (va_list) argliststart); + //vsnprintf(b, sz, fmtstr, (va_list) argliststart); } for (x=b; *x; x++) ADD_TO_T(*x); - HeapFree(GetProcessHeap(),0,b); + RtlFreeHeap(RtlGetProcessHeap(),0,b); } else { /* NULL args - copy formatstr * (probably wrong) @@ -333,7 +392,7 @@ DWORD WINAPI FormatMessageA( ADD_TO_T(*lastf++); } } - HeapFree(GetProcessHeap(),0,fmtstr); + RtlFreeHeap(GetProcessHeap(),0,fmtstr); break; case 'n': ADD_TO_T('\r'); @@ -380,9 +439,9 @@ DWORD WINAPI FormatMessageA( } *t='\0'; } - talloced = strlen(target)+1; + talloced = lstrlenA(target)+1; if (nSize && talloced 0 && !MultiByteToWideChar( CP_ACP, 0, target, -1, lpBuffer, nSize )) lpBuffer[nSize-1] = 0; } - HeapFree(GetProcessHeap(),0,target); - if (from) HeapFree(GetProcessHeap(),0,from); + RtlFreeHeap(RtlGetProcessHeap(),0,target); + if (from) RtlFreeHeap(RtlGetProcessHeap(),0,from); return (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) ? - strlenW(*(LPWSTR*)lpBuffer): - strlenW(lpBuffer); + lstrlenW(*(LPWSTR*)lpBuffer): + lstrlenW(lpBuffer); #else return 0; #endif /* __i386__ */ } #undef ADD_TO_T + + +#else + +/* EXPORTED */ + +/* + * @unimplemented + */ +DWORD +STDCALL +FormatMessageW( + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + LPWSTR lpBuffer, + DWORD nSize, + va_list* Arguments) +{ + +// RtlFormatMessage + + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} + + +/* + * @unimplemented + */ +DWORD +STDCALL +FormatMessageA( + DWORD dwFlags, + LPCVOID lpSource, + DWORD dwMessageId, + DWORD dwLanguageId, + LPSTR lpBuffer, + DWORD nSize, + va_list* Arguments) +{ + HLOCAL pBuf = NULL; + //LPSTR pBuf = NULL; + +#define MAX_MSG_STR_LEN 200 + + if (lpBuffer != NULL) { + + if (dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER) { + pBuf = LocalAlloc(LPTR, max(nSize, MAX_MSG_STR_LEN)); + if (pBuf == NULL) { + return 0; + } + *(LPSTR*)lpBuffer = pBuf; + } else { + pBuf = *(LPSTR*)lpBuffer; + } + + if (dwFlags & FORMAT_MESSAGE_FROM_STRING) { + } else { + } + +//FORMAT_MESSAGE_IGNORE_INSERTS +//FORMAT_MESSAGE_FROM_STRING +//FORMAT_MESSAGE_FROM_HMODULE +//FORMAT_MESSAGE_FROM_SYSTEM +//FORMAT_MESSAGE_ARGUMENT_ARRAY + + } +/* + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM, + 0, + error, + MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT), + (PTSTR)&msg, + 0, + NULL) + ) + */ + SetLastError(ERROR_CALL_NOT_IMPLEMENTED); + return 0; +} + +#endif + +/* EOF */