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
)
1079 LPWSTR szwProduct
= NULL
, szwFeature
= NULL
;
1080 INSTALLSTATE rc
= INSTALLSTATE_UNKNOWN
;
1082 szwProduct
= strdupAtoW( szProduct
);
1083 if ( szProduct
&& !szwProduct
)
1086 szwFeature
= strdupAtoW( szFeature
);
1087 if ( szFeature
&& !szwFeature
)
1090 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1093 msi_free( szwProduct
);
1094 msi_free( szwFeature
);
1099 /******************************************************************
1100 * MsiQueryFeatureStateW [MSI.@]
1102 * This does not verify that the Feature is functional. So i am only going to
1103 * check the existence of the key in the registry. This should tell me if it is
1106 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1108 WCHAR squishProduct
[GUID_SIZE
];
1113 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1115 if (!szProduct
|| !szFeature
)
1116 return INSTALLSTATE_INVALIDARG
;
1118 if (!squash_guid( szProduct
, squishProduct
))
1119 return INSTALLSTATE_INVALIDARG
;
1121 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1122 if (rc
!= ERROR_SUCCESS
)
1123 return INSTALLSTATE_UNKNOWN
;
1125 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1128 if (rc
== ERROR_SUCCESS
)
1129 return INSTALLSTATE_LOCAL
;
1131 return INSTALLSTATE_UNKNOWN
;
1134 /******************************************************************
1135 * MsiGetFileVersionA [MSI.@]
1137 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1138 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1140 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1141 UINT ret
= ERROR_OUTOFMEMORY
;
1145 szwFilePath
= strdupAtoW( szFilePath
);
1150 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1152 lpwVersionBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1153 if( !lpwVersionBuff
)
1157 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1159 lpwLangBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1164 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1165 lpwLangBuff
, pcchLangBuf
);
1167 if( lpwVersionBuff
)
1168 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1169 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1171 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1172 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1175 msi_free(szwFilePath
);
1176 msi_free(lpwVersionBuff
);
1177 msi_free(lpwLangBuff
);
1182 /******************************************************************
1183 * MsiGetFileVersionW [MSI.@]
1185 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1186 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1188 static WCHAR szVersionResource
[] = {'\\',0};
1189 static const WCHAR szVersionFormat
[] = {
1190 '%','d','.','%','d','.','%','d','.','%','d',0};
1191 static const WCHAR szLangFormat
[] = {'%','d',0};
1194 LPVOID lpVer
= NULL
;
1195 VS_FIXEDFILEINFO
*ffi
;
1199 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1200 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1201 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1203 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1205 return GetLastError();
1207 lpVer
= msi_alloc(dwVerLen
);
1210 ret
= ERROR_OUTOFMEMORY
;
1214 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1216 ret
= GetLastError();
1219 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1221 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1224 wsprintfW(tmp
, szVersionFormat
,
1225 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1226 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1227 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1228 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1233 *pcchVersionBuf
= 0;
1237 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1239 DWORD lang
= GetUserDefaultLangID();
1241 FIXME("Retrieve language from file\n");
1242 wsprintfW(tmp
, szLangFormat
, lang
);
1243 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1244 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1253 /******************************************************************
1256 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1260 case DLL_PROCESS_ATTACH
:
1261 msi_hInstance
= hinstDLL
;
1262 DisableThreadLibraryCalls(hinstDLL
);
1263 msi_dialog_register_class();
1265 case DLL_PROCESS_DETACH
:
1266 msi_dialog_unregister_class();
1267 /* FIXME: Cleanup */
1273 typedef struct tagIClassFactoryImpl
1275 const IClassFactoryVtbl
*lpVtbl
;
1276 } IClassFactoryImpl
;
1278 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1279 REFIID riid
,LPVOID
*ppobj
)
1281 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1282 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1283 return E_NOINTERFACE
;
1286 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1291 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1296 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1297 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1299 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1301 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1305 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1307 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1309 FIXME("%p %d\n", This
, dolock
);
1313 static const IClassFactoryVtbl MsiCF_Vtbl
=
1315 MsiCF_QueryInterface
,
1318 MsiCF_CreateInstance
,
1322 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1324 /******************************************************************
1325 * DllGetClassObject [MSI.@]
1327 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1329 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1331 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1332 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1333 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1334 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1335 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1337 *ppv
= (LPVOID
) &Msi_CF
;
1340 return CLASS_E_CLASSNOTAVAILABLE
;
1343 /******************************************************************
1344 * DllGetVersion [MSI.@]
1346 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1350 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1351 return E_INVALIDARG
;
1353 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1354 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1355 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1356 pdvi
->dwPlatformID
= 1;
1361 /******************************************************************
1362 * DllCanUnloadNow [MSI.@]
1364 HRESULT WINAPI
DllCanUnloadNow(void)
1369 /***********************************************************************
1370 * MsiGetFeatureUsageW [MSI.@]
1372 UINT WINAPI
MsiGetFeatureUsageW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1373 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1375 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1376 pdwUseCount
, pwDateUsed
);
1377 return ERROR_CALL_NOT_IMPLEMENTED
;
1380 /***********************************************************************
1381 * MsiGetFeatureUsageA [MSI.@]
1383 UINT WINAPI
MsiGetFeatureUsageA( LPCSTR szProduct
, LPCSTR szFeature
,
1384 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1386 LPWSTR prod
= NULL
, feat
= NULL
;
1387 UINT ret
= ERROR_OUTOFMEMORY
;
1389 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1390 pdwUseCount
, pwDateUsed
);
1392 prod
= strdupAtoW( szProduct
);
1393 if (szProduct
&& !prod
)
1396 feat
= strdupAtoW( szFeature
);
1397 if (szFeature
&& !feat
)
1400 ret
= MsiGetFeatureUsageW( prod
, feat
, pdwUseCount
, pwDateUsed
);
1409 /***********************************************************************
1410 * MsiUseFeatureExW [MSI.@]
1412 INSTALLSTATE WINAPI
MsiUseFeatureExW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1413 DWORD dwInstallMode
, DWORD dwReserved
)
1417 TRACE("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1418 dwInstallMode
, dwReserved
);
1420 state
= MsiQueryFeatureStateW( szProduct
, szFeature
);
1423 return INSTALLSTATE_INVALIDARG
;
1425 if (state
== INSTALLSTATE_LOCAL
&& dwInstallMode
!= INSTALLMODE_NODETECTION
)
1427 FIXME("mark product %s feature %s as used\n",
1428 debugstr_w(szProduct
), debugstr_w(szFeature
) );
1434 /***********************************************************************
1435 * MsiUseFeatureExA [MSI.@]
1437 INSTALLSTATE WINAPI
MsiUseFeatureExA( LPCSTR szProduct
, LPCSTR szFeature
,
1438 DWORD dwInstallMode
, DWORD dwReserved
)
1440 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1441 LPWSTR prod
= NULL
, feat
= NULL
;
1443 TRACE("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1444 dwInstallMode
, dwReserved
);
1446 prod
= strdupAtoW( szProduct
);
1447 if (szProduct
&& !prod
)
1450 feat
= strdupAtoW( szFeature
);
1451 if (szFeature
&& !feat
)
1454 ret
= MsiUseFeatureExW( prod
, feat
, dwInstallMode
, dwReserved
);
1463 INSTALLSTATE WINAPI
MsiUseFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
)
1465 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1467 return INSTALLSTATE_LOCAL
;
1470 INSTALLSTATE WINAPI
MsiUseFeatureA( LPCSTR szProduct
, LPCSTR szFeature
)
1472 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1473 LPWSTR prod
= NULL
, feat
= NULL
;
1475 TRACE("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
) );
1477 prod
= strdupAtoW( szProduct
);
1478 if (szProduct
&& !prod
)
1481 feat
= strdupAtoW( szFeature
);
1482 if (szFeature
&& !feat
)
1485 ret
= MsiUseFeatureW( prod
, feat
);
1494 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1495 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1496 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1503 LPWSTR product
= NULL
;
1504 LPWSTR component
= NULL
;
1508 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1509 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1510 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1512 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1513 if (rc
!= ERROR_SUCCESS
)
1514 return ERROR_INDEX_ABSENT
;
1517 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1521 return ERROR_INDEX_ABSENT
;
1524 info
= msi_alloc(sz
);
1525 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1526 if (rc
!= ERROR_SUCCESS
)
1530 return ERROR_INDEX_ABSENT
;
1533 /* find the component */
1534 ptr
= strchrW(&info
[20],'>');
1541 return ERROR_INDEX_ABSENT
;
1546 decode_base85_guid(info
,&clsid
);
1547 StringFromCLSID(&clsid
, &product
);
1549 decode_base85_guid(ptr
,&clsid
);
1550 StringFromCLSID(&clsid
, &component
);
1553 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1555 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1560 msi_free(component
);
1562 if (rc
== INSTALLSTATE_LOCAL
)
1563 return ERROR_SUCCESS
;
1565 return ERROR_FILE_NOT_FOUND
;
1568 /***********************************************************************
1569 * MsiProvideQualifiedComponentW [MSI.@]
1571 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1572 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1575 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1576 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1579 /***********************************************************************
1580 * MsiProvideQualifiedComponentA [MSI.@]
1582 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1583 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1586 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1590 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1591 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1593 szwComponent
= strdupAtoW( szComponent
);
1594 szwQualifier
= strdupAtoW( szQualifier
);
1596 lpwPathBuf
= msi_alloc(*pcchPathBuf
* sizeof(WCHAR
));
1598 pcchwPathBuf
= *pcchPathBuf
;
1600 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1601 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1603 msi_free(szwComponent
);
1604 msi_free(szwQualifier
);
1605 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1606 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1608 msi_free(lpwPathBuf
);
1612 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1613 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1614 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1618 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1620 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1621 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1624 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1625 if (rc
!= ERROR_SUCCESS
)
1626 return USERINFOSTATE_UNKNOWN
;
1630 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1631 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1632 NULL
, (LPBYTE
)lpUserNameBuf
,
1635 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1638 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1642 if (pcchUserNameBuf
)
1643 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1647 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1648 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1649 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1651 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1654 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1659 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1661 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1662 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1665 return USERINFOSTATE_ABSENT
;
1670 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1671 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1672 (LPBYTE
)lpSerialBuf
, &sz
);
1674 if (!lpSerialBuf
&& pcchSerialBuf
)
1677 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1681 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1684 return USERINFOSTATE_PRESENT
;
1687 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1688 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1689 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1691 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1692 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1695 return USERINFOSTATE_UNKNOWN
;
1698 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1702 MSIPACKAGE
*package
;
1703 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1705 TRACE("(%s)\n",debugstr_w(szProduct
));
1707 rc
= MsiOpenProductW(szProduct
,&handle
);
1708 if (rc
!= ERROR_SUCCESS
)
1709 return ERROR_INVALID_PARAMETER
;
1711 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1712 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1713 msiobj_release( &package
->hdr
);
1715 MsiCloseHandle(handle
);
1720 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1724 MSIPACKAGE
*package
;
1725 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1727 TRACE("(%s)\n",debugstr_a(szProduct
));
1729 rc
= MsiOpenProductA(szProduct
,&handle
);
1730 if (rc
!= ERROR_SUCCESS
)
1731 return ERROR_INVALID_PARAMETER
;
1733 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1734 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1735 msiobj_release( &package
->hdr
);
1737 MsiCloseHandle(handle
);
1742 /***********************************************************************
1743 * MsiConfigureFeatureA [MSI.@]
1745 UINT WINAPI
MsiConfigureFeatureA(LPCSTR szProduct
, LPCSTR szFeature
, INSTALLSTATE eInstallState
)
1747 FIXME("%s %s %i\n", debugstr_a(szProduct
), debugstr_a(szFeature
), eInstallState
);
1748 return ERROR_SUCCESS
;
1751 /***********************************************************************
1752 * MsiConfigureFeatureW [MSI.@]
1754 UINT WINAPI
MsiConfigureFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
, INSTALLSTATE eInstallState
)
1756 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1757 return ERROR_SUCCESS
;
1760 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1762 WCHAR path
[MAX_PATH
];
1765 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1766 return ERROR_CALL_NOT_IMPLEMENTED
;
1769 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1770 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1772 return ERROR_CALL_NOT_IMPLEMENTED
;
1775 strcatW(path
, installerW
);
1777 CreateDirectoryW(path
, NULL
);
1782 /***********************************************************************
1783 * MsiGetShortcutTargetA [MSI.@]
1785 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1786 LPSTR szProductCode
, LPSTR szFeatureId
,
1787 LPSTR szComponentCode
)
1790 const int len
= MAX_FEATURE_CHARS
+1;
1791 WCHAR product
[MAX_FEATURE_CHARS
+1], feature
[MAX_FEATURE_CHARS
+1], component
[MAX_FEATURE_CHARS
+1];
1794 target
= strdupAtoW( szShortcutTarget
);
1795 if (szShortcutTarget
&& !target
)
1796 return ERROR_OUTOFMEMORY
;
1800 r
= MsiGetShortcutTargetW( target
, product
, feature
, component
);
1802 if (r
== ERROR_SUCCESS
)
1804 WideCharToMultiByte( CP_ACP
, 0, product
, -1, szProductCode
, len
, NULL
, NULL
);
1805 WideCharToMultiByte( CP_ACP
, 0, feature
, -1, szFeatureId
, len
, NULL
, NULL
);
1806 WideCharToMultiByte( CP_ACP
, 0, component
, -1, szComponentCode
, len
, NULL
, NULL
);
1811 /***********************************************************************
1812 * MsiGetShortcutTargetW [MSI.@]
1814 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1815 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1816 LPWSTR szComponentCode
)
1818 IShellLinkDataList
*dl
= NULL
;
1819 IPersistFile
*pf
= NULL
;
1820 LPEXP_DARWIN_LINK darwin
= NULL
;
1823 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget
),
1824 szProductCode
, szFeatureId
, szComponentCode
);
1826 init
= CoInitialize(NULL
);
1828 r
= CoCreateInstance( &CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
1829 &IID_IPersistFile
, (LPVOID
*) &pf
);
1830 if( SUCCEEDED( r
) )
1832 r
= IPersistFile_Load( pf
, szShortcutTarget
,
1833 STGM_READ
| STGM_SHARE_DENY_WRITE
);
1834 if( SUCCEEDED( r
) )
1836 r
= IPersistFile_QueryInterface( pf
, &IID_IShellLinkDataList
,
1838 if( SUCCEEDED( r
) )
1840 IShellLinkDataList_CopyDataBlock( dl
, EXP_DARWIN_ID_SIG
,
1842 IShellLinkDataList_Release( dl
);
1845 IPersistFile_Release( pf
);
1848 if (SUCCEEDED(init
))
1851 TRACE("darwin = %p\n", darwin
);
1858 ret
= MsiDecomposeDescriptorW( darwin
->szwDarwinID
,
1859 szProductCode
, szFeatureId
, szComponentCode
, &sz
);
1860 LocalFree( darwin
);
1864 return ERROR_FUNCTION_FAILED
;
1867 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1868 DWORD dwReinstallMode
)
1870 MSIPACKAGE
* package
= NULL
;
1873 WCHAR sourcepath
[MAX_PATH
];
1874 WCHAR filename
[MAX_PATH
];
1875 static const WCHAR szInstalled
[] = {
1876 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1877 static const WCHAR fmt
[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1878 static const WCHAR REINSTALLMODE
[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1879 WCHAR reinstallmode
[11];
1883 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1886 memset(reinstallmode
,0,sizeof(reinstallmode
));
1887 ptr
= reinstallmode
;
1889 if (dwReinstallMode
& REINSTALLMODE_FILEMISSING
)
1890 { *ptr
= 'p'; ptr
++; }
1891 if (dwReinstallMode
& REINSTALLMODE_FILEOLDERVERSION
)
1892 { *ptr
= 'o'; ptr
++; }
1893 if (dwReinstallMode
& REINSTALLMODE_FILEEQUALVERSION
)
1894 { *ptr
= 'w'; ptr
++; }
1895 if (dwReinstallMode
& REINSTALLMODE_FILEEXACT
)
1896 { *ptr
= 'd'; ptr
++; }
1897 if (dwReinstallMode
& REINSTALLMODE_FILEVERIFY
)
1898 { *ptr
= 'c'; ptr
++; }
1899 if (dwReinstallMode
& REINSTALLMODE_FILEREPLACE
)
1900 { *ptr
= 'a'; ptr
++; }
1901 if (dwReinstallMode
& REINSTALLMODE_USERDATA
)
1902 { *ptr
= 'u'; ptr
++; }
1903 if (dwReinstallMode
& REINSTALLMODE_MACHINEDATA
)
1904 { *ptr
= 'm'; ptr
++; }
1905 if (dwReinstallMode
& REINSTALLMODE_SHORTCUT
)
1906 { *ptr
= 's'; ptr
++; }
1907 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1908 { *ptr
= 'v'; ptr
++; }
1910 sz
= sizeof(sourcepath
);
1911 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1912 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
1915 sz
= sizeof(filename
);
1916 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1917 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
1919 strcatW(sourcepath
,filename
);
1921 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1922 r
= MSI_OpenPackageW( sourcepath
, &package
);
1924 r
= MSI_OpenProductW( szProduct
, &package
);
1926 if (r
!= ERROR_SUCCESS
)
1929 MSI_SetPropertyW(package
,REINSTALLMODE
,reinstallmode
);
1931 sz
= lstrlenW(szInstalled
);
1932 sz
+= lstrlenW(fmt
);
1933 sz
+= lstrlenW(szFeature
);
1935 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
1937 sprintfW(commandline
,fmt
,szFeature
);
1938 lstrcatW(commandline
,szInstalled
);
1940 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
1942 msiobj_release( &package
->hdr
);
1944 msi_free(commandline
);
1949 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1950 DWORD dwReinstallMode
)
1956 TRACE("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1959 wszProduct
= strdupAtoW(szProduct
);
1960 wszFeature
= strdupAtoW(szFeature
);
1962 rc
= MsiReinstallFeatureW(wszProduct
, wszFeature
, dwReinstallMode
);
1964 msi_free(wszProduct
);
1965 msi_free(wszFeature
);
1969 /***********************************************************************
1970 * MsiEnumPatchesA [MSI.@]
1972 UINT WINAPI
MsiEnumPatchesA( LPCSTR szProduct
, DWORD iPatchIndex
,
1973 LPSTR lpPatchBuf
, LPSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1975 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct
),
1976 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1977 return ERROR_NO_MORE_ITEMS
;
1980 /***********************************************************************
1981 * MsiEnumPatchesW [MSI.@]
1983 UINT WINAPI
MsiEnumPatchesW( LPCWSTR szProduct
, DWORD iPatchIndex
,
1984 LPWSTR lpPatchBuf
, LPWSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1986 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct
),
1987 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1988 return ERROR_NO_MORE_ITEMS
;
1991 /***********************************************************************
1992 * MsiGetFileHashW [MSI.@]
1994 UINT WINAPI
MsiGetFileHashW( LPCWSTR szFilePath
, DWORD dwOptions
,
1995 PMSIFILEHASHINFO pHash
)
1997 FIXME("%s %08lx %p\n", debugstr_w(szFilePath
), dwOptions
, pHash
);
1998 return ERROR_CALL_NOT_IMPLEMENTED
;
2001 /***********************************************************************
2002 * MsiGetFileHashA [MSI.@]
2004 UINT WINAPI
MsiGetFileHashA( LPCSTR szFilePath
, DWORD dwOptions
,
2005 PMSIFILEHASHINFO pHash
)
2007 FIXME("%s %08lx %p\n", debugstr_a(szFilePath
), dwOptions
, pHash
);
2008 return ERROR_CALL_NOT_IMPLEMENTED
;
2011 /***********************************************************************
2012 * MsiAdvertiseScriptW [MSI.@]
2014 UINT WINAPI
MsiAdvertiseScriptW( LPCWSTR szScriptFile
, DWORD dwFlags
,
2015 PHKEY phRegData
, BOOL fRemoveItems
)
2017 FIXME("%s %08lx %p %d\n",
2018 debugstr_w( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2019 return ERROR_CALL_NOT_IMPLEMENTED
;
2022 /***********************************************************************
2023 * MsiAdvertiseScriptA [MSI.@]
2025 UINT WINAPI
MsiAdvertiseScriptA( LPCSTR szScriptFile
, DWORD dwFlags
,
2026 PHKEY phRegData
, BOOL fRemoveItems
)
2028 FIXME("%s %08lx %p %d\n",
2029 debugstr_a( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2030 return ERROR_CALL_NOT_IMPLEMENTED
;