2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004,2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
38 #include "wine/unicode.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
44 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
45 * which is a problem because LPCTSTR isn't defined when compiling wine.
46 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
47 * and make sure to only use it in W functions.
49 #define LPCTSTR LPCWSTR
52 INSTALLUILEVEL gUILevel
= INSTALLUILEVEL_BASIC
;
54 INSTALLUI_HANDLERA gUIHandlerA
= NULL
;
55 INSTALLUI_HANDLERW gUIHandlerW
= NULL
;
57 LPVOID gUIContext
= NULL
;
58 WCHAR gszLogFile
[MAX_PATH
];
59 HINSTANCE msi_hInstance
;
61 static const WCHAR installerW
[] = {'\\','I','n','s','t','a','l','l','e','r',0};
63 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
66 LPWSTR szwProd
= NULL
;
68 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
72 szwProd
= strdupAtoW( szProduct
);
74 return ERROR_OUTOFMEMORY
;
77 r
= MsiOpenProductW( szwProd
, phProduct
);
84 static UINT
MSI_OpenProductW( LPCWSTR szProduct
, MSIPACKAGE
**ppackage
)
88 HKEY hKeyProduct
= NULL
;
91 TRACE("%s %p\n", debugstr_w(szProduct
), ppackage
);
93 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
94 if( r
!= ERROR_SUCCESS
)
96 r
= ERROR_UNKNOWN_PRODUCT
;
100 /* find the size of the path */
102 r
= RegQueryValueExW( hKeyProduct
, INSTALLPROPERTY_LOCALPACKAGEW
,
103 NULL
, &type
, NULL
, &count
);
104 if( r
!= ERROR_SUCCESS
)
106 r
= ERROR_UNKNOWN_PRODUCT
;
110 /* now alloc and fetch the path of the database to open */
111 path
= msi_alloc( count
);
115 r
= RegQueryValueExW( hKeyProduct
, INSTALLPROPERTY_LOCALPACKAGEW
,
116 NULL
, &type
, (LPBYTE
) path
, &count
);
117 if( r
!= ERROR_SUCCESS
)
119 r
= ERROR_UNKNOWN_PRODUCT
;
123 r
= MSI_OpenPackageW( path
, ppackage
);
128 RegCloseKey( hKeyProduct
);
133 UINT WINAPI
MsiOpenProductW( LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
135 MSIPACKAGE
*package
= NULL
;
138 r
= MSI_OpenProductW( szProduct
, &package
);
139 if( r
== ERROR_SUCCESS
)
141 *phProduct
= alloc_msihandle( &package
->hdr
);
142 msiobj_release( &package
->hdr
);
147 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
148 LPCSTR szTransforms
, LANGID lgidLanguage
)
150 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
151 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
152 return ERROR_CALL_NOT_IMPLEMENTED
;
155 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
156 LPCWSTR szTransforms
, LANGID lgidLanguage
)
158 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
159 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
160 return ERROR_CALL_NOT_IMPLEMENTED
;
163 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
164 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
166 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
167 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
168 lgidLanguage
, dwPlatform
, dwOptions
);
169 return ERROR_CALL_NOT_IMPLEMENTED
;
172 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
173 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
175 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
176 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
177 lgidLanguage
, dwPlatform
, dwOptions
);
178 return ERROR_CALL_NOT_IMPLEMENTED
;
181 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
183 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
184 UINT r
= ERROR_OUTOFMEMORY
;
186 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
190 szwPath
= strdupAtoW( szPackagePath
);
197 szwCommand
= strdupAtoW( szCommandLine
);
202 r
= MsiInstallProductW( szwPath
, szwCommand
);
206 msi_free( szwCommand
);
211 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
213 MSIPACKAGE
*package
= NULL
;
216 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
218 r
= MSI_OpenPackageW( szPackagePath
, &package
);
219 if (r
== ERROR_SUCCESS
)
221 r
= MSI_InstallPackage( package
, szPackagePath
, szCommandLine
);
222 msiobj_release( &package
->hdr
);
228 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
230 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
231 return ERROR_CALL_NOT_IMPLEMENTED
;
234 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
236 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
237 return ERROR_CALL_NOT_IMPLEMENTED
;
240 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
241 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
243 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
244 eInstallType
, debugstr_a(szCommandLine
));
245 return ERROR_CALL_NOT_IMPLEMENTED
;
248 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
249 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
251 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
252 eInstallType
, debugstr_w(szCommandLine
));
253 return ERROR_CALL_NOT_IMPLEMENTED
;
256 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
257 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
259 MSIPACKAGE
* package
= NULL
;
262 WCHAR sourcepath
[MAX_PATH
];
263 WCHAR filename
[MAX_PATH
];
264 static const WCHAR szInstalled
[] = {
265 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
268 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
269 debugstr_w(szCommandLine
));
271 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
272 eInstallState
!= INSTALLSTATE_DEFAULT
)
274 FIXME("Not implemented for anything other than local installs\n");
275 return ERROR_CALL_NOT_IMPLEMENTED
;
278 sz
= sizeof(sourcepath
);
279 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
280 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
283 sz
= sizeof(filename
);
284 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
285 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
287 lstrcatW(sourcepath
,filename
);
290 * ok 1, we need to find the msi file for this product.
291 * 2, find the source dir for the files
292 * 3, do the configure/install.
293 * 4, cleanupany runonce entry.
296 r
= MSI_OpenProductW( szProduct
, &package
);
297 if (r
!= ERROR_SUCCESS
)
300 sz
= lstrlenW(szInstalled
) + 1;
303 sz
+= lstrlenW(szCommandLine
);
305 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
308 r
= ERROR_OUTOFMEMORY
;
314 lstrcpyW(commandline
,szCommandLine
);
316 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
317 lstrcatW(commandline
,szInstalled
);
319 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
321 msi_free(commandline
);
324 msiobj_release( &package
->hdr
);
329 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
330 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
332 LPWSTR szwProduct
= NULL
;
333 LPWSTR szwCommandLine
= NULL
;
334 UINT r
= ERROR_OUTOFMEMORY
;
338 szwProduct
= strdupAtoW( szProduct
);
345 szwCommandLine
= strdupAtoW( szCommandLine
);
350 r
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
353 msi_free( szwProduct
);
354 msi_free( szwCommandLine
);
359 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
360 INSTALLSTATE eInstallState
)
362 LPWSTR szwProduct
= NULL
;
365 TRACE("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
369 szwProduct
= strdupAtoW( szProduct
);
371 return ERROR_OUTOFMEMORY
;
374 r
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
375 msi_free( szwProduct
);
380 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
381 INSTALLSTATE eInstallState
)
383 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
385 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
, NULL
);
388 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
390 LPWSTR szwComponent
= NULL
;
392 WCHAR szwBuffer
[GUID_SIZE
];
394 TRACE("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
398 szwComponent
= strdupAtoW( szComponent
);
400 return ERROR_OUTOFMEMORY
;
403 r
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
405 if( ERROR_SUCCESS
== r
)
406 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
408 msi_free( szwComponent
);
413 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
417 WCHAR szSquished
[GUID_SIZE
];
418 DWORD sz
= GUID_SIZE
;
419 static const WCHAR szPermKey
[] =
420 { '0','0','0','0','0','0','0','0','0','0','0','0',
421 '0','0','0','0','0','0','0', '0','0','0','0','0',
422 '0','0','0','0','0','0','0','0',0};
424 TRACE("%s %p\n",debugstr_w(szComponent
), szBuffer
);
426 if (NULL
== szComponent
)
427 return ERROR_INVALID_PARAMETER
;
429 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
430 if (rc
!= ERROR_SUCCESS
)
431 return ERROR_UNKNOWN_COMPONENT
;
433 rc
= RegEnumValueW(hkey
, 0, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
434 if (rc
== ERROR_SUCCESS
&& strcmpW(szSquished
,szPermKey
)==0)
437 rc
= RegEnumValueW(hkey
, 1, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
442 if (rc
!= ERROR_SUCCESS
)
443 return ERROR_INSTALL_FAILURE
;
445 unsquash_guid(szSquished
, szBuffer
);
446 return ERROR_SUCCESS
;
449 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
450 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
452 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
453 UINT r
= ERROR_OUTOFMEMORY
;
454 DWORD pcchwValueBuf
= 0;
456 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szAttribute
),
457 szBuffer
, pcchValueBuf
);
461 szwProduct
= strdupAtoW( szProduct
);
468 szwAttribute
= strdupAtoW( szAttribute
);
475 szwBuffer
= msi_alloc( (*pcchValueBuf
) * sizeof(WCHAR
) );
476 pcchwValueBuf
= *pcchValueBuf
;
481 r
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
,
484 if( ERROR_SUCCESS
== r
)
486 INT old_len
= *pcchValueBuf
;
487 *pcchValueBuf
= WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, pcchwValueBuf
,
488 szBuffer
, *pcchValueBuf
, NULL
, NULL
);
489 if (old_len
> *pcchValueBuf
)
490 szBuffer
[*pcchValueBuf
]=0;
494 msi_free( szwProduct
);
495 msi_free( szwAttribute
);
496 msi_free( szwBuffer
);
501 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
502 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
506 static const WCHAR szProductVersion
[] =
507 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
508 static const WCHAR szProductLanguage
[] =
509 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
511 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
512 szBuffer
, pcchValueBuf
);
514 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
515 return ERROR_INVALID_PARAMETER
;
516 if (NULL
== szProduct
|| NULL
== szAttribute
)
517 return ERROR_INVALID_PARAMETER
;
519 /* check for special properties */
520 if (strcmpW(szAttribute
, INSTALLPROPERTY_PACKAGECODEW
)==0)
523 WCHAR squished
[GUID_SIZE
];
525 DWORD sz
= sizeof(squished
);
527 r
= MSIREG_OpenUserProductsKey(szProduct
, &hkey
, FALSE
);
528 if (r
!= ERROR_SUCCESS
)
529 return ERROR_UNKNOWN_PRODUCT
;
531 r
= RegQueryValueExW(hkey
, INSTALLPROPERTY_PACKAGECODEW
, NULL
, NULL
,
532 (LPBYTE
)squished
, &sz
);
533 if (r
!= ERROR_SUCCESS
)
536 return ERROR_UNKNOWN_PRODUCT
;
539 unsquash_guid(squished
, package
);
540 *pcchValueBuf
= strlenW(package
);
541 if (strlenW(package
) > *pcchValueBuf
)
544 return ERROR_MORE_DATA
;
547 strcpyW(szBuffer
, package
);
552 else if (strcmpW(szAttribute
, INSTALLPROPERTY_VERSIONSTRINGW
)==0)
554 r
= MsiOpenProductW(szProduct
, &hProduct
);
555 if (ERROR_SUCCESS
!= r
)
558 r
= MsiGetPropertyW(hProduct
, szProductVersion
, szBuffer
, pcchValueBuf
);
559 MsiCloseHandle(hProduct
);
561 else if (strcmpW(szAttribute
, INSTALLPROPERTY_ASSIGNMENTTYPEW
)==0)
563 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
573 else if (strcmpW(szAttribute
, INSTALLPROPERTY_LANGUAGEW
)==0)
575 r
= MsiOpenProductW(szProduct
, &hProduct
);
576 if (ERROR_SUCCESS
!= r
)
579 r
= MsiGetPropertyW(hProduct
, szProductLanguage
, szBuffer
, pcchValueBuf
);
580 MsiCloseHandle(hProduct
);
584 r
= MsiOpenProductW(szProduct
, &hProduct
);
585 if (ERROR_SUCCESS
!= r
)
588 r
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
589 MsiCloseHandle(hProduct
);
595 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
597 LPWSTR szwLogFile
= NULL
;
600 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
604 szwLogFile
= strdupAtoW( szLogFile
);
606 return ERROR_OUTOFMEMORY
;
608 r
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
609 msi_free( szwLogFile
);
613 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
615 HANDLE file
= INVALID_HANDLE_VALUE
;
617 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
619 lstrcpyW(gszLogFile
,szLogFile
);
620 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
621 DeleteFileW(szLogFile
);
622 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
623 FILE_ATTRIBUTE_NORMAL
, NULL
);
624 if (file
!= INVALID_HANDLE_VALUE
)
627 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
629 return ERROR_SUCCESS
;
632 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
634 LPWSTR szwProduct
= NULL
;
639 szwProduct
= strdupAtoW( szProduct
);
641 return ERROR_OUTOFMEMORY
;
643 r
= MsiQueryProductStateW( szwProduct
);
644 msi_free( szwProduct
);
648 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
651 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
653 static const WCHAR szWindowsInstaller
[] = {
654 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
657 TRACE("%s\n", debugstr_w(szProduct
));
659 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
660 if (rc
!= ERROR_SUCCESS
)
665 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
666 if (rc
!= ERROR_SUCCESS
)
670 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
671 if (rc
!= ERROR_SUCCESS
)
678 rrc
= INSTALLSTATE_DEFAULT
;
681 FIXME("Unknown install state read from registry (%i)\n",rrc
);
682 rrc
= INSTALLSTATE_UNKNOWN
;
690 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
692 INSTALLUILEVEL old
= gUILevel
;
693 HWND oldwnd
= gUIhwnd
;
695 TRACE("%08x %p\n", dwUILevel
, phWnd
);
697 gUILevel
= dwUILevel
;
706 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
707 DWORD dwMessageFilter
, LPVOID pvContext
)
709 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
711 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
712 gUIHandlerA
= puiHandler
;
713 gUIFilter
= dwMessageFilter
;
714 gUIContext
= pvContext
;
719 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
720 DWORD dwMessageFilter
, LPVOID pvContext
)
722 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
724 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
725 gUIHandlerW
= puiHandler
;
726 gUIFilter
= dwMessageFilter
;
727 gUIContext
= pvContext
;
732 /******************************************************************
733 * MsiLoadStringW [MSI.@]
735 * Loads a string from MSI's string resources.
739 * handle [I] only -1 is handled currently
740 * id [I] id of the string to be loaded
741 * lpBuffer [O] buffer for the string to be written to
742 * nBufferMax [I] maximum size of the buffer in characters
743 * lang [I] the preferred language for the string
747 * If successful, this function returns the language id of the string loaded
748 * If the function fails, the function returns zero.
752 * The type of the first parameter is unknown. LoadString's prototype
753 * suggests that it might be a module handle. I have made it an MSI handle
754 * for starters, as -1 is an invalid MSI handle, but not an invalid module
755 * handle. Maybe strings can be stored in an MSI database somehow.
757 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
758 int nBufferMax
, LANGID lang
)
765 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
768 FIXME("don't know how to deal with handle = %08lx\n", handle
);
771 lang
= GetUserDefaultLangID();
773 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
777 hResData
= LoadResource( msi_hInstance
, hres
);
780 p
= LockResource( hResData
);
784 for (i
= 0; i
< (id
&0xf); i
++)
788 if( nBufferMax
<= len
)
791 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
794 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
799 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
800 int nBufferMax
, LANGID lang
)
806 bufW
= msi_alloc(nBufferMax
*sizeof(WCHAR
));
807 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
810 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
811 if( len
<= nBufferMax
)
812 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
813 lpBuffer
, nBufferMax
, NULL
, NULL
);
821 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
824 FIXME("%s %p %p\n", debugstr_a(szComponent
), lpPathBuf
, pcchBuf
);
825 return INSTALLSTATE_UNKNOWN
;
828 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
831 FIXME("%s %p %p\n", debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
832 return INSTALLSTATE_UNKNOWN
;
835 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
836 WORD wLanguageId
, DWORD f
)
838 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
839 uType
,wLanguageId
,f
);
840 return ERROR_CALL_NOT_IMPLEMENTED
;
843 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
844 WORD wLanguageId
, DWORD f
)
846 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
847 uType
,wLanguageId
,f
);
848 return ERROR_CALL_NOT_IMPLEMENTED
;
851 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
852 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
855 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
856 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
858 return ERROR_CALL_NOT_IMPLEMENTED
;
861 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
862 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
865 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
866 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
868 return ERROR_CALL_NOT_IMPLEMENTED
;
871 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
872 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
874 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
875 return ERROR_CALL_NOT_IMPLEMENTED
;
878 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
879 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
881 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
882 return ERROR_CALL_NOT_IMPLEMENTED
;
885 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
886 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
889 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
890 ppcCertContext
, pbHashData
, pcbHashData
);
891 return ERROR_CALL_NOT_IMPLEMENTED
;
894 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
895 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
898 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
899 ppcCertContext
, pbHashData
, pcbHashData
);
900 return ERROR_CALL_NOT_IMPLEMENTED
;
903 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
904 LPSTR szValue
, DWORD
*pccbValue
)
906 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
907 return ERROR_CALL_NOT_IMPLEMENTED
;
910 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
911 LPWSTR szValue
, DWORD
*pccbValue
)
913 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
914 return ERROR_CALL_NOT_IMPLEMENTED
;
917 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
920 LPWSTR szPack
= NULL
;
922 TRACE("%s\n", debugstr_a(szPackage
) );
926 szPack
= strdupAtoW( szPackage
);
928 return ERROR_OUTOFMEMORY
;
931 r
= MsiVerifyPackageW( szPack
);
938 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
943 TRACE("%s\n", debugstr_w(szPackage
) );
945 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
946 MsiCloseHandle( handle
);
951 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
952 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
954 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
960 szwProduct
= strdupAtoW( szProduct
);
962 return ERROR_OUTOFMEMORY
;
967 szwComponent
= strdupAtoW( szComponent
);
970 msi_free( szwProduct
);
971 return ERROR_OUTOFMEMORY
;
975 if( pcchBuf
&& *pcchBuf
> 0 )
977 lpwPathBuf
= msi_alloc( *pcchBuf
* sizeof(WCHAR
));
978 incoming_len
= *pcchBuf
;
986 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
988 msi_free( szwProduct
);
989 msi_free( szwComponent
);
992 if (rc
!= INSTALLSTATE_UNKNOWN
)
993 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
994 lpPathBuf
, incoming_len
, NULL
, NULL
);
995 msi_free( lpwPathBuf
);
1001 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1002 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1004 WCHAR squished_pc
[GUID_SIZE
];
1006 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1011 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1012 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1014 if( lpPathBuf
&& !pcchBuf
)
1015 return INSTALLSTATE_INVALIDARG
;
1017 squash_guid(szProduct
,squished_pc
);
1019 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1020 if( rc
!= ERROR_SUCCESS
)
1025 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1026 if( rc
!= ERROR_SUCCESS
)
1031 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1032 if( rc
!= ERROR_SUCCESS
)
1034 if( type
!= REG_SZ
)
1037 sz
+= sizeof(WCHAR
);
1038 path
= msi_alloc( sz
);
1042 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1043 if( rc
!= ERROR_SUCCESS
)
1046 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1047 debugstr_w(szProduct
), debugstr_w(path
));
1051 FIXME("Registry entry.. check entry\n");
1052 rrc
= INSTALLSTATE_LOCAL
;
1056 /* PROBABLY a file */
1057 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1058 rrc
= INSTALLSTATE_LOCAL
;
1060 rrc
= INSTALLSTATE_ABSENT
;
1065 sz
= sz
/ sizeof(WCHAR
);
1066 if( *pcchBuf
>= sz
)
1067 lstrcpyW( lpPathBuf
, path
);
1077 /******************************************************************
1078 * MsiQueryFeatureStateA [MSI.@]
1080 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1083 LPWSTR szwProduct
= NULL
;
1084 LPWSTR szwFeature
= NULL
;
1088 szwProduct
= strdupAtoW( szProduct
);
1090 return ERROR_OUTOFMEMORY
;
1095 szwFeature
= strdupAtoW( szFeature
);
1098 msi_free( szwProduct
);
1099 return ERROR_OUTOFMEMORY
;
1103 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1105 msi_free( szwProduct
);
1106 msi_free( szwFeature
);
1111 /******************************************************************
1112 * MsiQueryFeatureStateW [MSI.@]
1114 * This does not verify that the Feature is functional. So i am only going to
1115 * check the existence of the key in the registry. This should tell me if it is
1118 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1124 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1126 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1127 if (rc
!= ERROR_SUCCESS
)
1128 return INSTALLSTATE_UNKNOWN
;
1130 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1133 if (rc
== ERROR_SUCCESS
)
1134 return INSTALLSTATE_LOCAL
;
1136 return INSTALLSTATE_ABSENT
;
1139 /******************************************************************
1140 * MsiGetFileVersionA [MSI.@]
1142 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1143 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1145 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1146 UINT ret
= ERROR_OUTOFMEMORY
;
1150 szwFilePath
= strdupAtoW( szFilePath
);
1155 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1157 lpwVersionBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1158 if( !lpwVersionBuff
)
1162 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1164 lpwLangBuff
= msi_alloc(*pcchVersionBuf
*sizeof(WCHAR
));
1169 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1170 lpwLangBuff
, pcchLangBuf
);
1172 if( lpwVersionBuff
)
1173 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1174 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1176 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1177 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1180 msi_free(szwFilePath
);
1181 msi_free(lpwVersionBuff
);
1182 msi_free(lpwLangBuff
);
1187 /******************************************************************
1188 * MsiGetFileVersionW [MSI.@]
1190 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1191 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1193 static const WCHAR szVersionResource
[] = {'\\',0};
1194 static const WCHAR szVersionFormat
[] = {
1195 '%','d','.','%','d','.','%','d','.','%','d',0};
1196 static const WCHAR szLangFormat
[] = {'%','d',0};
1199 LPVOID lpVer
= NULL
;
1200 VS_FIXEDFILEINFO
*ffi
;
1204 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1205 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1206 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1208 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1210 return GetLastError();
1212 lpVer
= msi_alloc(dwVerLen
);
1215 ret
= ERROR_OUTOFMEMORY
;
1219 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1221 ret
= GetLastError();
1224 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1226 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1229 wsprintfW(tmp
, szVersionFormat
,
1230 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1231 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1232 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1233 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1238 *pcchVersionBuf
= 0;
1242 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1244 DWORD lang
= GetUserDefaultLangID();
1246 FIXME("Retrieve language from file\n");
1247 wsprintfW(tmp
, szLangFormat
, lang
);
1248 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1249 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1258 /******************************************************************
1261 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1265 case DLL_PROCESS_ATTACH
:
1266 msi_hInstance
= hinstDLL
;
1267 DisableThreadLibraryCalls(hinstDLL
);
1268 msi_dialog_register_class();
1270 case DLL_PROCESS_DETACH
:
1271 msi_dialog_unregister_class();
1272 /* FIXME: Cleanup */
1278 typedef struct tagIClassFactoryImpl
1280 const IClassFactoryVtbl
*lpVtbl
;
1281 } IClassFactoryImpl
;
1283 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1284 REFIID riid
,LPVOID
*ppobj
)
1286 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1287 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1288 return E_NOINTERFACE
;
1291 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1296 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1301 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1302 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1304 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1306 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1310 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1312 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1314 FIXME("%p %d\n", This
, dolock
);
1318 static const IClassFactoryVtbl MsiCF_Vtbl
=
1320 MsiCF_QueryInterface
,
1323 MsiCF_CreateInstance
,
1327 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1329 /******************************************************************
1330 * DllGetClassObject [MSI.@]
1332 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1334 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1336 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1337 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1338 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1339 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1340 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1342 *ppv
= (LPVOID
) &Msi_CF
;
1345 return CLASS_E_CLASSNOTAVAILABLE
;
1348 /******************************************************************
1349 * DllGetVersion [MSI.@]
1351 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1355 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1356 return E_INVALIDARG
;
1358 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1359 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1360 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1361 pdvi
->dwPlatformID
= 1;
1366 /******************************************************************
1367 * DllCanUnloadNow [MSI.@]
1369 HRESULT WINAPI
DllCanUnloadNow(void)
1374 UINT WINAPI
MsiGetFeatureUsageW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1375 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1377 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1378 pdwUseCount
, pwDateUsed
);
1379 return ERROR_CALL_NOT_IMPLEMENTED
;
1382 UINT WINAPI
MsiGetFeatureUsageA(LPCSTR szProduct
, LPCSTR szFeature
,
1383 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1385 FIXME("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1386 pdwUseCount
, pwDateUsed
);
1387 return ERROR_CALL_NOT_IMPLEMENTED
;
1390 INSTALLSTATE WINAPI
MsiUseFeatureExW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1391 DWORD dwInstallMode
, DWORD dwReserved
)
1393 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1394 dwInstallMode
, dwReserved
);
1397 * Polls all the components of the feature to find install state and then
1399 * Software\\Microsoft\\Windows\\CurrentVersion\\
1400 * Installer\\Products\\<squishguid>\\<feature>
1401 * "Usage"=dword:........
1404 return INSTALLSTATE_LOCAL
;
1407 /***********************************************************************
1408 * MsiUseFeatureExA [MSI.@]
1410 INSTALLSTATE WINAPI
MsiUseFeatureExA(LPCSTR szProduct
, LPCSTR szFeature
,
1411 DWORD dwInstallMode
, DWORD dwReserved
)
1413 FIXME("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1414 dwInstallMode
, dwReserved
);
1416 return INSTALLSTATE_LOCAL
;
1419 INSTALLSTATE WINAPI
MsiUseFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1421 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1423 return INSTALLSTATE_LOCAL
;
1426 INSTALLSTATE WINAPI
MsiUseFeatureA(LPCSTR szProduct
, LPCSTR szFeature
)
1428 FIXME("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
));
1430 return INSTALLSTATE_LOCAL
;
1433 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1434 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1435 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1442 LPWSTR product
= NULL
;
1443 LPWSTR component
= NULL
;
1447 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1448 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1449 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1451 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1452 if (rc
!= ERROR_SUCCESS
)
1453 return ERROR_INDEX_ABSENT
;
1456 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1460 return ERROR_INDEX_ABSENT
;
1463 info
= msi_alloc(sz
);
1464 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1465 if (rc
!= ERROR_SUCCESS
)
1469 return ERROR_INDEX_ABSENT
;
1472 /* find the component */
1473 ptr
= strchrW(&info
[20],'>');
1480 return ERROR_INDEX_ABSENT
;
1485 decode_base85_guid(info
,&clsid
);
1486 StringFromCLSID(&clsid
, &product
);
1488 decode_base85_guid(ptr
,&clsid
);
1489 StringFromCLSID(&clsid
, &component
);
1492 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1494 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1499 msi_free(component
);
1501 if (rc
== INSTALLSTATE_LOCAL
)
1502 return ERROR_SUCCESS
;
1504 return ERROR_FILE_NOT_FOUND
;
1507 /***********************************************************************
1508 * MsiProvideQualifiedComponentW [MSI.@]
1510 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1511 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1514 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1515 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1518 /***********************************************************************
1519 * MsiProvideQualifiedComponentA [MSI.@]
1521 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1522 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1525 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1529 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1530 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1532 szwComponent
= strdupAtoW( szComponent
);
1533 szwQualifier
= strdupAtoW( szQualifier
);
1535 lpwPathBuf
= msi_alloc(*pcchPathBuf
* sizeof(WCHAR
));
1537 pcchwPathBuf
= *pcchPathBuf
;
1539 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1540 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1542 msi_free(szwComponent
);
1543 msi_free(szwQualifier
);
1544 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1545 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1547 msi_free(lpwPathBuf
);
1551 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1552 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1553 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1557 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1559 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1560 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1563 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1564 if (rc
!= ERROR_SUCCESS
)
1565 return USERINFOSTATE_UNKNOWN
;
1569 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1570 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1571 NULL
, (LPBYTE
)lpUserNameBuf
,
1574 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1577 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1581 if (pcchUserNameBuf
)
1582 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1586 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1587 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1588 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1590 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1593 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1598 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1600 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1601 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1604 return USERINFOSTATE_ABSENT
;
1609 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1610 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1611 (LPBYTE
)lpSerialBuf
, &sz
);
1613 if (!lpSerialBuf
&& pcchSerialBuf
)
1616 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1620 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1623 return USERINFOSTATE_PRESENT
;
1626 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1627 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1628 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1630 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1631 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1634 return USERINFOSTATE_UNKNOWN
;
1637 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1641 MSIPACKAGE
*package
;
1642 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1644 TRACE("(%s)\n",debugstr_w(szProduct
));
1646 rc
= MsiOpenProductW(szProduct
,&handle
);
1647 if (rc
!= ERROR_SUCCESS
)
1648 return ERROR_INVALID_PARAMETER
;
1650 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1651 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1652 msiobj_release( &package
->hdr
);
1654 MsiCloseHandle(handle
);
1659 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1663 MSIPACKAGE
*package
;
1664 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1666 TRACE("(%s)\n",debugstr_a(szProduct
));
1668 rc
= MsiOpenProductA(szProduct
,&handle
);
1669 if (rc
!= ERROR_SUCCESS
)
1670 return ERROR_INVALID_PARAMETER
;
1672 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1673 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1674 msiobj_release( &package
->hdr
);
1676 MsiCloseHandle(handle
);
1681 /***********************************************************************
1682 * MsiConfigureFeatureA [MSI.@]
1684 UINT WINAPI
MsiConfigureFeatureA(LPCSTR szProduct
, LPCSTR szFeature
, INSTALLSTATE eInstallState
)
1686 FIXME("%s %s %i\n", debugstr_a(szProduct
), debugstr_a(szFeature
), eInstallState
);
1687 return ERROR_SUCCESS
;
1690 /***********************************************************************
1691 * MsiConfigureFeatureW [MSI.@]
1693 UINT WINAPI
MsiConfigureFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
, INSTALLSTATE eInstallState
)
1695 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1696 return ERROR_SUCCESS
;
1699 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1701 WCHAR path
[MAX_PATH
];
1704 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1705 return ERROR_CALL_NOT_IMPLEMENTED
;
1708 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1709 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1711 return ERROR_CALL_NOT_IMPLEMENTED
;
1714 strcatW(path
, installerW
);
1716 CreateDirectoryW(path
, NULL
);
1721 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1722 LPSTR szProductCode
, LPSTR szFeatureId
,
1723 LPSTR szComponentCode
)
1726 const int len
= MAX_FEATURE_CHARS
+1;
1727 WCHAR product
[MAX_FEATURE_CHARS
+1], feature
[MAX_FEATURE_CHARS
+1], component
[MAX_FEATURE_CHARS
+1];
1730 target
= strdupAtoW( szShortcutTarget
);
1731 if (szShortcutTarget
&& !target
)
1732 return ERROR_OUTOFMEMORY
;
1736 r
= MsiGetShortcutTargetW( target
, product
, feature
, component
);
1738 if (r
== ERROR_SUCCESS
)
1740 WideCharToMultiByte( CP_ACP
, 0, product
, -1, szProductCode
, len
, NULL
, NULL
);
1741 WideCharToMultiByte( CP_ACP
, 0, feature
, -1, szFeatureId
, len
, NULL
, NULL
);
1742 WideCharToMultiByte( CP_ACP
, 0, component
, -1, szComponentCode
, len
, NULL
, NULL
);
1747 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1748 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1749 LPWSTR szComponentCode
)
1751 FIXME("%s\n", debugstr_w(szShortcutTarget
));
1752 return ERROR_CALL_NOT_IMPLEMENTED
;
1755 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1756 DWORD dwReinstallMode
)
1758 MSIPACKAGE
* package
= NULL
;
1761 WCHAR sourcepath
[MAX_PATH
];
1762 WCHAR filename
[MAX_PATH
];
1763 static const WCHAR szInstalled
[] = {
1764 ' ','L','O','G','V','E','R','B','O','S','E','=','1',' ','I','n','s','t','a','l','l','e','d','=','1',0};
1765 static const WCHAR fmt
[] = {'R','E','I','N','S','T','A','L','L','=','%','s',0};
1766 static const WCHAR REINSTALLMODE
[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1767 WCHAR reinstallmode
[11];
1771 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1774 memset(reinstallmode
,0,sizeof(reinstallmode
));
1775 ptr
= reinstallmode
;
1777 if (dwReinstallMode
& REINSTALLMODE_FILEMISSING
)
1778 { *ptr
= 'p'; ptr
++; }
1779 if (dwReinstallMode
& REINSTALLMODE_FILEOLDERVERSION
)
1780 { *ptr
= 'o'; ptr
++; }
1781 if (dwReinstallMode
& REINSTALLMODE_FILEEQUALVERSION
)
1782 { *ptr
= 'w'; ptr
++; }
1783 if (dwReinstallMode
& REINSTALLMODE_FILEEXACT
)
1784 { *ptr
= 'd'; ptr
++; }
1785 if (dwReinstallMode
& REINSTALLMODE_FILEVERIFY
)
1786 { *ptr
= 'c'; ptr
++; }
1787 if (dwReinstallMode
& REINSTALLMODE_FILEREPLACE
)
1788 { *ptr
= 'a'; ptr
++; }
1789 if (dwReinstallMode
& REINSTALLMODE_USERDATA
)
1790 { *ptr
= 'u'; ptr
++; }
1791 if (dwReinstallMode
& REINSTALLMODE_MACHINEDATA
)
1792 { *ptr
= 'm'; ptr
++; }
1793 if (dwReinstallMode
& REINSTALLMODE_SHORTCUT
)
1794 { *ptr
= 's'; ptr
++; }
1795 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1796 { *ptr
= 'v'; ptr
++; }
1798 sz
= sizeof(sourcepath
);
1799 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1800 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
1803 sz
= sizeof(filename
);
1804 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
1805 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
1807 strcatW(sourcepath
,filename
);
1809 if (dwReinstallMode
& REINSTALLMODE_PACKAGE
)
1810 r
= MSI_OpenPackageW( sourcepath
, &package
);
1812 r
= MSI_OpenProductW( szProduct
, &package
);
1814 if (r
!= ERROR_SUCCESS
)
1817 MSI_SetPropertyW(package
,REINSTALLMODE
,reinstallmode
);
1819 sz
= lstrlenW(szInstalled
);
1820 sz
+= lstrlenW(fmt
);
1821 sz
+= lstrlenW(szFeature
);
1823 commandline
= msi_alloc(sz
* sizeof(WCHAR
));
1825 sprintfW(commandline
,fmt
,szFeature
);
1826 lstrcatW(commandline
,szInstalled
);
1828 r
= MSI_InstallPackage( package
, sourcepath
, commandline
);
1830 msiobj_release( &package
->hdr
);
1832 msi_free(commandline
);
1837 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1838 DWORD dwReinstallMode
)
1844 TRACE("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1847 wszProduct
= strdupAtoW(szProduct
);
1848 wszFeature
= strdupAtoW(szFeature
);
1850 rc
= MsiReinstallFeatureW(wszProduct
, wszFeature
, dwReinstallMode
);
1852 msi_free(wszProduct
);
1853 msi_free(wszFeature
);
1857 /***********************************************************************
1858 * MsiEnumPatchesA [MSI.@]
1860 UINT WINAPI
MsiEnumPatchesA( LPCSTR szProduct
, DWORD iPatchIndex
,
1861 LPSTR lpPatchBuf
, LPSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1863 FIXME("%s %ld %p %p %p\n", debugstr_a(szProduct
),
1864 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1865 return ERROR_NO_MORE_ITEMS
;
1868 /***********************************************************************
1869 * MsiEnumPatchesW [MSI.@]
1871 UINT WINAPI
MsiEnumPatchesW( LPCWSTR szProduct
, DWORD iPatchIndex
,
1872 LPWSTR lpPatchBuf
, LPWSTR lpTransformsBuf
, DWORD
* pcchTransformsBuf
)
1874 FIXME("%s %ld %p %p %p\n", debugstr_w(szProduct
),
1875 iPatchIndex
, lpPatchBuf
, lpTransformsBuf
, pcchTransformsBuf
);
1876 return ERROR_NO_MORE_ITEMS
;