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);
46 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
48 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
51 LPWSTR szwProd = NULL;
53 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
57 szwProd = strdupAtoW( szProduct );
59 return ERROR_OUTOFMEMORY;
62 r = MsiOpenProductW( szwProd, phProduct );
69 static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
73 HKEY hKeyProduct = NULL;
76 TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
78 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
79 if( r != ERROR_SUCCESS )
81 r = ERROR_UNKNOWN_PRODUCT;
85 /* find the size of the path */
87 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
88 NULL, &type, NULL, &count );
89 if( r != ERROR_SUCCESS )
91 r = ERROR_UNKNOWN_PRODUCT;
95 /* now alloc and fetch the path of the database to open */
96 path = msi_alloc( count );
100 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
101 NULL, &type, (LPBYTE) path, &count );
102 if( r != ERROR_SUCCESS )
104 r = ERROR_UNKNOWN_PRODUCT;
108 r = MSI_OpenPackageW( path, ppackage );
113 RegCloseKey( hKeyProduct );
118 UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
120 MSIPACKAGE *package = NULL;
123 r = MSI_OpenProductW( szProduct, &package );
124 if( r == ERROR_SUCCESS )
126 *phProduct = alloc_msihandle( &package->hdr );
128 r = ERROR_NOT_ENOUGH_MEMORY;
129 msiobj_release( &package->hdr );
134 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
135 LPCSTR szTransforms, LANGID lgidLanguage)
137 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
138 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
139 return ERROR_CALL_NOT_IMPLEMENTED;
142 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
143 LPCWSTR szTransforms, LANGID lgidLanguage)
145 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
146 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
147 return ERROR_CALL_NOT_IMPLEMENTED;
150 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
151 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
153 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
154 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
155 lgidLanguage, dwPlatform, dwOptions);
156 return ERROR_CALL_NOT_IMPLEMENTED;
159 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
160 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
162 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
163 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
164 lgidLanguage, dwPlatform, dwOptions);
165 return ERROR_CALL_NOT_IMPLEMENTED;
168 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
170 LPWSTR szwPath = NULL, szwCommand = NULL;
171 UINT r = ERROR_OUTOFMEMORY;
173 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
177 szwPath = strdupAtoW( szPackagePath );
184 szwCommand = strdupAtoW( szCommandLine );
189 r = MsiInstallProductW( szwPath, szwCommand );
193 msi_free( szwCommand );
198 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
200 MSIPACKAGE *package = NULL;
203 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
205 r = MSI_OpenPackageW( szPackagePath, &package );
206 if (r == ERROR_SUCCESS)
208 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
209 msiobj_release( &package->hdr );
215 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
217 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
218 return ERROR_CALL_NOT_IMPLEMENTED;
221 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
223 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
224 return ERROR_CALL_NOT_IMPLEMENTED;
227 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
228 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
230 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
231 eInstallType, debugstr_a(szCommandLine));
232 return ERROR_CALL_NOT_IMPLEMENTED;
235 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
236 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
238 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
239 eInstallType, debugstr_w(szCommandLine));
240 return ERROR_CALL_NOT_IMPLEMENTED;
243 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
244 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
246 MSIPACKAGE* package = NULL;
249 WCHAR sourcepath[MAX_PATH];
250 WCHAR filename[MAX_PATH];
251 static const WCHAR szInstalled[] = {
252 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
255 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
256 debugstr_w(szCommandLine));
258 if (eInstallState != INSTALLSTATE_LOCAL &&
259 eInstallState != INSTALLSTATE_DEFAULT)
261 FIXME("Not implemented for anything other than local installs\n");
262 return ERROR_CALL_NOT_IMPLEMENTED;
265 sz = sizeof(sourcepath);
266 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
267 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
270 sz = sizeof(filename);
271 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
272 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
274 lstrcatW(sourcepath,filename);
277 * ok 1, we need to find the msi file for this product.
278 * 2, find the source dir for the files
279 * 3, do the configure/install.
280 * 4, cleanupany runonce entry.
283 r = MSI_OpenProductW( szProduct, &package );
284 if (r != ERROR_SUCCESS)
287 sz = lstrlenW(szInstalled) + 1;
290 sz += lstrlenW(szCommandLine);
292 commandline = msi_alloc(sz * sizeof(WCHAR));
295 r = ERROR_OUTOFMEMORY;
301 lstrcpyW(commandline,szCommandLine);
303 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
304 lstrcatW(commandline,szInstalled);
306 r = MSI_InstallPackage( package, sourcepath, commandline );
308 msi_free(commandline);
311 msiobj_release( &package->hdr );
316 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
317 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
319 LPWSTR szwProduct = NULL;
320 LPWSTR szwCommandLine = NULL;
321 UINT r = ERROR_OUTOFMEMORY;
325 szwProduct = strdupAtoW( szProduct );
332 szwCommandLine = strdupAtoW( szCommandLine );
337 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
340 msi_free( szwProduct );
341 msi_free( szwCommandLine);
346 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
347 INSTALLSTATE eInstallState)
349 LPWSTR szwProduct = NULL;
352 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
356 szwProduct = strdupAtoW( szProduct );
358 return ERROR_OUTOFMEMORY;
361 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
362 msi_free( szwProduct );
367 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
368 INSTALLSTATE eInstallState)
370 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
373 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
375 LPWSTR szwComponent = NULL;
377 WCHAR szwBuffer[GUID_SIZE];
379 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
383 szwComponent = strdupAtoW( szComponent );
385 return ERROR_OUTOFMEMORY;
388 r = MsiGetProductCodeW( szwComponent, szwBuffer );
390 if( ERROR_SUCCESS == r )
391 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
393 msi_free( szwComponent );
398 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
402 WCHAR szSquished[GUID_SIZE];
403 DWORD sz = GUID_SIZE;
404 static const WCHAR szPermKey[] =
405 { '0','0','0','0','0','0','0','0','0','0','0','0',
406 '0','0','0','0','0','0','0','0','0','0','0','0',
407 '0','0','0','0','0','0','0','0',0};
409 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
411 if (NULL == szComponent)
412 return ERROR_INVALID_PARAMETER;
414 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
415 if (rc != ERROR_SUCCESS)
416 return ERROR_UNKNOWN_COMPONENT;
418 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
419 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
422 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
427 if (rc != ERROR_SUCCESS)
428 return ERROR_INSTALL_FAILURE;
430 unsquash_guid(szSquished, szBuffer);
431 return ERROR_SUCCESS;
434 UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
435 awstring *szValue, DWORD *pcchValueBuf)
441 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
442 debugstr_w(szAttribute), szValue, pcchValueBuf);
445 * FIXME: Values seem scattered/duplicated in the registry. Is there a system?
448 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
449 return ERROR_INVALID_PARAMETER;
451 /* check for special properties */
452 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
455 WCHAR packagecode[35];
457 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
458 if (r != ERROR_SUCCESS)
459 return ERROR_UNKNOWN_PRODUCT;
461 regval = msi_reg_get_val_str( hkey, szAttribute );
464 if (unsquash_guid(regval, packagecode))
465 val = strdupW(packagecode);
471 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
473 static const WCHAR one[] = { '1',0 };
475 * FIXME: should be in the Product key (user or system?)
476 * but isn't written yet...
478 val = strdupW( one );
480 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
481 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
483 static const WCHAR fmt[] = { '%','u',0 };
487 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
488 if (r != ERROR_SUCCESS)
489 return ERROR_UNKNOWN_PRODUCT;
491 if (msi_reg_get_val_dword( hkey, szAttribute, ®val))
493 sprintfW(szVal, fmt, regval);
494 val = strdupW( szVal );
499 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
501 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
502 if (r != ERROR_SUCCESS)
503 return ERROR_UNKNOWN_PRODUCT;
505 val = msi_reg_get_val_str( hkey, szAttribute );
511 static const WCHAR szDisplayVersion[] = {
512 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
514 FIXME("%s\n", debugstr_w(szAttribute));
515 /* FIXME: some attribute values not tested... */
517 if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
518 szAttribute = szDisplayVersion;
520 r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
521 if (r != ERROR_SUCCESS)
522 return ERROR_UNKNOWN_PRODUCT;
524 val = msi_reg_get_val_str( hkey, szAttribute );
529 TRACE("returning %s\n", debugstr_w(val));
532 return ERROR_UNKNOWN_PROPERTY;
534 r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
541 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
542 LPSTR szBuffer, DWORD *pcchValueBuf)
544 LPWSTR szwProduct, szwAttribute = NULL;
545 UINT r = ERROR_OUTOFMEMORY;
548 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
549 szBuffer, pcchValueBuf);
551 szwProduct = strdupAtoW( szProduct );
552 if( szProduct && !szwProduct )
555 szwAttribute = strdupAtoW( szAttribute );
556 if( szAttribute && !szwAttribute )
559 buffer.unicode = FALSE;
560 buffer.str.a = szBuffer;
562 r = MSI_GetProductInfo( szwProduct, szwAttribute,
563 &buffer, pcchValueBuf );
566 msi_free( szwProduct );
567 msi_free( szwAttribute );
572 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
573 LPWSTR szBuffer, DWORD *pcchValueBuf)
577 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
578 szBuffer, pcchValueBuf);
580 buffer.unicode = TRUE;
581 buffer.str.w = szBuffer;
583 return MSI_GetProductInfo( szProduct, szAttribute,
584 &buffer, pcchValueBuf );
587 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
589 LPWSTR szwLogFile = NULL;
592 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
596 szwLogFile = strdupAtoW( szLogFile );
598 return ERROR_OUTOFMEMORY;
600 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
601 msi_free( szwLogFile );
605 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
607 HANDLE file = INVALID_HANDLE_VALUE;
609 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
613 lstrcpyW(gszLogFile,szLogFile);
614 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
615 DeleteFileW(szLogFile);
616 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
617 FILE_ATTRIBUTE_NORMAL, NULL);
618 if (file != INVALID_HANDLE_VALUE)
621 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
624 gszLogFile[0] = '\0';
626 return ERROR_SUCCESS;
629 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
631 LPWSTR szwProduct = NULL;
636 szwProduct = strdupAtoW( szProduct );
638 return ERROR_OUTOFMEMORY;
640 r = MsiQueryProductStateW( szwProduct );
641 msi_free( szwProduct );
645 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
648 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
650 static const WCHAR szWindowsInstaller[] = {
651 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
654 TRACE("%s\n", debugstr_w(szProduct));
657 return INSTALLSTATE_INVALIDARG;
659 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
660 if (rc != ERROR_SUCCESS)
665 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
666 if (rc != ERROR_SUCCESS)
670 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
671 if (rc != ERROR_SUCCESS)
678 rrc = INSTALLSTATE_DEFAULT;
681 FIXME("Unknown install state read from registry (%i)\n",rrc);
682 rrc = INSTALLSTATE_UNKNOWN;
690 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
692 INSTALLUILEVEL old = gUILevel;
693 HWND oldwnd = gUIhwnd;
695 TRACE("%08x %p\n", dwUILevel, phWnd);
697 gUILevel = dwUILevel;
706 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
707 DWORD dwMessageFilter, LPVOID pvContext)
709 INSTALLUI_HANDLERA prev = gUIHandlerA;
711 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
712 gUIHandlerA = puiHandler;
713 gUIFilter = dwMessageFilter;
714 gUIContext = pvContext;
719 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
720 DWORD dwMessageFilter, LPVOID pvContext)
722 INSTALLUI_HANDLERW prev = gUIHandlerW;
724 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
725 gUIHandlerW = puiHandler;
726 gUIFilter = dwMessageFilter;
727 gUIContext = pvContext;
732 /******************************************************************
733 * MsiLoadStringW [MSI.@]
735 * Loads a string from MSI's string resources.
739 * handle [I] only -1 is handled currently
740 * id [I] id of the string to be loaded
741 * lpBuffer [O] buffer for the string to be written to
742 * nBufferMax [I] maximum size of the buffer in characters
743 * lang [I] the preferred language for the string
747 * If successful, this function returns the language id of the string loaded
748 * If the function fails, the function returns zero.
752 * The type of the first parameter is unknown. LoadString's prototype
753 * suggests that it might be a module handle. I have made it an MSI handle
754 * for starters, as -1 is an invalid MSI handle, but not an invalid module
755 * handle. Maybe strings can be stored in an MSI database somehow.
757 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
758 int nBufferMax, LANGID lang )
765 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
768 FIXME("don't know how to deal with handle = %08lx\n", handle);
771 lang = GetUserDefaultLangID();
773 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
777 hResData = LoadResource( msi_hInstance, hres );
780 p = LockResource( hResData );
784 for (i = 0; i < (id&0xf); i++)
788 if( nBufferMax <= len )
791 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
794 TRACE("found -> %s\n", debugstr_w(lpBuffer));
799 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
800 int nBufferMax, LANGID lang )
806 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
807 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
810 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
811 if( len <= nBufferMax )
812 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
813 lpBuffer, nBufferMax, NULL, NULL );
821 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
824 char szProduct[GUID_SIZE];
826 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
828 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
829 return INSTALLSTATE_UNKNOWN;
831 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
834 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
837 WCHAR szProduct[GUID_SIZE];
839 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
841 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
842 return INSTALLSTATE_UNKNOWN;
844 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
847 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
848 WORD wLanguageId, DWORD f)
850 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
851 uType,wLanguageId,f);
852 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
855 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
856 WORD wLanguageId, DWORD f)
858 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
859 uType,wLanguageId,f);
860 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
863 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
864 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
867 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
868 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
870 return ERROR_CALL_NOT_IMPLEMENTED;
873 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
874 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
877 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
878 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
880 return ERROR_CALL_NOT_IMPLEMENTED;
883 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
884 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
886 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
887 return ERROR_CALL_NOT_IMPLEMENTED;
890 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
891 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
893 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
894 return ERROR_CALL_NOT_IMPLEMENTED;
897 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
898 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
901 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
902 ppcCertContext, pbHashData, pcbHashData);
903 return ERROR_CALL_NOT_IMPLEMENTED;
906 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
907 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
910 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
911 ppcCertContext, pbHashData, pcbHashData);
912 return ERROR_CALL_NOT_IMPLEMENTED;
915 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
916 LPSTR szValue, DWORD *pccbValue )
918 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
919 return ERROR_CALL_NOT_IMPLEMENTED;
922 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
923 LPWSTR szValue, DWORD *pccbValue )
925 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
926 return ERROR_CALL_NOT_IMPLEMENTED;
929 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
932 LPWSTR szPack = NULL;
934 TRACE("%s\n", debugstr_a(szPackage) );
938 szPack = strdupAtoW( szPackage );
940 return ERROR_OUTOFMEMORY;
943 r = MsiVerifyPackageW( szPack );
950 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
955 TRACE("%s\n", debugstr_w(szPackage) );
957 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
958 MsiCloseHandle( handle );
963 INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
964 awstring* lpPathBuf, DWORD* pcchBuf)
966 WCHAR squished_pc[GUID_SIZE], squished_comp[GUID_SIZE];
972 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
973 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
975 if( !szProduct || !szComponent )
976 return INSTALLSTATE_INVALIDARG;
977 if( lpPathBuf->str.w && !pcchBuf )
978 return INSTALLSTATE_INVALIDARG;
980 if (!squash_guid( szProduct, squished_pc ) ||
981 !squash_guid( szComponent, squished_comp ))
982 return INSTALLSTATE_INVALIDARG;
984 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
985 if( rc != ERROR_SUCCESS )
986 return INSTALLSTATE_UNKNOWN;
990 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
991 if( rc != ERROR_SUCCESS )
992 return INSTALLSTATE_UNKNOWN;
994 path = msi_reg_get_val_str( hkey, squished_pc );
997 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
998 debugstr_w(szProduct), debugstr_w(path));
1001 return INSTALLSTATE_UNKNOWN;
1004 r = INSTALLSTATE_LOCAL;
1006 r = INSTALLSTATE_NOTUSED;
1008 msi_strcpy_to_awstring( path, lpPathBuf, pcchBuf );
1014 /******************************************************************
1015 * MsiGetComponentPathW [MSI.@]
1017 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1018 LPWSTR lpPathBuf, DWORD* pcchBuf)
1022 path.unicode = TRUE;
1023 path.str.w = lpPathBuf;
1025 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1028 /******************************************************************
1029 * MsiGetComponentPathA [MSI.@]
1031 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1032 LPSTR lpPathBuf, DWORD* pcchBuf)
1034 LPWSTR szwProduct, szwComponent = NULL;
1035 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1038 szwProduct = strdupAtoW( szProduct );
1039 if( szProduct && !szwProduct)
1042 szwComponent = strdupAtoW( szComponent );
1043 if( szComponent && !szwComponent )
1046 path.unicode = FALSE;
1047 path.str.a = lpPathBuf;
1049 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1052 msi_free( szwProduct );
1053 msi_free( szwComponent );
1058 /******************************************************************
1059 * MsiQueryFeatureStateA [MSI.@]
1061 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1063 LPWSTR szwProduct = NULL, szwFeature= NULL;
1064 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1066 szwProduct = strdupAtoW( szProduct );
1067 if ( szProduct && !szwProduct )
1070 szwFeature = strdupAtoW( szFeature );
1071 if ( szFeature && !szwFeature )
1074 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1077 msi_free( szwProduct);
1078 msi_free( szwFeature);
1083 /******************************************************************
1084 * MsiQueryFeatureStateW [MSI.@]
1086 * Checks the state of a feature
1089 * szProduct [I] Product's GUID string
1090 * szFeature [I] Feature's GUID string
1093 * INSTALLSTATE_LOCAL Feature is installed and useable
1094 * INSTALLSTATE_ABSENT Feature is absent
1095 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1096 * INSTALLSTATE_UNKNOWN An error occurred
1097 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1100 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1102 WCHAR squishProduct[33], comp[GUID_SIZE];
1104 LPWSTR components, p, parent_feature;
1108 BOOL missing = FALSE;
1110 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1112 if (!szProduct || !szFeature)
1113 return INSTALLSTATE_INVALIDARG;
1115 if (!squash_guid( szProduct, squishProduct ))
1116 return INSTALLSTATE_INVALIDARG;
1118 /* check that it's installed at all */
1119 rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
1120 if (rc != ERROR_SUCCESS)
1121 return INSTALLSTATE_UNKNOWN;
1123 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1126 if (!parent_feature)
1127 return INSTALLSTATE_UNKNOWN;
1129 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1130 msi_free(parent_feature);
1131 if (r == INSTALLSTATE_ABSENT)
1134 /* now check if it's complete or advertised */
1135 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1136 if (rc != ERROR_SUCCESS)
1137 return INSTALLSTATE_UNKNOWN;
1139 components = msi_reg_get_val_str( hkey, szFeature );
1142 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1146 ERR("components missing %s %s\n",
1147 debugstr_w(szProduct), debugstr_w(szFeature));
1148 return INSTALLSTATE_UNKNOWN;
1151 for( p = components; *p != 2 ; p += 20)
1153 if (!decode_base85_guid( p, &guid ))
1155 ERR("%s\n", debugstr_w(p));
1158 StringFromGUID2(&guid, comp, GUID_SIZE);
1159 r = MsiGetComponentPathW(szProduct, comp, NULL, 0);
1160 TRACE("component %s state %d\n", debugstr_guid(&guid), r);
1163 case INSTALLSTATE_NOTUSED:
1164 case INSTALLSTATE_LOCAL:
1165 case INSTALLSTATE_SOURCE:
1172 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1173 msi_free(components);
1176 return INSTALLSTATE_ADVERTISED;
1178 return INSTALLSTATE_LOCAL;
1181 /******************************************************************
1182 * MsiGetFileVersionA [MSI.@]
1184 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1185 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1187 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1188 UINT ret = ERROR_OUTOFMEMORY;
1192 szwFilePath = strdupAtoW( szFilePath );
1197 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1199 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1200 if( !lpwVersionBuff )
1204 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1206 lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1211 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1212 lpwLangBuff, pcchLangBuf);
1214 if( lpwVersionBuff )
1215 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1216 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1218 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1219 lpLangBuf, *pcchLangBuf, NULL, NULL);
1222 msi_free(szwFilePath);
1223 msi_free(lpwVersionBuff);
1224 msi_free(lpwLangBuff);
1229 /******************************************************************
1230 * MsiGetFileVersionW [MSI.@]
1232 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1233 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1235 static WCHAR szVersionResource[] = {'\\',0};
1236 static const WCHAR szVersionFormat[] = {
1237 '%','d','.','%','d','.','%','d','.','%','d',0};
1238 static const WCHAR szLangFormat[] = {'%','d',0};
1241 LPVOID lpVer = NULL;
1242 VS_FIXEDFILEINFO *ffi;
1246 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1247 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1248 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1250 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1252 return GetLastError();
1254 lpVer = msi_alloc(dwVerLen);
1257 ret = ERROR_OUTOFMEMORY;
1261 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1263 ret = GetLastError();
1266 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1268 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1271 wsprintfW(tmp, szVersionFormat,
1272 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1273 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1274 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1275 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1280 *pcchVersionBuf = 0;
1284 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1286 DWORD lang = GetUserDefaultLangID();
1288 FIXME("Retrieve language from file\n");
1289 wsprintfW(tmp, szLangFormat, lang);
1290 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1291 *pcchLangBuf = lstrlenW(lpLangBuf);
1299 /***********************************************************************
1300 * MsiGetFeatureUsageW [MSI.@]
1302 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
1303 DWORD* pdwUseCount, WORD* pwDateUsed )
1305 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1306 pdwUseCount, pwDateUsed);
1307 return ERROR_CALL_NOT_IMPLEMENTED;
1310 /***********************************************************************
1311 * MsiGetFeatureUsageA [MSI.@]
1313 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
1314 DWORD* pdwUseCount, WORD* pwDateUsed )
1316 LPWSTR prod = NULL, feat = NULL;
1317 UINT ret = ERROR_OUTOFMEMORY;
1319 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1320 pdwUseCount, pwDateUsed);
1322 prod = strdupAtoW( szProduct );
1323 if (szProduct && !prod)
1326 feat = strdupAtoW( szFeature );
1327 if (szFeature && !feat)
1330 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
1339 /***********************************************************************
1340 * MsiUseFeatureExW [MSI.@]
1342 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
1343 DWORD dwInstallMode, DWORD dwReserved )
1347 TRACE("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1348 dwInstallMode, dwReserved);
1350 state = MsiQueryFeatureStateW( szProduct, szFeature );
1353 return INSTALLSTATE_INVALIDARG;
1355 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
1357 FIXME("mark product %s feature %s as used\n",
1358 debugstr_w(szProduct), debugstr_w(szFeature) );
1364 /***********************************************************************
1365 * MsiUseFeatureExA [MSI.@]
1367 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
1368 DWORD dwInstallMode, DWORD dwReserved )
1370 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
1371 LPWSTR prod = NULL, feat = NULL;
1373 TRACE("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1374 dwInstallMode, dwReserved);
1376 prod = strdupAtoW( szProduct );
1377 if (szProduct && !prod)
1380 feat = strdupAtoW( szFeature );
1381 if (szFeature && !feat)
1384 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
1393 /***********************************************************************
1394 * MsiUseFeatureW [MSI.@]
1396 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
1398 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
1401 /***********************************************************************
1402 * MsiUseFeatureA [MSI.@]
1404 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
1406 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
1409 /***********************************************************************
1410 * MSI_ProvideQualifiedComponentEx [internal]
1412 UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
1413 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1414 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
1417 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
1418 feature[MAX_FEATURE_CHARS+1];
1424 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1425 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1426 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1428 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1429 if (rc != ERROR_SUCCESS)
1430 return ERROR_INDEX_ABSENT;
1432 info = msi_reg_get_val_str( hkey, szQualifier );
1436 return ERROR_INDEX_ABSENT;
1438 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
1441 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
1443 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
1447 if (rc != INSTALLSTATE_LOCAL)
1448 return ERROR_FILE_NOT_FOUND;
1450 return ERROR_SUCCESS;
1453 /***********************************************************************
1454 * MsiProvideQualifiedComponentExW [MSI.@]
1456 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1457 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1458 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1463 path.unicode = TRUE;
1464 path.str.w = lpPathBuf;
1466 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
1467 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
1470 /***********************************************************************
1471 * MsiProvideQualifiedComponentExA [MSI.@]
1473 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
1474 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR szProduct,
1475 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
1478 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
1479 UINT r = ERROR_OUTOFMEMORY;
1482 TRACE("%s %s %lu %s %lu %lu %p %p\n", debugstr_a(szComponent),
1483 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
1484 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1486 szwComponent = strdupAtoW( szComponent );
1487 if (szComponent && !szwComponent)
1490 szwQualifier = strdupAtoW( szQualifier );
1491 if (szQualifier && !szwQualifier)
1494 szwProduct = strdupAtoW( szProduct );
1495 if (szProduct && !szwProduct)
1498 path.unicode = FALSE;
1499 path.str.a = lpPathBuf;
1501 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
1502 dwInstallMode, szwProduct, Unused1,
1503 Unused2, &path, pcchPathBuf);
1505 msi_free(szwProduct);
1506 msi_free(szwComponent);
1507 msi_free(szwQualifier);
1512 /***********************************************************************
1513 * MsiProvideQualifiedComponentW [MSI.@]
1515 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1516 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1519 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1520 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1523 /***********************************************************************
1524 * MsiProvideQualifiedComponentA [MSI.@]
1526 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1527 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1530 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
1531 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1534 /***********************************************************************
1535 * MSI_GetUserInfo [internal]
1537 USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
1538 awstring *lpUserNameBuf, DWORD* pcchUserNameBuf,
1539 awstring *lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1540 awstring *lpSerialBuf, DWORD* pcchSerialBuf)
1543 LPWSTR user, org, serial;
1545 USERINFOSTATE state;
1547 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1548 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1552 return USERINFOSTATE_INVALIDARG;
1554 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1555 if (r != ERROR_SUCCESS)
1556 return USERINFOSTATE_UNKNOWN;
1558 user = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGOWNERW );
1559 org = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGCOMPANYW );
1560 serial = msi_reg_get_val_str( hkey, INSTALLPROPERTY_PRODUCTIDW );
1564 state = USERINFOSTATE_PRESENT;
1566 r = msi_strcpy_to_awstring( user, lpUserNameBuf, pcchUserNameBuf );
1567 if (r == ERROR_MORE_DATA)
1568 state = USERINFOSTATE_MOREDATA;
1569 r = msi_strcpy_to_awstring( org, lpOrgNameBuf, pcchOrgNameBuf );
1570 if (r == ERROR_MORE_DATA)
1571 state = USERINFOSTATE_MOREDATA;
1572 r = msi_strcpy_to_awstring( serial, lpSerialBuf, pcchSerialBuf );
1573 if (r == ERROR_MORE_DATA)
1574 state = USERINFOSTATE_MOREDATA;
1583 /***********************************************************************
1584 * MsiGetUserInfoW [MSI.@]
1586 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
1587 LPWSTR lpUserNameBuf, DWORD* pcchUserNameBuf,
1588 LPWSTR lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1589 LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1591 awstring user, org, serial;
1593 user.unicode = TRUE;
1594 user.str.w = lpUserNameBuf;
1596 org.str.w = lpOrgNameBuf;
1597 serial.unicode = TRUE;
1598 serial.str.w = lpSerialBuf;
1600 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
1601 &org, pcchOrgNameBuf,
1602 &serial, pcchSerialBuf );
1605 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
1606 LPSTR lpUserNameBuf, DWORD* pcchUserNameBuf,
1607 LPSTR lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1608 LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1610 awstring user, org, serial;
1614 prod = strdupAtoW( szProduct );
1615 if (szProduct && !prod)
1616 return ERROR_OUTOFMEMORY;
1618 user.unicode = FALSE;
1619 user.str.a = lpUserNameBuf;
1620 org.unicode = FALSE;
1621 org.str.a = lpOrgNameBuf;
1622 serial.unicode = FALSE;
1623 serial.str.a = lpSerialBuf;
1625 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
1626 &org, pcchOrgNameBuf,
1627 &serial, pcchSerialBuf );
1634 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1638 MSIPACKAGE *package;
1639 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1641 TRACE("(%s)\n",debugstr_w(szProduct));
1643 rc = MsiOpenProductW(szProduct,&handle);
1644 if (rc != ERROR_SUCCESS)
1645 return ERROR_INVALID_PARAMETER;
1647 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1648 rc = ACTION_PerformUIAction(package, szFirstRun);
1649 msiobj_release( &package->hdr );
1651 MsiCloseHandle(handle);
1656 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1660 MSIPACKAGE *package;
1661 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1663 TRACE("(%s)\n",debugstr_a(szProduct));
1665 rc = MsiOpenProductA(szProduct,&handle);
1666 if (rc != ERROR_SUCCESS)
1667 return ERROR_INVALID_PARAMETER;
1669 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1670 rc = ACTION_PerformUIAction(package, szFirstRun);
1671 msiobj_release( &package->hdr );
1673 MsiCloseHandle(handle);
1678 /***********************************************************************
1679 * MsiConfigureFeatureA [MSI.@]
1681 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
1683 LPWSTR prod, feat = NULL;
1684 UINT r = ERROR_OUTOFMEMORY;
1686 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
1688 prod = strdupAtoW( szProduct );
1689 if (szProduct && !prod)
1692 feat = strdupAtoW( szFeature );
1693 if (szFeature && !feat)
1696 r = MsiConfigureFeatureW(prod, feat, eInstallState);
1705 /***********************************************************************
1706 * MsiConfigureFeatureW [MSI.@]
1708 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
1710 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
1711 MSIPACKAGE *package = NULL;
1713 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
1716 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
1718 if (!szProduct || !szFeature)
1719 return ERROR_INVALID_PARAMETER;
1721 switch (eInstallState)
1723 case INSTALLSTATE_DEFAULT:
1724 /* FIXME: how do we figure out the default location? */
1725 eInstallState = INSTALLSTATE_LOCAL;
1727 case INSTALLSTATE_LOCAL:
1728 case INSTALLSTATE_SOURCE:
1729 case INSTALLSTATE_ABSENT:
1730 case INSTALLSTATE_ADVERTISED:
1733 return ERROR_INVALID_PARAMETER;
1736 r = MSI_OpenProductW( szProduct, &package );
1737 if (r != ERROR_SUCCESS)
1740 sz = sizeof(sourcepath);
1741 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1742 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
1744 sz = sizeof(filename);
1745 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1746 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1748 lstrcatW( sourcepath, filename );
1750 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
1752 r = ACTION_PerformUIAction( package, szCostInit );
1753 if (r != ERROR_SUCCESS)
1756 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
1757 if (r != ERROR_SUCCESS)
1760 r = MSI_InstallPackage( package, sourcepath, NULL );
1763 msiobj_release( &package->hdr );
1768 /***********************************************************************
1769 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
1771 * Notes: undocumented
1773 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1775 WCHAR path[MAX_PATH];
1777 TRACE("%ld\n", dwReserved);
1781 FIXME("dwReserved=%ld\n", dwReserved);
1782 return ERROR_INVALID_PARAMETER;
1785 if (!GetWindowsDirectoryW(path, MAX_PATH))
1786 return ERROR_FUNCTION_FAILED;
1788 lstrcatW(path, installerW);
1790 if (!CreateDirectoryW(path, NULL))
1791 return ERROR_FUNCTION_FAILED;
1793 return ERROR_SUCCESS;
1796 /***********************************************************************
1797 * MsiGetShortcutTargetA [MSI.@]
1799 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1800 LPSTR szProductCode, LPSTR szFeatureId,
1801 LPSTR szComponentCode )
1804 const int len = MAX_FEATURE_CHARS+1;
1805 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
1808 target = strdupAtoW( szShortcutTarget );
1809 if (szShortcutTarget && !target )
1810 return ERROR_OUTOFMEMORY;
1814 r = MsiGetShortcutTargetW( target, product, feature, component );
1816 if (r == ERROR_SUCCESS)
1818 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
1819 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
1820 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
1825 /***********************************************************************
1826 * MsiGetShortcutTargetW [MSI.@]
1828 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1829 LPWSTR szProductCode, LPWSTR szFeatureId,
1830 LPWSTR szComponentCode )
1832 IShellLinkDataList *dl = NULL;
1833 IPersistFile *pf = NULL;
1834 LPEXP_DARWIN_LINK darwin = NULL;
1837 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
1838 szProductCode, szFeatureId, szComponentCode );
1840 init = CoInitialize(NULL);
1842 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
1843 &IID_IPersistFile, (LPVOID*) &pf );
1844 if( SUCCEEDED( r ) )
1846 r = IPersistFile_Load( pf, szShortcutTarget,
1847 STGM_READ | STGM_SHARE_DENY_WRITE );
1848 if( SUCCEEDED( r ) )
1850 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
1852 if( SUCCEEDED( r ) )
1854 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
1856 IShellLinkDataList_Release( dl );
1859 IPersistFile_Release( pf );
1862 if (SUCCEEDED(init))
1865 TRACE("darwin = %p\n", darwin);
1872 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
1873 szProductCode, szFeatureId, szComponentCode, &sz );
1874 LocalFree( darwin );
1878 return ERROR_FUNCTION_FAILED;
1881 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1882 DWORD dwReinstallMode )
1884 MSIPACKAGE* package = NULL;
1886 WCHAR sourcepath[MAX_PATH];
1887 WCHAR filename[MAX_PATH];
1888 static const WCHAR szLogVerbose[] = {
1889 ' ','L','O','G','V','E','R','B','O','S','E',0 };
1890 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
1891 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
1892 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1893 static const WCHAR szOne[] = {'1',0};
1894 WCHAR reinstallmode[11];
1898 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1901 ptr = reinstallmode;
1903 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
1905 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
1907 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
1909 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
1911 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
1913 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
1915 if (dwReinstallMode & REINSTALLMODE_USERDATA)
1917 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
1919 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
1921 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1925 sz = sizeof(sourcepath);
1926 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1927 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
1929 sz = sizeof(filename);
1930 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1931 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1933 lstrcatW( sourcepath, filename );
1935 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1936 r = MSI_OpenPackageW( sourcepath, &package );
1938 r = MSI_OpenProductW( szProduct, &package );
1940 if (r != ERROR_SUCCESS)
1943 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
1944 MSI_SetPropertyW( package, szInstalled, szOne );
1945 MSI_SetPropertyW( package, szLogVerbose, szOne );
1946 MSI_SetPropertyW( package, szReinstall, szFeature );
1948 r = MSI_InstallPackage( package, sourcepath, NULL );
1950 msiobj_release( &package->hdr );
1955 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1956 DWORD dwReinstallMode )
1962 TRACE("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1965 wszProduct = strdupAtoW(szProduct);
1966 wszFeature = strdupAtoW(szFeature);
1968 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
1970 msi_free(wszProduct);
1971 msi_free(wszFeature);
1978 unsigned int buf[4];
1979 unsigned char in[64];
1980 unsigned char digest[16];
1983 extern VOID WINAPI MD5Init( MD5_CTX *);
1984 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
1985 extern VOID WINAPI MD5Final( MD5_CTX *);
1987 /***********************************************************************
1988 * MsiGetFileHashW [MSI.@]
1990 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
1991 PMSIFILEHASHINFO pHash )
1993 HANDLE handle, mapping;
1996 UINT r = ERROR_FUNCTION_FAILED;
1998 TRACE("%s %08lx %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2001 return ERROR_INVALID_PARAMETER;
2003 return ERROR_INVALID_PARAMETER;
2004 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2005 return ERROR_INVALID_PARAMETER;
2007 handle = CreateFileW( szFilePath, GENERIC_READ,
2008 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2009 if (handle == INVALID_HANDLE_VALUE)
2010 return ERROR_FILE_NOT_FOUND;
2012 length = GetFileSize( handle, NULL );
2014 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2017 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2023 MD5Update( &ctx, p, length );
2025 UnmapViewOfFile( p );
2027 memcpy( pHash->dwData, &ctx.digest, sizeof pHash->dwData );
2030 CloseHandle( mapping );
2032 CloseHandle( handle );
2037 /***********************************************************************
2038 * MsiGetFileHashA [MSI.@]
2040 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2041 PMSIFILEHASHINFO pHash )
2046 TRACE("%s %08lx %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2048 file = strdupAtoW( szFilePath );
2049 if (szFilePath && !file)
2050 return ERROR_OUTOFMEMORY;
2052 r = MsiGetFileHashW( file, dwOptions, pHash );
2057 /***********************************************************************
2058 * MsiAdvertiseScriptW [MSI.@]
2060 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2061 PHKEY phRegData, BOOL fRemoveItems )
2063 FIXME("%s %08lx %p %d\n",
2064 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2065 return ERROR_CALL_NOT_IMPLEMENTED;
2068 /***********************************************************************
2069 * MsiAdvertiseScriptA [MSI.@]
2071 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2072 PHKEY phRegData, BOOL fRemoveItems )
2074 FIXME("%s %08lx %p %d\n",
2075 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2076 return ERROR_CALL_NOT_IMPLEMENTED;