2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004,2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
37 #include "wine/unicode.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msi);
47 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
48 * which is a problem because LPCTSTR isn't defined when compiling wine.
49 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
50 * and make sure to only use it in W functions.
52 #define LPCTSTR LPCWSTR
54 DEFINE_GUID( CLSID_MsiDatabase, 0x000c1084, 0x0000, 0x0000,
55 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
58 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
60 INSTALLUI_HANDLERA gUIHandlerA = NULL;
61 INSTALLUI_HANDLERW gUIHandlerW = NULL;
63 LPVOID gUIContext = NULL;
64 WCHAR gszLogFile[MAX_PATH];
65 HINSTANCE msi_hInstance;
70 * A .msi file is a structured storage file.
71 * It should contain a number of streams.
74 VOID MSI_CloseDatabase( MSIOBJECTHDR *arg )
76 MSIDATABASE *db = (MSIDATABASE *) arg;
79 free_cached_tables( db );
80 r = IStorage_Release( db->storage );
82 ERR("database reference count was not zero (%ld)\n", r);
85 UINT MSI_OpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIDATABASE **pdb)
89 MSIDATABASE *db = NULL;
90 UINT ret = ERROR_FUNCTION_FAILED;
94 TRACE("%s %s\n",debugstr_w(szDBPath),debugstr_w(szPersist) );
97 return ERROR_INVALID_PARAMETER;
99 szMode = (LPWSTR) szPersist;
100 if( HIWORD( szPersist ) )
102 /* UINT len = lstrlenW( szPerist ) + 1; */
103 FIXME("don't support persist files yet\b");
104 return ERROR_INVALID_PARAMETER;
105 /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
107 else if( szPersist == MSIDBOPEN_READONLY )
109 r = StgOpenStorage( szDBPath, NULL,
110 STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
112 else if( szPersist == MSIDBOPEN_CREATE )
114 r = StgCreateDocfile( szDBPath,
115 STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
116 if( r == ERROR_SUCCESS )
118 IStorage_SetClass( stg, &CLSID_MsiDatabase );
119 r = init_string_table( stg );
122 else if( szPersist == MSIDBOPEN_TRANSACT )
124 r = StgOpenStorage( szDBPath, NULL,
125 STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
129 ERR("unknown flag %p\n",szPersist);
130 return ERROR_INVALID_PARAMETER;
135 FIXME("open failed r = %08lx!\n",r);
136 return ERROR_FUNCTION_FAILED;
139 r = IStorage_Stat( stg, &stat, STATFLAG_NONAME );
142 FIXME("Failed to stat storage\n");
146 if( memcmp( &stat.clsid, &CLSID_MsiDatabase, sizeof (GUID) ) )
148 ERR("storage GUID is not a MSI database GUID %s\n",
149 debugstr_guid(&stat.clsid) );
154 db = alloc_msiobject( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
158 FIXME("Failed to allocate a handle\n");
162 if( TRACE_ON( msi ) )
163 enum_stream_names( stg );
168 ret = load_string_table( db );
169 if( ret != ERROR_SUCCESS )
172 msiobj_addref( &db->hdr );
173 IStorage_AddRef( stg );
178 msiobj_release( &db->hdr );
180 IStorage_Release( stg );
185 UINT WINAPI MsiOpenDatabaseW(LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
190 TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
192 ret = MSI_OpenDatabaseW( szDBPath, szPersist, &db );
193 if( ret == ERROR_SUCCESS )
195 *phDB = alloc_msihandle( &db->hdr );
196 msiobj_release( &db->hdr );
202 UINT WINAPI MsiOpenDatabaseA(LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
204 HRESULT r = ERROR_FUNCTION_FAILED;
205 LPWSTR szwDBPath = NULL, szwPersist = NULL;
207 TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
211 szwDBPath = strdupAtoW( szDBPath );
216 if( HIWORD(szPersist) )
218 szwPersist = strdupAtoW( szPersist );
223 szwPersist = (LPWSTR) szPersist;
225 r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
228 HeapFree( GetProcessHeap(), 0, szwPersist );
229 HeapFree( GetProcessHeap(), 0, szwDBPath );
234 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
237 LPWSTR szwProd = NULL;
239 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
243 szwProd = strdupAtoW( szProduct );
245 return ERROR_OUTOFMEMORY;
248 ret = MsiOpenProductW( szwProd, phProduct );
250 HeapFree( GetProcessHeap(), 0, szwProd );
255 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
257 static const WCHAR szLocalPackage[] = {
258 'L','o','c','a','l','P','a','c','k','a','g','e', 0
262 HKEY hKeyProduct = NULL;
265 TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
267 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
268 if( r != ERROR_SUCCESS )
270 r = ERROR_UNKNOWN_PRODUCT;
274 /* find the size of the path */
276 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
277 NULL, &type, NULL, &count );
278 if( r != ERROR_SUCCESS )
280 r = ERROR_UNKNOWN_PRODUCT;
284 /* now alloc and fetch the path of the database to open */
285 path = HeapAlloc( GetProcessHeap(), 0, count );
289 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
290 NULL, &type, (LPBYTE) path, &count );
291 if( r != ERROR_SUCCESS )
293 r = ERROR_UNKNOWN_PRODUCT;
297 r = MsiOpenPackageW( path, phProduct );
300 HeapFree( GetProcessHeap(), 0, path );
302 RegCloseKey( hKeyProduct );
307 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
308 LPCSTR szTransforms, LANGID lgidLanguage)
310 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
311 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
312 return ERROR_CALL_NOT_IMPLEMENTED;
315 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
316 LPCWSTR szTransforms, LANGID lgidLanguage)
318 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
319 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
320 return ERROR_CALL_NOT_IMPLEMENTED;
323 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
324 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
326 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
327 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
328 lgidLanguage, dwPlatform, dwOptions);
329 return ERROR_CALL_NOT_IMPLEMENTED;
332 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
333 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
335 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
336 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
337 lgidLanguage, dwPlatform, dwOptions);
338 return ERROR_CALL_NOT_IMPLEMENTED;
341 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
343 LPWSTR szwPath = NULL, szwCommand = NULL;
344 UINT r = ERROR_FUNCTION_FAILED; /* FIXME: check return code */
346 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
350 szwPath = strdupAtoW( szPackagePath );
357 szwCommand = strdupAtoW( szCommandLine );
362 r = MsiInstallProductW( szwPath, szwCommand );
365 HeapFree( GetProcessHeap(), 0, szwPath );
366 HeapFree( GetProcessHeap(), 0, szwCommand );
371 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
373 MSIPACKAGE *package = NULL;
374 UINT rc = ERROR_SUCCESS;
377 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
379 rc = MsiVerifyPackageW(szPackagePath);
380 if (rc != ERROR_SUCCESS)
383 rc = MSI_OpenPackageW(szPackagePath,&package);
384 if (rc != ERROR_SUCCESS)
387 handle = alloc_msihandle( &package->hdr );
389 rc = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
391 MsiCloseHandle(handle);
392 msiobj_release( &package->hdr );
396 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
398 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
399 return ERROR_CALL_NOT_IMPLEMENTED;
402 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
404 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
405 return ERROR_CALL_NOT_IMPLEMENTED;
408 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
409 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
411 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
412 eInstallType, debugstr_a(szCommandLine));
413 return ERROR_CALL_NOT_IMPLEMENTED;
416 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
417 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
419 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
420 eInstallType, debugstr_w(szCommandLine));
421 return ERROR_CALL_NOT_IMPLEMENTED;
424 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
425 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
432 static const WCHAR szSouceList[] = {
433 'S','o','u','r','c','e','L','i','s','t',0};
434 static const WCHAR szLUS[] = {
435 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
436 WCHAR sourcepath[0x200];
437 static const WCHAR szInstalled[] = {
438 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
441 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
442 debugstr_w(szCommandLine));
444 if (eInstallState != INSTALLSTATE_LOCAL &&
445 eInstallState != INSTALLSTATE_DEFAULT)
447 FIXME("Not implemented for anything other than local installs\n");
448 return ERROR_CALL_NOT_IMPLEMENTED;
451 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
452 if (rc != ERROR_SUCCESS)
455 rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
456 if (rc != ERROR_SUCCESS)
459 sz = sizeof(sourcepath);
460 rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
461 if (rc != ERROR_SUCCESS)
466 * ok 1, we need to find the msi file for this product.
467 * 2, find the source dir for the files
468 * 3, do the configure/install.
469 * 4, cleanupany runonce entry.
472 rc = MsiOpenProductW(szProduct,&handle);
473 if (rc != ERROR_SUCCESS)
476 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
479 rc = ERROR_INVALID_HANDLE;
483 sz = lstrlenW(szInstalled);
486 sz += lstrlenW(szCommandLine);
488 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
491 strcpyW(commandline,szCommandLine);
495 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
496 strcatW(commandline,szInstalled);
498 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
500 msiobj_release( &package->hdr );
502 HeapFree(GetProcessHeap(),0,commandline);
509 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
510 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
512 LPWSTR szwProduct = NULL;
513 LPWSTR szwCommandLine = NULL;
514 UINT hr = ERROR_FUNCTION_FAILED;
518 szwProduct = strdupAtoW( szProduct );
525 szwCommandLine = strdupAtoW( szCommandLine );
530 hr = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
533 HeapFree( GetProcessHeap(), 0, szwProduct );
534 HeapFree( GetProcessHeap(), 0, szwCommandLine);
539 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
540 INSTALLSTATE eInstallState)
542 LPWSTR szwProduct = NULL;
543 UINT hr = ERROR_SUCCESS;
545 FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
549 szwProduct = strdupAtoW( szProduct );
554 hr = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
557 HeapFree( GetProcessHeap(), 0, szwProduct );
562 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
563 INSTALLSTATE eInstallState)
565 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
567 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState,
571 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
573 LPWSTR szwComponent = NULL;
574 UINT hr = ERROR_INSTALL_FAILURE;
575 WCHAR szwBuffer[GUID_SIZE];
577 FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
581 szwComponent = strdupAtoW( szComponent );
586 return ERROR_INVALID_PARAMETER;
588 hr = MsiGetProductCodeW( szwComponent, szwBuffer );
590 if( ERROR_SUCCESS == hr )
591 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
594 HeapFree( GetProcessHeap(), 0, szwComponent );
599 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
601 FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
602 if (NULL == szComponent)
603 return ERROR_INVALID_PARAMETER;
604 return ERROR_CALL_NOT_IMPLEMENTED;
607 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
608 LPSTR szBuffer, DWORD *pcchValueBuf)
610 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
611 UINT hr = ERROR_INSTALL_FAILURE;
613 FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute),
614 szBuffer, pcchValueBuf);
616 if( NULL != szBuffer && NULL == pcchValueBuf )
617 return ERROR_INVALID_PARAMETER;
620 szwProduct = strdupAtoW( szProduct );
625 return ERROR_INVALID_PARAMETER;
629 szwAttribute = strdupAtoW( szAttribute );
635 hr = ERROR_INVALID_PARAMETER;
641 szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
646 hr = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
648 if( ERROR_SUCCESS == hr )
649 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);
652 HeapFree( GetProcessHeap(), 0, szwProduct );
653 HeapFree( GetProcessHeap(), 0, szwAttribute );
654 HeapFree( GetProcessHeap(), 0, szwBuffer );
659 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
660 LPWSTR szBuffer, DWORD *pcchValueBuf)
665 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
666 szBuffer, pcchValueBuf);
668 if (NULL != szBuffer && NULL == pcchValueBuf)
669 return ERROR_INVALID_PARAMETER;
670 if (NULL == szProduct || NULL == szAttribute)
671 return ERROR_INVALID_PARAMETER;
673 hr = MsiOpenProductW(szProduct, &hProduct);
674 if (ERROR_SUCCESS != hr)
677 hr = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
678 MsiCloseHandle(hProduct);
682 UINT WINAPI MsiDatabaseImportA(MSIHANDLE handle, LPCSTR szFolderPath, LPCSTR szFilename)
684 FIXME("%lx %s %s\n",handle,debugstr_a(szFolderPath), debugstr_a(szFilename));
685 return ERROR_CALL_NOT_IMPLEMENTED;
688 UINT WINAPI MsiDatabaseImportW(MSIHANDLE handle, LPCWSTR szFolderPath, LPCWSTR szFilename)
690 FIXME("%lx %s %s\n",handle,debugstr_w(szFolderPath), debugstr_w(szFilename));
691 return ERROR_CALL_NOT_IMPLEMENTED;
694 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
696 LPWSTR szwLogFile = NULL;
697 UINT hr = ERROR_INSTALL_FAILURE;
699 FIXME("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
703 szwLogFile = strdupAtoW( szLogFile );
708 return ERROR_INVALID_PARAMETER;
710 hr = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
713 HeapFree( GetProcessHeap(), 0, szwLogFile );
718 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
720 HANDLE file = INVALID_HANDLE_VALUE;
722 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
724 strcpyW(gszLogFile,szLogFile);
725 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
726 DeleteFileW(szLogFile);
727 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
728 FILE_ATTRIBUTE_NORMAL, NULL);
729 if (file != INVALID_HANDLE_VALUE)
732 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
734 return ERROR_SUCCESS;
737 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
739 LPWSTR szwProduct = NULL;
744 szwProduct = strdupAtoW( szProduct );
746 return ERROR_OUTOFMEMORY;
748 r = MsiQueryProductStateW( szwProduct );
749 HeapFree( GetProcessHeap(), 0, szwProduct );
753 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
756 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
758 static const WCHAR szWindowsInstaller[] = {
759 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
762 TRACE("%s\n", debugstr_w(szProduct));
764 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
765 if (rc != ERROR_SUCCESS)
770 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
771 if (rc != ERROR_SUCCESS)
775 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
776 if (rc != ERROR_SUCCESS)
783 rrc = INSTALLSTATE_DEFAULT;
786 FIXME("Unknown install state read from registry (%i)\n",rrc);
787 rrc = INSTALLSTATE_UNKNOWN;
795 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
797 INSTALLUILEVEL old = gUILevel;
798 HWND oldwnd = gUIhwnd;
800 TRACE("%08x %p\n", dwUILevel, phWnd);
802 gUILevel = dwUILevel;
811 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
812 DWORD dwMessageFilter, LPVOID pvContext)
814 INSTALLUI_HANDLERA prev = gUIHandlerA;
816 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
817 gUIHandlerA = puiHandler;
818 gUIFilter = dwMessageFilter;
819 gUIContext = pvContext;
824 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
825 DWORD dwMessageFilter, LPVOID pvContext)
827 INSTALLUI_HANDLERW prev = gUIHandlerW;
829 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
830 gUIHandlerW = puiHandler;
831 gUIFilter = dwMessageFilter;
832 gUIContext = pvContext;
837 /******************************************************************
838 * MsiLoadStringW [MSI.@]
840 * Loads a string from MSI's string resources.
844 * handle [I] only -1 is handled currently
845 * id [I] id of the string to be loaded
846 * lpBuffer [O] buffer for the string to be written to
847 * nBufferMax [I] maximum size of the buffer in characters
848 * lang [I] the preferred language for the string
852 * If successful, this function returns the language id of the string loaded
853 * If the function fails, the function returns zero.
857 * The type of the first parameter is unknown. LoadString's prototype
858 * suggests that it might be a module handle. I have made it an MSI handle
859 * for starters, as -1 is an invalid MSI handle, but not an invalid module
860 * handle. Maybe strings can be stored in an MSI database somehow.
862 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
863 int nBufferMax, LANGID lang )
870 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
873 FIXME("don't know how to deal with handle = %08lx\n", handle);
876 lang = GetUserDefaultLangID();
878 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
882 hResData = LoadResource( msi_hInstance, hres );
885 p = LockResource( hResData );
889 for (i = 0; i < (id&0xf); i++)
893 if( nBufferMax <= len )
896 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
899 TRACE("found -> %s\n", debugstr_w(lpBuffer));
904 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
905 int nBufferMax, LANGID lang )
911 bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
912 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
915 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
916 if( len <= nBufferMax )
917 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
918 lpBuffer, nBufferMax, NULL, NULL );
922 HeapFree(GetProcessHeap(), 0, bufW);
926 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
929 FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
930 return INSTALLSTATE_UNKNOWN;
933 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPSTR lpPathBuf,
936 FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
937 return INSTALLSTATE_UNKNOWN;
940 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
941 WORD wLanguageId, DWORD f)
943 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
944 uType,wLanguageId,f);
945 return ERROR_CALL_NOT_IMPLEMENTED;
948 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
949 WORD wLanguageId, DWORD f)
951 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
952 uType,wLanguageId,f);
953 return ERROR_CALL_NOT_IMPLEMENTED;
956 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
957 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
960 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
961 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
963 return ERROR_CALL_NOT_IMPLEMENTED;
966 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
967 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
970 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
971 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
973 return ERROR_CALL_NOT_IMPLEMENTED;
976 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
977 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
979 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
980 return ERROR_CALL_NOT_IMPLEMENTED;
983 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
984 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
986 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
987 return ERROR_CALL_NOT_IMPLEMENTED;
990 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
991 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
994 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
995 ppcCertContext, pbHashData, pcbHashData);
996 return ERROR_CALL_NOT_IMPLEMENTED;
999 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1000 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
1003 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1004 ppcCertContext, pbHashData, pcbHashData);
1005 return ERROR_CALL_NOT_IMPLEMENTED;
1008 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
1009 LPSTR szValue, DWORD *pccbValue )
1011 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
1012 return ERROR_CALL_NOT_IMPLEMENTED;
1015 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
1016 LPWSTR szValue, DWORD *pccbValue )
1018 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
1019 return ERROR_CALL_NOT_IMPLEMENTED;
1022 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
1025 LPWSTR szPack = NULL;
1027 TRACE("%s\n", debugstr_a(szPackage) );
1031 szPack = strdupAtoW( szPackage );
1033 return ERROR_OUTOFMEMORY;
1036 r = MsiVerifyPackageW( szPack );
1038 HeapFree( GetProcessHeap(), 0, szPack );
1043 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
1048 TRACE("%s\n", debugstr_w(szPackage) );
1050 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
1051 MsiCloseHandle( handle );
1056 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1057 LPSTR lpPathBuf, DWORD* pcchBuf)
1059 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
1065 szwProduct = strdupAtoW( szProduct );
1067 return ERROR_OUTOFMEMORY;
1072 szwComponent = strdupAtoW( szComponent );
1075 HeapFree( GetProcessHeap(), 0, szwProduct);
1076 return ERROR_OUTOFMEMORY;
1080 if( pcchBuf && *pcchBuf > 0 )
1081 lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
1085 incoming_len = *pcchBuf;
1086 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
1088 HeapFree( GetProcessHeap(), 0, szwProduct);
1089 HeapFree( GetProcessHeap(), 0, szwComponent);
1092 if (rc != INSTALLSTATE_UNKNOWN)
1093 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
1094 lpPathBuf, incoming_len, NULL, NULL);
1095 HeapFree( GetProcessHeap(), 0, lpwPathBuf);
1101 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1102 LPWSTR lpPathBuf, DWORD* pcchBuf)
1104 WCHAR squished_pc[GUID_SIZE];
1106 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
1111 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1112 debugstr_w(szComponent), lpPathBuf, pcchBuf);
1114 if( lpPathBuf && !pcchBuf )
1115 return INSTALLSTATE_INVALIDARG;
1117 squash_guid(szProduct,squished_pc);
1119 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1120 if( rc != ERROR_SUCCESS )
1125 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1126 if( rc != ERROR_SUCCESS )
1131 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
1132 if( rc != ERROR_SUCCESS )
1134 if( type != REG_SZ )
1137 sz += sizeof(WCHAR);
1138 path = HeapAlloc( GetProcessHeap(), 0, sz );
1142 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
1143 if( rc != ERROR_SUCCESS )
1146 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1147 debugstr_w(szProduct), debugstr_w(path));
1151 FIXME("Registry entry.. check entry\n");
1152 rrc = INSTALLSTATE_LOCAL;
1156 /* PROBABLY a file */
1157 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
1158 rrc = INSTALLSTATE_LOCAL;
1160 rrc = INSTALLSTATE_ABSENT;
1165 sz = sz / sizeof(WCHAR);
1166 if( *pcchBuf >= sz )
1167 strcpyW( lpPathBuf, path );
1172 HeapFree(GetProcessHeap(), 0, path );
1177 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1180 LPWSTR szwProduct= NULL;
1181 LPWSTR szwFeature= NULL;
1185 szwProduct = strdupAtoW( szProduct );
1187 return ERROR_OUTOFMEMORY;
1192 szwFeature = strdupAtoW( szFeature );
1195 HeapFree( GetProcessHeap(), 0, szwProduct);
1196 return ERROR_OUTOFMEMORY;
1200 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1202 HeapFree( GetProcessHeap(), 0, szwProduct);
1203 HeapFree( GetProcessHeap(), 0, szwFeature);
1208 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1210 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1212 * Iterates all the features components and the features parents components
1214 return INSTALLSTATE_LOCAL;
1217 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1218 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1220 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1221 UINT ret = ERROR_OUTOFMEMORY;
1225 szwFilePath = strdupAtoW( szFilePath );
1230 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1232 lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1233 if( !lpwVersionBuff )
1237 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1239 lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1244 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1245 lpwLangBuff, pcchLangBuf);
1247 if( lpwVersionBuff )
1248 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1249 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1251 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1252 lpLangBuf, *pcchLangBuf, NULL, NULL);
1255 HeapFree(GetProcessHeap(), 0, szwFilePath);
1256 HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
1257 HeapFree(GetProcessHeap(), 0, lpwLangBuff);
1262 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1263 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1265 static const WCHAR szVersionResource[] = {'\\',0};
1266 static const WCHAR szVersionFormat[] = {
1267 '%','d','.','%','d','.','%','d','.','%','d',0};
1268 static const WCHAR szLangFormat[] = {'%','d',0};
1271 LPVOID lpVer = NULL;
1272 VS_FIXEDFILEINFO *ffi;
1276 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1277 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1278 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1280 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1282 return GetLastError();
1284 lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
1287 ret = ERROR_OUTOFMEMORY;
1291 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1293 ret = GetLastError();
1296 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1298 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1301 wsprintfW(tmp, szVersionFormat,
1302 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1303 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1304 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1305 *pcchVersionBuf = strlenW(lpVersionBuf);
1310 *pcchVersionBuf = 0;
1314 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1316 DWORD lang = GetUserDefaultLangID();
1318 FIXME("Retrieve language from file\n");
1319 wsprintfW(tmp, szLangFormat, lang);
1320 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1321 *pcchLangBuf = strlenW(lpLangBuf);
1325 HeapFree(GetProcessHeap(), 0, lpVer);
1330 /******************************************************************
1333 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1337 case DLL_PROCESS_ATTACH:
1338 msi_hInstance = hinstDLL;
1339 DisableThreadLibraryCalls(hinstDLL);
1340 msi_dialog_register_class();
1342 case DLL_PROCESS_DETACH:
1343 msi_dialog_unregister_class();
1344 /* FIXME: Cleanup */
1350 typedef struct tagIClassFactoryImpl
1352 IClassFactoryVtbl *lpVtbl;
1353 } IClassFactoryImpl;
1355 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1356 REFIID riid,LPVOID *ppobj)
1358 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1359 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1360 return E_NOINTERFACE;
1363 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1368 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1373 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1374 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1376 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1378 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1382 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1384 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1386 FIXME("%p %d\n", This, dolock);
1390 static IClassFactoryVtbl MsiCF_Vtbl =
1392 MsiCF_QueryInterface,
1395 MsiCF_CreateInstance,
1399 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1401 /******************************************************************
1402 * DllGetClassObject [MSI.@]
1404 HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1406 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1408 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1409 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1410 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1411 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1412 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1414 *ppv = (LPVOID) &Msi_CF;
1417 return CLASS_E_CLASSNOTAVAILABLE;
1420 /******************************************************************
1421 * DllGetVersion [MSI.@]
1423 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
1427 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1428 return E_INVALIDARG;
1430 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1431 pdvi->dwMinorVersion = MSI_MINORVERSION;
1432 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1433 pdvi->dwPlatformID = 1;
1438 /******************************************************************
1439 * DllCanUnloadNow [MSI.@]
1441 BOOL WINAPI MSI_DllCanUnloadNow(void)
1446 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1447 DWORD* pdwUseCount, WORD* pwDateUsed)
1449 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1450 pdwUseCount, pwDateUsed);
1451 return ERROR_CALL_NOT_IMPLEMENTED;
1454 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1455 DWORD* pdwUseCount, WORD* pwDateUsed)
1457 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1458 pdwUseCount, pwDateUsed);
1459 return ERROR_CALL_NOT_IMPLEMENTED;
1462 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1463 DWORD dwInstallMode, DWORD dwReserved)
1465 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1466 dwInstallMode, dwReserved);
1469 * Polls all the components of the feature to find install state and then
1471 * Software\\Microsoft\\Windows\\CurrentVersion\\
1472 * Installer\\Products\\<squishguid>\\<feature>
1473 * "Usage"=dword:........
1476 return INSTALLSTATE_LOCAL;
1479 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1480 DWORD dwInstallMode, DWORD dwReserved)
1482 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1483 dwInstallMode, dwReserved);
1485 return INSTALLSTATE_LOCAL;
1488 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1490 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1492 return INSTALLSTATE_LOCAL;
1495 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1497 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1499 return INSTALLSTATE_LOCAL;
1502 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1503 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1504 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1507 FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1508 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1509 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1511 return ERROR_INDEX_ABSENT;
1514 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1515 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1516 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1518 FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1519 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1522 return USERINFOSTATE_UNKNOWN;
1525 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1526 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1527 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1529 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1530 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1533 return USERINFOSTATE_UNKNOWN;
1536 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1538 FIXME("%s\n",debugstr_w(szProduct));
1539 return ERROR_CALL_NOT_IMPLEMENTED;
1542 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1544 FIXME("%s\n",debugstr_a(szProduct));
1545 return ERROR_CALL_NOT_IMPLEMENTED;
1548 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1550 FIXME("%ld\n", dwReserved);
1551 return ERROR_CALL_NOT_IMPLEMENTED;
1554 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1555 LPSTR szProductCode, LPSTR szFeatureId,
1556 LPSTR szComponentCode )
1559 return ERROR_CALL_NOT_IMPLEMENTED;
1562 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1563 LPWSTR szProductCode, LPWSTR szFeatureId,
1564 LPWSTR szComponentCode )
1567 return ERROR_CALL_NOT_IMPLEMENTED;
1570 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1571 DWORD dwReinstallMode )
1573 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1575 return ERROR_SUCCESS;
1578 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1579 DWORD dwReinstallMode )
1581 FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1583 return ERROR_SUCCESS;