msi: Use msi_alloc/free, not HeapAlloc/Free.
[wine/wine-kai.git] / dlls / msi / msi.c
blob8c9139dd6c6fbb8c9e94d1f1f1b52596197eb137
1 /*
2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004,2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winnls.h"
30 #include "shlwapi.h"
31 #include "wine/debug.h"
32 #include "msi.h"
33 #include "msiquery.h"
34 #include "msipriv.h"
35 #include "wincrypt.h"
36 #include "winver.h"
37 #include "winuser.h"
38 #include "shlobj.h"
39 #include "shobjidl.h"
40 #include "objidl.h"
41 #include "wine/unicode.h"
42 #include "action.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msi);
46 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
48 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
50 UINT r;
51 LPWSTR szwProd = NULL;
53 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
55 if( szProduct )
57 szwProd = strdupAtoW( szProduct );
58 if( !szwProd )
59 return ERROR_OUTOFMEMORY;
62 r = MsiOpenProductW( szwProd, phProduct );
64 msi_free( szwProd );
66 return r;
69 static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
71 LPWSTR path = NULL;
72 UINT r;
73 HKEY hKeyProduct = NULL;
74 DWORD count, type;
76 TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
78 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
79 if( r != ERROR_SUCCESS )
81 r = ERROR_UNKNOWN_PRODUCT;
82 goto end;
85 /* find the size of the path */
86 type = count = 0;
87 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
88 NULL, &type, NULL, &count );
89 if( r != ERROR_SUCCESS )
91 r = ERROR_UNKNOWN_PRODUCT;
92 goto end;
95 /* now alloc and fetch the path of the database to open */
96 path = msi_alloc( count );
97 if( !path )
98 goto end;
100 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
101 NULL, &type, (LPBYTE) path, &count );
102 if( r != ERROR_SUCCESS )
104 r = ERROR_UNKNOWN_PRODUCT;
105 goto end;
108 r = MSI_OpenPackageW( path, ppackage );
110 end:
111 msi_free( path );
112 if( hKeyProduct )
113 RegCloseKey( hKeyProduct );
115 return r;
118 UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
120 MSIPACKAGE *package = NULL;
121 UINT r;
123 r = MSI_OpenProductW( szProduct, &package );
124 if( r == ERROR_SUCCESS )
126 *phProduct = alloc_msihandle( &package->hdr );
127 msiobj_release( &package->hdr );
129 return r;
132 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
133 LPCSTR szTransforms, LANGID lgidLanguage)
135 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
136 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
137 return ERROR_CALL_NOT_IMPLEMENTED;
140 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
141 LPCWSTR szTransforms, LANGID lgidLanguage)
143 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
144 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
145 return ERROR_CALL_NOT_IMPLEMENTED;
148 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
149 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
151 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
152 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
153 lgidLanguage, dwPlatform, dwOptions);
154 return ERROR_CALL_NOT_IMPLEMENTED;
157 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
158 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
160 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
161 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
162 lgidLanguage, dwPlatform, dwOptions);
163 return ERROR_CALL_NOT_IMPLEMENTED;
166 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
168 LPWSTR szwPath = NULL, szwCommand = NULL;
169 UINT r = ERROR_OUTOFMEMORY;
171 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
173 if( szPackagePath )
175 szwPath = strdupAtoW( szPackagePath );
176 if( !szwPath )
177 goto end;
180 if( szCommandLine )
182 szwCommand = strdupAtoW( szCommandLine );
183 if( !szwCommand )
184 goto end;
187 r = MsiInstallProductW( szwPath, szwCommand );
189 end:
190 msi_free( szwPath );
191 msi_free( szwCommand );
193 return r;
196 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
198 MSIPACKAGE *package = NULL;
199 UINT r;
201 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
203 r = MSI_OpenPackageW( szPackagePath, &package );
204 if (r == ERROR_SUCCESS)
206 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
207 msiobj_release( &package->hdr );
210 return r;
213 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
215 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
216 return ERROR_CALL_NOT_IMPLEMENTED;
219 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
221 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
222 return ERROR_CALL_NOT_IMPLEMENTED;
225 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
226 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
228 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
229 eInstallType, debugstr_a(szCommandLine));
230 return ERROR_CALL_NOT_IMPLEMENTED;
233 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
234 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
236 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
237 eInstallType, debugstr_w(szCommandLine));
238 return ERROR_CALL_NOT_IMPLEMENTED;
241 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
242 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
244 MSIPACKAGE* package = NULL;
245 UINT r;
246 DWORD sz;
247 WCHAR sourcepath[MAX_PATH];
248 WCHAR filename[MAX_PATH];
249 static const WCHAR szInstalled[] = {
250 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
251 LPWSTR commandline;
253 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
254 debugstr_w(szCommandLine));
256 if (eInstallState != INSTALLSTATE_LOCAL &&
257 eInstallState != INSTALLSTATE_DEFAULT)
259 FIXME("Not implemented for anything other than local installs\n");
260 return ERROR_CALL_NOT_IMPLEMENTED;
263 sz = sizeof(sourcepath);
264 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
265 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
266 &sz);
268 sz = sizeof(filename);
269 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
270 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
272 lstrcatW(sourcepath,filename);
275 * ok 1, we need to find the msi file for this product.
276 * 2, find the source dir for the files
277 * 3, do the configure/install.
278 * 4, cleanupany runonce entry.
281 r = MSI_OpenProductW( szProduct, &package );
282 if (r != ERROR_SUCCESS)
283 return r;
285 sz = lstrlenW(szInstalled) + 1;
287 if (szCommandLine)
288 sz += lstrlenW(szCommandLine);
290 commandline = msi_alloc(sz * sizeof(WCHAR));
291 if (!commandline )
293 r = ERROR_OUTOFMEMORY;
294 goto end;
297 commandline[0] = 0;
298 if (szCommandLine)
299 lstrcpyW(commandline,szCommandLine);
301 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
302 lstrcatW(commandline,szInstalled);
304 r = MSI_InstallPackage( package, sourcepath, commandline );
306 msi_free(commandline);
308 end:
309 msiobj_release( &package->hdr );
311 return r;
314 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
315 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
317 LPWSTR szwProduct = NULL;
318 LPWSTR szwCommandLine = NULL;
319 UINT r = ERROR_OUTOFMEMORY;
321 if( szProduct )
323 szwProduct = strdupAtoW( szProduct );
324 if( !szwProduct )
325 goto end;
328 if( szCommandLine)
330 szwCommandLine = strdupAtoW( szCommandLine );
331 if( !szwCommandLine)
332 goto end;
335 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
336 szwCommandLine );
337 end:
338 msi_free( szwProduct );
339 msi_free( szwCommandLine);
341 return r;
344 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
345 INSTALLSTATE eInstallState)
347 LPWSTR szwProduct = NULL;
348 UINT r;
350 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
352 if( szProduct )
354 szwProduct = strdupAtoW( szProduct );
355 if( !szwProduct )
356 return ERROR_OUTOFMEMORY;
359 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
360 msi_free( szwProduct );
362 return r;
365 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
366 INSTALLSTATE eInstallState)
368 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
371 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
373 LPWSTR szwComponent = NULL;
374 UINT r;
375 WCHAR szwBuffer[GUID_SIZE];
377 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
379 if( szComponent )
381 szwComponent = strdupAtoW( szComponent );
382 if( !szwComponent )
383 return ERROR_OUTOFMEMORY;
386 r = MsiGetProductCodeW( szwComponent, szwBuffer );
388 if( ERROR_SUCCESS == r )
389 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
391 msi_free( szwComponent );
393 return r;
396 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
398 UINT rc;
399 HKEY hkey;
400 WCHAR szSquished[GUID_SIZE];
401 DWORD sz = GUID_SIZE;
402 static const WCHAR szPermKey[] =
403 { '0','0','0','0','0','0','0','0','0','0','0','0',
404 '0','0','0','0','0','0','0','0','0','0','0','0',
405 '0','0','0','0','0','0','0','0',0};
407 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
409 if (NULL == szComponent)
410 return ERROR_INVALID_PARAMETER;
412 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
413 if (rc != ERROR_SUCCESS)
414 return ERROR_UNKNOWN_COMPONENT;
416 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
417 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
419 sz = GUID_SIZE;
420 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
423 RegCloseKey(hkey);
425 if (rc != ERROR_SUCCESS)
426 return ERROR_INSTALL_FAILURE;
428 unsquash_guid(szSquished, szBuffer);
429 return ERROR_SUCCESS;
432 UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
433 awstring *szValue, DWORD *pcchValueBuf)
435 UINT r;
436 HKEY hkey;
437 LPWSTR val = NULL;
439 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
440 debugstr_w(szAttribute), szValue, pcchValueBuf);
443 * FIXME: Values seem scattered/duplicated in the registry. Is there a system?
446 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
447 return ERROR_INVALID_PARAMETER;
449 /* check for special properties */
450 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
452 LPWSTR regval;
453 WCHAR packagecode[35];
455 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
456 if (r != ERROR_SUCCESS)
457 return ERROR_UNKNOWN_PRODUCT;
459 regval = msi_reg_get_val_str( hkey, szAttribute );
460 if (regval)
462 if (unsquash_guid(regval, packagecode))
463 val = strdupW(packagecode);
464 msi_free(regval);
467 RegCloseKey(hkey);
469 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
471 static const WCHAR one[] = { '1',0 };
473 * FIXME: should be in the Product key (user or system?)
474 * but isn't written yet...
476 val = strdupW( one );
478 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
479 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW))
481 static const WCHAR fmt[] = { '%','u',0 };
482 WCHAR szVal[16];
483 DWORD regval;
485 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
486 if (r != ERROR_SUCCESS)
487 return ERROR_UNKNOWN_PRODUCT;
489 if (msi_reg_get_val_dword( hkey, szAttribute, &regval))
491 sprintfW(szVal, fmt, regval);
492 val = strdupW( szVal );
495 RegCloseKey(hkey);
497 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW))
499 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
500 if (r != ERROR_SUCCESS)
501 return ERROR_UNKNOWN_PRODUCT;
503 val = msi_reg_get_val_str( hkey, szAttribute );
505 RegCloseKey(hkey);
507 else
509 static const WCHAR szDisplayVersion[] = {
510 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0 };
512 FIXME("%s\n", debugstr_w(szAttribute));
513 /* FIXME: some attribute values not tested... */
515 if (!lstrcmpW( szAttribute, INSTALLPROPERTY_VERSIONSTRINGW ))
516 szAttribute = szDisplayVersion;
518 r = MSIREG_OpenUninstallKey( szProduct, &hkey, FALSE );
519 if (r != ERROR_SUCCESS)
520 return ERROR_UNKNOWN_PRODUCT;
522 val = msi_reg_get_val_str( hkey, szAttribute );
524 RegCloseKey(hkey);
527 TRACE("returning %s\n", debugstr_w(val));
529 if (!val)
530 return ERROR_UNKNOWN_PROPERTY;
532 r = msi_strcpy_to_awstring( val, szValue, pcchValueBuf );
534 msi_free(val);
536 return r;
539 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
540 LPSTR szBuffer, DWORD *pcchValueBuf)
542 LPWSTR szwProduct, szwAttribute = NULL;
543 UINT r = ERROR_OUTOFMEMORY;
544 awstring buffer;
546 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
547 szBuffer, pcchValueBuf);
549 szwProduct = strdupAtoW( szProduct );
550 if( szProduct && !szwProduct )
551 goto end;
553 szwAttribute = strdupAtoW( szAttribute );
554 if( szAttribute && !szwAttribute )
555 goto end;
557 buffer.unicode = FALSE;
558 buffer.str.a = szBuffer;
560 r = MSI_GetProductInfo( szwProduct, szwAttribute,
561 &buffer, pcchValueBuf );
563 end:
564 msi_free( szwProduct );
565 msi_free( szwAttribute );
567 return r;
570 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
571 LPWSTR szBuffer, DWORD *pcchValueBuf)
573 awstring buffer;
575 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
576 szBuffer, pcchValueBuf);
578 buffer.unicode = TRUE;
579 buffer.str.w = szBuffer;
581 return MSI_GetProductInfo( szProduct, szAttribute,
582 &buffer, pcchValueBuf );
585 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
587 LPWSTR szwLogFile = NULL;
588 UINT r;
590 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
592 if( szLogFile )
594 szwLogFile = strdupAtoW( szLogFile );
595 if( !szwLogFile )
596 return ERROR_OUTOFMEMORY;
598 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
599 msi_free( szwLogFile );
600 return r;
603 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
605 HANDLE file = INVALID_HANDLE_VALUE;
607 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
609 if (szLogFile)
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)
617 CloseHandle(file);
618 else
619 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
621 else
622 gszLogFile[0] = '\0';
624 return ERROR_SUCCESS;
627 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
629 LPWSTR szwProduct = NULL;
630 INSTALLSTATE r;
632 if( szProduct )
634 szwProduct = strdupAtoW( szProduct );
635 if( !szwProduct )
636 return ERROR_OUTOFMEMORY;
638 r = MsiQueryProductStateW( szwProduct );
639 msi_free( szwProduct );
640 return r;
643 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
645 UINT rc;
646 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
647 HKEY hkey = 0;
648 static const WCHAR szWindowsInstaller[] = {
649 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
650 DWORD sz;
652 TRACE("%s\n", debugstr_w(szProduct));
654 if (!szProduct)
655 return INSTALLSTATE_INVALIDARG;
657 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
658 if (rc != ERROR_SUCCESS)
659 goto end;
661 RegCloseKey(hkey);
663 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
664 if (rc != ERROR_SUCCESS)
665 goto end;
667 sz = sizeof(rrc);
668 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
669 if (rc != ERROR_SUCCESS)
670 goto end;
672 switch (rrc)
674 case 1:
675 /* default */
676 rrc = INSTALLSTATE_DEFAULT;
677 break;
678 default:
679 FIXME("Unknown install state read from registry (%i)\n",rrc);
680 rrc = INSTALLSTATE_UNKNOWN;
681 break;
683 end:
684 RegCloseKey(hkey);
685 return rrc;
688 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
690 INSTALLUILEVEL old = gUILevel;
691 HWND oldwnd = gUIhwnd;
693 TRACE("%08x %p\n", dwUILevel, phWnd);
695 gUILevel = dwUILevel;
696 if (phWnd)
698 gUIhwnd = *phWnd;
699 *phWnd = oldwnd;
701 return old;
704 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
705 DWORD dwMessageFilter, LPVOID pvContext)
707 INSTALLUI_HANDLERA prev = gUIHandlerA;
709 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
710 gUIHandlerA = puiHandler;
711 gUIFilter = dwMessageFilter;
712 gUIContext = pvContext;
714 return prev;
717 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
718 DWORD dwMessageFilter, LPVOID pvContext)
720 INSTALLUI_HANDLERW prev = gUIHandlerW;
722 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
723 gUIHandlerW = puiHandler;
724 gUIFilter = dwMessageFilter;
725 gUIContext = pvContext;
727 return prev;
730 /******************************************************************
731 * MsiLoadStringW [MSI.@]
733 * Loads a string from MSI's string resources.
735 * PARAMS
737 * handle [I] only -1 is handled currently
738 * id [I] id of the string to be loaded
739 * lpBuffer [O] buffer for the string to be written to
740 * nBufferMax [I] maximum size of the buffer in characters
741 * lang [I] the preferred language for the string
743 * RETURNS
745 * If successful, this function returns the language id of the string loaded
746 * If the function fails, the function returns zero.
748 * NOTES
750 * The type of the first parameter is unknown. LoadString's prototype
751 * suggests that it might be a module handle. I have made it an MSI handle
752 * for starters, as -1 is an invalid MSI handle, but not an invalid module
753 * handle. Maybe strings can be stored in an MSI database somehow.
755 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
756 int nBufferMax, LANGID lang )
758 HRSRC hres;
759 HGLOBAL hResData;
760 LPWSTR p;
761 DWORD i, len;
763 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
765 if( handle != -1 )
766 FIXME("don't know how to deal with handle = %08lx\n", handle);
768 if( !lang )
769 lang = GetUserDefaultLangID();
771 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
772 (LPWSTR)1, lang );
773 if( !hres )
774 return 0;
775 hResData = LoadResource( msi_hInstance, hres );
776 if( !hResData )
777 return 0;
778 p = LockResource( hResData );
779 if( !p )
780 return 0;
782 for (i = 0; i < (id&0xf); i++)
783 p += *p + 1;
784 len = *p;
786 if( nBufferMax <= len )
787 return 0;
789 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
790 lpBuffer[ len ] = 0;
792 TRACE("found -> %s\n", debugstr_w(lpBuffer));
794 return lang;
797 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
798 int nBufferMax, LANGID lang )
800 LPWSTR bufW;
801 LANGID r;
802 DWORD len;
804 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
805 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
806 if( r )
808 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
809 if( len <= nBufferMax )
810 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
811 lpBuffer, nBufferMax, NULL, NULL );
812 else
813 r = 0;
815 msi_free(bufW);
816 return r;
819 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
820 DWORD *pcchBuf)
822 char szProduct[GUID_SIZE];
824 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
826 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
827 return INSTALLSTATE_UNKNOWN;
829 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
832 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
833 DWORD *pcchBuf)
835 WCHAR szProduct[GUID_SIZE];
837 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
839 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
840 return INSTALLSTATE_UNKNOWN;
842 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
845 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
846 WORD wLanguageId, DWORD f)
848 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
849 uType,wLanguageId,f);
850 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
853 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
854 WORD wLanguageId, DWORD f)
856 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
857 uType,wLanguageId,f);
858 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
861 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
862 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
863 DWORD* pcchPathBuf )
865 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
866 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
867 pcchPathBuf);
868 return ERROR_CALL_NOT_IMPLEMENTED;
871 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
872 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
873 DWORD* pcchPathBuf )
875 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
876 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
877 pcchPathBuf);
878 return ERROR_CALL_NOT_IMPLEMENTED;
881 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
882 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
884 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
885 return ERROR_CALL_NOT_IMPLEMENTED;
888 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
889 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
891 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
892 return ERROR_CALL_NOT_IMPLEMENTED;
895 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
896 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
897 DWORD* pcbHashData)
899 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
900 ppcCertContext, pbHashData, pcbHashData);
901 return ERROR_CALL_NOT_IMPLEMENTED;
904 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
905 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
906 DWORD* pcbHashData)
908 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
909 ppcCertContext, pbHashData, pcbHashData);
910 return ERROR_CALL_NOT_IMPLEMENTED;
913 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
914 LPSTR szValue, DWORD *pccbValue )
916 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
917 return ERROR_CALL_NOT_IMPLEMENTED;
920 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
921 LPWSTR szValue, DWORD *pccbValue )
923 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
924 return ERROR_CALL_NOT_IMPLEMENTED;
927 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
929 UINT r;
930 LPWSTR szPack = NULL;
932 TRACE("%s\n", debugstr_a(szPackage) );
934 if( szPackage )
936 szPack = strdupAtoW( szPackage );
937 if( !szPack )
938 return ERROR_OUTOFMEMORY;
941 r = MsiVerifyPackageW( szPack );
943 msi_free( szPack );
945 return r;
948 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
950 MSIHANDLE handle;
951 UINT r;
953 TRACE("%s\n", debugstr_w(szPackage) );
955 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
956 MsiCloseHandle( handle );
958 return r;
961 INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
962 awstring* lpPathBuf, DWORD* pcchBuf)
964 WCHAR squished_pc[GUID_SIZE], squished_comp[GUID_SIZE];
965 UINT rc;
966 HKEY hkey = 0;
967 LPWSTR path = NULL;
968 INSTALLSTATE r;
970 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
971 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
973 if( !szProduct || !szComponent )
974 return INSTALLSTATE_INVALIDARG;
975 if( lpPathBuf->str.w && !pcchBuf )
976 return INSTALLSTATE_INVALIDARG;
978 if (!squash_guid( szProduct, squished_pc ) ||
979 !squash_guid( szComponent, squished_comp ))
980 return INSTALLSTATE_INVALIDARG;
982 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
983 if( rc != ERROR_SUCCESS )
984 return INSTALLSTATE_UNKNOWN;
986 RegCloseKey(hkey);
988 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
989 if( rc != ERROR_SUCCESS )
990 return INSTALLSTATE_UNKNOWN;
992 path = msi_reg_get_val_str( hkey, squished_pc );
993 RegCloseKey(hkey);
995 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
996 debugstr_w(szProduct), debugstr_w(path));
998 if (!path)
999 return INSTALLSTATE_UNKNOWN;
1001 if (path[0])
1002 r = INSTALLSTATE_LOCAL;
1003 else
1004 r = INSTALLSTATE_NOTUSED;
1006 msi_strcpy_to_awstring( path, lpPathBuf, pcchBuf );
1008 msi_free( path );
1009 return r;
1012 /******************************************************************
1013 * MsiGetComponentPathW [MSI.@]
1015 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1016 LPWSTR lpPathBuf, DWORD* pcchBuf)
1018 awstring path;
1020 path.unicode = TRUE;
1021 path.str.w = lpPathBuf;
1023 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1026 /******************************************************************
1027 * MsiGetComponentPathA [MSI.@]
1029 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1030 LPSTR lpPathBuf, DWORD* pcchBuf)
1032 LPWSTR szwProduct, szwComponent = NULL;
1033 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1034 awstring path;
1036 szwProduct = strdupAtoW( szProduct );
1037 if( szProduct && !szwProduct)
1038 goto end;
1040 szwComponent = strdupAtoW( szComponent );
1041 if( szComponent && !szwComponent )
1042 goto end;
1044 path.unicode = FALSE;
1045 path.str.a = lpPathBuf;
1047 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1049 end:
1050 msi_free( szwProduct );
1051 msi_free( szwComponent );
1053 return r;
1056 /******************************************************************
1057 * MsiQueryFeatureStateA [MSI.@]
1059 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1061 LPWSTR szwProduct = NULL, szwFeature= NULL;
1062 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1064 szwProduct = strdupAtoW( szProduct );
1065 if ( szProduct && !szwProduct )
1066 goto end;
1068 szwFeature = strdupAtoW( szFeature );
1069 if ( szFeature && !szwFeature )
1070 goto end;
1072 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1074 end:
1075 msi_free( szwProduct);
1076 msi_free( szwFeature);
1078 return rc;
1081 /******************************************************************
1082 * MsiQueryFeatureStateW [MSI.@]
1084 * Checks the state of a feature
1086 * PARAMS
1087 * szProduct [I] Product's GUID string
1088 * szFeature [I] Feature's GUID string
1090 * RETURNS
1091 * INSTALLSTATE_LOCAL Feature is installed and useable
1092 * INSTALLSTATE_ABSENT Feature is absent
1093 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1094 * INSTALLSTATE_UNKNOWN An error occured
1095 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1098 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1100 WCHAR squishProduct[33], comp[GUID_SIZE];
1101 GUID guid;
1102 LPWSTR components, p, parent_feature;
1103 UINT rc;
1104 HKEY hkey;
1105 INSTALLSTATE r;
1106 BOOL missing = FALSE;
1108 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1110 if (!szProduct || !szFeature)
1111 return INSTALLSTATE_INVALIDARG;
1113 if (!squash_guid( szProduct, squishProduct ))
1114 return INSTALLSTATE_INVALIDARG;
1116 /* check that it's installed at all */
1117 rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
1118 if (rc != ERROR_SUCCESS)
1119 return INSTALLSTATE_UNKNOWN;
1121 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1122 RegCloseKey(hkey);
1124 if (!parent_feature)
1125 return INSTALLSTATE_UNKNOWN;
1127 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1128 msi_free(parent_feature);
1129 if (r == INSTALLSTATE_ABSENT)
1130 return r;
1132 /* now check if it's complete or advertised */
1133 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1134 if (rc != ERROR_SUCCESS)
1135 return INSTALLSTATE_UNKNOWN;
1137 components = msi_reg_get_val_str( hkey, szFeature );
1138 RegCloseKey(hkey);
1140 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1142 if (!components)
1144 ERR("components missing %s %s\n",
1145 debugstr_w(szProduct), debugstr_w(szFeature));
1146 return INSTALLSTATE_UNKNOWN;
1149 for( p = components; *p != 2 ; p += 20)
1151 if (!decode_base85_guid( p, &guid ))
1153 ERR("%s\n", debugstr_w(p));
1154 break;
1156 StringFromGUID2(&guid, comp, GUID_SIZE);
1157 r = MsiGetComponentPathW(szProduct, comp, NULL, 0);
1158 TRACE("component %s state %d\n", debugstr_guid(&guid), r);
1159 switch (r)
1161 case INSTALLSTATE_NOTUSED:
1162 case INSTALLSTATE_LOCAL:
1163 case INSTALLSTATE_SOURCE:
1164 break;
1165 default:
1166 missing = TRUE;
1170 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1171 msi_free(components);
1173 if (missing)
1174 return INSTALLSTATE_ADVERTISED;
1176 return INSTALLSTATE_LOCAL;
1179 /******************************************************************
1180 * MsiGetFileVersionA [MSI.@]
1182 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1183 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1185 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1186 UINT ret = ERROR_OUTOFMEMORY;
1188 if( szFilePath )
1190 szwFilePath = strdupAtoW( szFilePath );
1191 if( !szwFilePath )
1192 goto end;
1195 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1197 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1198 if( !lpwVersionBuff )
1199 goto end;
1202 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1204 lpwLangBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1205 if( !lpwLangBuff )
1206 goto end;
1209 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1210 lpwLangBuff, pcchLangBuf);
1212 if( lpwVersionBuff )
1213 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1214 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1215 if( lpwLangBuff )
1216 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1217 lpLangBuf, *pcchLangBuf, NULL, NULL);
1219 end:
1220 msi_free(szwFilePath);
1221 msi_free(lpwVersionBuff);
1222 msi_free(lpwLangBuff);
1224 return ret;
1227 /******************************************************************
1228 * MsiGetFileVersionW [MSI.@]
1230 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1231 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1233 static WCHAR szVersionResource[] = {'\\',0};
1234 static const WCHAR szVersionFormat[] = {
1235 '%','d','.','%','d','.','%','d','.','%','d',0};
1236 static const WCHAR szLangFormat[] = {'%','d',0};
1237 UINT ret = 0;
1238 DWORD dwVerLen;
1239 LPVOID lpVer = NULL;
1240 VS_FIXEDFILEINFO *ffi;
1241 UINT puLen;
1242 WCHAR tmp[32];
1244 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1245 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1246 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1248 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1249 if( !dwVerLen )
1250 return GetLastError();
1252 lpVer = msi_alloc(dwVerLen);
1253 if( !lpVer )
1255 ret = ERROR_OUTOFMEMORY;
1256 goto end;
1259 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1261 ret = GetLastError();
1262 goto end;
1264 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1266 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1267 (puLen > 0) )
1269 wsprintfW(tmp, szVersionFormat,
1270 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1271 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1272 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1273 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1275 else
1277 *lpVersionBuf = 0;
1278 *pcchVersionBuf = 0;
1282 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1284 DWORD lang = GetUserDefaultLangID();
1286 FIXME("Retrieve language from file\n");
1287 wsprintfW(tmp, szLangFormat, lang);
1288 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1289 *pcchLangBuf = lstrlenW(lpLangBuf);
1292 end:
1293 msi_free(lpVer);
1294 return ret;
1297 /***********************************************************************
1298 * MsiGetFeatureUsageW [MSI.@]
1300 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
1301 DWORD* pdwUseCount, WORD* pwDateUsed )
1303 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1304 pdwUseCount, pwDateUsed);
1305 return ERROR_CALL_NOT_IMPLEMENTED;
1308 /***********************************************************************
1309 * MsiGetFeatureUsageA [MSI.@]
1311 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
1312 DWORD* pdwUseCount, WORD* pwDateUsed )
1314 LPWSTR prod = NULL, feat = NULL;
1315 UINT ret = ERROR_OUTOFMEMORY;
1317 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1318 pdwUseCount, pwDateUsed);
1320 prod = strdupAtoW( szProduct );
1321 if (szProduct && !prod)
1322 goto end;
1324 feat = strdupAtoW( szFeature );
1325 if (szFeature && !feat)
1326 goto end;
1328 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
1330 end:
1331 msi_free( prod );
1332 msi_free( feat );
1334 return ret;
1337 /***********************************************************************
1338 * MsiUseFeatureExW [MSI.@]
1340 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
1341 DWORD dwInstallMode, DWORD dwReserved )
1343 INSTALLSTATE state;
1345 TRACE("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1346 dwInstallMode, dwReserved);
1348 state = MsiQueryFeatureStateW( szProduct, szFeature );
1350 if (dwReserved)
1351 return INSTALLSTATE_INVALIDARG;
1353 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
1355 FIXME("mark product %s feature %s as used\n",
1356 debugstr_w(szProduct), debugstr_w(szFeature) );
1359 return state;
1362 /***********************************************************************
1363 * MsiUseFeatureExA [MSI.@]
1365 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
1366 DWORD dwInstallMode, DWORD dwReserved )
1368 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
1369 LPWSTR prod = NULL, feat = NULL;
1371 TRACE("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1372 dwInstallMode, dwReserved);
1374 prod = strdupAtoW( szProduct );
1375 if (szProduct && !prod)
1376 goto end;
1378 feat = strdupAtoW( szFeature );
1379 if (szFeature && !feat)
1380 goto end;
1382 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
1384 end:
1385 msi_free( prod );
1386 msi_free( feat );
1388 return ret;
1391 /***********************************************************************
1392 * MsiUseFeatureW [MSI.@]
1394 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
1396 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
1399 /***********************************************************************
1400 * MsiUseFeatureA [MSI.@]
1402 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
1404 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
1407 /***********************************************************************
1408 * MSI_ProvideQualifiedComponentEx [internal]
1410 UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
1411 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1412 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
1413 DWORD* pcchPathBuf)
1415 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
1416 feature[MAX_FEATURE_CHARS+1];
1417 LPWSTR info;
1418 HKEY hkey;
1419 DWORD sz;
1420 UINT rc;
1422 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1423 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1424 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1426 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1427 if (rc != ERROR_SUCCESS)
1428 return ERROR_INDEX_ABSENT;
1430 info = msi_reg_get_val_str( hkey, szQualifier );
1431 RegCloseKey(hkey);
1433 if (!info)
1434 return ERROR_INDEX_ABSENT;
1436 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
1438 if (!szProduct)
1439 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
1440 else
1441 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
1444 if (rc != INSTALLSTATE_LOCAL)
1445 return ERROR_FILE_NOT_FOUND;
1447 return ERROR_SUCCESS;
1450 /***********************************************************************
1451 * MsiProvideQualifiedComponentExW [MSI.@]
1453 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1454 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1455 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1456 DWORD* pcchPathBuf)
1458 awstring path;
1460 path.unicode = TRUE;
1461 path.str.w = lpPathBuf;
1463 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
1464 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
1467 /***********************************************************************
1468 * MsiProvideQualifiedComponentExA [MSI.@]
1470 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
1471 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR szProduct,
1472 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
1473 DWORD* pcchPathBuf)
1475 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
1476 UINT r = ERROR_OUTOFMEMORY;
1477 awstring path;
1479 TRACE("%s %s %lu %s %lu %lu %p %p\n", debugstr_a(szComponent),
1480 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
1481 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1483 szwComponent = strdupAtoW( szComponent );
1484 if (szComponent && !szwComponent)
1485 goto end;
1487 szwQualifier = strdupAtoW( szQualifier );
1488 if (szQualifier && !szwQualifier)
1489 goto end;
1491 szwProduct = strdupAtoW( szProduct );
1492 if (szProduct && !szwProduct)
1493 goto end;
1495 path.unicode = FALSE;
1496 path.str.a = lpPathBuf;
1498 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
1499 dwInstallMode, szwProduct, Unused1,
1500 Unused2, &path, pcchPathBuf);
1501 end:
1502 msi_free(szwProduct);
1503 msi_free(szwComponent);
1504 msi_free(szwQualifier);
1506 return r;
1509 /***********************************************************************
1510 * MsiProvideQualifiedComponentW [MSI.@]
1512 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1513 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1514 DWORD* pcchPathBuf)
1516 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1517 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1520 /***********************************************************************
1521 * MsiProvideQualifiedComponentA [MSI.@]
1523 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1524 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1525 DWORD* pcchPathBuf)
1527 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
1528 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1531 /***********************************************************************
1532 * MSI_GetUserInfo [internal]
1534 USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
1535 awstring *lpUserNameBuf, DWORD* pcchUserNameBuf,
1536 awstring *lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1537 awstring *lpSerialBuf, DWORD* pcchSerialBuf)
1539 HKEY hkey;
1540 LPWSTR user, org, serial;
1541 UINT r;
1542 USERINFOSTATE state;
1544 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1545 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1546 pcchSerialBuf);
1548 if (!szProduct)
1549 return USERINFOSTATE_INVALIDARG;
1551 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1552 if (r != ERROR_SUCCESS)
1553 return USERINFOSTATE_UNKNOWN;
1555 user = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGOWNERW );
1556 org = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGCOMPANYW );
1557 serial = msi_reg_get_val_str( hkey, INSTALLPROPERTY_PRODUCTIDW );
1559 RegCloseKey(hkey);
1561 state = USERINFOSTATE_PRESENT;
1563 r = msi_strcpy_to_awstring( user, lpUserNameBuf, pcchUserNameBuf );
1564 if (r == ERROR_MORE_DATA)
1565 state = USERINFOSTATE_MOREDATA;
1566 r = msi_strcpy_to_awstring( org, lpOrgNameBuf, pcchOrgNameBuf );
1567 if (r == ERROR_MORE_DATA)
1568 state = USERINFOSTATE_MOREDATA;
1569 r = msi_strcpy_to_awstring( serial, lpSerialBuf, pcchSerialBuf );
1570 if (r == ERROR_MORE_DATA)
1571 state = USERINFOSTATE_MOREDATA;
1573 msi_free( user );
1574 msi_free( org );
1575 msi_free( serial );
1577 return state;
1580 /***********************************************************************
1581 * MsiGetUserInfoW [MSI.@]
1583 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
1584 LPWSTR lpUserNameBuf, DWORD* pcchUserNameBuf,
1585 LPWSTR lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1586 LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1588 awstring user, org, serial;
1590 user.unicode = TRUE;
1591 user.str.w = lpUserNameBuf;
1592 org.unicode = TRUE;
1593 org.str.w = lpOrgNameBuf;
1594 serial.unicode = TRUE;
1595 serial.str.w = lpSerialBuf;
1597 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
1598 &org, pcchOrgNameBuf,
1599 &serial, pcchSerialBuf );
1602 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
1603 LPSTR lpUserNameBuf, DWORD* pcchUserNameBuf,
1604 LPSTR lpOrgNameBuf, DWORD* pcchOrgNameBuf,
1605 LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1607 awstring user, org, serial;
1608 LPWSTR prod;
1609 UINT r;
1611 prod = strdupAtoW( szProduct );
1612 if (szProduct && !prod)
1613 return ERROR_OUTOFMEMORY;
1615 user.unicode = FALSE;
1616 user.str.a = lpUserNameBuf;
1617 org.unicode = FALSE;
1618 org.str.a = lpOrgNameBuf;
1619 serial.unicode = FALSE;
1620 serial.str.a = lpSerialBuf;
1622 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
1623 &org, pcchOrgNameBuf,
1624 &serial, pcchSerialBuf );
1626 msi_free( prod );
1628 return r;
1631 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1633 MSIHANDLE handle;
1634 UINT rc;
1635 MSIPACKAGE *package;
1636 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1638 TRACE("(%s)\n",debugstr_w(szProduct));
1640 rc = MsiOpenProductW(szProduct,&handle);
1641 if (rc != ERROR_SUCCESS)
1642 return ERROR_INVALID_PARAMETER;
1644 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1645 rc = ACTION_PerformUIAction(package, szFirstRun);
1646 msiobj_release( &package->hdr );
1648 MsiCloseHandle(handle);
1650 return rc;
1653 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1655 MSIHANDLE handle;
1656 UINT rc;
1657 MSIPACKAGE *package;
1658 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1660 TRACE("(%s)\n",debugstr_a(szProduct));
1662 rc = MsiOpenProductA(szProduct,&handle);
1663 if (rc != ERROR_SUCCESS)
1664 return ERROR_INVALID_PARAMETER;
1666 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1667 rc = ACTION_PerformUIAction(package, szFirstRun);
1668 msiobj_release( &package->hdr );
1670 MsiCloseHandle(handle);
1672 return rc;
1675 /***********************************************************************
1676 * MsiConfigureFeatureA [MSI.@]
1678 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
1680 LPWSTR prod, feat = NULL;
1681 UINT r = ERROR_OUTOFMEMORY;
1683 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
1685 prod = strdupAtoW( szProduct );
1686 if (szProduct && !prod)
1687 goto end;
1689 feat = strdupAtoW( szFeature );
1690 if (szFeature && !feat)
1691 goto end;
1693 r = MsiConfigureFeatureW(prod, feat, eInstallState);
1695 end:
1696 msi_free(feat);
1697 msi_free(prod);
1699 return r;
1702 /***********************************************************************
1703 * MsiConfigureFeatureW [MSI.@]
1705 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
1707 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
1708 MSIPACKAGE *package = NULL;
1709 UINT r;
1710 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
1711 DWORD sz;
1713 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
1715 if (!szProduct || !szFeature)
1716 return ERROR_INVALID_PARAMETER;
1718 switch (eInstallState)
1720 case INSTALLSTATE_DEFAULT:
1721 /* FIXME: how do we figure out the default location? */
1722 eInstallState = INSTALLSTATE_LOCAL;
1723 break;
1724 case INSTALLSTATE_LOCAL:
1725 case INSTALLSTATE_SOURCE:
1726 case INSTALLSTATE_ABSENT:
1727 case INSTALLSTATE_ADVERTISED:
1728 break;
1729 default:
1730 return ERROR_INVALID_PARAMETER;
1733 r = MSI_OpenProductW( szProduct, &package );
1734 if (r != ERROR_SUCCESS)
1735 return r;
1737 sz = sizeof(sourcepath);
1738 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1739 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
1741 sz = sizeof(filename);
1742 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1743 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1745 lstrcatW( sourcepath, filename );
1747 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
1749 r = ACTION_PerformUIAction( package, szCostInit );
1750 if (r != ERROR_SUCCESS)
1751 goto end;
1753 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
1754 if (r != ERROR_SUCCESS)
1755 goto end;
1757 r = MSI_InstallPackage( package, sourcepath, NULL );
1759 end:
1760 msiobj_release( &package->hdr );
1762 return r;
1765 /***********************************************************************
1766 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
1768 * Notes: undocumented
1770 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1772 WCHAR path[MAX_PATH];
1774 TRACE("%ld\n", dwReserved);
1776 if (dwReserved)
1778 FIXME("dwReserved=%ld\n", dwReserved);
1779 return ERROR_INVALID_PARAMETER;
1782 if (!GetWindowsDirectoryW(path, MAX_PATH))
1783 return ERROR_FUNCTION_FAILED;
1785 lstrcatW(path, installerW);
1787 if (!CreateDirectoryW(path, NULL))
1788 return ERROR_FUNCTION_FAILED;
1790 return ERROR_SUCCESS;
1793 /***********************************************************************
1794 * MsiGetShortcutTargetA [MSI.@]
1796 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1797 LPSTR szProductCode, LPSTR szFeatureId,
1798 LPSTR szComponentCode )
1800 LPWSTR target;
1801 const int len = MAX_FEATURE_CHARS+1;
1802 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
1803 UINT r;
1805 target = strdupAtoW( szShortcutTarget );
1806 if (szShortcutTarget && !target )
1807 return ERROR_OUTOFMEMORY;
1808 product[0] = 0;
1809 feature[0] = 0;
1810 component[0] = 0;
1811 r = MsiGetShortcutTargetW( target, product, feature, component );
1812 msi_free( target );
1813 if (r == ERROR_SUCCESS)
1815 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
1816 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
1817 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
1819 return r;
1822 /***********************************************************************
1823 * MsiGetShortcutTargetW [MSI.@]
1825 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1826 LPWSTR szProductCode, LPWSTR szFeatureId,
1827 LPWSTR szComponentCode )
1829 IShellLinkDataList *dl = NULL;
1830 IPersistFile *pf = NULL;
1831 LPEXP_DARWIN_LINK darwin = NULL;
1832 HRESULT r, init;
1834 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
1835 szProductCode, szFeatureId, szComponentCode );
1837 init = CoInitialize(NULL);
1839 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
1840 &IID_IPersistFile, (LPVOID*) &pf );
1841 if( SUCCEEDED( r ) )
1843 r = IPersistFile_Load( pf, szShortcutTarget,
1844 STGM_READ | STGM_SHARE_DENY_WRITE );
1845 if( SUCCEEDED( r ) )
1847 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
1848 (LPVOID*) &dl );
1849 if( SUCCEEDED( r ) )
1851 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
1852 (LPVOID) &darwin );
1853 IShellLinkDataList_Release( dl );
1856 IPersistFile_Release( pf );
1859 if (SUCCEEDED(init))
1860 CoUninitialize();
1862 TRACE("darwin = %p\n", darwin);
1864 if (darwin)
1866 DWORD sz;
1867 UINT ret;
1869 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
1870 szProductCode, szFeatureId, szComponentCode, &sz );
1871 LocalFree( darwin );
1872 return ret;
1875 return ERROR_FUNCTION_FAILED;
1878 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1879 DWORD dwReinstallMode )
1881 MSIPACKAGE* package = NULL;
1882 UINT r;
1883 WCHAR sourcepath[MAX_PATH];
1884 WCHAR filename[MAX_PATH];
1885 static const WCHAR szLogVerbose[] = {
1886 ' ','L','O','G','V','E','R','B','O','S','E',0 };
1887 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
1888 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
1889 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
1890 static const WCHAR szOne[] = {'1',0};
1891 WCHAR reinstallmode[11];
1892 LPWSTR ptr;
1893 DWORD sz;
1895 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1896 dwReinstallMode);
1898 ptr = reinstallmode;
1900 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
1901 *ptr++ = 'p';
1902 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
1903 *ptr++ = 'o';
1904 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
1905 *ptr++ = 'w';
1906 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
1907 *ptr++ = 'd';
1908 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
1909 *ptr++ = 'c';
1910 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
1911 *ptr++ = 'a';
1912 if (dwReinstallMode & REINSTALLMODE_USERDATA)
1913 *ptr++ = 'u';
1914 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
1915 *ptr++ = 'm';
1916 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
1917 *ptr++ = 's';
1918 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1919 *ptr++ = 'v';
1920 *ptr = 0;
1922 sz = sizeof(sourcepath);
1923 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1924 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
1926 sz = sizeof(filename);
1927 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERMANAGED,
1928 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
1930 lstrcatW( sourcepath, filename );
1932 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
1933 r = MSI_OpenPackageW( sourcepath, &package );
1934 else
1935 r = MSI_OpenProductW( szProduct, &package );
1937 if (r != ERROR_SUCCESS)
1938 return r;
1940 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
1941 MSI_SetPropertyW( package, szInstalled, szOne );
1942 MSI_SetPropertyW( package, szLogVerbose, szOne );
1943 MSI_SetPropertyW( package, szReinstall, szFeature );
1945 r = MSI_InstallPackage( package, sourcepath, NULL );
1947 msiobj_release( &package->hdr );
1949 return r;
1952 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1953 DWORD dwReinstallMode )
1955 LPWSTR wszProduct;
1956 LPWSTR wszFeature;
1957 UINT rc;
1959 TRACE("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1960 dwReinstallMode);
1962 wszProduct = strdupAtoW(szProduct);
1963 wszFeature = strdupAtoW(szFeature);
1965 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
1967 msi_free(wszProduct);
1968 msi_free(wszFeature);
1969 return rc;
1972 typedef struct
1974 unsigned int i[2];
1975 unsigned int buf[4];
1976 unsigned char in[64];
1977 unsigned char digest[16];
1978 } MD5_CTX;
1980 extern VOID WINAPI MD5Init( MD5_CTX *);
1981 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
1982 extern VOID WINAPI MD5Final( MD5_CTX *);
1984 /***********************************************************************
1985 * MsiGetFileHashW [MSI.@]
1987 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
1988 PMSIFILEHASHINFO pHash )
1990 HANDLE handle, mapping;
1991 void *p;
1992 DWORD length;
1993 UINT r = ERROR_FUNCTION_FAILED;
1995 TRACE("%s %08lx %p\n", debugstr_w(szFilePath), dwOptions, pHash );
1997 if (dwOptions)
1998 return ERROR_INVALID_PARAMETER;
1999 if (!pHash)
2000 return ERROR_INVALID_PARAMETER;
2001 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2002 return ERROR_INVALID_PARAMETER;
2004 handle = CreateFileW( szFilePath, GENERIC_READ,
2005 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2006 if (handle == INVALID_HANDLE_VALUE)
2007 return ERROR_FILE_NOT_FOUND;
2009 length = GetFileSize( handle, NULL );
2011 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2012 if (mapping)
2014 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2015 if (p)
2017 MD5_CTX ctx;
2019 MD5Init( &ctx );
2020 MD5Update( &ctx, p, length );
2021 MD5Final( &ctx );
2022 UnmapViewOfFile( p );
2024 memcpy( pHash->dwData, &ctx.digest, sizeof pHash->dwData );
2025 r = ERROR_SUCCESS;
2027 CloseHandle( mapping );
2029 CloseHandle( handle );
2031 return r;
2034 /***********************************************************************
2035 * MsiGetFileHashA [MSI.@]
2037 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2038 PMSIFILEHASHINFO pHash )
2040 LPWSTR file;
2041 UINT r;
2043 TRACE("%s %08lx %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2045 file = strdupAtoW( szFilePath );
2046 if (szFilePath && !file)
2047 return ERROR_OUTOFMEMORY;
2049 r = MsiGetFileHashW( file, dwOptions, pHash );
2050 msi_free( file );
2051 return r;
2054 /***********************************************************************
2055 * MsiAdvertiseScriptW [MSI.@]
2057 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2058 PHKEY phRegData, BOOL fRemoveItems )
2060 FIXME("%s %08lx %p %d\n",
2061 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2062 return ERROR_CALL_NOT_IMPLEMENTED;
2065 /***********************************************************************
2066 * MsiAdvertiseScriptA [MSI.@]
2068 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2069 PHKEY phRegData, BOOL fRemoveItems )
2071 FIXME("%s %08lx %p %d\n",
2072 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2073 return ERROR_CALL_NOT_IMPLEMENTED;