From 65fb09183b0c09fd2286280439f2956c6f41d98a Mon Sep 17 00:00:00 2001 From: Mike McCormack Date: Tue, 8 Feb 2005 12:12:29 +0000 Subject: [PATCH] Implement and document MsiLoadString. --- dlls/msi/.cvsignore | 2 +- dlls/msi/Makefile.in | 2 +- dlls/msi/msi.c | 93 ++++++++++++++++++++++++++++++++++++++++---- dlls/msi/msi.rc | 30 ++++++++++++++ dlls/msi/msi_En.rc | 33 ++++++++++++++++ 5 files changed, 150 insertions(+), 10 deletions(-) create mode 100644 dlls/msi/msi.rc create mode 100644 dlls/msi/msi_En.rc diff --git a/dlls/msi/.cvsignore b/dlls/msi/.cvsignore index 87a07b99af1..74bea65d6f4 100644 --- a/dlls/msi/.cvsignore +++ b/dlls/msi/.cvsignore @@ -2,7 +2,7 @@ Makefile cond.tab.c cond.tab.h msi.dll.dbg.c +msi.res msi.spec.def sql.tab.c sql.tab.h -version.res diff --git a/dlls/msi/Makefile.in b/dlls/msi/Makefile.in index 2f7ff0b5cef..c11a908d6d1 100644 --- a/dlls/msi/Makefile.in +++ b/dlls/msi/Makefile.in @@ -32,7 +32,7 @@ C_SRCS = \ update.c \ where.c -RC_SRCS = version.rc +RC_SRCS = msi.rc EXTRA_SRCS = sql.y cond.y EXTRA_OBJS = sql.tab.o cond.tab.o diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c index 06417256e27..9f934033c5d 100644 --- a/dlls/msi/msi.c +++ b/dlls/msi/msi.c @@ -62,6 +62,7 @@ INSTALLUI_HANDLERW gUIHandlerW = NULL; DWORD gUIFilter = 0; LPVOID gUIContext = NULL; WCHAR gszLogFile[MAX_PATH]; +HINSTANCE msi_hInstance; /* * .MSI file format @@ -848,18 +849,93 @@ INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler, return prev; } -UINT WINAPI MsiLoadStringA(HINSTANCE hInstance, UINT uID, LPSTR lpBuffer, - int nBufferMax, DWORD e) +/****************************************************************** + * MsiLoadStringW [MSI.@] + * + * Loads a string from MSI's string resources. + * + * PARAMS + * + * handle [I] only -1 is handled currently + * id [I] id of the string to be loaded + * lpBuffer [O] buffer for the string to be written to + * nBufferMax [I] maximum size of the buffer in characters + * lang [I] the prefered language for the string + * + * RETURNS + * + * If successful, this function returns the language id of the string loaded + * If the function fails, the function returns zero. + * + * NOTES + * + * The type of the first parameter is unknown. LoadString's prototype + * suggests that it might be a module handle. I have made it an MSI handle + * for starters, as -1 is an invalid MSI handle, but not an invalid module + * handle. Maybe strings can be stored in an MSI database somehow. + */ +LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer, + int nBufferMax, LANGID lang ) { - FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e); - return ERROR_CALL_NOT_IMPLEMENTED; + HRSRC hres; + HGLOBAL hResData; + LPWSTR p; + DWORD i, len; + + TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang); + + if( handle != -1 ) + FIXME("don't know how to deal with handle = %08lx\n", handle); + + if( !lang ) + lang = GetUserDefaultLangID(); + + hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING, + (LPWSTR)1, lang ); + if( !hres ) + return 0; + hResData = LoadResource( msi_hInstance, hres ); + if( !hResData ) + return 0; + p = LockResource( hResData ); + if( !p ) + return 0; + + for (i = 0; i < (id&0xf); i++) + p += *p + 1; + len = *p; + + if( nBufferMax <= len ) + return 0; + + memcpy( lpBuffer, p+1, len * sizeof(WCHAR)); + lpBuffer[ len ] = 0; + + TRACE("found -> %s\n", debugstr_w(lpBuffer)); + + return lang; } -UINT WINAPI MsiLoadStringW(HINSTANCE hInstance, UINT uID, LPWSTR lpBuffer, - int nBufferMax, DWORD e) +LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer, + int nBufferMax, LANGID lang ) { - FIXME("%p %u %p %d %08lx\n",hInstance,uID,lpBuffer,nBufferMax,e); - return ERROR_CALL_NOT_IMPLEMENTED; + LPWSTR bufW; + LANGID r; + DWORD len; + + bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR)); + r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang); + if( r ) + { + len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL ); + if( len <= nBufferMax ) + WideCharToMultiByte( CP_ACP, 0, bufW, -1, + lpBuffer, nBufferMax, NULL, NULL ); + else + r = 0; + } + HeapFree(GetProcessHeap(), 0, bufW); + return r; } INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf, @@ -1466,6 +1542,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) switch(fdwReason) { case DLL_PROCESS_ATTACH: + msi_hInstance = hinstDLL; DisableThreadLibraryCalls(hinstDLL); msi_dialog_register_class(); break; diff --git a/dlls/msi/msi.rc b/dlls/msi/msi.rc new file mode 100644 index 00000000000..879cad5c586 --- /dev/null +++ b/dlls/msi/msi.rc @@ -0,0 +1,30 @@ +/* + * Resources for MSI + * + * Copyright 2005 Mike McCormack + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winnls.h" + +LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL + +#include "version.rc" + +#include "msi_En.rc" diff --git a/dlls/msi/msi_En.rc b/dlls/msi/msi_En.rc new file mode 100644 index 00000000000..f3330c88528 --- /dev/null +++ b/dlls/msi/msi_En.rc @@ -0,0 +1,33 @@ +/* + * English resources for MSI + * + * Copyright 2005 Mike McCormack + * + * 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT + +STRINGTABLE DISCARDABLE +{ + 5 "path %s not found" + 9 "insert disk %s" + 10 "bad parameters" + 11 "enter which folder contains %s" + 12 "install source for feature missing" + 13 "network drive for feature missing" + 14 "feature from:" + 15 "choose which folder contains %s" +}