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"
39 WINE_DEFAULT_DEBUG_CHANNEL(msi);
42 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
43 * which is a problem because LPCTSTR isn't defined when compiling wine.
44 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
45 * and make sure to only use it in W functions.
47 #define LPCTSTR LPCWSTR
50 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
52 INSTALLUI_HANDLERA gUIHandlerA = NULL;
53 INSTALLUI_HANDLERW gUIHandlerW = NULL;
55 LPVOID gUIContext = NULL;
56 WCHAR gszLogFile[MAX_PATH];
57 HINSTANCE msi_hInstance;
59 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
62 LPWSTR szwProd = NULL;
64 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
68 szwProd = strdupAtoW( szProduct );
70 return ERROR_OUTOFMEMORY;
73 r = MsiOpenProductW( szwProd, phProduct );
75 HeapFree( GetProcessHeap(), 0, szwProd );
80 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
82 static const WCHAR szLocalPackage[] = {
83 'L','o','c','a','l','P','a','c','k','a','g','e', 0
87 HKEY hKeyProduct = NULL;
90 TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
92 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
93 if( r != ERROR_SUCCESS )
95 r = ERROR_UNKNOWN_PRODUCT;
99 /* find the size of the path */
101 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
102 NULL, &type, NULL, &count );
103 if( r != ERROR_SUCCESS )
105 r = ERROR_UNKNOWN_PRODUCT;
109 /* now alloc and fetch the path of the database to open */
110 path = HeapAlloc( GetProcessHeap(), 0, count );
114 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
115 NULL, &type, (LPBYTE) path, &count );
116 if( r != ERROR_SUCCESS )
118 r = ERROR_UNKNOWN_PRODUCT;
122 r = MsiOpenPackageW( path, phProduct );
125 HeapFree( GetProcessHeap(), 0, path );
127 RegCloseKey( hKeyProduct );
132 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
133 LPCSTR szTransforms, LANGID lgidLanguage)
135 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
136 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
137 return ERROR_CALL_NOT_IMPLEMENTED;
140 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
141 LPCWSTR szTransforms, LANGID lgidLanguage)
143 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
144 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
145 return ERROR_CALL_NOT_IMPLEMENTED;
148 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
149 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
151 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
152 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
153 lgidLanguage, dwPlatform, dwOptions);
154 return ERROR_CALL_NOT_IMPLEMENTED;
157 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
158 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
160 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
161 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
162 lgidLanguage, dwPlatform, dwOptions);
163 return ERROR_CALL_NOT_IMPLEMENTED;
166 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
168 LPWSTR szwPath = NULL, szwCommand = NULL;
169 UINT r = ERROR_OUTOFMEMORY;
171 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
175 szwPath = strdupAtoW( szPackagePath );
182 szwCommand = strdupAtoW( szCommandLine );
187 r = MsiInstallProductW( szwPath, szwCommand );
190 HeapFree( GetProcessHeap(), 0, szwPath );
191 HeapFree( GetProcessHeap(), 0, szwCommand );
196 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
198 MSIPACKAGE *package = NULL;
202 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
204 r = MsiVerifyPackageW(szPackagePath);
205 if (r != ERROR_SUCCESS)
208 r = MSI_OpenPackageW(szPackagePath,&package);
209 if (r != ERROR_SUCCESS)
212 handle = alloc_msihandle( &package->hdr );
214 r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
216 MsiCloseHandle(handle);
217 msiobj_release( &package->hdr );
221 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
223 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
224 return ERROR_CALL_NOT_IMPLEMENTED;
227 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
229 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
230 return ERROR_CALL_NOT_IMPLEMENTED;
233 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
234 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
236 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
237 eInstallType, debugstr_a(szCommandLine));
238 return ERROR_CALL_NOT_IMPLEMENTED;
241 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
242 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
244 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
245 eInstallType, debugstr_w(szCommandLine));
246 return ERROR_CALL_NOT_IMPLEMENTED;
249 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
250 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
257 static const WCHAR szSouceList[] = {
258 'S','o','u','r','c','e','L','i','s','t',0};
259 static const WCHAR szLUS[] = {
260 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
261 WCHAR sourcepath[0x200];
262 static const WCHAR szInstalled[] = {
263 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
266 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
267 debugstr_w(szCommandLine));
269 if (eInstallState != INSTALLSTATE_LOCAL &&
270 eInstallState != INSTALLSTATE_DEFAULT)
272 FIXME("Not implemented for anything other than local installs\n");
273 return ERROR_CALL_NOT_IMPLEMENTED;
276 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
277 if (rc != ERROR_SUCCESS)
280 rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
281 if (rc != ERROR_SUCCESS)
284 sz = sizeof(sourcepath);
285 rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
286 if (rc != ERROR_SUCCESS)
291 * ok 1, we need to find the msi file for this product.
292 * 2, find the source dir for the files
293 * 3, do the configure/install.
294 * 4, cleanupany runonce entry.
297 rc = MsiOpenProductW(szProduct,&handle);
298 if (rc != ERROR_SUCCESS)
301 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
304 rc = ERROR_INVALID_HANDLE;
308 sz = lstrlenW(szInstalled);
311 sz += lstrlenW(szCommandLine);
313 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
316 lstrcpyW(commandline,szCommandLine);
320 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
321 lstrcatW(commandline,szInstalled);
323 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
325 msiobj_release( &package->hdr );
327 HeapFree(GetProcessHeap(),0,commandline);
334 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
335 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
337 LPWSTR szwProduct = NULL;
338 LPWSTR szwCommandLine = NULL;
339 UINT r = ERROR_OUTOFMEMORY;
343 szwProduct = strdupAtoW( szProduct );
350 szwCommandLine = strdupAtoW( szCommandLine );
355 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
358 HeapFree( GetProcessHeap(), 0, szwProduct );
359 HeapFree( GetProcessHeap(), 0, szwCommandLine);
364 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
365 INSTALLSTATE eInstallState)
367 LPWSTR szwProduct = NULL;
370 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
374 szwProduct = strdupAtoW( szProduct );
376 return ERROR_OUTOFMEMORY;
379 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
380 HeapFree( GetProcessHeap(), 0, szwProduct );
385 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
386 INSTALLSTATE eInstallState)
388 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
390 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
393 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
395 LPWSTR szwComponent = NULL;
397 WCHAR szwBuffer[GUID_SIZE];
399 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
403 szwComponent = strdupAtoW( szComponent );
405 return ERROR_OUTOFMEMORY;
408 r = MsiGetProductCodeW( szwComponent, szwBuffer );
410 if( ERROR_SUCCESS == r )
411 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
413 HeapFree( GetProcessHeap(), 0, szwComponent );
418 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
420 FIXME("%s %p\n",debugstr_w(szComponent), szBuffer);
422 if (NULL == szComponent)
423 return ERROR_INVALID_PARAMETER;
424 return ERROR_CALL_NOT_IMPLEMENTED;
427 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
428 LPSTR szBuffer, DWORD *pcchValueBuf)
430 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
431 UINT r = ERROR_OUTOFMEMORY;
433 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
434 szBuffer, pcchValueBuf);
438 szwProduct = strdupAtoW( szProduct );
445 szwAttribute = strdupAtoW( szAttribute );
452 szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
457 r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
459 if( ERROR_SUCCESS == r )
460 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);
463 HeapFree( GetProcessHeap(), 0, szwProduct );
464 HeapFree( GetProcessHeap(), 0, szwAttribute );
465 HeapFree( GetProcessHeap(), 0, szwBuffer );
470 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
471 LPWSTR szBuffer, DWORD *pcchValueBuf)
476 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
477 szBuffer, pcchValueBuf);
479 if (NULL != szBuffer && NULL == pcchValueBuf)
480 return ERROR_INVALID_PARAMETER;
481 if (NULL == szProduct || NULL == szAttribute)
482 return ERROR_INVALID_PARAMETER;
484 r = MsiOpenProductW(szProduct, &hProduct);
485 if (ERROR_SUCCESS != r)
488 r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
489 MsiCloseHandle(hProduct);
493 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
495 LPWSTR szwLogFile = NULL;
498 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
502 szwLogFile = strdupAtoW( szLogFile );
504 return ERROR_OUTOFMEMORY;
506 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
507 HeapFree( GetProcessHeap(), 0, szwLogFile );
511 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
513 HANDLE file = INVALID_HANDLE_VALUE;
515 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
517 lstrcpyW(gszLogFile,szLogFile);
518 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
519 DeleteFileW(szLogFile);
520 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
521 FILE_ATTRIBUTE_NORMAL, NULL);
522 if (file != INVALID_HANDLE_VALUE)
525 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
527 return ERROR_SUCCESS;
530 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
532 LPWSTR szwProduct = NULL;
537 szwProduct = strdupAtoW( szProduct );
539 return ERROR_OUTOFMEMORY;
541 r = MsiQueryProductStateW( szwProduct );
542 HeapFree( GetProcessHeap(), 0, szwProduct );
546 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
549 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
551 static const WCHAR szWindowsInstaller[] = {
552 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
555 TRACE("%s\n", debugstr_w(szProduct));
557 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
558 if (rc != ERROR_SUCCESS)
563 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
564 if (rc != ERROR_SUCCESS)
568 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
569 if (rc != ERROR_SUCCESS)
576 rrc = INSTALLSTATE_DEFAULT;
579 FIXME("Unknown install state read from registry (%i)\n",rrc);
580 rrc = INSTALLSTATE_UNKNOWN;
588 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
590 INSTALLUILEVEL old = gUILevel;
591 HWND oldwnd = gUIhwnd;
593 TRACE("%08x %p\n", dwUILevel, phWnd);
595 gUILevel = dwUILevel;
604 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
605 DWORD dwMessageFilter, LPVOID pvContext)
607 INSTALLUI_HANDLERA prev = gUIHandlerA;
609 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
610 gUIHandlerA = puiHandler;
611 gUIFilter = dwMessageFilter;
612 gUIContext = pvContext;
617 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
618 DWORD dwMessageFilter, LPVOID pvContext)
620 INSTALLUI_HANDLERW prev = gUIHandlerW;
622 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
623 gUIHandlerW = puiHandler;
624 gUIFilter = dwMessageFilter;
625 gUIContext = pvContext;
630 /******************************************************************
631 * MsiLoadStringW [MSI.@]
633 * Loads a string from MSI's string resources.
637 * handle [I] only -1 is handled currently
638 * id [I] id of the string to be loaded
639 * lpBuffer [O] buffer for the string to be written to
640 * nBufferMax [I] maximum size of the buffer in characters
641 * lang [I] the preferred language for the string
645 * If successful, this function returns the language id of the string loaded
646 * If the function fails, the function returns zero.
650 * The type of the first parameter is unknown. LoadString's prototype
651 * suggests that it might be a module handle. I have made it an MSI handle
652 * for starters, as -1 is an invalid MSI handle, but not an invalid module
653 * handle. Maybe strings can be stored in an MSI database somehow.
655 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
656 int nBufferMax, LANGID lang )
663 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
666 FIXME("don't know how to deal with handle = %08lx\n", handle);
669 lang = GetUserDefaultLangID();
671 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
675 hResData = LoadResource( msi_hInstance, hres );
678 p = LockResource( hResData );
682 for (i = 0; i < (id&0xf); i++)
686 if( nBufferMax <= len )
689 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
692 TRACE("found -> %s\n", debugstr_w(lpBuffer));
697 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
698 int nBufferMax, LANGID lang )
704 bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
705 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
708 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
709 if( len <= nBufferMax )
710 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
711 lpBuffer, nBufferMax, NULL, NULL );
715 HeapFree(GetProcessHeap(), 0, bufW);
719 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
722 FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
723 return INSTALLSTATE_UNKNOWN;
726 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPSTR lpPathBuf,
729 FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
730 return INSTALLSTATE_UNKNOWN;
733 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
734 WORD wLanguageId, DWORD f)
736 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
737 uType,wLanguageId,f);
738 return ERROR_CALL_NOT_IMPLEMENTED;
741 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
742 WORD wLanguageId, DWORD f)
744 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
745 uType,wLanguageId,f);
746 return ERROR_CALL_NOT_IMPLEMENTED;
749 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
750 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
753 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
754 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
756 return ERROR_CALL_NOT_IMPLEMENTED;
759 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
760 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
763 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
764 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
766 return ERROR_CALL_NOT_IMPLEMENTED;
769 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
770 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
772 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
773 return ERROR_CALL_NOT_IMPLEMENTED;
776 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
777 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
779 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
780 return ERROR_CALL_NOT_IMPLEMENTED;
783 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
784 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
787 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
788 ppcCertContext, pbHashData, pcbHashData);
789 return ERROR_CALL_NOT_IMPLEMENTED;
792 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
793 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
796 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
797 ppcCertContext, pbHashData, pcbHashData);
798 return ERROR_CALL_NOT_IMPLEMENTED;
801 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
802 LPSTR szValue, DWORD *pccbValue )
804 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
805 return ERROR_CALL_NOT_IMPLEMENTED;
808 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
809 LPWSTR szValue, DWORD *pccbValue )
811 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
812 return ERROR_CALL_NOT_IMPLEMENTED;
815 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
818 LPWSTR szPack = NULL;
820 TRACE("%s\n", debugstr_a(szPackage) );
824 szPack = strdupAtoW( szPackage );
826 return ERROR_OUTOFMEMORY;
829 r = MsiVerifyPackageW( szPack );
831 HeapFree( GetProcessHeap(), 0, szPack );
836 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
841 TRACE("%s\n", debugstr_w(szPackage) );
843 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
844 MsiCloseHandle( handle );
849 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
850 LPSTR lpPathBuf, DWORD* pcchBuf)
852 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
858 szwProduct = strdupAtoW( szProduct );
860 return ERROR_OUTOFMEMORY;
865 szwComponent = strdupAtoW( szComponent );
868 HeapFree( GetProcessHeap(), 0, szwProduct);
869 return ERROR_OUTOFMEMORY;
873 if( pcchBuf && *pcchBuf > 0 )
874 lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
878 incoming_len = *pcchBuf;
879 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
881 HeapFree( GetProcessHeap(), 0, szwProduct);
882 HeapFree( GetProcessHeap(), 0, szwComponent);
885 if (rc != INSTALLSTATE_UNKNOWN)
886 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
887 lpPathBuf, incoming_len, NULL, NULL);
888 HeapFree( GetProcessHeap(), 0, lpwPathBuf);
894 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
895 LPWSTR lpPathBuf, DWORD* pcchBuf)
897 WCHAR squished_pc[GUID_SIZE];
899 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
904 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
905 debugstr_w(szComponent), lpPathBuf, pcchBuf);
907 if( lpPathBuf && !pcchBuf )
908 return INSTALLSTATE_INVALIDARG;
910 squash_guid(szProduct,squished_pc);
912 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
913 if( rc != ERROR_SUCCESS )
918 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
919 if( rc != ERROR_SUCCESS )
924 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
925 if( rc != ERROR_SUCCESS )
931 path = HeapAlloc( GetProcessHeap(), 0, sz );
935 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
936 if( rc != ERROR_SUCCESS )
939 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
940 debugstr_w(szProduct), debugstr_w(path));
944 FIXME("Registry entry.. check entry\n");
945 rrc = INSTALLSTATE_LOCAL;
949 /* PROBABLY a file */
950 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
951 rrc = INSTALLSTATE_LOCAL;
953 rrc = INSTALLSTATE_ABSENT;
958 sz = sz / sizeof(WCHAR);
960 lstrcpyW( lpPathBuf, path );
965 HeapFree(GetProcessHeap(), 0, path );
970 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
973 LPWSTR szwProduct= NULL;
974 LPWSTR szwFeature= NULL;
978 szwProduct = strdupAtoW( szProduct );
980 return ERROR_OUTOFMEMORY;
985 szwFeature = strdupAtoW( szFeature );
988 HeapFree( GetProcessHeap(), 0, szwProduct);
989 return ERROR_OUTOFMEMORY;
993 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
995 HeapFree( GetProcessHeap(), 0, szwProduct);
996 HeapFree( GetProcessHeap(), 0, szwFeature);
1001 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1003 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1005 * Iterates all the features components and the features parents components
1007 return INSTALLSTATE_LOCAL;
1010 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1011 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1013 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1014 UINT ret = ERROR_OUTOFMEMORY;
1018 szwFilePath = strdupAtoW( szFilePath );
1023 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1025 lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1026 if( !lpwVersionBuff )
1030 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1032 lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1037 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1038 lpwLangBuff, pcchLangBuf);
1040 if( lpwVersionBuff )
1041 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1042 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1044 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1045 lpLangBuf, *pcchLangBuf, NULL, NULL);
1048 HeapFree(GetProcessHeap(), 0, szwFilePath);
1049 HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
1050 HeapFree(GetProcessHeap(), 0, lpwLangBuff);
1055 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1056 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1058 static const WCHAR szVersionResource[] = {'\\',0};
1059 static const WCHAR szVersionFormat[] = {
1060 '%','d','.','%','d','.','%','d','.','%','d',0};
1061 static const WCHAR szLangFormat[] = {'%','d',0};
1064 LPVOID lpVer = NULL;
1065 VS_FIXEDFILEINFO *ffi;
1069 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1070 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1071 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1073 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1075 return GetLastError();
1077 lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
1080 ret = ERROR_OUTOFMEMORY;
1084 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1086 ret = GetLastError();
1089 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1091 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1094 wsprintfW(tmp, szVersionFormat,
1095 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1096 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1097 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1098 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1103 *pcchVersionBuf = 0;
1107 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1109 DWORD lang = GetUserDefaultLangID();
1111 FIXME("Retrieve language from file\n");
1112 wsprintfW(tmp, szLangFormat, lang);
1113 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1114 *pcchLangBuf = lstrlenW(lpLangBuf);
1118 HeapFree(GetProcessHeap(), 0, lpVer);
1123 /******************************************************************
1126 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1130 case DLL_PROCESS_ATTACH:
1131 msi_hInstance = hinstDLL;
1132 DisableThreadLibraryCalls(hinstDLL);
1133 msi_dialog_register_class();
1135 case DLL_PROCESS_DETACH:
1136 msi_dialog_unregister_class();
1137 /* FIXME: Cleanup */
1143 typedef struct tagIClassFactoryImpl
1145 IClassFactoryVtbl *lpVtbl;
1146 } IClassFactoryImpl;
1148 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1149 REFIID riid,LPVOID *ppobj)
1151 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1152 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1153 return E_NOINTERFACE;
1156 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1161 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1166 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1167 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1169 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1171 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1175 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1177 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1179 FIXME("%p %d\n", This, dolock);
1183 static IClassFactoryVtbl MsiCF_Vtbl =
1185 MsiCF_QueryInterface,
1188 MsiCF_CreateInstance,
1192 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1194 /******************************************************************
1195 * DllGetClassObject [MSI.@]
1197 HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1199 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1201 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1202 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1203 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1204 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1205 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1207 *ppv = (LPVOID) &Msi_CF;
1210 return CLASS_E_CLASSNOTAVAILABLE;
1213 /******************************************************************
1214 * DllGetVersion [MSI.@]
1216 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
1220 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1221 return E_INVALIDARG;
1223 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1224 pdvi->dwMinorVersion = MSI_MINORVERSION;
1225 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1226 pdvi->dwPlatformID = 1;
1231 /******************************************************************
1232 * DllCanUnloadNow [MSI.@]
1234 BOOL WINAPI MSI_DllCanUnloadNow(void)
1239 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1240 DWORD* pdwUseCount, WORD* pwDateUsed)
1242 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1243 pdwUseCount, pwDateUsed);
1244 return ERROR_CALL_NOT_IMPLEMENTED;
1247 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1248 DWORD* pdwUseCount, WORD* pwDateUsed)
1250 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1251 pdwUseCount, pwDateUsed);
1252 return ERROR_CALL_NOT_IMPLEMENTED;
1255 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1256 DWORD dwInstallMode, DWORD dwReserved)
1258 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1259 dwInstallMode, dwReserved);
1262 * Polls all the components of the feature to find install state and then
1264 * Software\\Microsoft\\Windows\\CurrentVersion\\
1265 * Installer\\Products\\<squishguid>\\<feature>
1266 * "Usage"=dword:........
1269 return INSTALLSTATE_LOCAL;
1272 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1273 DWORD dwInstallMode, DWORD dwReserved)
1275 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1276 dwInstallMode, dwReserved);
1278 return INSTALLSTATE_LOCAL;
1281 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1283 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1285 return INSTALLSTATE_LOCAL;
1288 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1290 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1292 return INSTALLSTATE_LOCAL;
1295 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1296 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1297 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1300 FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1301 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1302 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1304 return ERROR_INDEX_ABSENT;
1307 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1308 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1309 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1311 FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1312 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1315 return USERINFOSTATE_UNKNOWN;
1318 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1319 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1320 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1322 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1323 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1326 return USERINFOSTATE_UNKNOWN;
1329 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1331 FIXME("%s\n",debugstr_w(szProduct));
1332 return ERROR_CALL_NOT_IMPLEMENTED;
1335 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1337 FIXME("%s\n",debugstr_a(szProduct));
1338 return ERROR_CALL_NOT_IMPLEMENTED;
1341 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1343 FIXME("%ld\n", dwReserved);
1344 return ERROR_CALL_NOT_IMPLEMENTED;
1347 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1348 LPSTR szProductCode, LPSTR szFeatureId,
1349 LPSTR szComponentCode )
1352 return ERROR_CALL_NOT_IMPLEMENTED;
1355 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1356 LPWSTR szProductCode, LPWSTR szFeatureId,
1357 LPWSTR szComponentCode )
1360 return ERROR_CALL_NOT_IMPLEMENTED;
1363 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1364 DWORD dwReinstallMode )
1366 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1368 return ERROR_SUCCESS;
1371 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1372 DWORD dwReinstallMode )
1374 FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1376 return ERROR_SUCCESS;