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 FIXME("%s %p %p\n", debugstr_a(szComponent
), lpPathBuf
, pcchBuf
);
836 return INSTALLSTATE_UNKNOWN
;
839 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
842 FIXME("%s %p %p\n", debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
843 return INSTALLSTATE_UNKNOWN
;
846 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
847 WORD wLanguageId
, DWORD f
)
849 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
850 uType
,wLanguageId
,f
);
851 return MessageBoxExA(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
854 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
855 WORD wLanguageId
, DWORD f
)
857 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
858 uType
,wLanguageId
,f
);
859 return MessageBoxExW(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
862 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
863 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
866 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
867 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
869 return ERROR_CALL_NOT_IMPLEMENTED
;
872 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
873 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
876 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
877 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
879 return ERROR_CALL_NOT_IMPLEMENTED
;
882 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
883 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
885 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
886 return ERROR_CALL_NOT_IMPLEMENTED
;
889 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
890 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
892 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
893 return ERROR_CALL_NOT_IMPLEMENTED
;
896 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
897 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
900 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
901 ppcCertContext
, pbHashData
, pcbHashData
);
902 return ERROR_CALL_NOT_IMPLEMENTED
;
905 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
906 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
909 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
910 ppcCertContext
, pbHashData
, pcbHashData
);
911 return ERROR_CALL_NOT_IMPLEMENTED
;
914 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
915 LPSTR szValue
, DWORD
*pccbValue
)
917 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
918 return ERROR_CALL_NOT_IMPLEMENTED
;
921 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
922 LPWSTR szValue
, DWORD
*pccbValue
)
924 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
925 return ERROR_CALL_NOT_IMPLEMENTED
;
928 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
931 LPWSTR szPack
= NULL
;
933 TRACE("%s\n", debugstr_a(szPackage
) );
937 szPack
= strdupAtoW( szPackage
);
939 return ERROR_OUTOFMEMORY
;
942 r
= MsiVerifyPackageW( szPack
);
949 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
954 TRACE("%s\n", debugstr_w(szPackage
) );
956 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
957 MsiCloseHandle( handle
);
962 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
963 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
965 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
971 szwProduct
= strdupAtoW( szProduct
);
973 return ERROR_OUTOFMEMORY
;
978 szwComponent
= strdupAtoW( szComponent
);
981 msi_free( szwProduct
);
982 return ERROR_OUTOFMEMORY
;
986 if( pcchBuf
&& *pcchBuf
> 0 )
988 lpwPathBuf
= msi_alloc( *pcchBuf
* sizeof(WCHAR
));
989 incoming_len
= *pcchBuf
;
997 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
999 msi_free( szwProduct
);
1000 msi_free( szwComponent
);
1003 if (rc
!= INSTALLSTATE_UNKNOWN
)
1004 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
1005 lpPathBuf
, incoming_len
, NULL
, NULL
);
1006 msi_free( lpwPathBuf
);
1012 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1013 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1015 WCHAR squished_pc
[GUID_SIZE
];
1017 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1022 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1023 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1026 return INSTALLSTATE_INVALIDARG
;
1027 if( lpPathBuf
&& !pcchBuf
)
1028 return INSTALLSTATE_INVALIDARG
;
1030 squash_guid(szProduct
,squished_pc
);
1032 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1033 if( rc
!= ERROR_SUCCESS
)
1038 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1039 if( rc
!= ERROR_SUCCESS
)
1044 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1045 if( rc
!= ERROR_SUCCESS
)
1047 if( type
!= REG_SZ
)
1050 sz
+= sizeof(WCHAR
);
1051 path
= msi_alloc( sz
);
1055 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1056 if( rc
!= ERROR_SUCCESS
)
1059 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1060 debugstr_w(szProduct
), debugstr_w(path
));
1064 FIXME("Registry entry.. check entry\n");
1065 rrc
= INSTALLSTATE_LOCAL
;
1069 /* PROBABLY a file */
1070 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1071 rrc
= INSTALLSTATE_LOCAL
;
1073 rrc
= INSTALLSTATE_ABSENT
;
1078 sz
= sz
/ sizeof(WCHAR
);
1079 if( *pcchBuf
>= sz
)
1080 lstrcpyW( lpPathBuf
, path
);
1090 /******************************************************************
1091 * MsiQueryFeatureStateA [MSI.@]
1093 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1095 LPWSTR szwProduct
= NULL
, szwFeature
= NULL
;
1096 INSTALLSTATE rc
= INSTALLSTATE_UNKNOWN
;
1098 szwProduct
= strdupAtoW( szProduct
);
1099 if ( szProduct
&& !szwProduct
)
1102 szwFeature
= strdupAtoW( szFeature
);
1103 if ( szFeature
&& !szwFeature
)
1106 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1109 msi_free( szwProduct
);
1110 msi_free( szwFeature
);
1115 /******************************************************************
1116 * MsiQueryFeatureStateW [MSI.@]
1118 * This does not verify that the Feature is functional. So i am only going to
1119 * check the existence of the key in the registry. This should tell me if it is
1122 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1124 WCHAR squishProduct
[GUID_SIZE
];
1129 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1131 if (!szProduct
|| !szFeature
)
1132 return INSTALLSTATE_INVALIDARG
;
1134 if (!squash_guid( szProduct
, squishProduct
))
1135 return INSTALLSTATE_INVALIDARG
;
1137 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1138 if (rc
!= ERROR_SUCCESS
)
1139 return INSTALLSTATE_UNKNOWN
;
1141 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1144 if (rc
== ERROR_SUCCESS
)
1145 return INSTALLSTATE_LOCAL
;
1147 return INSTALLSTATE_UNKNOWN
;
1150 /******************************************************************
1151 * MsiGetFileVersionA [MSI.@]
1153 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1154 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1156 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1157 UINT ret
= ERROR_OUTOFMEMORY
;
1161 szwFilePath
= strdupAtoW( szFilePath
);
1166 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1168 lpwVersionBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1169 if( !lpwVersionBuff
)
1173 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1175 lpwLangBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1180 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1181 lpwLangBuff
, pcchLangBuf
);
1183 if( lpwVersionBuff
)
1184 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1185 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1187 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1188 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1191 msi_free(szwFilePath
);
1192 msi_free(lpwVersionBuff
);
1193 msi_free(lpwLangBuff
);
1198 /******************************************************************
1199 * MsiGetFileVersionW [MSI.@]
1201 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1202 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1204 static WCHAR szVersionResource
[] = {'\\',0};
1205 static const WCHAR szVersionFormat
[] = {
1206 '%','d','.','%','d','.','%','d','.','%','d',0};
1207 static const WCHAR szLangFormat
[] = {'%','d',0};
1210 LPVOID lpVer
= NULL
;
1211 VS_FIXEDFILEINFO
*ffi
;
1215 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1216 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1217 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1219 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1221 return GetLastError();
1223 lpVer
= msi_alloc(dwVerLen
);
1226 ret
= ERROR_OUTOFMEMORY
;
1230 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1232 ret
= GetLastError();
1235 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1237 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1240 wsprintfW(tmp
, szVersionFormat
,
1241 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1242 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1243 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1244 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1249 *pcchVersionBuf
= 0;
1253 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1255 DWORD lang
= GetUserDefaultLangID();
1257 FIXME("Retrieve language from file\n");
1258 wsprintfW(tmp
, szLangFormat
, lang
);
1259 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1260 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1269 /******************************************************************
1272 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1276 case DLL_PROCESS_ATTACH
:
1277 msi_hInstance
= hinstDLL
;
1278 DisableThreadLibraryCalls(hinstDLL
);
1279 msi_dialog_register_class();
1281 case DLL_PROCESS_DETACH
:
1282 msi_dialog_unregister_class();
1283 /* FIXME: Cleanup */
1289 typedef struct tagIClassFactoryImpl
1291 const IClassFactoryVtbl
*lpVtbl
;
1292 } IClassFactoryImpl
;
1294 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1295 REFIID riid
,LPVOID
*ppobj
)
1297 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1298 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1299 return E_NOINTERFACE
;
1302 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1308 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1314 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1315 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1317 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1319 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1323 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1325 TRACE("(%p)->(%d)\n", iface
, dolock
);
1335 static const IClassFactoryVtbl MsiCF_Vtbl
=
1337 MsiCF_QueryInterface
,
1340 MsiCF_CreateInstance
,
1344 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1346 /******************************************************************
1347 * DllGetClassObject [MSI.@]
1349 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1351 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1353 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1354 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1355 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1356 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1357 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1359 *ppv
= (LPVOID
) &Msi_CF
;
1362 return CLASS_E_CLASSNOTAVAILABLE
;
1365 /******************************************************************
1366 * DllGetVersion [MSI.@]
1368 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1372 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1373 return E_INVALIDARG
;
1375 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1376 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1377 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1378 pdvi
->dwPlatformID
= 1;
1383 /******************************************************************
1384 * DllCanUnloadNow [MSI.@]
1386 HRESULT WINAPI
DllCanUnloadNow(void)
1388 return dll_count
== 0 ? S_OK
: S_FALSE
;
1391 /***********************************************************************
1392 * MsiGetFeatureUsageW [MSI.@]
1394 UINT WINAPI
MsiGetFeatureUsageW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1395 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1397 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1398 pdwUseCount
, pwDateUsed
);
1399 return ERROR_CALL_NOT_IMPLEMENTED
;
1402 /***********************************************************************
1403 * MsiGetFeatureUsageA [MSI.@]
1405 UINT WINAPI
MsiGetFeatureUsageA( LPCSTR szProduct
, LPCSTR szFeature
,
1406 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1408 LPWSTR prod
= NULL
, feat
= NULL
;
1409 UINT ret
= ERROR_OUTOFMEMORY
;
1411 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1412 pdwUseCount
, pwDateUsed
);
1414 prod
= strdupAtoW( szProduct
);
1415 if (szProduct
&& !prod
)
1418 feat
= strdupAtoW( szFeature
);
1419 if (szFeature
&& !feat
)
1422 ret
= MsiGetFeatureUsageW( prod
, feat
, pdwUseCount
, pwDateUsed
);
1431 /***********************************************************************
1432 * MsiUseFeatureExW [MSI.@]
1434 INSTALLSTATE WINAPI
MsiUseFeatureExW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1435 DWORD dwInstallMode
, DWORD dwReserved
)
1439 TRACE("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1440 dwInstallMode
, dwReserved
);
1442 state
= MsiQueryFeatureStateW( szProduct
, szFeature
);
1445 return INSTALLSTATE_INVALIDARG
;
1447 if (state
== INSTALLSTATE_LOCAL
&& dwInstallMode
!= INSTALLMODE_NODETECTION
)
1449 FIXME("mark product %s feature %s as used\n",
1450 debugstr_w(szProduct
), debugstr_w(szFeature
) );
1456 /***********************************************************************
1457 * MsiUseFeatureExA [MSI.@]
1459 INSTALLSTATE WINAPI
MsiUseFeatureExA( LPCSTR szProduct
, LPCSTR szFeature
,
1460 DWORD dwInstallMode
, DWORD dwReserved
)
1462 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1463 LPWSTR prod
= NULL
, feat
= NULL
;
1465 TRACE("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1466 dwInstallMode
, dwReserved
);
1468 prod
= strdupAtoW( szProduct
);
1469 if (szProduct
&& !prod
)
1472 feat
= strdupAtoW( szFeature
);
1473 if (szFeature
&& !feat
)
1476 ret
= MsiUseFeatureExW( prod
, feat
, dwInstallMode
, dwReserved
);
1485 INSTALLSTATE WINAPI
MsiUseFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
)
1487 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1489 return INSTALLSTATE_LOCAL
;
1492 INSTALLSTATE WINAPI
MsiUseFeatureA( LPCSTR szProduct
, LPCSTR szFeature
)
1494 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1495 LPWSTR prod
= NULL
, feat
= NULL
;
1497 TRACE("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
) );
1499 prod
= strdupAtoW( szProduct
);
1500 if (szProduct
&& !prod
)
1503 feat
= strdupAtoW( szFeature
);
1504 if (szFeature
&& !feat
)
1507 ret
= MsiUseFeatureW( prod
, feat
);
1516 /***********************************************************************
1517 * MsiProvideQualifiedComponentExW [MSI.@]
1519 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1520 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1521 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1528 WCHAR product
[MAX_FEATURE_CHARS
+1];
1529 WCHAR component
[MAX_FEATURE_CHARS
+1];
1530 WCHAR feature
[MAX_FEATURE_CHARS
+1];
1532 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1533 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1534 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1536 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1537 if (rc
!= ERROR_SUCCESS
)
1538 return ERROR_INDEX_ABSENT
;
1541 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1545 return ERROR_INDEX_ABSENT
;
1548 info
= msi_alloc(sz
);
1549 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1550 if (rc
!= ERROR_SUCCESS
)
1554 return ERROR_INDEX_ABSENT
;
1557 MsiDecomposeDescriptorW(info
, product
, feature
, component
, &sz
);
1560 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1562 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1567 if (rc
== INSTALLSTATE_LOCAL
)
1568 return ERROR_SUCCESS
;
1570 return ERROR_FILE_NOT_FOUND
;
1573 /***********************************************************************
1574 * MsiProvideQualifiedComponentW [MSI.@]
1576 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1577 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1580 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1581 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1584 /***********************************************************************
1585 * MsiProvideQualifiedComponentA [MSI.@]
1587 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1588 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1591 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1595 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1596 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1598 szwComponent
= strdupAtoW( szComponent
);
1599 szwQualifier
= strdupAtoW( szQualifier
);
1601 lpwPathBuf
= msi_alloc(*pcchPathBuf
* sizeof(WCHAR
));
1603 pcchwPathBuf
= *pcchPathBuf
;
1605 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1606 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1608 msi_free(szwComponent
);
1609 msi_free(szwQualifier
);
1610 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1611 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1613 msi_free(lpwPathBuf
);
1617 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1618 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1619 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1623 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1625 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1626 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1629 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1630 if (rc
!= ERROR_SUCCESS
)
1631 return USERINFOSTATE_UNKNOWN
;
1635 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1636 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1637 NULL
, (LPBYTE
)lpUserNameBuf
,
1640 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1643 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1647 if (pcchUserNameBuf
)
1648 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1652 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1653 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1654 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1656 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1659 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1664 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1666 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1667 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1670 return USERINFOSTATE_ABSENT
;
1675 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1676 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1677 (LPBYTE
)lpSerialBuf
, &sz
);
1679 if (!lpSerialBuf
&& pcchSerialBuf
)
1682 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1686 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1689 return USERINFOSTATE_PRESENT
;
1692 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1693 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1694 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1696 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1697 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1700 return USERINFOSTATE_UNKNOWN
;
1703 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1707 MSIPACKAGE
*package
;
1708 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1710 TRACE("(%s)\n",debugstr_w(szProduct
));
1712 rc
= MsiOpenProductW(szProduct
,&handle
);
1713 if (rc
!= ERROR_SUCCESS
)
1714 return ERROR_INVALID_PARAMETER
;
1716 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1717 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1718 msiobj_release( &package
->hdr
);
1720 MsiCloseHandle(handle
);
1725 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1729 MSIPACKAGE
*package
;
1730 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1732 TRACE("(%s)\n",debugstr_a(szProduct
));
1734 rc
= MsiOpenProductA(szProduct
,&handle
);
1735 if (rc
!= ERROR_SUCCESS
)
1736 return ERROR_INVALID_PARAMETER
;
1738 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1739 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1740 msiobj_release( &package
->hdr
);
1742 MsiCloseHandle(handle
);
1747 /***********************************************************************
1748 * MsiConfigureFeatureA [MSI.@]
1750 UINT WINAPI
MsiConfigureFeatureA(LPCSTR szProduct
, LPCSTR szFeature
, INSTALLSTATE eInstallState
)
1752 FIXME("%s %s %i\n", debugstr_a(szProduct
), debugstr_a(szFeature
), eInstallState
);
1753 return ERROR_SUCCESS
;
1756 /***********************************************************************
1757 * MsiConfigureFeatureW [MSI.@]
1759 UINT WINAPI
MsiConfigureFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
, INSTALLSTATE eInstallState
)
1761 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1762 return ERROR_SUCCESS
;
1765 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1767 WCHAR path
[MAX_PATH
];
1770 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1771 return ERROR_CALL_NOT_IMPLEMENTED
;
1774 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1775 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1777 return ERROR_CALL_NOT_IMPLEMENTED
;
1780 strcatW(path
, installerW
);
1782 CreateDirectoryW(path
, NULL
);
1787 /***********************************************************************
1788 * MsiGetShortcutTargetA [MSI.@]
1790 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1791 LPSTR szProductCode
, LPSTR szFeatureId
,
1792 LPSTR szComponentCode
)
1795 const int len
= MAX_FEATURE_CHARS
+1;
1796 WCHAR product
[MAX_FEATURE_CHARS
+1], feature
[MAX_FEATURE_CHARS
+1], component
[MAX_FEATURE_CHARS
+1];
1799 target
= strdupAtoW( szShortcutTarget
);
1800 if (szShortcutTarget
&& !target
)
1801 return ERROR_OUTOFMEMORY
;
1805 r
= MsiGetShortcutTargetW( target
, product
, feature
, component
);
1807 if (r
== ERROR_SUCCESS
)
1809 WideCharToMultiByte( CP_ACP
, 0, product
, -1, szProductCode
, len
, NULL
, NULL
);
1810 WideCharToMultiByte( CP_ACP
, 0, feature
, -1, szFeatureId
, len
, NULL
, NULL
);
1811 WideCharToMultiByte( CP_ACP
, 0, component
, -1, szComponentCode
, len
, NULL
, NULL
);
1816 /***********************************************************************
1817 * MsiGetShortcutTargetW [MSI.@]
1819 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1820 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1821 LPWSTR szComponentCode
)
1823 IShellLinkDataList
*dl
= NULL
;
1824 IPersistFile
*pf
= NULL
;
1825 LPEXP_DARWIN_LINK darwin
= NULL
;
1828 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget
),
1829 szProductCode
, szFeatureId
, szComponentCode
);
1831 init
= CoInitialize(NULL
);
1833 r
= CoCreateInstance( &CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
1834 &IID_IPersistFile
, (LPVOID
*) &pf
);
1835 if( SUCCEEDED( r
) )
1837 r
= IPersistFile_Load( pf
, szShortcutTarget
,
1838 STGM_READ
| STGM_SHARE_DENY_WRITE
);
1839 if( SUCCEEDED( r
) )
1841 r
= IPersistFile_QueryInterface( pf
, &IID_IShellLinkDataList
,
1843 if( SUCCEEDED( r
) )
1845 IShellLinkDataList_CopyDataBlock( dl
, EXP_DARWIN_ID_SIG
,
1847 IShellLinkDataList_Release( dl
);
1850 IPersistFile_Release( pf
);
1853 if (SUCCEEDED(init
))
1856 TRACE("darwin = %p\n", darwin
);
1863 ret
= MsiDecomposeDescriptorW( darwin
->szwDarwinID
,
1864 szProductCode
, szFeatureId
, szComponentCode
, &sz
);
1865 LocalFree( darwin
);
1869 return ERROR_FUNCTION_FAILED
;
1872 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1873 DWORD dwReinstallMode
)
1875 MSIPACKAGE
* package
= NULL
;
1878 WCHAR sourcepath
[MAX_PATH
];
1879 WCHAR filename
[MAX_PATH
];
1880 static const WCHAR szInstalled
[] = {
1881 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1882 static const WCHAR fmt
[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1883 static const WCHAR REINSTALLMODE
[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1884 WCHAR reinstallmode
[11];
1888 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1891 memset(reinstallmode
,0,sizeof(reinstallmode
));
1892 ptr
= reinstallmode
;
1894 if (dwReinstallMode
& REINSTALLMODE_FILEMISSING
)
1895 { *ptr
= 'p'; ptr
++; }
1896 if (dwReinstallMode
& REINSTALLMODE_FILEOLDERVERSION
)
1897 { *ptr
= 'o'; ptr
++; }
1898 if (dwReinstallMode
& REINSTALLMODE_FILEEQUALVERSION
)
1899 { *ptr
= 'w'; ptr
++; }
1900 if (dwReinstallMode
& REINSTALLMODE_FILEEXACT
)
1901 { *ptr
= 'd'; ptr
++; }
1902 if (dwReinstallMode
& REINSTALLMODE_FILEVERIFY
)
1903 { *ptr
= 'c'; ptr
++; }
1904 if (dwReinstallMode
& REINSTALLMODE_FILEREPLACE
)
1905 { *ptr
= 'a'; ptr
++; }
1906 if (dwReinstallMode
& REINSTALLMODE_USERDATA
)
1907 { *ptr
= 'u'; ptr
++; }
1908 if (dwReinstallMode
& REINSTALLMODE_MACHINEDATA
)
1909 { *ptr
= 'm'; ptr
++; }
1910 if (dwReinstallMode
& REINSTALLMODE_SHORTCUT
)
1911 { *ptr
= 's'; ptr
++; }
1912 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1913 { *ptr
= 'v'; ptr
++; }
1915 sz
= sizeof(sourcepath
);
1916 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1917 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
1920 sz
= sizeof(filename
);
1921 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1922 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
1924 strcatW(sourcepath
,filename
);
1926 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1927 r
= MSI_OpenPackageW( sourcepath
, &package
);
1929 r
= MSI_OpenProductW( szProduct
, &package
);
1931 if (r
!= ERROR_SUCCESS
)
1934 MSI_SetPropertyW(package
,REINSTALLMODE
,reinstallmode
);
1936 sz
= lstrlenW(szInstalled
);
1937 sz
+= lstrlenW(fmt
);
1938 sz
+= lstrlenW(szFeature
);
1940 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
1942 sprintfW(commandline
,fmt
,szFeature
);
1943 lstrcatW(commandline
,szInstalled
);
1945 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
1947 msiobj_release( &package
->hdr
);
1949 msi_free(commandline
);
1954 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1955 DWORD dwReinstallMode
)
1961 TRACE("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1964 wszProduct
= strdupAtoW(szProduct
);
1965 wszFeature
= strdupAtoW(szFeature
);
1967 rc
= MsiReinstallFeatureW(wszProduct
, wszFeature
, dwReinstallMode
);
1969 msi_free(wszProduct
);
1970 msi_free(wszFeature
);
1974 /***********************************************************************
1975 * MsiEnumPatchesA [MSI.@]
1977 UINT WINAPI
MsiEnumPatchesA( LPCSTR szProduct
, DWORD iPatchIndex
,
1978 LPSTR lpPatchBuf
, LPSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1980 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct
),
1981 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1982 return ERROR_NO_MORE_ITEMS
;
1985 /***********************************************************************
1986 * MsiEnumPatchesW [MSI.@]
1988 UINT WINAPI
MsiEnumPatchesW( LPCWSTR szProduct
, DWORD iPatchIndex
,
1989 LPWSTR lpPatchBuf
, LPWSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1991 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct
),
1992 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1993 return ERROR_NO_MORE_ITEMS
;
1996 /***********************************************************************
1997 * MsiGetFileHashW [MSI.@]
1999 UINT WINAPI
MsiGetFileHashW( LPCWSTR szFilePath
, DWORD dwOptions
,
2000 PMSIFILEHASHINFO pHash
)
2002 FIXME("%s %08lx %p\n", debugstr_w(szFilePath
), dwOptions
, pHash
);
2003 return ERROR_CALL_NOT_IMPLEMENTED
;
2006 /***********************************************************************
2007 * MsiGetFileHashA [MSI.@]
2009 UINT WINAPI
MsiGetFileHashA( LPCSTR szFilePath
, DWORD dwOptions
,
2010 PMSIFILEHASHINFO pHash
)
2012 FIXME("%s %08lx %p\n", debugstr_a(szFilePath
), dwOptions
, pHash
);
2013 return ERROR_CALL_NOT_IMPLEMENTED
;
2016 /***********************************************************************
2017 * MsiAdvertiseScriptW [MSI.@]
2019 UINT WINAPI
MsiAdvertiseScriptW( LPCWSTR szScriptFile
, DWORD dwFlags
,
2020 PHKEY phRegData
, BOOL fRemoveItems
)
2022 FIXME("%s %08lx %p %d\n",
2023 debugstr_w( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2024 return ERROR_CALL_NOT_IMPLEMENTED
;
2027 /***********************************************************************
2028 * MsiAdvertiseScriptA [MSI.@]
2030 UINT WINAPI
MsiAdvertiseScriptA( LPCSTR szScriptFile
, DWORD dwFlags
,
2031 PHKEY phRegData
, BOOL fRemoveItems
)
2033 FIXME("%s %08lx %p %d\n",
2034 debugstr_a( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2035 return ERROR_CALL_NOT_IMPLEMENTED
;