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
);
79 HeapFree( GetProcessHeap(), 0, szwProd
);
84 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
88 HKEY hKeyProduct
= NULL
;
91 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
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
= HeapAlloc( GetProcessHeap(), 0, 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
= MsiOpenPackageW( path
, phProduct
);
126 HeapFree( GetProcessHeap(), 0, path
);
128 RegCloseKey( hKeyProduct
);
133 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
134 LPCSTR szTransforms
, LANGID lgidLanguage
)
136 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
137 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
138 return ERROR_CALL_NOT_IMPLEMENTED
;
141 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
142 LPCWSTR szTransforms
, LANGID lgidLanguage
)
144 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
145 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
146 return ERROR_CALL_NOT_IMPLEMENTED
;
149 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
150 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
152 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
153 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
154 lgidLanguage
, dwPlatform
, dwOptions
);
155 return ERROR_CALL_NOT_IMPLEMENTED
;
158 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
159 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
161 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
162 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
163 lgidLanguage
, dwPlatform
, dwOptions
);
164 return ERROR_CALL_NOT_IMPLEMENTED
;
167 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
169 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
170 UINT r
= ERROR_OUTOFMEMORY
;
172 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
176 szwPath
= strdupAtoW( szPackagePath
);
183 szwCommand
= strdupAtoW( szCommandLine
);
188 r
= MsiInstallProductW( szwPath
, szwCommand
);
191 HeapFree( GetProcessHeap(), 0, szwPath
);
192 HeapFree( GetProcessHeap(), 0, szwCommand
);
197 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
199 MSIPACKAGE
*package
= NULL
;
202 WCHAR path
[MAX_PATH
];
203 WCHAR filename
[MAX_PATH
];
204 static const WCHAR szMSI
[] = {'M','S','I',0};
206 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
208 r
= MsiVerifyPackageW(szPackagePath
);
209 if (r
!= ERROR_SUCCESS
)
212 /* copy the msi file to a temp file to pervent locking a CD
213 * with a multi disc install
215 GetTempPathW(MAX_PATH
, path
);
216 GetTempFileNameW(path
, szMSI
, 0, filename
);
218 CopyFileW(szPackagePath
, filename
, FALSE
);
220 TRACE("Opening relocated package %s\n",debugstr_w(filename
));
221 r
= MSI_OpenPackageW(filename
, &package
);
222 if (r
!= ERROR_SUCCESS
)
224 DeleteFileW(filename
);
228 handle
= alloc_msihandle( &package
->hdr
);
230 r
= ACTION_DoTopLevelINSTALL(package
, szPackagePath
, szCommandLine
,
233 MsiCloseHandle(handle
);
234 msiobj_release( &package
->hdr
);
236 DeleteFileW(filename
);
240 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
242 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
243 return ERROR_CALL_NOT_IMPLEMENTED
;
246 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
248 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
249 return ERROR_CALL_NOT_IMPLEMENTED
;
252 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
253 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
255 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
256 eInstallType
, debugstr_a(szCommandLine
));
257 return ERROR_CALL_NOT_IMPLEMENTED
;
260 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
261 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
263 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
264 eInstallType
, debugstr_w(szCommandLine
));
265 return ERROR_CALL_NOT_IMPLEMENTED
;
268 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
269 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
271 MSIHANDLE handle
= -1;
275 WCHAR sourcepath
[MAX_PATH
];
276 WCHAR filename
[MAX_PATH
];
277 static const WCHAR szInstalled
[] = {
278 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
281 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
282 debugstr_w(szCommandLine
));
284 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
285 eInstallState
!= INSTALLSTATE_DEFAULT
)
287 FIXME("Not implemented for anything other than local installs\n");
288 return ERROR_CALL_NOT_IMPLEMENTED
;
291 sz
= sizeof(sourcepath
);
292 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
293 MSICODE_PRODUCT
, INSTALLPROPERTY_LASTUSEDSOURCEW
, sourcepath
,
296 sz
= sizeof(filename
);
297 MsiSourceListGetInfoW(szProduct
, NULL
, MSIINSTALLCONTEXT_USERMANAGED
,
298 MSICODE_PRODUCT
, INSTALLPROPERTY_PACKAGENAMEW
, filename
, &sz
);
300 strcatW(sourcepath
,filename
);
303 * ok 1, we need to find the msi file for this product.
304 * 2, find the source dir for the files
305 * 3, do the configure/install.
306 * 4, cleanupany runonce entry.
309 rc
= MsiOpenProductW(szProduct
,&handle
);
310 if (rc
!= ERROR_SUCCESS
)
313 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
316 rc
= ERROR_INVALID_HANDLE
;
320 sz
= lstrlenW(szInstalled
);
323 sz
+= lstrlenW(szCommandLine
);
325 commandline
= HeapAlloc(GetProcessHeap(),0,sz
* sizeof(WCHAR
));
328 lstrcpyW(commandline
,szCommandLine
);
332 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
333 lstrcatW(commandline
,szInstalled
);
335 rc
= ACTION_DoTopLevelINSTALL(package
, sourcepath
, commandline
, sourcepath
);
337 msiobj_release( &package
->hdr
);
339 HeapFree(GetProcessHeap(),0,commandline
);
342 MsiCloseHandle(handle
);
347 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
348 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
350 LPWSTR szwProduct
= NULL
;
351 LPWSTR szwCommandLine
= NULL
;
352 UINT r
= ERROR_OUTOFMEMORY
;
356 szwProduct
= strdupAtoW( szProduct
);
363 szwCommandLine
= strdupAtoW( szCommandLine
);
368 r
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
371 HeapFree( GetProcessHeap(), 0, szwProduct
);
372 HeapFree( GetProcessHeap(), 0, szwCommandLine
);
377 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
378 INSTALLSTATE eInstallState
)
380 LPWSTR szwProduct
= NULL
;
383 TRACE("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
387 szwProduct
= strdupAtoW( szProduct
);
389 return ERROR_OUTOFMEMORY
;
392 r
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
393 HeapFree( GetProcessHeap(), 0, szwProduct
);
398 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
399 INSTALLSTATE eInstallState
)
401 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
403 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
, NULL
);
406 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
408 LPWSTR szwComponent
= NULL
;
410 WCHAR szwBuffer
[GUID_SIZE
];
412 TRACE("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
416 szwComponent
= strdupAtoW( szComponent
);
418 return ERROR_OUTOFMEMORY
;
421 r
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
423 if( ERROR_SUCCESS
== r
)
424 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
426 HeapFree( GetProcessHeap(), 0, szwComponent
);
431 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
435 WCHAR szSquished
[GUID_SIZE
];
436 DWORD sz
= GUID_SIZE
;
437 static const WCHAR szPermKey
[] =
438 { '0','0','0','0','0','0','0','0','0','0','0','0',
439 '0','0','0','0','0','0','0', '0','0','0','0','0',
440 '0','0','0','0','0','0','0','0',0};
442 TRACE("%s %p\n",debugstr_w(szComponent
), szBuffer
);
444 if (NULL
== szComponent
)
445 return ERROR_INVALID_PARAMETER
;
447 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
448 if (rc
!= ERROR_SUCCESS
)
449 return ERROR_UNKNOWN_COMPONENT
;
451 rc
= RegEnumValueW(hkey
, 0, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
452 if (rc
== ERROR_SUCCESS
&& strcmpW(szSquished
,szPermKey
)==0)
455 rc
= RegEnumValueW(hkey
, 1, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
460 if (rc
!= ERROR_SUCCESS
)
461 return ERROR_INSTALL_FAILURE
;
463 unsquash_guid(szSquished
, szBuffer
);
464 return ERROR_SUCCESS
;
467 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
468 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
470 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
471 UINT r
= ERROR_OUTOFMEMORY
;
472 DWORD pcchwValueBuf
= 0;
474 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szAttribute
),
475 szBuffer
, pcchValueBuf
);
479 szwProduct
= strdupAtoW( szProduct
);
486 szwAttribute
= strdupAtoW( szAttribute
);
493 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf
) * sizeof(WCHAR
) );
494 pcchwValueBuf
= *pcchValueBuf
;
499 r
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
,
502 if( ERROR_SUCCESS
== r
)
503 *pcchValueBuf
= WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, pcchwValueBuf
,
504 szBuffer
, *pcchValueBuf
, NULL
, NULL
);
507 HeapFree( GetProcessHeap(), 0, szwProduct
);
508 HeapFree( GetProcessHeap(), 0, szwAttribute
);
509 HeapFree( GetProcessHeap(), 0, szwBuffer
);
514 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
515 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
519 static const WCHAR szProductVersion
[] =
520 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
521 static const WCHAR szProductLanguage
[] =
522 {'P','r','o','d','u','c','t','L','a','n','g','u','a','g','e',0};
524 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
525 szBuffer
, pcchValueBuf
);
527 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
528 return ERROR_INVALID_PARAMETER
;
529 if (NULL
== szProduct
|| NULL
== szAttribute
)
530 return ERROR_INVALID_PARAMETER
;
532 /* check for special properties */
533 if (strcmpW(szAttribute
, INSTALLPROPERTY_PACKAGECODEW
)==0)
536 WCHAR squished
[GUID_SIZE
];
538 DWORD sz
= sizeof(squished
);
540 r
= MSIREG_OpenUserProductsKey(szProduct
, &hkey
, FALSE
);
541 if (r
!= ERROR_SUCCESS
)
542 return ERROR_UNKNOWN_PRODUCT
;
544 r
= RegQueryValueExW(hkey
, INSTALLPROPERTY_PACKAGECODEW
, NULL
, NULL
,
545 (LPBYTE
)squished
, &sz
);
546 if (r
!= ERROR_SUCCESS
)
549 return ERROR_UNKNOWN_PRODUCT
;
552 unsquash_guid(squished
, package
);
553 *pcchValueBuf
= strlenW(package
);
554 if (strlenW(package
) > *pcchValueBuf
)
557 return ERROR_MORE_DATA
;
560 strcpyW(szBuffer
, package
);
565 else if (strcmpW(szAttribute
, INSTALLPROPERTY_VERSIONSTRINGW
)==0)
567 r
= MsiOpenProductW(szProduct
, &hProduct
);
568 if (ERROR_SUCCESS
!= r
)
571 r
= MsiGetPropertyW(hProduct
, szProductVersion
, szBuffer
, pcchValueBuf
);
572 MsiCloseHandle(hProduct
);
574 else if (strcmpW(szAttribute
, INSTALLPROPERTY_ASSIGNMENTTYPEW
)==0)
576 FIXME("0 (zero) if advertised or per user , 1(one) if per machine.\n");
586 else if (strcmpW(szAttribute
, INSTALLPROPERTY_LANGUAGEW
)==0)
588 r
= MsiOpenProductW(szProduct
, &hProduct
);
589 if (ERROR_SUCCESS
!= r
)
592 r
= MsiGetPropertyW(hProduct
, szProductLanguage
, szBuffer
, pcchValueBuf
);
593 MsiCloseHandle(hProduct
);
597 r
= MsiOpenProductW(szProduct
, &hProduct
);
598 if (ERROR_SUCCESS
!= r
)
601 r
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
602 MsiCloseHandle(hProduct
);
608 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
610 LPWSTR szwLogFile
= NULL
;
613 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
617 szwLogFile
= strdupAtoW( szLogFile
);
619 return ERROR_OUTOFMEMORY
;
621 r
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
622 HeapFree( GetProcessHeap(), 0, szwLogFile
);
626 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
628 HANDLE file
= INVALID_HANDLE_VALUE
;
630 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
632 lstrcpyW(gszLogFile
,szLogFile
);
633 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
634 DeleteFileW(szLogFile
);
635 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
636 FILE_ATTRIBUTE_NORMAL
, NULL
);
637 if (file
!= INVALID_HANDLE_VALUE
)
640 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
642 return ERROR_SUCCESS
;
645 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
647 LPWSTR szwProduct
= NULL
;
652 szwProduct
= strdupAtoW( szProduct
);
654 return ERROR_OUTOFMEMORY
;
656 r
= MsiQueryProductStateW( szwProduct
);
657 HeapFree( GetProcessHeap(), 0, szwProduct
);
661 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
664 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
666 static const WCHAR szWindowsInstaller
[] = {
667 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
670 TRACE("%s\n", debugstr_w(szProduct
));
672 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
673 if (rc
!= ERROR_SUCCESS
)
678 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
679 if (rc
!= ERROR_SUCCESS
)
683 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
684 if (rc
!= ERROR_SUCCESS
)
691 rrc
= INSTALLSTATE_DEFAULT
;
694 FIXME("Unknown install state read from registry (%i)\n",rrc
);
695 rrc
= INSTALLSTATE_UNKNOWN
;
703 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
705 INSTALLUILEVEL old
= gUILevel
;
706 HWND oldwnd
= gUIhwnd
;
708 TRACE("%08x %p\n", dwUILevel
, phWnd
);
710 gUILevel
= dwUILevel
;
719 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
720 DWORD dwMessageFilter
, LPVOID pvContext
)
722 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
724 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
725 gUIHandlerA
= puiHandler
;
726 gUIFilter
= dwMessageFilter
;
727 gUIContext
= pvContext
;
732 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
733 DWORD dwMessageFilter
, LPVOID pvContext
)
735 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
737 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
738 gUIHandlerW
= puiHandler
;
739 gUIFilter
= dwMessageFilter
;
740 gUIContext
= pvContext
;
745 /******************************************************************
746 * MsiLoadStringW [MSI.@]
748 * Loads a string from MSI's string resources.
752 * handle [I] only -1 is handled currently
753 * id [I] id of the string to be loaded
754 * lpBuffer [O] buffer for the string to be written to
755 * nBufferMax [I] maximum size of the buffer in characters
756 * lang [I] the preferred language for the string
760 * If successful, this function returns the language id of the string loaded
761 * If the function fails, the function returns zero.
765 * The type of the first parameter is unknown. LoadString's prototype
766 * suggests that it might be a module handle. I have made it an MSI handle
767 * for starters, as -1 is an invalid MSI handle, but not an invalid module
768 * handle. Maybe strings can be stored in an MSI database somehow.
770 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
771 int nBufferMax
, LANGID lang
)
778 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
781 FIXME("don't know how to deal with handle = %08lx\n", handle
);
784 lang
= GetUserDefaultLangID();
786 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
790 hResData
= LoadResource( msi_hInstance
, hres
);
793 p
= LockResource( hResData
);
797 for (i
= 0; i
< (id
&0xf); i
++)
801 if( nBufferMax
<= len
)
804 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
807 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
812 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
813 int nBufferMax
, LANGID lang
)
819 bufW
= HeapAlloc(GetProcessHeap(), 0, nBufferMax
*sizeof(WCHAR
));
820 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
823 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
824 if( len
<= nBufferMax
)
825 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
826 lpBuffer
, nBufferMax
, NULL
, NULL
);
830 HeapFree(GetProcessHeap(), 0, bufW
);
834 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
837 FIXME("%s %p %p\n", debugstr_a(szComponent
), lpPathBuf
, pcchBuf
);
838 return INSTALLSTATE_UNKNOWN
;
841 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
844 FIXME("%s %p %p\n", debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
845 return INSTALLSTATE_UNKNOWN
;
848 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
849 WORD wLanguageId
, DWORD f
)
851 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
852 uType
,wLanguageId
,f
);
853 return ERROR_CALL_NOT_IMPLEMENTED
;
856 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
857 WORD wLanguageId
, DWORD f
)
859 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
860 uType
,wLanguageId
,f
);
861 return ERROR_CALL_NOT_IMPLEMENTED
;
864 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
865 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
868 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
869 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
871 return ERROR_CALL_NOT_IMPLEMENTED
;
874 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
875 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
878 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
879 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
881 return ERROR_CALL_NOT_IMPLEMENTED
;
884 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
885 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
887 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
888 return ERROR_CALL_NOT_IMPLEMENTED
;
891 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
892 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
894 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
895 return ERROR_CALL_NOT_IMPLEMENTED
;
898 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
899 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
902 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
903 ppcCertContext
, pbHashData
, pcbHashData
);
904 return ERROR_CALL_NOT_IMPLEMENTED
;
907 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
908 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
911 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
912 ppcCertContext
, pbHashData
, pcbHashData
);
913 return ERROR_CALL_NOT_IMPLEMENTED
;
916 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
917 LPSTR szValue
, DWORD
*pccbValue
)
919 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
920 return ERROR_CALL_NOT_IMPLEMENTED
;
923 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
924 LPWSTR szValue
, DWORD
*pccbValue
)
926 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
927 return ERROR_CALL_NOT_IMPLEMENTED
;
930 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
933 LPWSTR szPack
= NULL
;
935 TRACE("%s\n", debugstr_a(szPackage
) );
939 szPack
= strdupAtoW( szPackage
);
941 return ERROR_OUTOFMEMORY
;
944 r
= MsiVerifyPackageW( szPack
);
946 HeapFree( GetProcessHeap(), 0, szPack
);
951 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
956 TRACE("%s\n", debugstr_w(szPackage
) );
958 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
959 MsiCloseHandle( handle
);
964 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
965 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
967 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
973 szwProduct
= strdupAtoW( szProduct
);
975 return ERROR_OUTOFMEMORY
;
980 szwComponent
= strdupAtoW( szComponent
);
983 HeapFree( GetProcessHeap(), 0, szwProduct
);
984 return ERROR_OUTOFMEMORY
;
988 if( pcchBuf
&& *pcchBuf
> 0 )
990 lpwPathBuf
= HeapAlloc( GetProcessHeap(), 0, *pcchBuf
* sizeof(WCHAR
));
991 incoming_len
= *pcchBuf
;
999 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
1001 HeapFree( GetProcessHeap(), 0, szwProduct
);
1002 HeapFree( GetProcessHeap(), 0, szwComponent
);
1005 if (rc
!= INSTALLSTATE_UNKNOWN
)
1006 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
1007 lpPathBuf
, incoming_len
, NULL
, NULL
);
1008 HeapFree( GetProcessHeap(), 0, lpwPathBuf
);
1014 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1015 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1017 WCHAR squished_pc
[GUID_SIZE
];
1019 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1024 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1025 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1027 if( lpPathBuf
&& !pcchBuf
)
1028 return INSTALLSTATE_INVALIDARG
;
1030 squash_guid(szProduct
,squished_pc
);
1032 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1033 if( rc
!= ERROR_SUCCESS
)
1038 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1039 if( rc
!= ERROR_SUCCESS
)
1044 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1045 if( rc
!= ERROR_SUCCESS
)
1047 if( type
!= REG_SZ
)
1050 sz
+= sizeof(WCHAR
);
1051 path
= HeapAlloc( GetProcessHeap(), 0, sz
);
1055 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1056 if( rc
!= ERROR_SUCCESS
)
1059 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1060 debugstr_w(szProduct
), debugstr_w(path
));
1064 FIXME("Registry entry.. check entry\n");
1065 rrc
= INSTALLSTATE_LOCAL
;
1069 /* PROBABLY a file */
1070 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1071 rrc
= INSTALLSTATE_LOCAL
;
1073 rrc
= INSTALLSTATE_ABSENT
;
1078 sz
= sz
/ sizeof(WCHAR
);
1079 if( *pcchBuf
>= sz
)
1080 lstrcpyW( lpPathBuf
, path
);
1085 HeapFree(GetProcessHeap(), 0, path
);
1090 /******************************************************************
1091 * MsiQueryFeatureStateA [MSI.@]
1093 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1096 LPWSTR szwProduct
= NULL
;
1097 LPWSTR szwFeature
= NULL
;
1101 szwProduct
= strdupAtoW( szProduct
);
1103 return ERROR_OUTOFMEMORY
;
1108 szwFeature
= strdupAtoW( szFeature
);
1111 HeapFree( GetProcessHeap(), 0, szwProduct
);
1112 return ERROR_OUTOFMEMORY
;
1116 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1118 HeapFree( GetProcessHeap(), 0, szwProduct
);
1119 HeapFree( GetProcessHeap(), 0, szwFeature
);
1124 /******************************************************************
1125 * MsiQueryFeatureStateW [MSI.@]
1127 * This does not verify that the Feature is functional. So i am only going to
1128 * check the existence of the key in the registry. This should tell me if it is
1131 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1137 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1139 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1140 if (rc
!= ERROR_SUCCESS
)
1141 return INSTALLSTATE_UNKNOWN
;
1143 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1146 if (rc
== ERROR_SUCCESS
)
1147 return INSTALLSTATE_LOCAL
;
1149 return INSTALLSTATE_ABSENT
;
1152 /******************************************************************
1153 * MsiGetFileVersionA [MSI.@]
1155 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1156 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1158 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1159 UINT ret
= ERROR_OUTOFMEMORY
;
1163 szwFilePath
= strdupAtoW( szFilePath
);
1168 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1170 lpwVersionBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1171 if( !lpwVersionBuff
)
1175 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1177 lpwLangBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1182 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1183 lpwLangBuff
, pcchLangBuf
);
1185 if( lpwVersionBuff
)
1186 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1187 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1189 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1190 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1193 HeapFree(GetProcessHeap(), 0, szwFilePath
);
1194 HeapFree(GetProcessHeap(), 0, lpwVersionBuff
);
1195 HeapFree(GetProcessHeap(), 0, lpwLangBuff
);
1200 /******************************************************************
1201 * MsiGetFileVersionW [MSI.@]
1203 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1204 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1206 static const WCHAR szVersionResource
[] = {'\\',0};
1207 static const WCHAR szVersionFormat
[] = {
1208 '%','d','.','%','d','.','%','d','.','%','d',0};
1209 static const WCHAR szLangFormat
[] = {'%','d',0};
1212 LPVOID lpVer
= NULL
;
1213 VS_FIXEDFILEINFO
*ffi
;
1217 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1218 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1219 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1221 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1223 return GetLastError();
1225 lpVer
= HeapAlloc(GetProcessHeap(), 0, dwVerLen
);
1228 ret
= ERROR_OUTOFMEMORY
;
1232 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1234 ret
= GetLastError();
1237 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1239 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1242 wsprintfW(tmp
, szVersionFormat
,
1243 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1244 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1245 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1246 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1251 *pcchVersionBuf
= 0;
1255 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1257 DWORD lang
= GetUserDefaultLangID();
1259 FIXME("Retrieve language from file\n");
1260 wsprintfW(tmp
, szLangFormat
, lang
);
1261 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1262 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1266 HeapFree(GetProcessHeap(), 0, lpVer
);
1271 /******************************************************************
1274 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1278 case DLL_PROCESS_ATTACH
:
1279 msi_hInstance
= hinstDLL
;
1280 DisableThreadLibraryCalls(hinstDLL
);
1281 msi_dialog_register_class();
1283 case DLL_PROCESS_DETACH
:
1284 msi_dialog_unregister_class();
1285 /* FIXME: Cleanup */
1291 typedef struct tagIClassFactoryImpl
1293 const IClassFactoryVtbl
*lpVtbl
;
1294 } IClassFactoryImpl
;
1296 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1297 REFIID riid
,LPVOID
*ppobj
)
1299 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1300 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1301 return E_NOINTERFACE
;
1304 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1309 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1314 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1315 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1317 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1319 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1323 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1325 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1327 FIXME("%p %d\n", This
, dolock
);
1331 static const IClassFactoryVtbl MsiCF_Vtbl
=
1333 MsiCF_QueryInterface
,
1336 MsiCF_CreateInstance
,
1340 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1342 /******************************************************************
1343 * DllGetClassObject [MSI.@]
1345 HRESULT WINAPI
DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1347 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1349 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1350 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1351 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1352 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1353 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1355 *ppv
= (LPVOID
) &Msi_CF
;
1358 return CLASS_E_CLASSNOTAVAILABLE
;
1361 /******************************************************************
1362 * DllGetVersion [MSI.@]
1364 HRESULT WINAPI
DllGetVersion(DLLVERSIONINFO
*pdvi
)
1368 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1369 return E_INVALIDARG
;
1371 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1372 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1373 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1374 pdvi
->dwPlatformID
= 1;
1379 /******************************************************************
1380 * DllCanUnloadNow [MSI.@]
1382 HRESULT WINAPI
DllCanUnloadNow(void)
1387 UINT WINAPI
MsiGetFeatureUsageW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1388 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1390 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1391 pdwUseCount
, pwDateUsed
);
1392 return ERROR_CALL_NOT_IMPLEMENTED
;
1395 UINT WINAPI
MsiGetFeatureUsageA(LPCSTR szProduct
, LPCSTR szFeature
,
1396 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1398 FIXME("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1399 pdwUseCount
, pwDateUsed
);
1400 return ERROR_CALL_NOT_IMPLEMENTED
;
1403 INSTALLSTATE WINAPI
MsiUseFeatureExW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1404 DWORD dwInstallMode
, DWORD dwReserved
)
1406 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1407 dwInstallMode
, dwReserved
);
1410 * Polls all the components of the feature to find install state and then
1412 * Software\\Microsoft\\Windows\\CurrentVersion\\
1413 * Installer\\Products\\<squishguid>\\<feature>
1414 * "Usage"=dword:........
1417 return INSTALLSTATE_LOCAL
;
1420 /***********************************************************************
1421 * MsiUseFeatureExA [MSI.@]
1423 INSTALLSTATE WINAPI
MsiUseFeatureExA(LPCSTR szProduct
, LPCSTR szFeature
,
1424 DWORD dwInstallMode
, DWORD dwReserved
)
1426 FIXME("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1427 dwInstallMode
, dwReserved
);
1429 return INSTALLSTATE_LOCAL
;
1432 INSTALLSTATE WINAPI
MsiUseFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1434 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1436 return INSTALLSTATE_LOCAL
;
1439 INSTALLSTATE WINAPI
MsiUseFeatureA(LPCSTR szProduct
, LPCSTR szFeature
)
1441 FIXME("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
));
1443 return INSTALLSTATE_LOCAL
;
1446 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1447 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1448 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1455 LPWSTR product
= NULL
;
1456 LPWSTR component
= NULL
;
1460 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1461 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1462 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1464 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1465 if (rc
!= ERROR_SUCCESS
)
1466 return ERROR_INDEX_ABSENT
;
1469 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1473 return ERROR_INDEX_ABSENT
;
1476 info
= HeapAlloc(GetProcessHeap(),0,sz
);
1477 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1478 if (rc
!= ERROR_SUCCESS
)
1481 HeapFree(GetProcessHeap(),0,info
);
1482 return ERROR_INDEX_ABSENT
;
1485 /* find the component */
1486 ptr
= strchrW(&info
[20],'>');
1492 HeapFree(GetProcessHeap(),0,info
);
1493 return ERROR_INDEX_ABSENT
;
1498 decode_base85_guid(info
,&clsid
);
1499 StringFromCLSID(&clsid
, &product
);
1501 decode_base85_guid(ptr
,&clsid
);
1502 StringFromCLSID(&clsid
, &component
);
1505 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1507 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1510 HeapFree(GetProcessHeap(),0,info
);
1511 HeapFree(GetProcessHeap(),0,product
);
1512 HeapFree(GetProcessHeap(),0,component
);
1514 if (rc
== INSTALLSTATE_LOCAL
)
1515 return ERROR_SUCCESS
;
1517 return ERROR_FILE_NOT_FOUND
;
1520 /***********************************************************************
1521 * MsiProvideQualifiedComponentW [MSI.@]
1523 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1524 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1527 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1528 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1531 /***********************************************************************
1532 * MsiProvideQualifiedComponentA [MSI.@]
1534 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1535 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1538 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1542 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1543 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1545 szwComponent
= strdupAtoW( szComponent
);
1546 szwQualifier
= strdupAtoW( szQualifier
);
1548 lpwPathBuf
= HeapAlloc(GetProcessHeap(),0,*pcchPathBuf
* sizeof(WCHAR
));
1550 pcchwPathBuf
= *pcchPathBuf
;
1552 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1553 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1555 HeapFree(GetProcessHeap(),0,szwComponent
);
1556 HeapFree(GetProcessHeap(),0,szwQualifier
);
1557 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1558 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1560 HeapFree(GetProcessHeap(),0,lpwPathBuf
);
1564 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1565 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1566 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1570 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1572 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1573 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1576 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1577 if (rc
!= ERROR_SUCCESS
)
1578 return USERINFOSTATE_UNKNOWN
;
1582 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1583 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1584 NULL
, (LPBYTE
)lpUserNameBuf
,
1587 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1590 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGOWNERW
, NULL
,
1594 if (pcchUserNameBuf
)
1595 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1599 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1600 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1601 NULL
, (LPBYTE
)lpOrgNameBuf
, &sz
);
1603 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1606 rc2
= RegQueryValueExW( hkey
, INSTALLPROPERTY_REGCOMPANYW
, NULL
,
1611 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1613 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1614 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1617 return USERINFOSTATE_ABSENT
;
1622 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1623 RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
, NULL
,
1624 (LPBYTE
)lpSerialBuf
, &sz
);
1626 if (!lpSerialBuf
&& pcchSerialBuf
)
1629 rc
= RegQueryValueExW( hkey
, INSTALLPROPERTY_PRODUCTIDW
, NULL
,
1633 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1636 return USERINFOSTATE_PRESENT
;
1639 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1640 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1641 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1643 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1644 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1647 return USERINFOSTATE_UNKNOWN
;
1650 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1654 MSIPACKAGE
*package
;
1655 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1657 TRACE("(%s)\n",debugstr_w(szProduct
));
1659 rc
= MsiOpenProductW(szProduct
,&handle
);
1660 if (rc
!= ERROR_SUCCESS
)
1661 return ERROR_INVALID_PARAMETER
;
1663 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1664 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1665 msiobj_release( &package
->hdr
);
1667 MsiCloseHandle(handle
);
1672 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1676 MSIPACKAGE
*package
;
1677 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1679 TRACE("(%s)\n",debugstr_a(szProduct
));
1681 rc
= MsiOpenProductA(szProduct
,&handle
);
1682 if (rc
!= ERROR_SUCCESS
)
1683 return ERROR_INVALID_PARAMETER
;
1685 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1686 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1687 msiobj_release( &package
->hdr
);
1689 MsiCloseHandle(handle
);
1694 UINT WINAPI
MsiConfigureFeatureW(LPWSTR szProduct
, LPWSTR szFeature
, INSTALLSTATE eInstallState
)
1696 FIXME("%s %s %i\n", debugstr_w(szProduct
), debugstr_w(szFeature
), eInstallState
);
1697 return ERROR_SUCCESS
;
1702 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1704 WCHAR path
[MAX_PATH
];
1707 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1708 return ERROR_CALL_NOT_IMPLEMENTED
;
1711 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1712 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1714 return ERROR_CALL_NOT_IMPLEMENTED
;
1717 strcatW(path
, installerW
);
1719 CreateDirectoryW(path
, NULL
);
1724 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1725 LPSTR szProductCode
, LPSTR szFeatureId
,
1726 LPSTR szComponentCode
)
1729 return ERROR_CALL_NOT_IMPLEMENTED
;
1732 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1733 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1734 LPWSTR szComponentCode
)
1737 return ERROR_CALL_NOT_IMPLEMENTED
;
1740 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1741 DWORD dwReinstallMode
)
1743 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1745 return ERROR_SUCCESS
;
1748 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1749 DWORD dwReinstallMode
)
1751 FIXME("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1753 return ERROR_SUCCESS
;