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"
41 #include "wine/unicode.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
47 INSTALLUILEVEL gUILevel
= INSTALLUILEVEL_BASIC
;
49 INSTALLUI_HANDLERA gUIHandlerA
= NULL
;
50 INSTALLUI_HANDLERW gUIHandlerW
= NULL
;
52 LPVOID gUIContext
= NULL
;
53 WCHAR gszLogFile
[MAX_PATH
];
54 HINSTANCE msi_hInstance
;
56 static const WCHAR installerW
[] = {'\\','I','n','s','t','a','l','l','e','r',0};
58 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
61 LPWSTR szwProd
= NULL
;
63 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
67 szwProd
= strdupAtoW( szProduct
);
69 return ERROR_OUTOFMEMORY
;
72 r
= MsiOpenProductW( szwProd
, phProduct
);
79 static UINT
MSI_OpenProductW( LPCWSTR szProduct
, MSIPACKAGE
**ppackage
)
83 HKEY hKeyProduct
= NULL
;
86 TRACE("%s %p\n", debugstr_w(szProduct
), ppackage
);
88 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
89 if( r
!= ERROR_SUCCESS
)
91 r
= ERROR_UNKNOWN_PRODUCT
;
95 /* find the size of the path */
97 r
= RegQueryValueExW( hKeyProduct
, INSTALLPROPERTY_LOCALPACKAGEW
,
98 NULL
, &type
, NULL
, &count
);
99 if( r
!= ERROR_SUCCESS
)
101 r
= ERROR_UNKNOWN_PRODUCT
;
105 /* now alloc and fetch the path of the database to open */
106 path
= msi_alloc( count
);
110 r
= RegQueryValueExW( hKeyProduct
, INSTALLPROPERTY_LOCALPACKAGEW
,
111 NULL
, &type
, (LPBYTE
) path
, &count
);
112 if( r
!= ERROR_SUCCESS
)
114 r
= ERROR_UNKNOWN_PRODUCT
;
118 r
= MSI_OpenPackageW( path
, ppackage
);
123 RegCloseKey( hKeyProduct
);
128 UINT WINAPI
MsiOpenProductW( LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
130 MSIPACKAGE
*package
= NULL
;
133 r
= MSI_OpenProductW( szProduct
, &package
);
134 if( r
== ERROR_SUCCESS
)
136 *phProduct
= alloc_msihandle( &package
->hdr
);
137 msiobj_release( &package
->hdr
);
142 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
143 LPCSTR szTransforms
, LANGID lgidLanguage
)
145 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
146 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
147 return ERROR_CALL_NOT_IMPLEMENTED
;
150 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
151 LPCWSTR szTransforms
, LANGID lgidLanguage
)
153 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
154 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
155 return ERROR_CALL_NOT_IMPLEMENTED
;
158 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
159 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
161 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
162 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
163 lgidLanguage
, dwPlatform
, dwOptions
);
164 return ERROR_CALL_NOT_IMPLEMENTED
;
167 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
168 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
170 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
171 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
172 lgidLanguage
, dwPlatform
, dwOptions
);
173 return ERROR_CALL_NOT_IMPLEMENTED
;
176 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
178 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
179 UINT r
= ERROR_OUTOFMEMORY
;
181 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
185 szwPath
= strdupAtoW( szPackagePath
);
192 szwCommand
= strdupAtoW( szCommandLine
);
197 r
= MsiInstallProductW( szwPath
, szwCommand
);
201 msi_free( szwCommand
);
206 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
208 MSIPACKAGE
*package
= NULL
;
211 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
213 r
= MSI_OpenPackageW( szPackagePath
, &package
);
214 if (r
== ERROR_SUCCESS
)
216 r
= MSI_InstallPackage( package
, szPackagePath
, szCommandLine
);
217 msiobj_release( &package
->hdr
);
223 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
225 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
226 return ERROR_CALL_NOT_IMPLEMENTED
;
229 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
231 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
232 return ERROR_CALL_NOT_IMPLEMENTED
;
235 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
236 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
238 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
239 eInstallType
, debugstr_a(szCommandLine
));
240 return ERROR_CALL_NOT_IMPLEMENTED
;
243 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
244 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
246 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
247 eInstallType
, debugstr_w(szCommandLine
));
248 return ERROR_CALL_NOT_IMPLEMENTED
;
251 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
252 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
254 MSIPACKAGE
* package
= NULL
;
257 WCHAR sourcepath
[MAX_PATH
];
258 WCHAR filename
[MAX_PATH
];
259 static const WCHAR szInstalled
[] = {
260 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
263 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
264 debugstr_w(szCommandLine
));
266 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
267 eInstallState
!= INSTALLSTATE_DEFAULT
)
269 FIXME("Not implemented for anything other than local installs\n");
270 return ERROR_CALL_NOT_IMPLEMENTED
;
273 sz
= sizeof(sourcepath
);
274 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
275 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
278 sz
= sizeof(filename
);
279 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
280 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
282 lstrcatW(sourcepath
,filename
);
285 * ok 1, we need to find the msi file for this product.
286 * 2, find the source dir for the files
287 * 3, do the configure/install.
288 * 4, cleanupany runonce entry.
291 r
= MSI_OpenProductW( szProduct
, &package
);
292 if (r
!= ERROR_SUCCESS
)
295 sz
= lstrlenW(szInstalled
) + 1;
298 sz
+= lstrlenW(szCommandLine
);
300 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
303 r
= ERROR_OUTOFMEMORY
;
309 lstrcpyW(commandline
,szCommandLine
);
311 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
312 lstrcatW(commandline
,szInstalled
);
314 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
316 msi_free(commandline
);
319 msiobj_release( &package
->hdr
);
324 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
325 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
327 LPWSTR szwProduct
= NULL
;
328 LPWSTR szwCommandLine
= NULL
;
329 UINT r
= ERROR_OUTOFMEMORY
;
333 szwProduct
= strdupAtoW( szProduct
);
340 szwCommandLine
= strdupAtoW( szCommandLine
);
345 r
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
348 msi_free( szwProduct
);
349 msi_free( szwCommandLine
);
354 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
355 INSTALLSTATE eInstallState
)
357 LPWSTR szwProduct
= NULL
;
360 TRACE("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
364 szwProduct
= strdupAtoW( szProduct
);
366 return ERROR_OUTOFMEMORY
;
369 r
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
370 msi_free( szwProduct
);
375 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
376 INSTALLSTATE eInstallState
)
378 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
380 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
, NULL
);
383 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
385 LPWSTR szwComponent
= NULL
;
387 WCHAR szwBuffer
[GUID_SIZE
];
389 TRACE("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
393 szwComponent
= strdupAtoW( szComponent
);
395 return ERROR_OUTOFMEMORY
;
398 r
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
400 if( ERROR_SUCCESS
== r
)
401 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
403 msi_free( szwComponent
);
408 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
412 WCHAR szSquished
[GUID_SIZE
];
413 DWORD sz
= GUID_SIZE
;
414 static const WCHAR szPermKey
[] =
415 { '0','0','0','0','0','0','0','0','0','0','0','0',
416 '0','0','0','0','0','0','0','0','0','0','0','0',
417 '0','0','0','0','0','0','0','0',0};
419 TRACE("%s %p\n",debugstr_w(szComponent
), szBuffer
);
421 if (NULL
== szComponent
)
422 return ERROR_INVALID_PARAMETER
;
424 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
425 if (rc
!= ERROR_SUCCESS
)
426 return ERROR_UNKNOWN_COMPONENT
;
428 rc
= RegEnumValueW(hkey
, 0, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
429 if (rc
== ERROR_SUCCESS
&& strcmpW(szSquished
,szPermKey
)==0)
432 rc
= RegEnumValueW(hkey
, 1, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
437 if (rc
!= ERROR_SUCCESS
)
438 return ERROR_INSTALL_FAILURE
;
440 unsquash_guid(szSquished
, szBuffer
);
441 return ERROR_SUCCESS
;
444 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
445 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
447 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
448 UINT r
= ERROR_OUTOFMEMORY
;
449 DWORD pcchwValueBuf
= 0;
451 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szAttribute
),
452 szBuffer
, pcchValueBuf
);
456 szwProduct
= strdupAtoW( szProduct
);
463 szwAttribute
= strdupAtoW( szAttribute
);
470 szwBuffer
= msi_alloc( (*pcchValueBuf
) * sizeof(WCHAR
) );
471 pcchwValueBuf
= *pcchValueBuf
;
476 r
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
,
479 if( ERROR_SUCCESS
== r
)
481 INT old_len
= *pcchValueBuf
;
482 *pcchValueBuf
= WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, pcchwValueBuf
,
483 szBuffer
, *pcchValueBuf
, NULL
, NULL
);
484 if (old_len
> *pcchValueBuf
)
485 szBuffer
[*pcchValueBuf
]=0;
489 msi_free( szwProduct
);
490 msi_free( szwAttribute
);
491 msi_free( szwBuffer
);
496 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
497 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
501 static const WCHAR szProductVersion
[] =
502 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
503 static const WCHAR szProductLanguage
[] =
504 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
506 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
507 szBuffer
, pcchValueBuf
);
509 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
510 return ERROR_INVALID_PARAMETER
;
511 if (NULL
== szProduct
|| NULL
== szAttribute
)
512 return ERROR_INVALID_PARAMETER
;
514 /* check for special properties */
515 if (strcmpW(szAttribute
, INSTALLPROPERTY_PACKAGECODEW
)==0)
518 WCHAR squished
[GUID_SIZE
];
520 DWORD sz
= sizeof(squished
);
522 r
= MSIREG_OpenUserProductsKey(szProduct
, &hkey
, FALSE
);
523 if (r
!= ERROR_SUCCESS
)
524 return ERROR_UNKNOWN_PRODUCT
;
526 r
= RegQueryValueExW(hkey
, INSTALLPROPERTY_PACKAGECODEW
, NULL
, NULL
,
527 (LPBYTE
)squished
, &sz
);
528 if (r
!= ERROR_SUCCESS
)
531 return ERROR_UNKNOWN_PRODUCT
;
534 unsquash_guid(squished
, package
);
535 *pcchValueBuf
= strlenW(package
);
536 if (strlenW(package
) > *pcchValueBuf
)
539 return ERROR_MORE_DATA
;
542 strcpyW(szBuffer
, package
);
547 else if (strcmpW(szAttribute
, INSTALLPROPERTY_VERSIONSTRINGW
)==0)
549 r
= MsiOpenProductW(szProduct
, &hProduct
);
550 if (ERROR_SUCCESS
!= r
)
553 r
= MsiGetPropertyW(hProduct
, szProductVersion
, szBuffer
, pcchValueBuf
);
554 MsiCloseHandle(hProduct
);
556 else if (strcmpW(szAttribute
, INSTALLPROPERTY_ASSIGNMENTTYPEW
)==0)
558 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
568 else if (strcmpW(szAttribute
, INSTALLPROPERTY_LANGUAGEW
)==0)
570 r
= MsiOpenProductW(szProduct
, &hProduct
);
571 if (ERROR_SUCCESS
!= r
)
574 r
= MsiGetPropertyW(hProduct
, szProductLanguage
, szBuffer
, pcchValueBuf
);
575 MsiCloseHandle(hProduct
);
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 msi_free( 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 msi_free( 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
= msi_alloc(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
);
816 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
819 FIXME("%s %p %p\n", debugstr_a(szComponent
), lpPathBuf
, pcchBuf
);
820 return INSTALLSTATE_UNKNOWN
;
823 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
826 FIXME("%s %p %p\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
);
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 msi_free( szwProduct
);
966 return ERROR_OUTOFMEMORY
;
970 if( pcchBuf
&& *pcchBuf
> 0 )
972 lpwPathBuf
= msi_alloc( *pcchBuf
* sizeof(WCHAR
));
973 incoming_len
= *pcchBuf
;
981 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
983 msi_free( szwProduct
);
984 msi_free( szwComponent
);
987 if (rc
!= INSTALLSTATE_UNKNOWN
)
988 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
989 lpPathBuf
, incoming_len
, NULL
, NULL
);
990 msi_free( lpwPathBuf
);
996 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
997 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
999 WCHAR squished_pc
[GUID_SIZE
];
1001 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1006 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1007 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1010 return INSTALLSTATE_INVALIDARG
;
1011 if( lpPathBuf
&& !pcchBuf
)
1012 return INSTALLSTATE_INVALIDARG
;
1014 squash_guid(szProduct
,squished_pc
);
1016 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1017 if( rc
!= ERROR_SUCCESS
)
1022 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1023 if( rc
!= ERROR_SUCCESS
)
1028 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1029 if( rc
!= ERROR_SUCCESS
)
1031 if( type
!= REG_SZ
)
1034 sz
+= sizeof(WCHAR
);
1035 path
= msi_alloc( sz
);
1039 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1040 if( rc
!= ERROR_SUCCESS
)
1043 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1044 debugstr_w(szProduct
), debugstr_w(path
));
1048 FIXME("Registry entry.. check entry\n");
1049 rrc
= INSTALLSTATE_LOCAL
;
1053 /* PROBABLY a file */
1054 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1055 rrc
= INSTALLSTATE_LOCAL
;
1057 rrc
= INSTALLSTATE_ABSENT
;
1062 sz
= sz
/ sizeof(WCHAR
);
1063 if( *pcchBuf
>= sz
)
1064 lstrcpyW( lpPathBuf
, path
);
1074 /******************************************************************
1075 * MsiQueryFeatureStateA [MSI.@]
1077 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1080 LPWSTR szwProduct
= NULL
;
1081 LPWSTR szwFeature
= NULL
;
1085 szwProduct
= strdupAtoW( szProduct
);
1087 return ERROR_OUTOFMEMORY
;
1092 szwFeature
= strdupAtoW( szFeature
);
1095 msi_free( szwProduct
);
1096 return ERROR_OUTOFMEMORY
;
1100 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1102 msi_free( szwProduct
);
1103 msi_free( szwFeature
);
1108 /******************************************************************
1109 * MsiQueryFeatureStateW [MSI.@]
1111 * This does not verify that the Feature is functional. So i am only going to
1112 * check the existence of the key in the registry. This should tell me if it is
1115 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1121 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1123 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1124 if (rc
!= ERROR_SUCCESS
)
1125 return INSTALLSTATE_UNKNOWN
;
1127 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1130 if (rc
== ERROR_SUCCESS
)
1131 return INSTALLSTATE_LOCAL
;
1133 return INSTALLSTATE_ABSENT
;
1136 /******************************************************************
1137 * MsiGetFileVersionA [MSI.@]
1139 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1140 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1142 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1143 UINT ret
= ERROR_OUTOFMEMORY
;
1147 szwFilePath
= strdupAtoW( szFilePath
);
1152 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1154 lpwVersionBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1155 if( !lpwVersionBuff
)
1159 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1161 lpwLangBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1166 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1167 lpwLangBuff
, pcchLangBuf
);
1169 if( lpwVersionBuff
)
1170 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1171 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1173 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1174 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1177 msi_free(szwFilePath
);
1178 msi_free(lpwVersionBuff
);
1179 msi_free(lpwLangBuff
);
1184 /******************************************************************
1185 * MsiGetFileVersionW [MSI.@]
1187 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1188 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1190 static const WCHAR szVersionResource
[] = {'\\',0};
1191 static const WCHAR szVersionFormat
[] = {
1192 '%','d','.','%','d','.','%','d','.','%','d',0};
1193 static const WCHAR szLangFormat
[] = {'%','d',0};
1196 LPVOID lpVer
= NULL
;
1197 VS_FIXEDFILEINFO
*ffi
;
1201 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1202 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1203 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1205 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1207 return GetLastError();
1209 lpVer
= msi_alloc(dwVerLen
);
1212 ret
= ERROR_OUTOFMEMORY
;
1216 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1218 ret
= GetLastError();
1221 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1223 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1226 wsprintfW(tmp
, szVersionFormat
,
1227 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1228 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1229 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1230 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1235 *pcchVersionBuf
= 0;
1239 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1241 DWORD lang
= GetUserDefaultLangID();
1243 FIXME("Retrieve language from file\n");
1244 wsprintfW(tmp
, szLangFormat
, lang
);
1245 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1246 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1255 /******************************************************************
1258 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1262 case DLL_PROCESS_ATTACH
:
1263 msi_hInstance
= hinstDLL
;
1264 DisableThreadLibraryCalls(hinstDLL
);
1265 msi_dialog_register_class();
1267 case DLL_PROCESS_DETACH
:
1268 msi_dialog_unregister_class();
1269 /* FIXME: Cleanup */
1275 typedef struct tagIClassFactoryImpl
1277 const IClassFactoryVtbl
*lpVtbl
;
1278 } IClassFactoryImpl
;
1280 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1281 REFIID riid
,LPVOID
*ppobj
)
1283 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1284 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1285 return E_NOINTERFACE
;
1288 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1293 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1298 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1299 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1301 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1303 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1307 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1309 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1311 FIXME("%p %d\n", This
, dolock
);
1315 static const IClassFactoryVtbl MsiCF_Vtbl
=
1317 MsiCF_QueryInterface
,
1320 MsiCF_CreateInstance
,
1324 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1326 /******************************************************************
1327 * DllGetClassObject [MSI.@]
1329 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1331 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1333 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1334 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1335 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1336 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1337 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1339 *ppv
= (LPVOID
) &Msi_CF
;
1342 return CLASS_E_CLASSNOTAVAILABLE
;
1345 /******************************************************************
1346 * DllGetVersion [MSI.@]
1348 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1352 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1353 return E_INVALIDARG
;
1355 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1356 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1357 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1358 pdvi
->dwPlatformID
= 1;
1363 /******************************************************************
1364 * DllCanUnloadNow [MSI.@]
1366 HRESULT WINAPI
DllCanUnloadNow(void)
1371 /***********************************************************************
1372 * MsiGetFeatureUsageW [MSI.@]
1374 UINT WINAPI
MsiGetFeatureUsageW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1375 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1377 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1378 pdwUseCount
, pwDateUsed
);
1379 return ERROR_CALL_NOT_IMPLEMENTED
;
1382 /***********************************************************************
1383 * MsiGetFeatureUsageA [MSI.@]
1385 UINT WINAPI
MsiGetFeatureUsageA( LPCSTR szProduct
, LPCSTR szFeature
,
1386 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1388 LPWSTR prod
= NULL
, feat
= NULL
;
1389 UINT ret
= ERROR_OUTOFMEMORY
;
1391 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1392 pdwUseCount
, pwDateUsed
);
1394 prod
= strdupAtoW( szProduct
);
1395 if (szProduct
&& !prod
)
1398 feat
= strdupAtoW( szFeature
);
1399 if (szFeature
&& !feat
)
1402 ret
= MsiGetFeatureUsageW( prod
, feat
, pdwUseCount
, pwDateUsed
);
1411 /***********************************************************************
1412 * MsiUseFeatureExW [MSI.@]
1414 INSTALLSTATE WINAPI
MsiUseFeatureExW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1415 DWORD dwInstallMode
, DWORD dwReserved
)
1417 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1418 dwInstallMode
, dwReserved
);
1421 * Polls all the components of the feature to find install state and then
1423 * Software\\Microsoft\\Windows\\CurrentVersion\\
1424 * Installer\\Products\\<squishguid>\\<feature>
1425 * "Usage"=dword:........
1428 return INSTALLSTATE_LOCAL
;
1431 /***********************************************************************
1432 * MsiUseFeatureExA [MSI.@]
1434 INSTALLSTATE WINAPI
MsiUseFeatureExA( LPCSTR szProduct
, LPCSTR szFeature
,
1435 DWORD dwInstallMode
, DWORD dwReserved
)
1437 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1438 LPWSTR prod
= NULL
, feat
= NULL
;
1440 TRACE("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1441 dwInstallMode
, dwReserved
);
1443 prod
= strdupAtoW( szProduct
);
1444 if (szProduct
&& !prod
)
1447 feat
= strdupAtoW( szFeature
);
1448 if (szFeature
&& !feat
)
1451 ret
= MsiUseFeatureExW( prod
, feat
, dwInstallMode
, dwReserved
);
1460 INSTALLSTATE WINAPI
MsiUseFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
)
1462 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1464 return INSTALLSTATE_LOCAL
;
1467 INSTALLSTATE WINAPI
MsiUseFeatureA( LPCSTR szProduct
, LPCSTR szFeature
)
1469 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1470 LPWSTR prod
= NULL
, feat
= NULL
;
1472 TRACE("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
) );
1474 prod
= strdupAtoW( szProduct
);
1475 if (szProduct
&& !prod
)
1478 feat
= strdupAtoW( szFeature
);
1479 if (szFeature
&& !feat
)
1482 ret
= MsiUseFeatureW( prod
, feat
);
1491 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1492 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1493 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1500 LPWSTR product
= NULL
;
1501 LPWSTR component
= NULL
;
1505 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1506 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1507 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1509 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1510 if (rc
!= ERROR_SUCCESS
)
1511 return ERROR_INDEX_ABSENT
;
1514 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1518 return ERROR_INDEX_ABSENT
;
1521 info
= msi_alloc(sz
);
1522 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1523 if (rc
!= ERROR_SUCCESS
)
1527 return ERROR_INDEX_ABSENT
;
1530 /* find the component */
1531 ptr
= strchrW(&info
[20],'>');
1538 return ERROR_INDEX_ABSENT
;
1543 decode_base85_guid(info
,&clsid
);
1544 StringFromCLSID(&clsid
, &product
);
1546 decode_base85_guid(ptr
,&clsid
);
1547 StringFromCLSID(&clsid
, &component
);
1550 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1552 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1557 msi_free(component
);
1559 if (rc
== INSTALLSTATE_LOCAL
)
1560 return ERROR_SUCCESS
;
1562 return ERROR_FILE_NOT_FOUND
;
1565 /***********************************************************************
1566 * MsiProvideQualifiedComponentW [MSI.@]
1568 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1569 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1572 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1573 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1576 /***********************************************************************
1577 * MsiProvideQualifiedComponentA [MSI.@]
1579 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1580 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1583 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1587 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1588 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1590 szwComponent
= strdupAtoW( szComponent
);
1591 szwQualifier
= strdupAtoW( szQualifier
);
1593 lpwPathBuf
= msi_alloc(*pcchPathBuf
* sizeof(WCHAR
));
1595 pcchwPathBuf
= *pcchPathBuf
;
1597 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1598 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1600 msi_free(szwComponent
);
1601 msi_free(szwQualifier
);
1602 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1603 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1605 msi_free(lpwPathBuf
);
1609 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1610 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1611 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1615 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1617 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1618 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1621 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1622 if (rc
!= ERROR_SUCCESS
)
1623 return USERINFOSTATE_UNKNOWN
;
1627 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1628 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1629 NULL
, (LPBYTE
)lpUserNameBuf
,
1632 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1635 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1639 if (pcchUserNameBuf
)
1640 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1644 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1645 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1646 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1648 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1651 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1656 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1658 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1659 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1662 return USERINFOSTATE_ABSENT
;
1667 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1668 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1669 (LPBYTE
)lpSerialBuf
, &sz
);
1671 if (!lpSerialBuf
&& pcchSerialBuf
)
1674 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1678 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1681 return USERINFOSTATE_PRESENT
;
1684 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1685 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1686 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1688 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1689 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1692 return USERINFOSTATE_UNKNOWN
;
1695 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1699 MSIPACKAGE
*package
;
1700 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1702 TRACE("(%s)\n",debugstr_w(szProduct
));
1704 rc
= MsiOpenProductW(szProduct
,&handle
);
1705 if (rc
!= ERROR_SUCCESS
)
1706 return ERROR_INVALID_PARAMETER
;
1708 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1709 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1710 msiobj_release( &package
->hdr
);
1712 MsiCloseHandle(handle
);
1717 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1721 MSIPACKAGE
*package
;
1722 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1724 TRACE("(%s)\n",debugstr_a(szProduct
));
1726 rc
= MsiOpenProductA(szProduct
,&handle
);
1727 if (rc
!= ERROR_SUCCESS
)
1728 return ERROR_INVALID_PARAMETER
;
1730 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1731 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1732 msiobj_release( &package
->hdr
);
1734 MsiCloseHandle(handle
);
1739 /***********************************************************************
1740 * MsiConfigureFeatureA [MSI.@]
1742 UINT WINAPI
MsiConfigureFeatureA(LPCSTR szProduct
, LPCSTR szFeature
, INSTALLSTATE eInstallState
)
1744 FIXME("%s %s %i\n", debugstr_a(szProduct
), debugstr_a(szFeature
), eInstallState
);
1745 return ERROR_SUCCESS
;
1748 /***********************************************************************
1749 * MsiConfigureFeatureW [MSI.@]
1751 UINT WINAPI
MsiConfigureFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
, INSTALLSTATE eInstallState
)
1753 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1754 return ERROR_SUCCESS
;
1757 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1759 WCHAR path
[MAX_PATH
];
1762 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1763 return ERROR_CALL_NOT_IMPLEMENTED
;
1766 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1767 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1769 return ERROR_CALL_NOT_IMPLEMENTED
;
1772 strcatW(path
, installerW
);
1774 CreateDirectoryW(path
, NULL
);
1779 /***********************************************************************
1780 * MsiGetShortcutTargetA [MSI.@]
1782 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1783 LPSTR szProductCode
, LPSTR szFeatureId
,
1784 LPSTR szComponentCode
)
1787 const int len
= MAX_FEATURE_CHARS
+1;
1788 WCHAR product
[MAX_FEATURE_CHARS
+1], feature
[MAX_FEATURE_CHARS
+1], component
[MAX_FEATURE_CHARS
+1];
1791 target
= strdupAtoW( szShortcutTarget
);
1792 if (szShortcutTarget
&& !target
)
1793 return ERROR_OUTOFMEMORY
;
1797 r
= MsiGetShortcutTargetW( target
, product
, feature
, component
);
1799 if (r
== ERROR_SUCCESS
)
1801 WideCharToMultiByte( CP_ACP
, 0, product
, -1, szProductCode
, len
, NULL
, NULL
);
1802 WideCharToMultiByte( CP_ACP
, 0, feature
, -1, szFeatureId
, len
, NULL
, NULL
);
1803 WideCharToMultiByte( CP_ACP
, 0, component
, -1, szComponentCode
, len
, NULL
, NULL
);
1808 /***********************************************************************
1809 * MsiGetShortcutTargetW [MSI.@]
1811 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1812 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1813 LPWSTR szComponentCode
)
1815 IShellLinkDataList
*dl
= NULL
;
1816 IPersistFile
*pf
= NULL
;
1817 LPEXP_DARWIN_LINK darwin
= NULL
;
1820 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget
),
1821 szProductCode
, szFeatureId
, szComponentCode
);
1823 r
= CoInitialize(NULL
);
1825 return ERROR_FUNCTION_FAILED
;
1827 r
= CoCreateInstance( &CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
1828 &IID_IPersistFile
, (LPVOID
*) &pf
);
1829 if( SUCCEEDED( r
) )
1831 r
= IPersistFile_Load( pf
, szShortcutTarget
,
1832 STGM_READ
| STGM_SHARE_DENY_WRITE
);
1833 if( SUCCEEDED( r
) )
1835 r
= IPersistFile_QueryInterface( pf
, &IID_IShellLinkDataList
,
1837 if( SUCCEEDED( r
) )
1839 IShellLinkDataList_CopyDataBlock( dl
, EXP_DARWIN_ID_SIG
,
1841 IShellLinkDataList_Release( dl
);
1844 IPersistFile_Release( pf
);
1849 TRACE("darwin = %p\n", darwin
);
1856 ret
= MsiDecomposeDescriptorW( darwin
->szwDarwinID
,
1857 szProductCode
, szFeatureId
, szComponentCode
, &sz
);
1858 LocalFree( darwin
);
1862 return ERROR_FUNCTION_FAILED
;
1865 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1866 DWORD dwReinstallMode
)
1868 MSIPACKAGE
* package
= NULL
;
1871 WCHAR sourcepath
[MAX_PATH
];
1872 WCHAR filename
[MAX_PATH
];
1873 static const WCHAR szInstalled
[] = {
1874 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1875 static const WCHAR fmt
[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1876 static const WCHAR REINSTALLMODE
[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1877 WCHAR reinstallmode
[11];
1881 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1884 memset(reinstallmode
,0,sizeof(reinstallmode
));
1885 ptr
= reinstallmode
;
1887 if (dwReinstallMode
& REINSTALLMODE_FILEMISSING
)
1888 { *ptr
= 'p'; ptr
++; }
1889 if (dwReinstallMode
& REINSTALLMODE_FILEOLDERVERSION
)
1890 { *ptr
= 'o'; ptr
++; }
1891 if (dwReinstallMode
& REINSTALLMODE_FILEEQUALVERSION
)
1892 { *ptr
= 'w'; ptr
++; }
1893 if (dwReinstallMode
& REINSTALLMODE_FILEEXACT
)
1894 { *ptr
= 'd'; ptr
++; }
1895 if (dwReinstallMode
& REINSTALLMODE_FILEVERIFY
)
1896 { *ptr
= 'c'; ptr
++; }
1897 if (dwReinstallMode
& REINSTALLMODE_FILEREPLACE
)
1898 { *ptr
= 'a'; ptr
++; }
1899 if (dwReinstallMode
& REINSTALLMODE_USERDATA
)
1900 { *ptr
= 'u'; ptr
++; }
1901 if (dwReinstallMode
& REINSTALLMODE_MACHINEDATA
)
1902 { *ptr
= 'm'; ptr
++; }
1903 if (dwReinstallMode
& REINSTALLMODE_SHORTCUT
)
1904 { *ptr
= 's'; ptr
++; }
1905 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1906 { *ptr
= 'v'; ptr
++; }
1908 sz
= sizeof(sourcepath
);
1909 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1910 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
1913 sz
= sizeof(filename
);
1914 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1915 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
1917 strcatW(sourcepath
,filename
);
1919 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1920 r
= MSI_OpenPackageW( sourcepath
, &package
);
1922 r
= MSI_OpenProductW( szProduct
, &package
);
1924 if (r
!= ERROR_SUCCESS
)
1927 MSI_SetPropertyW(package
,REINSTALLMODE
,reinstallmode
);
1929 sz
= lstrlenW(szInstalled
);
1930 sz
+= lstrlenW(fmt
);
1931 sz
+= lstrlenW(szFeature
);
1933 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
1935 sprintfW(commandline
,fmt
,szFeature
);
1936 lstrcatW(commandline
,szInstalled
);
1938 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
1940 msiobj_release( &package
->hdr
);
1942 msi_free(commandline
);
1947 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1948 DWORD dwReinstallMode
)
1954 TRACE("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1957 wszProduct
= strdupAtoW(szProduct
);
1958 wszFeature
= strdupAtoW(szFeature
);
1960 rc
= MsiReinstallFeatureW(wszProduct
, wszFeature
, dwReinstallMode
);
1962 msi_free(wszProduct
);
1963 msi_free(wszFeature
);
1967 /***********************************************************************
1968 * MsiEnumPatchesA [MSI.@]
1970 UINT WINAPI
MsiEnumPatchesA( LPCSTR szProduct
, DWORD iPatchIndex
,
1971 LPSTR lpPatchBuf
, LPSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1973 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct
),
1974 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1975 return ERROR_NO_MORE_ITEMS
;
1978 /***********************************************************************
1979 * MsiEnumPatchesW [MSI.@]
1981 UINT WINAPI
MsiEnumPatchesW( LPCWSTR szProduct
, DWORD iPatchIndex
,
1982 LPWSTR lpPatchBuf
, LPWSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1984 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct
),
1985 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1986 return ERROR_NO_MORE_ITEMS
;