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 char szProduct
[GUID_SIZE
];
840 TRACE("%s %p %p\n", debugstr_a(szComponent
), lpPathBuf
, pcchBuf
);
842 if (MsiGetProductCodeA( szComponent
, szProduct
) != ERROR_SUCCESS
)
843 return INSTALLSTATE_UNKNOWN
;
845 return MsiGetComponentPathA( szProduct
, szComponent
, lpPathBuf
, pcchBuf
);
848 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
851 WCHAR szProduct
[GUID_SIZE
];
853 TRACE("%s %p %p\n", debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
855 if (MsiGetProductCodeW( szComponent
, szProduct
) != ERROR_SUCCESS
)
856 return INSTALLSTATE_UNKNOWN
;
858 return MsiGetComponentPathW( szProduct
, szComponent
, lpPathBuf
, pcchBuf
);
861 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
862 WORD wLanguageId
, DWORD f
)
864 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
865 uType
,wLanguageId
,f
);
866 return MessageBoxExA(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
869 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
870 WORD wLanguageId
, DWORD f
)
872 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
873 uType
,wLanguageId
,f
);
874 return MessageBoxExW(hWnd
,lpText
,lpCaption
,uType
,wLanguageId
);
877 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
878 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
881 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
882 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
884 return ERROR_CALL_NOT_IMPLEMENTED
;
887 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
888 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
891 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
892 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
894 return ERROR_CALL_NOT_IMPLEMENTED
;
897 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
898 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
900 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
901 return ERROR_CALL_NOT_IMPLEMENTED
;
904 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
905 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
907 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
908 return ERROR_CALL_NOT_IMPLEMENTED
;
911 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
912 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
915 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
916 ppcCertContext
, pbHashData
, pcbHashData
);
917 return ERROR_CALL_NOT_IMPLEMENTED
;
920 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
921 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
924 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
925 ppcCertContext
, pbHashData
, pcbHashData
);
926 return ERROR_CALL_NOT_IMPLEMENTED
;
929 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
930 LPSTR szValue
, DWORD
*pccbValue
)
932 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
933 return ERROR_CALL_NOT_IMPLEMENTED
;
936 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
937 LPWSTR szValue
, DWORD
*pccbValue
)
939 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
940 return ERROR_CALL_NOT_IMPLEMENTED
;
943 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
946 LPWSTR szPack
= NULL
;
948 TRACE("%s\n", debugstr_a(szPackage
) );
952 szPack
= strdupAtoW( szPackage
);
954 return ERROR_OUTOFMEMORY
;
957 r
= MsiVerifyPackageW( szPack
);
964 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
969 TRACE("%s\n", debugstr_w(szPackage
) );
971 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
972 MsiCloseHandle( handle
);
977 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
978 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
980 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
986 szwProduct
= strdupAtoW( szProduct
);
988 return ERROR_OUTOFMEMORY
;
993 szwComponent
= strdupAtoW( szComponent
);
996 msi_free( szwProduct
);
997 return ERROR_OUTOFMEMORY
;
1001 if( pcchBuf
&& *pcchBuf
> 0 )
1003 lpwPathBuf
= msi_alloc( *pcchBuf
* sizeof(WCHAR
));
1004 incoming_len
= *pcchBuf
;
1012 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
1014 msi_free( szwProduct
);
1015 msi_free( szwComponent
);
1018 if (rc
!= INSTALLSTATE_UNKNOWN
)
1019 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
1020 lpPathBuf
, incoming_len
, NULL
, NULL
);
1021 msi_free( lpwPathBuf
);
1027 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1028 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1030 WCHAR squished_pc
[GUID_SIZE
];
1032 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1037 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1038 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1041 return INSTALLSTATE_INVALIDARG
;
1042 if( lpPathBuf
&& !pcchBuf
)
1043 return INSTALLSTATE_INVALIDARG
;
1045 squash_guid(szProduct
,squished_pc
);
1047 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1048 if( rc
!= ERROR_SUCCESS
)
1053 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1054 if( rc
!= ERROR_SUCCESS
)
1059 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1060 if( rc
!= ERROR_SUCCESS
)
1062 if( type
!= REG_SZ
)
1065 sz
+= sizeof(WCHAR
);
1066 path
= msi_alloc( sz
);
1070 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1071 if( rc
!= ERROR_SUCCESS
)
1074 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1075 debugstr_w(szProduct
), debugstr_w(path
));
1079 FIXME("Registry entry.. check entry\n");
1080 rrc
= INSTALLSTATE_LOCAL
;
1084 /* PROBABLY a file */
1085 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1086 rrc
= INSTALLSTATE_LOCAL
;
1088 rrc
= INSTALLSTATE_ABSENT
;
1093 sz
= sz
/ sizeof(WCHAR
);
1094 if( *pcchBuf
>= sz
)
1095 lstrcpyW( lpPathBuf
, path
);
1105 /******************************************************************
1106 * MsiQueryFeatureStateA [MSI.@]
1108 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1110 LPWSTR szwProduct
= NULL
, szwFeature
= NULL
;
1111 INSTALLSTATE rc
= INSTALLSTATE_UNKNOWN
;
1113 szwProduct
= strdupAtoW( szProduct
);
1114 if ( szProduct
&& !szwProduct
)
1117 szwFeature
= strdupAtoW( szFeature
);
1118 if ( szFeature
&& !szwFeature
)
1121 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1124 msi_free( szwProduct
);
1125 msi_free( szwFeature
);
1130 /******************************************************************
1131 * MsiQueryFeatureStateW [MSI.@]
1133 * This does not verify that the Feature is functional. So i am only going to
1134 * check the existence of the key in the registry. This should tell me if it is
1137 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1139 WCHAR squishProduct
[GUID_SIZE
];
1144 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1146 if (!szProduct
|| !szFeature
)
1147 return INSTALLSTATE_INVALIDARG
;
1149 if (!squash_guid( szProduct
, squishProduct
))
1150 return INSTALLSTATE_INVALIDARG
;
1152 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1153 if (rc
!= ERROR_SUCCESS
)
1154 return INSTALLSTATE_UNKNOWN
;
1156 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1159 if (rc
== ERROR_SUCCESS
)
1160 return INSTALLSTATE_LOCAL
;
1162 return INSTALLSTATE_UNKNOWN
;
1165 /******************************************************************
1166 * MsiGetFileVersionA [MSI.@]
1168 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1169 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1171 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1172 UINT ret
= ERROR_OUTOFMEMORY
;
1176 szwFilePath
= strdupAtoW( szFilePath
);
1181 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1183 lpwVersionBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1184 if( !lpwVersionBuff
)
1188 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1190 lpwLangBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1195 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1196 lpwLangBuff
, pcchLangBuf
);
1198 if( lpwVersionBuff
)
1199 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1200 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1202 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1203 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1206 msi_free(szwFilePath
);
1207 msi_free(lpwVersionBuff
);
1208 msi_free(lpwLangBuff
);
1213 /******************************************************************
1214 * MsiGetFileVersionW [MSI.@]
1216 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1217 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1219 static WCHAR szVersionResource
[] = {'\\',0};
1220 static const WCHAR szVersionFormat
[] = {
1221 '%','d','.','%','d','.','%','d','.','%','d',0};
1222 static const WCHAR szLangFormat
[] = {'%','d',0};
1225 LPVOID lpVer
= NULL
;
1226 VS_FIXEDFILEINFO
*ffi
;
1230 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1231 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1232 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1234 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1236 return GetLastError();
1238 lpVer
= msi_alloc(dwVerLen
);
1241 ret
= ERROR_OUTOFMEMORY
;
1245 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1247 ret
= GetLastError();
1250 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1252 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1255 wsprintfW(tmp
, szVersionFormat
,
1256 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1257 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1258 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1259 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1264 *pcchVersionBuf
= 0;
1268 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1270 DWORD lang
= GetUserDefaultLangID();
1272 FIXME("Retrieve language from file\n");
1273 wsprintfW(tmp
, szLangFormat
, lang
);
1274 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1275 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1284 /******************************************************************
1287 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1291 case DLL_PROCESS_ATTACH
:
1292 msi_hInstance
= hinstDLL
;
1293 DisableThreadLibraryCalls(hinstDLL
);
1294 msi_dialog_register_class();
1296 case DLL_PROCESS_DETACH
:
1297 msi_dialog_unregister_class();
1298 /* FIXME: Cleanup */
1304 typedef struct tagIClassFactoryImpl
1306 const IClassFactoryVtbl
*lpVtbl
;
1307 } IClassFactoryImpl
;
1309 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1310 REFIID riid
,LPVOID
*ppobj
)
1312 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1313 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1314 return E_NOINTERFACE
;
1317 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1323 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1329 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1330 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1332 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1334 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1338 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1340 TRACE("(%p)->(%d)\n", iface
, dolock
);
1350 static const IClassFactoryVtbl MsiCF_Vtbl
=
1352 MsiCF_QueryInterface
,
1355 MsiCF_CreateInstance
,
1359 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1361 /******************************************************************
1362 * DllGetClassObject [MSI.@]
1364 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1366 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1368 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1369 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1370 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1371 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1372 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1374 *ppv
= (LPVOID
) &Msi_CF
;
1377 return CLASS_E_CLASSNOTAVAILABLE
;
1380 /******************************************************************
1381 * DllGetVersion [MSI.@]
1383 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1387 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1388 return E_INVALIDARG
;
1390 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1391 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1392 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1393 pdvi
->dwPlatformID
= 1;
1398 /******************************************************************
1399 * DllCanUnloadNow [MSI.@]
1401 HRESULT WINAPI
DllCanUnloadNow(void)
1403 return dll_count
== 0 ? S_OK
: S_FALSE
;
1406 /***********************************************************************
1407 * MsiGetFeatureUsageW [MSI.@]
1409 UINT WINAPI
MsiGetFeatureUsageW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1410 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1412 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1413 pdwUseCount
, pwDateUsed
);
1414 return ERROR_CALL_NOT_IMPLEMENTED
;
1417 /***********************************************************************
1418 * MsiGetFeatureUsageA [MSI.@]
1420 UINT WINAPI
MsiGetFeatureUsageA( LPCSTR szProduct
, LPCSTR szFeature
,
1421 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1423 LPWSTR prod
= NULL
, feat
= NULL
;
1424 UINT ret
= ERROR_OUTOFMEMORY
;
1426 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1427 pdwUseCount
, pwDateUsed
);
1429 prod
= strdupAtoW( szProduct
);
1430 if (szProduct
&& !prod
)
1433 feat
= strdupAtoW( szFeature
);
1434 if (szFeature
&& !feat
)
1437 ret
= MsiGetFeatureUsageW( prod
, feat
, pdwUseCount
, pwDateUsed
);
1446 /***********************************************************************
1447 * MsiUseFeatureExW [MSI.@]
1449 INSTALLSTATE WINAPI
MsiUseFeatureExW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1450 DWORD dwInstallMode
, DWORD dwReserved
)
1454 TRACE("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1455 dwInstallMode
, dwReserved
);
1457 state
= MsiQueryFeatureStateW( szProduct
, szFeature
);
1460 return INSTALLSTATE_INVALIDARG
;
1462 if (state
== INSTALLSTATE_LOCAL
&& dwInstallMode
!= INSTALLMODE_NODETECTION
)
1464 FIXME("mark product %s feature %s as used\n",
1465 debugstr_w(szProduct
), debugstr_w(szFeature
) );
1471 /***********************************************************************
1472 * MsiUseFeatureExA [MSI.@]
1474 INSTALLSTATE WINAPI
MsiUseFeatureExA( LPCSTR szProduct
, LPCSTR szFeature
,
1475 DWORD dwInstallMode
, DWORD dwReserved
)
1477 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1478 LPWSTR prod
= NULL
, feat
= NULL
;
1480 TRACE("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1481 dwInstallMode
, dwReserved
);
1483 prod
= strdupAtoW( szProduct
);
1484 if (szProduct
&& !prod
)
1487 feat
= strdupAtoW( szFeature
);
1488 if (szFeature
&& !feat
)
1491 ret
= MsiUseFeatureExW( prod
, feat
, dwInstallMode
, dwReserved
);
1500 INSTALLSTATE WINAPI
MsiUseFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
)
1502 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1504 return INSTALLSTATE_LOCAL
;
1507 INSTALLSTATE WINAPI
MsiUseFeatureA( LPCSTR szProduct
, LPCSTR szFeature
)
1509 INSTALLSTATE ret
= INSTALLSTATE_UNKNOWN
;
1510 LPWSTR prod
= NULL
, feat
= NULL
;
1512 TRACE("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
) );
1514 prod
= strdupAtoW( szProduct
);
1515 if (szProduct
&& !prod
)
1518 feat
= strdupAtoW( szFeature
);
1519 if (szFeature
&& !feat
)
1522 ret
= MsiUseFeatureW( prod
, feat
);
1531 /***********************************************************************
1532 * MsiProvideQualifiedComponentExW [MSI.@]
1534 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1535 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1536 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1543 WCHAR product
[MAX_FEATURE_CHARS
+1];
1544 WCHAR component
[MAX_FEATURE_CHARS
+1];
1545 WCHAR feature
[MAX_FEATURE_CHARS
+1];
1547 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1548 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1549 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1551 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1552 if (rc
!= ERROR_SUCCESS
)
1553 return ERROR_INDEX_ABSENT
;
1556 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1560 return ERROR_INDEX_ABSENT
;
1563 info
= msi_alloc(sz
);
1564 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1565 if (rc
!= ERROR_SUCCESS
)
1569 return ERROR_INDEX_ABSENT
;
1572 MsiDecomposeDescriptorW(info
, product
, feature
, component
, &sz
);
1575 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1577 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1582 if (rc
== INSTALLSTATE_LOCAL
)
1583 return ERROR_SUCCESS
;
1585 return ERROR_FILE_NOT_FOUND
;
1588 /***********************************************************************
1589 * MsiProvideQualifiedComponentW [MSI.@]
1591 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1592 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1595 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1596 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1599 /***********************************************************************
1600 * MsiProvideQualifiedComponentA [MSI.@]
1602 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1603 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1606 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1610 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1611 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1613 szwComponent
= strdupAtoW( szComponent
);
1614 szwQualifier
= strdupAtoW( szQualifier
);
1616 lpwPathBuf
= msi_alloc(*pcchPathBuf
* sizeof(WCHAR
));
1618 pcchwPathBuf
= *pcchPathBuf
;
1620 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1621 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1623 msi_free(szwComponent
);
1624 msi_free(szwQualifier
);
1626 if (rc
== ERROR_SUCCESS
)
1627 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1628 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1630 msi_free(lpwPathBuf
);
1634 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1635 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1636 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1640 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1642 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1643 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1646 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1647 if (rc
!= ERROR_SUCCESS
)
1648 return USERINFOSTATE_UNKNOWN
;
1652 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1653 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1654 NULL
, (LPBYTE
)lpUserNameBuf
,
1657 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1660 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1664 if (pcchUserNameBuf
)
1665 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1669 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1670 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1671 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1673 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1676 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1681 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1683 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1684 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1687 return USERINFOSTATE_ABSENT
;
1692 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1693 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1694 (LPBYTE
)lpSerialBuf
, &sz
);
1696 if (!lpSerialBuf
&& pcchSerialBuf
)
1699 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1703 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1706 return USERINFOSTATE_PRESENT
;
1709 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1710 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1711 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1713 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1714 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1717 return USERINFOSTATE_UNKNOWN
;
1720 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1724 MSIPACKAGE
*package
;
1725 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1727 TRACE("(%s)\n",debugstr_w(szProduct
));
1729 rc
= MsiOpenProductW(szProduct
,&handle
);
1730 if (rc
!= ERROR_SUCCESS
)
1731 return ERROR_INVALID_PARAMETER
;
1733 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1734 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1735 msiobj_release( &package
->hdr
);
1737 MsiCloseHandle(handle
);
1742 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1746 MSIPACKAGE
*package
;
1747 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1749 TRACE("(%s)\n",debugstr_a(szProduct
));
1751 rc
= MsiOpenProductA(szProduct
,&handle
);
1752 if (rc
!= ERROR_SUCCESS
)
1753 return ERROR_INVALID_PARAMETER
;
1755 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1756 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1757 msiobj_release( &package
->hdr
);
1759 MsiCloseHandle(handle
);
1764 /***********************************************************************
1765 * MsiConfigureFeatureA [MSI.@]
1767 UINT WINAPI
MsiConfigureFeatureA(LPCSTR szProduct
, LPCSTR szFeature
, INSTALLSTATE eInstallState
)
1769 FIXME("%s %s %i\n", debugstr_a(szProduct
), debugstr_a(szFeature
), eInstallState
);
1770 return ERROR_SUCCESS
;
1773 /***********************************************************************
1774 * MsiConfigureFeatureW [MSI.@]
1776 UINT WINAPI
MsiConfigureFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
, INSTALLSTATE eInstallState
)
1778 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1779 return ERROR_SUCCESS
;
1782 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1784 WCHAR path
[MAX_PATH
];
1787 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1788 return ERROR_CALL_NOT_IMPLEMENTED
;
1791 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1792 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1794 return ERROR_CALL_NOT_IMPLEMENTED
;
1797 strcatW(path
, installerW
);
1799 CreateDirectoryW(path
, NULL
);
1804 /***********************************************************************
1805 * MsiGetShortcutTargetA [MSI.@]
1807 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1808 LPSTR szProductCode
, LPSTR szFeatureId
,
1809 LPSTR szComponentCode
)
1812 const int len
= MAX_FEATURE_CHARS
+1;
1813 WCHAR product
[MAX_FEATURE_CHARS
+1], feature
[MAX_FEATURE_CHARS
+1], component
[MAX_FEATURE_CHARS
+1];
1816 target
= strdupAtoW( szShortcutTarget
);
1817 if (szShortcutTarget
&& !target
)
1818 return ERROR_OUTOFMEMORY
;
1822 r
= MsiGetShortcutTargetW( target
, product
, feature
, component
);
1824 if (r
== ERROR_SUCCESS
)
1826 WideCharToMultiByte( CP_ACP
, 0, product
, -1, szProductCode
, len
, NULL
, NULL
);
1827 WideCharToMultiByte( CP_ACP
, 0, feature
, -1, szFeatureId
, len
, NULL
, NULL
);
1828 WideCharToMultiByte( CP_ACP
, 0, component
, -1, szComponentCode
, len
, NULL
, NULL
);
1833 /***********************************************************************
1834 * MsiGetShortcutTargetW [MSI.@]
1836 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1837 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1838 LPWSTR szComponentCode
)
1840 IShellLinkDataList
*dl
= NULL
;
1841 IPersistFile
*pf
= NULL
;
1842 LPEXP_DARWIN_LINK darwin
= NULL
;
1845 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget
),
1846 szProductCode
, szFeatureId
, szComponentCode
);
1848 init
= CoInitialize(NULL
);
1850 r
= CoCreateInstance( &CLSID_ShellLink
, NULL
, CLSCTX_INPROC_SERVER
,
1851 &IID_IPersistFile
, (LPVOID
*) &pf
);
1852 if( SUCCEEDED( r
) )
1854 r
= IPersistFile_Load( pf
, szShortcutTarget
,
1855 STGM_READ
| STGM_SHARE_DENY_WRITE
);
1856 if( SUCCEEDED( r
) )
1858 r
= IPersistFile_QueryInterface( pf
, &IID_IShellLinkDataList
,
1860 if( SUCCEEDED( r
) )
1862 IShellLinkDataList_CopyDataBlock( dl
, EXP_DARWIN_ID_SIG
,
1864 IShellLinkDataList_Release( dl
);
1867 IPersistFile_Release( pf
);
1870 if (SUCCEEDED(init
))
1873 TRACE("darwin = %p\n", darwin
);
1880 ret
= MsiDecomposeDescriptorW( darwin
->szwDarwinID
,
1881 szProductCode
, szFeatureId
, szComponentCode
, &sz
);
1882 LocalFree( darwin
);
1886 return ERROR_FUNCTION_FAILED
;
1889 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1890 DWORD dwReinstallMode
)
1892 MSIPACKAGE
* package
= NULL
;
1895 WCHAR sourcepath
[MAX_PATH
];
1896 WCHAR filename
[MAX_PATH
];
1897 static const WCHAR szInstalled
[] = {
1898 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1899 static const WCHAR fmt
[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1900 static const WCHAR REINSTALLMODE
[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1901 WCHAR reinstallmode
[11];
1905 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1908 ptr
= reinstallmode
;
1910 if (dwReinstallMode
& REINSTALLMODE_FILEMISSING
)
1912 if (dwReinstallMode
& REINSTALLMODE_FILEOLDERVERSION
)
1914 if (dwReinstallMode
& REINSTALLMODE_FILEEQUALVERSION
)
1916 if (dwReinstallMode
& REINSTALLMODE_FILEEXACT
)
1918 if (dwReinstallMode
& REINSTALLMODE_FILEVERIFY
)
1920 if (dwReinstallMode
& REINSTALLMODE_FILEREPLACE
)
1922 if (dwReinstallMode
& REINSTALLMODE_USERDATA
)
1924 if (dwReinstallMode
& REINSTALLMODE_MACHINEDATA
)
1926 if (dwReinstallMode
& REINSTALLMODE_SHORTCUT
)
1928 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1932 sz
= sizeof(sourcepath
);
1933 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1934 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
1937 sz
= sizeof(filename
);
1938 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1939 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
1941 strcatW(sourcepath
,filename
);
1943 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1944 r
= MSI_OpenPackageW( sourcepath
, &package
);
1946 r
= MSI_OpenProductW( szProduct
, &package
);
1948 if (r
!= ERROR_SUCCESS
)
1951 MSI_SetPropertyW(package
,REINSTALLMODE
,reinstallmode
);
1953 sz
= lstrlenW(szInstalled
);
1954 sz
+= lstrlenW(fmt
);
1955 sz
+= lstrlenW(szFeature
);
1957 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
1959 sprintfW(commandline
,fmt
,szFeature
);
1960 lstrcatW(commandline
,szInstalled
);
1962 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
1964 msiobj_release( &package
->hdr
);
1966 msi_free(commandline
);
1971 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1972 DWORD dwReinstallMode
)
1978 TRACE("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1981 wszProduct
= strdupAtoW(szProduct
);
1982 wszFeature
= strdupAtoW(szFeature
);
1984 rc
= MsiReinstallFeatureW(wszProduct
, wszFeature
, dwReinstallMode
);
1986 msi_free(wszProduct
);
1987 msi_free(wszFeature
);
1991 /***********************************************************************
1992 * MsiEnumPatchesA [MSI.@]
1994 UINT WINAPI
MsiEnumPatchesA( LPCSTR szProduct
, DWORD iPatchIndex
,
1995 LPSTR lpPatchBuf
, LPSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1997 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct
),
1998 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1999 return ERROR_NO_MORE_ITEMS
;
2002 /***********************************************************************
2003 * MsiEnumPatchesW [MSI.@]
2005 UINT WINAPI
MsiEnumPatchesW( LPCWSTR szProduct
, DWORD iPatchIndex
,
2006 LPWSTR lpPatchBuf
, LPWSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
2008 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct
),
2009 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
2010 return ERROR_NO_MORE_ITEMS
;
2013 /***********************************************************************
2014 * MsiGetFileHashW [MSI.@]
2016 UINT WINAPI
MsiGetFileHashW( LPCWSTR szFilePath
, DWORD dwOptions
,
2017 PMSIFILEHASHINFO pHash
)
2019 FIXME("%s %08lx %p\n", debugstr_w(szFilePath
), dwOptions
, pHash
);
2020 return ERROR_CALL_NOT_IMPLEMENTED
;
2023 /***********************************************************************
2024 * MsiGetFileHashA [MSI.@]
2026 UINT WINAPI
MsiGetFileHashA( LPCSTR szFilePath
, DWORD dwOptions
,
2027 PMSIFILEHASHINFO pHash
)
2029 FIXME("%s %08lx %p\n", debugstr_a(szFilePath
), dwOptions
, pHash
);
2030 return ERROR_CALL_NOT_IMPLEMENTED
;
2033 /***********************************************************************
2034 * MsiAdvertiseScriptW [MSI.@]
2036 UINT WINAPI
MsiAdvertiseScriptW( LPCWSTR szScriptFile
, DWORD dwFlags
,
2037 PHKEY phRegData
, BOOL fRemoveItems
)
2039 FIXME("%s %08lx %p %d\n",
2040 debugstr_w( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2041 return ERROR_CALL_NOT_IMPLEMENTED
;
2044 /***********************************************************************
2045 * MsiAdvertiseScriptA [MSI.@]
2047 UINT WINAPI
MsiAdvertiseScriptA( LPCSTR szScriptFile
, DWORD dwFlags
,
2048 PHKEY phRegData
, BOOL fRemoveItems
)
2050 FIXME("%s %08lx %p %d\n",
2051 debugstr_a( szScriptFile
), dwFlags
, phRegData
, fRemoveItems
);
2052 return ERROR_CALL_NOT_IMPLEMENTED
;