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"
40 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
43 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
44 * which is a problem because LPCTSTR isn't defined when compiling wine.
45 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
46 * and make sure to only use it in W functions.
48 #define LPCTSTR LPCWSTR
51 INSTALLUILEVEL gUILevel
= INSTALLUILEVEL_BASIC
;
53 INSTALLUI_HANDLERA gUIHandlerA
= NULL
;
54 INSTALLUI_HANDLERW gUIHandlerW
= NULL
;
56 LPVOID gUIContext
= NULL
;
57 WCHAR gszLogFile
[MAX_PATH
];
58 HINSTANCE msi_hInstance
;
60 static const WCHAR installerW
[] = {'\\','I','n','s','t','a','l','l','e','r',0};
62 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
65 LPWSTR szwProd
= NULL
;
67 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
71 szwProd
= strdupAtoW( szProduct
);
73 return ERROR_OUTOFMEMORY
;
76 r
= MsiOpenProductW( szwProd
, phProduct
);
78 HeapFree( GetProcessHeap(), 0, szwProd
);
83 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
85 static const WCHAR szLocalPackage
[] = {
86 'L','o','c','a','l','P','a','c','k','a','g','e', 0
90 HKEY hKeyProduct
= NULL
;
93 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
95 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
96 if( r
!= ERROR_SUCCESS
)
98 r
= ERROR_UNKNOWN_PRODUCT
;
102 /* find the size of the path */
104 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
105 NULL
, &type
, NULL
, &count
);
106 if( r
!= ERROR_SUCCESS
)
108 r
= ERROR_UNKNOWN_PRODUCT
;
112 /* now alloc and fetch the path of the database to open */
113 path
= HeapAlloc( GetProcessHeap(), 0, count
);
117 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
118 NULL
, &type
, (LPBYTE
) path
, &count
);
119 if( r
!= ERROR_SUCCESS
)
121 r
= ERROR_UNKNOWN_PRODUCT
;
125 r
= MsiOpenPackageW( path
, phProduct
);
128 HeapFree( GetProcessHeap(), 0, path
);
130 RegCloseKey( hKeyProduct
);
135 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
136 LPCSTR szTransforms
, LANGID lgidLanguage
)
138 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
139 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
140 return ERROR_CALL_NOT_IMPLEMENTED
;
143 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
144 LPCWSTR szTransforms
, LANGID lgidLanguage
)
146 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
147 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
148 return ERROR_CALL_NOT_IMPLEMENTED
;
151 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
152 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
154 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
155 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
156 lgidLanguage
, dwPlatform
, dwOptions
);
157 return ERROR_CALL_NOT_IMPLEMENTED
;
160 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
161 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
163 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
164 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
165 lgidLanguage
, dwPlatform
, dwOptions
);
166 return ERROR_CALL_NOT_IMPLEMENTED
;
169 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
171 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
172 UINT r
= ERROR_OUTOFMEMORY
;
174 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
178 szwPath
= strdupAtoW( szPackagePath
);
185 szwCommand
= strdupAtoW( szCommandLine
);
190 r
= MsiInstallProductW( szwPath
, szwCommand
);
193 HeapFree( GetProcessHeap(), 0, szwPath
);
194 HeapFree( GetProcessHeap(), 0, szwCommand
);
199 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
201 MSIPACKAGE
*package
= NULL
;
205 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
207 r
= MsiVerifyPackageW(szPackagePath
);
208 if (r
!= ERROR_SUCCESS
)
211 r
= MSI_OpenPackageW(szPackagePath
,&package
);
212 if (r
!= ERROR_SUCCESS
)
215 handle
= alloc_msihandle( &package
->hdr
);
217 r
= ACTION_DoTopLevelINSTALL(package
, szPackagePath
, szCommandLine
);
219 MsiCloseHandle(handle
);
220 msiobj_release( &package
->hdr
);
224 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
226 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
227 return ERROR_CALL_NOT_IMPLEMENTED
;
230 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
232 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
233 return ERROR_CALL_NOT_IMPLEMENTED
;
236 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
237 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
239 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
240 eInstallType
, debugstr_a(szCommandLine
));
241 return ERROR_CALL_NOT_IMPLEMENTED
;
244 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
245 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
247 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
248 eInstallType
, debugstr_w(szCommandLine
));
249 return ERROR_CALL_NOT_IMPLEMENTED
;
252 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
253 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
260 static const WCHAR szSouceList
[] = {
261 'S','o','u','r','c','e','L','i','s','t',0};
262 static const WCHAR szLUS
[] = {
263 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
264 WCHAR sourcepath
[0x200];
265 static const WCHAR szInstalled
[] = {
266 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
269 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
270 debugstr_w(szCommandLine
));
272 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
273 eInstallState
!= INSTALLSTATE_DEFAULT
)
275 FIXME("Not implemented for anything other than local installs\n");
276 return ERROR_CALL_NOT_IMPLEMENTED
;
279 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
280 if (rc
!= ERROR_SUCCESS
)
283 rc
= RegOpenKeyW(hkey
,szSouceList
,&hkey1
);
284 if (rc
!= ERROR_SUCCESS
)
287 sz
= sizeof(sourcepath
);
288 rc
= RegQueryValueExW(hkey1
, szLUS
, NULL
, NULL
,(LPBYTE
)sourcepath
, &sz
);
289 if (rc
!= ERROR_SUCCESS
)
294 * ok 1, we need to find the msi file for this product.
295 * 2, find the source dir for the files
296 * 3, do the configure/install.
297 * 4, cleanupany runonce entry.
300 rc
= MsiOpenProductW(szProduct
,&handle
);
301 if (rc
!= ERROR_SUCCESS
)
304 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
307 rc
= ERROR_INVALID_HANDLE
;
311 sz
= lstrlenW(szInstalled
);
314 sz
+= lstrlenW(szCommandLine
);
316 commandline
= HeapAlloc(GetProcessHeap(),0,sz
* sizeof(WCHAR
));
319 lstrcpyW(commandline
,szCommandLine
);
323 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
324 lstrcatW(commandline
,szInstalled
);
326 rc
= ACTION_DoTopLevelINSTALL(package
, sourcepath
, commandline
);
328 msiobj_release( &package
->hdr
);
330 HeapFree(GetProcessHeap(),0,commandline
);
337 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
338 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
340 LPWSTR szwProduct
= NULL
;
341 LPWSTR szwCommandLine
= NULL
;
342 UINT r
= ERROR_OUTOFMEMORY
;
346 szwProduct
= strdupAtoW( szProduct
);
353 szwCommandLine
= strdupAtoW( szCommandLine
);
358 r
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
361 HeapFree( GetProcessHeap(), 0, szwProduct
);
362 HeapFree( GetProcessHeap(), 0, szwCommandLine
);
367 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
368 INSTALLSTATE eInstallState
)
370 LPWSTR szwProduct
= NULL
;
373 TRACE("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
377 szwProduct
= strdupAtoW( szProduct
);
379 return ERROR_OUTOFMEMORY
;
382 r
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
383 HeapFree( GetProcessHeap(), 0, szwProduct
);
388 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
389 INSTALLSTATE eInstallState
)
391 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
393 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
, NULL
);
396 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
398 LPWSTR szwComponent
= NULL
;
400 WCHAR szwBuffer
[GUID_SIZE
];
402 TRACE("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
406 szwComponent
= strdupAtoW( szComponent
);
408 return ERROR_OUTOFMEMORY
;
411 r
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
413 if( ERROR_SUCCESS
== r
)
414 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
416 HeapFree( GetProcessHeap(), 0, szwComponent
);
421 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
423 FIXME("%s %p\n",debugstr_w(szComponent
), szBuffer
);
425 if (NULL
== szComponent
)
426 return ERROR_INVALID_PARAMETER
;
427 return ERROR_CALL_NOT_IMPLEMENTED
;
430 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
431 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
433 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
434 UINT r
= ERROR_OUTOFMEMORY
;
436 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szAttribute
),
437 szBuffer
, pcchValueBuf
);
441 szwProduct
= strdupAtoW( szProduct
);
448 szwAttribute
= strdupAtoW( szAttribute
);
455 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf
) * sizeof(WCHAR
) );
460 r
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
, pcchValueBuf
);
462 if( ERROR_SUCCESS
== r
)
463 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, *pcchValueBuf
, NULL
, NULL
);
466 HeapFree( GetProcessHeap(), 0, szwProduct
);
467 HeapFree( GetProcessHeap(), 0, szwAttribute
);
468 HeapFree( GetProcessHeap(), 0, szwBuffer
);
473 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
474 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
478 static const WCHAR szPackageCode
[] =
479 {'P','a','c','k','a','g','e','C','o','d','e',0};
480 static const WCHAR szVersionString
[] =
481 {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
482 static const WCHAR szProductVersion
[] =
483 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
484 static const WCHAR szAssignmentType
[] =
485 {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
487 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
488 szBuffer
, pcchValueBuf
);
490 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
491 return ERROR_INVALID_PARAMETER
;
492 if (NULL
== szProduct
|| NULL
== szAttribute
)
493 return ERROR_INVALID_PARAMETER
;
495 /* check for special properties */
496 if (strcmpW(szAttribute
, szPackageCode
)==0)
499 WCHAR squished
[GUID_SIZE
];
501 DWORD sz
= sizeof(squished
);
503 r
= MSIREG_OpenUserProductsKey(szProduct
, &hkey
, FALSE
);
504 if (r
!= ERROR_SUCCESS
)
505 return ERROR_UNKNOWN_PRODUCT
;
507 r
= RegQueryValueExW(hkey
, szPackageCode
, NULL
, NULL
,
508 (LPBYTE
)squished
, &sz
);
509 if (r
!= ERROR_SUCCESS
)
512 return ERROR_UNKNOWN_PRODUCT
;
515 unsquash_guid(squished
, package
);
516 *pcchValueBuf
= strlenW(package
);
517 if (strlenW(package
) > *pcchValueBuf
)
520 return ERROR_MORE_DATA
;
523 strcpyW(szBuffer
, package
);
528 else if (strcmpW(szAttribute
, szVersionString
)==0)
530 r
= MsiOpenProductW(szProduct
, &hProduct
);
531 if (ERROR_SUCCESS
!= r
)
534 r
= MsiGetPropertyW(hProduct
, szProductVersion
, szBuffer
, pcchValueBuf
);
535 MsiCloseHandle(hProduct
);
537 else if (strcmpW(szAttribute
, szAssignmentType
)==0)
539 FIXME("0 (zero) if advertised, 1(one) if per machine.\n");
546 r
= MsiOpenProductW(szProduct
, &hProduct
);
547 if (ERROR_SUCCESS
!= r
)
550 r
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
551 MsiCloseHandle(hProduct
);
557 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
559 LPWSTR szwLogFile
= NULL
;
562 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
566 szwLogFile
= strdupAtoW( szLogFile
);
568 return ERROR_OUTOFMEMORY
;
570 r
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
571 HeapFree( GetProcessHeap(), 0, szwLogFile
);
575 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
577 HANDLE file
= INVALID_HANDLE_VALUE
;
579 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
581 lstrcpyW(gszLogFile
,szLogFile
);
582 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
583 DeleteFileW(szLogFile
);
584 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
585 FILE_ATTRIBUTE_NORMAL
, NULL
);
586 if (file
!= INVALID_HANDLE_VALUE
)
589 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
591 return ERROR_SUCCESS
;
594 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
596 LPWSTR szwProduct
= NULL
;
601 szwProduct
= strdupAtoW( szProduct
);
603 return ERROR_OUTOFMEMORY
;
605 r
= MsiQueryProductStateW( szwProduct
);
606 HeapFree( GetProcessHeap(), 0, szwProduct
);
610 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
613 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
615 static const WCHAR szWindowsInstaller
[] = {
616 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
619 TRACE("%s\n", debugstr_w(szProduct
));
621 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
622 if (rc
!= ERROR_SUCCESS
)
627 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
628 if (rc
!= ERROR_SUCCESS
)
632 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
633 if (rc
!= ERROR_SUCCESS
)
640 rrc
= INSTALLSTATE_DEFAULT
;
643 FIXME("Unknown install state read from registry (%i)\n",rrc
);
644 rrc
= INSTALLSTATE_UNKNOWN
;
652 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
654 INSTALLUILEVEL old
= gUILevel
;
655 HWND oldwnd
= gUIhwnd
;
657 TRACE("%08x %p\n", dwUILevel
, phWnd
);
659 gUILevel
= dwUILevel
;
668 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
669 DWORD dwMessageFilter
, LPVOID pvContext
)
671 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
673 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
674 gUIHandlerA
= puiHandler
;
675 gUIFilter
= dwMessageFilter
;
676 gUIContext
= pvContext
;
681 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
682 DWORD dwMessageFilter
, LPVOID pvContext
)
684 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
686 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
687 gUIHandlerW
= puiHandler
;
688 gUIFilter
= dwMessageFilter
;
689 gUIContext
= pvContext
;
694 /******************************************************************
695 * MsiLoadStringW [MSI.@]
697 * Loads a string from MSI's string resources.
701 * handle [I] only -1 is handled currently
702 * id [I] id of the string to be loaded
703 * lpBuffer [O] buffer for the string to be written to
704 * nBufferMax [I] maximum size of the buffer in characters
705 * lang [I] the preferred language for the string
709 * If successful, this function returns the language id of the string loaded
710 * If the function fails, the function returns zero.
714 * The type of the first parameter is unknown. LoadString's prototype
715 * suggests that it might be a module handle. I have made it an MSI handle
716 * for starters, as -1 is an invalid MSI handle, but not an invalid module
717 * handle. Maybe strings can be stored in an MSI database somehow.
719 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
720 int nBufferMax
, LANGID lang
)
727 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
730 FIXME("don't know how to deal with handle = %08lx\n", handle
);
733 lang
= GetUserDefaultLangID();
735 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
739 hResData
= LoadResource( msi_hInstance
, hres
);
742 p
= LockResource( hResData
);
746 for (i
= 0; i
< (id
&0xf); i
++)
750 if( nBufferMax
<= len
)
753 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
756 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
761 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
762 int nBufferMax
, LANGID lang
)
768 bufW
= HeapAlloc(GetProcessHeap(), 0, nBufferMax
*sizeof(WCHAR
));
769 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
772 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
773 if( len
<= nBufferMax
)
774 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
775 lpBuffer
, nBufferMax
, NULL
, NULL
);
779 HeapFree(GetProcessHeap(), 0, bufW
);
783 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
786 FIXME("%s %p %08lx\n", debugstr_a(szComponent
), lpPathBuf
, *pcchBuf
);
787 return INSTALLSTATE_UNKNOWN
;
790 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPSTR lpPathBuf
,
793 FIXME("%s %p %08lx\n", debugstr_w(szComponent
), lpPathBuf
, *pcchBuf
);
794 return INSTALLSTATE_UNKNOWN
;
797 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
798 WORD wLanguageId
, DWORD f
)
800 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
801 uType
,wLanguageId
,f
);
802 return ERROR_CALL_NOT_IMPLEMENTED
;
805 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
806 WORD wLanguageId
, DWORD f
)
808 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
809 uType
,wLanguageId
,f
);
810 return ERROR_CALL_NOT_IMPLEMENTED
;
813 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
814 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
817 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
818 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
820 return ERROR_CALL_NOT_IMPLEMENTED
;
823 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
824 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
827 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
828 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
830 return ERROR_CALL_NOT_IMPLEMENTED
;
833 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
834 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
836 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
837 return ERROR_CALL_NOT_IMPLEMENTED
;
840 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
841 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
843 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
844 return ERROR_CALL_NOT_IMPLEMENTED
;
847 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
848 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
851 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
852 ppcCertContext
, pbHashData
, pcbHashData
);
853 return ERROR_CALL_NOT_IMPLEMENTED
;
856 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
857 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
860 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
861 ppcCertContext
, pbHashData
, pcbHashData
);
862 return ERROR_CALL_NOT_IMPLEMENTED
;
865 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
866 LPSTR szValue
, DWORD
*pccbValue
)
868 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
869 return ERROR_CALL_NOT_IMPLEMENTED
;
872 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
873 LPWSTR szValue
, DWORD
*pccbValue
)
875 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
876 return ERROR_CALL_NOT_IMPLEMENTED
;
879 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
882 LPWSTR szPack
= NULL
;
884 TRACE("%s\n", debugstr_a(szPackage
) );
888 szPack
= strdupAtoW( szPackage
);
890 return ERROR_OUTOFMEMORY
;
893 r
= MsiVerifyPackageW( szPack
);
895 HeapFree( GetProcessHeap(), 0, szPack
);
900 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
905 TRACE("%s\n", debugstr_w(szPackage
) );
907 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
908 MsiCloseHandle( handle
);
913 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
914 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
916 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
922 szwProduct
= strdupAtoW( szProduct
);
924 return ERROR_OUTOFMEMORY
;
929 szwComponent
= strdupAtoW( szComponent
);
932 HeapFree( GetProcessHeap(), 0, szwProduct
);
933 return ERROR_OUTOFMEMORY
;
937 if( pcchBuf
&& *pcchBuf
> 0 )
938 lpwPathBuf
= HeapAlloc( GetProcessHeap(), 0, *pcchBuf
* sizeof(WCHAR
));
942 incoming_len
= *pcchBuf
;
943 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
945 HeapFree( GetProcessHeap(), 0, szwProduct
);
946 HeapFree( GetProcessHeap(), 0, szwComponent
);
949 if (rc
!= INSTALLSTATE_UNKNOWN
)
950 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
951 lpPathBuf
, incoming_len
, NULL
, NULL
);
952 HeapFree( GetProcessHeap(), 0, lpwPathBuf
);
958 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
959 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
961 WCHAR squished_pc
[GUID_SIZE
];
963 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
968 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
969 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
971 if( lpPathBuf
&& !pcchBuf
)
972 return INSTALLSTATE_INVALIDARG
;
974 squash_guid(szProduct
,squished_pc
);
976 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
977 if( rc
!= ERROR_SUCCESS
)
982 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
983 if( rc
!= ERROR_SUCCESS
)
988 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
989 if( rc
!= ERROR_SUCCESS
)
995 path
= HeapAlloc( GetProcessHeap(), 0, sz
);
999 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1000 if( rc
!= ERROR_SUCCESS
)
1003 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1004 debugstr_w(szProduct
), debugstr_w(path
));
1008 FIXME("Registry entry.. check entry\n");
1009 rrc
= INSTALLSTATE_LOCAL
;
1013 /* PROBABLY a file */
1014 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1015 rrc
= INSTALLSTATE_LOCAL
;
1017 rrc
= INSTALLSTATE_ABSENT
;
1022 sz
= sz
/ sizeof(WCHAR
);
1023 if( *pcchBuf
>= sz
)
1024 lstrcpyW( lpPathBuf
, path
);
1029 HeapFree(GetProcessHeap(), 0, path
);
1034 /******************************************************************
1035 * MsiQueryFeatureStateA [MSI.@]
1037 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1040 LPWSTR szwProduct
= NULL
;
1041 LPWSTR szwFeature
= NULL
;
1045 szwProduct
= strdupAtoW( szProduct
);
1047 return ERROR_OUTOFMEMORY
;
1052 szwFeature
= strdupAtoW( szFeature
);
1055 HeapFree( GetProcessHeap(), 0, szwProduct
);
1056 return ERROR_OUTOFMEMORY
;
1060 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1062 HeapFree( GetProcessHeap(), 0, szwProduct
);
1063 HeapFree( GetProcessHeap(), 0, szwFeature
);
1068 /******************************************************************
1069 * MsiQueryFeatureStateW [MSI.@]
1071 * This does not verify that the Feature is functional. So i am only going to
1072 * check the existence of the key in the registry. This should tell me if it is
1075 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1081 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1083 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1084 if (rc
!= ERROR_SUCCESS
)
1085 return INSTALLSTATE_UNKNOWN
;
1087 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1090 if (rc
== ERROR_SUCCESS
)
1091 return INSTALLSTATE_LOCAL
;
1093 return INSTALLSTATE_ABSENT
;
1096 /******************************************************************
1097 * MsiGetFileVersionA [MSI.@]
1099 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1100 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1102 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1103 UINT ret
= ERROR_OUTOFMEMORY
;
1107 szwFilePath
= strdupAtoW( szFilePath
);
1112 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1114 lpwVersionBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1115 if( !lpwVersionBuff
)
1119 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1121 lpwLangBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1126 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1127 lpwLangBuff
, pcchLangBuf
);
1129 if( lpwVersionBuff
)
1130 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1131 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1133 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1134 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1137 HeapFree(GetProcessHeap(), 0, szwFilePath
);
1138 HeapFree(GetProcessHeap(), 0, lpwVersionBuff
);
1139 HeapFree(GetProcessHeap(), 0, lpwLangBuff
);
1144 /******************************************************************
1145 * MsiGetFileVersionW [MSI.@]
1147 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1148 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1150 static const WCHAR szVersionResource
[] = {'\\',0};
1151 static const WCHAR szVersionFormat
[] = {
1152 '%','d','.','%','d','.','%','d','.','%','d',0};
1153 static const WCHAR szLangFormat
[] = {'%','d',0};
1156 LPVOID lpVer
= NULL
;
1157 VS_FIXEDFILEINFO
*ffi
;
1161 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1162 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1163 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1165 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1167 return GetLastError();
1169 lpVer
= HeapAlloc(GetProcessHeap(), 0, dwVerLen
);
1172 ret
= ERROR_OUTOFMEMORY
;
1176 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1178 ret
= GetLastError();
1181 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1183 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1186 wsprintfW(tmp
, szVersionFormat
,
1187 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1188 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1189 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1190 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1195 *pcchVersionBuf
= 0;
1199 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1201 DWORD lang
= GetUserDefaultLangID();
1203 FIXME("Retrieve language from file\n");
1204 wsprintfW(tmp
, szLangFormat
, lang
);
1205 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1206 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1210 HeapFree(GetProcessHeap(), 0, lpVer
);
1215 /******************************************************************
1218 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1222 case DLL_PROCESS_ATTACH
:
1223 msi_hInstance
= hinstDLL
;
1224 DisableThreadLibraryCalls(hinstDLL
);
1225 msi_dialog_register_class();
1227 case DLL_PROCESS_DETACH
:
1228 msi_dialog_unregister_class();
1229 /* FIXME: Cleanup */
1235 typedef struct tagIClassFactoryImpl
1237 IClassFactoryVtbl
*lpVtbl
;
1238 } IClassFactoryImpl
;
1240 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1241 REFIID riid
,LPVOID
*ppobj
)
1243 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1244 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1245 return E_NOINTERFACE
;
1248 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1253 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1258 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1259 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1261 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1263 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1267 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1269 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1271 FIXME("%p %d\n", This
, dolock
);
1275 static IClassFactoryVtbl MsiCF_Vtbl
=
1277 MsiCF_QueryInterface
,
1280 MsiCF_CreateInstance
,
1284 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1286 /******************************************************************
1287 * DllGetClassObject [MSI.@]
1289 HRESULT WINAPI
MSI_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1291 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1293 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1294 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1295 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1296 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1297 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1299 *ppv
= (LPVOID
) &Msi_CF
;
1302 return CLASS_E_CLASSNOTAVAILABLE
;
1305 /******************************************************************
1306 * DllGetVersion [MSI.@]
1308 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
1312 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1313 return E_INVALIDARG
;
1315 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1316 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1317 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1318 pdvi
->dwPlatformID
= 1;
1323 /******************************************************************
1324 * DllCanUnloadNow [MSI.@]
1326 BOOL WINAPI
MSI_DllCanUnloadNow(void)
1331 UINT WINAPI
MsiGetFeatureUsageW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1332 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1334 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1335 pdwUseCount
, pwDateUsed
);
1336 return ERROR_CALL_NOT_IMPLEMENTED
;
1339 UINT WINAPI
MsiGetFeatureUsageA(LPCSTR szProduct
, LPCSTR szFeature
,
1340 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1342 FIXME("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1343 pdwUseCount
, pwDateUsed
);
1344 return ERROR_CALL_NOT_IMPLEMENTED
;
1347 INSTALLSTATE WINAPI
MsiUseFeatureExW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1348 DWORD dwInstallMode
, DWORD dwReserved
)
1350 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1351 dwInstallMode
, dwReserved
);
1354 * Polls all the components of the feature to find install state and then
1356 * Software\\Microsoft\\Windows\\CurrentVersion\\
1357 * Installer\\Products\\<squishguid>\\<feature>
1358 * "Usage"=dword:........
1361 return INSTALLSTATE_LOCAL
;
1364 /***********************************************************************
1365 * MsiUseFeatureExA [MSI.@]
1367 INSTALLSTATE WINAPI
MsiUseFeatureExA(LPCSTR szProduct
, LPCSTR szFeature
,
1368 DWORD dwInstallMode
, DWORD dwReserved
)
1370 FIXME("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1371 dwInstallMode
, dwReserved
);
1373 return INSTALLSTATE_LOCAL
;
1376 INSTALLSTATE WINAPI
MsiUseFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1378 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1380 return INSTALLSTATE_LOCAL
;
1383 INSTALLSTATE WINAPI
MsiUseFeatureA(LPCSTR szProduct
, LPCSTR szFeature
)
1385 FIXME("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
));
1387 return INSTALLSTATE_LOCAL
;
1390 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1391 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1392 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1399 LPWSTR product
= NULL
;
1400 LPWSTR component
= NULL
;
1404 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1405 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1406 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1408 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1409 if (rc
!= ERROR_SUCCESS
)
1410 return ERROR_INDEX_ABSENT
;
1413 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1417 return ERROR_INDEX_ABSENT
;
1420 info
= HeapAlloc(GetProcessHeap(),0,sz
);
1421 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1422 if (rc
!= ERROR_SUCCESS
)
1425 HeapFree(GetProcessHeap(),0,info
);
1426 return ERROR_INDEX_ABSENT
;
1429 /* find the component */
1430 ptr
= strchrW(&info
[20],'>');
1436 HeapFree(GetProcessHeap(),0,info
);
1437 return ERROR_INDEX_ABSENT
;
1442 decode_base85_guid(info
,&clsid
);
1443 StringFromCLSID(&clsid
, &product
);
1445 decode_base85_guid(ptr
,&clsid
);
1446 StringFromCLSID(&clsid
, &component
);
1449 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1451 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1454 HeapFree(GetProcessHeap(),0,info
);
1455 HeapFree(GetProcessHeap(),0,product
);
1456 HeapFree(GetProcessHeap(),0,component
);
1458 if (rc
== INSTALLSTATE_LOCAL
)
1459 return ERROR_SUCCESS
;
1461 return ERROR_FILE_NOT_FOUND
;
1464 /***********************************************************************
1465 * MsiProvideQualifiedComponentW [MSI.@]
1467 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1468 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1471 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1472 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1475 /***********************************************************************
1476 * MsiProvideQualifiedComponentA [MSI.@]
1478 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1479 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1482 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1486 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1487 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1489 szwComponent
= strdupAtoW( szComponent
);
1490 szwQualifier
= strdupAtoW( szQualifier
);
1492 lpwPathBuf
= HeapAlloc(GetProcessHeap(),0,*pcchPathBuf
* sizeof(WCHAR
));
1494 pcchwPathBuf
= *pcchPathBuf
;
1496 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1497 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1499 HeapFree(GetProcessHeap(),0,szwComponent
);
1500 HeapFree(GetProcessHeap(),0,szwQualifier
);
1501 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1502 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1504 HeapFree(GetProcessHeap(),0,lpwPathBuf
);
1508 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1509 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1510 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1512 FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1513 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1516 return USERINFOSTATE_UNKNOWN
;
1519 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1520 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1521 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1523 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1524 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1527 return USERINFOSTATE_UNKNOWN
;
1530 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1532 FIXME("%s\n",debugstr_w(szProduct
));
1533 return ERROR_CALL_NOT_IMPLEMENTED
;
1536 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1538 FIXME("%s\n",debugstr_a(szProduct
));
1539 return ERROR_CALL_NOT_IMPLEMENTED
;
1542 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1544 WCHAR path
[MAX_PATH
];
1547 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1548 return ERROR_CALL_NOT_IMPLEMENTED
;
1551 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1552 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1554 return ERROR_CALL_NOT_IMPLEMENTED
;
1557 strcatW(path
, installerW
);
1559 CreateDirectoryW(path
, NULL
);
1564 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1565 LPSTR szProductCode
, LPSTR szFeatureId
,
1566 LPSTR szComponentCode
)
1569 return ERROR_CALL_NOT_IMPLEMENTED
;
1572 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1573 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1574 LPWSTR szComponentCode
)
1577 return ERROR_CALL_NOT_IMPLEMENTED
;
1580 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1581 DWORD dwReinstallMode
)
1583 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1585 return ERROR_SUCCESS
;
1588 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1589 DWORD dwReinstallMode
)
1591 FIXME("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1593 return ERROR_SUCCESS
;