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 LONG dll_count
;
58 static const WCHAR installerW
[] = {'\\','I','n','s','t','a','l','l','e','r',0};
61 * Dll lifetime tracking declaration
63 static void LockModule(void)
65 InterlockedIncrement(&dll_count
);
68 static void UnlockModule(void)
70 InterlockedDecrement(&dll_count
);
74 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
77 LPWSTR szwProd
= NULL
;
79 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
83 szwProd
= strdupAtoW( szProduct
);
85 return ERROR_OUTOFMEMORY
;
88 r
= MsiOpenProductW( szwProd
, phProduct
);
95 static UINT
MSI_OpenProductW( LPCWSTR szProduct
, MSIPACKAGE
**ppackage
)
99 HKEY hKeyProduct
= NULL
;
102 TRACE("%s %p\n", debugstr_w(szProduct
), ppackage
);
104 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
105 if( r
!= ERROR_SUCCESS
)
107 r
= ERROR_UNKNOWN_PRODUCT
;
111 /* find the size of the path */
113 r
= RegQueryValueExW( hKeyProduct
, INSTALLPROPERTY_LOCALPACKAGEW
,
114 NULL
, &type
, NULL
, &count
);
115 if( r
!= ERROR_SUCCESS
)
117 r
= ERROR_UNKNOWN_PRODUCT
;
121 /* now alloc and fetch the path of the database to open */
122 path
= msi_alloc( count
);
126 r
= RegQueryValueExW( hKeyProduct
, INSTALLPROPERTY_LOCALPACKAGEW
,
127 NULL
, &type
, (LPBYTE
) path
, &count
);
128 if( r
!= ERROR_SUCCESS
)
130 r
= ERROR_UNKNOWN_PRODUCT
;
134 r
= MSI_OpenPackageW( path
, ppackage
);
139 RegCloseKey( hKeyProduct
);
144 UINT WINAPI
MsiOpenProductW( LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
146 MSIPACKAGE
*package
= NULL
;
149 r
= MSI_OpenProductW( szProduct
, &package
);
150 if( r
== ERROR_SUCCESS
)
152 *phProduct
= alloc_msihandle( &package
->hdr
);
153 msiobj_release( &package
->hdr
);
158 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
159 LPCSTR szTransforms
, LANGID lgidLanguage
)
161 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
162 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
163 return ERROR_CALL_NOT_IMPLEMENTED
;
166 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
167 LPCWSTR szTransforms
, LANGID lgidLanguage
)
169 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
170 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
171 return ERROR_CALL_NOT_IMPLEMENTED
;
174 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
175 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
177 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
178 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
179 lgidLanguage
, dwPlatform
, dwOptions
);
180 return ERROR_CALL_NOT_IMPLEMENTED
;
183 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
184 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
186 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
187 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
188 lgidLanguage
, dwPlatform
, dwOptions
);
189 return ERROR_CALL_NOT_IMPLEMENTED
;
192 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
194 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
195 UINT r
= ERROR_OUTOFMEMORY
;
197 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
201 szwPath
= strdupAtoW( szPackagePath
);
208 szwCommand
= strdupAtoW( szCommandLine
);
213 r
= MsiInstallProductW( szwPath
, szwCommand
);
217 msi_free( szwCommand
);
222 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
224 MSIPACKAGE
*package
= NULL
;
227 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
229 r
= MSI_OpenPackageW( szPackagePath
, &package
);
230 if (r
== ERROR_SUCCESS
)
232 r
= MSI_InstallPackage( package
, szPackagePath
, szCommandLine
);
233 msiobj_release( &package
->hdr
);
239 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
241 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
242 return ERROR_CALL_NOT_IMPLEMENTED
;
245 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
247 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
248 return ERROR_CALL_NOT_IMPLEMENTED
;
251 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
252 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
254 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
255 eInstallType
, debugstr_a(szCommandLine
));
256 return ERROR_CALL_NOT_IMPLEMENTED
;
259 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
260 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
262 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
263 eInstallType
, debugstr_w(szCommandLine
));
264 return ERROR_CALL_NOT_IMPLEMENTED
;
267 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
268 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
270 MSIPACKAGE
* package
= NULL
;
273 WCHAR sourcepath
[MAX_PATH
];
274 WCHAR filename
[MAX_PATH
];
275 static const WCHAR szInstalled
[] = {
276 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
279 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
280 debugstr_w(szCommandLine
));
282 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
283 eInstallState
!= INSTALLSTATE_DEFAULT
)
285 FIXME("Not implemented for anything other than local installs\n");
286 return ERROR_CALL_NOT_IMPLEMENTED
;
289 sz
= sizeof(sourcepath
);
290 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
291 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
294 sz
= sizeof(filename
);
295 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
296 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
298 lstrcatW(sourcepath
,filename
);
301 * ok 1, we need to find the msi file for this product.
302 * 2, find the source dir for the files
303 * 3, do the configure/install.
304 * 4, cleanupany runonce entry.
307 r
= MSI_OpenProductW( szProduct
, &package
);
308 if (r
!= ERROR_SUCCESS
)
311 sz
= lstrlenW(szInstalled
) + 1;
314 sz
+= lstrlenW(szCommandLine
);
316 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
319 r
= ERROR_OUTOFMEMORY
;
325 lstrcpyW(commandline
,szCommandLine
);
327 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
328 lstrcatW(commandline
,szInstalled
);
330 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
332 msi_free(commandline
);
335 msiobj_release( &package
->hdr
);
340 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
341 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
343 LPWSTR szwProduct
= NULL
;
344 LPWSTR szwCommandLine
= NULL
;
345 UINT r
= ERROR_OUTOFMEMORY
;
349 szwProduct
= strdupAtoW( szProduct
);
356 szwCommandLine
= strdupAtoW( szCommandLine
);
361 r
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
364 msi_free( szwProduct
);
365 msi_free( szwCommandLine
);
370 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
371 INSTALLSTATE eInstallState
)
373 LPWSTR szwProduct
= NULL
;
376 TRACE("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
380 szwProduct
= strdupAtoW( szProduct
);
382 return ERROR_OUTOFMEMORY
;
385 r
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
386 msi_free( szwProduct
);
391 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
392 INSTALLSTATE eInstallState
)
394 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
396 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
, NULL
);
399 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
401 LPWSTR szwComponent
= NULL
;
403 WCHAR szwBuffer
[GUID_SIZE
];
405 TRACE("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
409 szwComponent
= strdupAtoW( szComponent
);
411 return ERROR_OUTOFMEMORY
;
414 r
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
416 if( ERROR_SUCCESS
== r
)
417 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
419 msi_free( szwComponent
);
424 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
428 WCHAR szSquished
[GUID_SIZE
];
429 DWORD sz
= GUID_SIZE
;
430 static const WCHAR szPermKey
[] =
431 { '0','0','0','0','0','0','0','0','0','0','0','0',
432 '0','0','0','0','0','0','0','0','0','0','0','0',
433 '0','0','0','0','0','0','0','0',0};
435 TRACE("%s %p\n",debugstr_w(szComponent
), szBuffer
);
437 if (NULL
== szComponent
)
438 return ERROR_INVALID_PARAMETER
;
440 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
441 if (rc
!= ERROR_SUCCESS
)
442 return ERROR_UNKNOWN_COMPONENT
;
444 rc
= RegEnumValueW(hkey
, 0, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
445 if (rc
== ERROR_SUCCESS
&& strcmpW(szSquished
,szPermKey
)==0)
448 rc
= RegEnumValueW(hkey
, 1, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
453 if (rc
!= ERROR_SUCCESS
)
454 return ERROR_INSTALL_FAILURE
;
456 unsquash_guid(szSquished
, szBuffer
);
457 return ERROR_SUCCESS
;
460 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
461 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
463 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
464 UINT r
= ERROR_OUTOFMEMORY
;
465 DWORD pcchwValueBuf
= 0;
467 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szAttribute
),
468 szBuffer
, pcchValueBuf
);
472 szwProduct
= strdupAtoW( szProduct
);
479 szwAttribute
= strdupAtoW( szAttribute
);
486 szwBuffer
= msi_alloc( (*pcchValueBuf
) * sizeof(WCHAR
) );
487 pcchwValueBuf
= *pcchValueBuf
;
492 r
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
,
495 if( ERROR_SUCCESS
== r
)
497 INT old_len
= *pcchValueBuf
;
498 *pcchValueBuf
= WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, pcchwValueBuf
,
499 szBuffer
, *pcchValueBuf
, NULL
, NULL
);
500 if (old_len
> *pcchValueBuf
)
501 szBuffer
[*pcchValueBuf
]=0;
505 msi_free( szwProduct
);
506 msi_free( szwAttribute
);
507 msi_free( szwBuffer
);
512 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
513 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
517 static const WCHAR szProductVersion
[] =
518 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
519 static const WCHAR szProductLanguage
[] =
520 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
522 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
523 szBuffer
, pcchValueBuf
);
525 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
526 return ERROR_INVALID_PARAMETER
;
527 if (NULL
== szProduct
|| NULL
== szAttribute
)
528 return ERROR_INVALID_PARAMETER
;
530 /* check for special properties */
531 if (strcmpW(szAttribute
, INSTALLPROPERTY_PACKAGECODEW
)==0)
534 WCHAR squished
[GUID_SIZE
];
536 DWORD sz
= sizeof(squished
);
538 r
= MSIREG_OpenUserProductsKey(szProduct
, &hkey
, FALSE
);
539 if (r
!= ERROR_SUCCESS
)
540 return ERROR_UNKNOWN_PRODUCT
;
542 r
= RegQueryValueExW(hkey
, INSTALLPROPERTY_PACKAGECODEW
, NULL
, NULL
,
543 (LPBYTE
)squished
, &sz
);
544 if (r
!= ERROR_SUCCESS
)
547 return ERROR_UNKNOWN_PRODUCT
;
550 unsquash_guid(squished
, package
);
551 *pcchValueBuf
= strlenW(package
);
552 if (strlenW(package
) > *pcchValueBuf
)
555 return ERROR_MORE_DATA
;
558 strcpyW(szBuffer
, package
);
563 else if (strcmpW(szAttribute
, INSTALLPROPERTY_VERSIONSTRINGW
)==0)
565 r
= MsiOpenProductW(szProduct
, &hProduct
);
566 if (ERROR_SUCCESS
!= r
)
569 r
= MsiGetPropertyW(hProduct
, szProductVersion
, szBuffer
, pcchValueBuf
);
570 MsiCloseHandle(hProduct
);
572 else if (strcmpW(szAttribute
, INSTALLPROPERTY_ASSIGNMENTTYPEW
)==0)
574 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
584 else if (strcmpW(szAttribute
, INSTALLPROPERTY_LANGUAGEW
)==0)
586 r
= MsiOpenProductW(szProduct
, &hProduct
);
587 if (ERROR_SUCCESS
!= r
)
590 r
= MsiGetPropertyW(hProduct
, szProductLanguage
, szBuffer
, pcchValueBuf
);
591 MsiCloseHandle(hProduct
);
595 r
= MsiOpenProductW(szProduct
, &hProduct
);
596 if (ERROR_SUCCESS
!= r
)
599 r
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
600 MsiCloseHandle(hProduct
);
606 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
608 LPWSTR szwLogFile
= NULL
;
611 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
615 szwLogFile
= strdupAtoW( szLogFile
);
617 return ERROR_OUTOFMEMORY
;
619 r
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
620 msi_free( szwLogFile
);
624 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
626 HANDLE file
= INVALID_HANDLE_VALUE
;
628 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
630 lstrcpyW(gszLogFile
,szLogFile
);
631 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
632 DeleteFileW(szLogFile
);
633 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
634 FILE_ATTRIBUTE_NORMAL
, NULL
);
635 if (file
!= INVALID_HANDLE_VALUE
)
638 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
640 return ERROR_SUCCESS
;
643 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
645 LPWSTR szwProduct
= NULL
;
650 szwProduct
= strdupAtoW( szProduct
);
652 return ERROR_OUTOFMEMORY
;
654 r
= MsiQueryProductStateW( szwProduct
);
655 msi_free( szwProduct
);
659 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
662 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
664 static const WCHAR szWindowsInstaller
[] = {
665 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
668 TRACE("%s\n", debugstr_w(szProduct
));
670 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
671 if (rc
!= ERROR_SUCCESS
)
676 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
677 if (rc
!= ERROR_SUCCESS
)
681 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
682 if (rc
!= ERROR_SUCCESS
)
689 rrc
= INSTALLSTATE_DEFAULT
;
692 FIXME("Unknown install state read from registry (%i)\n",rrc
);
693 rrc
= INSTALLSTATE_UNKNOWN
;
701 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
703 INSTALLUILEVEL old
= gUILevel
;
704 HWND oldwnd
= gUIhwnd
;
706 TRACE("%08x %p\n", dwUILevel
, phWnd
);
708 gUILevel
= dwUILevel
;
717 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
718 DWORD dwMessageFilter
, LPVOID pvContext
)
720 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
722 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
723 gUIHandlerA
= puiHandler
;
724 gUIFilter
= dwMessageFilter
;
725 gUIContext
= pvContext
;
730 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
731 DWORD dwMessageFilter
, LPVOID pvContext
)
733 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
735 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
736 gUIHandlerW
= puiHandler
;
737 gUIFilter
= dwMessageFilter
;
738 gUIContext
= pvContext
;
743 /******************************************************************
744 * MsiLoadStringW [MSI.@]
746 * Loads a string from MSI's string resources.
750 * handle [I] only -1 is handled currently
751 * id [I] id of the string to be loaded
752 * lpBuffer [O] buffer for the string to be written to
753 * nBufferMax [I] maximum size of the buffer in characters
754 * lang [I] the preferred language for the string
758 * If successful, this function returns the language id of the string loaded
759 * If the function fails, the function returns zero.
763 * The type of the first parameter is unknown. LoadString's prototype
764 * suggests that it might be a module handle. I have made it an MSI handle
765 * for starters, as -1 is an invalid MSI handle, but not an invalid module
766 * handle. Maybe strings can be stored in an MSI database somehow.
768 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
769 int nBufferMax
, LANGID lang
)
776 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
779 FIXME("don't know how to deal with handle = %08lx\n", handle
);
782 lang
= GetUserDefaultLangID();
784 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
788 hResData
= LoadResource( msi_hInstance
, hres
);
791 p
= LockResource( hResData
);
795 for (i
= 0; i
< (id
&0xf); i
++)
799 if( nBufferMax
<= len
)
802 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
805 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
810 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
811 int nBufferMax
, LANGID lang
)
817 bufW
= msi_alloc(nBufferMax
*sizeof(WCHAR
));
818 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
821 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
822 if( len
<= nBufferMax
)
823 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
824 lpBuffer
, nBufferMax
, NULL
, NULL
);
832 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
835 /* This FIXME will crash some installer
836 * FIXME("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
838 return INSTALLSTATE_UNKNOWN
;
841 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
844 FIXME("%s %p %p\n", debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
845 return INSTALLSTATE_UNKNOWN
;
848 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
849 WORD wLanguageId
, DWORD f
)
851 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
852 uType
,wLanguageId
,f
);
853 return MessageBoxExA(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
856 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
857 WORD wLanguageId
, DWORD f
)
859 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
860 uType
,wLanguageId
,f
);
861 return MessageBoxExW(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
864 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
865 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
868 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
869 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
871 return ERROR_CALL_NOT_IMPLEMENTED
;
874 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
875 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
878 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
879 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
881 return ERROR_CALL_NOT_IMPLEMENTED
;
884 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
885 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
887 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
888 return ERROR_CALL_NOT_IMPLEMENTED
;
891 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
892 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
894 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
895 return ERROR_CALL_NOT_IMPLEMENTED
;
898 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
899 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
902 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
903 ppcCertContext
, pbHashData
, pcbHashData
);
904 return ERROR_CALL_NOT_IMPLEMENTED
;
907 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
908 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
911 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
912 ppcCertContext
, pbHashData
, pcbHashData
);
913 return ERROR_CALL_NOT_IMPLEMENTED
;
916 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
917 LPSTR szValue
, DWORD
*pccbValue
)
919 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
920 return ERROR_CALL_NOT_IMPLEMENTED
;
923 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
924 LPWSTR szValue
, DWORD
*pccbValue
)
926 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
927 return ERROR_CALL_NOT_IMPLEMENTED
;
930 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
933 LPWSTR szPack
= NULL
;
935 TRACE("%s\n", debugstr_a(szPackage
) );
939 szPack
= strdupAtoW( szPackage
);
941 return ERROR_OUTOFMEMORY
;
944 r
= MsiVerifyPackageW( szPack
);
951 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
956 TRACE("%s\n", debugstr_w(szPackage
) );
958 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
959 MsiCloseHandle( handle
);
964 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
965 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
967 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
973 szwProduct
= strdupAtoW( szProduct
);
975 return ERROR_OUTOFMEMORY
;
980 szwComponent
= strdupAtoW( szComponent
);
983 msi_free( szwProduct
);
984 return ERROR_OUTOFMEMORY
;
988 if( pcchBuf
&& *pcchBuf
> 0 )
990 lpwPathBuf
= msi_alloc( *pcchBuf
* sizeof(WCHAR
));
991 incoming_len
= *pcchBuf
;
999 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
1001 msi_free( szwProduct
);
1002 msi_free( szwComponent
);
1005 if (rc
!= INSTALLSTATE_UNKNOWN
)
1006 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
1007 lpPathBuf
, incoming_len
, NULL
, NULL
);
1008 msi_free( lpwPathBuf
);
1014 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1015 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1017 WCHAR squished_pc
[GUID_SIZE
];
1019 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1024 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1025 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1028 return INSTALLSTATE_INVALIDARG
;
1029 if( lpPathBuf
&& !pcchBuf
)
1030 return INSTALLSTATE_INVALIDARG
;
1032 squash_guid(szProduct
,squished_pc
);
1034 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1035 if( rc
!= ERROR_SUCCESS
)
1040 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1041 if( rc
!= ERROR_SUCCESS
)
1046 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1047 if( rc
!= ERROR_SUCCESS
)
1049 if( type
!= REG_SZ
)
1052 sz
+= sizeof(WCHAR
);
1053 path
= msi_alloc( sz
);
1057 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1058 if( rc
!= ERROR_SUCCESS
)
1061 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1062 debugstr_w(szProduct
), debugstr_w(path
));
1066 FIXME("Registry entry.. check entry\n");
1067 rrc
= INSTALLSTATE_LOCAL
;
1071 /* PROBABLY a file */
1072 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1073 rrc
= INSTALLSTATE_LOCAL
;
1075 rrc
= INSTALLSTATE_ABSENT
;
1080 sz
= sz
/ sizeof(WCHAR
);
1081 if( *pcchBuf
>= sz
)
1082 lstrcpyW( lpPathBuf
, path
);
1092 /******************************************************************
1093 * MsiQueryFeatureStateA [MSI.@]
1095 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1097 LPWSTR szwProduct
= NULL
, szwFeature
= NULL
;
1098 INSTALLSTATE rc
= INSTALLSTATE_UNKNOWN
;
1100 szwProduct
= strdupAtoW( szProduct
);
1101 if ( szProduct
&& !szwProduct
)
1104 szwFeature
= strdupAtoW( szFeature
);
1105 if ( szFeature
&& !szwFeature
)
1108 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1111 msi_free( szwProduct
);
1112 msi_free( szwFeature
);
1117 /******************************************************************
1118 * MsiQueryFeatureStateW [MSI.@]
1120 * This does not verify that the Feature is functional. So i am only going to
1121 * check the existence of the key in the registry. This should tell me if it is
1124 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1126 WCHAR squishProduct
[GUID_SIZE
];
1131 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1133 if (!szProduct
|| !szFeature
)
1134 return INSTALLSTATE_INVALIDARG
;
1136 if (!squash_guid( szProduct
, squishProduct
))
1137 return INSTALLSTATE_INVALIDARG
;
1139 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1140 if (rc
!= ERROR_SUCCESS
)
1141 return INSTALLSTATE_UNKNOWN
;
1143 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1146 if (rc
== ERROR_SUCCESS
)
1147 return INSTALLSTATE_LOCAL
;
1149 return INSTALLSTATE_UNKNOWN
;
1152 /******************************************************************
1153 * MsiGetFileVersionA [MSI.@]
1155 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1156 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1158 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1159 UINT ret
= ERROR_OUTOFMEMORY
;
1163 szwFilePath
= strdupAtoW( szFilePath
);
1168 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1170 lpwVersionBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1171 if( !lpwVersionBuff
)
1175 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1177 lpwLangBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1182 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1183 lpwLangBuff
, pcchLangBuf
);
1185 if( lpwVersionBuff
)
1186 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1187 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1189 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1190 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1193 msi_free(szwFilePath
);
1194 msi_free(lpwVersionBuff
);
1195 msi_free(lpwLangBuff
);
1200 /******************************************************************
1201 * MsiGetFileVersionW [MSI.@]
1203 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1204 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1206 static WCHAR szVersionResource
[] = {'\\',0};
1207 static const WCHAR szVersionFormat
[] = {
1208 '%','d','.','%','d','.','%','d','.','%','d',0};
1209 static const WCHAR szLangFormat
[] = {'%','d',0};
1212 LPVOID lpVer
= NULL
;
1213 VS_FIXEDFILEINFO
*ffi
;
1217 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1218 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1219 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1221 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1223 return GetLastError();
1225 lpVer
= msi_alloc(dwVerLen
);
1228 ret
= ERROR_OUTOFMEMORY
;
1232 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1234 ret
= GetLastError();
1237 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1239 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1242 wsprintfW(tmp
, szVersionFormat
,
1243 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1244 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1245 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1246 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1251 *pcchVersionBuf
= 0;
1255 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1257 DWORD lang
= GetUserDefaultLangID();
1259 FIXME("Retrieve language from file\n");
1260 wsprintfW(tmp
, szLangFormat
, lang
);
1261 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1262 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1271 /******************************************************************
1274 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1278 case DLL_PROCESS_ATTACH
:
1279 msi_hInstance
= hinstDLL
;
1280 DisableThreadLibraryCalls(hinstDLL
);
1281 msi_dialog_register_class();
1283 case DLL_PROCESS_DETACH
:
1284 msi_dialog_unregister_class();
1285 /* FIXME: Cleanup */
1291 typedef struct tagIClassFactoryImpl
1293 const IClassFactoryVtbl
*lpVtbl
;
1294 } IClassFactoryImpl
;
1296 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1297 REFIID riid
,LPVOID
*ppobj
)
1299 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1300 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1301 return E_NOINTERFACE
;
1304 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1310 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1316 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1317 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1319 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1321 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1325 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1327 TRACE("(%p)->(%d)\n", iface
, dolock
);
1337 static const IClassFactoryVtbl MsiCF_Vtbl
=
1339 MsiCF_QueryInterface
,
1342 MsiCF_CreateInstance
,
1346 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1348 /******************************************************************
1349 * DllGetClassObject [MSI.@]
1351 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1353 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1355 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1356 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1357 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1358 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1359 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1361 *ppv
= (LPVOID
) &Msi_CF
;
1364 return CLASS_E_CLASSNOTAVAILABLE
;
1367 /******************************************************************
1368 * DllGetVersion [MSI.@]
1370 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1374 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1375 return E_INVALIDARG
;
1377 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1378 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1379 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1380 pdvi
->dwPlatformID
= 1;
1385 /******************************************************************
1386 * DllCanUnloadNow [MSI.@]
1388 HRESULT WINAPI
DllCanUnloadNow(void)
1390 return dll_count
== 0 ? S_OK
: S_FALSE
;
1393 /***********************************************************************
1394 * MsiGetFeatureUsageW [MSI.@]
1396 UINT WINAPI
MsiGetFeatureUsageW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1397 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1399 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1400 pdwUseCount
, pwDateUsed
);
1401 return ERROR_CALL_NOT_IMPLEMENTED
;
1404 /***********************************************************************
1405 * MsiGetFeatureUsageA [MSI.@]
1407 UINT WINAPI
MsiGetFeatureUsageA( LPCSTR szProduct
, LPCSTR szFeature
,
1408 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1410 LPWSTR prod
= NULL
, feat
= NULL
;
1411 UINT ret
= ERROR_OUTOFMEMORY
;
1413 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1414 pdwUseCount
, pwDateUsed
);
1416 prod
= strdupAtoW( szProduct
);
1417 if (szProduct
&& !prod
)
1420 feat
= strdupAtoW( szFeature
);
1421 if (szFeature
&& !feat
)
1424 ret
= MsiGetFeatureUsageW( prod
, feat
, pdwUseCount
, pwDateUsed
);
1433 /***********************************************************************
1434 * MsiUseFeatureExW [MSI.@]
1436 INSTALLSTATE WINAPI
MsiUseFeatureExW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1437 DWORD dwInstallMode
, DWORD dwReserved
)
1441 TRACE("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1442 dwInstallMode
, dwReserved
);
1444 state
= MsiQueryFeatureStateW( szProduct
, szFeature
);
1447 return INSTALLSTATE_INVALIDARG
;
1449 if (state
== INSTALLSTATE_LOCAL
&& dwInstallMode
!= INSTALLMODE_NODETECTION
)
1451 FIXME("mark product %s feature %s as used\n",
1452 debugstr_w(szProduct
), debugstr_w(szFeature
) );
1458 /***********************************************************************
1459 * MsiUseFeatureExA [MSI.@]
1461 INSTALLSTATE WINAPI
MsiUseFeatureExA( LPCSTR szProduct
, LPCSTR szFeature
,
1462 DWORD dwInstallMode
, DWORD dwReserved
)
1464 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1465 LPWSTR prod
= NULL
, feat
= NULL
;
1467 TRACE("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1468 dwInstallMode
, dwReserved
);
1470 prod
= strdupAtoW( szProduct
);
1471 if (szProduct
&& !prod
)
1474 feat
= strdupAtoW( szFeature
);
1475 if (szFeature
&& !feat
)
1478 ret
= MsiUseFeatureExW( prod
, feat
, dwInstallMode
, dwReserved
);
1487 INSTALLSTATE WINAPI
MsiUseFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
)
1489 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1491 return INSTALLSTATE_LOCAL
;
1494 INSTALLSTATE WINAPI
MsiUseFeatureA( LPCSTR szProduct
, LPCSTR szFeature
)
1496 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1497 LPWSTR prod
= NULL
, feat
= NULL
;
1499 TRACE("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
) );
1501 prod
= strdupAtoW( szProduct
);
1502 if (szProduct
&& !prod
)
1505 feat
= strdupAtoW( szFeature
);
1506 if (szFeature
&& !feat
)
1509 ret
= MsiUseFeatureW( prod
, feat
);
1518 /***********************************************************************
1519 * MsiProvideQualifiedComponentExW [MSI.@]
1521 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1522 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1523 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1530 WCHAR product
[MAX_FEATURE_CHARS
+1];
1531 WCHAR component
[MAX_FEATURE_CHARS
+1];
1532 WCHAR feature
[MAX_FEATURE_CHARS
+1];
1534 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1535 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1536 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1538 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1539 if (rc
!= ERROR_SUCCESS
)
1540 return ERROR_INDEX_ABSENT
;
1543 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1547 return ERROR_INDEX_ABSENT
;
1550 info
= msi_alloc(sz
);
1551 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1552 if (rc
!= ERROR_SUCCESS
)
1556 return ERROR_INDEX_ABSENT
;
1559 MsiDecomposeDescriptorW(info
, product
, feature
, component
, &sz
);
1562 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1564 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1569 if (rc
== INSTALLSTATE_LOCAL
)
1570 return ERROR_SUCCESS
;
1572 return ERROR_FILE_NOT_FOUND
;
1575 /***********************************************************************
1576 * MsiProvideQualifiedComponentW [MSI.@]
1578 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1579 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1582 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1583 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1586 /***********************************************************************
1587 * MsiProvideQualifiedComponentA [MSI.@]
1589 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1590 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1593 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1597 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1598 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1600 szwComponent
= strdupAtoW( szComponent
);
1601 szwQualifier
= strdupAtoW( szQualifier
);
1603 lpwPathBuf
= msi_alloc(*pcchPathBuf
* sizeof(WCHAR
));
1605 pcchwPathBuf
= *pcchPathBuf
;
1607 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1608 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1610 msi_free(szwComponent
);
1611 msi_free(szwQualifier
);
1612 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1613 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1615 msi_free(lpwPathBuf
);
1619 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1620 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1621 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1625 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1627 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1628 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1631 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1632 if (rc
!= ERROR_SUCCESS
)
1633 return USERINFOSTATE_UNKNOWN
;
1637 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1638 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1639 NULL
, (LPBYTE
)lpUserNameBuf
,
1642 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1645 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1649 if (pcchUserNameBuf
)
1650 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1654 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1655 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1656 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1658 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1661 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1666 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1668 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1669 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1672 return USERINFOSTATE_ABSENT
;
1677 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1678 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1679 (LPBYTE
)lpSerialBuf
, &sz
);
1681 if (!lpSerialBuf
&& pcchSerialBuf
)
1684 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1688 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1691 return USERINFOSTATE_PRESENT
;
1694 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1695 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1696 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1698 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1699 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1702 return USERINFOSTATE_UNKNOWN
;
1705 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1709 MSIPACKAGE
*package
;
1710 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1712 TRACE("(%s)\n",debugstr_w(szProduct
));
1714 rc
= MsiOpenProductW(szProduct
,&handle
);
1715 if (rc
!= ERROR_SUCCESS
)
1716 return ERROR_INVALID_PARAMETER
;
1718 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1719 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1720 msiobj_release( &package
->hdr
);
1722 MsiCloseHandle(handle
);
1727 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1731 MSIPACKAGE
*package
;
1732 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1734 TRACE("(%s)\n",debugstr_a(szProduct
));
1736 rc
= MsiOpenProductA(szProduct
,&handle
);
1737 if (rc
!= ERROR_SUCCESS
)
1738 return ERROR_INVALID_PARAMETER
;
1740 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1741 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1742 msiobj_release( &package
->hdr
);
1744 MsiCloseHandle(handle
);
1749 /***********************************************************************
1750 * MsiConfigureFeatureA [MSI.@]
1752 UINT WINAPI
MsiConfigureFeatureA(LPCSTR szProduct
, LPCSTR szFeature
, INSTALLSTATE eInstallState
)
1754 FIXME("%s %s %i\n", debugstr_a(szProduct
), debugstr_a(szFeature
), eInstallState
);
1755 return ERROR_SUCCESS
;
1758 /***********************************************************************
1759 * MsiConfigureFeatureW [MSI.@]
1761 UINT WINAPI
MsiConfigureFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
, INSTALLSTATE eInstallState
)
1763 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1764 return ERROR_SUCCESS
;
1767 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1769 WCHAR path
[MAX_PATH
];
1772 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1773 return ERROR_CALL_NOT_IMPLEMENTED
;
1776 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1777 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1779 return ERROR_CALL_NOT_IMPLEMENTED
;
1782 strcatW(path
, installerW
);
1784 CreateDirectoryW(path
, NULL
);
1789 /***********************************************************************
1790 * MsiGetShortcutTargetA [MSI.@]
1792 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1793 LPSTR szProductCode
, LPSTR szFeatureId
,
1794 LPSTR szComponentCode
)
1797 const int len
= MAX_FEATURE_CHARS
+1;
1798 WCHAR product
[MAX_FEATURE_CHARS
+1], feature
[MAX_FEATURE_CHARS
+1], component
[MAX_FEATURE_CHARS
+1];
1801 target
= strdupAtoW( szShortcutTarget
);
1802 if (szShortcutTarget
&& !target
)
1803 return ERROR_OUTOFMEMORY
;
1807 r
= MsiGetShortcutTargetW( target
, product
, feature
, component
);
1809 if (r
== ERROR_SUCCESS
)
1811 WideCharToMultiByte( CP_ACP
, 0, product
, -1, szProductCode
, len
, NULL
, NULL
);
1812 WideCharToMultiByte( CP_ACP
, 0, feature
, -1, szFeatureId
, len
, NULL
, NULL
);
1813 WideCharToMultiByte( CP_ACP
, 0, component
, -1, szComponentCode
, len
, NULL
, NULL
);
1818 /***********************************************************************
1819 * MsiGetShortcutTargetW [MSI.@]
1821 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1822 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1823 LPWSTR szComponentCode
)
1825 IShellLinkDataList
*dl
= NULL
;
1826 IPersistFile
*pf
= NULL
;
1827 LPEXP_DARWIN_LINK darwin
= NULL
;
1830 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget
),
1831 szProductCode
, szFeatureId
, szComponentCode
);
1833 init
= CoInitialize(NULL
);
1835 r
= CoCreateInstance( &CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
1836 &IID_IPersistFile
, (LPVOID
*) &pf
);
1837 if( SUCCEEDED( r
) )
1839 r
= IPersistFile_Load( pf
, szShortcutTarget
,
1840 STGM_READ
| STGM_SHARE_DENY_WRITE
);
1841 if( SUCCEEDED( r
) )
1843 r
= IPersistFile_QueryInterface( pf
, &IID_IShellLinkDataList
,
1845 if( SUCCEEDED( r
) )
1847 IShellLinkDataList_CopyDataBlock( dl
, EXP_DARWIN_ID_SIG
,
1849 IShellLinkDataList_Release( dl
);
1852 IPersistFile_Release( pf
);
1855 if (SUCCEEDED(init
))
1858 TRACE("darwin = %p\n", darwin
);
1865 ret
= MsiDecomposeDescriptorW( darwin
->szwDarwinID
,
1866 szProductCode
, szFeatureId
, szComponentCode
, &sz
);
1867 LocalFree( darwin
);
1871 return ERROR_FUNCTION_FAILED
;
1874 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1875 DWORD dwReinstallMode
)
1877 MSIPACKAGE
* package
= NULL
;
1880 WCHAR sourcepath
[MAX_PATH
];
1881 WCHAR filename
[MAX_PATH
];
1882 static const WCHAR szInstalled
[] = {
1883 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1884 static const WCHAR fmt
[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1885 static const WCHAR REINSTALLMODE
[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1886 WCHAR reinstallmode
[11];
1890 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1893 memset(reinstallmode
,0,sizeof(reinstallmode
));
1894 ptr
= reinstallmode
;
1896 if (dwReinstallMode
& REINSTALLMODE_FILEMISSING
)
1897 { *ptr
= 'p'; ptr
++; }
1898 if (dwReinstallMode
& REINSTALLMODE_FILEOLDERVERSION
)
1899 { *ptr
= 'o'; ptr
++; }
1900 if (dwReinstallMode
& REINSTALLMODE_FILEEQUALVERSION
)
1901 { *ptr
= 'w'; ptr
++; }
1902 if (dwReinstallMode
& REINSTALLMODE_FILEEXACT
)
1903 { *ptr
= 'd'; ptr
++; }
1904 if (dwReinstallMode
& REINSTALLMODE_FILEVERIFY
)
1905 { *ptr
= 'c'; ptr
++; }
1906 if (dwReinstallMode
& REINSTALLMODE_FILEREPLACE
)
1907 { *ptr
= 'a'; ptr
++; }
1908 if (dwReinstallMode
& REINSTALLMODE_USERDATA
)
1909 { *ptr
= 'u'; ptr
++; }
1910 if (dwReinstallMode
& REINSTALLMODE_MACHINEDATA
)
1911 { *ptr
= 'm'; ptr
++; }
1912 if (dwReinstallMode
& REINSTALLMODE_SHORTCUT
)
1913 { *ptr
= 's'; ptr
++; }
1914 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1915 { *ptr
= 'v'; ptr
++; }
1917 sz
= sizeof(sourcepath
);
1918 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1919 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
1922 sz
= sizeof(filename
);
1923 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1924 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
1926 strcatW(sourcepath
,filename
);
1928 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1929 r
= MSI_OpenPackageW( sourcepath
, &package
);
1931 r
= MSI_OpenProductW( szProduct
, &package
);
1933 if (r
!= ERROR_SUCCESS
)
1936 MSI_SetPropertyW(package
,REINSTALLMODE
,reinstallmode
);
1938 sz
= lstrlenW(szInstalled
);
1939 sz
+= lstrlenW(fmt
);
1940 sz
+= lstrlenW(szFeature
);
1942 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
1944 sprintfW(commandline
,fmt
,szFeature
);
1945 lstrcatW(commandline
,szInstalled
);
1947 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
1949 msiobj_release( &package
->hdr
);
1951 msi_free(commandline
);
1956 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1957 DWORD dwReinstallMode
)
1963 TRACE("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1966 wszProduct
= strdupAtoW(szProduct
);
1967 wszFeature
= strdupAtoW(szFeature
);
1969 rc
= MsiReinstallFeatureW(wszProduct
, wszFeature
, dwReinstallMode
);
1971 msi_free(wszProduct
);
1972 msi_free(wszFeature
);
1976 /***********************************************************************
1977 * MsiEnumPatchesA [MSI.@]
1979 UINT WINAPI
MsiEnumPatchesA( LPCSTR szProduct
, DWORD iPatchIndex
,
1980 LPSTR lpPatchBuf
, LPSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1982 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct
),
1983 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1984 return ERROR_NO_MORE_ITEMS
;
1987 /***********************************************************************
1988 * MsiEnumPatchesW [MSI.@]
1990 UINT WINAPI
MsiEnumPatchesW( LPCWSTR szProduct
, DWORD iPatchIndex
,
1991 LPWSTR lpPatchBuf
, LPWSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1993 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct
),
1994 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1995 return ERROR_NO_MORE_ITEMS
;
1998 /***********************************************************************
1999 * MsiGetFileHashW [MSI.@]
2001 UINT WINAPI
MsiGetFileHashW( LPCWSTR szFilePath
, DWORD dwOptions
,
2002 PMSIFILEHASHINFO pHash
)
2004 FIXME("%s %08lx %p\n", debugstr_w(szFilePath
), dwOptions
, pHash
);
2005 return ERROR_CALL_NOT_IMPLEMENTED
;
2008 /***********************************************************************
2009 * MsiGetFileHashA [MSI.@]
2011 UINT WINAPI
MsiGetFileHashA( LPCSTR szFilePath
, DWORD dwOptions
,
2012 PMSIFILEHASHINFO pHash
)
2014 FIXME("%s %08lx %p\n", debugstr_a(szFilePath
), dwOptions
, pHash
);
2015 return ERROR_CALL_NOT_IMPLEMENTED
;
2018 /***********************************************************************
2019 * MsiAdvertiseScriptW [MSI.@]
2021 UINT WINAPI
MsiAdvertiseScriptW( LPCWSTR szScriptFile
, DWORD dwFlags
,
2022 PHKEY phRegData
, BOOL fRemoveItems
)
2024 FIXME("%s %08lx %p %d\n",
2025 debugstr_w( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2026 return ERROR_CALL_NOT_IMPLEMENTED
;
2029 /***********************************************************************
2030 * MsiAdvertiseScriptA [MSI.@]
2032 UINT WINAPI
MsiAdvertiseScriptA( LPCSTR szScriptFile
, DWORD dwFlags
,
2033 PHKEY phRegData
, BOOL fRemoveItems
)
2035 FIXME("%s %08lx %p %d\n",
2036 debugstr_a( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2037 return ERROR_CALL_NOT_IMPLEMENTED
;