2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004,2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
38 #include "wine/unicode.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi);
44 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
45 * which is a problem because LPCTSTR isn't defined when compiling wine.
46 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
47 * and make sure to only use it in W functions.
49 #define LPCTSTR LPCWSTR
52 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
54 INSTALLUI_HANDLERA gUIHandlerA = NULL;
55 INSTALLUI_HANDLERW gUIHandlerW = NULL;
57 LPVOID gUIContext = NULL;
58 WCHAR gszLogFile[MAX_PATH];
59 HINSTANCE msi_hInstance;
61 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
63 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
66 LPWSTR szwProd = NULL;
68 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
72 szwProd = strdupAtoW( szProduct );
74 return ERROR_OUTOFMEMORY;
77 r = MsiOpenProductW( szwProd, phProduct );
84 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
88 HKEY hKeyProduct = NULL;
91 TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
93 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
94 if( r != ERROR_SUCCESS )
96 r = ERROR_UNKNOWN_PRODUCT;
100 /* find the size of the path */
102 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
103 NULL, &type, NULL, &count );
104 if( r != ERROR_SUCCESS )
106 r = ERROR_UNKNOWN_PRODUCT;
110 /* now alloc and fetch the path of the database to open */
111 path = msi_alloc( count );
115 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
116 NULL, &type, (LPBYTE) path, &count );
117 if( r != ERROR_SUCCESS )
119 r = ERROR_UNKNOWN_PRODUCT;
123 r = MsiOpenPackageW( path, phProduct );
128 RegCloseKey( hKeyProduct );
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 %08lx %08lx\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 %08lx %08lx\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;
203 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
205 r = MSI_OpenPackageW( szPackagePath, &package );
206 if (r != ERROR_SUCCESS)
209 handle = alloc_msihandle( &package->hdr );
211 r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine,
214 MsiCloseHandle(handle);
215 msiobj_release( &package->hdr );
220 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
222 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
223 return ERROR_CALL_NOT_IMPLEMENTED;
226 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
228 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
229 return ERROR_CALL_NOT_IMPLEMENTED;
232 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
233 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
235 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
236 eInstallType, debugstr_a(szCommandLine));
237 return ERROR_CALL_NOT_IMPLEMENTED;
240 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
241 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
243 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
244 eInstallType, debugstr_w(szCommandLine));
245 return ERROR_CALL_NOT_IMPLEMENTED;
248 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
249 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
251 MSIHANDLE handle = -1;
255 WCHAR sourcepath[MAX_PATH];
256 WCHAR filename[MAX_PATH];
257 static const WCHAR szInstalled[] = {
258 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
261 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
262 debugstr_w(szCommandLine));
264 if (eInstallState != INSTALLSTATE_LOCAL &&
265 eInstallState != INSTALLSTATE_DEFAULT)
267 FIXME("Not implemented for anything other than local installs\n");
268 return ERROR_CALL_NOT_IMPLEMENTED;
271 sz = sizeof(sourcepath);
272 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
273 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
276 sz = sizeof(filename);
277 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
278 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
280 strcatW(sourcepath,filename);
283 * ok 1, we need to find the msi file for this product.
284 * 2, find the source dir for the files
285 * 3, do the configure/install.
286 * 4, cleanupany runonce entry.
289 rc = MsiOpenProductW(szProduct,&handle);
290 if (rc != ERROR_SUCCESS)
293 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
296 rc = ERROR_INVALID_HANDLE;
300 sz = lstrlenW(szInstalled);
303 sz += lstrlenW(szCommandLine);
305 commandline = msi_alloc(sz * sizeof(WCHAR));
308 lstrcpyW(commandline,szCommandLine);
312 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
313 lstrcatW(commandline,szInstalled);
315 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath);
317 msiobj_release( &package->hdr );
319 msi_free(commandline);
322 MsiCloseHandle(handle);
327 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
328 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
330 LPWSTR szwProduct = NULL;
331 LPWSTR szwCommandLine = NULL;
332 UINT r = ERROR_OUTOFMEMORY;
336 szwProduct = strdupAtoW( szProduct );
343 szwCommandLine = strdupAtoW( szCommandLine );
348 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
351 msi_free( szwProduct );
352 msi_free( szwCommandLine);
357 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
358 INSTALLSTATE eInstallState)
360 LPWSTR szwProduct = NULL;
363 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
367 szwProduct = strdupAtoW( szProduct );
369 return ERROR_OUTOFMEMORY;
372 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
373 msi_free( szwProduct );
378 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
379 INSTALLSTATE eInstallState)
381 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
383 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
386 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
388 LPWSTR szwComponent = NULL;
390 WCHAR szwBuffer[GUID_SIZE];
392 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
396 szwComponent = strdupAtoW( szComponent );
398 return ERROR_OUTOFMEMORY;
401 r = MsiGetProductCodeW( szwComponent, szwBuffer );
403 if( ERROR_SUCCESS == r )
404 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
406 msi_free( szwComponent );
411 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
415 WCHAR szSquished[GUID_SIZE];
416 DWORD sz = GUID_SIZE;
417 static const WCHAR szPermKey[] =
418 { '0','0','0','0','0','0','0','0','0','0','0','0',
419 '0','0','0','0','0','0','0', '0','0','0','0','0',
420 '0','0','0','0','0','0','0','0',0};
422 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
424 if (NULL == szComponent)
425 return ERROR_INVALID_PARAMETER;
427 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
428 if (rc != ERROR_SUCCESS)
429 return ERROR_UNKNOWN_COMPONENT;
431 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
432 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
435 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
440 if (rc != ERROR_SUCCESS)
441 return ERROR_INSTALL_FAILURE;
443 unsquash_guid(szSquished, szBuffer);
444 return ERROR_SUCCESS;
447 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
448 LPSTR szBuffer, DWORD *pcchValueBuf)
450 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
451 UINT r = ERROR_OUTOFMEMORY;
452 DWORD pcchwValueBuf = 0;
454 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
455 szBuffer, pcchValueBuf);
459 szwProduct = strdupAtoW( szProduct );
466 szwAttribute = strdupAtoW( szAttribute );
473 szwBuffer = msi_alloc( (*pcchValueBuf) * sizeof(WCHAR) );
474 pcchwValueBuf = *pcchValueBuf;
479 r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer,
482 if( ERROR_SUCCESS == r )
484 INT old_len = *pcchValueBuf;
485 *pcchValueBuf = WideCharToMultiByte(CP_ACP, 0, szwBuffer, pcchwValueBuf,
486 szBuffer, *pcchValueBuf, NULL, NULL);
487 if (old_len > *pcchValueBuf)
488 szBuffer[*pcchValueBuf]=0;
492 msi_free( szwProduct );
493 msi_free( szwAttribute );
494 msi_free( szwBuffer );
499 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
500 LPWSTR szBuffer, DWORD *pcchValueBuf)
504 static const WCHAR szProductVersion[] =
505 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
506 static const WCHAR szProductLanguage[] =
507 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
509 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
510 szBuffer, pcchValueBuf);
512 if (NULL != szBuffer && NULL == pcchValueBuf)
513 return ERROR_INVALID_PARAMETER;
514 if (NULL == szProduct || NULL == szAttribute)
515 return ERROR_INVALID_PARAMETER;
517 /* check for special properties */
518 if (strcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW)==0)
521 WCHAR squished[GUID_SIZE];
523 DWORD sz = sizeof(squished);
525 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
526 if (r != ERROR_SUCCESS)
527 return ERROR_UNKNOWN_PRODUCT;
529 r = RegQueryValueExW(hkey, INSTALLPROPERTY_PACKAGECODEW, NULL, NULL,
530 (LPBYTE)squished, &sz);
531 if (r != ERROR_SUCCESS)
534 return ERROR_UNKNOWN_PRODUCT;
537 unsquash_guid(squished, package);
538 *pcchValueBuf = strlenW(package);
539 if (strlenW(package) > *pcchValueBuf)
542 return ERROR_MORE_DATA;
545 strcpyW(szBuffer, package);
550 else if (strcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW)==0)
552 r = MsiOpenProductW(szProduct, &hProduct);
553 if (ERROR_SUCCESS != r)
556 r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf);
557 MsiCloseHandle(hProduct);
559 else if (strcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW)==0)
561 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
571 else if (strcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW)==0)
573 r = MsiOpenProductW(szProduct, &hProduct);
574 if (ERROR_SUCCESS != r)
577 r = MsiGetPropertyW(hProduct, szProductLanguage, szBuffer, pcchValueBuf);
578 MsiCloseHandle(hProduct);
582 r = MsiOpenProductW(szProduct, &hProduct);
583 if (ERROR_SUCCESS != r)
586 r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
587 MsiCloseHandle(hProduct);
593 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
595 LPWSTR szwLogFile = NULL;
598 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
602 szwLogFile = strdupAtoW( szLogFile );
604 return ERROR_OUTOFMEMORY;
606 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
607 msi_free( szwLogFile );
611 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
613 HANDLE file = INVALID_HANDLE_VALUE;
615 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
617 lstrcpyW(gszLogFile,szLogFile);
618 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
619 DeleteFileW(szLogFile);
620 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
621 FILE_ATTRIBUTE_NORMAL, NULL);
622 if (file != INVALID_HANDLE_VALUE)
625 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
627 return ERROR_SUCCESS;
630 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
632 LPWSTR szwProduct = NULL;
637 szwProduct = strdupAtoW( szProduct );
639 return ERROR_OUTOFMEMORY;
641 r = MsiQueryProductStateW( szwProduct );
642 msi_free( szwProduct );
646 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
649 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
651 static const WCHAR szWindowsInstaller[] = {
652 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
655 TRACE("%s\n", debugstr_w(szProduct));
657 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
658 if (rc != ERROR_SUCCESS)
663 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
664 if (rc != ERROR_SUCCESS)
668 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
669 if (rc != ERROR_SUCCESS)
676 rrc = INSTALLSTATE_DEFAULT;
679 FIXME("Unknown install state read from registry (%i)\n",rrc);
680 rrc = INSTALLSTATE_UNKNOWN;
688 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
690 INSTALLUILEVEL old = gUILevel;
691 HWND oldwnd = gUIhwnd;
693 TRACE("%08x %p\n", dwUILevel, phWnd);
695 gUILevel = dwUILevel;
704 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
705 DWORD dwMessageFilter, LPVOID pvContext)
707 INSTALLUI_HANDLERA prev = gUIHandlerA;
709 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
710 gUIHandlerA = puiHandler;
711 gUIFilter = dwMessageFilter;
712 gUIContext = pvContext;
717 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
718 DWORD dwMessageFilter, LPVOID pvContext)
720 INSTALLUI_HANDLERW prev = gUIHandlerW;
722 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
723 gUIHandlerW = puiHandler;
724 gUIFilter = dwMessageFilter;
725 gUIContext = pvContext;
730 /******************************************************************
731 * MsiLoadStringW [MSI.@]
733 * Loads a string from MSI's string resources.
737 * handle [I] only -1 is handled currently
738 * id [I] id of the string to be loaded
739 * lpBuffer [O] buffer for the string to be written to
740 * nBufferMax [I] maximum size of the buffer in characters
741 * lang [I] the preferred language for the string
745 * If successful, this function returns the language id of the string loaded
746 * If the function fails, the function returns zero.
750 * The type of the first parameter is unknown. LoadString's prototype
751 * suggests that it might be a module handle. I have made it an MSI handle
752 * for starters, as -1 is an invalid MSI handle, but not an invalid module
753 * handle. Maybe strings can be stored in an MSI database somehow.
755 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
756 int nBufferMax, LANGID lang )
763 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
766 FIXME("don't know how to deal with handle = %08lx\n", handle);
769 lang = GetUserDefaultLangID();
771 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
775 hResData = LoadResource( msi_hInstance, hres );
778 p = LockResource( hResData );
782 for (i = 0; i < (id&0xf); i++)
786 if( nBufferMax <= len )
789 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
792 TRACE("found -> %s\n", debugstr_w(lpBuffer));
797 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
798 int nBufferMax, LANGID lang )
804 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
805 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
808 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
809 if( len <= nBufferMax )
810 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
811 lpBuffer, nBufferMax, NULL, NULL );
819 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
822 FIXME("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
823 return INSTALLSTATE_UNKNOWN;
826 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
829 FIXME("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
830 return INSTALLSTATE_UNKNOWN;
833 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
834 WORD wLanguageId, DWORD f)
836 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
837 uType,wLanguageId,f);
838 return ERROR_CALL_NOT_IMPLEMENTED;
841 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
842 WORD wLanguageId, DWORD f)
844 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
845 uType,wLanguageId,f);
846 return ERROR_CALL_NOT_IMPLEMENTED;
849 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
850 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
853 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
854 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
856 return ERROR_CALL_NOT_IMPLEMENTED;
859 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
860 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
863 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
864 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
866 return ERROR_CALL_NOT_IMPLEMENTED;
869 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
870 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
872 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
873 return ERROR_CALL_NOT_IMPLEMENTED;
876 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
877 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
879 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
880 return ERROR_CALL_NOT_IMPLEMENTED;
883 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
884 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
887 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
888 ppcCertContext, pbHashData, pcbHashData);
889 return ERROR_CALL_NOT_IMPLEMENTED;
892 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
893 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
896 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
897 ppcCertContext, pbHashData, pcbHashData);
898 return ERROR_CALL_NOT_IMPLEMENTED;
901 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
902 LPSTR szValue, DWORD *pccbValue )
904 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
905 return ERROR_CALL_NOT_IMPLEMENTED;
908 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
909 LPWSTR szValue, DWORD *pccbValue )
911 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
912 return ERROR_CALL_NOT_IMPLEMENTED;
915 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
918 LPWSTR szPack = NULL;
920 TRACE("%s\n", debugstr_a(szPackage) );
924 szPack = strdupAtoW( szPackage );
926 return ERROR_OUTOFMEMORY;
929 r = MsiVerifyPackageW( szPack );
936 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
941 TRACE("%s\n", debugstr_w(szPackage) );
943 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
944 MsiCloseHandle( handle );
949 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
950 LPSTR lpPathBuf, DWORD* pcchBuf)
952 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
958 szwProduct = strdupAtoW( szProduct );
960 return ERROR_OUTOFMEMORY;
965 szwComponent = strdupAtoW( szComponent );
968 msi_free( szwProduct);
969 return ERROR_OUTOFMEMORY;
973 if( pcchBuf && *pcchBuf > 0 )
975 lpwPathBuf = msi_alloc( *pcchBuf * sizeof(WCHAR));
976 incoming_len = *pcchBuf;
984 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
986 msi_free( szwProduct);
987 msi_free( szwComponent);
990 if (rc != INSTALLSTATE_UNKNOWN)
991 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
992 lpPathBuf, incoming_len, NULL, NULL);
993 msi_free( lpwPathBuf);
999 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1000 LPWSTR lpPathBuf, DWORD* pcchBuf)
1002 WCHAR squished_pc[GUID_SIZE];
1004 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
1009 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1010 debugstr_w(szComponent), lpPathBuf, pcchBuf);
1012 if( lpPathBuf && !pcchBuf )
1013 return INSTALLSTATE_INVALIDARG;
1015 squash_guid(szProduct,squished_pc);
1017 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1018 if( rc != ERROR_SUCCESS )
1023 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1024 if( rc != ERROR_SUCCESS )
1029 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
1030 if( rc != ERROR_SUCCESS )
1032 if( type != REG_SZ )
1035 sz += sizeof(WCHAR);
1036 path = msi_alloc( sz );
1040 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
1041 if( rc != ERROR_SUCCESS )
1044 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1045 debugstr_w(szProduct), debugstr_w(path));
1049 FIXME("Registry entry.. check entry\n");
1050 rrc = INSTALLSTATE_LOCAL;
1054 /* PROBABLY a file */
1055 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
1056 rrc = INSTALLSTATE_LOCAL;
1058 rrc = INSTALLSTATE_ABSENT;
1063 sz = sz / sizeof(WCHAR);
1064 if( *pcchBuf >= sz )
1065 lstrcpyW( lpPathBuf, path );
1075 /******************************************************************
1076 * MsiQueryFeatureStateA [MSI.@]
1078 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1081 LPWSTR szwProduct= NULL;
1082 LPWSTR szwFeature= NULL;
1086 szwProduct = strdupAtoW( szProduct );
1088 return ERROR_OUTOFMEMORY;
1093 szwFeature = strdupAtoW( szFeature );
1096 msi_free( szwProduct);
1097 return ERROR_OUTOFMEMORY;
1101 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1103 msi_free( szwProduct);
1104 msi_free( szwFeature);
1109 /******************************************************************
1110 * MsiQueryFeatureStateW [MSI.@]
1112 * This does not verify that the Feature is functional. So i am only going to
1113 * check the existence of the key in the registry. This should tell me if it is
1116 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1122 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1124 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1125 if (rc != ERROR_SUCCESS)
1126 return INSTALLSTATE_UNKNOWN;
1128 rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz);
1131 if (rc == ERROR_SUCCESS)
1132 return INSTALLSTATE_LOCAL;
1134 return INSTALLSTATE_ABSENT;
1137 /******************************************************************
1138 * MsiGetFileVersionA [MSI.@]
1140 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1141 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1143 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1144 UINT ret = ERROR_OUTOFMEMORY;
1148 szwFilePath = strdupAtoW( szFilePath );
1153 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1155 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1156 if( !lpwVersionBuff )
1160 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1162 lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1167 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1168 lpwLangBuff, pcchLangBuf);
1170 if( lpwVersionBuff )
1171 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1172 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1174 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1175 lpLangBuf, *pcchLangBuf, NULL, NULL);
1178 msi_free(szwFilePath);
1179 msi_free(lpwVersionBuff);
1180 msi_free(lpwLangBuff);
1185 /******************************************************************
1186 * MsiGetFileVersionW [MSI.@]
1188 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1189 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1191 static const WCHAR szVersionResource[] = {'\\',0};
1192 static const WCHAR szVersionFormat[] = {
1193 '%','d','.','%','d','.','%','d','.','%','d',0};
1194 static const WCHAR szLangFormat[] = {'%','d',0};
1197 LPVOID lpVer = NULL;
1198 VS_FIXEDFILEINFO *ffi;
1202 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1203 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1204 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1206 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1208 return GetLastError();
1210 lpVer = msi_alloc(dwVerLen);
1213 ret = ERROR_OUTOFMEMORY;
1217 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1219 ret = GetLastError();
1222 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1224 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1227 wsprintfW(tmp, szVersionFormat,
1228 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1229 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1230 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1231 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1236 *pcchVersionBuf = 0;
1240 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1242 DWORD lang = GetUserDefaultLangID();
1244 FIXME("Retrieve language from file\n");
1245 wsprintfW(tmp, szLangFormat, lang);
1246 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1247 *pcchLangBuf = lstrlenW(lpLangBuf);
1256 /******************************************************************
1259 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1263 case DLL_PROCESS_ATTACH:
1264 msi_hInstance = hinstDLL;
1265 DisableThreadLibraryCalls(hinstDLL);
1266 msi_dialog_register_class();
1268 case DLL_PROCESS_DETACH:
1269 msi_dialog_unregister_class();
1270 /* FIXME: Cleanup */
1276 typedef struct tagIClassFactoryImpl
1278 const IClassFactoryVtbl *lpVtbl;
1279 } IClassFactoryImpl;
1281 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1282 REFIID riid,LPVOID *ppobj)
1284 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1285 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1286 return E_NOINTERFACE;
1289 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1294 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1299 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1300 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1302 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1304 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1308 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1310 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1312 FIXME("%p %d\n", This, dolock);
1316 static const IClassFactoryVtbl MsiCF_Vtbl =
1318 MsiCF_QueryInterface,
1321 MsiCF_CreateInstance,
1325 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1327 /******************************************************************
1328 * DllGetClassObject [MSI.@]
1330 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1332 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1334 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1335 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1336 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1337 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1338 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1340 *ppv = (LPVOID) &Msi_CF;
1343 return CLASS_E_CLASSNOTAVAILABLE;
1346 /******************************************************************
1347 * DllGetVersion [MSI.@]
1349 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
1353 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1354 return E_INVALIDARG;
1356 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1357 pdvi->dwMinorVersion = MSI_MINORVERSION;
1358 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1359 pdvi->dwPlatformID = 1;
1364 /******************************************************************
1365 * DllCanUnloadNow [MSI.@]
1367 HRESULT WINAPI DllCanUnloadNow(void)
1372 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1373 DWORD* pdwUseCount, WORD* pwDateUsed)
1375 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1376 pdwUseCount, pwDateUsed);
1377 return ERROR_CALL_NOT_IMPLEMENTED;
1380 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1381 DWORD* pdwUseCount, WORD* pwDateUsed)
1383 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1384 pdwUseCount, pwDateUsed);
1385 return ERROR_CALL_NOT_IMPLEMENTED;
1388 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1389 DWORD dwInstallMode, DWORD dwReserved)
1391 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1392 dwInstallMode, dwReserved);
1395 * Polls all the components of the feature to find install state and then
1397 * Software\\Microsoft\\Windows\\CurrentVersion\\
1398 * Installer\\Products\\<squishguid>\\<feature>
1399 * "Usage"=dword:........
1402 return INSTALLSTATE_LOCAL;
1405 /***********************************************************************
1406 * MsiUseFeatureExA [MSI.@]
1408 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1409 DWORD dwInstallMode, DWORD dwReserved)
1411 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1412 dwInstallMode, dwReserved);
1414 return INSTALLSTATE_LOCAL;
1417 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1419 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1421 return INSTALLSTATE_LOCAL;
1424 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1426 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1428 return INSTALLSTATE_LOCAL;
1431 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1432 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1433 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1440 LPWSTR product = NULL;
1441 LPWSTR component = NULL;
1445 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1446 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1447 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1449 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1450 if (rc != ERROR_SUCCESS)
1451 return ERROR_INDEX_ABSENT;
1454 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
1458 return ERROR_INDEX_ABSENT;
1461 info = msi_alloc(sz);
1462 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
1463 if (rc != ERROR_SUCCESS)
1467 return ERROR_INDEX_ABSENT;
1470 /* find the component */
1471 ptr = strchrW(&info[20],'>');
1478 return ERROR_INDEX_ABSENT;
1483 decode_base85_guid(info,&clsid);
1484 StringFromCLSID(&clsid, &product);
1486 decode_base85_guid(ptr,&clsid);
1487 StringFromCLSID(&clsid, &component);
1490 rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
1492 rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
1497 msi_free(component);
1499 if (rc == INSTALLSTATE_LOCAL)
1500 return ERROR_SUCCESS;
1502 return ERROR_FILE_NOT_FOUND;
1505 /***********************************************************************
1506 * MsiProvideQualifiedComponentW [MSI.@]
1508 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1509 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1512 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1513 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1516 /***********************************************************************
1517 * MsiProvideQualifiedComponentA [MSI.@]
1519 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1520 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1523 LPWSTR szwComponent, szwQualifier, lpwPathBuf;
1527 TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
1528 dwInstallMode, lpPathBuf, pcchPathBuf);
1530 szwComponent= strdupAtoW( szComponent);
1531 szwQualifier= strdupAtoW( szQualifier);
1533 lpwPathBuf = msi_alloc(*pcchPathBuf * sizeof(WCHAR));
1535 pcchwPathBuf = *pcchPathBuf;
1537 rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
1538 dwInstallMode, lpwPathBuf, &pcchwPathBuf);
1540 msi_free(szwComponent);
1541 msi_free(szwQualifier);
1542 *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
1543 lpPathBuf, *pcchPathBuf, NULL, NULL);
1545 msi_free(lpwPathBuf);
1549 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1550 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1551 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1555 UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
1557 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1558 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1561 rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1562 if (rc != ERROR_SUCCESS)
1563 return USERINFOSTATE_UNKNOWN;
1567 sz = *lpUserNameBuf * sizeof(WCHAR);
1568 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1569 NULL, (LPBYTE)lpUserNameBuf,
1572 if (!lpUserNameBuf && pcchUserNameBuf)
1575 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1579 if (pcchUserNameBuf)
1580 *pcchUserNameBuf = sz / sizeof(WCHAR);
1584 sz = *pcchOrgNameBuf * sizeof(WCHAR);
1585 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1586 NULL, (LPBYTE)lpOrgNameBuf, &sz);
1588 if (!lpOrgNameBuf && pcchOrgNameBuf)
1591 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1596 *pcchOrgNameBuf = sz / sizeof(WCHAR);
1598 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA &&
1599 rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA)
1602 return USERINFOSTATE_ABSENT;
1607 sz = *pcchSerialBuf * sizeof(WCHAR);
1608 RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL, NULL,
1609 (LPBYTE)lpSerialBuf, &sz);
1611 if (!lpSerialBuf && pcchSerialBuf)
1614 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL,
1618 *pcchSerialBuf = sz / sizeof(WCHAR);
1621 return USERINFOSTATE_PRESENT;
1624 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1625 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1626 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1628 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1629 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1632 return USERINFOSTATE_UNKNOWN;
1635 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1639 MSIPACKAGE *package;
1640 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1642 TRACE("(%s)\n",debugstr_w(szProduct));
1644 rc = MsiOpenProductW(szProduct,&handle);
1645 if (rc != ERROR_SUCCESS)
1646 return ERROR_INVALID_PARAMETER;
1648 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1649 rc = ACTION_PerformUIAction(package, szFirstRun);
1650 msiobj_release( &package->hdr );
1652 MsiCloseHandle(handle);
1657 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1661 MSIPACKAGE *package;
1662 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1664 TRACE("(%s)\n",debugstr_a(szProduct));
1666 rc = MsiOpenProductA(szProduct,&handle);
1667 if (rc != ERROR_SUCCESS)
1668 return ERROR_INVALID_PARAMETER;
1670 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1671 rc = ACTION_PerformUIAction(package, szFirstRun);
1672 msiobj_release( &package->hdr );
1674 MsiCloseHandle(handle);
1679 /***********************************************************************
1680 * MsiConfigureFeatureA [MSI.@]
1682 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
1684 FIXME("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
1685 return ERROR_SUCCESS;
1688 /***********************************************************************
1689 * MsiConfigureFeatureW [MSI.@]
1691 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
1693 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
1694 return ERROR_SUCCESS;
1697 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1699 WCHAR path[MAX_PATH];
1702 FIXME("Don't know how to handle argument %ld\n", dwReserved);
1703 return ERROR_CALL_NOT_IMPLEMENTED;
1706 if(!GetWindowsDirectoryW(path, MAX_PATH)) {
1707 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1709 return ERROR_CALL_NOT_IMPLEMENTED;
1712 strcatW(path, installerW);
1714 CreateDirectoryW(path, NULL);
1719 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1720 LPSTR szProductCode, LPSTR szFeatureId,
1721 LPSTR szComponentCode )
1724 const int len = MAX_FEATURE_CHARS+1;
1725 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
1728 target = strdupAtoW( szShortcutTarget );
1729 if (szShortcutTarget && !target )
1730 return ERROR_OUTOFMEMORY;
1734 r = MsiGetShortcutTargetW( target, product, feature, component );
1736 if (r == ERROR_SUCCESS)
1738 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
1739 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
1740 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
1745 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1746 LPWSTR szProductCode, LPWSTR szFeatureId,
1747 LPWSTR szComponentCode )
1749 FIXME("%s\n", debugstr_w(szShortcutTarget));
1750 return ERROR_CALL_NOT_IMPLEMENTED;
1753 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1754 DWORD dwReinstallMode )
1756 MSIHANDLE handle = -1;
1757 MSIPACKAGE* package;
1760 WCHAR sourcepath[MAX_PATH];
1761 WCHAR filename[MAX_PATH];
1762 static const WCHAR szInstalled[] = {
1763 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1764 static const WCHAR fmt[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1765 static const WCHAR REINSTALLMODE[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1766 WCHAR reinstallmode[11];
1770 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1773 memset(reinstallmode,0,sizeof(reinstallmode));
1774 ptr = reinstallmode;
1776 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
1777 { *ptr = 'p'; ptr++; }
1778 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
1779 { *ptr = 'o'; ptr++; }
1780 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
1781 { *ptr = 'w'; ptr++; }
1782 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
1783 { *ptr = 'd'; ptr++; }
1784 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
1785 { *ptr = 'c'; ptr++; }
1786 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
1787 { *ptr = 'a'; ptr++; }
1788 if (dwReinstallMode & REINSTALLMODE_USERDATA)
1789 { *ptr = 'u'; ptr++; }
1790 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
1791 { *ptr = 'm'; ptr++; }
1792 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
1793 { *ptr = 's'; ptr++; }
1794 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1795 { *ptr = 'v'; ptr++; }
1797 sz = sizeof(sourcepath);
1798 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1799 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
1802 sz = sizeof(filename);
1803 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1804 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1806 strcatW(sourcepath,filename);
1808 if (!(dwReinstallMode & REINSTALLMODE_PACKAGE))
1809 rc = MsiOpenProductW(szProduct,&handle);
1811 rc = MsiOpenPackageW(sourcepath,&handle);
1813 if (rc != ERROR_SUCCESS)
1816 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1819 rc = ERROR_INVALID_HANDLE;
1823 MSI_SetPropertyW(package,REINSTALLMODE,reinstallmode);
1825 sz = lstrlenW(szInstalled);
1826 sz += lstrlenW(fmt);
1827 sz += lstrlenW(szFeature);
1829 commandline = msi_alloc(sz * sizeof(WCHAR));
1831 sprintfW(commandline,fmt,szFeature);
1832 lstrcatW(commandline,szInstalled);
1834 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath);
1836 msiobj_release( &package->hdr );
1838 msi_free(commandline);
1841 MsiCloseHandle(handle);
1846 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1847 DWORD dwReinstallMode )
1853 TRACE("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1856 wszProduct = strdupAtoW(szProduct);
1857 wszFeature = strdupAtoW(szFeature);
1859 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
1861 msi_free(wszProduct);
1862 msi_free(wszFeature);
1866 /***********************************************************************
1867 * MsiEnumPatchesA [MSI.@]
1869 UINT WINAPI MsiEnumPatchesA( LPCSTR szProduct, DWORD iPatchIndex,
1870 LPSTR lpPatchBuf, LPSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
1872 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct),
1873 iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
1874 return ERROR_NO_MORE_ITEMS;
1877 /***********************************************************************
1878 * MsiEnumPatchesW [MSI.@]
1880 UINT WINAPI MsiEnumPatchesW( LPCWSTR szProduct, DWORD iPatchIndex,
1881 LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
1883 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct),
1884 iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
1885 return ERROR_NO_MORE_ITEMS;