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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
41 #include "wine/unicode.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msi);
47 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
49 INSTALLUI_HANDLERA gUIHandlerA = NULL;
50 INSTALLUI_HANDLERW gUIHandlerW = NULL;
52 LPVOID gUIContext = NULL;
53 WCHAR gszLogFile[MAX_PATH];
54 HINSTANCE msi_hInstance;
56 static LONG dll_count;
58 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
61 * Dll lifetime tracking declaration
63 static void LockModule(void)
65 InterlockedIncrement(&dll_count);
68 static void UnlockModule(void)
70 InterlockedDecrement(&dll_count);
74 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
77 LPWSTR szwProd = NULL;
79 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
83 szwProd = strdupAtoW( szProduct );
85 return ERROR_OUTOFMEMORY;
88 r = MsiOpenProductW( szwProd, phProduct );
95 static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
99 HKEY hKeyProduct = NULL;
102 TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
104 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
105 if( r != ERROR_SUCCESS )
107 r = ERROR_UNKNOWN_PRODUCT;
111 /* find the size of the path */
113 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
114 NULL, &type, NULL, &count );
115 if( r != ERROR_SUCCESS )
117 r = ERROR_UNKNOWN_PRODUCT;
121 /* now alloc and fetch the path of the database to open */
122 path = msi_alloc( count );
126 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
127 NULL, &type, (LPBYTE) path, &count );
128 if( r != ERROR_SUCCESS )
130 r = ERROR_UNKNOWN_PRODUCT;
134 r = MSI_OpenPackageW( path, ppackage );
139 RegCloseKey( hKeyProduct );
144 UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
146 MSIPACKAGE *package = NULL;
149 r = MSI_OpenProductW( szProduct, &package );
150 if( r == ERROR_SUCCESS )
152 *phProduct = alloc_msihandle( &package->hdr );
153 msiobj_release( &package->hdr );
158 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
159 LPCSTR szTransforms, LANGID lgidLanguage)
161 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
162 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
163 return ERROR_CALL_NOT_IMPLEMENTED;
166 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
167 LPCWSTR szTransforms, LANGID lgidLanguage)
169 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
170 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
171 return ERROR_CALL_NOT_IMPLEMENTED;
174 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
175 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
177 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
178 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
179 lgidLanguage, dwPlatform, dwOptions);
180 return ERROR_CALL_NOT_IMPLEMENTED;
183 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
184 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
186 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
187 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
188 lgidLanguage, dwPlatform, dwOptions);
189 return ERROR_CALL_NOT_IMPLEMENTED;
192 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
194 LPWSTR szwPath = NULL, szwCommand = NULL;
195 UINT r = ERROR_OUTOFMEMORY;
197 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
201 szwPath = strdupAtoW( szPackagePath );
208 szwCommand = strdupAtoW( szCommandLine );
213 r = MsiInstallProductW( szwPath, szwCommand );
217 msi_free( szwCommand );
222 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
224 MSIPACKAGE *package = NULL;
227 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
229 r = MSI_OpenPackageW( szPackagePath, &package );
230 if (r == ERROR_SUCCESS)
232 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
233 msiobj_release( &package->hdr );
239 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
241 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
242 return ERROR_CALL_NOT_IMPLEMENTED;
245 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
247 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
248 return ERROR_CALL_NOT_IMPLEMENTED;
251 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
252 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
254 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
255 eInstallType, debugstr_a(szCommandLine));
256 return ERROR_CALL_NOT_IMPLEMENTED;
259 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
260 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
262 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
263 eInstallType, debugstr_w(szCommandLine));
264 return ERROR_CALL_NOT_IMPLEMENTED;
267 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
268 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
270 MSIPACKAGE* package = NULL;
273 WCHAR sourcepath[MAX_PATH];
274 WCHAR filename[MAX_PATH];
275 static const WCHAR szInstalled[] = {
276 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
279 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
280 debugstr_w(szCommandLine));
282 if (eInstallState != INSTALLSTATE_LOCAL &&
283 eInstallState != INSTALLSTATE_DEFAULT)
285 FIXME("Not implemented for anything other than local installs\n");
286 return ERROR_CALL_NOT_IMPLEMENTED;
289 sz = sizeof(sourcepath);
290 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
291 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
294 sz = sizeof(filename);
295 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
296 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
298 lstrcatW(sourcepath,filename);
301 * ok 1, we need to find the msi file for this product.
302 * 2, find the source dir for the files
303 * 3, do the configure/install.
304 * 4, cleanupany runonce entry.
307 r = MSI_OpenProductW( szProduct, &package );
308 if (r != ERROR_SUCCESS)
311 sz = lstrlenW(szInstalled) + 1;
314 sz += lstrlenW(szCommandLine);
316 commandline = msi_alloc(sz * sizeof(WCHAR));
319 r = ERROR_OUTOFMEMORY;
325 lstrcpyW(commandline,szCommandLine);
327 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
328 lstrcatW(commandline,szInstalled);
330 r = MSI_InstallPackage( package, sourcepath, commandline );
332 msi_free(commandline);
335 msiobj_release( &package->hdr );
340 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
341 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
343 LPWSTR szwProduct = NULL;
344 LPWSTR szwCommandLine = NULL;
345 UINT r = ERROR_OUTOFMEMORY;
349 szwProduct = strdupAtoW( szProduct );
356 szwCommandLine = strdupAtoW( szCommandLine );
361 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
364 msi_free( szwProduct );
365 msi_free( szwCommandLine);
370 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
371 INSTALLSTATE eInstallState)
373 LPWSTR szwProduct = NULL;
376 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
380 szwProduct = strdupAtoW( szProduct );
382 return ERROR_OUTOFMEMORY;
385 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
386 msi_free( szwProduct );
391 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
392 INSTALLSTATE eInstallState)
394 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
397 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
399 LPWSTR szwComponent = NULL;
401 WCHAR szwBuffer[GUID_SIZE];
403 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
407 szwComponent = strdupAtoW( szComponent );
409 return ERROR_OUTOFMEMORY;
412 r = MsiGetProductCodeW( szwComponent, szwBuffer );
414 if( ERROR_SUCCESS == r )
415 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
417 msi_free( szwComponent );
422 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
426 WCHAR szSquished[GUID_SIZE];
427 DWORD sz = GUID_SIZE;
428 static const WCHAR szPermKey[] =
429 { '0','0','0','0','0','0','0','0','0','0','0','0',
430 '0','0','0','0','0','0','0','0','0','0','0','0',
431 '0','0','0','0','0','0','0','0',0};
433 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
435 if (NULL == szComponent)
436 return ERROR_INVALID_PARAMETER;
438 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
439 if (rc != ERROR_SUCCESS)
440 return ERROR_UNKNOWN_COMPONENT;
442 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
443 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
446 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
451 if (rc != ERROR_SUCCESS)
452 return ERROR_INSTALL_FAILURE;
454 unsquash_guid(szSquished, szBuffer);
455 return ERROR_SUCCESS;
458 UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
459 awstring *szValue, DWORD *pcchValueBuf)
465 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
466 debugstr_w(szAttribute), szValue, pcchValueBuf);
469 * FIXME: Values seem scattered/duplicated in the registry. Is there a system?
472 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
473 return ERROR_INVALID_PARAMETER;
475 /* check for special properties */
476 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
479 WCHAR packagecode[35];
481 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
482 if (r != ERROR_SUCCESS)
483 return ERROR_UNKNOWN_PRODUCT;
485 regval = msi_reg_get_val_str( hkey, szAttribute );
488 if (unsquash_guid(regval, packagecode))
489 val = strdupW(packagecode);
495 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
497 static const WCHAR one[] = { '1',0 };
499 * FIXME: should be in the Product key (user or system?)
500 * but isn't written yet...
502 val = strdupW( one );
504 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
505 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
507 static const WCHAR fmt[] = { '%','u',0 };
511 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
512 if (r != ERROR_SUCCESS)
513 return ERROR_UNKNOWN_PRODUCT;
515 if (msi_reg_get_val_dword( hkey, szAttribute, ®val))
517 sprintfW(szVal, fmt, regval);
518 val = strdupW( szVal );
523 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
525 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
526 if (r != ERROR_SUCCESS)
527 return ERROR_UNKNOWN_PRODUCT;
529 val = msi_reg_get_val_str( hkey, szAttribute );
535 static const WCHAR szDisplayVersion[] = {
536 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
538 FIXME("%s\n", debugstr_w(szAttribute));
539 /* FIXME: some attribute values not tested... */
541 if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
542 szAttribute = szDisplayVersion;
544 r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
545 if (r != ERROR_SUCCESS)
546 return ERROR_UNKNOWN_PRODUCT;
548 val = msi_reg_get_val_str( hkey, szAttribute );
553 TRACE("returning %s\n", debugstr_w(val));
556 return ERROR_UNKNOWN_PROPERTY;
558 r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
560 HeapFree(GetProcessHeap(), 0, val);
565 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
566 LPSTR szBuffer, DWORD *pcchValueBuf)
568 LPWSTR szwProduct, szwAttribute = NULL;
569 UINT r = ERROR_OUTOFMEMORY;
572 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
573 szBuffer, pcchValueBuf);
575 szwProduct = strdupAtoW( szProduct );
576 if( szProduct && !szwProduct )
579 szwAttribute = strdupAtoW( szAttribute );
580 if( szAttribute && !szwAttribute )
583 buffer.unicode = FALSE;
584 buffer.str.a = szBuffer;
586 r = MSI_GetProductInfo( szwProduct, szwAttribute,
587 &buffer, pcchValueBuf );
590 msi_free( szwProduct );
591 msi_free( szwAttribute );
596 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
597 LPWSTR szBuffer, DWORD *pcchValueBuf)
601 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
602 szBuffer, pcchValueBuf);
604 buffer.unicode = TRUE;
605 buffer.str.w = szBuffer;
607 return MSI_GetProductInfo( szProduct, szAttribute,
608 &buffer, pcchValueBuf );
611 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
613 LPWSTR szwLogFile = NULL;
616 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
620 szwLogFile = strdupAtoW( szLogFile );
622 return ERROR_OUTOFMEMORY;
624 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
625 msi_free( szwLogFile );
629 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
631 HANDLE file = INVALID_HANDLE_VALUE;
633 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
635 lstrcpyW(gszLogFile,szLogFile);
636 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
637 DeleteFileW(szLogFile);
638 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
639 FILE_ATTRIBUTE_NORMAL, NULL);
640 if (file != INVALID_HANDLE_VALUE)
643 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
645 return ERROR_SUCCESS;
648 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
650 LPWSTR szwProduct = NULL;
655 szwProduct = strdupAtoW( szProduct );
657 return ERROR_OUTOFMEMORY;
659 r = MsiQueryProductStateW( szwProduct );
660 msi_free( szwProduct );
664 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
667 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
669 static const WCHAR szWindowsInstaller[] = {
670 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
673 TRACE("%s\n", debugstr_w(szProduct));
676 return INSTALLSTATE_INVALIDARG;
678 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
679 if (rc != ERROR_SUCCESS)
684 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
685 if (rc != ERROR_SUCCESS)
689 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
690 if (rc != ERROR_SUCCESS)
697 rrc = INSTALLSTATE_DEFAULT;
700 FIXME("Unknown install state read from registry (%i)\n",rrc);
701 rrc = INSTALLSTATE_UNKNOWN;
709 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
711 INSTALLUILEVEL old = gUILevel;
712 HWND oldwnd = gUIhwnd;
714 TRACE("%08x %p\n", dwUILevel, phWnd);
716 gUILevel = dwUILevel;
725 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
726 DWORD dwMessageFilter, LPVOID pvContext)
728 INSTALLUI_HANDLERA prev = gUIHandlerA;
730 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
731 gUIHandlerA = puiHandler;
732 gUIFilter = dwMessageFilter;
733 gUIContext = pvContext;
738 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
739 DWORD dwMessageFilter, LPVOID pvContext)
741 INSTALLUI_HANDLERW prev = gUIHandlerW;
743 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
744 gUIHandlerW = puiHandler;
745 gUIFilter = dwMessageFilter;
746 gUIContext = pvContext;
751 /******************************************************************
752 * MsiLoadStringW [MSI.@]
754 * Loads a string from MSI's string resources.
758 * handle [I] only -1 is handled currently
759 * id [I] id of the string to be loaded
760 * lpBuffer [O] buffer for the string to be written to
761 * nBufferMax [I] maximum size of the buffer in characters
762 * lang [I] the preferred language for the string
766 * If successful, this function returns the language id of the string loaded
767 * If the function fails, the function returns zero.
771 * The type of the first parameter is unknown. LoadString's prototype
772 * suggests that it might be a module handle. I have made it an MSI handle
773 * for starters, as -1 is an invalid MSI handle, but not an invalid module
774 * handle. Maybe strings can be stored in an MSI database somehow.
776 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
777 int nBufferMax, LANGID lang )
784 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
787 FIXME("don't know how to deal with handle = %08lx\n", handle);
790 lang = GetUserDefaultLangID();
792 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
796 hResData = LoadResource( msi_hInstance, hres );
799 p = LockResource( hResData );
803 for (i = 0; i < (id&0xf); i++)
807 if( nBufferMax <= len )
810 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
813 TRACE("found -> %s\n", debugstr_w(lpBuffer));
818 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
819 int nBufferMax, LANGID lang )
825 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
826 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
829 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
830 if( len <= nBufferMax )
831 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
832 lpBuffer, nBufferMax, NULL, NULL );
840 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
843 char szProduct[GUID_SIZE];
845 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
847 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
848 return INSTALLSTATE_UNKNOWN;
850 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
853 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
856 WCHAR szProduct[GUID_SIZE];
858 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
860 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
861 return INSTALLSTATE_UNKNOWN;
863 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
866 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
867 WORD wLanguageId, DWORD f)
869 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
870 uType,wLanguageId,f);
871 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
874 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
875 WORD wLanguageId, DWORD f)
877 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
878 uType,wLanguageId,f);
879 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
882 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
883 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
886 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
887 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
889 return ERROR_CALL_NOT_IMPLEMENTED;
892 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
893 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
896 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
897 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
899 return ERROR_CALL_NOT_IMPLEMENTED;
902 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
903 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
905 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
906 return ERROR_CALL_NOT_IMPLEMENTED;
909 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
910 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
912 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
913 return ERROR_CALL_NOT_IMPLEMENTED;
916 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
917 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
920 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
921 ppcCertContext, pbHashData, pcbHashData);
922 return ERROR_CALL_NOT_IMPLEMENTED;
925 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
926 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
929 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
930 ppcCertContext, pbHashData, pcbHashData);
931 return ERROR_CALL_NOT_IMPLEMENTED;
934 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
935 LPSTR szValue, DWORD *pccbValue )
937 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
938 return ERROR_CALL_NOT_IMPLEMENTED;
941 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
942 LPWSTR szValue, DWORD *pccbValue )
944 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
945 return ERROR_CALL_NOT_IMPLEMENTED;
948 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
951 LPWSTR szPack = NULL;
953 TRACE("%s\n", debugstr_a(szPackage) );
957 szPack = strdupAtoW( szPackage );
959 return ERROR_OUTOFMEMORY;
962 r = MsiVerifyPackageW( szPack );
969 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
974 TRACE("%s\n", debugstr_w(szPackage) );
976 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
977 MsiCloseHandle( handle );
982 INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
983 awstring* lpPathBuf, DWORD* pcchBuf)
985 WCHAR squished_pc[GUID_SIZE], squished_comp[GUID_SIZE];
991 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
992 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
994 if( !szProduct || !szComponent )
995 return INSTALLSTATE_INVALIDARG;
996 if( lpPathBuf->str.w && !pcchBuf )
997 return INSTALLSTATE_INVALIDARG;
999 if (!squash_guid( szProduct, squished_pc ) ||
1000 !squash_guid( szComponent, squished_comp ))
1001 return INSTALLSTATE_INVALIDARG;
1003 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1004 if( rc != ERROR_SUCCESS )
1005 return INSTALLSTATE_UNKNOWN;
1009 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1010 if( rc != ERROR_SUCCESS )
1011 return INSTALLSTATE_UNKNOWN;
1013 path = msi_reg_get_val_str( hkey, squished_pc );
1016 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1017 debugstr_w(szProduct), debugstr_w(path));
1020 return INSTALLSTATE_UNKNOWN;
1023 r = INSTALLSTATE_LOCAL;
1025 r = INSTALLSTATE_NOTUSED;
1027 msi_strcpy_to_awstring( path, lpPathBuf, pcchBuf );
1033 /******************************************************************
1034 * MsiGetComponentPathW [MSI.@]
1036 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1037 LPWSTR lpPathBuf, DWORD* pcchBuf)
1041 path.unicode = TRUE;
1042 path.str.w = lpPathBuf;
1044 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1047 /******************************************************************
1048 * MsiGetComponentPathA [MSI.@]
1050 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1051 LPSTR lpPathBuf, DWORD* pcchBuf)
1053 LPWSTR szwProduct, szwComponent = NULL;
1054 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1057 szwProduct = strdupAtoW( szProduct );
1058 if( szProduct && !szwProduct)
1061 szwComponent = strdupAtoW( szComponent );
1062 if( szComponent && !szwComponent )
1065 path.unicode = FALSE;
1066 path.str.a = lpPathBuf;
1068 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1071 msi_free( szwProduct );
1072 msi_free( szwComponent );
1077 /******************************************************************
1078 * MsiQueryFeatureStateA [MSI.@]
1080 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1082 LPWSTR szwProduct = NULL, szwFeature= NULL;
1083 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1085 szwProduct = strdupAtoW( szProduct );
1086 if ( szProduct && !szwProduct )
1089 szwFeature = strdupAtoW( szFeature );
1090 if ( szFeature && !szwFeature )
1093 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1096 msi_free( szwProduct);
1097 msi_free( szwFeature);
1102 /******************************************************************
1103 * MsiQueryFeatureStateW [MSI.@]
1105 * Checks the state of a feature
1108 * szProduct [I] Product's GUID string
1109 * szFeature [I] Feature's GUID string
1112 * INSTALLSTATE_LOCAL Feature is installed and useable
1113 * INSTALLSTATE_ABSENT Feature is absent
1114 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1115 * INSTALLSTATE_UNKNOWN An error occured
1116 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1119 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1121 WCHAR squishProduct[33], comp[GUID_SIZE];
1123 LPWSTR components, p, parent_feature;
1127 BOOL missing = FALSE;
1129 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1131 if (!szProduct || !szFeature)
1132 return INSTALLSTATE_INVALIDARG;
1134 if (!squash_guid( szProduct, squishProduct ))
1135 return INSTALLSTATE_INVALIDARG;
1137 /* check that it's installed at all */
1138 rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
1139 if (rc != ERROR_SUCCESS)
1140 return INSTALLSTATE_UNKNOWN;
1142 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1145 if (!parent_feature)
1146 return INSTALLSTATE_UNKNOWN;
1148 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1149 msi_free(parent_feature);
1150 if (r == INSTALLSTATE_ABSENT)
1153 /* now check if it's complete or advertised */
1154 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1155 if (rc != ERROR_SUCCESS)
1156 return INSTALLSTATE_UNKNOWN;
1158 components = msi_reg_get_val_str( hkey, szFeature );
1161 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1165 ERR("components missing %s %s\n",
1166 debugstr_w(szProduct), debugstr_w(szFeature));
1167 return INSTALLSTATE_UNKNOWN;
1170 for( p = components; *p != 2 ; p += 20)
1172 if (!decode_base85_guid( p, &guid ))
1174 ERR("%s\n", debugstr_w(p));
1177 StringFromGUID2(&guid, comp, GUID_SIZE);
1178 r = MsiGetComponentPathW(szProduct, comp, NULL, 0);
1179 TRACE("component %s state %d\n", debugstr_guid(&guid), r);
1182 case INSTALLSTATE_NOTUSED:
1183 case INSTALLSTATE_LOCAL:
1184 case INSTALLSTATE_SOURCE:
1191 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1192 msi_free(components);
1195 return INSTALLSTATE_ADVERTISED;
1197 return INSTALLSTATE_LOCAL;
1200 /******************************************************************
1201 * MsiGetFileVersionA [MSI.@]
1203 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1204 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1206 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1207 UINT ret = ERROR_OUTOFMEMORY;
1211 szwFilePath = strdupAtoW( szFilePath );
1216 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1218 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1219 if( !lpwVersionBuff )
1223 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1225 lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1230 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1231 lpwLangBuff, pcchLangBuf);
1233 if( lpwVersionBuff )
1234 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1235 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1237 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1238 lpLangBuf, *pcchLangBuf, NULL, NULL);
1241 msi_free(szwFilePath);
1242 msi_free(lpwVersionBuff);
1243 msi_free(lpwLangBuff);
1248 /******************************************************************
1249 * MsiGetFileVersionW [MSI.@]
1251 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1252 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1254 static WCHAR szVersionResource[] = {'\\',0};
1255 static const WCHAR szVersionFormat[] = {
1256 '%','d','.','%','d','.','%','d','.','%','d',0};
1257 static const WCHAR szLangFormat[] = {'%','d',0};
1260 LPVOID lpVer = NULL;
1261 VS_FIXEDFILEINFO *ffi;
1265 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1266 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1267 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1269 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1271 return GetLastError();
1273 lpVer = msi_alloc(dwVerLen);
1276 ret = ERROR_OUTOFMEMORY;
1280 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1282 ret = GetLastError();
1285 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1287 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1290 wsprintfW(tmp, szVersionFormat,
1291 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1292 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1293 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1294 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1299 *pcchVersionBuf = 0;
1303 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1305 DWORD lang = GetUserDefaultLangID();
1307 FIXME("Retrieve language from file\n");
1308 wsprintfW(tmp, szLangFormat, lang);
1309 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1310 *pcchLangBuf = lstrlenW(lpLangBuf);
1319 /******************************************************************
1322 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1326 case DLL_PROCESS_ATTACH:
1327 msi_hInstance = hinstDLL;
1328 DisableThreadLibraryCalls(hinstDLL);
1329 msi_dialog_register_class();
1331 case DLL_PROCESS_DETACH:
1332 msi_dialog_unregister_class();
1333 /* FIXME: Cleanup */
1339 typedef struct tagIClassFactoryImpl
1341 const IClassFactoryVtbl *lpVtbl;
1342 } IClassFactoryImpl;
1344 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1345 REFIID riid,LPVOID *ppobj)
1347 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1348 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1349 return E_NOINTERFACE;
1352 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1358 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1364 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1365 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1367 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1369 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1373 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1375 TRACE("(%p)->(%d)\n", iface, dolock);
1385 static const IClassFactoryVtbl MsiCF_Vtbl =
1387 MsiCF_QueryInterface,
1390 MsiCF_CreateInstance,
1394 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1396 /******************************************************************
1397 * DllGetClassObject [MSI.@]
1399 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1401 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1403 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1404 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1405 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1406 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1407 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1409 *ppv = (LPVOID) &Msi_CF;
1412 return CLASS_E_CLASSNOTAVAILABLE;
1415 /******************************************************************
1416 * DllGetVersion [MSI.@]
1418 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
1422 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1423 return E_INVALIDARG;
1425 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1426 pdvi->dwMinorVersion = MSI_MINORVERSION;
1427 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1428 pdvi->dwPlatformID = 1;
1433 /******************************************************************
1434 * DllCanUnloadNow [MSI.@]
1436 HRESULT WINAPI DllCanUnloadNow(void)
1438 return dll_count == 0 ? S_OK : S_FALSE;
1441 /***********************************************************************
1442 * MsiGetFeatureUsageW [MSI.@]
1444 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
1445 DWORD* pdwUseCount, WORD* pwDateUsed )
1447 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1448 pdwUseCount, pwDateUsed);
1449 return ERROR_CALL_NOT_IMPLEMENTED;
1452 /***********************************************************************
1453 * MsiGetFeatureUsageA [MSI.@]
1455 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
1456 DWORD* pdwUseCount, WORD* pwDateUsed )
1458 LPWSTR prod = NULL, feat = NULL;
1459 UINT ret = ERROR_OUTOFMEMORY;
1461 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1462 pdwUseCount, pwDateUsed);
1464 prod = strdupAtoW( szProduct );
1465 if (szProduct && !prod)
1468 feat = strdupAtoW( szFeature );
1469 if (szFeature && !feat)
1472 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
1481 /***********************************************************************
1482 * MsiUseFeatureExW [MSI.@]
1484 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
1485 DWORD dwInstallMode, DWORD dwReserved )
1489 TRACE("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1490 dwInstallMode, dwReserved);
1492 state = MsiQueryFeatureStateW( szProduct, szFeature );
1495 return INSTALLSTATE_INVALIDARG;
1497 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
1499 FIXME("mark product %s feature %s as used\n",
1500 debugstr_w(szProduct), debugstr_w(szFeature) );
1506 /***********************************************************************
1507 * MsiUseFeatureExA [MSI.@]
1509 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
1510 DWORD dwInstallMode, DWORD dwReserved )
1512 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
1513 LPWSTR prod = NULL, feat = NULL;
1515 TRACE("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1516 dwInstallMode, dwReserved);
1518 prod = strdupAtoW( szProduct );
1519 if (szProduct && !prod)
1522 feat = strdupAtoW( szFeature );
1523 if (szFeature && !feat)
1526 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
1535 /***********************************************************************
1536 * MsiUseFeatureW [MSI.@]
1538 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
1540 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
1543 /***********************************************************************
1544 * MsiUseFeatureA [MSI.@]
1546 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
1548 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
1551 /***********************************************************************
1552 * MSI_ProvideQualifiedComponentEx [internal]
1554 UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
1555 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1556 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
1559 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
1560 feature[MAX_FEATURE_CHARS+1];
1566 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1567 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1568 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1570 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1571 if (rc != ERROR_SUCCESS)
1572 return ERROR_INDEX_ABSENT;
1574 info = msi_reg_get_val_str( hkey, szQualifier );
1578 return ERROR_INDEX_ABSENT;
1580 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
1583 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
1585 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
1588 if (rc != INSTALLSTATE_LOCAL)
1589 return ERROR_FILE_NOT_FOUND;
1591 return ERROR_SUCCESS;
1594 /***********************************************************************
1595 * MsiProvideQualifiedComponentExW [MSI.@]
1597 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1598 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1599 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1604 path.unicode = TRUE;
1605 path.str.w = lpPathBuf;
1607 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
1608 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
1611 /***********************************************************************
1612 * MsiProvideQualifiedComponentExA [MSI.@]
1614 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
1615 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR szProduct,
1616 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
1619 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
1620 UINT r = ERROR_OUTOFMEMORY;
1623 TRACE("%s %s %lu %s %lu %lu %p %p\n", debugstr_a(szComponent),
1624 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
1625 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1627 szwComponent = strdupAtoW( szComponent );
1628 if (szComponent && !szwComponent)
1631 szwQualifier = strdupAtoW( szQualifier );
1632 if (szQualifier && !szwQualifier)
1635 szwProduct = strdupAtoW( szProduct );
1636 if (szProduct && !szwProduct)
1639 path.unicode = FALSE;
1640 path.str.a = lpPathBuf;
1642 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
1643 dwInstallMode, szwProduct, Unused1,
1644 Unused2, &path, pcchPathBuf);
1646 msi_free(szwProduct);
1647 msi_free(szwComponent);
1648 msi_free(szwQualifier);
1653 /***********************************************************************
1654 * MsiProvideQualifiedComponentW [MSI.@]
1656 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1657 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1660 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1661 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1664 /***********************************************************************
1665 * MsiProvideQualifiedComponentA [MSI.@]
1667 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1668 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1671 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
1672 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1675 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1676 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1677 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1681 UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
1683 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1684 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1687 rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1688 if (rc != ERROR_SUCCESS)
1689 return USERINFOSTATE_UNKNOWN;
1693 sz = *lpUserNameBuf * sizeof(WCHAR);
1694 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1695 NULL, (LPBYTE)lpUserNameBuf,
1698 if (!lpUserNameBuf && pcchUserNameBuf)
1701 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1705 if (pcchUserNameBuf)
1706 *pcchUserNameBuf = sz / sizeof(WCHAR);
1710 sz = *pcchOrgNameBuf * sizeof(WCHAR);
1711 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1712 NULL, (LPBYTE)lpOrgNameBuf, &sz);
1714 if (!lpOrgNameBuf && pcchOrgNameBuf)
1717 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1722 *pcchOrgNameBuf = sz / sizeof(WCHAR);
1724 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA &&
1725 rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA)
1728 return USERINFOSTATE_ABSENT;
1733 sz = *pcchSerialBuf * sizeof(WCHAR);
1734 RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL, NULL,
1735 (LPBYTE)lpSerialBuf, &sz);
1737 if (!lpSerialBuf && pcchSerialBuf)
1740 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL,
1744 *pcchSerialBuf = sz / sizeof(WCHAR);
1747 return USERINFOSTATE_PRESENT;
1750 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1751 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1752 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1754 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1755 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1758 return USERINFOSTATE_UNKNOWN;
1761 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1765 MSIPACKAGE *package;
1766 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1768 TRACE("(%s)\n",debugstr_w(szProduct));
1770 rc = MsiOpenProductW(szProduct,&handle);
1771 if (rc != ERROR_SUCCESS)
1772 return ERROR_INVALID_PARAMETER;
1774 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1775 rc = ACTION_PerformUIAction(package, szFirstRun);
1776 msiobj_release( &package->hdr );
1778 MsiCloseHandle(handle);
1783 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1787 MSIPACKAGE *package;
1788 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1790 TRACE("(%s)\n",debugstr_a(szProduct));
1792 rc = MsiOpenProductA(szProduct,&handle);
1793 if (rc != ERROR_SUCCESS)
1794 return ERROR_INVALID_PARAMETER;
1796 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1797 rc = ACTION_PerformUIAction(package, szFirstRun);
1798 msiobj_release( &package->hdr );
1800 MsiCloseHandle(handle);
1805 /***********************************************************************
1806 * MsiConfigureFeatureA [MSI.@]
1808 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
1810 LPWSTR prod, feat = NULL;
1811 UINT r = ERROR_OUTOFMEMORY;
1813 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
1815 prod = strdupAtoW( szProduct );
1816 if (szProduct && !prod)
1819 feat = strdupAtoW( szFeature );
1820 if (szFeature && !feat)
1823 r = MsiConfigureFeatureW(prod, feat, eInstallState);
1832 /***********************************************************************
1833 * MsiConfigureFeatureW [MSI.@]
1835 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
1837 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
1838 MSIPACKAGE *package = NULL;
1840 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
1843 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
1845 if (!szProduct || !szFeature)
1846 return ERROR_INVALID_PARAMETER;
1848 r = MSI_OpenProductW( szProduct, &package );
1849 if (r != ERROR_SUCCESS)
1852 sz = sizeof(sourcepath);
1853 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1854 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
1856 sz = sizeof(filename);
1857 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1858 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1860 lstrcatW( sourcepath, filename );
1862 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
1864 /* FIXME: how do we figure out the default location? */
1865 if (eInstallState == INSTALLSTATE_DEFAULT)
1866 eInstallState = INSTALLSTATE_LOCAL;
1868 r = ACTION_PerformUIAction( package, szCostInit );
1869 if (r != ERROR_SUCCESS)
1872 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
1873 if (r != ERROR_SUCCESS)
1876 r = MSI_InstallPackage( package, sourcepath, NULL );
1879 msiobj_release( &package->hdr );
1884 /***********************************************************************
1885 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
1887 * Notes: undocumented
1889 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1891 WCHAR path[MAX_PATH];
1893 TRACE("%ld\n", dwReserved);
1897 FIXME("dwReserved=%ld\n", dwReserved);
1898 return ERROR_INVALID_PARAMETER;
1901 if (!GetWindowsDirectoryW(path, MAX_PATH))
1902 return ERROR_FUNCTION_FAILED;
1904 lstrcatW(path, installerW);
1906 if (!CreateDirectoryW(path, NULL))
1907 return ERROR_FUNCTION_FAILED;
1909 return ERROR_SUCCESS;
1912 /***********************************************************************
1913 * MsiGetShortcutTargetA [MSI.@]
1915 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1916 LPSTR szProductCode, LPSTR szFeatureId,
1917 LPSTR szComponentCode )
1920 const int len = MAX_FEATURE_CHARS+1;
1921 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
1924 target = strdupAtoW( szShortcutTarget );
1925 if (szShortcutTarget && !target )
1926 return ERROR_OUTOFMEMORY;
1930 r = MsiGetShortcutTargetW( target, product, feature, component );
1932 if (r == ERROR_SUCCESS)
1934 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
1935 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
1936 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
1941 /***********************************************************************
1942 * MsiGetShortcutTargetW [MSI.@]
1944 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1945 LPWSTR szProductCode, LPWSTR szFeatureId,
1946 LPWSTR szComponentCode )
1948 IShellLinkDataList *dl = NULL;
1949 IPersistFile *pf = NULL;
1950 LPEXP_DARWIN_LINK darwin = NULL;
1953 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
1954 szProductCode, szFeatureId, szComponentCode );
1956 init = CoInitialize(NULL);
1958 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
1959 &IID_IPersistFile, (LPVOID*) &pf );
1960 if( SUCCEEDED( r ) )
1962 r = IPersistFile_Load( pf, szShortcutTarget,
1963 STGM_READ | STGM_SHARE_DENY_WRITE );
1964 if( SUCCEEDED( r ) )
1966 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
1968 if( SUCCEEDED( r ) )
1970 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
1972 IShellLinkDataList_Release( dl );
1975 IPersistFile_Release( pf );
1978 if (SUCCEEDED(init))
1981 TRACE("darwin = %p\n", darwin);
1988 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
1989 szProductCode, szFeatureId, szComponentCode, &sz );
1990 LocalFree( darwin );
1994 return ERROR_FUNCTION_FAILED;
1997 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1998 DWORD dwReinstallMode )
2000 MSIPACKAGE* package = NULL;
2002 WCHAR sourcepath[MAX_PATH];
2003 WCHAR filename[MAX_PATH];
2004 static const WCHAR szLogVerbose[] = {
2005 ' ','L','O','G','V','E','R','B','O','S','E',0 };
2006 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
2007 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
2008 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
2009 static const WCHAR szOne[] = {'1',0};
2010 WCHAR reinstallmode[11];
2014 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
2017 ptr = reinstallmode;
2019 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
2021 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
2023 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
2025 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
2027 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
2029 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
2031 if (dwReinstallMode & REINSTALLMODE_USERDATA)
2033 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
2035 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
2037 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2041 sz = sizeof(sourcepath);
2042 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
2043 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2045 sz = sizeof(filename);
2046 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
2047 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2049 lstrcatW( sourcepath, filename );
2051 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2052 r = MSI_OpenPackageW( sourcepath, &package );
2054 r = MSI_OpenProductW( szProduct, &package );
2056 if (r != ERROR_SUCCESS)
2059 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
2060 MSI_SetPropertyW( package, szInstalled, szOne );
2061 MSI_SetPropertyW( package, szLogVerbose, szOne );
2062 MSI_SetPropertyW( package, szReinstall, szFeature );
2064 r = MSI_InstallPackage( package, sourcepath, NULL );
2066 msiobj_release( &package->hdr );
2071 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
2072 DWORD dwReinstallMode )
2078 TRACE("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
2081 wszProduct = strdupAtoW(szProduct);
2082 wszFeature = strdupAtoW(szFeature);
2084 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
2086 msi_free(wszProduct);
2087 msi_free(wszFeature);
2091 /***********************************************************************
2092 * MsiGetFileHashW [MSI.@]
2094 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2095 PMSIFILEHASHINFO pHash )
2097 FIXME("%s %08lx %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2098 return ERROR_CALL_NOT_IMPLEMENTED;
2101 /***********************************************************************
2102 * MsiGetFileHashA [MSI.@]
2104 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2105 PMSIFILEHASHINFO pHash )
2107 FIXME("%s %08lx %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2108 return ERROR_CALL_NOT_IMPLEMENTED;
2111 /***********************************************************************
2112 * MsiAdvertiseScriptW [MSI.@]
2114 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2115 PHKEY phRegData, BOOL fRemoveItems )
2117 FIXME("%s %08lx %p %d\n",
2118 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2119 return ERROR_CALL_NOT_IMPLEMENTED;
2122 /***********************************************************************
2123 * MsiAdvertiseScriptA [MSI.@]
2125 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2126 PHKEY phRegData, BOOL fRemoveItems )
2128 FIXME("%s %08lx %p %d\n",
2129 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2130 return ERROR_CALL_NOT_IMPLEMENTED;