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)
86 static const WCHAR szLocalPackage[] = {
87 'L','o','c','a','l','P','a','c','k','a','g','e', 0
91 HKEY hKeyProduct = NULL;
94 TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
96 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
97 if( r != ERROR_SUCCESS )
99 r = ERROR_UNKNOWN_PRODUCT;
103 /* find the size of the path */
105 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
106 NULL, &type, NULL, &count );
107 if( r != ERROR_SUCCESS )
109 r = ERROR_UNKNOWN_PRODUCT;
113 /* now alloc and fetch the path of the database to open */
114 path = HeapAlloc( GetProcessHeap(), 0, count );
118 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
119 NULL, &type, (LPBYTE) path, &count );
120 if( r != ERROR_SUCCESS )
122 r = ERROR_UNKNOWN_PRODUCT;
126 r = MsiOpenPackageW( path, phProduct );
129 HeapFree( GetProcessHeap(), 0, path );
131 RegCloseKey( hKeyProduct );
136 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
137 LPCSTR szTransforms, LANGID lgidLanguage)
139 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
140 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
141 return ERROR_CALL_NOT_IMPLEMENTED;
144 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
145 LPCWSTR szTransforms, LANGID lgidLanguage)
147 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
148 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
149 return ERROR_CALL_NOT_IMPLEMENTED;
152 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
153 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
155 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
156 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
157 lgidLanguage, dwPlatform, dwOptions);
158 return ERROR_CALL_NOT_IMPLEMENTED;
161 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
162 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
164 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
165 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
166 lgidLanguage, dwPlatform, dwOptions);
167 return ERROR_CALL_NOT_IMPLEMENTED;
170 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
172 LPWSTR szwPath = NULL, szwCommand = NULL;
173 UINT r = ERROR_OUTOFMEMORY;
175 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
179 szwPath = strdupAtoW( szPackagePath );
186 szwCommand = strdupAtoW( szCommandLine );
191 r = MsiInstallProductW( szwPath, szwCommand );
194 HeapFree( GetProcessHeap(), 0, szwPath );
195 HeapFree( GetProcessHeap(), 0, szwCommand );
200 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
202 MSIPACKAGE *package = NULL;
205 WCHAR path[MAX_PATH];
206 WCHAR filename[MAX_PATH];
207 static const WCHAR szMSI[] = {'M','S','I',0};
209 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
211 r = MsiVerifyPackageW(szPackagePath);
212 if (r != ERROR_SUCCESS)
215 /* copy the msi file to a temp file to pervent locking a CD
216 * with a multi disc install
218 GetTempPathW(MAX_PATH, path);
219 GetTempFileNameW(path, szMSI, 0, filename);
221 CopyFileW(szPackagePath, filename, FALSE);
223 TRACE("Opening relocated package %s\n",debugstr_w(filename));
224 r = MSI_OpenPackageW(filename, &package);
225 if (r != ERROR_SUCCESS)
227 DeleteFileW(filename);
231 handle = alloc_msihandle( &package->hdr );
233 r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine,
236 MsiCloseHandle(handle);
237 msiobj_release( &package->hdr );
239 DeleteFileW(filename);
243 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
245 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
246 return ERROR_CALL_NOT_IMPLEMENTED;
249 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
251 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
252 return ERROR_CALL_NOT_IMPLEMENTED;
255 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
256 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
258 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
259 eInstallType, debugstr_a(szCommandLine));
260 return ERROR_CALL_NOT_IMPLEMENTED;
263 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
264 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
266 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
267 eInstallType, debugstr_w(szCommandLine));
268 return ERROR_CALL_NOT_IMPLEMENTED;
271 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
272 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
274 MSIHANDLE handle = -1;
279 static const WCHAR szSouceList[] = {
280 'S','o','u','r','c','e','L','i','s','t',0};
281 static const WCHAR szLUS[] = {
282 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
283 WCHAR sourcepath[0x200];
284 static const WCHAR szInstalled[] = {
285 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
288 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
289 debugstr_w(szCommandLine));
291 if (eInstallState != INSTALLSTATE_LOCAL &&
292 eInstallState != INSTALLSTATE_DEFAULT)
294 FIXME("Not implemented for anything other than local installs\n");
295 return ERROR_CALL_NOT_IMPLEMENTED;
298 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
299 if (rc != ERROR_SUCCESS)
302 rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
303 if (rc != ERROR_SUCCESS)
306 sz = sizeof(sourcepath);
307 rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
308 if (rc != ERROR_SUCCESS)
313 * ok 1, we need to find the msi file for this product.
314 * 2, find the source dir for the files
315 * 3, do the configure/install.
316 * 4, cleanupany runonce entry.
319 rc = MsiOpenProductW(szProduct,&handle);
320 if (rc != ERROR_SUCCESS)
323 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
326 rc = ERROR_INVALID_HANDLE;
330 sz = lstrlenW(szInstalled);
333 sz += lstrlenW(szCommandLine);
335 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
338 lstrcpyW(commandline,szCommandLine);
342 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
343 lstrcatW(commandline,szInstalled);
345 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline, sourcepath);
347 msiobj_release( &package->hdr );
349 HeapFree(GetProcessHeap(),0,commandline);
353 MsiCloseHandle(handle);
358 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
359 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
361 LPWSTR szwProduct = NULL;
362 LPWSTR szwCommandLine = NULL;
363 UINT r = ERROR_OUTOFMEMORY;
367 szwProduct = strdupAtoW( szProduct );
374 szwCommandLine = strdupAtoW( szCommandLine );
379 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
382 HeapFree( GetProcessHeap(), 0, szwProduct );
383 HeapFree( GetProcessHeap(), 0, szwCommandLine);
388 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
389 INSTALLSTATE eInstallState)
391 LPWSTR szwProduct = NULL;
394 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
398 szwProduct = strdupAtoW( szProduct );
400 return ERROR_OUTOFMEMORY;
403 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
404 HeapFree( GetProcessHeap(), 0, szwProduct );
409 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
410 INSTALLSTATE eInstallState)
412 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
414 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
417 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
419 LPWSTR szwComponent = NULL;
421 WCHAR szwBuffer[GUID_SIZE];
423 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
427 szwComponent = strdupAtoW( szComponent );
429 return ERROR_OUTOFMEMORY;
432 r = MsiGetProductCodeW( szwComponent, szwBuffer );
434 if( ERROR_SUCCESS == r )
435 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
437 HeapFree( GetProcessHeap(), 0, szwComponent );
442 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
446 WCHAR szSquished[GUID_SIZE];
447 DWORD sz = GUID_SIZE;
448 static const WCHAR szPermKey[] =
449 { '0','0','0','0','0','0','0','0','0','0','0','0',
450 '0','0','0','0','0','0','0', '0','0','0','0','0',
451 '0','0','0','0','0','0','0','0',0};
453 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
455 if (NULL == szComponent)
456 return ERROR_INVALID_PARAMETER;
458 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
459 if (rc != ERROR_SUCCESS)
460 return ERROR_UNKNOWN_COMPONENT;
462 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
463 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
466 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
471 if (rc != ERROR_SUCCESS)
472 return ERROR_INSTALL_FAILURE;
474 unsquash_guid(szSquished, szBuffer);
475 return ERROR_SUCCESS;
478 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
479 LPSTR szBuffer, DWORD *pcchValueBuf)
481 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
482 UINT r = ERROR_OUTOFMEMORY;
483 DWORD pcchwValueBuf = 0;
485 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
486 szBuffer, pcchValueBuf);
490 szwProduct = strdupAtoW( szProduct );
497 szwAttribute = strdupAtoW( szAttribute );
504 szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
505 pcchwValueBuf = *pcchValueBuf;
510 r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer,
513 if( ERROR_SUCCESS == r )
514 *pcchValueBuf = WideCharToMultiByte(CP_ACP, 0, szwBuffer, pcchwValueBuf,
515 szBuffer, *pcchValueBuf, NULL, NULL);
518 HeapFree( GetProcessHeap(), 0, szwProduct );
519 HeapFree( GetProcessHeap(), 0, szwAttribute );
520 HeapFree( GetProcessHeap(), 0, szwBuffer );
525 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
526 LPWSTR szBuffer, DWORD *pcchValueBuf)
530 static const WCHAR szPackageCode[] =
531 {'P','a','c','k','a','g','e','C','o','d','e',0};
532 static const WCHAR szVersionString[] =
533 {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
534 static const WCHAR szProductVersion[] =
535 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
536 static const WCHAR szAssignmentType[] =
537 {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
538 static const WCHAR szLanguage[] =
539 {'L','a','n','g','u','a','g','e',0};
540 static const WCHAR szProductLanguage[] =
541 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
543 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
544 szBuffer, pcchValueBuf);
546 if (NULL != szBuffer && NULL == pcchValueBuf)
547 return ERROR_INVALID_PARAMETER;
548 if (NULL == szProduct || NULL == szAttribute)
549 return ERROR_INVALID_PARAMETER;
551 /* check for special properties */
552 if (strcmpW(szAttribute, szPackageCode)==0)
555 WCHAR squished[GUID_SIZE];
557 DWORD sz = sizeof(squished);
559 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
560 if (r != ERROR_SUCCESS)
561 return ERROR_UNKNOWN_PRODUCT;
563 r = RegQueryValueExW(hkey, szPackageCode, NULL, NULL,
564 (LPBYTE)squished, &sz);
565 if (r != ERROR_SUCCESS)
568 return ERROR_UNKNOWN_PRODUCT;
571 unsquash_guid(squished, package);
572 *pcchValueBuf = strlenW(package);
573 if (strlenW(package) > *pcchValueBuf)
576 return ERROR_MORE_DATA;
579 strcpyW(szBuffer, package);
584 else if (strcmpW(szAttribute, szVersionString)==0)
586 r = MsiOpenProductW(szProduct, &hProduct);
587 if (ERROR_SUCCESS != r)
590 r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf);
591 MsiCloseHandle(hProduct);
593 else if (strcmpW(szAttribute, szAssignmentType)==0)
595 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
605 else if (strcmpW(szAttribute, szLanguage)==0)
607 r = MsiOpenProductW(szProduct, &hProduct);
608 if (ERROR_SUCCESS != r)
611 r = MsiGetPropertyW(hProduct, szProductLanguage, szBuffer, pcchValueBuf);
612 MsiCloseHandle(hProduct);
616 r = MsiOpenProductW(szProduct, &hProduct);
617 if (ERROR_SUCCESS != r)
620 r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
621 MsiCloseHandle(hProduct);
627 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
629 LPWSTR szwLogFile = NULL;
632 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
636 szwLogFile = strdupAtoW( szLogFile );
638 return ERROR_OUTOFMEMORY;
640 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
641 HeapFree( GetProcessHeap(), 0, szwLogFile );
645 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
647 HANDLE file = INVALID_HANDLE_VALUE;
649 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
651 lstrcpyW(gszLogFile,szLogFile);
652 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
653 DeleteFileW(szLogFile);
654 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
655 FILE_ATTRIBUTE_NORMAL, NULL);
656 if (file != INVALID_HANDLE_VALUE)
659 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
661 return ERROR_SUCCESS;
664 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
666 LPWSTR szwProduct = NULL;
671 szwProduct = strdupAtoW( szProduct );
673 return ERROR_OUTOFMEMORY;
675 r = MsiQueryProductStateW( szwProduct );
676 HeapFree( GetProcessHeap(), 0, szwProduct );
680 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
683 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
685 static const WCHAR szWindowsInstaller[] = {
686 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
689 TRACE("%s\n", debugstr_w(szProduct));
691 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
692 if (rc != ERROR_SUCCESS)
697 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
698 if (rc != ERROR_SUCCESS)
702 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
703 if (rc != ERROR_SUCCESS)
710 rrc = INSTALLSTATE_DEFAULT;
713 FIXME("Unknown install state read from registry (%i)\n",rrc);
714 rrc = INSTALLSTATE_UNKNOWN;
722 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
724 INSTALLUILEVEL old = gUILevel;
725 HWND oldwnd = gUIhwnd;
727 TRACE("%08x %p\n", dwUILevel, phWnd);
729 gUILevel = dwUILevel;
738 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
739 DWORD dwMessageFilter, LPVOID pvContext)
741 INSTALLUI_HANDLERA prev = gUIHandlerA;
743 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
744 gUIHandlerA = puiHandler;
745 gUIFilter = dwMessageFilter;
746 gUIContext = pvContext;
751 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
752 DWORD dwMessageFilter, LPVOID pvContext)
754 INSTALLUI_HANDLERW prev = gUIHandlerW;
756 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
757 gUIHandlerW = puiHandler;
758 gUIFilter = dwMessageFilter;
759 gUIContext = pvContext;
764 /******************************************************************
765 * MsiLoadStringW [MSI.@]
767 * Loads a string from MSI's string resources.
771 * handle [I] only -1 is handled currently
772 * id [I] id of the string to be loaded
773 * lpBuffer [O] buffer for the string to be written to
774 * nBufferMax [I] maximum size of the buffer in characters
775 * lang [I] the preferred language for the string
779 * If successful, this function returns the language id of the string loaded
780 * If the function fails, the function returns zero.
784 * The type of the first parameter is unknown. LoadString's prototype
785 * suggests that it might be a module handle. I have made it an MSI handle
786 * for starters, as -1 is an invalid MSI handle, but not an invalid module
787 * handle. Maybe strings can be stored in an MSI database somehow.
789 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
790 int nBufferMax, LANGID lang )
797 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
800 FIXME("don't know how to deal with handle = %08lx\n", handle);
803 lang = GetUserDefaultLangID();
805 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
809 hResData = LoadResource( msi_hInstance, hres );
812 p = LockResource( hResData );
816 for (i = 0; i < (id&0xf); i++)
820 if( nBufferMax <= len )
823 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
826 TRACE("found -> %s\n", debugstr_w(lpBuffer));
831 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
832 int nBufferMax, LANGID lang )
838 bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
839 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
842 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
843 if( len <= nBufferMax )
844 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
845 lpBuffer, nBufferMax, NULL, NULL );
849 HeapFree(GetProcessHeap(), 0, bufW);
853 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
856 FIXME("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
857 return INSTALLSTATE_UNKNOWN;
860 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
863 FIXME("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
864 return INSTALLSTATE_UNKNOWN;
867 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
868 WORD wLanguageId, DWORD f)
870 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
871 uType,wLanguageId,f);
872 return ERROR_CALL_NOT_IMPLEMENTED;
875 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
876 WORD wLanguageId, DWORD f)
878 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
879 uType,wLanguageId,f);
880 return ERROR_CALL_NOT_IMPLEMENTED;
883 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
884 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
887 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
888 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
890 return ERROR_CALL_NOT_IMPLEMENTED;
893 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
894 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
897 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
898 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
900 return ERROR_CALL_NOT_IMPLEMENTED;
903 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
904 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
906 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
907 return ERROR_CALL_NOT_IMPLEMENTED;
910 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
911 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
913 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
914 return ERROR_CALL_NOT_IMPLEMENTED;
917 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
918 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
921 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
922 ppcCertContext, pbHashData, pcbHashData);
923 return ERROR_CALL_NOT_IMPLEMENTED;
926 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
927 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
930 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
931 ppcCertContext, pbHashData, pcbHashData);
932 return ERROR_CALL_NOT_IMPLEMENTED;
935 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
936 LPSTR szValue, DWORD *pccbValue )
938 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
939 return ERROR_CALL_NOT_IMPLEMENTED;
942 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
943 LPWSTR szValue, DWORD *pccbValue )
945 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
946 return ERROR_CALL_NOT_IMPLEMENTED;
949 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
952 LPWSTR szPack = NULL;
954 TRACE("%s\n", debugstr_a(szPackage) );
958 szPack = strdupAtoW( szPackage );
960 return ERROR_OUTOFMEMORY;
963 r = MsiVerifyPackageW( szPack );
965 HeapFree( GetProcessHeap(), 0, szPack );
970 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
975 TRACE("%s\n", debugstr_w(szPackage) );
977 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
978 MsiCloseHandle( handle );
983 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
984 LPSTR lpPathBuf, DWORD* pcchBuf)
986 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
992 szwProduct = strdupAtoW( szProduct );
994 return ERROR_OUTOFMEMORY;
999 szwComponent = strdupAtoW( szComponent );
1002 HeapFree( GetProcessHeap(), 0, szwProduct);
1003 return ERROR_OUTOFMEMORY;
1007 if( pcchBuf && *pcchBuf > 0 )
1009 lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
1010 incoming_len = *pcchBuf;
1018 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
1020 HeapFree( GetProcessHeap(), 0, szwProduct);
1021 HeapFree( GetProcessHeap(), 0, szwComponent);
1024 if (rc != INSTALLSTATE_UNKNOWN)
1025 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
1026 lpPathBuf, incoming_len, NULL, NULL);
1027 HeapFree( GetProcessHeap(), 0, lpwPathBuf);
1033 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1034 LPWSTR lpPathBuf, DWORD* pcchBuf)
1036 WCHAR squished_pc[GUID_SIZE];
1038 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
1043 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1044 debugstr_w(szComponent), lpPathBuf, pcchBuf);
1046 if( lpPathBuf && !pcchBuf )
1047 return INSTALLSTATE_INVALIDARG;
1049 squash_guid(szProduct,squished_pc);
1051 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1052 if( rc != ERROR_SUCCESS )
1057 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1058 if( rc != ERROR_SUCCESS )
1063 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
1064 if( rc != ERROR_SUCCESS )
1066 if( type != REG_SZ )
1069 sz += sizeof(WCHAR);
1070 path = HeapAlloc( GetProcessHeap(), 0, sz );
1074 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
1075 if( rc != ERROR_SUCCESS )
1078 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1079 debugstr_w(szProduct), debugstr_w(path));
1083 FIXME("Registry entry.. check entry\n");
1084 rrc = INSTALLSTATE_LOCAL;
1088 /* PROBABLY a file */
1089 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
1090 rrc = INSTALLSTATE_LOCAL;
1092 rrc = INSTALLSTATE_ABSENT;
1097 sz = sz / sizeof(WCHAR);
1098 if( *pcchBuf >= sz )
1099 lstrcpyW( lpPathBuf, path );
1104 HeapFree(GetProcessHeap(), 0, path );
1109 /******************************************************************
1110 * MsiQueryFeatureStateA [MSI.@]
1112 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1115 LPWSTR szwProduct= NULL;
1116 LPWSTR szwFeature= NULL;
1120 szwProduct = strdupAtoW( szProduct );
1122 return ERROR_OUTOFMEMORY;
1127 szwFeature = strdupAtoW( szFeature );
1130 HeapFree( GetProcessHeap(), 0, szwProduct);
1131 return ERROR_OUTOFMEMORY;
1135 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1137 HeapFree( GetProcessHeap(), 0, szwProduct);
1138 HeapFree( GetProcessHeap(), 0, szwFeature);
1143 /******************************************************************
1144 * MsiQueryFeatureStateW [MSI.@]
1146 * This does not verify that the Feature is functional. So i am only going to
1147 * check the existence of the key in the registry. This should tell me if it is
1150 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1156 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1158 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1159 if (rc != ERROR_SUCCESS)
1160 return INSTALLSTATE_UNKNOWN;
1162 rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz);
1165 if (rc == ERROR_SUCCESS)
1166 return INSTALLSTATE_LOCAL;
1168 return INSTALLSTATE_ABSENT;
1171 /******************************************************************
1172 * MsiGetFileVersionA [MSI.@]
1174 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1175 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1177 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1178 UINT ret = ERROR_OUTOFMEMORY;
1182 szwFilePath = strdupAtoW( szFilePath );
1187 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1189 lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1190 if( !lpwVersionBuff )
1194 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1196 lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1201 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1202 lpwLangBuff, pcchLangBuf);
1204 if( lpwVersionBuff )
1205 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1206 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1208 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1209 lpLangBuf, *pcchLangBuf, NULL, NULL);
1212 HeapFree(GetProcessHeap(), 0, szwFilePath);
1213 HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
1214 HeapFree(GetProcessHeap(), 0, lpwLangBuff);
1219 /******************************************************************
1220 * MsiGetFileVersionW [MSI.@]
1222 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1223 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1225 static const WCHAR szVersionResource[] = {'\\',0};
1226 static const WCHAR szVersionFormat[] = {
1227 '%','d','.','%','d','.','%','d','.','%','d',0};
1228 static const WCHAR szLangFormat[] = {'%','d',0};
1231 LPVOID lpVer = NULL;
1232 VS_FIXEDFILEINFO *ffi;
1236 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1237 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1238 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1240 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1242 return GetLastError();
1244 lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
1247 ret = ERROR_OUTOFMEMORY;
1251 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1253 ret = GetLastError();
1256 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1258 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1261 wsprintfW(tmp, szVersionFormat,
1262 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1263 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1264 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1265 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1270 *pcchVersionBuf = 0;
1274 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1276 DWORD lang = GetUserDefaultLangID();
1278 FIXME("Retrieve language from file\n");
1279 wsprintfW(tmp, szLangFormat, lang);
1280 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1281 *pcchLangBuf = lstrlenW(lpLangBuf);
1285 HeapFree(GetProcessHeap(), 0, lpVer);
1290 /******************************************************************
1293 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1297 case DLL_PROCESS_ATTACH:
1298 msi_hInstance = hinstDLL;
1299 DisableThreadLibraryCalls(hinstDLL);
1300 msi_dialog_register_class();
1302 case DLL_PROCESS_DETACH:
1303 msi_dialog_unregister_class();
1304 /* FIXME: Cleanup */
1310 typedef struct tagIClassFactoryImpl
1312 const IClassFactoryVtbl *lpVtbl;
1313 } IClassFactoryImpl;
1315 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1316 REFIID riid,LPVOID *ppobj)
1318 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1319 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1320 return E_NOINTERFACE;
1323 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1328 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1333 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1334 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1336 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1338 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1342 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1344 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1346 FIXME("%p %d\n", This, dolock);
1350 static const IClassFactoryVtbl MsiCF_Vtbl =
1352 MsiCF_QueryInterface,
1355 MsiCF_CreateInstance,
1359 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1361 /******************************************************************
1362 * DllGetClassObject [MSI.@]
1364 HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1366 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1368 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1369 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1370 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1371 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1372 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1374 *ppv = (LPVOID) &Msi_CF;
1377 return CLASS_E_CLASSNOTAVAILABLE;
1380 /******************************************************************
1381 * DllGetVersion [MSI.@]
1383 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
1387 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1388 return E_INVALIDARG;
1390 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1391 pdvi->dwMinorVersion = MSI_MINORVERSION;
1392 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1393 pdvi->dwPlatformID = 1;
1398 /******************************************************************
1399 * DllCanUnloadNow [MSI.@]
1401 BOOL WINAPI MSI_DllCanUnloadNow(void)
1406 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1407 DWORD* pdwUseCount, WORD* pwDateUsed)
1409 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1410 pdwUseCount, pwDateUsed);
1411 return ERROR_CALL_NOT_IMPLEMENTED;
1414 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1415 DWORD* pdwUseCount, WORD* pwDateUsed)
1417 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1418 pdwUseCount, pwDateUsed);
1419 return ERROR_CALL_NOT_IMPLEMENTED;
1422 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1423 DWORD dwInstallMode, DWORD dwReserved)
1425 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1426 dwInstallMode, dwReserved);
1429 * Polls all the components of the feature to find install state and then
1431 * Software\\Microsoft\\Windows\\CurrentVersion\\
1432 * Installer\\Products\\<squishguid>\\<feature>
1433 * "Usage"=dword:........
1436 return INSTALLSTATE_LOCAL;
1439 /***********************************************************************
1440 * MsiUseFeatureExA [MSI.@]
1442 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1443 DWORD dwInstallMode, DWORD dwReserved)
1445 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1446 dwInstallMode, dwReserved);
1448 return INSTALLSTATE_LOCAL;
1451 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1453 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1455 return INSTALLSTATE_LOCAL;
1458 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1460 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1462 return INSTALLSTATE_LOCAL;
1465 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1466 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1467 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1474 LPWSTR product = NULL;
1475 LPWSTR component = NULL;
1479 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1480 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1481 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1483 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1484 if (rc != ERROR_SUCCESS)
1485 return ERROR_INDEX_ABSENT;
1488 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
1492 return ERROR_INDEX_ABSENT;
1495 info = HeapAlloc(GetProcessHeap(),0,sz);
1496 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
1497 if (rc != ERROR_SUCCESS)
1500 HeapFree(GetProcessHeap(),0,info);
1501 return ERROR_INDEX_ABSENT;
1504 /* find the component */
1505 ptr = strchrW(&info[20],'>');
1511 HeapFree(GetProcessHeap(),0,info);
1512 return ERROR_INDEX_ABSENT;
1517 decode_base85_guid(info,&clsid);
1518 StringFromCLSID(&clsid, &product);
1520 decode_base85_guid(ptr,&clsid);
1521 StringFromCLSID(&clsid, &component);
1524 rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
1526 rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
1529 HeapFree(GetProcessHeap(),0,info);
1530 HeapFree(GetProcessHeap(),0,product);
1531 HeapFree(GetProcessHeap(),0,component);
1533 if (rc == INSTALLSTATE_LOCAL)
1534 return ERROR_SUCCESS;
1536 return ERROR_FILE_NOT_FOUND;
1539 /***********************************************************************
1540 * MsiProvideQualifiedComponentW [MSI.@]
1542 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1543 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1546 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1547 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1550 /***********************************************************************
1551 * MsiProvideQualifiedComponentA [MSI.@]
1553 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1554 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1557 LPWSTR szwComponent, szwQualifier, lpwPathBuf;
1561 TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
1562 dwInstallMode, lpPathBuf, pcchPathBuf);
1564 szwComponent= strdupAtoW( szComponent);
1565 szwQualifier= strdupAtoW( szQualifier);
1567 lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR));
1569 pcchwPathBuf = *pcchPathBuf;
1571 rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
1572 dwInstallMode, lpwPathBuf, &pcchwPathBuf);
1574 HeapFree(GetProcessHeap(),0,szwComponent);
1575 HeapFree(GetProcessHeap(),0,szwQualifier);
1576 *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
1577 lpPathBuf, *pcchPathBuf, NULL, NULL);
1579 HeapFree(GetProcessHeap(),0,lpwPathBuf);
1583 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1584 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1585 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1589 UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
1590 static const WCHAR szOwner[] = {'R','e','g','O','w','n','e','r',0};
1591 static const WCHAR szCompany[] = {'R','e','g','C','o','m','p','a','n','y',0};
1592 static const WCHAR szSerial[] = {'P','r','o','d','u','c','t','I','D',0};
1594 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1595 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1598 rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1599 if (rc != ERROR_SUCCESS)
1600 return USERINFOSTATE_UNKNOWN;
1604 sz = *lpUserNameBuf * sizeof(WCHAR);
1605 rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, (LPBYTE)lpUserNameBuf,
1608 if (!lpUserNameBuf && pcchUserNameBuf)
1611 rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, NULL, &sz);
1614 if (pcchUserNameBuf)
1615 *pcchUserNameBuf = sz / sizeof(WCHAR);
1619 sz = *pcchOrgNameBuf * sizeof(WCHAR);
1620 rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL,
1621 (LPBYTE)lpOrgNameBuf, &sz);
1623 if (!lpOrgNameBuf && pcchOrgNameBuf)
1626 rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL, NULL, &sz);
1630 *pcchOrgNameBuf = sz / sizeof(WCHAR);
1632 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA &&
1633 rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA)
1636 return USERINFOSTATE_ABSENT;
1641 sz = *pcchSerialBuf * sizeof(WCHAR);
1642 RegQueryValueExW( hkey, szSerial, NULL, NULL, (LPBYTE)lpSerialBuf,
1645 if (!lpSerialBuf && pcchSerialBuf)
1648 rc = RegQueryValueExW( hkey, szSerial, NULL, NULL, NULL, &sz);
1651 *pcchSerialBuf = sz / sizeof(WCHAR);
1654 return USERINFOSTATE_PRESENT;
1657 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1658 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1659 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1661 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1662 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1665 return USERINFOSTATE_UNKNOWN;
1668 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1672 MSIPACKAGE *package;
1673 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1675 TRACE("(%s)\n",debugstr_w(szProduct));
1677 rc = MsiOpenProductW(szProduct,&handle);
1678 if (rc != ERROR_SUCCESS)
1679 return ERROR_INVALID_PARAMETER;
1681 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1682 rc = ACTION_PerformUIAction(package, szFirstRun);
1683 msiobj_release( &package->hdr );
1685 MsiCloseHandle(handle);
1690 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1694 MSIPACKAGE *package;
1695 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1697 TRACE("(%s)\n",debugstr_a(szProduct));
1699 rc = MsiOpenProductA(szProduct,&handle);
1700 if (rc != ERROR_SUCCESS)
1701 return ERROR_INVALID_PARAMETER;
1703 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1704 rc = ACTION_PerformUIAction(package, szFirstRun);
1705 msiobj_release( &package->hdr );
1707 MsiCloseHandle(handle);
1712 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1714 WCHAR path[MAX_PATH];
1717 FIXME("Don't know how to handle argument %ld\n", dwReserved);
1718 return ERROR_CALL_NOT_IMPLEMENTED;
1721 if(!GetWindowsDirectoryW(path, MAX_PATH)) {
1722 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1724 return ERROR_CALL_NOT_IMPLEMENTED;
1727 strcatW(path, installerW);
1729 CreateDirectoryW(path, NULL);
1734 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1735 LPSTR szProductCode, LPSTR szFeatureId,
1736 LPSTR szComponentCode )
1739 return ERROR_CALL_NOT_IMPLEMENTED;
1742 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1743 LPWSTR szProductCode, LPWSTR szFeatureId,
1744 LPWSTR szComponentCode )
1747 return ERROR_CALL_NOT_IMPLEMENTED;
1750 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1751 DWORD dwReinstallMode )
1753 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1755 return ERROR_SUCCESS;
1758 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1759 DWORD dwReinstallMode )
1761 FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1763 return ERROR_SUCCESS;