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
)
86 static const WCHAR szLocalPackage
[] = {
87 'L','o','c','a','l','P','a','c','k','a','g','e', 0
91 HKEY hKeyProduct
= NULL
;
94 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
96 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
97 if( r
!= ERROR_SUCCESS
)
99 r
= ERROR_UNKNOWN_PRODUCT
;
103 /* find the size of the path */
105 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
106 NULL
, &type
, NULL
, &count
);
107 if( r
!= ERROR_SUCCESS
)
109 r
= ERROR_UNKNOWN_PRODUCT
;
113 /* now alloc and fetch the path of the database to open */
114 path
= HeapAlloc( GetProcessHeap(), 0, count
);
118 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
119 NULL
, &type
, (LPBYTE
) path
, &count
);
120 if( r
!= ERROR_SUCCESS
)
122 r
= ERROR_UNKNOWN_PRODUCT
;
126 r
= MsiOpenPackageW( path
, phProduct
);
129 HeapFree( GetProcessHeap(), 0, path
);
131 RegCloseKey( hKeyProduct
);
136 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
137 LPCSTR szTransforms
, LANGID lgidLanguage
)
139 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
140 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
141 return ERROR_CALL_NOT_IMPLEMENTED
;
144 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
145 LPCWSTR szTransforms
, LANGID lgidLanguage
)
147 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
148 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
149 return ERROR_CALL_NOT_IMPLEMENTED
;
152 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
153 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
155 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
156 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
157 lgidLanguage
, dwPlatform
, dwOptions
);
158 return ERROR_CALL_NOT_IMPLEMENTED
;
161 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
162 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
164 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
165 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
166 lgidLanguage
, dwPlatform
, dwOptions
);
167 return ERROR_CALL_NOT_IMPLEMENTED
;
170 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
172 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
173 UINT r
= ERROR_OUTOFMEMORY
;
175 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
179 szwPath
= strdupAtoW( szPackagePath
);
186 szwCommand
= strdupAtoW( szCommandLine
);
191 r
= MsiInstallProductW( szwPath
, szwCommand
);
194 HeapFree( GetProcessHeap(), 0, szwPath
);
195 HeapFree( GetProcessHeap(), 0, szwCommand
);
200 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
202 MSIPACKAGE
*package
= NULL
;
206 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
208 r
= MsiVerifyPackageW(szPackagePath
);
209 if (r
!= ERROR_SUCCESS
)
212 r
= MSI_OpenPackageW(szPackagePath
,&package
);
213 if (r
!= ERROR_SUCCESS
)
216 handle
= alloc_msihandle( &package
->hdr
);
218 r
= ACTION_DoTopLevelINSTALL(package
, szPackagePath
, szCommandLine
);
220 MsiCloseHandle(handle
);
221 msiobj_release( &package
->hdr
);
225 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
227 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
228 return ERROR_CALL_NOT_IMPLEMENTED
;
231 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
233 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
234 return ERROR_CALL_NOT_IMPLEMENTED
;
237 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
238 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
240 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
241 eInstallType
, debugstr_a(szCommandLine
));
242 return ERROR_CALL_NOT_IMPLEMENTED
;
245 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
246 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
248 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
249 eInstallType
, debugstr_w(szCommandLine
));
250 return ERROR_CALL_NOT_IMPLEMENTED
;
253 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
254 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
256 MSIHANDLE handle
= -1;
261 static const WCHAR szSouceList
[] = {
262 'S','o','u','r','c','e','L','i','s','t',0};
263 static const WCHAR szLUS
[] = {
264 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
265 WCHAR sourcepath
[0x200];
266 static const WCHAR szInstalled
[] = {
267 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
270 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
271 debugstr_w(szCommandLine
));
273 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
274 eInstallState
!= INSTALLSTATE_DEFAULT
)
276 FIXME("Not implemented for anything other than local installs\n");
277 return ERROR_CALL_NOT_IMPLEMENTED
;
280 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
281 if (rc
!= ERROR_SUCCESS
)
284 rc
= RegOpenKeyW(hkey
,szSouceList
,&hkey1
);
285 if (rc
!= ERROR_SUCCESS
)
288 sz
= sizeof(sourcepath
);
289 rc
= RegQueryValueExW(hkey1
, szLUS
, NULL
, NULL
,(LPBYTE
)sourcepath
, &sz
);
290 if (rc
!= ERROR_SUCCESS
)
295 * ok 1, we need to find the msi file for this product.
296 * 2, find the source dir for the files
297 * 3, do the configure/install.
298 * 4, cleanupany runonce entry.
301 rc
= MsiOpenProductW(szProduct
,&handle
);
302 if (rc
!= ERROR_SUCCESS
)
305 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
308 rc
= ERROR_INVALID_HANDLE
;
312 sz
= lstrlenW(szInstalled
);
315 sz
+= lstrlenW(szCommandLine
);
317 commandline
= HeapAlloc(GetProcessHeap(),0,sz
* sizeof(WCHAR
));
320 lstrcpyW(commandline
,szCommandLine
);
324 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
325 lstrcatW(commandline
,szInstalled
);
327 rc
= ACTION_DoTopLevelINSTALL(package
, sourcepath
, commandline
);
329 msiobj_release( &package
->hdr
);
331 HeapFree(GetProcessHeap(),0,commandline
);
335 MsiCloseHandle(handle
);
340 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
341 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
343 LPWSTR szwProduct
= NULL
;
344 LPWSTR szwCommandLine
= NULL
;
345 UINT r
= ERROR_OUTOFMEMORY
;
349 szwProduct
= strdupAtoW( szProduct
);
356 szwCommandLine
= strdupAtoW( szCommandLine
);
361 r
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
364 HeapFree( GetProcessHeap(), 0, szwProduct
);
365 HeapFree( GetProcessHeap(), 0, szwCommandLine
);
370 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
371 INSTALLSTATE eInstallState
)
373 LPWSTR szwProduct
= NULL
;
376 TRACE("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
380 szwProduct
= strdupAtoW( szProduct
);
382 return ERROR_OUTOFMEMORY
;
385 r
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
386 HeapFree( GetProcessHeap(), 0, szwProduct
);
391 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
392 INSTALLSTATE eInstallState
)
394 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
396 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
, NULL
);
399 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
401 LPWSTR szwComponent
= NULL
;
403 WCHAR szwBuffer
[GUID_SIZE
];
405 TRACE("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
409 szwComponent
= strdupAtoW( szComponent
);
411 return ERROR_OUTOFMEMORY
;
414 r
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
416 if( ERROR_SUCCESS
== r
)
417 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
419 HeapFree( GetProcessHeap(), 0, szwComponent
);
424 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
428 WCHAR szSquished
[GUID_SIZE
];
429 DWORD sz
= GUID_SIZE
;
430 static const WCHAR szPermKey
[] =
431 { '0','0','0','0','0','0','0','0','0','0','0','0',
432 '0','0','0','0','0','0','0', '0','0','0','0','0',
433 '0','0','0','0','0','0','0','0',0};
435 TRACE("%s %p\n",debugstr_w(szComponent
), szBuffer
);
437 if (NULL
== szComponent
)
438 return ERROR_INVALID_PARAMETER
;
440 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
441 if (rc
!= ERROR_SUCCESS
)
442 return ERROR_UNKNOWN_COMPONENT
;
444 rc
= RegEnumValueW(hkey
, 0, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
445 if (rc
== ERROR_SUCCESS
&& strcmpW(szSquished
,szPermKey
)==0)
448 rc
= RegEnumValueW(hkey
, 1, szSquished
, &sz
, NULL
, NULL
, NULL
, NULL
);
453 if (rc
!= ERROR_SUCCESS
)
454 return ERROR_INSTALL_FAILURE
;
456 unsquash_guid(szSquished
, szBuffer
);
457 return ERROR_SUCCESS
;
460 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
461 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
463 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
464 UINT r
= ERROR_OUTOFMEMORY
;
466 TRACE("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szAttribute
),
467 szBuffer
, pcchValueBuf
);
471 szwProduct
= strdupAtoW( szProduct
);
478 szwAttribute
= strdupAtoW( szAttribute
);
485 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf
) * sizeof(WCHAR
) );
490 r
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
, pcchValueBuf
);
492 if( ERROR_SUCCESS
== r
)
493 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, *pcchValueBuf
, NULL
, NULL
);
496 HeapFree( GetProcessHeap(), 0, szwProduct
);
497 HeapFree( GetProcessHeap(), 0, szwAttribute
);
498 HeapFree( GetProcessHeap(), 0, szwBuffer
);
503 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
504 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
508 static const WCHAR szPackageCode
[] =
509 {'P','a','c','k','a','g','e','C','o','d','e',0};
510 static const WCHAR szVersionString
[] =
511 {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
512 static const WCHAR szProductVersion
[] =
513 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
514 static const WCHAR szAssignmentType
[] =
515 {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
517 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
518 szBuffer
, pcchValueBuf
);
520 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
521 return ERROR_INVALID_PARAMETER
;
522 if (NULL
== szProduct
|| NULL
== szAttribute
)
523 return ERROR_INVALID_PARAMETER
;
525 /* check for special properties */
526 if (strcmpW(szAttribute
, szPackageCode
)==0)
529 WCHAR squished
[GUID_SIZE
];
531 DWORD sz
= sizeof(squished
);
533 r
= MSIREG_OpenUserProductsKey(szProduct
, &hkey
, FALSE
);
534 if (r
!= ERROR_SUCCESS
)
535 return ERROR_UNKNOWN_PRODUCT
;
537 r
= RegQueryValueExW(hkey
, szPackageCode
, NULL
, NULL
,
538 (LPBYTE
)squished
, &sz
);
539 if (r
!= ERROR_SUCCESS
)
542 return ERROR_UNKNOWN_PRODUCT
;
545 unsquash_guid(squished
, package
);
546 *pcchValueBuf
= strlenW(package
);
547 if (strlenW(package
) > *pcchValueBuf
)
550 return ERROR_MORE_DATA
;
553 strcpyW(szBuffer
, package
);
558 else if (strcmpW(szAttribute
, szVersionString
)==0)
560 r
= MsiOpenProductW(szProduct
, &hProduct
);
561 if (ERROR_SUCCESS
!= r
)
564 r
= MsiGetPropertyW(hProduct
, szProductVersion
, szBuffer
, pcchValueBuf
);
565 MsiCloseHandle(hProduct
);
567 else if (strcmpW(szAttribute
, szAssignmentType
)==0)
569 FIXME("0 (zero) if advertised, 1(one) if per machine.\n");
576 r
= MsiOpenProductW(szProduct
, &hProduct
);
577 if (ERROR_SUCCESS
!= r
)
580 r
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
581 MsiCloseHandle(hProduct
);
587 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
589 LPWSTR szwLogFile
= NULL
;
592 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
596 szwLogFile
= strdupAtoW( szLogFile
);
598 return ERROR_OUTOFMEMORY
;
600 r
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
601 HeapFree( GetProcessHeap(), 0, szwLogFile
);
605 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
607 HANDLE file
= INVALID_HANDLE_VALUE
;
609 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
611 lstrcpyW(gszLogFile
,szLogFile
);
612 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
613 DeleteFileW(szLogFile
);
614 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
615 FILE_ATTRIBUTE_NORMAL
, NULL
);
616 if (file
!= INVALID_HANDLE_VALUE
)
619 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
621 return ERROR_SUCCESS
;
624 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
626 LPWSTR szwProduct
= NULL
;
631 szwProduct
= strdupAtoW( szProduct
);
633 return ERROR_OUTOFMEMORY
;
635 r
= MsiQueryProductStateW( szwProduct
);
636 HeapFree( GetProcessHeap(), 0, szwProduct
);
640 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
643 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
645 static const WCHAR szWindowsInstaller
[] = {
646 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
649 TRACE("%s\n", debugstr_w(szProduct
));
651 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
652 if (rc
!= ERROR_SUCCESS
)
657 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
658 if (rc
!= ERROR_SUCCESS
)
662 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
663 if (rc
!= ERROR_SUCCESS
)
670 rrc
= INSTALLSTATE_DEFAULT
;
673 FIXME("Unknown install state read from registry (%i)\n",rrc
);
674 rrc
= INSTALLSTATE_UNKNOWN
;
682 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
684 INSTALLUILEVEL old
= gUILevel
;
685 HWND oldwnd
= gUIhwnd
;
687 TRACE("%08x %p\n", dwUILevel
, phWnd
);
689 gUILevel
= dwUILevel
;
698 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
699 DWORD dwMessageFilter
, LPVOID pvContext
)
701 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
703 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
704 gUIHandlerA
= puiHandler
;
705 gUIFilter
= dwMessageFilter
;
706 gUIContext
= pvContext
;
711 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
712 DWORD dwMessageFilter
, LPVOID pvContext
)
714 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
716 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
717 gUIHandlerW
= puiHandler
;
718 gUIFilter
= dwMessageFilter
;
719 gUIContext
= pvContext
;
724 /******************************************************************
725 * MsiLoadStringW [MSI.@]
727 * Loads a string from MSI's string resources.
731 * handle [I] only -1 is handled currently
732 * id [I] id of the string to be loaded
733 * lpBuffer [O] buffer for the string to be written to
734 * nBufferMax [I] maximum size of the buffer in characters
735 * lang [I] the preferred language for the string
739 * If successful, this function returns the language id of the string loaded
740 * If the function fails, the function returns zero.
744 * The type of the first parameter is unknown. LoadString's prototype
745 * suggests that it might be a module handle. I have made it an MSI handle
746 * for starters, as -1 is an invalid MSI handle, but not an invalid module
747 * handle. Maybe strings can be stored in an MSI database somehow.
749 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
750 int nBufferMax
, LANGID lang
)
757 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
760 FIXME("don't know how to deal with handle = %08lx\n", handle
);
763 lang
= GetUserDefaultLangID();
765 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
769 hResData
= LoadResource( msi_hInstance
, hres
);
772 p
= LockResource( hResData
);
776 for (i
= 0; i
< (id
&0xf); i
++)
780 if( nBufferMax
<= len
)
783 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
786 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
791 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
792 int nBufferMax
, LANGID lang
)
798 bufW
= HeapAlloc(GetProcessHeap(), 0, nBufferMax
*sizeof(WCHAR
));
799 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
802 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
803 if( len
<= nBufferMax
)
804 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
805 lpBuffer
, nBufferMax
, NULL
, NULL
);
809 HeapFree(GetProcessHeap(), 0, bufW
);
813 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
816 FIXME("%s %p %08lx\n", debugstr_a(szComponent
), lpPathBuf
, *pcchBuf
);
817 return INSTALLSTATE_UNKNOWN
;
820 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPWSTR lpPathBuf
,
823 FIXME("%s %p %08lx\n", debugstr_w(szComponent
), lpPathBuf
, *pcchBuf
);
824 return INSTALLSTATE_UNKNOWN
;
827 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
828 WORD wLanguageId
, DWORD f
)
830 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
831 uType
,wLanguageId
,f
);
832 return ERROR_CALL_NOT_IMPLEMENTED
;
835 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
836 WORD wLanguageId
, DWORD f
)
838 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
839 uType
,wLanguageId
,f
);
840 return ERROR_CALL_NOT_IMPLEMENTED
;
843 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
844 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
847 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
848 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
850 return ERROR_CALL_NOT_IMPLEMENTED
;
853 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
854 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
857 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
858 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
860 return ERROR_CALL_NOT_IMPLEMENTED
;
863 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
864 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
866 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
867 return ERROR_CALL_NOT_IMPLEMENTED
;
870 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
871 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
873 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
874 return ERROR_CALL_NOT_IMPLEMENTED
;
877 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
878 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
881 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
882 ppcCertContext
, pbHashData
, pcbHashData
);
883 return ERROR_CALL_NOT_IMPLEMENTED
;
886 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
887 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
890 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
891 ppcCertContext
, pbHashData
, pcbHashData
);
892 return ERROR_CALL_NOT_IMPLEMENTED
;
895 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
896 LPSTR szValue
, DWORD
*pccbValue
)
898 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
899 return ERROR_CALL_NOT_IMPLEMENTED
;
902 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
903 LPWSTR szValue
, DWORD
*pccbValue
)
905 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
906 return ERROR_CALL_NOT_IMPLEMENTED
;
909 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
912 LPWSTR szPack
= NULL
;
914 TRACE("%s\n", debugstr_a(szPackage
) );
918 szPack
= strdupAtoW( szPackage
);
920 return ERROR_OUTOFMEMORY
;
923 r
= MsiVerifyPackageW( szPack
);
925 HeapFree( GetProcessHeap(), 0, szPack
);
930 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
935 TRACE("%s\n", debugstr_w(szPackage
) );
937 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
938 MsiCloseHandle( handle
);
943 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
944 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
946 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
952 szwProduct
= strdupAtoW( szProduct
);
954 return ERROR_OUTOFMEMORY
;
959 szwComponent
= strdupAtoW( szComponent
);
962 HeapFree( GetProcessHeap(), 0, szwProduct
);
963 return ERROR_OUTOFMEMORY
;
967 if( pcchBuf
&& *pcchBuf
> 0 )
968 lpwPathBuf
= HeapAlloc( GetProcessHeap(), 0, *pcchBuf
* sizeof(WCHAR
));
972 incoming_len
= *pcchBuf
;
973 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
975 HeapFree( GetProcessHeap(), 0, szwProduct
);
976 HeapFree( GetProcessHeap(), 0, szwComponent
);
979 if (rc
!= INSTALLSTATE_UNKNOWN
)
980 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
981 lpPathBuf
, incoming_len
, NULL
, NULL
);
982 HeapFree( GetProcessHeap(), 0, lpwPathBuf
);
988 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
989 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
991 WCHAR squished_pc
[GUID_SIZE
];
993 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
998 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
999 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1001 if( lpPathBuf
&& !pcchBuf
)
1002 return INSTALLSTATE_INVALIDARG
;
1004 squash_guid(szProduct
,squished_pc
);
1006 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1007 if( rc
!= ERROR_SUCCESS
)
1012 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1013 if( rc
!= ERROR_SUCCESS
)
1018 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1019 if( rc
!= ERROR_SUCCESS
)
1021 if( type
!= REG_SZ
)
1024 sz
+= sizeof(WCHAR
);
1025 path
= HeapAlloc( GetProcessHeap(), 0, sz
);
1029 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1030 if( rc
!= ERROR_SUCCESS
)
1033 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1034 debugstr_w(szProduct
), debugstr_w(path
));
1038 FIXME("Registry entry.. check entry\n");
1039 rrc
= INSTALLSTATE_LOCAL
;
1043 /* PROBABLY a file */
1044 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1045 rrc
= INSTALLSTATE_LOCAL
;
1047 rrc
= INSTALLSTATE_ABSENT
;
1052 sz
= sz
/ sizeof(WCHAR
);
1053 if( *pcchBuf
>= sz
)
1054 lstrcpyW( lpPathBuf
, path
);
1059 HeapFree(GetProcessHeap(), 0, path
);
1064 /******************************************************************
1065 * MsiQueryFeatureStateA [MSI.@]
1067 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1070 LPWSTR szwProduct
= NULL
;
1071 LPWSTR szwFeature
= NULL
;
1075 szwProduct
= strdupAtoW( szProduct
);
1077 return ERROR_OUTOFMEMORY
;
1082 szwFeature
= strdupAtoW( szFeature
);
1085 HeapFree( GetProcessHeap(), 0, szwProduct
);
1086 return ERROR_OUTOFMEMORY
;
1090 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1092 HeapFree( GetProcessHeap(), 0, szwProduct
);
1093 HeapFree( GetProcessHeap(), 0, szwFeature
);
1098 /******************************************************************
1099 * MsiQueryFeatureStateW [MSI.@]
1101 * This does not verify that the Feature is functional. So i am only going to
1102 * check the existence of the key in the registry. This should tell me if it is
1105 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1111 TRACE("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1113 rc
= MSIREG_OpenFeaturesKey(szProduct
, &hkey
, FALSE
);
1114 if (rc
!= ERROR_SUCCESS
)
1115 return INSTALLSTATE_UNKNOWN
;
1117 rc
= RegQueryValueExW( hkey
, szFeature
, NULL
, NULL
, NULL
, &sz
);
1120 if (rc
== ERROR_SUCCESS
)
1121 return INSTALLSTATE_LOCAL
;
1123 return INSTALLSTATE_ABSENT
;
1126 /******************************************************************
1127 * MsiGetFileVersionA [MSI.@]
1129 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1130 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1132 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1133 UINT ret
= ERROR_OUTOFMEMORY
;
1137 szwFilePath
= strdupAtoW( szFilePath
);
1142 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1144 lpwVersionBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1145 if( !lpwVersionBuff
)
1149 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1151 lpwLangBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1156 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1157 lpwLangBuff
, pcchLangBuf
);
1159 if( lpwVersionBuff
)
1160 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1161 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1163 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1164 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1167 HeapFree(GetProcessHeap(), 0, szwFilePath
);
1168 HeapFree(GetProcessHeap(), 0, lpwVersionBuff
);
1169 HeapFree(GetProcessHeap(), 0, lpwLangBuff
);
1174 /******************************************************************
1175 * MsiGetFileVersionW [MSI.@]
1177 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1178 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1180 static const WCHAR szVersionResource
[] = {'\\',0};
1181 static const WCHAR szVersionFormat
[] = {
1182 '%','d','.','%','d','.','%','d','.','%','d',0};
1183 static const WCHAR szLangFormat
[] = {'%','d',0};
1186 LPVOID lpVer
= NULL
;
1187 VS_FIXEDFILEINFO
*ffi
;
1191 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1192 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1193 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1195 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1197 return GetLastError();
1199 lpVer
= HeapAlloc(GetProcessHeap(), 0, dwVerLen
);
1202 ret
= ERROR_OUTOFMEMORY
;
1206 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1208 ret
= GetLastError();
1211 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1213 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1216 wsprintfW(tmp
, szVersionFormat
,
1217 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1218 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1219 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1220 *pcchVersionBuf
= lstrlenW(lpVersionBuf
);
1225 *pcchVersionBuf
= 0;
1229 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1231 DWORD lang
= GetUserDefaultLangID();
1233 FIXME("Retrieve language from file\n");
1234 wsprintfW(tmp
, szLangFormat
, lang
);
1235 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1236 *pcchLangBuf
= lstrlenW(lpLangBuf
);
1240 HeapFree(GetProcessHeap(), 0, lpVer
);
1245 /******************************************************************
1248 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1252 case DLL_PROCESS_ATTACH
:
1253 msi_hInstance
= hinstDLL
;
1254 DisableThreadLibraryCalls(hinstDLL
);
1255 msi_dialog_register_class();
1257 case DLL_PROCESS_DETACH
:
1258 msi_dialog_unregister_class();
1259 /* FIXME: Cleanup */
1265 typedef struct tagIClassFactoryImpl
1267 IClassFactoryVtbl
*lpVtbl
;
1268 } IClassFactoryImpl
;
1270 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1271 REFIID riid
,LPVOID
*ppobj
)
1273 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1274 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1275 return E_NOINTERFACE
;
1278 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1283 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1288 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1289 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1291 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1293 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1297 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1299 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1301 FIXME("%p %d\n", This
, dolock
);
1305 static IClassFactoryVtbl MsiCF_Vtbl
=
1307 MsiCF_QueryInterface
,
1310 MsiCF_CreateInstance
,
1314 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1316 /******************************************************************
1317 * DllGetClassObject [MSI.@]
1319 HRESULT WINAPI
MSI_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1321 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1323 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1324 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1325 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1326 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1327 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1329 *ppv
= (LPVOID
) &Msi_CF
;
1332 return CLASS_E_CLASSNOTAVAILABLE
;
1335 /******************************************************************
1336 * DllGetVersion [MSI.@]
1338 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
1342 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1343 return E_INVALIDARG
;
1345 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1346 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1347 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1348 pdvi
->dwPlatformID
= 1;
1353 /******************************************************************
1354 * DllCanUnloadNow [MSI.@]
1356 BOOL WINAPI
MSI_DllCanUnloadNow(void)
1361 UINT WINAPI
MsiGetFeatureUsageW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1362 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1364 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1365 pdwUseCount
, pwDateUsed
);
1366 return ERROR_CALL_NOT_IMPLEMENTED
;
1369 UINT WINAPI
MsiGetFeatureUsageA(LPCSTR szProduct
, LPCSTR szFeature
,
1370 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1372 FIXME("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1373 pdwUseCount
, pwDateUsed
);
1374 return ERROR_CALL_NOT_IMPLEMENTED
;
1377 INSTALLSTATE WINAPI
MsiUseFeatureExW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1378 DWORD dwInstallMode
, DWORD dwReserved
)
1380 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1381 dwInstallMode
, dwReserved
);
1384 * Polls all the components of the feature to find install state and then
1386 * Software\\Microsoft\\Windows\\CurrentVersion\\
1387 * Installer\\Products\\<squishguid>\\<feature>
1388 * "Usage"=dword:........
1391 return INSTALLSTATE_LOCAL
;
1394 /***********************************************************************
1395 * MsiUseFeatureExA [MSI.@]
1397 INSTALLSTATE WINAPI
MsiUseFeatureExA(LPCSTR szProduct
, LPCSTR szFeature
,
1398 DWORD dwInstallMode
, DWORD dwReserved
)
1400 FIXME("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1401 dwInstallMode
, dwReserved
);
1403 return INSTALLSTATE_LOCAL
;
1406 INSTALLSTATE WINAPI
MsiUseFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1408 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1410 return INSTALLSTATE_LOCAL
;
1413 INSTALLSTATE WINAPI
MsiUseFeatureA(LPCSTR szProduct
, LPCSTR szFeature
)
1415 FIXME("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
));
1417 return INSTALLSTATE_LOCAL
;
1420 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1421 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1422 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1429 LPWSTR product
= NULL
;
1430 LPWSTR component
= NULL
;
1434 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1435 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1436 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1438 rc
= MSIREG_OpenUserComponentsKey(szComponent
, &hkey
, FALSE
);
1439 if (rc
!= ERROR_SUCCESS
)
1440 return ERROR_INDEX_ABSENT
;
1443 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, NULL
, &sz
);
1447 return ERROR_INDEX_ABSENT
;
1450 info
= HeapAlloc(GetProcessHeap(),0,sz
);
1451 rc
= RegQueryValueExW( hkey
, szQualifier
, NULL
, NULL
, (LPBYTE
)info
, &sz
);
1452 if (rc
!= ERROR_SUCCESS
)
1455 HeapFree(GetProcessHeap(),0,info
);
1456 return ERROR_INDEX_ABSENT
;
1459 /* find the component */
1460 ptr
= strchrW(&info
[20],'>');
1466 HeapFree(GetProcessHeap(),0,info
);
1467 return ERROR_INDEX_ABSENT
;
1472 decode_base85_guid(info
,&clsid
);
1473 StringFromCLSID(&clsid
, &product
);
1475 decode_base85_guid(ptr
,&clsid
);
1476 StringFromCLSID(&clsid
, &component
);
1479 rc
= MsiGetComponentPathW(product
, component
, lpPathBuf
, pcchPathBuf
);
1481 rc
= MsiGetComponentPathW(szProduct
, component
, lpPathBuf
, pcchPathBuf
);
1484 HeapFree(GetProcessHeap(),0,info
);
1485 HeapFree(GetProcessHeap(),0,product
);
1486 HeapFree(GetProcessHeap(),0,component
);
1488 if (rc
== INSTALLSTATE_LOCAL
)
1489 return ERROR_SUCCESS
;
1491 return ERROR_FILE_NOT_FOUND
;
1494 /***********************************************************************
1495 * MsiProvideQualifiedComponentW [MSI.@]
1497 UINT WINAPI
MsiProvideQualifiedComponentW( LPCWSTR szComponent
,
1498 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR lpPathBuf
,
1501 return MsiProvideQualifiedComponentExW(szComponent
, szQualifier
,
1502 dwInstallMode
, NULL
, 0, 0, lpPathBuf
, pcchPathBuf
);
1505 /***********************************************************************
1506 * MsiProvideQualifiedComponentA [MSI.@]
1508 UINT WINAPI
MsiProvideQualifiedComponentA( LPCSTR szComponent
,
1509 LPCSTR szQualifier
, DWORD dwInstallMode
, LPSTR lpPathBuf
,
1512 LPWSTR szwComponent
, szwQualifier
, lpwPathBuf
;
1516 TRACE("%s %s %li %p %p\n",szComponent
, szQualifier
,
1517 dwInstallMode
, lpPathBuf
, pcchPathBuf
);
1519 szwComponent
= strdupAtoW( szComponent
);
1520 szwQualifier
= strdupAtoW( szQualifier
);
1522 lpwPathBuf
= HeapAlloc(GetProcessHeap(),0,*pcchPathBuf
* sizeof(WCHAR
));
1524 pcchwPathBuf
= *pcchPathBuf
;
1526 rc
= MsiProvideQualifiedComponentW(szwComponent
, szwQualifier
,
1527 dwInstallMode
, lpwPathBuf
, &pcchwPathBuf
);
1529 HeapFree(GetProcessHeap(),0,szwComponent
);
1530 HeapFree(GetProcessHeap(),0,szwQualifier
);
1531 *pcchPathBuf
= WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, pcchwPathBuf
,
1532 lpPathBuf
, *pcchPathBuf
, NULL
, NULL
);
1534 HeapFree(GetProcessHeap(),0,lpwPathBuf
);
1538 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1539 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1540 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1544 UINT rc
= ERROR_SUCCESS
,rc2
= ERROR_SUCCESS
;
1545 static const WCHAR szOwner
[] = {'R','e','g','O','w','n','e','r',0};
1546 static const WCHAR szCompany
[] = {'R','e','g','C','o','m','p','a','n','y',0};
1547 static const WCHAR szSerial
[] = {'P','r','o','d','u','c','t','I','D',0};
1549 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1550 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1553 rc
= MSIREG_OpenUninstallKey(szProduct
, &hkey
, FALSE
);
1554 if (rc
!= ERROR_SUCCESS
)
1555 return USERINFOSTATE_UNKNOWN
;
1559 sz
= *lpUserNameBuf
* sizeof(WCHAR
);
1560 rc
= RegQueryValueExW( hkey
, szOwner
, NULL
, NULL
, (LPBYTE
)lpUserNameBuf
,
1563 if (!lpUserNameBuf
&& pcchUserNameBuf
)
1566 rc
= RegQueryValueExW( hkey
, szOwner
, NULL
, NULL
, NULL
, &sz
);
1569 if (pcchUserNameBuf
)
1570 *pcchUserNameBuf
= sz
/ sizeof(WCHAR
);
1574 sz
= *pcchOrgNameBuf
* sizeof(WCHAR
);
1575 rc2
= RegQueryValueExW( hkey
, szCompany
, NULL
, NULL
,
1576 (LPBYTE
)lpOrgNameBuf
, &sz
);
1578 if (!lpOrgNameBuf
&& pcchOrgNameBuf
)
1581 rc2
= RegQueryValueExW( hkey
, szCompany
, NULL
, NULL
, NULL
, &sz
);
1585 *pcchOrgNameBuf
= sz
/ sizeof(WCHAR
);
1587 if (rc
!= ERROR_SUCCESS
&& rc
!= ERROR_MORE_DATA
&&
1588 rc2
!= ERROR_SUCCESS
&& rc2
!= ERROR_MORE_DATA
)
1591 return USERINFOSTATE_ABSENT
;
1596 sz
= *pcchSerialBuf
* sizeof(WCHAR
);
1597 RegQueryValueExW( hkey
, szSerial
, NULL
, NULL
, (LPBYTE
)lpSerialBuf
,
1600 if (!lpSerialBuf
&& pcchSerialBuf
)
1603 rc
= RegQueryValueExW( hkey
, szSerial
, NULL
, NULL
, NULL
, &sz
);
1606 *pcchSerialBuf
= sz
/ sizeof(WCHAR
);
1609 return USERINFOSTATE_PRESENT
;
1612 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1613 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1614 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1616 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1617 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1620 return USERINFOSTATE_UNKNOWN
;
1623 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1627 MSIPACKAGE
*package
;
1628 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1630 TRACE("(%s)\n",debugstr_w(szProduct
));
1632 rc
= MsiOpenProductW(szProduct
,&handle
);
1633 if (rc
!= ERROR_SUCCESS
)
1634 return ERROR_INVALID_PARAMETER
;
1636 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1637 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1638 msiobj_release( &package
->hdr
);
1640 MsiCloseHandle(handle
);
1645 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1649 MSIPACKAGE
*package
;
1650 static const WCHAR szFirstRun
[] = {'F','i','r','s','t','R','u','n',0};
1652 TRACE("(%s)\n",debugstr_a(szProduct
));
1654 rc
= MsiOpenProductA(szProduct
,&handle
);
1655 if (rc
!= ERROR_SUCCESS
)
1656 return ERROR_INVALID_PARAMETER
;
1658 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
1659 rc
= ACTION_PerformUIAction(package
, szFirstRun
);
1660 msiobj_release( &package
->hdr
);
1662 MsiCloseHandle(handle
);
1667 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved
)
1669 WCHAR path
[MAX_PATH
];
1672 FIXME("Don't know how to handle argument %ld\n", dwReserved
);
1673 return ERROR_CALL_NOT_IMPLEMENTED
;
1676 if(!GetWindowsDirectoryW(path
, MAX_PATH
)) {
1677 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1679 return ERROR_CALL_NOT_IMPLEMENTED
;
1682 strcatW(path
, installerW
);
1684 CreateDirectoryW(path
, NULL
);
1689 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1690 LPSTR szProductCode
, LPSTR szFeatureId
,
1691 LPSTR szComponentCode
)
1694 return ERROR_CALL_NOT_IMPLEMENTED
;
1697 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1698 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1699 LPWSTR szComponentCode
)
1702 return ERROR_CALL_NOT_IMPLEMENTED
;
1705 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1706 DWORD dwReinstallMode
)
1708 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1710 return ERROR_SUCCESS
;
1713 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1714 DWORD dwReinstallMode
)
1716 FIXME("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1718 return ERROR_SUCCESS
;