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 );
79 HeapFree( GetProcessHeap(), 0, szwProd );
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 = HeapAlloc( GetProcessHeap(), 0, 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 );
126 HeapFree( GetProcessHeap(), 0, path );
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 );
191 HeapFree( GetProcessHeap(), 0, szwPath );
192 HeapFree( GetProcessHeap(), 0, szwCommand );
197 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
199 MSIPACKAGE *package = NULL;
202 WCHAR path[MAX_PATH];
203 WCHAR filename[MAX_PATH];
204 static const WCHAR szMSI[] = {'M','S','I',0};
206 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
208 r = MsiVerifyPackageW(szPackagePath);
209 if (r != ERROR_SUCCESS)
212 /* copy the msi file to a temp file to pervent locking a CD
213 * with a multi disc install
215 GetTempPathW(MAX_PATH, path);
216 GetTempFileNameW(path, szMSI, 0, filename);
218 CopyFileW(szPackagePath, filename, FALSE);
220 TRACE("Opening relocated package %s\n",debugstr_w(filename));
221 r = MSI_OpenPackageW(filename, &package);
222 if (r != ERROR_SUCCESS)
224 DeleteFileW(filename);
228 handle = alloc_msihandle( &package->hdr );
230 r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine,
233 MsiCloseHandle(handle);
234 msiobj_release( &package->hdr );
236 DeleteFileW(filename);
240 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
242 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
243 return ERROR_CALL_NOT_IMPLEMENTED;
246 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
248 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
249 return ERROR_CALL_NOT_IMPLEMENTED;
252 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
253 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
255 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
256 eInstallType, debugstr_a(szCommandLine));
257 return ERROR_CALL_NOT_IMPLEMENTED;
260 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
261 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
263 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
264 eInstallType, debugstr_w(szCommandLine));
265 return ERROR_CALL_NOT_IMPLEMENTED;
268 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
269 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
271 MSIHANDLE handle = -1;
275 WCHAR sourcepath[MAX_PATH];
276 WCHAR filename[MAX_PATH];
277 static const WCHAR szInstalled[] = {
278 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
281 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
282 debugstr_w(szCommandLine));
284 if (eInstallState != INSTALLSTATE_LOCAL &&
285 eInstallState != INSTALLSTATE_DEFAULT)
287 FIXME("Not implemented for anything other than local installs\n");
288 return ERROR_CALL_NOT_IMPLEMENTED;
291 sz = sizeof(sourcepath);
292 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
293 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
296 sz = sizeof(filename);
297 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
298 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
300 strcatW(sourcepath,filename);
303 * ok 1, we need to find the msi file for this product.
304 * 2, find the source dir for the files
305 * 3, do the configure/install.
306 * 4, cleanupany runonce entry.
309 rc = MsiOpenProductW(szProduct,&handle);
310 if (rc != ERROR_SUCCESS)
313 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
316 rc = ERROR_INVALID_HANDLE;
320 sz = lstrlenW(szInstalled);
323 sz += lstrlenW(szCommandLine);
325 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
328 lstrcpyW(commandline,szCommandLine);
332 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
333 lstrcatW(commandline,szInstalled);
335 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath);
337 msiobj_release( &package->hdr );
339 HeapFree(GetProcessHeap(),0,commandline);
342 MsiCloseHandle(handle);
347 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
348 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
350 LPWSTR szwProduct = NULL;
351 LPWSTR szwCommandLine = NULL;
352 UINT r = ERROR_OUTOFMEMORY;
356 szwProduct = strdupAtoW( szProduct );
363 szwCommandLine = strdupAtoW( szCommandLine );
368 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
371 HeapFree( GetProcessHeap(), 0, szwProduct );
372 HeapFree( GetProcessHeap(), 0, szwCommandLine);
377 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
378 INSTALLSTATE eInstallState)
380 LPWSTR szwProduct = NULL;
383 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
387 szwProduct = strdupAtoW( szProduct );
389 return ERROR_OUTOFMEMORY;
392 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
393 HeapFree( GetProcessHeap(), 0, szwProduct );
398 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
399 INSTALLSTATE eInstallState)
401 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
403 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
406 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
408 LPWSTR szwComponent = NULL;
410 WCHAR szwBuffer[GUID_SIZE];
412 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
416 szwComponent = strdupAtoW( szComponent );
418 return ERROR_OUTOFMEMORY;
421 r = MsiGetProductCodeW( szwComponent, szwBuffer );
423 if( ERROR_SUCCESS == r )
424 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
426 HeapFree( GetProcessHeap(), 0, szwComponent );
431 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
435 WCHAR szSquished[GUID_SIZE];
436 DWORD sz = GUID_SIZE;
437 static const WCHAR szPermKey[] =
438 { '0','0','0','0','0','0','0','0','0','0','0','0',
439 '0','0','0','0','0','0','0', '0','0','0','0','0',
440 '0','0','0','0','0','0','0','0',0};
442 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
444 if (NULL == szComponent)
445 return ERROR_INVALID_PARAMETER;
447 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
448 if (rc != ERROR_SUCCESS)
449 return ERROR_UNKNOWN_COMPONENT;
451 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
452 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
455 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
460 if (rc != ERROR_SUCCESS)
461 return ERROR_INSTALL_FAILURE;
463 unsquash_guid(szSquished, szBuffer);
464 return ERROR_SUCCESS;
467 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
468 LPSTR szBuffer, DWORD *pcchValueBuf)
470 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
471 UINT r = ERROR_OUTOFMEMORY;
472 DWORD pcchwValueBuf = 0;
474 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
475 szBuffer, pcchValueBuf);
479 szwProduct = strdupAtoW( szProduct );
486 szwAttribute = strdupAtoW( szAttribute );
493 szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
494 pcchwValueBuf = *pcchValueBuf;
499 r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer,
502 if( ERROR_SUCCESS == r )
504 INT old_len = *pcchValueBuf;
505 *pcchValueBuf = WideCharToMultiByte(CP_ACP, 0, szwBuffer, pcchwValueBuf,
506 szBuffer, *pcchValueBuf, NULL, NULL);
507 if (old_len > *pcchValueBuf)
508 szBuffer[*pcchValueBuf]=0;
512 HeapFree( GetProcessHeap(), 0, szwProduct );
513 HeapFree( GetProcessHeap(), 0, szwAttribute );
514 HeapFree( GetProcessHeap(), 0, szwBuffer );
519 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
520 LPWSTR szBuffer, DWORD *pcchValueBuf)
524 static const WCHAR szProductVersion[] =
525 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
526 static const WCHAR szProductLanguage[] =
527 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
529 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
530 szBuffer, pcchValueBuf);
532 if (NULL != szBuffer && NULL == pcchValueBuf)
533 return ERROR_INVALID_PARAMETER;
534 if (NULL == szProduct || NULL == szAttribute)
535 return ERROR_INVALID_PARAMETER;
537 /* check for special properties */
538 if (strcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW)==0)
541 WCHAR squished[GUID_SIZE];
543 DWORD sz = sizeof(squished);
545 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
546 if (r != ERROR_SUCCESS)
547 return ERROR_UNKNOWN_PRODUCT;
549 r = RegQueryValueExW(hkey, INSTALLPROPERTY_PACKAGECODEW, NULL, NULL,
550 (LPBYTE)squished, &sz);
551 if (r != ERROR_SUCCESS)
554 return ERROR_UNKNOWN_PRODUCT;
557 unsquash_guid(squished, package);
558 *pcchValueBuf = strlenW(package);
559 if (strlenW(package) > *pcchValueBuf)
562 return ERROR_MORE_DATA;
565 strcpyW(szBuffer, package);
570 else if (strcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW)==0)
572 r = MsiOpenProductW(szProduct, &hProduct);
573 if (ERROR_SUCCESS != r)
576 r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf);
577 MsiCloseHandle(hProduct);
579 else if (strcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW)==0)
581 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
591 else if (strcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW)==0)
593 r = MsiOpenProductW(szProduct, &hProduct);
594 if (ERROR_SUCCESS != r)
597 r = MsiGetPropertyW(hProduct, szProductLanguage, szBuffer, pcchValueBuf);
598 MsiCloseHandle(hProduct);
602 r = MsiOpenProductW(szProduct, &hProduct);
603 if (ERROR_SUCCESS != r)
606 r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
607 MsiCloseHandle(hProduct);
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 HeapFree( GetProcessHeap(), 0, 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 HeapFree( GetProcessHeap(), 0, 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));
677 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
678 if (rc != ERROR_SUCCESS)
683 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
684 if (rc != ERROR_SUCCESS)
688 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
689 if (rc != ERROR_SUCCESS)
696 rrc = INSTALLSTATE_DEFAULT;
699 FIXME("Unknown install state read from registry (%i)\n",rrc);
700 rrc = INSTALLSTATE_UNKNOWN;
708 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
710 INSTALLUILEVEL old = gUILevel;
711 HWND oldwnd = gUIhwnd;
713 TRACE("%08x %p\n", dwUILevel, phWnd);
715 gUILevel = dwUILevel;
724 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
725 DWORD dwMessageFilter, LPVOID pvContext)
727 INSTALLUI_HANDLERA prev = gUIHandlerA;
729 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
730 gUIHandlerA = puiHandler;
731 gUIFilter = dwMessageFilter;
732 gUIContext = pvContext;
737 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
738 DWORD dwMessageFilter, LPVOID pvContext)
740 INSTALLUI_HANDLERW prev = gUIHandlerW;
742 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
743 gUIHandlerW = puiHandler;
744 gUIFilter = dwMessageFilter;
745 gUIContext = pvContext;
750 /******************************************************************
751 * MsiLoadStringW [MSI.@]
753 * Loads a string from MSI's string resources.
757 * handle [I] only -1 is handled currently
758 * id [I] id of the string to be loaded
759 * lpBuffer [O] buffer for the string to be written to
760 * nBufferMax [I] maximum size of the buffer in characters
761 * lang [I] the preferred language for the string
765 * If successful, this function returns the language id of the string loaded
766 * If the function fails, the function returns zero.
770 * The type of the first parameter is unknown. LoadString's prototype
771 * suggests that it might be a module handle. I have made it an MSI handle
772 * for starters, as -1 is an invalid MSI handle, but not an invalid module
773 * handle. Maybe strings can be stored in an MSI database somehow.
775 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
776 int nBufferMax, LANGID lang )
783 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
786 FIXME("don't know how to deal with handle = %08lx\n", handle);
789 lang = GetUserDefaultLangID();
791 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
795 hResData = LoadResource( msi_hInstance, hres );
798 p = LockResource( hResData );
802 for (i = 0; i < (id&0xf); i++)
806 if( nBufferMax <= len )
809 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
812 TRACE("found -> %s\n", debugstr_w(lpBuffer));
817 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
818 int nBufferMax, LANGID lang )
824 bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
825 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
828 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
829 if( len <= nBufferMax )
830 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
831 lpBuffer, nBufferMax, NULL, NULL );
835 HeapFree(GetProcessHeap(), 0, bufW);
839 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
842 FIXME("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
843 return INSTALLSTATE_UNKNOWN;
846 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
849 FIXME("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
850 return INSTALLSTATE_UNKNOWN;
853 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
854 WORD wLanguageId, DWORD f)
856 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
857 uType,wLanguageId,f);
858 return ERROR_CALL_NOT_IMPLEMENTED;
861 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
862 WORD wLanguageId, DWORD f)
864 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
865 uType,wLanguageId,f);
866 return ERROR_CALL_NOT_IMPLEMENTED;
869 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
870 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
873 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
874 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
876 return ERROR_CALL_NOT_IMPLEMENTED;
879 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
880 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
883 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
884 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
886 return ERROR_CALL_NOT_IMPLEMENTED;
889 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
890 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
892 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
893 return ERROR_CALL_NOT_IMPLEMENTED;
896 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
897 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
899 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
900 return ERROR_CALL_NOT_IMPLEMENTED;
903 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
904 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
907 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
908 ppcCertContext, pbHashData, pcbHashData);
909 return ERROR_CALL_NOT_IMPLEMENTED;
912 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
913 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
916 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
917 ppcCertContext, pbHashData, pcbHashData);
918 return ERROR_CALL_NOT_IMPLEMENTED;
921 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
922 LPSTR szValue, DWORD *pccbValue )
924 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
925 return ERROR_CALL_NOT_IMPLEMENTED;
928 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
929 LPWSTR szValue, DWORD *pccbValue )
931 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
932 return ERROR_CALL_NOT_IMPLEMENTED;
935 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
938 LPWSTR szPack = NULL;
940 TRACE("%s\n", debugstr_a(szPackage) );
944 szPack = strdupAtoW( szPackage );
946 return ERROR_OUTOFMEMORY;
949 r = MsiVerifyPackageW( szPack );
951 HeapFree( GetProcessHeap(), 0, szPack );
956 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
961 TRACE("%s\n", debugstr_w(szPackage) );
963 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
964 MsiCloseHandle( handle );
969 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
970 LPSTR lpPathBuf, DWORD* pcchBuf)
972 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
978 szwProduct = strdupAtoW( szProduct );
980 return ERROR_OUTOFMEMORY;
985 szwComponent = strdupAtoW( szComponent );
988 HeapFree( GetProcessHeap(), 0, szwProduct);
989 return ERROR_OUTOFMEMORY;
993 if( pcchBuf && *pcchBuf > 0 )
995 lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
996 incoming_len = *pcchBuf;
1004 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
1006 HeapFree( GetProcessHeap(), 0, szwProduct);
1007 HeapFree( GetProcessHeap(), 0, szwComponent);
1010 if (rc != INSTALLSTATE_UNKNOWN)
1011 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
1012 lpPathBuf, incoming_len, NULL, NULL);
1013 HeapFree( GetProcessHeap(), 0, lpwPathBuf);
1019 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1020 LPWSTR lpPathBuf, DWORD* pcchBuf)
1022 WCHAR squished_pc[GUID_SIZE];
1024 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
1029 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1030 debugstr_w(szComponent), lpPathBuf, pcchBuf);
1032 if( lpPathBuf && !pcchBuf )
1033 return INSTALLSTATE_INVALIDARG;
1035 squash_guid(szProduct,squished_pc);
1037 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1038 if( rc != ERROR_SUCCESS )
1043 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1044 if( rc != ERROR_SUCCESS )
1049 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
1050 if( rc != ERROR_SUCCESS )
1052 if( type != REG_SZ )
1055 sz += sizeof(WCHAR);
1056 path = HeapAlloc( GetProcessHeap(), 0, sz );
1060 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
1061 if( rc != ERROR_SUCCESS )
1064 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1065 debugstr_w(szProduct), debugstr_w(path));
1069 FIXME("Registry entry.. check entry\n");
1070 rrc = INSTALLSTATE_LOCAL;
1074 /* PROBABLY a file */
1075 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
1076 rrc = INSTALLSTATE_LOCAL;
1078 rrc = INSTALLSTATE_ABSENT;
1083 sz = sz / sizeof(WCHAR);
1084 if( *pcchBuf >= sz )
1085 lstrcpyW( lpPathBuf, path );
1090 HeapFree(GetProcessHeap(), 0, path );
1095 /******************************************************************
1096 * MsiQueryFeatureStateA [MSI.@]
1098 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1101 LPWSTR szwProduct= NULL;
1102 LPWSTR szwFeature= NULL;
1106 szwProduct = strdupAtoW( szProduct );
1108 return ERROR_OUTOFMEMORY;
1113 szwFeature = strdupAtoW( szFeature );
1116 HeapFree( GetProcessHeap(), 0, szwProduct);
1117 return ERROR_OUTOFMEMORY;
1121 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1123 HeapFree( GetProcessHeap(), 0, szwProduct);
1124 HeapFree( GetProcessHeap(), 0, szwFeature);
1129 /******************************************************************
1130 * MsiQueryFeatureStateW [MSI.@]
1132 * This does not verify that the Feature is functional. So i am only going to
1133 * check the existence of the key in the registry. This should tell me if it is
1136 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1142 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1144 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1145 if (rc != ERROR_SUCCESS)
1146 return INSTALLSTATE_UNKNOWN;
1148 rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz);
1151 if (rc == ERROR_SUCCESS)
1152 return INSTALLSTATE_LOCAL;
1154 return INSTALLSTATE_ABSENT;
1157 /******************************************************************
1158 * MsiGetFileVersionA [MSI.@]
1160 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1161 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1163 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1164 UINT ret = ERROR_OUTOFMEMORY;
1168 szwFilePath = strdupAtoW( szFilePath );
1173 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1175 lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1176 if( !lpwVersionBuff )
1180 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1182 lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1187 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1188 lpwLangBuff, pcchLangBuf);
1190 if( lpwVersionBuff )
1191 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1192 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1194 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1195 lpLangBuf, *pcchLangBuf, NULL, NULL);
1198 HeapFree(GetProcessHeap(), 0, szwFilePath);
1199 HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
1200 HeapFree(GetProcessHeap(), 0, lpwLangBuff);
1205 /******************************************************************
1206 * MsiGetFileVersionW [MSI.@]
1208 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1209 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1211 static const WCHAR szVersionResource[] = {'\\',0};
1212 static const WCHAR szVersionFormat[] = {
1213 '%','d','.','%','d','.','%','d','.','%','d',0};
1214 static const WCHAR szLangFormat[] = {'%','d',0};
1217 LPVOID lpVer = NULL;
1218 VS_FIXEDFILEINFO *ffi;
1222 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1223 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1224 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1226 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1228 return GetLastError();
1230 lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
1233 ret = ERROR_OUTOFMEMORY;
1237 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1239 ret = GetLastError();
1242 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1244 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1247 wsprintfW(tmp, szVersionFormat,
1248 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1249 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1250 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1251 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1256 *pcchVersionBuf = 0;
1260 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1262 DWORD lang = GetUserDefaultLangID();
1264 FIXME("Retrieve language from file\n");
1265 wsprintfW(tmp, szLangFormat, lang);
1266 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1267 *pcchLangBuf = lstrlenW(lpLangBuf);
1271 HeapFree(GetProcessHeap(), 0, lpVer);
1276 /******************************************************************
1279 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1283 case DLL_PROCESS_ATTACH:
1284 msi_hInstance = hinstDLL;
1285 DisableThreadLibraryCalls(hinstDLL);
1286 msi_dialog_register_class();
1288 case DLL_PROCESS_DETACH:
1289 msi_dialog_unregister_class();
1290 /* FIXME: Cleanup */
1296 typedef struct tagIClassFactoryImpl
1298 const IClassFactoryVtbl *lpVtbl;
1299 } IClassFactoryImpl;
1301 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1302 REFIID riid,LPVOID *ppobj)
1304 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1305 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1306 return E_NOINTERFACE;
1309 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1314 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1319 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1320 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1322 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1324 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1328 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1330 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1332 FIXME("%p %d\n", This, dolock);
1336 static const IClassFactoryVtbl MsiCF_Vtbl =
1338 MsiCF_QueryInterface,
1341 MsiCF_CreateInstance,
1345 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1347 /******************************************************************
1348 * DllGetClassObject [MSI.@]
1350 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1352 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1354 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1355 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1356 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1357 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1358 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1360 *ppv = (LPVOID) &Msi_CF;
1363 return CLASS_E_CLASSNOTAVAILABLE;
1366 /******************************************************************
1367 * DllGetVersion [MSI.@]
1369 HRESULT WINAPI DllGetVersion(DLLVERSIONINFO *pdvi)
1373 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1374 return E_INVALIDARG;
1376 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1377 pdvi->dwMinorVersion = MSI_MINORVERSION;
1378 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1379 pdvi->dwPlatformID = 1;
1384 /******************************************************************
1385 * DllCanUnloadNow [MSI.@]
1387 HRESULT WINAPI DllCanUnloadNow(void)
1392 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1393 DWORD* pdwUseCount, WORD* pwDateUsed)
1395 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1396 pdwUseCount, pwDateUsed);
1397 return ERROR_CALL_NOT_IMPLEMENTED;
1400 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1401 DWORD* pdwUseCount, WORD* pwDateUsed)
1403 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1404 pdwUseCount, pwDateUsed);
1405 return ERROR_CALL_NOT_IMPLEMENTED;
1408 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1409 DWORD dwInstallMode, DWORD dwReserved)
1411 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1412 dwInstallMode, dwReserved);
1415 * Polls all the components of the feature to find install state and then
1417 * Software\\Microsoft\\Windows\\CurrentVersion\\
1418 * Installer\\Products\\<squishguid>\\<feature>
1419 * "Usage"=dword:........
1422 return INSTALLSTATE_LOCAL;
1425 /***********************************************************************
1426 * MsiUseFeatureExA [MSI.@]
1428 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1429 DWORD dwInstallMode, DWORD dwReserved)
1431 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1432 dwInstallMode, dwReserved);
1434 return INSTALLSTATE_LOCAL;
1437 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1439 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1441 return INSTALLSTATE_LOCAL;
1444 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1446 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1448 return INSTALLSTATE_LOCAL;
1451 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1452 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1453 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1460 LPWSTR product = NULL;
1461 LPWSTR component = NULL;
1465 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1466 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1467 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1469 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1470 if (rc != ERROR_SUCCESS)
1471 return ERROR_INDEX_ABSENT;
1474 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
1478 return ERROR_INDEX_ABSENT;
1481 info = HeapAlloc(GetProcessHeap(),0,sz);
1482 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
1483 if (rc != ERROR_SUCCESS)
1486 HeapFree(GetProcessHeap(),0,info);
1487 return ERROR_INDEX_ABSENT;
1490 /* find the component */
1491 ptr = strchrW(&info[20],'>');
1497 HeapFree(GetProcessHeap(),0,info);
1498 return ERROR_INDEX_ABSENT;
1503 decode_base85_guid(info,&clsid);
1504 StringFromCLSID(&clsid, &product);
1506 decode_base85_guid(ptr,&clsid);
1507 StringFromCLSID(&clsid, &component);
1510 rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
1512 rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
1515 HeapFree(GetProcessHeap(),0,info);
1516 HeapFree(GetProcessHeap(),0,product);
1517 HeapFree(GetProcessHeap(),0,component);
1519 if (rc == INSTALLSTATE_LOCAL)
1520 return ERROR_SUCCESS;
1522 return ERROR_FILE_NOT_FOUND;
1525 /***********************************************************************
1526 * MsiProvideQualifiedComponentW [MSI.@]
1528 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1529 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1532 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1533 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1536 /***********************************************************************
1537 * MsiProvideQualifiedComponentA [MSI.@]
1539 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1540 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1543 LPWSTR szwComponent, szwQualifier, lpwPathBuf;
1547 TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
1548 dwInstallMode, lpPathBuf, pcchPathBuf);
1550 szwComponent= strdupAtoW( szComponent);
1551 szwQualifier= strdupAtoW( szQualifier);
1553 lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR));
1555 pcchwPathBuf = *pcchPathBuf;
1557 rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
1558 dwInstallMode, lpwPathBuf, &pcchwPathBuf);
1560 HeapFree(GetProcessHeap(),0,szwComponent);
1561 HeapFree(GetProcessHeap(),0,szwQualifier);
1562 *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
1563 lpPathBuf, *pcchPathBuf, NULL, NULL);
1565 HeapFree(GetProcessHeap(),0,lpwPathBuf);
1569 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1570 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1571 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1575 UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
1577 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1578 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1581 rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1582 if (rc != ERROR_SUCCESS)
1583 return USERINFOSTATE_UNKNOWN;
1587 sz = *lpUserNameBuf * sizeof(WCHAR);
1588 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1589 NULL, (LPBYTE)lpUserNameBuf,
1592 if (!lpUserNameBuf && pcchUserNameBuf)
1595 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_REGOWNERW, NULL,
1599 if (pcchUserNameBuf)
1600 *pcchUserNameBuf = sz / sizeof(WCHAR);
1604 sz = *pcchOrgNameBuf * sizeof(WCHAR);
1605 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1606 NULL, (LPBYTE)lpOrgNameBuf, &sz);
1608 if (!lpOrgNameBuf && pcchOrgNameBuf)
1611 rc2 = RegQueryValueExW( hkey, INSTALLPROPERTY_REGCOMPANYW, NULL,
1616 *pcchOrgNameBuf = sz / sizeof(WCHAR);
1618 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA &&
1619 rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA)
1622 return USERINFOSTATE_ABSENT;
1627 sz = *pcchSerialBuf * sizeof(WCHAR);
1628 RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL, NULL,
1629 (LPBYTE)lpSerialBuf, &sz);
1631 if (!lpSerialBuf && pcchSerialBuf)
1634 rc = RegQueryValueExW( hkey, INSTALLPROPERTY_PRODUCTIDW, NULL,
1638 *pcchSerialBuf = sz / sizeof(WCHAR);
1641 return USERINFOSTATE_PRESENT;
1644 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1645 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1646 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1648 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1649 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1652 return USERINFOSTATE_UNKNOWN;
1655 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1659 MSIPACKAGE *package;
1660 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1662 TRACE("(%s)\n",debugstr_w(szProduct));
1664 rc = MsiOpenProductW(szProduct,&handle);
1665 if (rc != ERROR_SUCCESS)
1666 return ERROR_INVALID_PARAMETER;
1668 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1669 rc = ACTION_PerformUIAction(package, szFirstRun);
1670 msiobj_release( &package->hdr );
1672 MsiCloseHandle(handle);
1677 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1681 MSIPACKAGE *package;
1682 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1684 TRACE("(%s)\n",debugstr_a(szProduct));
1686 rc = MsiOpenProductA(szProduct,&handle);
1687 if (rc != ERROR_SUCCESS)
1688 return ERROR_INVALID_PARAMETER;
1690 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1691 rc = ACTION_PerformUIAction(package, szFirstRun);
1692 msiobj_release( &package->hdr );
1694 MsiCloseHandle(handle);
1699 /***********************************************************************
1700 * MsiConfigureFeatureA [MSI.@]
1702 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
1704 FIXME("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
1705 return ERROR_SUCCESS;
1708 /***********************************************************************
1709 * MsiConfigureFeatureW [MSI.@]
1711 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
1713 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
1714 return ERROR_SUCCESS;
1717 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1719 WCHAR path[MAX_PATH];
1722 FIXME("Don't know how to handle argument %ld\n", dwReserved);
1723 return ERROR_CALL_NOT_IMPLEMENTED;
1726 if(!GetWindowsDirectoryW(path, MAX_PATH)) {
1727 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1729 return ERROR_CALL_NOT_IMPLEMENTED;
1732 strcatW(path, installerW);
1734 CreateDirectoryW(path, NULL);
1739 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1740 LPSTR szProductCode, LPSTR szFeatureId,
1741 LPSTR szComponentCode )
1744 return ERROR_CALL_NOT_IMPLEMENTED;
1747 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1748 LPWSTR szProductCode, LPWSTR szFeatureId,
1749 LPWSTR szComponentCode )
1752 return ERROR_CALL_NOT_IMPLEMENTED;
1755 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1756 DWORD dwReinstallMode )
1758 MSIHANDLE handle = -1;
1759 MSIPACKAGE* package;
1762 WCHAR sourcepath[MAX_PATH];
1763 WCHAR filename[MAX_PATH];
1764 static const WCHAR szInstalled[] = {
1765 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1766 static const WCHAR fmt[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1767 static const WCHAR REINSTALLMODE[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1768 WCHAR reinstallmode[11];
1772 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1775 memset(reinstallmode,0,sizeof(reinstallmode));
1776 ptr = reinstallmode;
1778 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
1779 { *ptr = 'p'; ptr++; }
1780 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
1781 { *ptr = 'o'; ptr++; }
1782 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
1783 { *ptr = 'w'; ptr++; }
1784 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
1785 { *ptr = 'd'; ptr++; }
1786 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
1787 { *ptr = 'c'; ptr++; }
1788 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
1789 { *ptr = 'a'; ptr++; }
1790 if (dwReinstallMode & REINSTALLMODE_USERDATA)
1791 { *ptr = 'u'; ptr++; }
1792 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
1793 { *ptr = 'm'; ptr++; }
1794 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
1795 { *ptr = 's'; ptr++; }
1796 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1797 { *ptr = 'v'; ptr++; }
1799 sz = sizeof(sourcepath);
1800 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1801 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
1804 sz = sizeof(filename);
1805 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1806 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1808 strcatW(sourcepath,filename);
1810 if (!(dwReinstallMode & REINSTALLMODE_PACKAGE))
1811 rc = MsiOpenProductW(szProduct,&handle);
1813 rc = MsiOpenPackageW(sourcepath,&handle);
1815 if (rc != ERROR_SUCCESS)
1818 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1821 rc = ERROR_INVALID_HANDLE;
1825 MSI_SetPropertyW(package,REINSTALLMODE,reinstallmode);
1827 sz = lstrlenW(szInstalled);
1828 sz += lstrlenW(fmt);
1829 sz += lstrlenW(szFeature);
1831 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
1833 sprintfW(commandline,fmt,szFeature);
1834 lstrcatW(commandline,szInstalled);
1836 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath);
1838 msiobj_release( &package->hdr );
1840 HeapFree(GetProcessHeap(),0,commandline);
1843 MsiCloseHandle(handle);
1848 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1849 DWORD dwReinstallMode )
1855 TRACE("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1858 wszProduct = strdupAtoW(szProduct);
1859 wszFeature = strdupAtoW(szFeature);
1861 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
1863 HeapFree(GetProcessHeap(),0,wszProduct);
1864 HeapFree(GetProcessHeap(),0,wszFeature);
1868 /***********************************************************************
1869 * MsiEnumPatchesA [MSI.@]
1871 UINT WINAPI MsiEnumPatchesA( LPCSTR szProduct, DWORD iPatchIndex,
1872 LPSTR lpPatchBuf, LPSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
1874 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct),
1875 iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
1876 return ERROR_NO_MORE_ITEMS;
1879 /***********************************************************************
1880 * MsiEnumPatchesW [MSI.@]
1882 UINT WINAPI MsiEnumPatchesW( LPCWSTR szProduct, DWORD iPatchIndex,
1883 LPWSTR lpPatchBuf, LPWSTR lpTransformsBuf, DWORD* pcchTransformsBuf)
1885 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct),
1886 iPatchIndex, lpPatchBuf, lpTransformsBuf, pcchTransformsBuf);
1887 return ERROR_NO_MORE_ITEMS;