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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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
));
671 return INSTALLSTATE_INVALIDARG
;
673 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
674 if (rc
!= ERROR_SUCCESS
)
679 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
680 if (rc
!= ERROR_SUCCESS
)
684 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
685 if (rc
!= ERROR_SUCCESS
)
692 rrc
= INSTALLSTATE_DEFAULT
;
695 FIXME("Unknown install state read from registry (%i)\n",rrc
);
696 rrc
= INSTALLSTATE_UNKNOWN
;
704 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
706 INSTALLUILEVEL old
= gUILevel
;
707 HWND oldwnd
= gUIhwnd
;
709 TRACE("%08x %p\n", dwUILevel
, phWnd
);
711 gUILevel
= dwUILevel
;
720 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
721 DWORD dwMessageFilter
, LPVOID pvContext
)
723 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
725 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
726 gUIHandlerA
= puiHandler
;
727 gUIFilter
= dwMessageFilter
;
728 gUIContext
= pvContext
;
733 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
734 DWORD dwMessageFilter
, LPVOID pvContext
)
736 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
738 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
739 gUIHandlerW
= puiHandler
;
740 gUIFilter
= dwMessageFilter
;
741 gUIContext
= pvContext
;
746 /******************************************************************
747 * MsiLoadStringW [MSI.@]
749 * Loads a string from MSI's string resources.
753 * handle [I] only -1 is handled currently
754 * id [I] id of the string to be loaded
755 * lpBuffer [O] buffer for the string to be written to
756 * nBufferMax [I] maximum size of the buffer in characters
757 * lang [I] the preferred language for the string
761 * If successful, this function returns the language id of the string loaded
762 * If the function fails, the function returns zero.
766 * The type of the first parameter is unknown. LoadString's prototype
767 * suggests that it might be a module handle. I have made it an MSI handle
768 * for starters, as -1 is an invalid MSI handle, but not an invalid module
769 * handle. Maybe strings can be stored in an MSI database somehow.
771 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
772 int nBufferMax
, LANGID lang
)
779 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
782 FIXME("don't know how to deal with handle = %08lx\n", handle
);
785 lang
= GetUserDefaultLangID();
787 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
791 hResData
= LoadResource( msi_hInstance
, hres
);
794 p
= LockResource( hResData
);
798 for (i
= 0; i
< (id
&0xf); i
++)
802 if( nBufferMax
<= len
)
805 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
808 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
813 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
814 int nBufferMax
, LANGID lang
)
820 bufW
= msi_alloc(nBufferMax
*sizeof(WCHAR
));
821 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
824 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
825 if( len
<= nBufferMax
)
826 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
827 lpBuffer
, nBufferMax
, NULL
, NULL
);
835 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
838 FIXME("%s %p %p\n", debugstr_a(szComponent
), lpPathBuf
, pcchBuf
);
839 return INSTALLSTATE_UNKNOWN
;
842 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
845 FIXME("%s %p %p\n", debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
846 return INSTALLSTATE_UNKNOWN
;
849 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
850 WORD wLanguageId
, DWORD f
)
852 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
853 uType
,wLanguageId
,f
);
854 return MessageBoxExA(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
857 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
858 WORD wLanguageId
, DWORD f
)
860 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
861 uType
,wLanguageId
,f
);
862 return MessageBoxExW(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
865 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
866 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
869 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
870 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
872 return ERROR_CALL_NOT_IMPLEMENTED
;
875 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
876 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
879 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
880 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
882 return ERROR_CALL_NOT_IMPLEMENTED
;
885 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
886 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
888 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
889 return ERROR_CALL_NOT_IMPLEMENTED
;
892 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
893 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
895 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
896 return ERROR_CALL_NOT_IMPLEMENTED
;
899 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
900 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
903 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
904 ppcCertContext
, pbHashData
, pcbHashData
);
905 return ERROR_CALL_NOT_IMPLEMENTED
;
908 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
909 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
912 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
913 ppcCertContext
, pbHashData
, pcbHashData
);
914 return ERROR_CALL_NOT_IMPLEMENTED
;
917 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
918 LPSTR szValue
, DWORD
*pccbValue
)
920 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
921 return ERROR_CALL_NOT_IMPLEMENTED
;
924 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
925 LPWSTR szValue
, DWORD
*pccbValue
)
927 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
928 return ERROR_CALL_NOT_IMPLEMENTED
;
931 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
934 LPWSTR szPack
= NULL
;
936 TRACE("%s\n", debugstr_a(szPackage
) );
940 szPack
= strdupAtoW( szPackage
);
942 return ERROR_OUTOFMEMORY
;
945 r
= MsiVerifyPackageW( szPack
);
952 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
957 TRACE("%s\n", debugstr_w(szPackage
) );
959 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
960 MsiCloseHandle( handle
);
965 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
966 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
968 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
974 szwProduct
= strdupAtoW( szProduct
);
976 return ERROR_OUTOFMEMORY
;
981 szwComponent
= strdupAtoW( szComponent
);
984 msi_free( szwProduct
);
985 return ERROR_OUTOFMEMORY
;
989 if( pcchBuf
&& *pcchBuf
> 0 )
991 lpwPathBuf
= msi_alloc( *pcchBuf
* sizeof(WCHAR
));
992 incoming_len
= *pcchBuf
;
1000 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
1002 msi_free( szwProduct
);
1003 msi_free( szwComponent
);
1006 if (rc
!= INSTALLSTATE_UNKNOWN
)
1007 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
1008 lpPathBuf
, incoming_len
, NULL
, NULL
);
1009 msi_free( lpwPathBuf
);
1015 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1016 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1018 WCHAR squished_pc
[GUID_SIZE
];
1020 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1025 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1026 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1029 return INSTALLSTATE_INVALIDARG
;
1030 if( lpPathBuf
&& !pcchBuf
)
1031 return INSTALLSTATE_INVALIDARG
;
1033 squash_guid(szProduct
,squished_pc
);
1035 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1036 if( rc
!= ERROR_SUCCESS
)
1041 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1042 if( rc
!= ERROR_SUCCESS
)
1047 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1048 if( rc
!= ERROR_SUCCESS
)
1050 if( type
!= REG_SZ
)
1053 sz
+= sizeof(WCHAR
);
1054 path
= msi_alloc( sz
);
1058 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1059 if( rc
!= ERROR_SUCCESS
)
1062 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1063 debugstr_w(szProduct
), debugstr_w(path
));
1067 FIXME("Registry entry.. check entry\n");
1068 rrc
= INSTALLSTATE_LOCAL
;
1072 /* PROBABLY a file */
1073 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1074 rrc
= INSTALLSTATE_LOCAL
;
1076 rrc
= INSTALLSTATE_ABSENT
;
1081 sz
= sz
/ sizeof(WCHAR
);
1082 if( *pcchBuf
>= sz
)
1083 lstrcpyW( lpPathBuf
, path
);
1093 /******************************************************************
1094 * MsiQueryFeatureStateA [MSI.@]
1096 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1098 LPWSTR szwProduct
= NULL
, szwFeature
= NULL
;
1099 INSTALLSTATE rc
= INSTALLSTATE_UNKNOWN
;
1101 szwProduct
= strdupAtoW( szProduct
);
1102 if ( szProduct
&& !szwProduct
)
1105 szwFeature
= strdupAtoW( szFeature
);
1106 if ( szFeature
&& !szwFeature
)
1109 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1112 msi_free( szwProduct
);
1113 msi_free( szwFeature
);
1118 /******************************************************************
1119 * MsiQueryFeatureStateW [MSI.@]
1121 * This does not verify that the Feature is functional. So i am only going to
1122 * check the existence of the key in the registry. This should tell me if it is
1125 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1127 WCHAR squishProduct
[GUID_SIZE
];
1132 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1134 if (!szProduct
|| !szFeature
)
1135 return INSTALLSTATE_INVALIDARG
;
1137 if (!squash_guid( szProduct
, squishProduct
))
1138 return INSTALLSTATE_INVALIDARG
;
1140 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1141 if (rc
!= ERROR_SUCCESS
)
1142 return INSTALLSTATE_UNKNOWN
;
1144 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1147 if (rc
== ERROR_SUCCESS
)
1148 return INSTALLSTATE_LOCAL
;
1150 return INSTALLSTATE_UNKNOWN
;
1153 /******************************************************************
1154 * MsiGetFileVersionA [MSI.@]
1156 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1157 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1159 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1160 UINT ret
= ERROR_OUTOFMEMORY
;
1164 szwFilePath
= strdupAtoW( szFilePath
);
1169 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1171 lpwVersionBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1172 if( !lpwVersionBuff
)
1176 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1178 lpwLangBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1183 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1184 lpwLangBuff
, pcchLangBuf
);
1186 if( lpwVersionBuff
)
1187 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1188 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1190 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1191 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1194 msi_free(szwFilePath
);
1195 msi_free(lpwVersionBuff
);
1196 msi_free(lpwLangBuff
);
1201 /******************************************************************
1202 * MsiGetFileVersionW [MSI.@]
1204 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1205 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1207 static WCHAR szVersionResource
[] = {'\\',0};
1208 static const WCHAR szVersionFormat
[] = {
1209 '%','d','.','%','d','.','%','d','.','%','d',0};
1210 static const WCHAR szLangFormat
[] = {'%','d',0};
1213 LPVOID lpVer
= NULL
;
1214 VS_FIXEDFILEINFO
*ffi
;
1218 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1219 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1220 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1222 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1224 return GetLastError();
1226 lpVer
= msi_alloc(dwVerLen
);
1229 ret
= ERROR_OUTOFMEMORY
;
1233 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1235 ret
= GetLastError();
1238 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1240 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1243 wsprintfW(tmp
, szVersionFormat
,
1244 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1245 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1246 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1247 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1252 *pcchVersionBuf
= 0;
1256 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1258 DWORD lang
= GetUserDefaultLangID();
1260 FIXME("Retrieve language from file\n");
1261 wsprintfW(tmp
, szLangFormat
, lang
);
1262 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1263 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1272 /******************************************************************
1275 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1279 case DLL_PROCESS_ATTACH
:
1280 msi_hInstance
= hinstDLL
;
1281 DisableThreadLibraryCalls(hinstDLL
);
1282 msi_dialog_register_class();
1284 case DLL_PROCESS_DETACH
:
1285 msi_dialog_unregister_class();
1286 /* FIXME: Cleanup */
1292 typedef struct tagIClassFactoryImpl
1294 const IClassFactoryVtbl
*lpVtbl
;
1295 } IClassFactoryImpl
;
1297 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1298 REFIID riid
,LPVOID
*ppobj
)
1300 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1301 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1302 return E_NOINTERFACE
;
1305 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1311 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1317 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1318 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1320 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1322 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1326 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1328 TRACE("(%p)->(%d)\n", iface
, dolock
);
1338 static const IClassFactoryVtbl MsiCF_Vtbl
=
1340 MsiCF_QueryInterface
,
1343 MsiCF_CreateInstance
,
1347 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1349 /******************************************************************
1350 * DllGetClassObject [MSI.@]
1352 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1354 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1356 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1357 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1358 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1359 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1360 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1362 *ppv
= (LPVOID
) &Msi_CF
;
1365 return CLASS_E_CLASSNOTAVAILABLE
;
1368 /******************************************************************
1369 * DllGetVersion [MSI.@]
1371 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1375 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1376 return E_INVALIDARG
;
1378 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1379 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1380 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1381 pdvi
->dwPlatformID
= 1;
1386 /******************************************************************
1387 * DllCanUnloadNow [MSI.@]
1389 HRESULT WINAPI
DllCanUnloadNow(void)
1391 return dll_count
== 0 ? S_OK
: S_FALSE
;
1394 /***********************************************************************
1395 * MsiGetFeatureUsageW [MSI.@]
1397 UINT WINAPI
MsiGetFeatureUsageW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1398 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1400 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1401 pdwUseCount
, pwDateUsed
);
1402 return ERROR_CALL_NOT_IMPLEMENTED
;
1405 /***********************************************************************
1406 * MsiGetFeatureUsageA [MSI.@]
1408 UINT WINAPI
MsiGetFeatureUsageA( LPCSTR szProduct
, LPCSTR szFeature
,
1409 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1411 LPWSTR prod
= NULL
, feat
= NULL
;
1412 UINT ret
= ERROR_OUTOFMEMORY
;
1414 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1415 pdwUseCount
, pwDateUsed
);
1417 prod
= strdupAtoW( szProduct
);
1418 if (szProduct
&& !prod
)
1421 feat
= strdupAtoW( szFeature
);
1422 if (szFeature
&& !feat
)
1425 ret
= MsiGetFeatureUsageW( prod
, feat
, pdwUseCount
, pwDateUsed
);
1434 /***********************************************************************
1435 * MsiUseFeatureExW [MSI.@]
1437 INSTALLSTATE WINAPI
MsiUseFeatureExW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1438 DWORD dwInstallMode
, DWORD dwReserved
)
1442 TRACE("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1443 dwInstallMode
, dwReserved
);
1445 state
= MsiQueryFeatureStateW( szProduct
, szFeature
);
1448 return INSTALLSTATE_INVALIDARG
;
1450 if (state
== INSTALLSTATE_LOCAL
&& dwInstallMode
!= INSTALLMODE_NODETECTION
)
1452 FIXME("mark product %s feature %s as used\n",
1453 debugstr_w(szProduct
), debugstr_w(szFeature
) );
1459 /***********************************************************************
1460 * MsiUseFeatureExA [MSI.@]
1462 INSTALLSTATE WINAPI
MsiUseFeatureExA( LPCSTR szProduct
, LPCSTR szFeature
,
1463 DWORD dwInstallMode
, DWORD dwReserved
)
1465 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1466 LPWSTR prod
= NULL
, feat
= NULL
;
1468 TRACE("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1469 dwInstallMode
, dwReserved
);
1471 prod
= strdupAtoW( szProduct
);
1472 if (szProduct
&& !prod
)
1475 feat
= strdupAtoW( szFeature
);
1476 if (szFeature
&& !feat
)
1479 ret
= MsiUseFeatureExW( prod
, feat
, dwInstallMode
, dwReserved
);
1488 INSTALLSTATE WINAPI
MsiUseFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
)
1490 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1492 return INSTALLSTATE_LOCAL
;
1495 INSTALLSTATE WINAPI
MsiUseFeatureA( LPCSTR szProduct
, LPCSTR szFeature
)
1497 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1498 LPWSTR prod
= NULL
, feat
= NULL
;
1500 TRACE("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
) );
1502 prod
= strdupAtoW( szProduct
);
1503 if (szProduct
&& !prod
)
1506 feat
= strdupAtoW( szFeature
);
1507 if (szFeature
&& !feat
)
1510 ret
= MsiUseFeatureW( prod
, feat
);
1519 /***********************************************************************
1520 * MsiProvideQualifiedComponentExW [MSI.@]
1522 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1523 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1524 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1531 WCHAR product
[MAX_FEATURE_CHARS
+1];
1532 WCHAR component
[MAX_FEATURE_CHARS
+1];
1533 WCHAR feature
[MAX_FEATURE_CHARS
+1];
1535 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1536 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1537 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1539 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1540 if (rc
!= ERROR_SUCCESS
)
1541 return ERROR_INDEX_ABSENT
;
1544 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1548 return ERROR_INDEX_ABSENT
;
1551 info
= msi_alloc(sz
);
1552 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1553 if (rc
!= ERROR_SUCCESS
)
1557 return ERROR_INDEX_ABSENT
;
1560 MsiDecomposeDescriptorW(info
, product
, feature
, component
, &sz
);
1563 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1565 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1570 if (rc
== INSTALLSTATE_LOCAL
)
1571 return ERROR_SUCCESS
;
1573 return ERROR_FILE_NOT_FOUND
;
1576 /***********************************************************************
1577 * MsiProvideQualifiedComponentW [MSI.@]
1579 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1580 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1583 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1584 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1587 /***********************************************************************
1588 * MsiProvideQualifiedComponentA [MSI.@]
1590 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1591 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1594 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1598 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1599 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1601 szwComponent
= strdupAtoW( szComponent
);
1602 szwQualifier
= strdupAtoW( szQualifier
);
1604 lpwPathBuf
= msi_alloc(*pcchPathBuf
* sizeof(WCHAR
));
1606 pcchwPathBuf
= *pcchPathBuf
;
1608 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1609 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1611 msi_free(szwComponent
);
1612 msi_free(szwQualifier
);
1613 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1614 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1616 msi_free(lpwPathBuf
);
1620 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1621 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1622 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1626 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1628 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1629 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1632 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1633 if (rc
!= ERROR_SUCCESS
)
1634 return USERINFOSTATE_UNKNOWN
;
1638 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1639 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1640 NULL
, (LPBYTE
)lpUserNameBuf
,
1643 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1646 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1650 if (pcchUserNameBuf
)
1651 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1655 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1656 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1657 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1659 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1662 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1667 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1669 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1670 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1673 return USERINFOSTATE_ABSENT
;
1678 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1679 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1680 (LPBYTE
)lpSerialBuf
, &sz
);
1682 if (!lpSerialBuf
&& pcchSerialBuf
)
1685 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1689 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1692 return USERINFOSTATE_PRESENT
;
1695 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1696 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1697 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1699 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1700 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1703 return USERINFOSTATE_UNKNOWN
;
1706 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1710 MSIPACKAGE
*package
;
1711 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1713 TRACE("(%s)\n",debugstr_w(szProduct
));
1715 rc
= MsiOpenProductW(szProduct
,&handle
);
1716 if (rc
!= ERROR_SUCCESS
)
1717 return ERROR_INVALID_PARAMETER
;
1719 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1720 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1721 msiobj_release( &package
->hdr
);
1723 MsiCloseHandle(handle
);
1728 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1732 MSIPACKAGE
*package
;
1733 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1735 TRACE("(%s)\n",debugstr_a(szProduct
));
1737 rc
= MsiOpenProductA(szProduct
,&handle
);
1738 if (rc
!= ERROR_SUCCESS
)
1739 return ERROR_INVALID_PARAMETER
;
1741 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1742 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1743 msiobj_release( &package
->hdr
);
1745 MsiCloseHandle(handle
);
1750 /***********************************************************************
1751 * MsiConfigureFeatureA [MSI.@]
1753 UINT WINAPI
MsiConfigureFeatureA(LPCSTR szProduct
, LPCSTR szFeature
, INSTALLSTATE eInstallState
)
1755 FIXME("%s %s %i\n", debugstr_a(szProduct
), debugstr_a(szFeature
), eInstallState
);
1756 return ERROR_SUCCESS
;
1759 /***********************************************************************
1760 * MsiConfigureFeatureW [MSI.@]
1762 UINT WINAPI
MsiConfigureFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
, INSTALLSTATE eInstallState
)
1764 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1765 return ERROR_SUCCESS
;
1768 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1770 WCHAR path
[MAX_PATH
];
1773 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1774 return ERROR_CALL_NOT_IMPLEMENTED
;
1777 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1778 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1780 return ERROR_CALL_NOT_IMPLEMENTED
;
1783 strcatW(path
, installerW
);
1785 CreateDirectoryW(path
, NULL
);
1790 /***********************************************************************
1791 * MsiGetShortcutTargetA [MSI.@]
1793 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1794 LPSTR szProductCode
, LPSTR szFeatureId
,
1795 LPSTR szComponentCode
)
1798 const int len
= MAX_FEATURE_CHARS
+1;
1799 WCHAR product
[MAX_FEATURE_CHARS
+1], feature
[MAX_FEATURE_CHARS
+1], component
[MAX_FEATURE_CHARS
+1];
1802 target
= strdupAtoW( szShortcutTarget
);
1803 if (szShortcutTarget
&& !target
)
1804 return ERROR_OUTOFMEMORY
;
1808 r
= MsiGetShortcutTargetW( target
, product
, feature
, component
);
1810 if (r
== ERROR_SUCCESS
)
1812 WideCharToMultiByte( CP_ACP
, 0, product
, -1, szProductCode
, len
, NULL
, NULL
);
1813 WideCharToMultiByte( CP_ACP
, 0, feature
, -1, szFeatureId
, len
, NULL
, NULL
);
1814 WideCharToMultiByte( CP_ACP
, 0, component
, -1, szComponentCode
, len
, NULL
, NULL
);
1819 /***********************************************************************
1820 * MsiGetShortcutTargetW [MSI.@]
1822 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1823 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1824 LPWSTR szComponentCode
)
1826 IShellLinkDataList
*dl
= NULL
;
1827 IPersistFile
*pf
= NULL
;
1828 LPEXP_DARWIN_LINK darwin
= NULL
;
1831 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget
),
1832 szProductCode
, szFeatureId
, szComponentCode
);
1834 init
= CoInitialize(NULL
);
1836 r
= CoCreateInstance( &CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
1837 &IID_IPersistFile
, (LPVOID
*) &pf
);
1838 if( SUCCEEDED( r
) )
1840 r
= IPersistFile_Load( pf
, szShortcutTarget
,
1841 STGM_READ
| STGM_SHARE_DENY_WRITE
);
1842 if( SUCCEEDED( r
) )
1844 r
= IPersistFile_QueryInterface( pf
, &IID_IShellLinkDataList
,
1846 if( SUCCEEDED( r
) )
1848 IShellLinkDataList_CopyDataBlock( dl
, EXP_DARWIN_ID_SIG
,
1850 IShellLinkDataList_Release( dl
);
1853 IPersistFile_Release( pf
);
1856 if (SUCCEEDED(init
))
1859 TRACE("darwin = %p\n", darwin
);
1866 ret
= MsiDecomposeDescriptorW( darwin
->szwDarwinID
,
1867 szProductCode
, szFeatureId
, szComponentCode
, &sz
);
1868 LocalFree( darwin
);
1872 return ERROR_FUNCTION_FAILED
;
1875 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1876 DWORD dwReinstallMode
)
1878 MSIPACKAGE
* package
= NULL
;
1881 WCHAR sourcepath
[MAX_PATH
];
1882 WCHAR filename
[MAX_PATH
];
1883 static const WCHAR szInstalled
[] = {
1884 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1885 static const WCHAR fmt
[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1886 static const WCHAR REINSTALLMODE
[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1887 WCHAR reinstallmode
[11];
1891 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1894 ptr
= reinstallmode
;
1896 if (dwReinstallMode
& REINSTALLMODE_FILEMISSING
)
1898 if (dwReinstallMode
& REINSTALLMODE_FILEOLDERVERSION
)
1900 if (dwReinstallMode
& REINSTALLMODE_FILEEQUALVERSION
)
1902 if (dwReinstallMode
& REINSTALLMODE_FILEEXACT
)
1904 if (dwReinstallMode
& REINSTALLMODE_FILEVERIFY
)
1906 if (dwReinstallMode
& REINSTALLMODE_FILEREPLACE
)
1908 if (dwReinstallMode
& REINSTALLMODE_USERDATA
)
1910 if (dwReinstallMode
& REINSTALLMODE_MACHINEDATA
)
1912 if (dwReinstallMode
& REINSTALLMODE_SHORTCUT
)
1914 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1918 sz
= sizeof(sourcepath
);
1919 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1920 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
1923 sz
= sizeof(filename
);
1924 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1925 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
1927 strcatW(sourcepath
,filename
);
1929 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1930 r
= MSI_OpenPackageW( sourcepath
, &package
);
1932 r
= MSI_OpenProductW( szProduct
, &package
);
1934 if (r
!= ERROR_SUCCESS
)
1937 MSI_SetPropertyW(package
,REINSTALLMODE
,reinstallmode
);
1939 sz
= lstrlenW(szInstalled
);
1940 sz
+= lstrlenW(fmt
);
1941 sz
+= lstrlenW(szFeature
);
1943 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
1945 sprintfW(commandline
,fmt
,szFeature
);
1946 lstrcatW(commandline
,szInstalled
);
1948 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
1950 msiobj_release( &package
->hdr
);
1952 msi_free(commandline
);
1957 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1958 DWORD dwReinstallMode
)
1964 TRACE("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1967 wszProduct
= strdupAtoW(szProduct
);
1968 wszFeature
= strdupAtoW(szFeature
);
1970 rc
= MsiReinstallFeatureW(wszProduct
, wszFeature
, dwReinstallMode
);
1972 msi_free(wszProduct
);
1973 msi_free(wszFeature
);
1977 /***********************************************************************
1978 * MsiEnumPatchesA [MSI.@]
1980 UINT WINAPI
MsiEnumPatchesA( LPCSTR szProduct
, DWORD iPatchIndex
,
1981 LPSTR lpPatchBuf
, LPSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1983 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct
),
1984 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1985 return ERROR_NO_MORE_ITEMS
;
1988 /***********************************************************************
1989 * MsiEnumPatchesW [MSI.@]
1991 UINT WINAPI
MsiEnumPatchesW( LPCWSTR szProduct
, DWORD iPatchIndex
,
1992 LPWSTR lpPatchBuf
, LPWSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1994 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct
),
1995 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1996 return ERROR_NO_MORE_ITEMS
;
1999 /***********************************************************************
2000 * MsiGetFileHashW [MSI.@]
2002 UINT WINAPI
MsiGetFileHashW( LPCWSTR szFilePath
, DWORD dwOptions
,
2003 PMSIFILEHASHINFO pHash
)
2005 FIXME("%s %08lx %p\n", debugstr_w(szFilePath
), dwOptions
, pHash
);
2006 return ERROR_CALL_NOT_IMPLEMENTED
;
2009 /***********************************************************************
2010 * MsiGetFileHashA [MSI.@]
2012 UINT WINAPI
MsiGetFileHashA( LPCSTR szFilePath
, DWORD dwOptions
,
2013 PMSIFILEHASHINFO pHash
)
2015 FIXME("%s %08lx %p\n", debugstr_a(szFilePath
), dwOptions
, pHash
);
2016 return ERROR_CALL_NOT_IMPLEMENTED
;
2019 /***********************************************************************
2020 * MsiAdvertiseScriptW [MSI.@]
2022 UINT WINAPI
MsiAdvertiseScriptW( LPCWSTR szScriptFile
, DWORD dwFlags
,
2023 PHKEY phRegData
, BOOL fRemoveItems
)
2025 FIXME("%s %08lx %p %d\n",
2026 debugstr_w( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2027 return ERROR_CALL_NOT_IMPLEMENTED
;
2030 /***********************************************************************
2031 * MsiAdvertiseScriptA [MSI.@]
2033 UINT WINAPI
MsiAdvertiseScriptA( LPCSTR szScriptFile
, DWORD dwFlags
,
2034 PHKEY phRegData
, BOOL fRemoveItems
)
2036 FIXME("%s %08lx %p %d\n",
2037 debugstr_a( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2038 return ERROR_CALL_NOT_IMPLEMENTED
;