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 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
, DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
);
44 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
47 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
48 * which is a problem because LPCTSTR isn't defined when compiling wine.
49 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
50 * and make sure to only use it in W functions.
52 #define LPCTSTR LPCWSTR
55 INSTALLUILEVEL gUILevel
= INSTALLUILEVEL_BASIC
;
57 INSTALLUI_HANDLERA gUIHandlerA
= NULL
;
58 INSTALLUI_HANDLERW gUIHandlerW
= NULL
;
60 LPVOID gUIContext
= NULL
;
61 WCHAR gszLogFile
[MAX_PATH
];
62 HINSTANCE msi_hInstance
;
64 static const WCHAR installerW
[] = {'\\','I','n','s','t','a','l','l','e','r',0};
66 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
69 LPWSTR szwProd
= NULL
;
71 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
75 szwProd
= strdupAtoW( szProduct
);
77 return ERROR_OUTOFMEMORY
;
80 r
= MsiOpenProductW( szwProd
, phProduct
);
82 HeapFree( GetProcessHeap(), 0, szwProd
);
87 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
89 static const WCHAR szLocalPackage
[] = {
90 'L','o','c','a','l','P','a','c','k','a','g','e', 0
94 HKEY hKeyProduct
= NULL
;
97 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
99 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
100 if( r
!= ERROR_SUCCESS
)
102 r
= ERROR_UNKNOWN_PRODUCT
;
106 /* find the size of the path */
108 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
109 NULL
, &type
, NULL
, &count
);
110 if( r
!= ERROR_SUCCESS
)
112 r
= ERROR_UNKNOWN_PRODUCT
;
116 /* now alloc and fetch the path of the database to open */
117 path
= HeapAlloc( GetProcessHeap(), 0, count
);
121 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
122 NULL
, &type
, (LPBYTE
) path
, &count
);
123 if( r
!= ERROR_SUCCESS
)
125 r
= ERROR_UNKNOWN_PRODUCT
;
129 r
= MsiOpenPackageW( path
, phProduct
);
132 HeapFree( GetProcessHeap(), 0, path
);
134 RegCloseKey( hKeyProduct
);
139 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
140 LPCSTR szTransforms
, LANGID lgidLanguage
)
142 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
143 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
144 return ERROR_CALL_NOT_IMPLEMENTED
;
147 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
148 LPCWSTR szTransforms
, LANGID lgidLanguage
)
150 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
151 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
152 return ERROR_CALL_NOT_IMPLEMENTED
;
155 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
156 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
158 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
159 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
160 lgidLanguage
, dwPlatform
, dwOptions
);
161 return ERROR_CALL_NOT_IMPLEMENTED
;
164 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
165 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
167 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
168 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
169 lgidLanguage
, dwPlatform
, dwOptions
);
170 return ERROR_CALL_NOT_IMPLEMENTED
;
173 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
175 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
176 UINT r
= ERROR_OUTOFMEMORY
;
178 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
182 szwPath
= strdupAtoW( szPackagePath
);
189 szwCommand
= strdupAtoW( szCommandLine
);
194 r
= MsiInstallProductW( szwPath
, szwCommand
);
197 HeapFree( GetProcessHeap(), 0, szwPath
);
198 HeapFree( GetProcessHeap(), 0, szwCommand
);
203 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
205 MSIPACKAGE
*package
= NULL
;
209 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
211 r
= MsiVerifyPackageW(szPackagePath
);
212 if (r
!= ERROR_SUCCESS
)
215 r
= MSI_OpenPackageW(szPackagePath
,&package
);
216 if (r
!= ERROR_SUCCESS
)
219 handle
= alloc_msihandle( &package
->hdr
);
221 r
= ACTION_DoTopLevelINSTALL(package
, szPackagePath
, szCommandLine
);
223 MsiCloseHandle(handle
);
224 msiobj_release( &package
->hdr
);
228 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
230 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
231 return ERROR_CALL_NOT_IMPLEMENTED
;
234 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
236 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
237 return ERROR_CALL_NOT_IMPLEMENTED
;
240 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
241 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
243 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
244 eInstallType
, debugstr_a(szCommandLine
));
245 return ERROR_CALL_NOT_IMPLEMENTED
;
248 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
249 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
251 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
252 eInstallType
, debugstr_w(szCommandLine
));
253 return ERROR_CALL_NOT_IMPLEMENTED
;
256 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
257 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
259 MSIHANDLE handle
= -1;
264 static const WCHAR szSouceList
[] = {
265 'S','o','u','r','c','e','L','i','s','t',0};
266 static const WCHAR szLUS
[] = {
267 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
268 WCHAR sourcepath
[0x200];
269 static const WCHAR szInstalled
[] = {
270 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
273 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
274 debugstr_w(szCommandLine
));
276 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
277 eInstallState
!= INSTALLSTATE_DEFAULT
)
279 FIXME("Not implemented for anything other than local installs\n");
280 return ERROR_CALL_NOT_IMPLEMENTED
;
283 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
284 if (rc
!= ERROR_SUCCESS
)
287 rc
= RegOpenKeyW(hkey
,szSouceList
,&hkey1
);
288 if (rc
!= ERROR_SUCCESS
)
291 sz
= sizeof(sourcepath
);
292 rc
= RegQueryValueExW(hkey1
, szLUS
, NULL
, NULL
,(LPBYTE
)sourcepath
, &sz
);
293 if (rc
!= ERROR_SUCCESS
)
298 * ok 1, we need to find the msi file for this product.
299 * 2, find the source dir for the files
300 * 3, do the configure/install.
301 * 4, cleanupany runonce entry.
304 rc
= MsiOpenProductW(szProduct
,&handle
);
305 if (rc
!= ERROR_SUCCESS
)
308 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
311 rc
= ERROR_INVALID_HANDLE
;
315 sz
= lstrlenW(szInstalled
);
318 sz
+= lstrlenW(szCommandLine
);
320 commandline
= HeapAlloc(GetProcessHeap(),0,sz
* sizeof(WCHAR
));
323 lstrcpyW(commandline
,szCommandLine
);
327 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
328 lstrcatW(commandline
,szInstalled
);
330 rc
= ACTION_DoTopLevelINSTALL(package
, sourcepath
, commandline
);
332 msiobj_release( &package
->hdr
);
334 HeapFree(GetProcessHeap(),0,commandline
);
338 MsiCloseHandle(handle
);
343 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
344 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
346 LPWSTR szwProduct
= NULL
;
347 LPWSTR szwCommandLine
= NULL
;
348 UINT r
= ERROR_OUTOFMEMORY
;
352 szwProduct
= strdupAtoW( szProduct
);
359 szwCommandLine
= strdupAtoW( szCommandLine
);
364 r
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
367 HeapFree( GetProcessHeap(), 0, szwProduct
);
368 HeapFree( GetProcessHeap(), 0, szwCommandLine
);
373 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
374 INSTALLSTATE eInstallState
)
376 LPWSTR szwProduct
= NULL
;
379 TRACE("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
383 szwProduct
= strdupAtoW( szProduct
);
385 return ERROR_OUTOFMEMORY
;
388 r
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
389 HeapFree( GetProcessHeap(), 0, szwProduct
);
394 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
395 INSTALLSTATE eInstallState
)
397 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
399 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
, NULL
);
402 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
404 LPWSTR szwComponent
= NULL
;
406 WCHAR szwBuffer
[GUID_SIZE
];
408 TRACE("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
412 szwComponent
= strdupAtoW( szComponent
);
414 return ERROR_OUTOFMEMORY
;
417 r
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
419 if( ERROR_SUCCESS
== r
)
420 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
422 HeapFree( GetProcessHeap(), 0, szwComponent
);
427 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
431 WCHAR szSquished
[GUID_SIZE
];
432 DWORD sz
= GUID_SIZE
;
433 static const WCHAR szPermKey
[] =
434 { '0','0','0','0','0','0','0','0','0','0','0','0',
435 '0','0','0','0','0','0','0', '0','0','0','0','0',
436 '0','0','0','0','0','0','0','0',0};
438 TRACE("%s %p\n",debugstr_w(szComponent
), szBuffer
);
440 if (NULL
== szComponent
)
441 return ERROR_INVALID_PARAMETER
;
443 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
444 if (rc
!= ERROR_SUCCESS
)
445 return ERROR_UNKNOWN_COMPONENT
;
447 rc
= RegEnumValueW(hkey
, 0, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
448 if (rc
== ERROR_SUCCESS
&& strcmpW(szSquished
,szPermKey
)==0)
451 rc
= RegEnumValueW(hkey
, 1, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
456 if (rc
!= ERROR_SUCCESS
)
457 return ERROR_INSTALL_FAILURE
;
459 unsquash_guid(szSquished
, szBuffer
);
460 return ERROR_SUCCESS
;
463 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
464 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
466 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
467 UINT r
= ERROR_OUTOFMEMORY
;
469 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szAttribute
),
470 szBuffer
, pcchValueBuf
);
474 szwProduct
= strdupAtoW( szProduct
);
481 szwAttribute
= strdupAtoW( szAttribute
);
488 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf
) * sizeof(WCHAR
) );
493 r
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
, pcchValueBuf
);
495 if( ERROR_SUCCESS
== r
)
496 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, *pcchValueBuf
, NULL
, NULL
);
499 HeapFree( GetProcessHeap(), 0, szwProduct
);
500 HeapFree( GetProcessHeap(), 0, szwAttribute
);
501 HeapFree( GetProcessHeap(), 0, szwBuffer
);
506 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
507 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
511 static const WCHAR szPackageCode
[] =
512 {'P','a','c','k','a','g','e','C','o','d','e',0};
513 static const WCHAR szVersionString
[] =
514 {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
515 static const WCHAR szProductVersion
[] =
516 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
517 static const WCHAR szAssignmentType
[] =
518 {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
520 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
521 szBuffer
, pcchValueBuf
);
523 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
524 return ERROR_INVALID_PARAMETER
;
525 if (NULL
== szProduct
|| NULL
== szAttribute
)
526 return ERROR_INVALID_PARAMETER
;
528 /* check for special properties */
529 if (strcmpW(szAttribute
, szPackageCode
)==0)
532 WCHAR squished
[GUID_SIZE
];
534 DWORD sz
= sizeof(squished
);
536 r
= MSIREG_OpenUserProductsKey(szProduct
, &hkey
, FALSE
);
537 if (r
!= ERROR_SUCCESS
)
538 return ERROR_UNKNOWN_PRODUCT
;
540 r
= RegQueryValueExW(hkey
, szPackageCode
, NULL
, NULL
,
541 (LPBYTE
)squished
, &sz
);
542 if (r
!= ERROR_SUCCESS
)
545 return ERROR_UNKNOWN_PRODUCT
;
548 unsquash_guid(squished
, package
);
549 *pcchValueBuf
= strlenW(package
);
550 if (strlenW(package
) > *pcchValueBuf
)
553 return ERROR_MORE_DATA
;
556 strcpyW(szBuffer
, package
);
561 else if (strcmpW(szAttribute
, szVersionString
)==0)
563 r
= MsiOpenProductW(szProduct
, &hProduct
);
564 if (ERROR_SUCCESS
!= r
)
567 r
= MsiGetPropertyW(hProduct
, szProductVersion
, szBuffer
, pcchValueBuf
);
568 MsiCloseHandle(hProduct
);
570 else if (strcmpW(szAttribute
, szAssignmentType
)==0)
572 FIXME("0 (zero) if advertised, 1(one) if per machine.\n");
579 r
= MsiOpenProductW(szProduct
, &hProduct
);
580 if (ERROR_SUCCESS
!= r
)
583 r
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
584 MsiCloseHandle(hProduct
);
590 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
592 LPWSTR szwLogFile
= NULL
;
595 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
599 szwLogFile
= strdupAtoW( szLogFile
);
601 return ERROR_OUTOFMEMORY
;
603 r
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
604 HeapFree( GetProcessHeap(), 0, szwLogFile
);
608 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
610 HANDLE file
= INVALID_HANDLE_VALUE
;
612 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
614 lstrcpyW(gszLogFile
,szLogFile
);
615 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
616 DeleteFileW(szLogFile
);
617 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
618 FILE_ATTRIBUTE_NORMAL
, NULL
);
619 if (file
!= INVALID_HANDLE_VALUE
)
622 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
624 return ERROR_SUCCESS
;
627 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
629 LPWSTR szwProduct
= NULL
;
634 szwProduct
= strdupAtoW( szProduct
);
636 return ERROR_OUTOFMEMORY
;
638 r
= MsiQueryProductStateW( szwProduct
);
639 HeapFree( GetProcessHeap(), 0, szwProduct
);
643 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
646 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
648 static const WCHAR szWindowsInstaller
[] = {
649 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
652 TRACE("%s\n", debugstr_w(szProduct
));
654 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
655 if (rc
!= ERROR_SUCCESS
)
660 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
661 if (rc
!= ERROR_SUCCESS
)
665 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
666 if (rc
!= ERROR_SUCCESS
)
673 rrc
= INSTALLSTATE_DEFAULT
;
676 FIXME("Unknown install state read from registry (%i)\n",rrc
);
677 rrc
= INSTALLSTATE_UNKNOWN
;
685 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
687 INSTALLUILEVEL old
= gUILevel
;
688 HWND oldwnd
= gUIhwnd
;
690 TRACE("%08x %p\n", dwUILevel
, phWnd
);
692 gUILevel
= dwUILevel
;
701 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
702 DWORD dwMessageFilter
, LPVOID pvContext
)
704 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
706 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
707 gUIHandlerA
= puiHandler
;
708 gUIFilter
= dwMessageFilter
;
709 gUIContext
= pvContext
;
714 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
715 DWORD dwMessageFilter
, LPVOID pvContext
)
717 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
719 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
720 gUIHandlerW
= puiHandler
;
721 gUIFilter
= dwMessageFilter
;
722 gUIContext
= pvContext
;
727 /******************************************************************
728 * MsiLoadStringW [MSI.@]
730 * Loads a string from MSI's string resources.
734 * handle [I] only -1 is handled currently
735 * id [I] id of the string to be loaded
736 * lpBuffer [O] buffer for the string to be written to
737 * nBufferMax [I] maximum size of the buffer in characters
738 * lang [I] the preferred language for the string
742 * If successful, this function returns the language id of the string loaded
743 * If the function fails, the function returns zero.
747 * The type of the first parameter is unknown. LoadString's prototype
748 * suggests that it might be a module handle. I have made it an MSI handle
749 * for starters, as -1 is an invalid MSI handle, but not an invalid module
750 * handle. Maybe strings can be stored in an MSI database somehow.
752 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
753 int nBufferMax
, LANGID lang
)
760 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
763 FIXME("don't know how to deal with handle = %08lx\n", handle
);
766 lang
= GetUserDefaultLangID();
768 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
772 hResData
= LoadResource( msi_hInstance
, hres
);
775 p
= LockResource( hResData
);
779 for (i
= 0; i
< (id
&0xf); i
++)
783 if( nBufferMax
<= len
)
786 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
789 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
794 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
795 int nBufferMax
, LANGID lang
)
801 bufW
= HeapAlloc(GetProcessHeap(), 0, nBufferMax
*sizeof(WCHAR
));
802 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
805 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
806 if( len
<= nBufferMax
)
807 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
808 lpBuffer
, nBufferMax
, NULL
, NULL
);
812 HeapFree(GetProcessHeap(), 0, bufW
);
816 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
819 FIXME("%s %p %08lx\n", debugstr_a(szComponent
), lpPathBuf
, *pcchBuf
);
820 return INSTALLSTATE_UNKNOWN
;
823 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPSTR lpPathBuf
,
826 FIXME("%s %p %08lx\n", debugstr_w(szComponent
), lpPathBuf
, *pcchBuf
);
827 return INSTALLSTATE_UNKNOWN
;
830 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
831 WORD wLanguageId
, DWORD f
)
833 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
834 uType
,wLanguageId
,f
);
835 return ERROR_CALL_NOT_IMPLEMENTED
;
838 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
839 WORD wLanguageId
, DWORD f
)
841 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
842 uType
,wLanguageId
,f
);
843 return ERROR_CALL_NOT_IMPLEMENTED
;
846 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
847 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
850 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
851 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
853 return ERROR_CALL_NOT_IMPLEMENTED
;
856 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
857 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
860 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
861 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
863 return ERROR_CALL_NOT_IMPLEMENTED
;
866 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
867 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
869 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
870 return ERROR_CALL_NOT_IMPLEMENTED
;
873 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
874 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
876 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
877 return ERROR_CALL_NOT_IMPLEMENTED
;
880 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
881 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
884 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
885 ppcCertContext
, pbHashData
, pcbHashData
);
886 return ERROR_CALL_NOT_IMPLEMENTED
;
889 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
890 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
893 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
894 ppcCertContext
, pbHashData
, pcbHashData
);
895 return ERROR_CALL_NOT_IMPLEMENTED
;
898 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
899 LPSTR szValue
, DWORD
*pccbValue
)
901 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
902 return ERROR_CALL_NOT_IMPLEMENTED
;
905 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
906 LPWSTR szValue
, DWORD
*pccbValue
)
908 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
909 return ERROR_CALL_NOT_IMPLEMENTED
;
912 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
915 LPWSTR szPack
= NULL
;
917 TRACE("%s\n", debugstr_a(szPackage
) );
921 szPack
= strdupAtoW( szPackage
);
923 return ERROR_OUTOFMEMORY
;
926 r
= MsiVerifyPackageW( szPack
);
928 HeapFree( GetProcessHeap(), 0, szPack
);
933 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
938 TRACE("%s\n", debugstr_w(szPackage
) );
940 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
941 MsiCloseHandle( handle
);
946 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
947 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
949 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
955 szwProduct
= strdupAtoW( szProduct
);
957 return ERROR_OUTOFMEMORY
;
962 szwComponent
= strdupAtoW( szComponent
);
965 HeapFree( GetProcessHeap(), 0, szwProduct
);
966 return ERROR_OUTOFMEMORY
;
970 if( pcchBuf
&& *pcchBuf
> 0 )
971 lpwPathBuf
= HeapAlloc( GetProcessHeap(), 0, *pcchBuf
* sizeof(WCHAR
));
975 incoming_len
= *pcchBuf
;
976 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
978 HeapFree( GetProcessHeap(), 0, szwProduct
);
979 HeapFree( GetProcessHeap(), 0, szwComponent
);
982 if (rc
!= INSTALLSTATE_UNKNOWN
)
983 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
984 lpPathBuf
, incoming_len
, NULL
, NULL
);
985 HeapFree( GetProcessHeap(), 0, lpwPathBuf
);
991 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
992 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
994 WCHAR squished_pc
[GUID_SIZE
];
996 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1001 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1002 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1004 if( lpPathBuf
&& !pcchBuf
)
1005 return INSTALLSTATE_INVALIDARG
;
1007 squash_guid(szProduct
,squished_pc
);
1009 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1010 if( rc
!= ERROR_SUCCESS
)
1015 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1016 if( rc
!= ERROR_SUCCESS
)
1021 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1022 if( rc
!= ERROR_SUCCESS
)
1024 if( type
!= REG_SZ
)
1027 sz
+= sizeof(WCHAR
);
1028 path
= HeapAlloc( GetProcessHeap(), 0, sz
);
1032 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1033 if( rc
!= ERROR_SUCCESS
)
1036 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1037 debugstr_w(szProduct
), debugstr_w(path
));
1041 FIXME("Registry entry.. check entry\n");
1042 rrc
= INSTALLSTATE_LOCAL
;
1046 /* PROBABLY a file */
1047 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1048 rrc
= INSTALLSTATE_LOCAL
;
1050 rrc
= INSTALLSTATE_ABSENT
;
1055 sz
= sz
/ sizeof(WCHAR
);
1056 if( *pcchBuf
>= sz
)
1057 lstrcpyW( lpPathBuf
, path
);
1062 HeapFree(GetProcessHeap(), 0, path
);
1067 /******************************************************************
1068 * MsiQueryFeatureStateA [MSI.@]
1070 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1073 LPWSTR szwProduct
= NULL
;
1074 LPWSTR szwFeature
= NULL
;
1078 szwProduct
= strdupAtoW( szProduct
);
1080 return ERROR_OUTOFMEMORY
;
1085 szwFeature
= strdupAtoW( szFeature
);
1088 HeapFree( GetProcessHeap(), 0, szwProduct
);
1089 return ERROR_OUTOFMEMORY
;
1093 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1095 HeapFree( GetProcessHeap(), 0, szwProduct
);
1096 HeapFree( GetProcessHeap(), 0, szwFeature
);
1101 /******************************************************************
1102 * MsiQueryFeatureStateW [MSI.@]
1104 * This does not verify that the Feature is functional. So i am only going to
1105 * check the existence of the key in the registry. This should tell me if it is
1108 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1114 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1116 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1117 if (rc
!= ERROR_SUCCESS
)
1118 return INSTALLSTATE_UNKNOWN
;
1120 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1123 if (rc
== ERROR_SUCCESS
)
1124 return INSTALLSTATE_LOCAL
;
1126 return INSTALLSTATE_ABSENT
;
1129 /******************************************************************
1130 * MsiGetFileVersionA [MSI.@]
1132 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1133 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1135 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1136 UINT ret
= ERROR_OUTOFMEMORY
;
1140 szwFilePath
= strdupAtoW( szFilePath
);
1145 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1147 lpwVersionBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1148 if( !lpwVersionBuff
)
1152 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1154 lpwLangBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1159 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1160 lpwLangBuff
, pcchLangBuf
);
1162 if( lpwVersionBuff
)
1163 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1164 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1166 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1167 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1170 HeapFree(GetProcessHeap(), 0, szwFilePath
);
1171 HeapFree(GetProcessHeap(), 0, lpwVersionBuff
);
1172 HeapFree(GetProcessHeap(), 0, lpwLangBuff
);
1177 /******************************************************************
1178 * MsiGetFileVersionW [MSI.@]
1180 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1181 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1183 static const WCHAR szVersionResource
[] = {'\\',0};
1184 static const WCHAR szVersionFormat
[] = {
1185 '%','d','.','%','d','.','%','d','.','%','d',0};
1186 static const WCHAR szLangFormat
[] = {'%','d',0};
1189 LPVOID lpVer
= NULL
;
1190 VS_FIXEDFILEINFO
*ffi
;
1194 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1195 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1196 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1198 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1200 return GetLastError();
1202 lpVer
= HeapAlloc(GetProcessHeap(), 0, dwVerLen
);
1205 ret
= ERROR_OUTOFMEMORY
;
1209 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1211 ret
= GetLastError();
1214 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1216 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1219 wsprintfW(tmp
, szVersionFormat
,
1220 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1221 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1222 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1223 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1228 *pcchVersionBuf
= 0;
1232 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1234 DWORD lang
= GetUserDefaultLangID();
1236 FIXME("Retrieve language from file\n");
1237 wsprintfW(tmp
, szLangFormat
, lang
);
1238 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1239 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1243 HeapFree(GetProcessHeap(), 0, lpVer
);
1248 /******************************************************************
1251 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1255 case DLL_PROCESS_ATTACH
:
1256 msi_hInstance
= hinstDLL
;
1257 DisableThreadLibraryCalls(hinstDLL
);
1258 msi_dialog_register_class();
1260 case DLL_PROCESS_DETACH
:
1261 msi_dialog_unregister_class();
1262 /* FIXME: Cleanup */
1268 typedef struct tagIClassFactoryImpl
1270 IClassFactoryVtbl
*lpVtbl
;
1271 } IClassFactoryImpl
;
1273 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1274 REFIID riid
,LPVOID
*ppobj
)
1276 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1277 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1278 return E_NOINTERFACE
;
1281 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1286 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1291 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1292 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1294 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1296 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1300 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1302 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1304 FIXME("%p %d\n", This
, dolock
);
1308 static IClassFactoryVtbl MsiCF_Vtbl
=
1310 MsiCF_QueryInterface
,
1313 MsiCF_CreateInstance
,
1317 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1319 /******************************************************************
1320 * DllGetClassObject [MSI.@]
1322 HRESULT WINAPI
MSI_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1324 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1326 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1327 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1328 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1329 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1330 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1332 *ppv
= (LPVOID
) &Msi_CF
;
1335 return CLASS_E_CLASSNOTAVAILABLE
;
1338 /******************************************************************
1339 * DllGetVersion [MSI.@]
1341 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
1345 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1346 return E_INVALIDARG
;
1348 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1349 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1350 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1351 pdvi
->dwPlatformID
= 1;
1356 /******************************************************************
1357 * DllCanUnloadNow [MSI.@]
1359 BOOL WINAPI
MSI_DllCanUnloadNow(void)
1364 UINT WINAPI
MsiGetFeatureUsageW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1365 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1367 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1368 pdwUseCount
, pwDateUsed
);
1369 return ERROR_CALL_NOT_IMPLEMENTED
;
1372 UINT WINAPI
MsiGetFeatureUsageA(LPCSTR szProduct
, LPCSTR szFeature
,
1373 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1375 FIXME("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1376 pdwUseCount
, pwDateUsed
);
1377 return ERROR_CALL_NOT_IMPLEMENTED
;
1380 INSTALLSTATE WINAPI
MsiUseFeatureExW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1381 DWORD dwInstallMode
, DWORD dwReserved
)
1383 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1384 dwInstallMode
, dwReserved
);
1387 * Polls all the components of the feature to find install state and then
1389 * Software\\Microsoft\\Windows\\CurrentVersion\\
1390 * Installer\\Products\\<squishguid>\\<feature>
1391 * "Usage"=dword:........
1394 return INSTALLSTATE_LOCAL
;
1397 /***********************************************************************
1398 * MsiUseFeatureExA [MSI.@]
1400 INSTALLSTATE WINAPI
MsiUseFeatureExA(LPCSTR szProduct
, LPCSTR szFeature
,
1401 DWORD dwInstallMode
, DWORD dwReserved
)
1403 FIXME("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1404 dwInstallMode
, dwReserved
);
1406 return INSTALLSTATE_LOCAL
;
1409 INSTALLSTATE WINAPI
MsiUseFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1411 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1413 return INSTALLSTATE_LOCAL
;
1416 INSTALLSTATE WINAPI
MsiUseFeatureA(LPCSTR szProduct
, LPCSTR szFeature
)
1418 FIXME("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
));
1420 return INSTALLSTATE_LOCAL
;
1423 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1424 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1425 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1432 LPWSTR product
= NULL
;
1433 LPWSTR component
= NULL
;
1437 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1438 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1439 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1441 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1442 if (rc
!= ERROR_SUCCESS
)
1443 return ERROR_INDEX_ABSENT
;
1446 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1450 return ERROR_INDEX_ABSENT
;
1453 info
= HeapAlloc(GetProcessHeap(),0,sz
);
1454 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1455 if (rc
!= ERROR_SUCCESS
)
1458 HeapFree(GetProcessHeap(),0,info
);
1459 return ERROR_INDEX_ABSENT
;
1462 /* find the component */
1463 ptr
= strchrW(&info
[20],'>');
1469 HeapFree(GetProcessHeap(),0,info
);
1470 return ERROR_INDEX_ABSENT
;
1475 decode_base85_guid(info
,&clsid
);
1476 StringFromCLSID(&clsid
, &product
);
1478 decode_base85_guid(ptr
,&clsid
);
1479 StringFromCLSID(&clsid
, &component
);
1482 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1484 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1487 HeapFree(GetProcessHeap(),0,info
);
1488 HeapFree(GetProcessHeap(),0,product
);
1489 HeapFree(GetProcessHeap(),0,component
);
1491 if (rc
== INSTALLSTATE_LOCAL
)
1492 return ERROR_SUCCESS
;
1494 return ERROR_FILE_NOT_FOUND
;
1497 /***********************************************************************
1498 * MsiProvideQualifiedComponentW [MSI.@]
1500 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1501 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1504 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1505 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1508 /***********************************************************************
1509 * MsiProvideQualifiedComponentA [MSI.@]
1511 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1512 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1515 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1519 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1520 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1522 szwComponent
= strdupAtoW( szComponent
);
1523 szwQualifier
= strdupAtoW( szQualifier
);
1525 lpwPathBuf
= HeapAlloc(GetProcessHeap(),0,*pcchPathBuf
* sizeof(WCHAR
));
1527 pcchwPathBuf
= *pcchPathBuf
;
1529 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1530 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1532 HeapFree(GetProcessHeap(),0,szwComponent
);
1533 HeapFree(GetProcessHeap(),0,szwQualifier
);
1534 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1535 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1537 HeapFree(GetProcessHeap(),0,lpwPathBuf
);
1541 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1542 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1543 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1547 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1548 static const WCHAR szOwner
[] = {'R','e','g','O','w','n','e','r',0};
1549 static const WCHAR szCompany
[] = {'R','e','g','C','o','m','p','a','n','y',0};
1550 static const WCHAR szSerial
[] = {'P','r','o','d','u','c','t','I','D',0};
1552 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1553 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1556 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1557 if (rc
!= ERROR_SUCCESS
)
1558 return USERINFOSTATE_UNKNOWN
;
1562 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1563 rc
= RegQueryValueExW( hkey
, szOwner
, NULL
, NULL
, (LPBYTE
)lpUserNameBuf
,
1566 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1569 rc
= RegQueryValueExW( hkey
, szOwner
, NULL
, NULL
, NULL
, &sz
);
1572 if (pcchUserNameBuf
)
1573 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1577 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1578 rc2
= RegQueryValueExW( hkey
, szCompany
, NULL
, NULL
,
1579 (LPBYTE
)lpOrgNameBuf
, &sz
);
1581 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1584 rc2
= RegQueryValueExW( hkey
, szCompany
, NULL
, NULL
, NULL
, &sz
);
1588 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1590 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1591 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1594 return USERINFOSTATE_ABSENT
;
1599 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1600 RegQueryValueExW( hkey
, szSerial
, NULL
, NULL
, (LPBYTE
)lpSerialBuf
,
1603 if (!lpSerialBuf
&& pcchSerialBuf
)
1606 rc
= RegQueryValueExW( hkey
, szSerial
, NULL
, NULL
, NULL
, &sz
);
1609 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1612 return USERINFOSTATE_PRESENT
;
1615 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1616 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1617 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1619 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1620 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1623 return USERINFOSTATE_UNKNOWN
;
1626 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1630 MSIPACKAGE
*package
;
1631 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1633 TRACE("(%s)\n",debugstr_w(szProduct
));
1635 rc
= MsiOpenProductW(szProduct
,&handle
);
1636 if (rc
!= ERROR_SUCCESS
)
1637 return ERROR_INVALID_PARAMETER
;
1639 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1640 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1641 msiobj_release( &package
->hdr
);
1643 MsiCloseHandle(handle
);
1648 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1652 MSIPACKAGE
*package
;
1653 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1655 TRACE("(%s)\n",debugstr_a(szProduct
));
1657 rc
= MsiOpenProductA(szProduct
,&handle
);
1658 if (rc
!= ERROR_SUCCESS
)
1659 return ERROR_INVALID_PARAMETER
;
1661 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1662 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1663 msiobj_release( &package
->hdr
);
1665 MsiCloseHandle(handle
);
1670 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1672 WCHAR path
[MAX_PATH
];
1675 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1676 return ERROR_CALL_NOT_IMPLEMENTED
;
1679 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1680 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1682 return ERROR_CALL_NOT_IMPLEMENTED
;
1685 strcatW(path
, installerW
);
1687 CreateDirectoryW(path
, NULL
);
1692 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1693 LPSTR szProductCode
, LPSTR szFeatureId
,
1694 LPSTR szComponentCode
)
1697 return ERROR_CALL_NOT_IMPLEMENTED
;
1700 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1701 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1702 LPWSTR szComponentCode
)
1705 return ERROR_CALL_NOT_IMPLEMENTED
;
1708 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1709 DWORD dwReinstallMode
)
1711 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1713 return ERROR_SUCCESS
;
1716 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1717 DWORD dwReinstallMode
)
1719 FIXME("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1721 return ERROR_SUCCESS
;