2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004,2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
41 #include "wine/unicode.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msi);
47 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
49 INSTALLUI_HANDLERA gUIHandlerA = NULL;
50 INSTALLUI_HANDLERW gUIHandlerW = NULL;
52 LPVOID gUIContext = NULL;
53 WCHAR gszLogFile[MAX_PATH];
54 HINSTANCE msi_hInstance;
56 static LONG dll_count;
58 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
61 * Dll lifetime tracking declaration
63 static void LockModule(void)
65 InterlockedIncrement(&dll_count);
68 static void UnlockModule(void)
70 InterlockedDecrement(&dll_count);
74 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
77 LPWSTR szwProd = NULL;
79 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
83 szwProd = strdupAtoW( szProduct );
85 return ERROR_OUTOFMEMORY;
88 r = MsiOpenProductW( szwProd, phProduct );
95 static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
99 HKEY hKeyProduct = NULL;
102 TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
104 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
105 if( r != ERROR_SUCCESS )
107 r = ERROR_UNKNOWN_PRODUCT;
111 /* find the size of the path */
113 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
114 NULL, &type, NULL, &count );
115 if( r != ERROR_SUCCESS )
117 r = ERROR_UNKNOWN_PRODUCT;
121 /* now alloc and fetch the path of the database to open */
122 path = msi_alloc( count );
126 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
127 NULL, &type, (LPBYTE) path, &count );
128 if( r != ERROR_SUCCESS )
130 r = ERROR_UNKNOWN_PRODUCT;
134 r = MSI_OpenPackageW( path, ppackage );
139 RegCloseKey( hKeyProduct );
144 UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
146 MSIPACKAGE *package = NULL;
149 r = MSI_OpenProductW( szProduct, &package );
150 if( r == ERROR_SUCCESS )
152 *phProduct = alloc_msihandle( &package->hdr );
153 msiobj_release( &package->hdr );
158 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
159 LPCSTR szTransforms, LANGID lgidLanguage)
161 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
162 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
163 return ERROR_CALL_NOT_IMPLEMENTED;
166 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
167 LPCWSTR szTransforms, LANGID lgidLanguage)
169 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
170 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
171 return ERROR_CALL_NOT_IMPLEMENTED;
174 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
175 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
177 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
178 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
179 lgidLanguage, dwPlatform, dwOptions);
180 return ERROR_CALL_NOT_IMPLEMENTED;
183 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
184 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
186 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
187 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
188 lgidLanguage, dwPlatform, dwOptions);
189 return ERROR_CALL_NOT_IMPLEMENTED;
192 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
194 LPWSTR szwPath = NULL, szwCommand = NULL;
195 UINT r = ERROR_OUTOFMEMORY;
197 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
201 szwPath = strdupAtoW( szPackagePath );
208 szwCommand = strdupAtoW( szCommandLine );
213 r = MsiInstallProductW( szwPath, szwCommand );
217 msi_free( szwCommand );
222 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
224 MSIPACKAGE *package = NULL;
227 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
229 r = MSI_OpenPackageW( szPackagePath, &package );
230 if (r == ERROR_SUCCESS)
232 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
233 msiobj_release( &package->hdr );
239 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
241 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
242 return ERROR_CALL_NOT_IMPLEMENTED;
245 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
247 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
248 return ERROR_CALL_NOT_IMPLEMENTED;
251 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
252 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
254 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
255 eInstallType, debugstr_a(szCommandLine));
256 return ERROR_CALL_NOT_IMPLEMENTED;
259 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
260 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
262 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
263 eInstallType, debugstr_w(szCommandLine));
264 return ERROR_CALL_NOT_IMPLEMENTED;
267 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
268 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
270 MSIPACKAGE* package = NULL;
273 WCHAR sourcepath[MAX_PATH];
274 WCHAR filename[MAX_PATH];
275 static const WCHAR szInstalled[] = {
276 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
279 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
280 debugstr_w(szCommandLine));
282 if (eInstallState != INSTALLSTATE_LOCAL &&
283 eInstallState != INSTALLSTATE_DEFAULT)
285 FIXME("Not implemented for anything other than local installs\n");
286 return ERROR_CALL_NOT_IMPLEMENTED;
289 sz = sizeof(sourcepath);
290 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
291 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
294 sz = sizeof(filename);
295 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
296 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
298 lstrcatW(sourcepath,filename);
301 * ok 1, we need to find the msi file for this product.
302 * 2, find the source dir for the files
303 * 3, do the configure/install.
304 * 4, cleanupany runonce entry.
307 r = MSI_OpenProductW( szProduct, &package );
308 if (r != ERROR_SUCCESS)
311 sz = lstrlenW(szInstalled) + 1;
314 sz += lstrlenW(szCommandLine);
316 commandline = msi_alloc(sz * sizeof(WCHAR));
319 r = ERROR_OUTOFMEMORY;
325 lstrcpyW(commandline,szCommandLine);
327 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
328 lstrcatW(commandline,szInstalled);
330 r = MSI_InstallPackage( package, sourcepath, commandline );
332 msi_free(commandline);
335 msiobj_release( &package->hdr );
340 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
341 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
343 LPWSTR szwProduct = NULL;
344 LPWSTR szwCommandLine = NULL;
345 UINT r = ERROR_OUTOFMEMORY;
349 szwProduct = strdupAtoW( szProduct );
356 szwCommandLine = strdupAtoW( szCommandLine );
361 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
364 msi_free( szwProduct );
365 msi_free( szwCommandLine);
370 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
371 INSTALLSTATE eInstallState)
373 LPWSTR szwProduct = NULL;
376 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
380 szwProduct = strdupAtoW( szProduct );
382 return ERROR_OUTOFMEMORY;
385 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
386 msi_free( szwProduct );
391 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
392 INSTALLSTATE eInstallState)
394 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
396 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
399 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
401 LPWSTR szwComponent = NULL;
403 WCHAR szwBuffer[GUID_SIZE];
405 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
409 szwComponent = strdupAtoW( szComponent );
411 return ERROR_OUTOFMEMORY;
414 r = MsiGetProductCodeW( szwComponent, szwBuffer );
416 if( ERROR_SUCCESS == r )
417 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
419 msi_free( szwComponent );
424 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
428 WCHAR szSquished[GUID_SIZE];
429 DWORD sz = GUID_SIZE;
430 static const WCHAR szPermKey[] =
431 { '0','0','0','0','0','0','0','0','0','0','0','0',
432 '0','0','0','0','0','0','0','0','0','0','0','0',
433 '0','0','0','0','0','0','0','0',0};
435 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
437 if (NULL == szComponent)
438 return ERROR_INVALID_PARAMETER;
440 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
441 if (rc != ERROR_SUCCESS)
442 return ERROR_UNKNOWN_COMPONENT;
444 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
445 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
448 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
453 if (rc != ERROR_SUCCESS)
454 return ERROR_INSTALL_FAILURE;
456 unsquash_guid(szSquished, szBuffer);
457 return ERROR_SUCCESS;
460 UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
461 awstring *szValue, DWORD *pcchValueBuf)
467 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
468 debugstr_w(szAttribute), szValue, pcchValueBuf);
471 * FIXME: Values seem scattered/duplicated in the registry. Is there a system?
474 if ((szValue && !pcchValueBuf) || !szProduct || !szAttribute)
475 return ERROR_INVALID_PARAMETER;
477 /* check for special properties */
478 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
481 WCHAR packagecode[35];
483 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
484 if (r != ERROR_SUCCESS)
485 return ERROR_UNKNOWN_PRODUCT;
487 regval = msi_reg_get_val_str( hkey, szAttribute );
490 if (unsquash_guid(regval, packagecode))
491 val = strdupW(packagecode);
497 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
499 static const WCHAR one[] = { '1',0 };
501 * FIXME: should be in the Product key (user or system?)
502 * but isn't written yet...
504 val = strdupW( one );
506 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
507 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
509 static const WCHAR fmt[] = { '%','u',0 };
513 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
514 if (r != ERROR_SUCCESS)
515 return ERROR_UNKNOWN_PRODUCT;
517 if (msi_reg_get_val_dword( hkey, szAttribute, ®val))
519 sprintfW(szVal, fmt, regval);
520 val = strdupW( szVal );
525 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
527 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
528 if (r != ERROR_SUCCESS)
529 return ERROR_UNKNOWN_PRODUCT;
531 val = msi_reg_get_val_str( hkey, szAttribute );
537 static const WCHAR szDisplayVersion[] = {
538 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
540 FIXME("%s\n", debugstr_w(szAttribute));
541 /* FIXME: some attribute values not tested... */
543 if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
544 szAttribute = szDisplayVersion;
546 r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
547 if (r != ERROR_SUCCESS)
548 return ERROR_UNKNOWN_PRODUCT;
550 val = msi_reg_get_val_str( hkey, szAttribute );
555 TRACE("returning %s\n", debugstr_w(val));
558 return ERROR_UNKNOWN_PROPERTY;
560 r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
562 HeapFree(GetProcessHeap(), 0, val);
567 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
568 LPSTR szBuffer, DWORD *pcchValueBuf)
570 LPWSTR szwProduct, szwAttribute = NULL;
571 UINT r = ERROR_OUTOFMEMORY;
574 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
575 szBuffer, pcchValueBuf);
577 szwProduct = strdupAtoW( szProduct );
578 if( szProduct && !szwProduct )
581 szwAttribute = strdupAtoW( szAttribute );
582 if( szAttribute && !szwAttribute )
585 buffer.unicode = FALSE;
586 buffer.str.a = szBuffer;
588 r = MSI_GetProductInfo( szwProduct, szwAttribute,
589 &buffer, pcchValueBuf );
592 msi_free( szwProduct );
593 msi_free( szwAttribute );
598 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
599 LPWSTR szBuffer, DWORD *pcchValueBuf)
603 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
604 szBuffer, pcchValueBuf);
606 buffer.unicode = TRUE;
607 buffer.str.w = szBuffer;
609 return MSI_GetProductInfo( szProduct, szAttribute,
610 &buffer, pcchValueBuf );
613 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
615 LPWSTR szwLogFile = NULL;
618 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
622 szwLogFile = strdupAtoW( szLogFile );
624 return ERROR_OUTOFMEMORY;
626 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
627 msi_free( szwLogFile );
631 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
633 HANDLE file = INVALID_HANDLE_VALUE;
635 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
637 lstrcpyW(gszLogFile,szLogFile);
638 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
639 DeleteFileW(szLogFile);
640 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
641 FILE_ATTRIBUTE_NORMAL, NULL);
642 if (file != INVALID_HANDLE_VALUE)
645 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
647 return ERROR_SUCCESS;
650 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
652 LPWSTR szwProduct = NULL;
657 szwProduct = strdupAtoW( szProduct );
659 return ERROR_OUTOFMEMORY;
661 r = MsiQueryProductStateW( szwProduct );
662 msi_free( szwProduct );
666 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
669 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
671 static const WCHAR szWindowsInstaller[] = {
672 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
675 TRACE("%s\n", debugstr_w(szProduct));
678 return INSTALLSTATE_INVALIDARG;
680 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
681 if (rc != ERROR_SUCCESS)
686 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
687 if (rc != ERROR_SUCCESS)
691 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
692 if (rc != ERROR_SUCCESS)
699 rrc = INSTALLSTATE_DEFAULT;
702 FIXME("Unknown install state read from registry (%i)\n",rrc);
703 rrc = INSTALLSTATE_UNKNOWN;
711 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
713 INSTALLUILEVEL old = gUILevel;
714 HWND oldwnd = gUIhwnd;
716 TRACE("%08x %p\n", dwUILevel, phWnd);
718 gUILevel = dwUILevel;
727 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
728 DWORD dwMessageFilter, LPVOID pvContext)
730 INSTALLUI_HANDLERA prev = gUIHandlerA;
732 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
733 gUIHandlerA = puiHandler;
734 gUIFilter = dwMessageFilter;
735 gUIContext = pvContext;
740 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
741 DWORD dwMessageFilter, LPVOID pvContext)
743 INSTALLUI_HANDLERW prev = gUIHandlerW;
745 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
746 gUIHandlerW = puiHandler;
747 gUIFilter = dwMessageFilter;
748 gUIContext = pvContext;
753 /******************************************************************
754 * MsiLoadStringW [MSI.@]
756 * Loads a string from MSI's string resources.
760 * handle [I] only -1 is handled currently
761 * id [I] id of the string to be loaded
762 * lpBuffer [O] buffer for the string to be written to
763 * nBufferMax [I] maximum size of the buffer in characters
764 * lang [I] the preferred language for the string
768 * If successful, this function returns the language id of the string loaded
769 * If the function fails, the function returns zero.
773 * The type of the first parameter is unknown. LoadString's prototype
774 * suggests that it might be a module handle. I have made it an MSI handle
775 * for starters, as -1 is an invalid MSI handle, but not an invalid module
776 * handle. Maybe strings can be stored in an MSI database somehow.
778 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
779 int nBufferMax, LANGID lang )
786 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
789 FIXME("don't know how to deal with handle = %08lx\n", handle);
792 lang = GetUserDefaultLangID();
794 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
798 hResData = LoadResource( msi_hInstance, hres );
801 p = LockResource( hResData );
805 for (i = 0; i < (id&0xf); i++)
809 if( nBufferMax <= len )
812 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
815 TRACE("found -> %s\n", debugstr_w(lpBuffer));
820 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
821 int nBufferMax, LANGID lang )
827 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
828 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
831 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
832 if( len <= nBufferMax )
833 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
834 lpBuffer, nBufferMax, NULL, NULL );
842 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
845 char szProduct[GUID_SIZE];
847 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
849 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
850 return INSTALLSTATE_UNKNOWN;
852 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
855 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
858 WCHAR szProduct[GUID_SIZE];
860 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
862 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
863 return INSTALLSTATE_UNKNOWN;
865 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
868 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
869 WORD wLanguageId, DWORD f)
871 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
872 uType,wLanguageId,f);
873 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
876 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
877 WORD wLanguageId, DWORD f)
879 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
880 uType,wLanguageId,f);
881 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
884 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
885 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
888 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
889 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
891 return ERROR_CALL_NOT_IMPLEMENTED;
894 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
895 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
898 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
899 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
901 return ERROR_CALL_NOT_IMPLEMENTED;
904 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
905 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
907 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
908 return ERROR_CALL_NOT_IMPLEMENTED;
911 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
912 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
914 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
915 return ERROR_CALL_NOT_IMPLEMENTED;
918 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
919 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
922 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
923 ppcCertContext, pbHashData, pcbHashData);
924 return ERROR_CALL_NOT_IMPLEMENTED;
927 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
928 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
931 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
932 ppcCertContext, pbHashData, pcbHashData);
933 return ERROR_CALL_NOT_IMPLEMENTED;
936 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
937 LPSTR szValue, DWORD *pccbValue )
939 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
940 return ERROR_CALL_NOT_IMPLEMENTED;
943 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
944 LPWSTR szValue, DWORD *pccbValue )
946 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
947 return ERROR_CALL_NOT_IMPLEMENTED;
950 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
953 LPWSTR szPack = NULL;
955 TRACE("%s\n", debugstr_a(szPackage) );
959 szPack = strdupAtoW( szPackage );
961 return ERROR_OUTOFMEMORY;
964 r = MsiVerifyPackageW( szPack );
971 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
976 TRACE("%s\n", debugstr_w(szPackage) );
978 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
979 MsiCloseHandle( handle );
984 INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
985 awstring* lpPathBuf, DWORD* pcchBuf)
987 WCHAR squished_pc[GUID_SIZE], squished_comp[GUID_SIZE];
992 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
993 debugstr_w(szComponent), lpPathBuf, pcchBuf);
996 return INSTALLSTATE_INVALIDARG;
997 if( lpPathBuf && !pcchBuf )
998 return INSTALLSTATE_INVALIDARG;
1000 if (!squash_guid( szProduct, squished_pc ) ||
1001 !squash_guid( szComponent, squished_comp ))
1002 return INSTALLSTATE_INVALIDARG;
1004 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1005 if( rc != ERROR_SUCCESS )
1006 return INSTALLSTATE_UNKNOWN;
1010 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1011 if( rc != ERROR_SUCCESS )
1012 return INSTALLSTATE_UNKNOWN;
1014 path = msi_reg_get_val_str( hkey, squished_pc );
1017 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1018 debugstr_w(szProduct), debugstr_w(path));
1021 return INSTALLSTATE_UNKNOWN;
1024 FIXME("Registry entry.. check entry\n");
1026 msi_strcpy_to_awstring( path, lpPathBuf, pcchBuf );
1029 return INSTALLSTATE_LOCAL;
1032 /******************************************************************
1033 * MsiGetComponentPathW [MSI.@]
1035 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1036 LPWSTR lpPathBuf, DWORD* pcchBuf)
1040 path.unicode = TRUE;
1041 path.str.w = lpPathBuf;
1043 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1046 /******************************************************************
1047 * MsiGetComponentPathA [MSI.@]
1049 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1050 LPSTR lpPathBuf, DWORD* pcchBuf)
1052 LPWSTR szwProduct, szwComponent = NULL;
1053 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1056 szwProduct = strdupAtoW( szProduct );
1057 if( szProduct && !szwProduct)
1060 szwComponent = strdupAtoW( szComponent );
1061 if( szComponent && !szwComponent )
1064 path.unicode = FALSE;
1065 path.str.a = lpPathBuf;
1067 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1070 msi_free( szwProduct );
1071 msi_free( szwComponent );
1076 /******************************************************************
1077 * MsiQueryFeatureStateA [MSI.@]
1079 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1081 LPWSTR szwProduct = NULL, szwFeature= NULL;
1082 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1084 szwProduct = strdupAtoW( szProduct );
1085 if ( szProduct && !szwProduct )
1088 szwFeature = strdupAtoW( szFeature );
1089 if ( szFeature && !szwFeature )
1092 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1095 msi_free( szwProduct);
1096 msi_free( szwFeature);
1101 /******************************************************************
1102 * MsiQueryFeatureStateW [MSI.@]
1104 * Checks the state of a feature
1107 * szProduct [I] Product's GUID string
1108 * szFeature [I] Feature's GUID string
1111 * INSTALLSTATE_LOCAL Feature is installed and useable
1112 * INSTALLSTATE_ABSENT Feature is absent
1113 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1114 * INSTALLSTATE_UNKNOWN An error occured
1115 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1118 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1120 WCHAR squishProduct[GUID_SIZE], comp[39];
1122 LPWSTR components, p, parent_feature;
1127 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1129 if (!szProduct || !szFeature)
1130 return INSTALLSTATE_INVALIDARG;
1132 if (!squash_guid( szProduct, squishProduct ))
1133 return INSTALLSTATE_INVALIDARG;
1135 /* check that it's installed at all */
1136 rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
1137 if (rc != ERROR_SUCCESS)
1138 return INSTALLSTATE_UNKNOWN;
1140 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1143 if (!parent_feature)
1144 return INSTALLSTATE_UNKNOWN;
1146 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1147 msi_free(parent_feature);
1148 if (r == INSTALLSTATE_ABSENT)
1151 /* now check if it's complete or advertised */
1152 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1153 if (rc != ERROR_SUCCESS)
1154 return INSTALLSTATE_UNKNOWN;
1156 components = msi_reg_get_val_str( hkey, szFeature );
1159 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1163 ERR("components missing %s %s\n",
1164 debugstr_w(szProduct), debugstr_w(szFeature));
1165 return INSTALLSTATE_UNKNOWN;
1168 r = INSTALLSTATE_LOCAL;
1169 for( p = components; (*p != 2) && (lstrlenW(p) > GUID_SIZE); p += GUID_SIZE)
1171 if (!decode_base85_guid( p, &guid ))
1173 ERR("%s\n", debugstr_w(p));
1176 StringFromGUID2(&guid, comp, 39);
1177 r = MsiGetComponentPathW(szProduct, comp, NULL, 0);
1178 if (r != INSTALLSTATE_LOCAL && r != INSTALLSTATE_SOURCE)
1180 TRACE("component %s state %d\n", debugstr_guid(&guid), r);
1181 r = INSTALLSTATE_ADVERTISED;
1185 if (r == INSTALLSTATE_LOCAL && *p != 2)
1186 ERR("%s -> %s\n", debugstr_w(szFeature), debugstr_w(components));
1188 msi_free(components);
1193 /******************************************************************
1194 * MsiGetFileVersionA [MSI.@]
1196 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1197 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1199 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1200 UINT ret = ERROR_OUTOFMEMORY;
1204 szwFilePath = strdupAtoW( szFilePath );
1209 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1211 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1212 if( !lpwVersionBuff )
1216 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1218 lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1223 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1224 lpwLangBuff, pcchLangBuf);
1226 if( lpwVersionBuff )
1227 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1228 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1230 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1231 lpLangBuf, *pcchLangBuf, NULL, NULL);
1234 msi_free(szwFilePath);
1235 msi_free(lpwVersionBuff);
1236 msi_free(lpwLangBuff);
1241 /******************************************************************
1242 * MsiGetFileVersionW [MSI.@]
1244 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1245 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1247 static WCHAR szVersionResource[] = {'\\',0};
1248 static const WCHAR szVersionFormat[] = {
1249 '%','d','.','%','d','.','%','d','.','%','d',0};
1250 static const WCHAR szLangFormat[] = {'%','d',0};
1253 LPVOID lpVer = NULL;
1254 VS_FIXEDFILEINFO *ffi;
1258 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1259 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1260 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1262 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1264 return GetLastError();
1266 lpVer = msi_alloc(dwVerLen);
1269 ret = ERROR_OUTOFMEMORY;
1273 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1275 ret = GetLastError();
1278 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1280 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1283 wsprintfW(tmp, szVersionFormat,
1284 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1285 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1286 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1287 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1292 *pcchVersionBuf = 0;
1296 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1298 DWORD lang = GetUserDefaultLangID();
1300 FIXME("Retrieve language from file\n");
1301 wsprintfW(tmp, szLangFormat, lang);
1302 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1303 *pcchLangBuf = lstrlenW(lpLangBuf);
1312 /******************************************************************
1315 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1319 case DLL_PROCESS_ATTACH:
1320 msi_hInstance = hinstDLL;
1321 DisableThreadLibraryCalls(hinstDLL);
1322 msi_dialog_register_class();
1324 case DLL_PROCESS_DETACH:
1325 msi_dialog_unregister_class();
1326 /* FIXME: Cleanup */
1332 typedef struct tagIClassFactoryImpl
1334 const IClassFactoryVtbl *lpVtbl;
1335 } IClassFactoryImpl;
1337 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1338 REFIID riid,LPVOID *ppobj)
1340 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1341 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1342 return E_NOINTERFACE;
1345 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1351 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1357 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1358 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1360 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1362 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1366 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1368 TRACE("(%p)->(%d)\n", iface, dolock);
1378 static const IClassFactoryVtbl MsiCF_Vtbl =
1380 MsiCF_QueryInterface,
1383 MsiCF_CreateInstance,
1387 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1389 /******************************************************************
1390 * DllGetClassObject [MSI.@]
1392 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1394 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1396 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1397 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1398 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1399 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1400 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1402 *ppv = (LPVOID) &Msi_CF;
1405 return CLASS_E_CLASSNOTAVAILABLE;
1408 /******************************************************************
1409 * DllGetVersion [MSI.@]
1411 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
1415 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1416 return E_INVALIDARG;
1418 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1419 pdvi->dwMinorVersion = MSI_MINORVERSION;
1420 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1421 pdvi->dwPlatformID = 1;
1426 /******************************************************************
1427 * DllCanUnloadNow [MSI.@]
1429 HRESULT WINAPI DllCanUnloadNow(void)
1431 return dll_count == 0 ? S_OK : S_FALSE;
1434 /***********************************************************************
1435 * MsiGetFeatureUsageW [MSI.@]
1437 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
1438 DWORD* pdwUseCount, WORD* pwDateUsed )
1440 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1441 pdwUseCount, pwDateUsed);
1442 return ERROR_CALL_NOT_IMPLEMENTED;
1445 /***********************************************************************
1446 * MsiGetFeatureUsageA [MSI.@]
1448 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
1449 DWORD* pdwUseCount, WORD* pwDateUsed )
1451 LPWSTR prod = NULL, feat = NULL;
1452 UINT ret = ERROR_OUTOFMEMORY;
1454 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1455 pdwUseCount, pwDateUsed);
1457 prod = strdupAtoW( szProduct );
1458 if (szProduct && !prod)
1461 feat = strdupAtoW( szFeature );
1462 if (szFeature && !feat)
1465 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
1474 /***********************************************************************
1475 * MsiUseFeatureExW [MSI.@]
1477 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
1478 DWORD dwInstallMode, DWORD dwReserved )
1482 TRACE("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1483 dwInstallMode, dwReserved);
1485 state = MsiQueryFeatureStateW( szProduct, szFeature );
1488 return INSTALLSTATE_INVALIDARG;
1490 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
1492 FIXME("mark product %s feature %s as used\n",
1493 debugstr_w(szProduct), debugstr_w(szFeature) );
1499 /***********************************************************************
1500 * MsiUseFeatureExA [MSI.@]
1502 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
1503 DWORD dwInstallMode, DWORD dwReserved )
1505 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
1506 LPWSTR prod = NULL, feat = NULL;
1508 TRACE("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1509 dwInstallMode, dwReserved);
1511 prod = strdupAtoW( szProduct );
1512 if (szProduct && !prod)
1515 feat = strdupAtoW( szFeature );
1516 if (szFeature && !feat)
1519 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
1528 /***********************************************************************
1529 * MsiUseFeatureW [MSI.@]
1531 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
1533 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
1536 /***********************************************************************
1537 * MsiUseFeatureA [MSI.@]
1539 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
1541 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
1544 /***********************************************************************
1545 * MsiProvideQualifiedComponentExW [MSI.@]
1547 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1548 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1549 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1556 WCHAR product[MAX_FEATURE_CHARS+1];
1557 WCHAR component[MAX_FEATURE_CHARS+1];
1558 WCHAR feature[MAX_FEATURE_CHARS+1];
1560 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1561 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1562 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1564 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1565 if (rc != ERROR_SUCCESS)
1566 return ERROR_INDEX_ABSENT;
1569 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
1573 return ERROR_INDEX_ABSENT;
1576 info = msi_alloc(sz);
1577 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
1578 if (rc != ERROR_SUCCESS)
1582 return ERROR_INDEX_ABSENT;
1585 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
1588 rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
1590 rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
1595 if (rc == INSTALLSTATE_LOCAL)
1596 return ERROR_SUCCESS;
1598 return ERROR_FILE_NOT_FOUND;
1601 /***********************************************************************
1602 * MsiProvideQualifiedComponentW [MSI.@]
1604 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1605 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1608 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1609 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1612 /***********************************************************************
1613 * MsiProvideQualifiedComponentA [MSI.@]
1615 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1616 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1619 LPWSTR szwComponent, szwQualifier, lpwPathBuf;
1623 TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
1624 dwInstallMode, lpPathBuf, pcchPathBuf);
1626 szwComponent= strdupAtoW( szComponent);
1627 szwQualifier= strdupAtoW( szQualifier);
1629 lpwPathBuf = msi_alloc(*pcchPathBuf * sizeof(WCHAR));
1631 pcchwPathBuf = *pcchPathBuf;
1633 rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
1634 dwInstallMode, lpwPathBuf, &pcchwPathBuf);
1636 msi_free(szwComponent);
1637 msi_free(szwQualifier);
1639 if (rc == ERROR_SUCCESS)
1640 *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
1641 lpPathBuf, *pcchPathBuf, NULL, NULL);
1643 msi_free(lpwPathBuf);
1647 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1648 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1649 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1653 UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
1655 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1656 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1659 rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1660 if (rc != ERROR_SUCCESS)
1661 return USERINFOSTATE_UNKNOWN;
1665 sz = *lpUserNameBuf * sizeof(WCHAR);
1666 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1667 NULL, (LPBYTE)lpUserNameBuf,
1670 if (!lpUserNameBuf && pcchUserNameBuf)
1673 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1677 if (pcchUserNameBuf)
1678 *pcchUserNameBuf = sz / sizeof(WCHAR);
1682 sz = *pcchOrgNameBuf * sizeof(WCHAR);
1683 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1684 NULL, (LPBYTE)lpOrgNameBuf, &sz);
1686 if (!lpOrgNameBuf && pcchOrgNameBuf)
1689 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1694 *pcchOrgNameBuf = sz / sizeof(WCHAR);
1696 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA &&
1697 rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA)
1700 return USERINFOSTATE_ABSENT;
1705 sz = *pcchSerialBuf * sizeof(WCHAR);
1706 RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL, NULL,
1707 (LPBYTE)lpSerialBuf, &sz);
1709 if (!lpSerialBuf && pcchSerialBuf)
1712 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL,
1716 *pcchSerialBuf = sz / sizeof(WCHAR);
1719 return USERINFOSTATE_PRESENT;
1722 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1723 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1724 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1726 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1727 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1730 return USERINFOSTATE_UNKNOWN;
1733 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1737 MSIPACKAGE *package;
1738 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1740 TRACE("(%s)\n",debugstr_w(szProduct));
1742 rc = MsiOpenProductW(szProduct,&handle);
1743 if (rc != ERROR_SUCCESS)
1744 return ERROR_INVALID_PARAMETER;
1746 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1747 rc = ACTION_PerformUIAction(package, szFirstRun);
1748 msiobj_release( &package->hdr );
1750 MsiCloseHandle(handle);
1755 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1759 MSIPACKAGE *package;
1760 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1762 TRACE("(%s)\n",debugstr_a(szProduct));
1764 rc = MsiOpenProductA(szProduct,&handle);
1765 if (rc != ERROR_SUCCESS)
1766 return ERROR_INVALID_PARAMETER;
1768 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1769 rc = ACTION_PerformUIAction(package, szFirstRun);
1770 msiobj_release( &package->hdr );
1772 MsiCloseHandle(handle);
1777 /***********************************************************************
1778 * MsiConfigureFeatureA [MSI.@]
1780 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
1782 LPWSTR prod, feat = NULL;
1783 UINT r = ERROR_OUTOFMEMORY;
1785 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
1787 prod = strdupAtoW( szProduct );
1788 if (szProduct && !prod)
1791 feat = strdupAtoW( szFeature );
1792 if (szFeature && !feat)
1795 r = MsiConfigureFeatureW(prod, feat, eInstallState);
1804 /***********************************************************************
1805 * MsiConfigureFeatureW [MSI.@]
1807 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
1809 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
1810 return ERROR_SUCCESS;
1813 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1815 WCHAR path[MAX_PATH];
1818 FIXME("Don't know how to handle argument %ld\n", dwReserved);
1819 return ERROR_CALL_NOT_IMPLEMENTED;
1822 if(!GetWindowsDirectoryW(path, MAX_PATH)) {
1823 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1825 return ERROR_CALL_NOT_IMPLEMENTED;
1828 strcatW(path, installerW);
1830 CreateDirectoryW(path, NULL);
1835 /***********************************************************************
1836 * MsiGetShortcutTargetA [MSI.@]
1838 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1839 LPSTR szProductCode, LPSTR szFeatureId,
1840 LPSTR szComponentCode )
1843 const int len = MAX_FEATURE_CHARS+1;
1844 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
1847 target = strdupAtoW( szShortcutTarget );
1848 if (szShortcutTarget && !target )
1849 return ERROR_OUTOFMEMORY;
1853 r = MsiGetShortcutTargetW( target, product, feature, component );
1855 if (r == ERROR_SUCCESS)
1857 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
1858 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
1859 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
1864 /***********************************************************************
1865 * MsiGetShortcutTargetW [MSI.@]
1867 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1868 LPWSTR szProductCode, LPWSTR szFeatureId,
1869 LPWSTR szComponentCode )
1871 IShellLinkDataList *dl = NULL;
1872 IPersistFile *pf = NULL;
1873 LPEXP_DARWIN_LINK darwin = NULL;
1876 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
1877 szProductCode, szFeatureId, szComponentCode );
1879 init = CoInitialize(NULL);
1881 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
1882 &IID_IPersistFile, (LPVOID*) &pf );
1883 if( SUCCEEDED( r ) )
1885 r = IPersistFile_Load( pf, szShortcutTarget,
1886 STGM_READ | STGM_SHARE_DENY_WRITE );
1887 if( SUCCEEDED( r ) )
1889 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
1891 if( SUCCEEDED( r ) )
1893 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
1895 IShellLinkDataList_Release( dl );
1898 IPersistFile_Release( pf );
1901 if (SUCCEEDED(init))
1904 TRACE("darwin = %p\n", darwin);
1911 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
1912 szProductCode, szFeatureId, szComponentCode, &sz );
1913 LocalFree( darwin );
1917 return ERROR_FUNCTION_FAILED;
1920 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1921 DWORD dwReinstallMode )
1923 MSIPACKAGE* package = NULL;
1926 WCHAR sourcepath[MAX_PATH];
1927 WCHAR filename[MAX_PATH];
1928 static const WCHAR szInstalled[] = {
1929 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1930 static const WCHAR fmt[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1931 static const WCHAR REINSTALLMODE[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1932 WCHAR reinstallmode[11];
1936 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1939 ptr = reinstallmode;
1941 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
1943 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
1945 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
1947 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
1949 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
1951 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
1953 if (dwReinstallMode & REINSTALLMODE_USERDATA)
1955 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
1957 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
1959 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1963 sz = sizeof(sourcepath);
1964 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1965 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
1968 sz = sizeof(filename);
1969 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1970 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1972 strcatW(sourcepath,filename);
1974 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1975 r = MSI_OpenPackageW( sourcepath, &package );
1977 r = MSI_OpenProductW( szProduct, &package );
1979 if (r != ERROR_SUCCESS)
1982 MSI_SetPropertyW(package,REINSTALLMODE,reinstallmode);
1984 sz = lstrlenW(szInstalled);
1985 sz += lstrlenW(fmt);
1986 sz += lstrlenW(szFeature);
1988 commandline = msi_alloc(sz * sizeof(WCHAR));
1990 sprintfW(commandline,fmt,szFeature);
1991 lstrcatW(commandline,szInstalled);
1993 r = MSI_InstallPackage( package, sourcepath, commandline );
1995 msiobj_release( &package->hdr );
1997 msi_free(commandline);
2002 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
2003 DWORD dwReinstallMode )
2009 TRACE("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
2012 wszProduct = strdupAtoW(szProduct);
2013 wszFeature = strdupAtoW(szFeature);
2015 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
2017 msi_free(wszProduct);
2018 msi_free(wszFeature);
2022 /***********************************************************************
2023 * MsiEnumPatchesA [MSI.@]
2025 UINT WINAPI MsiEnumPatchesA( LPCSTR szProduct, DWORD iPatchIndex,
2026 LPSTR lpPatchBuf, LPSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
2028 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct),
2029 iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
2030 return ERROR_NO_MORE_ITEMS;
2033 /***********************************************************************
2034 * MsiEnumPatchesW [MSI.@]
2036 UINT WINAPI MsiEnumPatchesW( LPCWSTR szProduct, DWORD iPatchIndex,
2037 LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
2039 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct),
2040 iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
2041 return ERROR_NO_MORE_ITEMS;
2044 /***********************************************************************
2045 * MsiGetFileHashW [MSI.@]
2047 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2048 PMSIFILEHASHINFO pHash )
2050 FIXME("%s %08lx %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2051 return ERROR_CALL_NOT_IMPLEMENTED;
2054 /***********************************************************************
2055 * MsiGetFileHashA [MSI.@]
2057 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2058 PMSIFILEHASHINFO pHash )
2060 FIXME("%s %08lx %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2061 return ERROR_CALL_NOT_IMPLEMENTED;
2064 /***********************************************************************
2065 * MsiAdvertiseScriptW [MSI.@]
2067 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2068 PHKEY phRegData, BOOL fRemoveItems )
2070 FIXME("%s %08lx %p %d\n",
2071 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2072 return ERROR_CALL_NOT_IMPLEMENTED;
2075 /***********************************************************************
2076 * MsiAdvertiseScriptA [MSI.@]
2078 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2079 PHKEY phRegData, BOOL fRemoveItems )
2081 FIXME("%s %08lx %p %d\n",
2082 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2083 return ERROR_CALL_NOT_IMPLEMENTED;