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"
43 WINE_DEFAULT_DEBUG_CHANNEL(msi);
45 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
47 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
50 LPWSTR szwProd = NULL;
52 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
56 szwProd = strdupAtoW( szProduct );
58 return ERROR_OUTOFMEMORY;
61 r = MsiOpenProductW( szwProd, phProduct );
68 static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
72 HKEY hKeyProduct = NULL;
75 TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
77 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
78 if( r != ERROR_SUCCESS )
80 r = ERROR_UNKNOWN_PRODUCT;
84 /* find the size of the path */
86 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
87 NULL, &type, NULL, &count );
88 if( r != ERROR_SUCCESS )
90 r = ERROR_UNKNOWN_PRODUCT;
94 /* now alloc and fetch the path of the database to open */
95 path = msi_alloc( count );
99 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
100 NULL, &type, (LPBYTE) path, &count );
101 if( r != ERROR_SUCCESS )
103 r = ERROR_UNKNOWN_PRODUCT;
107 r = MSI_OpenPackageW( path, ppackage );
112 RegCloseKey( hKeyProduct );
117 UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
119 MSIPACKAGE *package = NULL;
122 r = MSI_OpenProductW( szProduct, &package );
123 if( r == ERROR_SUCCESS )
125 *phProduct = alloc_msihandle( &package->hdr );
127 r = ERROR_NOT_ENOUGH_MEMORY;
128 msiobj_release( &package->hdr );
133 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
134 LPCSTR szTransforms, LANGID lgidLanguage)
136 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
137 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
138 return ERROR_CALL_NOT_IMPLEMENTED;
141 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
142 LPCWSTR szTransforms, LANGID lgidLanguage)
144 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
145 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
146 return ERROR_CALL_NOT_IMPLEMENTED;
149 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
150 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
152 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
153 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
154 lgidLanguage, dwPlatform, dwOptions);
155 return ERROR_CALL_NOT_IMPLEMENTED;
158 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
159 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
161 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
162 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
163 lgidLanguage, dwPlatform, dwOptions);
164 return ERROR_CALL_NOT_IMPLEMENTED;
167 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
169 LPWSTR szwPath = NULL, szwCommand = NULL;
170 UINT r = ERROR_OUTOFMEMORY;
172 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
176 szwPath = strdupAtoW( szPackagePath );
183 szwCommand = strdupAtoW( szCommandLine );
188 r = MsiInstallProductW( szwPath, szwCommand );
192 msi_free( szwCommand );
197 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
199 MSIPACKAGE *package = NULL;
202 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
204 r = MSI_OpenPackageW( szPackagePath, &package );
205 if (r == ERROR_SUCCESS)
207 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
208 msiobj_release( &package->hdr );
214 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
216 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
217 return ERROR_CALL_NOT_IMPLEMENTED;
220 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
222 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
223 return ERROR_CALL_NOT_IMPLEMENTED;
226 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
227 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
229 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
230 eInstallType, debugstr_a(szCommandLine));
231 return ERROR_CALL_NOT_IMPLEMENTED;
234 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
235 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
237 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
238 eInstallType, debugstr_w(szCommandLine));
239 return ERROR_CALL_NOT_IMPLEMENTED;
242 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
243 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
245 MSIPACKAGE* package = NULL;
248 WCHAR sourcepath[MAX_PATH];
249 WCHAR filename[MAX_PATH];
250 static const WCHAR szInstalled[] = {
251 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
254 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
255 debugstr_w(szCommandLine));
257 if (eInstallState != INSTALLSTATE_LOCAL &&
258 eInstallState != INSTALLSTATE_DEFAULT)
260 FIXME("Not implemented for anything other than local installs\n");
261 return ERROR_CALL_NOT_IMPLEMENTED;
264 sz = sizeof(sourcepath);
265 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
266 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
269 sz = sizeof(filename);
270 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
271 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
273 lstrcatW(sourcepath,filename);
276 * ok 1, we need to find the msi file for this product.
277 * 2, find the source dir for the files
278 * 3, do the configure/install.
279 * 4, cleanupany runonce entry.
282 r = MSI_OpenProductW( szProduct, &package );
283 if (r != ERROR_SUCCESS)
286 sz = lstrlenW(szInstalled) + 1;
289 sz += lstrlenW(szCommandLine);
291 commandline = msi_alloc(sz * sizeof(WCHAR));
294 r = ERROR_OUTOFMEMORY;
300 lstrcpyW(commandline,szCommandLine);
302 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
303 lstrcatW(commandline,szInstalled);
305 r = MSI_InstallPackage( package, sourcepath, commandline );
307 msi_free(commandline);
310 msiobj_release( &package->hdr );
315 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
316 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
318 LPWSTR szwProduct = NULL;
319 LPWSTR szwCommandLine = NULL;
320 UINT r = ERROR_OUTOFMEMORY;
324 szwProduct = strdupAtoW( szProduct );
331 szwCommandLine = strdupAtoW( szCommandLine );
336 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
339 msi_free( szwProduct );
340 msi_free( szwCommandLine);
345 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
346 INSTALLSTATE eInstallState)
348 LPWSTR szwProduct = NULL;
351 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
355 szwProduct = strdupAtoW( szProduct );
357 return ERROR_OUTOFMEMORY;
360 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
361 msi_free( szwProduct );
366 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
367 INSTALLSTATE eInstallState)
369 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
372 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
374 LPWSTR szwComponent = NULL;
376 WCHAR szwBuffer[GUID_SIZE];
378 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
382 szwComponent = strdupAtoW( szComponent );
384 return ERROR_OUTOFMEMORY;
387 r = MsiGetProductCodeW( szwComponent, szwBuffer );
389 if( ERROR_SUCCESS == r )
390 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
392 msi_free( szwComponent );
397 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
401 WCHAR szSquished[GUID_SIZE];
402 DWORD sz = GUID_SIZE;
403 static const WCHAR szPermKey[] =
404 { '0','0','0','0','0','0','0','0','0','0','0','0',
405 '0','0','0','0','0','0','0','0','0','0','0','0',
406 '0','0','0','0','0','0','0','0',0};
408 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
410 if (NULL == szComponent)
411 return ERROR_INVALID_PARAMETER;
413 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
414 if (rc != ERROR_SUCCESS)
415 return ERROR_UNKNOWN_COMPONENT;
417 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
418 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
421 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
426 if (rc != ERROR_SUCCESS)
427 return ERROR_INSTALL_FAILURE;
429 unsquash_guid(szSquished, szBuffer);
430 return ERROR_SUCCESS;
433 static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
434 awstring *szValue, DWORD *pcchValueBuf)
440 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
441 debugstr_w(szAttribute), szValue, pcchValueBuf);
444 * FIXME: Values seem scattered/duplicated in the registry. Is there a system?
447 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szProduct[0] || !szAttribute)
448 return ERROR_INVALID_PARAMETER;
450 /* check for special properties */
451 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
454 WCHAR packagecode[35];
456 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
457 if (r != ERROR_SUCCESS)
458 return ERROR_UNKNOWN_PRODUCT;
460 regval = msi_reg_get_val_str( hkey, szAttribute );
463 if (unsquash_guid(regval, packagecode))
464 val = strdupW(packagecode);
470 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
472 static const WCHAR one[] = { '1',0 };
474 * FIXME: should be in the Product key (user or system?)
475 * but isn't written yet...
477 val = strdupW( one );
479 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
480 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
482 static const WCHAR fmt[] = { '%','u',0 };
486 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
487 if (r != ERROR_SUCCESS)
488 return ERROR_UNKNOWN_PRODUCT;
490 if (msi_reg_get_val_dword( hkey, szAttribute, ®val))
492 sprintfW(szVal, fmt, regval);
493 val = strdupW( szVal );
498 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
500 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
501 if (r != ERROR_SUCCESS)
502 return ERROR_UNKNOWN_PRODUCT;
504 val = msi_reg_get_val_str( hkey, szAttribute );
508 else if (!szAttribute[0])
510 return ERROR_UNKNOWN_PROPERTY;
514 static const WCHAR szDisplayVersion[] = {
515 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
517 FIXME("%s\n", debugstr_w(szAttribute));
518 /* FIXME: some attribute values not tested... */
520 if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
521 szAttribute = szDisplayVersion;
523 r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
524 if (r != ERROR_SUCCESS)
525 return ERROR_UNKNOWN_PRODUCT;
527 val = msi_reg_get_val_str( hkey, szAttribute );
532 TRACE("returning %s\n", debugstr_w(val));
535 return ERROR_UNKNOWN_PROPERTY;
537 r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
544 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
545 LPSTR szBuffer, DWORD *pcchValueBuf)
547 LPWSTR szwProduct, szwAttribute = NULL;
548 UINT r = ERROR_OUTOFMEMORY;
551 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
552 szBuffer, pcchValueBuf);
554 szwProduct = strdupAtoW( szProduct );
555 if( szProduct && !szwProduct )
558 szwAttribute = strdupAtoW( szAttribute );
559 if( szAttribute && !szwAttribute )
562 buffer.unicode = FALSE;
563 buffer.str.a = szBuffer;
565 r = MSI_GetProductInfo( szwProduct, szwAttribute,
566 &buffer, pcchValueBuf );
569 msi_free( szwProduct );
570 msi_free( szwAttribute );
575 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
576 LPWSTR szBuffer, DWORD *pcchValueBuf)
580 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
581 szBuffer, pcchValueBuf);
583 buffer.unicode = TRUE;
584 buffer.str.w = szBuffer;
586 return MSI_GetProductInfo( szProduct, szAttribute,
587 &buffer, pcchValueBuf );
590 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
592 LPWSTR szwLogFile = NULL;
595 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
599 szwLogFile = strdupAtoW( szLogFile );
601 return ERROR_OUTOFMEMORY;
603 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
604 msi_free( szwLogFile );
608 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
610 HANDLE file = INVALID_HANDLE_VALUE;
612 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
616 lstrcpyW(gszLogFile,szLogFile);
617 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
618 DeleteFileW(szLogFile);
619 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
620 FILE_ATTRIBUTE_NORMAL, NULL);
621 if (file != INVALID_HANDLE_VALUE)
624 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
627 gszLogFile[0] = '\0';
629 return ERROR_SUCCESS;
632 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
634 LPWSTR szwProduct = NULL;
639 szwProduct = strdupAtoW( szProduct );
641 return ERROR_OUTOFMEMORY;
643 r = MsiQueryProductStateW( szwProduct );
644 msi_free( szwProduct );
648 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
651 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
653 static const WCHAR szWindowsInstaller[] = {
654 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
657 TRACE("%s\n", debugstr_w(szProduct));
660 return INSTALLSTATE_INVALIDARG;
662 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
663 if (rc != ERROR_SUCCESS)
668 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
669 if (rc != ERROR_SUCCESS)
673 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
674 if (rc != ERROR_SUCCESS)
681 rrc = INSTALLSTATE_DEFAULT;
684 FIXME("Unknown install state read from registry (%i)\n",rrc);
685 rrc = INSTALLSTATE_UNKNOWN;
693 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
695 INSTALLUILEVEL old = gUILevel;
696 HWND oldwnd = gUIhwnd;
698 TRACE("%08x %p\n", dwUILevel, phWnd);
700 gUILevel = dwUILevel;
709 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
710 DWORD dwMessageFilter, LPVOID pvContext)
712 INSTALLUI_HANDLERA prev = gUIHandlerA;
714 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
715 gUIHandlerA = puiHandler;
716 gUIFilter = dwMessageFilter;
717 gUIContext = pvContext;
722 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
723 DWORD dwMessageFilter, LPVOID pvContext)
725 INSTALLUI_HANDLERW prev = gUIHandlerW;
727 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
728 gUIHandlerW = puiHandler;
729 gUIFilter = dwMessageFilter;
730 gUIContext = pvContext;
735 /******************************************************************
736 * MsiLoadStringW [MSI.@]
738 * Loads a string from MSI's string resources.
742 * handle [I] only -1 is handled currently
743 * id [I] id of the string to be loaded
744 * lpBuffer [O] buffer for the string to be written to
745 * nBufferMax [I] maximum size of the buffer in characters
746 * lang [I] the preferred language for the string
750 * If successful, this function returns the language id of the string loaded
751 * If the function fails, the function returns zero.
755 * The type of the first parameter is unknown. LoadString's prototype
756 * suggests that it might be a module handle. I have made it an MSI handle
757 * for starters, as -1 is an invalid MSI handle, but not an invalid module
758 * handle. Maybe strings can be stored in an MSI database somehow.
760 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
761 int nBufferMax, LANGID lang )
768 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
771 FIXME("don't know how to deal with handle = %08lx\n", handle);
774 lang = GetUserDefaultLangID();
776 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
780 hResData = LoadResource( msi_hInstance, hres );
783 p = LockResource( hResData );
787 for (i = 0; i < (id&0xf); i++)
791 if( nBufferMax <= len )
794 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
797 TRACE("found -> %s\n", debugstr_w(lpBuffer));
802 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
803 int nBufferMax, LANGID lang )
809 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
810 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
813 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
814 if( len <= nBufferMax )
815 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
816 lpBuffer, nBufferMax, NULL, NULL );
824 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
827 char szProduct[GUID_SIZE];
829 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
831 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
832 return INSTALLSTATE_UNKNOWN;
834 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
837 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
840 WCHAR szProduct[GUID_SIZE];
842 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
844 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
845 return INSTALLSTATE_UNKNOWN;
847 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
850 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
851 WORD wLanguageId, DWORD f)
853 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
854 uType, wLanguageId, f);
855 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
858 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
859 WORD wLanguageId, DWORD f)
861 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
862 uType, wLanguageId, f);
863 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
866 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
867 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
870 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
871 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
873 return ERROR_CALL_NOT_IMPLEMENTED;
876 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
877 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
880 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
881 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
883 return ERROR_CALL_NOT_IMPLEMENTED;
886 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
887 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
889 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
890 return ERROR_CALL_NOT_IMPLEMENTED;
893 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
894 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
896 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
897 return ERROR_CALL_NOT_IMPLEMENTED;
900 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
901 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
904 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
905 ppcCertContext, pbHashData, pcbHashData);
906 return ERROR_CALL_NOT_IMPLEMENTED;
909 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
910 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
913 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
914 ppcCertContext, pbHashData, pcbHashData);
915 return ERROR_CALL_NOT_IMPLEMENTED;
918 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
919 LPSTR szValue, DWORD *pccbValue )
921 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
922 return ERROR_CALL_NOT_IMPLEMENTED;
925 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
926 LPWSTR szValue, DWORD *pccbValue )
928 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
929 return ERROR_CALL_NOT_IMPLEMENTED;
932 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
935 LPWSTR szPack = NULL;
937 TRACE("%s\n", debugstr_a(szPackage) );
941 szPack = strdupAtoW( szPackage );
943 return ERROR_OUTOFMEMORY;
946 r = MsiVerifyPackageW( szPack );
953 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
958 TRACE("%s\n", debugstr_w(szPackage) );
960 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
961 MsiCloseHandle( handle );
966 static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
967 awstring* lpPathBuf, DWORD* pcchBuf)
969 WCHAR squished_pc[GUID_SIZE], squished_comp[GUID_SIZE];
975 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
976 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
978 if( !szProduct || !szComponent )
979 return INSTALLSTATE_INVALIDARG;
980 if( lpPathBuf->str.w && !pcchBuf )
981 return INSTALLSTATE_INVALIDARG;
983 if (!squash_guid( szProduct, squished_pc ) ||
984 !squash_guid( szComponent, squished_comp ))
985 return INSTALLSTATE_INVALIDARG;
987 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
988 if( rc != ERROR_SUCCESS )
989 return INSTALLSTATE_UNKNOWN;
993 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
994 if( rc != ERROR_SUCCESS )
995 return INSTALLSTATE_UNKNOWN;
997 path = msi_reg_get_val_str( hkey, squished_pc );
1000 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1001 debugstr_w(szProduct), debugstr_w(path));
1004 return INSTALLSTATE_UNKNOWN;
1007 r = INSTALLSTATE_LOCAL;
1009 r = INSTALLSTATE_NOTUSED;
1011 msi_strcpy_to_awstring( path, lpPathBuf, pcchBuf );
1017 /******************************************************************
1018 * MsiGetComponentPathW [MSI.@]
1020 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1021 LPWSTR lpPathBuf, DWORD* pcchBuf)
1025 path.unicode = TRUE;
1026 path.str.w = lpPathBuf;
1028 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1031 /******************************************************************
1032 * MsiGetComponentPathA [MSI.@]
1034 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1035 LPSTR lpPathBuf, DWORD* pcchBuf)
1037 LPWSTR szwProduct, szwComponent = NULL;
1038 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1041 szwProduct = strdupAtoW( szProduct );
1042 if( szProduct && !szwProduct)
1045 szwComponent = strdupAtoW( szComponent );
1046 if( szComponent && !szwComponent )
1049 path.unicode = FALSE;
1050 path.str.a = lpPathBuf;
1052 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1055 msi_free( szwProduct );
1056 msi_free( szwComponent );
1061 /******************************************************************
1062 * MsiQueryFeatureStateA [MSI.@]
1064 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1066 LPWSTR szwProduct = NULL, szwFeature= NULL;
1067 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1069 szwProduct = strdupAtoW( szProduct );
1070 if ( szProduct && !szwProduct )
1073 szwFeature = strdupAtoW( szFeature );
1074 if ( szFeature && !szwFeature )
1077 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1080 msi_free( szwProduct);
1081 msi_free( szwFeature);
1086 /******************************************************************
1087 * MsiQueryFeatureStateW [MSI.@]
1089 * Checks the state of a feature
1092 * szProduct [I] Product's GUID string
1093 * szFeature [I] Feature's GUID string
1096 * INSTALLSTATE_LOCAL Feature is installed and useable
1097 * INSTALLSTATE_ABSENT Feature is absent
1098 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1099 * INSTALLSTATE_UNKNOWN An error occurred
1100 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1103 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1105 WCHAR squishProduct[33], comp[GUID_SIZE];
1107 LPWSTR components, p, parent_feature;
1111 BOOL missing = FALSE;
1113 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1115 if (!szProduct || !szFeature)
1116 return INSTALLSTATE_INVALIDARG;
1118 if (!squash_guid( szProduct, squishProduct ))
1119 return INSTALLSTATE_INVALIDARG;
1121 /* check that it's installed at all */
1122 rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
1123 if (rc != ERROR_SUCCESS)
1124 return INSTALLSTATE_UNKNOWN;
1126 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1129 if (!parent_feature)
1130 return INSTALLSTATE_UNKNOWN;
1132 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1133 msi_free(parent_feature);
1134 if (r == INSTALLSTATE_ABSENT)
1137 /* now check if it's complete or advertised */
1138 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1139 if (rc != ERROR_SUCCESS)
1140 return INSTALLSTATE_UNKNOWN;
1142 components = msi_reg_get_val_str( hkey, szFeature );
1145 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1149 ERR("components missing %s %s\n",
1150 debugstr_w(szProduct), debugstr_w(szFeature));
1151 return INSTALLSTATE_UNKNOWN;
1154 for( p = components; *p != 2 ; p += 20)
1156 if (!decode_base85_guid( p, &guid ))
1158 ERR("%s\n", debugstr_w(p));
1161 StringFromGUID2(&guid, comp, GUID_SIZE);
1162 r = MsiGetComponentPathW(szProduct, comp, NULL, 0);
1163 TRACE("component %s state %d\n", debugstr_guid(&guid), r);
1166 case INSTALLSTATE_NOTUSED:
1167 case INSTALLSTATE_LOCAL:
1168 case INSTALLSTATE_SOURCE:
1175 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1176 msi_free(components);
1179 return INSTALLSTATE_ADVERTISED;
1181 return INSTALLSTATE_LOCAL;
1184 /******************************************************************
1185 * MsiGetFileVersionA [MSI.@]
1187 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1188 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1190 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1191 UINT ret = ERROR_OUTOFMEMORY;
1195 szwFilePath = strdupAtoW( szFilePath );
1200 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1202 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1203 if( !lpwVersionBuff )
1207 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1209 lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1214 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1215 lpwLangBuff, pcchLangBuf);
1217 if( lpwVersionBuff )
1218 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1219 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1221 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1222 lpLangBuf, *pcchLangBuf, NULL, NULL);
1225 msi_free(szwFilePath);
1226 msi_free(lpwVersionBuff);
1227 msi_free(lpwLangBuff);
1232 /******************************************************************
1233 * MsiGetFileVersionW [MSI.@]
1235 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1236 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1238 static const WCHAR szVersionResource[] = {'\\',0};
1239 static const WCHAR szVersionFormat[] = {
1240 '%','d','.','%','d','.','%','d','.','%','d',0};
1241 static const WCHAR szLangFormat[] = {'%','d',0};
1244 LPVOID lpVer = NULL;
1245 VS_FIXEDFILEINFO *ffi;
1249 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
1250 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1251 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1253 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1255 return GetLastError();
1257 lpVer = msi_alloc(dwVerLen);
1260 ret = ERROR_OUTOFMEMORY;
1264 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1266 ret = GetLastError();
1269 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1271 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1274 wsprintfW(tmp, szVersionFormat,
1275 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1276 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1277 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1278 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1283 *pcchVersionBuf = 0;
1287 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1289 DWORD lang = GetUserDefaultLangID();
1291 FIXME("Retrieve language from file\n");
1292 wsprintfW(tmp, szLangFormat, lang);
1293 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1294 *pcchLangBuf = lstrlenW(lpLangBuf);
1302 /***********************************************************************
1303 * MsiGetFeatureUsageW [MSI.@]
1305 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
1306 DWORD* pdwUseCount, WORD* pwDateUsed )
1308 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1309 pdwUseCount, pwDateUsed);
1310 return ERROR_CALL_NOT_IMPLEMENTED;
1313 /***********************************************************************
1314 * MsiGetFeatureUsageA [MSI.@]
1316 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
1317 DWORD* pdwUseCount, WORD* pwDateUsed )
1319 LPWSTR prod = NULL, feat = NULL;
1320 UINT ret = ERROR_OUTOFMEMORY;
1322 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1323 pdwUseCount, pwDateUsed);
1325 prod = strdupAtoW( szProduct );
1326 if (szProduct && !prod)
1329 feat = strdupAtoW( szFeature );
1330 if (szFeature && !feat)
1333 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
1342 /***********************************************************************
1343 * MsiUseFeatureExW [MSI.@]
1345 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
1346 DWORD dwInstallMode, DWORD dwReserved )
1350 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
1351 dwInstallMode, dwReserved);
1353 state = MsiQueryFeatureStateW( szProduct, szFeature );
1356 return INSTALLSTATE_INVALIDARG;
1358 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
1360 FIXME("mark product %s feature %s as used\n",
1361 debugstr_w(szProduct), debugstr_w(szFeature) );
1367 /***********************************************************************
1368 * MsiUseFeatureExA [MSI.@]
1370 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
1371 DWORD dwInstallMode, DWORD dwReserved )
1373 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
1374 LPWSTR prod = NULL, feat = NULL;
1376 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
1377 dwInstallMode, dwReserved);
1379 prod = strdupAtoW( szProduct );
1380 if (szProduct && !prod)
1383 feat = strdupAtoW( szFeature );
1384 if (szFeature && !feat)
1387 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
1396 /***********************************************************************
1397 * MsiUseFeatureW [MSI.@]
1399 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
1401 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
1404 /***********************************************************************
1405 * MsiUseFeatureA [MSI.@]
1407 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
1409 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
1412 /***********************************************************************
1413 * MSI_ProvideQualifiedComponentEx [internal]
1415 static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
1416 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1417 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
1420 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
1421 feature[MAX_FEATURE_CHARS+1];
1427 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
1428 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1429 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1431 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1432 if (rc != ERROR_SUCCESS)
1433 return ERROR_INDEX_ABSENT;
1435 info = msi_reg_get_val_str( hkey, szQualifier );
1439 return ERROR_INDEX_ABSENT;
1441 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
1444 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
1446 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
1450 if (rc != INSTALLSTATE_LOCAL)
1451 return ERROR_FILE_NOT_FOUND;
1453 return ERROR_SUCCESS;
1456 /***********************************************************************
1457 * MsiProvideQualifiedComponentExW [MSI.@]
1459 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1460 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1461 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1466 path.unicode = TRUE;
1467 path.str.w = lpPathBuf;
1469 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
1470 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
1473 /***********************************************************************
1474 * MsiProvideQualifiedComponentExA [MSI.@]
1476 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
1477 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR szProduct,
1478 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
1481 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
1482 UINT r = ERROR_OUTOFMEMORY;
1485 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
1486 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
1487 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1489 szwComponent = strdupAtoW( szComponent );
1490 if (szComponent && !szwComponent)
1493 szwQualifier = strdupAtoW( szQualifier );
1494 if (szQualifier && !szwQualifier)
1497 szwProduct = strdupAtoW( szProduct );
1498 if (szProduct && !szwProduct)
1501 path.unicode = FALSE;
1502 path.str.a = lpPathBuf;
1504 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
1505 dwInstallMode, szwProduct, Unused1,
1506 Unused2, &path, pcchPathBuf);
1508 msi_free(szwProduct);
1509 msi_free(szwComponent);
1510 msi_free(szwQualifier);
1515 /***********************************************************************
1516 * MsiProvideQualifiedComponentW [MSI.@]
1518 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1519 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1522 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1523 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1526 /***********************************************************************
1527 * MsiProvideQualifiedComponentA [MSI.@]
1529 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1530 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1533 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
1534 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1537 /***********************************************************************
1538 * MSI_GetUserInfo [internal]
1540 static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
1541 awstring *lpUserNameBuf, DWORD* pcchUserNameBuf,
1542 awstring *lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1543 awstring *lpSerialBuf, DWORD* pcchSerialBuf)
1546 LPWSTR user, org, serial;
1548 USERINFOSTATE state;
1550 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1551 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1555 return USERINFOSTATE_INVALIDARG;
1557 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1558 if (r != ERROR_SUCCESS)
1559 return USERINFOSTATE_UNKNOWN;
1561 user = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGOWNERW );
1562 org = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGCOMPANYW );
1563 serial = msi_reg_get_val_str( hkey, INSTALLPROPERTY_PRODUCTIDW );
1567 state = USERINFOSTATE_PRESENT;
1571 r = msi_strcpy_to_awstring( user, lpUserNameBuf, pcchUserNameBuf );
1572 if (r == ERROR_MORE_DATA)
1573 state = USERINFOSTATE_MOREDATA;
1576 state = USERINFOSTATE_ABSENT;
1579 r = msi_strcpy_to_awstring( org, lpOrgNameBuf, pcchOrgNameBuf );
1580 if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
1581 state = USERINFOSTATE_MOREDATA;
1583 /* msdn states: The user information is considered to be present even in the absence of a company name. */
1586 r = msi_strcpy_to_awstring( serial, lpSerialBuf, pcchSerialBuf );
1587 if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
1588 state = USERINFOSTATE_MOREDATA;
1591 state = USERINFOSTATE_ABSENT;
1600 /***********************************************************************
1601 * MsiGetUserInfoW [MSI.@]
1603 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
1604 LPWSTR lpUserNameBuf, DWORD* pcchUserNameBuf,
1605 LPWSTR lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1606 LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1608 awstring user, org, serial;
1610 user.unicode = TRUE;
1611 user.str.w = lpUserNameBuf;
1613 org.str.w = lpOrgNameBuf;
1614 serial.unicode = TRUE;
1615 serial.str.w = lpSerialBuf;
1617 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
1618 &org, pcchOrgNameBuf,
1619 &serial, pcchSerialBuf );
1622 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
1623 LPSTR lpUserNameBuf, DWORD* pcchUserNameBuf,
1624 LPSTR lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1625 LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1627 awstring user, org, serial;
1631 prod = strdupAtoW( szProduct );
1632 if (szProduct && !prod)
1633 return ERROR_OUTOFMEMORY;
1635 user.unicode = FALSE;
1636 user.str.a = lpUserNameBuf;
1637 org.unicode = FALSE;
1638 org.str.a = lpOrgNameBuf;
1639 serial.unicode = FALSE;
1640 serial.str.a = lpSerialBuf;
1642 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
1643 &org, pcchOrgNameBuf,
1644 &serial, pcchSerialBuf );
1651 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1655 MSIPACKAGE *package;
1656 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1658 TRACE("(%s)\n",debugstr_w(szProduct));
1660 rc = MsiOpenProductW(szProduct,&handle);
1661 if (rc != ERROR_SUCCESS)
1662 return ERROR_INVALID_PARAMETER;
1664 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1665 rc = ACTION_PerformUIAction(package, szFirstRun);
1666 msiobj_release( &package->hdr );
1668 MsiCloseHandle(handle);
1673 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1677 MSIPACKAGE *package;
1678 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1680 TRACE("(%s)\n",debugstr_a(szProduct));
1682 rc = MsiOpenProductA(szProduct,&handle);
1683 if (rc != ERROR_SUCCESS)
1684 return ERROR_INVALID_PARAMETER;
1686 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1687 rc = ACTION_PerformUIAction(package, szFirstRun);
1688 msiobj_release( &package->hdr );
1690 MsiCloseHandle(handle);
1695 /***********************************************************************
1696 * MsiConfigureFeatureA [MSI.@]
1698 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
1700 LPWSTR prod, feat = NULL;
1701 UINT r = ERROR_OUTOFMEMORY;
1703 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
1705 prod = strdupAtoW( szProduct );
1706 if (szProduct && !prod)
1709 feat = strdupAtoW( szFeature );
1710 if (szFeature && !feat)
1713 r = MsiConfigureFeatureW(prod, feat, eInstallState);
1722 /***********************************************************************
1723 * MsiConfigureFeatureW [MSI.@]
1725 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
1727 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
1728 MSIPACKAGE *package = NULL;
1730 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
1733 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
1735 if (!szProduct || !szFeature)
1736 return ERROR_INVALID_PARAMETER;
1738 switch (eInstallState)
1740 case INSTALLSTATE_DEFAULT:
1741 /* FIXME: how do we figure out the default location? */
1742 eInstallState = INSTALLSTATE_LOCAL;
1744 case INSTALLSTATE_LOCAL:
1745 case INSTALLSTATE_SOURCE:
1746 case INSTALLSTATE_ABSENT:
1747 case INSTALLSTATE_ADVERTISED:
1750 return ERROR_INVALID_PARAMETER;
1753 r = MSI_OpenProductW( szProduct, &package );
1754 if (r != ERROR_SUCCESS)
1757 sz = sizeof(sourcepath);
1758 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1759 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
1761 sz = sizeof(filename);
1762 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1763 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1765 lstrcatW( sourcepath, filename );
1767 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
1769 r = ACTION_PerformUIAction( package, szCostInit );
1770 if (r != ERROR_SUCCESS)
1773 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
1774 if (r != ERROR_SUCCESS)
1777 r = MSI_InstallPackage( package, sourcepath, NULL );
1780 msiobj_release( &package->hdr );
1785 /***********************************************************************
1786 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
1788 * Notes: undocumented
1790 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1792 WCHAR path[MAX_PATH];
1794 TRACE("%d\n", dwReserved);
1798 FIXME("dwReserved=%d\n", dwReserved);
1799 return ERROR_INVALID_PARAMETER;
1802 if (!GetWindowsDirectoryW(path, MAX_PATH))
1803 return ERROR_FUNCTION_FAILED;
1805 lstrcatW(path, installerW);
1807 if (!CreateDirectoryW(path, NULL))
1808 return ERROR_FUNCTION_FAILED;
1810 return ERROR_SUCCESS;
1813 /***********************************************************************
1814 * MsiGetShortcutTargetA [MSI.@]
1816 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1817 LPSTR szProductCode, LPSTR szFeatureId,
1818 LPSTR szComponentCode )
1821 const int len = MAX_FEATURE_CHARS+1;
1822 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
1825 target = strdupAtoW( szShortcutTarget );
1826 if (szShortcutTarget && !target )
1827 return ERROR_OUTOFMEMORY;
1831 r = MsiGetShortcutTargetW( target, product, feature, component );
1833 if (r == ERROR_SUCCESS)
1835 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
1836 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
1837 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
1842 /***********************************************************************
1843 * MsiGetShortcutTargetW [MSI.@]
1845 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1846 LPWSTR szProductCode, LPWSTR szFeatureId,
1847 LPWSTR szComponentCode )
1849 IShellLinkDataList *dl = NULL;
1850 IPersistFile *pf = NULL;
1851 LPEXP_DARWIN_LINK darwin = NULL;
1854 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
1855 szProductCode, szFeatureId, szComponentCode );
1857 init = CoInitialize(NULL);
1859 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
1860 &IID_IPersistFile, (LPVOID*) &pf );
1861 if( SUCCEEDED( r ) )
1863 r = IPersistFile_Load( pf, szShortcutTarget,
1864 STGM_READ | STGM_SHARE_DENY_WRITE );
1865 if( SUCCEEDED( r ) )
1867 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
1869 if( SUCCEEDED( r ) )
1871 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
1873 IShellLinkDataList_Release( dl );
1876 IPersistFile_Release( pf );
1879 if (SUCCEEDED(init))
1882 TRACE("darwin = %p\n", darwin);
1889 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
1890 szProductCode, szFeatureId, szComponentCode, &sz );
1891 LocalFree( darwin );
1895 return ERROR_FUNCTION_FAILED;
1898 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1899 DWORD dwReinstallMode )
1901 MSIPACKAGE* package = NULL;
1903 WCHAR sourcepath[MAX_PATH];
1904 WCHAR filename[MAX_PATH];
1905 static const WCHAR szLogVerbose[] = {
1906 ' ','L','O','G','V','E','R','B','O','S','E',0 };
1907 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
1908 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
1909 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1910 static const WCHAR szOne[] = {'1',0};
1911 WCHAR reinstallmode[11];
1915 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
1918 ptr = reinstallmode;
1920 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
1922 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
1924 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
1926 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
1928 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
1930 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
1932 if (dwReinstallMode & REINSTALLMODE_USERDATA)
1934 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
1936 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
1938 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1942 sz = sizeof(sourcepath);
1943 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1944 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
1946 sz = sizeof(filename);
1947 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1948 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1950 lstrcatW( sourcepath, filename );
1952 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1953 r = MSI_OpenPackageW( sourcepath, &package );
1955 r = MSI_OpenProductW( szProduct, &package );
1957 if (r != ERROR_SUCCESS)
1960 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
1961 MSI_SetPropertyW( package, szInstalled, szOne );
1962 MSI_SetPropertyW( package, szLogVerbose, szOne );
1963 MSI_SetPropertyW( package, szReinstall, szFeature );
1965 r = MSI_InstallPackage( package, sourcepath, NULL );
1967 msiobj_release( &package->hdr );
1972 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1973 DWORD dwReinstallMode )
1979 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
1982 wszProduct = strdupAtoW(szProduct);
1983 wszFeature = strdupAtoW(szFeature);
1985 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
1987 msi_free(wszProduct);
1988 msi_free(wszFeature);
1995 unsigned int buf[4];
1996 unsigned char in[64];
1997 unsigned char digest[16];
2000 extern VOID WINAPI MD5Init( MD5_CTX *);
2001 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
2002 extern VOID WINAPI MD5Final( MD5_CTX *);
2004 /***********************************************************************
2005 * MsiGetFileHashW [MSI.@]
2007 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2008 PMSIFILEHASHINFO pHash )
2010 HANDLE handle, mapping;
2013 UINT r = ERROR_FUNCTION_FAILED;
2015 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2018 return ERROR_INVALID_PARAMETER;
2020 return ERROR_INVALID_PARAMETER;
2021 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2022 return ERROR_INVALID_PARAMETER;
2024 handle = CreateFileW( szFilePath, GENERIC_READ,
2025 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2026 if (handle == INVALID_HANDLE_VALUE)
2027 return ERROR_FILE_NOT_FOUND;
2029 length = GetFileSize( handle, NULL );
2031 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2034 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2040 MD5Update( &ctx, p, length );
2042 UnmapViewOfFile( p );
2044 memcpy( pHash->dwData, &ctx.digest, sizeof pHash->dwData );
2047 CloseHandle( mapping );
2049 CloseHandle( handle );
2054 /***********************************************************************
2055 * MsiGetFileHashA [MSI.@]
2057 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2058 PMSIFILEHASHINFO pHash )
2063 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2065 file = strdupAtoW( szFilePath );
2066 if (szFilePath && !file)
2067 return ERROR_OUTOFMEMORY;
2069 r = MsiGetFileHashW( file, dwOptions, pHash );
2074 /***********************************************************************
2075 * MsiAdvertiseScriptW [MSI.@]
2077 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2078 PHKEY phRegData, BOOL fRemoveItems )
2080 FIXME("%s %08x %p %d\n",
2081 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2082 return ERROR_CALL_NOT_IMPLEMENTED;
2085 /***********************************************************************
2086 * MsiAdvertiseScriptA [MSI.@]
2088 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2089 PHKEY phRegData, BOOL fRemoveItems )
2091 FIXME("%s %08x %p %d\n",
2092 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2093 return ERROR_CALL_NOT_IMPLEMENTED;