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;
206 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
208 r = MsiVerifyPackageW(szPackagePath);
209 if (r != ERROR_SUCCESS)
212 r = MSI_OpenPackageW(szPackagePath,&package);
213 if (r != ERROR_SUCCESS)
216 handle = alloc_msihandle( &package->hdr );
218 r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
220 MsiCloseHandle(handle);
221 msiobj_release( &package->hdr );
225 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
227 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
228 return ERROR_CALL_NOT_IMPLEMENTED;
231 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
233 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
234 return ERROR_CALL_NOT_IMPLEMENTED;
237 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
238 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
240 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
241 eInstallType, debugstr_a(szCommandLine));
242 return ERROR_CALL_NOT_IMPLEMENTED;
245 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
246 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
248 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
249 eInstallType, debugstr_w(szCommandLine));
250 return ERROR_CALL_NOT_IMPLEMENTED;
253 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
254 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
256 MSIHANDLE handle = -1;
261 static const WCHAR szSouceList[] = {
262 'S','o','u','r','c','e','L','i','s','t',0};
263 static const WCHAR szLUS[] = {
264 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
265 WCHAR sourcepath[0x200];
266 static const WCHAR szInstalled[] = {
267 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
270 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
271 debugstr_w(szCommandLine));
273 if (eInstallState != INSTALLSTATE_LOCAL &&
274 eInstallState != INSTALLSTATE_DEFAULT)
276 FIXME("Not implemented for anything other than local installs\n");
277 return ERROR_CALL_NOT_IMPLEMENTED;
280 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
281 if (rc != ERROR_SUCCESS)
284 rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
285 if (rc != ERROR_SUCCESS)
288 sz = sizeof(sourcepath);
289 rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
290 if (rc != ERROR_SUCCESS)
295 * ok 1, we need to find the msi file for this product.
296 * 2, find the source dir for the files
297 * 3, do the configure/install.
298 * 4, cleanupany runonce entry.
301 rc = MsiOpenProductW(szProduct,&handle);
302 if (rc != ERROR_SUCCESS)
305 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
308 rc = ERROR_INVALID_HANDLE;
312 sz = lstrlenW(szInstalled);
315 sz += lstrlenW(szCommandLine);
317 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
320 lstrcpyW(commandline,szCommandLine);
324 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
325 lstrcatW(commandline,szInstalled);
327 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
329 msiobj_release( &package->hdr );
331 HeapFree(GetProcessHeap(),0,commandline);
335 MsiCloseHandle(handle);
340 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
341 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
343 LPWSTR szwProduct = NULL;
344 LPWSTR szwCommandLine = NULL;
345 UINT r = ERROR_OUTOFMEMORY;
349 szwProduct = strdupAtoW( szProduct );
356 szwCommandLine = strdupAtoW( szCommandLine );
361 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
364 HeapFree( GetProcessHeap(), 0, szwProduct );
365 HeapFree( GetProcessHeap(), 0, szwCommandLine);
370 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
371 INSTALLSTATE eInstallState)
373 LPWSTR szwProduct = NULL;
376 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
380 szwProduct = strdupAtoW( szProduct );
382 return ERROR_OUTOFMEMORY;
385 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
386 HeapFree( GetProcessHeap(), 0, szwProduct );
391 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
392 INSTALLSTATE eInstallState)
394 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
396 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
399 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
401 LPWSTR szwComponent = NULL;
403 WCHAR szwBuffer[GUID_SIZE];
405 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
409 szwComponent = strdupAtoW( szComponent );
411 return ERROR_OUTOFMEMORY;
414 r = MsiGetProductCodeW( szwComponent, szwBuffer );
416 if( ERROR_SUCCESS == r )
417 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
419 HeapFree( GetProcessHeap(), 0, szwComponent );
424 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
428 WCHAR szSquished[GUID_SIZE];
429 DWORD sz = GUID_SIZE;
430 static const WCHAR szPermKey[] =
431 { '0','0','0','0','0','0','0','0','0','0','0','0',
432 '0','0','0','0','0','0','0', '0','0','0','0','0',
433 '0','0','0','0','0','0','0','0',0};
435 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
437 if (NULL == szComponent)
438 return ERROR_INVALID_PARAMETER;
440 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
441 if (rc != ERROR_SUCCESS)
442 return ERROR_UNKNOWN_COMPONENT;
444 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
445 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
448 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
453 if (rc != ERROR_SUCCESS)
454 return ERROR_INSTALL_FAILURE;
456 unsquash_guid(szSquished, szBuffer);
457 return ERROR_SUCCESS;
460 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
461 LPSTR szBuffer, DWORD *pcchValueBuf)
463 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
464 UINT r = ERROR_OUTOFMEMORY;
465 DWORD pcchwValueBuf = 0;
467 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
468 szBuffer, pcchValueBuf);
472 szwProduct = strdupAtoW( szProduct );
479 szwAttribute = strdupAtoW( szAttribute );
486 szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
487 pcchwValueBuf = *pcchValueBuf;
492 r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer,
495 if( ERROR_SUCCESS == r )
496 *pcchValueBuf = WideCharToMultiByte(CP_ACP, 0, szwBuffer, pcchwValueBuf,
497 szBuffer, *pcchValueBuf, NULL, NULL);
500 HeapFree( GetProcessHeap(), 0, szwProduct );
501 HeapFree( GetProcessHeap(), 0, szwAttribute );
502 HeapFree( GetProcessHeap(), 0, szwBuffer );
507 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
508 LPWSTR szBuffer, DWORD *pcchValueBuf)
512 static const WCHAR szPackageCode[] =
513 {'P','a','c','k','a','g','e','C','o','d','e',0};
514 static const WCHAR szVersionString[] =
515 {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
516 static const WCHAR szProductVersion[] =
517 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
518 static const WCHAR szAssignmentType[] =
519 {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
520 static const WCHAR szLanguage[] =
521 {'L','a','n','g','u','a','g','e',0};
522 static const WCHAR szProductLanguage[] =
523 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
525 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
526 szBuffer, pcchValueBuf);
528 if (NULL != szBuffer && NULL == pcchValueBuf)
529 return ERROR_INVALID_PARAMETER;
530 if (NULL == szProduct || NULL == szAttribute)
531 return ERROR_INVALID_PARAMETER;
533 /* check for special properties */
534 if (strcmpW(szAttribute, szPackageCode)==0)
537 WCHAR squished[GUID_SIZE];
539 DWORD sz = sizeof(squished);
541 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
542 if (r != ERROR_SUCCESS)
543 return ERROR_UNKNOWN_PRODUCT;
545 r = RegQueryValueExW(hkey, szPackageCode, NULL, NULL,
546 (LPBYTE)squished, &sz);
547 if (r != ERROR_SUCCESS)
550 return ERROR_UNKNOWN_PRODUCT;
553 unsquash_guid(squished, package);
554 *pcchValueBuf = strlenW(package);
555 if (strlenW(package) > *pcchValueBuf)
558 return ERROR_MORE_DATA;
561 strcpyW(szBuffer, package);
566 else if (strcmpW(szAttribute, szVersionString)==0)
568 r = MsiOpenProductW(szProduct, &hProduct);
569 if (ERROR_SUCCESS != r)
572 r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf);
573 MsiCloseHandle(hProduct);
575 else if (strcmpW(szAttribute, szAssignmentType)==0)
577 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
587 else if (strcmpW(szAttribute, szLanguage)==0)
589 r = MsiOpenProductW(szProduct, &hProduct);
590 if (ERROR_SUCCESS != r)
593 r = MsiGetPropertyW(hProduct, szProductLanguage, szBuffer, pcchValueBuf);
594 MsiCloseHandle(hProduct);
598 r = MsiOpenProductW(szProduct, &hProduct);
599 if (ERROR_SUCCESS != r)
602 r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
603 MsiCloseHandle(hProduct);
609 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
611 LPWSTR szwLogFile = NULL;
614 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
618 szwLogFile = strdupAtoW( szLogFile );
620 return ERROR_OUTOFMEMORY;
622 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
623 HeapFree( GetProcessHeap(), 0, szwLogFile );
627 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
629 HANDLE file = INVALID_HANDLE_VALUE;
631 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
633 lstrcpyW(gszLogFile,szLogFile);
634 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
635 DeleteFileW(szLogFile);
636 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
637 FILE_ATTRIBUTE_NORMAL, NULL);
638 if (file != INVALID_HANDLE_VALUE)
641 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
643 return ERROR_SUCCESS;
646 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
648 LPWSTR szwProduct = NULL;
653 szwProduct = strdupAtoW( szProduct );
655 return ERROR_OUTOFMEMORY;
657 r = MsiQueryProductStateW( szwProduct );
658 HeapFree( GetProcessHeap(), 0, szwProduct );
662 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
665 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
667 static const WCHAR szWindowsInstaller[] = {
668 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
671 TRACE("%s\n", debugstr_w(szProduct));
673 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
674 if (rc != ERROR_SUCCESS)
679 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
680 if (rc != ERROR_SUCCESS)
684 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
685 if (rc != ERROR_SUCCESS)
692 rrc = INSTALLSTATE_DEFAULT;
695 FIXME("Unknown install state read from registry (%i)\n",rrc);
696 rrc = INSTALLSTATE_UNKNOWN;
704 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
706 INSTALLUILEVEL old = gUILevel;
707 HWND oldwnd = gUIhwnd;
709 TRACE("%08x %p\n", dwUILevel, phWnd);
711 gUILevel = dwUILevel;
720 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
721 DWORD dwMessageFilter, LPVOID pvContext)
723 INSTALLUI_HANDLERA prev = gUIHandlerA;
725 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
726 gUIHandlerA = puiHandler;
727 gUIFilter = dwMessageFilter;
728 gUIContext = pvContext;
733 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
734 DWORD dwMessageFilter, LPVOID pvContext)
736 INSTALLUI_HANDLERW prev = gUIHandlerW;
738 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
739 gUIHandlerW = puiHandler;
740 gUIFilter = dwMessageFilter;
741 gUIContext = pvContext;
746 /******************************************************************
747 * MsiLoadStringW [MSI.@]
749 * Loads a string from MSI's string resources.
753 * handle [I] only -1 is handled currently
754 * id [I] id of the string to be loaded
755 * lpBuffer [O] buffer for the string to be written to
756 * nBufferMax [I] maximum size of the buffer in characters
757 * lang [I] the preferred language for the string
761 * If successful, this function returns the language id of the string loaded
762 * If the function fails, the function returns zero.
766 * The type of the first parameter is unknown. LoadString's prototype
767 * suggests that it might be a module handle. I have made it an MSI handle
768 * for starters, as -1 is an invalid MSI handle, but not an invalid module
769 * handle. Maybe strings can be stored in an MSI database somehow.
771 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
772 int nBufferMax, LANGID lang )
779 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
782 FIXME("don't know how to deal with handle = %08lx\n", handle);
785 lang = GetUserDefaultLangID();
787 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
791 hResData = LoadResource( msi_hInstance, hres );
794 p = LockResource( hResData );
798 for (i = 0; i < (id&0xf); i++)
802 if( nBufferMax <= len )
805 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
808 TRACE("found -> %s\n", debugstr_w(lpBuffer));
813 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
814 int nBufferMax, LANGID lang )
820 bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
821 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
824 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
825 if( len <= nBufferMax )
826 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
827 lpBuffer, nBufferMax, NULL, NULL );
831 HeapFree(GetProcessHeap(), 0, bufW);
835 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
838 FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
839 return INSTALLSTATE_UNKNOWN;
842 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
845 FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
846 return INSTALLSTATE_UNKNOWN;
849 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
850 WORD wLanguageId, DWORD f)
852 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
853 uType,wLanguageId,f);
854 return ERROR_CALL_NOT_IMPLEMENTED;
857 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
858 WORD wLanguageId, DWORD f)
860 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
861 uType,wLanguageId,f);
862 return ERROR_CALL_NOT_IMPLEMENTED;
865 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
866 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
869 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
870 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
872 return ERROR_CALL_NOT_IMPLEMENTED;
875 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
876 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
879 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
880 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
882 return ERROR_CALL_NOT_IMPLEMENTED;
885 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
886 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
888 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
889 return ERROR_CALL_NOT_IMPLEMENTED;
892 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
893 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
895 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
896 return ERROR_CALL_NOT_IMPLEMENTED;
899 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
900 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
903 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
904 ppcCertContext, pbHashData, pcbHashData);
905 return ERROR_CALL_NOT_IMPLEMENTED;
908 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
909 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
912 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
913 ppcCertContext, pbHashData, pcbHashData);
914 return ERROR_CALL_NOT_IMPLEMENTED;
917 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
918 LPSTR szValue, DWORD *pccbValue )
920 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
921 return ERROR_CALL_NOT_IMPLEMENTED;
924 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
925 LPWSTR szValue, DWORD *pccbValue )
927 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
928 return ERROR_CALL_NOT_IMPLEMENTED;
931 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
934 LPWSTR szPack = NULL;
936 TRACE("%s\n", debugstr_a(szPackage) );
940 szPack = strdupAtoW( szPackage );
942 return ERROR_OUTOFMEMORY;
945 r = MsiVerifyPackageW( szPack );
947 HeapFree( GetProcessHeap(), 0, szPack );
952 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
957 TRACE("%s\n", debugstr_w(szPackage) );
959 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
960 MsiCloseHandle( handle );
965 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
966 LPSTR lpPathBuf, DWORD* pcchBuf)
968 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
974 szwProduct = strdupAtoW( szProduct );
976 return ERROR_OUTOFMEMORY;
981 szwComponent = strdupAtoW( szComponent );
984 HeapFree( GetProcessHeap(), 0, szwProduct);
985 return ERROR_OUTOFMEMORY;
989 if( pcchBuf && *pcchBuf > 0 )
991 lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
992 incoming_len = *pcchBuf;
1000 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
1002 HeapFree( GetProcessHeap(), 0, szwProduct);
1003 HeapFree( GetProcessHeap(), 0, szwComponent);
1006 if (rc != INSTALLSTATE_UNKNOWN)
1007 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
1008 lpPathBuf, incoming_len, NULL, NULL);
1009 HeapFree( GetProcessHeap(), 0, lpwPathBuf);
1015 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1016 LPWSTR lpPathBuf, DWORD* pcchBuf)
1018 WCHAR squished_pc[GUID_SIZE];
1020 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
1025 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1026 debugstr_w(szComponent), lpPathBuf, pcchBuf);
1028 if( lpPathBuf && !pcchBuf )
1029 return INSTALLSTATE_INVALIDARG;
1031 squash_guid(szProduct,squished_pc);
1033 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1034 if( rc != ERROR_SUCCESS )
1039 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1040 if( rc != ERROR_SUCCESS )
1045 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
1046 if( rc != ERROR_SUCCESS )
1048 if( type != REG_SZ )
1051 sz += sizeof(WCHAR);
1052 path = HeapAlloc( GetProcessHeap(), 0, sz );
1056 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
1057 if( rc != ERROR_SUCCESS )
1060 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1061 debugstr_w(szProduct), debugstr_w(path));
1065 FIXME("Registry entry.. check entry\n");
1066 rrc = INSTALLSTATE_LOCAL;
1070 /* PROBABLY a file */
1071 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
1072 rrc = INSTALLSTATE_LOCAL;
1074 rrc = INSTALLSTATE_ABSENT;
1079 sz = sz / sizeof(WCHAR);
1080 if( *pcchBuf >= sz )
1081 lstrcpyW( lpPathBuf, path );
1086 HeapFree(GetProcessHeap(), 0, path );
1091 /******************************************************************
1092 * MsiQueryFeatureStateA [MSI.@]
1094 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1097 LPWSTR szwProduct= NULL;
1098 LPWSTR szwFeature= NULL;
1102 szwProduct = strdupAtoW( szProduct );
1104 return ERROR_OUTOFMEMORY;
1109 szwFeature = strdupAtoW( szFeature );
1112 HeapFree( GetProcessHeap(), 0, szwProduct);
1113 return ERROR_OUTOFMEMORY;
1117 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1119 HeapFree( GetProcessHeap(), 0, szwProduct);
1120 HeapFree( GetProcessHeap(), 0, szwFeature);
1125 /******************************************************************
1126 * MsiQueryFeatureStateW [MSI.@]
1128 * This does not verify that the Feature is functional. So i am only going to
1129 * check the existence of the key in the registry. This should tell me if it is
1132 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1138 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1140 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1141 if (rc != ERROR_SUCCESS)
1142 return INSTALLSTATE_UNKNOWN;
1144 rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz);
1147 if (rc == ERROR_SUCCESS)
1148 return INSTALLSTATE_LOCAL;
1150 return INSTALLSTATE_ABSENT;
1153 /******************************************************************
1154 * MsiGetFileVersionA [MSI.@]
1156 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1157 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1159 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1160 UINT ret = ERROR_OUTOFMEMORY;
1164 szwFilePath = strdupAtoW( szFilePath );
1169 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1171 lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1172 if( !lpwVersionBuff )
1176 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1178 lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1183 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1184 lpwLangBuff, pcchLangBuf);
1186 if( lpwVersionBuff )
1187 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1188 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1190 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1191 lpLangBuf, *pcchLangBuf, NULL, NULL);
1194 HeapFree(GetProcessHeap(), 0, szwFilePath);
1195 HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
1196 HeapFree(GetProcessHeap(), 0, lpwLangBuff);
1201 /******************************************************************
1202 * MsiGetFileVersionW [MSI.@]
1204 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1205 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1207 static const WCHAR szVersionResource[] = {'\\',0};
1208 static const WCHAR szVersionFormat[] = {
1209 '%','d','.','%','d','.','%','d','.','%','d',0};
1210 static const WCHAR szLangFormat[] = {'%','d',0};
1213 LPVOID lpVer = NULL;
1214 VS_FIXEDFILEINFO *ffi;
1218 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1219 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1220 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1222 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1224 return GetLastError();
1226 lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
1229 ret = ERROR_OUTOFMEMORY;
1233 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1235 ret = GetLastError();
1238 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1240 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1243 wsprintfW(tmp, szVersionFormat,
1244 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1245 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1246 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1247 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1252 *pcchVersionBuf = 0;
1256 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1258 DWORD lang = GetUserDefaultLangID();
1260 FIXME("Retrieve language from file\n");
1261 wsprintfW(tmp, szLangFormat, lang);
1262 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1263 *pcchLangBuf = lstrlenW(lpLangBuf);
1267 HeapFree(GetProcessHeap(), 0, lpVer);
1272 /******************************************************************
1275 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1279 case DLL_PROCESS_ATTACH:
1280 msi_hInstance = hinstDLL;
1281 DisableThreadLibraryCalls(hinstDLL);
1282 msi_dialog_register_class();
1284 case DLL_PROCESS_DETACH:
1285 msi_dialog_unregister_class();
1286 /* FIXME: Cleanup */
1292 typedef struct tagIClassFactoryImpl
1294 const IClassFactoryVtbl *lpVtbl;
1295 } IClassFactoryImpl;
1297 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1298 REFIID riid,LPVOID *ppobj)
1300 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1301 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1302 return E_NOINTERFACE;
1305 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1310 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1315 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1316 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1318 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1320 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1324 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1326 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1328 FIXME("%p %d\n", This, dolock);
1332 static const IClassFactoryVtbl MsiCF_Vtbl =
1334 MsiCF_QueryInterface,
1337 MsiCF_CreateInstance,
1341 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1343 /******************************************************************
1344 * DllGetClassObject [MSI.@]
1346 HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1348 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1350 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1351 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1352 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1353 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1354 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1356 *ppv = (LPVOID) &Msi_CF;
1359 return CLASS_E_CLASSNOTAVAILABLE;
1362 /******************************************************************
1363 * DllGetVersion [MSI.@]
1365 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
1369 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1370 return E_INVALIDARG;
1372 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1373 pdvi->dwMinorVersion = MSI_MINORVERSION;
1374 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1375 pdvi->dwPlatformID = 1;
1380 /******************************************************************
1381 * DllCanUnloadNow [MSI.@]
1383 BOOL WINAPI MSI_DllCanUnloadNow(void)
1388 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1389 DWORD* pdwUseCount, WORD* pwDateUsed)
1391 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1392 pdwUseCount, pwDateUsed);
1393 return ERROR_CALL_NOT_IMPLEMENTED;
1396 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1397 DWORD* pdwUseCount, WORD* pwDateUsed)
1399 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1400 pdwUseCount, pwDateUsed);
1401 return ERROR_CALL_NOT_IMPLEMENTED;
1404 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1405 DWORD dwInstallMode, DWORD dwReserved)
1407 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1408 dwInstallMode, dwReserved);
1411 * Polls all the components of the feature to find install state and then
1413 * Software\\Microsoft\\Windows\\CurrentVersion\\
1414 * Installer\\Products\\<squishguid>\\<feature>
1415 * "Usage"=dword:........
1418 return INSTALLSTATE_LOCAL;
1421 /***********************************************************************
1422 * MsiUseFeatureExA [MSI.@]
1424 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1425 DWORD dwInstallMode, DWORD dwReserved)
1427 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1428 dwInstallMode, dwReserved);
1430 return INSTALLSTATE_LOCAL;
1433 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1435 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1437 return INSTALLSTATE_LOCAL;
1440 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1442 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1444 return INSTALLSTATE_LOCAL;
1447 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1448 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1449 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1456 LPWSTR product = NULL;
1457 LPWSTR component = NULL;
1461 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1462 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1463 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1465 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1466 if (rc != ERROR_SUCCESS)
1467 return ERROR_INDEX_ABSENT;
1470 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
1474 return ERROR_INDEX_ABSENT;
1477 info = HeapAlloc(GetProcessHeap(),0,sz);
1478 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
1479 if (rc != ERROR_SUCCESS)
1482 HeapFree(GetProcessHeap(),0,info);
1483 return ERROR_INDEX_ABSENT;
1486 /* find the component */
1487 ptr = strchrW(&info[20],'>');
1493 HeapFree(GetProcessHeap(),0,info);
1494 return ERROR_INDEX_ABSENT;
1499 decode_base85_guid(info,&clsid);
1500 StringFromCLSID(&clsid, &product);
1502 decode_base85_guid(ptr,&clsid);
1503 StringFromCLSID(&clsid, &component);
1506 rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
1508 rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
1511 HeapFree(GetProcessHeap(),0,info);
1512 HeapFree(GetProcessHeap(),0,product);
1513 HeapFree(GetProcessHeap(),0,component);
1515 if (rc == INSTALLSTATE_LOCAL)
1516 return ERROR_SUCCESS;
1518 return ERROR_FILE_NOT_FOUND;
1521 /***********************************************************************
1522 * MsiProvideQualifiedComponentW [MSI.@]
1524 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1525 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1528 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1529 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1532 /***********************************************************************
1533 * MsiProvideQualifiedComponentA [MSI.@]
1535 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1536 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1539 LPWSTR szwComponent, szwQualifier, lpwPathBuf;
1543 TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
1544 dwInstallMode, lpPathBuf, pcchPathBuf);
1546 szwComponent= strdupAtoW( szComponent);
1547 szwQualifier= strdupAtoW( szQualifier);
1549 lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR));
1551 pcchwPathBuf = *pcchPathBuf;
1553 rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
1554 dwInstallMode, lpwPathBuf, &pcchwPathBuf);
1556 HeapFree(GetProcessHeap(),0,szwComponent);
1557 HeapFree(GetProcessHeap(),0,szwQualifier);
1558 *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
1559 lpPathBuf, *pcchPathBuf, NULL, NULL);
1561 HeapFree(GetProcessHeap(),0,lpwPathBuf);
1565 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1566 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1567 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1571 UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
1572 static const WCHAR szOwner[] = {'R','e','g','O','w','n','e','r',0};
1573 static const WCHAR szCompany[] = {'R','e','g','C','o','m','p','a','n','y',0};
1574 static const WCHAR szSerial[] = {'P','r','o','d','u','c','t','I','D',0};
1576 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1577 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1580 rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1581 if (rc != ERROR_SUCCESS)
1582 return USERINFOSTATE_UNKNOWN;
1586 sz = *lpUserNameBuf * sizeof(WCHAR);
1587 rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, (LPBYTE)lpUserNameBuf,
1590 if (!lpUserNameBuf && pcchUserNameBuf)
1593 rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, NULL, &sz);
1596 if (pcchUserNameBuf)
1597 *pcchUserNameBuf = sz / sizeof(WCHAR);
1601 sz = *pcchOrgNameBuf * sizeof(WCHAR);
1602 rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL,
1603 (LPBYTE)lpOrgNameBuf, &sz);
1605 if (!lpOrgNameBuf && pcchOrgNameBuf)
1608 rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL, NULL, &sz);
1612 *pcchOrgNameBuf = sz / sizeof(WCHAR);
1614 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA &&
1615 rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA)
1618 return USERINFOSTATE_ABSENT;
1623 sz = *pcchSerialBuf * sizeof(WCHAR);
1624 RegQueryValueExW( hkey, szSerial, NULL, NULL, (LPBYTE)lpSerialBuf,
1627 if (!lpSerialBuf && pcchSerialBuf)
1630 rc = RegQueryValueExW( hkey, szSerial, NULL, NULL, NULL, &sz);
1633 *pcchSerialBuf = sz / sizeof(WCHAR);
1636 return USERINFOSTATE_PRESENT;
1639 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1640 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1641 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1643 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1644 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1647 return USERINFOSTATE_UNKNOWN;
1650 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1654 MSIPACKAGE *package;
1655 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1657 TRACE("(%s)\n",debugstr_w(szProduct));
1659 rc = MsiOpenProductW(szProduct,&handle);
1660 if (rc != ERROR_SUCCESS)
1661 return ERROR_INVALID_PARAMETER;
1663 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1664 rc = ACTION_PerformUIAction(package, szFirstRun);
1665 msiobj_release( &package->hdr );
1667 MsiCloseHandle(handle);
1672 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1676 MSIPACKAGE *package;
1677 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1679 TRACE("(%s)\n",debugstr_a(szProduct));
1681 rc = MsiOpenProductA(szProduct,&handle);
1682 if (rc != ERROR_SUCCESS)
1683 return ERROR_INVALID_PARAMETER;
1685 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1686 rc = ACTION_PerformUIAction(package, szFirstRun);
1687 msiobj_release( &package->hdr );
1689 MsiCloseHandle(handle);
1694 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1696 WCHAR path[MAX_PATH];
1699 FIXME("Don't know how to handle argument %ld\n", dwReserved);
1700 return ERROR_CALL_NOT_IMPLEMENTED;
1703 if(!GetWindowsDirectoryW(path, MAX_PATH)) {
1704 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1706 return ERROR_CALL_NOT_IMPLEMENTED;
1709 strcatW(path, installerW);
1711 CreateDirectoryW(path, NULL);
1716 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1717 LPSTR szProductCode, LPSTR szFeatureId,
1718 LPSTR szComponentCode )
1721 return ERROR_CALL_NOT_IMPLEMENTED;
1724 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1725 LPWSTR szProductCode, LPWSTR szFeatureId,
1726 LPWSTR szComponentCode )
1729 return ERROR_CALL_NOT_IMPLEMENTED;
1732 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1733 DWORD dwReinstallMode )
1735 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1737 return ERROR_SUCCESS;
1740 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1741 DWORD dwReinstallMode )
1743 FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1745 return ERROR_SUCCESS;