push a116a683330fd450d855d812b32928cd0eff60f8
[wine/hacks.git] / dlls / msi / msi.c
blob85446e87ee327c20150d9df254ed5b842633fa93
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 "msidefs.h"
34 #include "msiquery.h"
35 #include "msipriv.h"
36 #include "wincrypt.h"
37 #include "winver.h"
38 #include "winuser.h"
39 #include "shlobj.h"
40 #include "shobjidl.h"
41 #include "objidl.h"
42 #include "wine/unicode.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 if (! *phProduct)
128 r = ERROR_NOT_ENOUGH_MEMORY;
129 msiobj_release( &package->hdr );
131 return r;
134 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
135 LPCSTR szTransforms, LANGID lgidLanguage)
137 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
138 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
139 return ERROR_CALL_NOT_IMPLEMENTED;
142 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
143 LPCWSTR szTransforms, LANGID lgidLanguage)
145 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
146 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
147 return ERROR_CALL_NOT_IMPLEMENTED;
150 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
151 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
153 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
154 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
155 lgidLanguage, dwPlatform, dwOptions);
156 return ERROR_CALL_NOT_IMPLEMENTED;
159 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
160 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
162 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
163 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
164 lgidLanguage, dwPlatform, dwOptions);
165 return ERROR_CALL_NOT_IMPLEMENTED;
168 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
170 LPWSTR szwPath = NULL, szwCommand = NULL;
171 UINT r = ERROR_OUTOFMEMORY;
173 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
175 if( szPackagePath )
177 szwPath = strdupAtoW( szPackagePath );
178 if( !szwPath )
179 goto end;
182 if( szCommandLine )
184 szwCommand = strdupAtoW( szCommandLine );
185 if( !szwCommand )
186 goto end;
189 r = MsiInstallProductW( szwPath, szwCommand );
191 end:
192 msi_free( szwPath );
193 msi_free( szwCommand );
195 return r;
198 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
200 MSIPACKAGE *package = NULL;
201 UINT r;
203 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
205 r = MSI_OpenPackageW( szPackagePath, &package );
206 if (r == ERROR_SUCCESS)
208 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
209 msiobj_release( &package->hdr );
212 return r;
215 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
217 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
218 return ERROR_CALL_NOT_IMPLEMENTED;
221 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
223 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
224 return ERROR_CALL_NOT_IMPLEMENTED;
227 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
228 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
230 LPWSTR patch_package = NULL;
231 LPWSTR install_package = NULL;
232 LPWSTR command_line = NULL;
233 UINT r = ERROR_OUTOFMEMORY;
235 TRACE("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
236 eInstallType, debugstr_a(szCommandLine));
238 if (szPatchPackage && !(patch_package = strdupAtoW(szPatchPackage)))
239 goto done;
241 if (szInstallPackage && !(install_package = strdupAtoW(szInstallPackage)))
242 goto done;
244 if (szCommandLine && !(command_line = strdupAtoW(szCommandLine)))
245 goto done;
247 r = MsiApplyPatchW(patch_package, install_package, eInstallType, command_line);
249 done:
250 msi_free(patch_package);
251 msi_free(install_package);
252 msi_free(command_line);
254 return r;
257 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
258 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
260 MSIHANDLE patch, info;
261 UINT r, type;
262 DWORD size = 0;
263 LPCWSTR cmd_ptr = szCommandLine;
264 LPWSTR beg, end;
265 LPWSTR cmd = NULL, codes = NULL;
267 static const WCHAR space[] = {' ',0};
268 static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
269 static WCHAR empty[] = {0};
271 TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
272 eInstallType, debugstr_w(szCommandLine));
274 if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
275 eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
277 FIXME("Only reading target products from patch\n");
278 return ERROR_CALL_NOT_IMPLEMENTED;
281 r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
282 if (r != ERROR_SUCCESS)
283 return r;
285 r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
286 if (r != ERROR_SUCCESS)
287 goto done;
289 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
290 if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
292 ERR("Failed to read product codes from patch\n");
293 goto done;
296 codes = msi_alloc(++size * sizeof(WCHAR));
297 if (!codes)
299 r = ERROR_OUTOFMEMORY;
300 goto done;
303 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
304 if (r != ERROR_SUCCESS)
305 goto done;
307 if (!szCommandLine)
308 cmd_ptr = empty;
310 size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
311 cmd = msi_alloc(size * sizeof(WCHAR));
312 if (!cmd)
314 r = ERROR_OUTOFMEMORY;
315 goto done;
318 lstrcpyW(cmd, cmd_ptr);
319 if (szCommandLine) lstrcatW(cmd, space);
320 lstrcatW(cmd, patcheq);
321 lstrcatW(cmd, szPatchPackage);
323 beg = codes;
324 while ((end = strchrW(beg, '}')))
326 *(end + 1) = '\0';
328 r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
329 if (r != ERROR_SUCCESS)
330 goto done;
332 beg = end + 2;
335 done:
336 msi_free(cmd);
337 msi_free(codes);
339 MsiCloseHandle(info);
340 MsiCloseHandle(patch);
342 return r;
345 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
346 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
348 MSIPACKAGE* package = NULL;
349 UINT r;
350 DWORD sz;
351 WCHAR sourcepath[MAX_PATH];
352 WCHAR filename[MAX_PATH];
353 static const WCHAR szInstalled[] = {
354 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
355 LPWSTR commandline;
357 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
358 debugstr_w(szCommandLine));
360 if (eInstallState != INSTALLSTATE_LOCAL &&
361 eInstallState != INSTALLSTATE_DEFAULT)
363 FIXME("Not implemented for anything other than local installs\n");
364 return ERROR_CALL_NOT_IMPLEMENTED;
367 sz = sizeof(sourcepath);
368 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
369 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath,
370 &sz);
372 sz = sizeof(filename);
373 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
374 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
376 lstrcatW(sourcepath,filename);
379 * ok 1, we need to find the msi file for this product.
380 * 2, find the source dir for the files
381 * 3, do the configure/install.
382 * 4, cleanupany runonce entry.
385 r = MSI_OpenProductW( szProduct, &package );
386 if (r != ERROR_SUCCESS)
387 return r;
389 sz = lstrlenW(szInstalled) + 1;
391 if (szCommandLine)
392 sz += lstrlenW(szCommandLine);
394 commandline = msi_alloc(sz * sizeof(WCHAR));
395 if (!commandline )
397 r = ERROR_OUTOFMEMORY;
398 goto end;
401 commandline[0] = 0;
402 if (szCommandLine)
403 lstrcpyW(commandline,szCommandLine);
405 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
406 lstrcatW(commandline,szInstalled);
408 r = MSI_InstallPackage( package, sourcepath, commandline );
410 msi_free(commandline);
412 end:
413 msiobj_release( &package->hdr );
415 return r;
418 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
419 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
421 LPWSTR szwProduct = NULL;
422 LPWSTR szwCommandLine = NULL;
423 UINT r = ERROR_OUTOFMEMORY;
425 if( szProduct )
427 szwProduct = strdupAtoW( szProduct );
428 if( !szwProduct )
429 goto end;
432 if( szCommandLine)
434 szwCommandLine = strdupAtoW( szCommandLine );
435 if( !szwCommandLine)
436 goto end;
439 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
440 szwCommandLine );
441 end:
442 msi_free( szwProduct );
443 msi_free( szwCommandLine);
445 return r;
448 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
449 INSTALLSTATE eInstallState)
451 LPWSTR szwProduct = NULL;
452 UINT r;
454 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
456 if( szProduct )
458 szwProduct = strdupAtoW( szProduct );
459 if( !szwProduct )
460 return ERROR_OUTOFMEMORY;
463 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
464 msi_free( szwProduct );
466 return r;
469 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
470 INSTALLSTATE eInstallState)
472 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
475 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
477 LPWSTR szwComponent = NULL;
478 UINT r;
479 WCHAR szwBuffer[GUID_SIZE];
481 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
483 if( szComponent )
485 szwComponent = strdupAtoW( szComponent );
486 if( !szwComponent )
487 return ERROR_OUTOFMEMORY;
490 *szwBuffer = '\0';
491 r = MsiGetProductCodeW( szwComponent, szwBuffer );
493 if(*szwBuffer)
494 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
496 msi_free( szwComponent );
498 return r;
501 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
503 UINT rc, index;
504 HKEY compkey, prodkey;
505 WCHAR squished_comp[GUID_SIZE];
506 WCHAR squished_prod[GUID_SIZE];
507 DWORD sz = GUID_SIZE;
509 TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
511 if (!szComponent || !*szComponent)
512 return ERROR_INVALID_PARAMETER;
514 if (!squash_guid(szComponent, squished_comp))
515 return ERROR_INVALID_PARAMETER;
517 if (MSIREG_OpenUserDataComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS &&
518 MSIREG_OpenLocalSystemComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS)
520 return ERROR_UNKNOWN_COMPONENT;
523 rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
524 if (rc != ERROR_SUCCESS)
526 RegCloseKey(compkey);
527 return ERROR_UNKNOWN_COMPONENT;
530 /* check simple case, only one product */
531 rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
532 if (rc == ERROR_NO_MORE_ITEMS)
534 rc = ERROR_SUCCESS;
535 goto done;
538 index = 0;
539 while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
540 NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
542 index++;
543 sz = GUID_SIZE;
544 unsquash_guid(squished_prod, szBuffer);
546 if (MSIREG_OpenLocalManagedProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
547 MSIREG_OpenUserProductsKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
548 MSIREG_OpenLocalClassesProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS)
550 RegCloseKey(prodkey);
551 rc = ERROR_SUCCESS;
552 goto done;
556 rc = ERROR_INSTALL_FAILURE;
558 done:
559 RegCloseKey(compkey);
560 unsquash_guid(squished_prod, szBuffer);
561 return rc;
564 static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
566 DWORD dval;
567 LONG res;
568 WCHAR temp[20];
570 static const WCHAR format[] = {'%','d',0};
572 res = RegQueryValueExW(hkey, name, NULL, type, NULL, NULL);
573 if (res != ERROR_SUCCESS)
574 return NULL;
576 if (*type == REG_SZ)
577 return msi_reg_get_val_str(hkey, name);
579 if (!msi_reg_get_val_dword(hkey, name, &dval))
580 return NULL;
582 sprintfW(temp, format, dval);
583 return strdupW(temp);
586 static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
587 awstring *szValue, LPDWORD pcchValueBuf)
589 UINT r = ERROR_UNKNOWN_PROPERTY;
590 HKEY prodkey, userdata, source;
591 LPWSTR val = NULL;
592 WCHAR squished_pc[GUID_SIZE];
593 WCHAR packagecode[GUID_SIZE];
594 BOOL classes = FALSE;
595 BOOL badconfig = FALSE;
596 LONG res;
597 DWORD save, type = REG_NONE;
599 static WCHAR empty[] = {0};
600 static const WCHAR sourcelist[] = {
601 'S','o','u','r','c','e','L','i','s','t',0};
602 static const WCHAR display_name[] = {
603 'D','i','s','p','l','a','y','N','a','m','e',0};
604 static const WCHAR display_version[] = {
605 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
606 static const WCHAR assignment[] = {
607 'A','s','s','i','g','n','m','e','n','t',0};
609 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
610 debugstr_w(szAttribute), szValue, pcchValueBuf);
612 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
613 return ERROR_INVALID_PARAMETER;
615 if (!squash_guid(szProduct, squished_pc))
616 return ERROR_INVALID_PARAMETER;
618 r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
619 if (r != ERROR_SUCCESS)
621 r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
622 if (r != ERROR_SUCCESS)
624 r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
625 if (r == ERROR_SUCCESS)
626 classes = TRUE;
630 if (classes)
631 MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
632 else
633 MSIREG_OpenInstallPropertiesKey(szProduct, &userdata, FALSE);
635 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
636 !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
637 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
638 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
639 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
640 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
641 !lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
642 !lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
643 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
644 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
645 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
646 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
647 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
648 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
649 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
650 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
652 if (!prodkey)
654 r = ERROR_UNKNOWN_PRODUCT;
655 goto done;
658 if (!userdata)
659 return ERROR_UNKNOWN_PROPERTY;
661 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
662 szAttribute = display_name;
663 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
664 szAttribute = display_version;
666 val = msi_reg_get_value(userdata, szAttribute, &type);
667 if (!val)
668 val = empty;
670 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
671 !lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
672 !lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
673 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
674 !lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
675 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
676 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
677 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
678 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
679 !lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
681 if (!prodkey)
683 r = ERROR_UNKNOWN_PRODUCT;
684 goto done;
687 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
688 szAttribute = assignment;
690 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
692 res = RegOpenKeyW(prodkey, sourcelist, &source);
693 if (res == ERROR_SUCCESS)
694 val = msi_reg_get_value(source, szAttribute, &type);
696 RegCloseKey(source);
698 else
700 val = msi_reg_get_value(prodkey, szAttribute, &type);
701 if (!val)
702 val = empty;
705 if (val != empty && type != REG_DWORD &&
706 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
708 if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
709 badconfig = TRUE;
710 else
712 unsquash_guid(val, packagecode);
713 msi_free(val);
714 val = strdupW(packagecode);
719 if (!val)
721 r = ERROR_UNKNOWN_PROPERTY;
722 goto done;
725 save = *pcchValueBuf;
727 if (lstrlenW(val) < *pcchValueBuf)
728 r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
729 else if (szValue->str.a || szValue->str.w)
730 r = ERROR_MORE_DATA;
732 if (!badconfig)
733 *pcchValueBuf = lstrlenW(val);
734 else if (r == ERROR_SUCCESS)
736 *pcchValueBuf = save;
737 r = ERROR_BAD_CONFIGURATION;
740 if (val != empty)
741 msi_free(val);
743 done:
744 RegCloseKey(prodkey);
745 RegCloseKey(userdata);
746 return r;
749 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
750 LPSTR szBuffer, LPDWORD pcchValueBuf)
752 LPWSTR szwProduct, szwAttribute = NULL;
753 UINT r = ERROR_OUTOFMEMORY;
754 awstring buffer;
756 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
757 szBuffer, pcchValueBuf);
759 szwProduct = strdupAtoW( szProduct );
760 if( szProduct && !szwProduct )
761 goto end;
763 szwAttribute = strdupAtoW( szAttribute );
764 if( szAttribute && !szwAttribute )
765 goto end;
767 buffer.unicode = FALSE;
768 buffer.str.a = szBuffer;
770 r = MSI_GetProductInfo( szwProduct, szwAttribute,
771 &buffer, pcchValueBuf );
773 end:
774 msi_free( szwProduct );
775 msi_free( szwAttribute );
777 return r;
780 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
781 LPWSTR szBuffer, LPDWORD pcchValueBuf)
783 awstring buffer;
785 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
786 szBuffer, pcchValueBuf);
788 buffer.unicode = TRUE;
789 buffer.str.w = szBuffer;
791 return MSI_GetProductInfo( szProduct, szAttribute,
792 &buffer, pcchValueBuf );
795 UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid,
796 MSIINSTALLCONTEXT dwContext, LPCSTR szProperty,
797 LPSTR szValue, LPDWORD pcchValue)
799 LPWSTR product = NULL;
800 LPWSTR usersid = NULL;
801 LPWSTR property = NULL;
802 LPWSTR value = NULL;
803 DWORD len = 0;
804 UINT r;
806 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_a(szProductCode),
807 debugstr_a(szUserSid), dwContext, debugstr_a(szProperty),
808 szValue, pcchValue);
810 if (szValue && !pcchValue)
811 return ERROR_INVALID_PARAMETER;
813 if (szProductCode) product = strdupAtoW(szProductCode);
814 if (szUserSid) usersid = strdupAtoW(szUserSid);
815 if (szProperty) property = strdupAtoW(szProperty);
817 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
818 NULL, &len);
819 if (r != ERROR_SUCCESS)
820 goto done;
822 value = msi_alloc(++len * sizeof(WCHAR));
823 if (!value)
825 r = ERROR_OUTOFMEMORY;
826 goto done;
829 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
830 value, &len);
831 if (r != ERROR_SUCCESS)
832 goto done;
834 if (!pcchValue)
835 goto done;
837 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
838 if (*pcchValue >= len)
839 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
840 else if (szValue)
842 r = ERROR_MORE_DATA;
843 if (*pcchValue > 0)
844 *szValue = '\0';
847 if (*pcchValue <= len || !szValue)
848 len = len * sizeof(WCHAR) - 1;
850 *pcchValue = len - 1;
852 done:
853 msi_free(product);
854 msi_free(usersid);
855 msi_free(property);
856 msi_free(value);
858 return r;
861 static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
863 UINT r;
865 if (!val)
866 return ERROR_UNKNOWN_PROPERTY;
868 if (out)
870 if (lstrlenW(val) >= *size)
872 r = ERROR_MORE_DATA;
873 if (*size > 0)
874 *out = '\0';
876 else
877 lstrcpyW(out, val);
880 if (size)
881 *size = lstrlenW(val);
883 return ERROR_SUCCESS;
886 UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
887 MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty,
888 LPWSTR szValue, LPDWORD pcchValue)
890 WCHAR squished_pc[GUID_SIZE];
891 LPWSTR val = NULL;
892 LPCWSTR package = NULL;
893 HKEY props = NULL, prod;
894 HKEY classes = NULL, managed;
895 HKEY hkey = NULL;
896 DWORD type;
897 UINT r = ERROR_UNKNOWN_PRODUCT;
899 static const WCHAR one[] = {'1',0};
900 static const WCHAR five[] = {'5',0};
901 static const WCHAR empty[] = {0};
902 static const WCHAR displayname[] = {
903 'D','i','s','p','l','a','y','N','a','m','e',0};
904 static const WCHAR displayversion[] = {
905 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
906 static const WCHAR managed_local_package[] = {
907 'M','a','n','a','g','e','d','L','o','c','a','l',
908 'P','a','c','k','a','g','e',0};
910 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_w(szProductCode),
911 debugstr_w(szUserSid), dwContext, debugstr_w(szProperty),
912 szValue, pcchValue);
914 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
915 return ERROR_INVALID_PARAMETER;
917 if (szValue && !pcchValue)
918 return ERROR_INVALID_PARAMETER;
920 if (dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
921 dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
922 dwContext != MSIINSTALLCONTEXT_MACHINE)
923 return ERROR_INVALID_PARAMETER;
925 if (!szProperty || !*szProperty)
926 return ERROR_INVALID_PARAMETER;
928 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
929 return ERROR_INVALID_PARAMETER;
931 MSIREG_OpenLocalManagedProductKey(szProductCode, &managed, FALSE);
932 MSIREG_OpenUserProductsKey(szProductCode, &prod, FALSE);
934 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
936 package = INSTALLPROPERTY_LOCALPACKAGEW;
937 MSIREG_OpenInstallPropertiesKey(szProductCode, &props, FALSE);
939 if (!props && !prod)
940 goto done;
942 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
944 package = managed_local_package;
945 MSIREG_OpenInstallPropertiesKey(szProductCode, &props, FALSE);
947 if (!props && !managed)
948 goto done;
950 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
952 package = INSTALLPROPERTY_LOCALPACKAGEW;
953 MSIREG_OpenLocalSystemProductKey(szProductCode, &props, FALSE);
954 MSIREG_OpenLocalClassesProductKey(szProductCode, &classes, FALSE);
956 if (!props && !classes)
957 goto done;
960 if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) ||
961 !lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) ||
962 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) ||
963 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
964 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) ||
965 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) ||
966 !lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) ||
967 !lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) ||
968 !lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) ||
969 !lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) ||
970 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) ||
971 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) ||
972 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) ||
973 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) ||
974 !lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) ||
975 !lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) ||
976 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW))
978 val = msi_reg_get_value(props, package, &type);
979 if (!val)
981 if (prod || classes)
982 r = ERROR_UNKNOWN_PROPERTY;
984 goto done;
987 msi_free(val);
989 if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
990 szProperty = displayname;
991 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW))
992 szProperty = displayversion;
994 val = msi_reg_get_value(props, szProperty, &type);
995 if (!val)
996 val = strdupW(empty);
998 r = msi_copy_outval(val, szValue, pcchValue);
1000 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
1001 !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
1002 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
1003 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
1004 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
1005 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
1006 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
1007 !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
1009 if (!prod && !classes)
1010 goto done;
1012 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1013 hkey = prod;
1014 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1015 hkey = managed;
1016 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1017 hkey = classes;
1019 val = msi_reg_get_value(hkey, szProperty, &type);
1020 if (!val)
1021 val = strdupW(empty);
1023 r = msi_copy_outval(val, szValue, pcchValue);
1025 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
1027 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1029 if (props)
1031 val = msi_reg_get_value(props, package, &type);
1032 if (!val)
1033 goto done;
1035 msi_free(val);
1036 val = strdupW(five);
1038 else
1039 val = strdupW(one);
1041 r = msi_copy_outval(val, szValue, pcchValue);
1042 goto done;
1044 else if (props && (val = msi_reg_get_value(props, package, &type)))
1046 msi_free(val);
1047 val = strdupW(five);
1048 r = msi_copy_outval(val, szValue, pcchValue);
1049 goto done;
1052 if (prod || managed)
1053 val = strdupW(one);
1054 else
1055 goto done;
1057 r = msi_copy_outval(val, szValue, pcchValue);
1059 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
1061 if (!prod && !classes)
1062 goto done;
1064 /* FIME */
1065 val = strdupW(empty);
1066 r = msi_copy_outval(val, szValue, pcchValue);
1068 else
1069 r = ERROR_UNKNOWN_PROPERTY;
1071 done:
1072 RegCloseKey(props);
1073 RegCloseKey(prod);
1074 RegCloseKey(managed);
1075 RegCloseKey(classes);
1076 msi_free(val);
1078 return r;
1081 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
1083 LPWSTR szwLogFile = NULL;
1084 UINT r;
1086 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
1088 if( szLogFile )
1090 szwLogFile = strdupAtoW( szLogFile );
1091 if( !szwLogFile )
1092 return ERROR_OUTOFMEMORY;
1094 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
1095 msi_free( szwLogFile );
1096 return r;
1099 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
1101 HANDLE file = INVALID_HANDLE_VALUE;
1103 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
1105 if (szLogFile)
1107 lstrcpyW(gszLogFile,szLogFile);
1108 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
1109 DeleteFileW(szLogFile);
1110 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
1111 FILE_ATTRIBUTE_NORMAL, NULL);
1112 if (file != INVALID_HANDLE_VALUE)
1113 CloseHandle(file);
1114 else
1115 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
1117 else
1118 gszLogFile[0] = '\0';
1120 return ERROR_SUCCESS;
1123 UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
1124 DWORD dwIndex, INSTALLSTATE iState,
1125 LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
1126 int *piCost, int *pTempCost)
1128 FIXME("(%ld, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
1129 debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
1130 pcchDriveBuf, piCost, pTempCost);
1132 return ERROR_NO_MORE_ITEMS;
1135 UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
1136 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1137 LPCSTR szComponent, INSTALLSTATE *pdwState)
1139 LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
1140 UINT r;
1142 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
1143 debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
1145 if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
1146 return ERROR_OUTOFMEMORY;
1148 if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
1149 return ERROR_OUTOFMEMORY;
1151 if (szComponent && !(comp = strdupAtoW(szComponent)))
1152 return ERROR_OUTOFMEMORY;
1154 r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
1156 msi_free(prodcode);
1157 msi_free(usersid);
1158 msi_free(comp);
1160 return r;
1163 static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1165 UINT r;
1166 HKEY hkey;
1168 if (context == MSIINSTALLCONTEXT_MACHINE)
1169 r = MSIREG_OpenLocalClassesProductKey(prodcode, &hkey, FALSE);
1170 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
1171 r = MSIREG_OpenUserProductsKey(prodcode, &hkey, FALSE);
1172 else
1173 r = MSIREG_OpenLocalManagedProductKey(prodcode, &hkey, FALSE);
1175 RegCloseKey(hkey);
1176 return (r == ERROR_SUCCESS);
1179 static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1181 LPCWSTR package;
1182 HKEY hkey;
1183 DWORD sz;
1184 LONG res;
1185 UINT r;
1187 static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
1188 static const WCHAR managed_local_package[] = {
1189 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
1192 if (context == MSIINSTALLCONTEXT_MACHINE)
1193 r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
1194 else
1195 r = MSIREG_OpenInstallPropertiesKey(prodcode, &hkey, FALSE);
1197 if (r != ERROR_SUCCESS)
1198 return FALSE;
1200 if (context == MSIINSTALLCONTEXT_USERMANAGED)
1201 package = managed_local_package;
1202 else
1203 package = local_package;
1205 sz = 0;
1206 res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
1207 RegCloseKey(hkey);
1209 return (res == ERROR_SUCCESS);
1212 static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
1213 MSIINSTALLCONTEXT context,
1214 LPCWSTR comp, DWORD *sz)
1216 HKEY hkey;
1217 LONG res;
1218 UINT r;
1220 if (context == MSIINSTALLCONTEXT_MACHINE)
1221 r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
1222 else
1223 r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1225 if (r != ERROR_SUCCESS)
1226 return FALSE;
1228 *sz = 0;
1229 res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, sz);
1230 if (res != ERROR_SUCCESS)
1231 return FALSE;
1233 RegCloseKey(hkey);
1234 return TRUE;
1237 UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
1238 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1239 LPCWSTR szComponent, INSTALLSTATE *pdwState)
1241 WCHAR squished_pc[GUID_SIZE];
1242 BOOL found;
1243 DWORD sz;
1245 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
1246 debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
1248 if (!pdwState)
1249 return ERROR_INVALID_PARAMETER;
1251 if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
1252 return ERROR_INVALID_PARAMETER;
1254 if (!squash_guid(szProductCode, squished_pc))
1255 return ERROR_INVALID_PARAMETER;
1257 found = msi_comp_find_prod_key(szProductCode, dwContext);
1259 if (!msi_comp_find_package(szProductCode, dwContext))
1261 if (found)
1263 *pdwState = INSTALLSTATE_UNKNOWN;
1264 return ERROR_UNKNOWN_COMPONENT;
1267 return ERROR_UNKNOWN_PRODUCT;
1270 *pdwState = INSTALLSTATE_UNKNOWN;
1272 if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, &sz))
1273 return ERROR_UNKNOWN_COMPONENT;
1275 if (sz == 0)
1276 *pdwState = INSTALLSTATE_NOTUSED;
1277 else
1278 *pdwState = INSTALLSTATE_LOCAL;
1280 return ERROR_SUCCESS;
1283 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
1285 LPWSTR szwProduct = NULL;
1286 INSTALLSTATE r;
1288 if( szProduct )
1290 szwProduct = strdupAtoW( szProduct );
1291 if( !szwProduct )
1292 return ERROR_OUTOFMEMORY;
1294 r = MsiQueryProductStateW( szwProduct );
1295 msi_free( szwProduct );
1296 return r;
1299 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
1301 UINT rc;
1302 INSTALLSTATE state = INSTALLSTATE_UNKNOWN;
1303 HKEY hkey = 0, props = 0;
1304 DWORD sz;
1305 BOOL userkey_exists = FALSE;
1307 static const int GUID_LEN = 38;
1308 static const WCHAR szInstallProperties[] = {
1309 'I','n','s','t','a','l','l','P','r','o','p','e','r','t','i','e','s',0
1311 static const WCHAR szWindowsInstaller[] = {
1312 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0
1315 TRACE("%s\n", debugstr_w(szProduct));
1317 if (!szProduct || !*szProduct || lstrlenW(szProduct) != GUID_LEN)
1318 return INSTALLSTATE_INVALIDARG;
1320 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
1321 if (rc == ERROR_SUCCESS)
1323 userkey_exists = TRUE;
1324 state = INSTALLSTATE_ADVERTISED;
1325 RegCloseKey(hkey);
1328 rc = MSIREG_OpenUserDataProductKey(szProduct,&hkey,FALSE);
1329 if (rc != ERROR_SUCCESS)
1330 goto end;
1332 rc = RegOpenKeyW(hkey, szInstallProperties, &props);
1333 if (rc != ERROR_SUCCESS)
1334 goto end;
1336 sz = sizeof(state);
1337 rc = RegQueryValueExW(props,szWindowsInstaller,NULL,NULL,(LPVOID)&state, &sz);
1338 if (rc != ERROR_SUCCESS)
1339 goto end;
1341 if (state)
1342 state = INSTALLSTATE_DEFAULT;
1343 else
1344 state = INSTALLSTATE_UNKNOWN;
1346 if (state == INSTALLSTATE_DEFAULT && !userkey_exists)
1347 state = INSTALLSTATE_ABSENT;
1349 end:
1350 RegCloseKey(props);
1351 RegCloseKey(hkey);
1352 return state;
1355 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
1357 INSTALLUILEVEL old = gUILevel;
1358 HWND oldwnd = gUIhwnd;
1360 TRACE("%08x %p\n", dwUILevel, phWnd);
1362 gUILevel = dwUILevel;
1363 if (phWnd)
1365 gUIhwnd = *phWnd;
1366 *phWnd = oldwnd;
1368 return old;
1371 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
1372 DWORD dwMessageFilter, LPVOID pvContext)
1374 INSTALLUI_HANDLERA prev = gUIHandlerA;
1376 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
1377 gUIHandlerA = puiHandler;
1378 gUIFilter = dwMessageFilter;
1379 gUIContext = pvContext;
1381 return prev;
1384 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
1385 DWORD dwMessageFilter, LPVOID pvContext)
1387 INSTALLUI_HANDLERW prev = gUIHandlerW;
1389 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
1390 gUIHandlerW = puiHandler;
1391 gUIFilter = dwMessageFilter;
1392 gUIContext = pvContext;
1394 return prev;
1397 /******************************************************************
1398 * MsiLoadStringW [MSI.@]
1400 * Loads a string from MSI's string resources.
1402 * PARAMS
1404 * handle [I] only -1 is handled currently
1405 * id [I] id of the string to be loaded
1406 * lpBuffer [O] buffer for the string to be written to
1407 * nBufferMax [I] maximum size of the buffer in characters
1408 * lang [I] the preferred language for the string
1410 * RETURNS
1412 * If successful, this function returns the language id of the string loaded
1413 * If the function fails, the function returns zero.
1415 * NOTES
1417 * The type of the first parameter is unknown. LoadString's prototype
1418 * suggests that it might be a module handle. I have made it an MSI handle
1419 * for starters, as -1 is an invalid MSI handle, but not an invalid module
1420 * handle. Maybe strings can be stored in an MSI database somehow.
1422 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
1423 int nBufferMax, LANGID lang )
1425 HRSRC hres;
1426 HGLOBAL hResData;
1427 LPWSTR p;
1428 DWORD i, len;
1430 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
1432 if( handle != -1 )
1433 FIXME("don't know how to deal with handle = %08lx\n", handle);
1435 if( !lang )
1436 lang = GetUserDefaultLangID();
1438 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
1439 (LPWSTR)1, lang );
1440 if( !hres )
1441 return 0;
1442 hResData = LoadResource( msi_hInstance, hres );
1443 if( !hResData )
1444 return 0;
1445 p = LockResource( hResData );
1446 if( !p )
1447 return 0;
1449 for (i = 0; i < (id&0xf); i++)
1450 p += *p + 1;
1451 len = *p;
1453 if( nBufferMax <= len )
1454 return 0;
1456 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
1457 lpBuffer[ len ] = 0;
1459 TRACE("found -> %s\n", debugstr_w(lpBuffer));
1461 return lang;
1464 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
1465 int nBufferMax, LANGID lang )
1467 LPWSTR bufW;
1468 LANGID r;
1469 DWORD len;
1471 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
1472 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
1473 if( r )
1475 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
1476 if( len <= nBufferMax )
1477 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
1478 lpBuffer, nBufferMax, NULL, NULL );
1479 else
1480 r = 0;
1482 msi_free(bufW);
1483 return r;
1486 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
1487 LPDWORD pcchBuf)
1489 char szProduct[GUID_SIZE];
1491 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
1493 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
1494 return INSTALLSTATE_UNKNOWN;
1496 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
1499 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
1500 LPDWORD pcchBuf)
1502 WCHAR szProduct[GUID_SIZE];
1504 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
1506 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
1507 return INSTALLSTATE_UNKNOWN;
1509 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
1512 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
1513 WORD wLanguageId, DWORD f)
1515 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
1516 uType, wLanguageId, f);
1517 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
1520 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
1521 WORD wLanguageId, DWORD f)
1523 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
1524 uType, wLanguageId, f);
1525 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
1528 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
1529 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
1530 LPDWORD pcchPathBuf )
1532 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
1533 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1534 pcchPathBuf);
1535 return ERROR_CALL_NOT_IMPLEMENTED;
1538 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
1539 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
1540 LPDWORD pcchPathBuf )
1542 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
1543 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1544 pcchPathBuf);
1545 return ERROR_CALL_NOT_IMPLEMENTED;
1548 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
1549 LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1551 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
1552 return ERROR_CALL_NOT_IMPLEMENTED;
1555 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
1556 LPWSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1558 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
1559 return ERROR_CALL_NOT_IMPLEMENTED;
1562 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
1563 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1564 LPDWORD pcbHashData)
1566 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
1567 ppcCertContext, pbHashData, pcbHashData);
1568 return ERROR_CALL_NOT_IMPLEMENTED;
1571 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1572 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1573 LPDWORD pcbHashData)
1575 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1576 ppcCertContext, pbHashData, pcbHashData);
1577 return ERROR_CALL_NOT_IMPLEMENTED;
1580 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
1581 LPSTR szValue, LPDWORD pccbValue )
1583 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
1584 return ERROR_CALL_NOT_IMPLEMENTED;
1587 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
1588 LPWSTR szValue, LPDWORD pccbValue )
1590 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
1591 return ERROR_CALL_NOT_IMPLEMENTED;
1594 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
1596 UINT r;
1597 LPWSTR szPack = NULL;
1599 TRACE("%s\n", debugstr_a(szPackage) );
1601 if( szPackage )
1603 szPack = strdupAtoW( szPackage );
1604 if( !szPack )
1605 return ERROR_OUTOFMEMORY;
1608 r = MsiVerifyPackageW( szPack );
1610 msi_free( szPack );
1612 return r;
1615 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
1617 MSIHANDLE handle;
1618 UINT r;
1620 TRACE("%s\n", debugstr_w(szPackage) );
1622 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
1623 MsiCloseHandle( handle );
1625 return r;
1628 static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
1629 awstring* lpPathBuf, LPDWORD pcchBuf)
1631 WCHAR squished_pc[GUID_SIZE];
1632 WCHAR squished_comp[GUID_SIZE];
1633 HKEY hkey;
1634 LPWSTR path = NULL;
1635 INSTALLSTATE state;
1636 DWORD version;
1638 static const WCHAR wininstaller[] = {
1639 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1641 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1642 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
1644 if (!szProduct || !szComponent)
1645 return INSTALLSTATE_INVALIDARG;
1647 if (lpPathBuf->str.w && !pcchBuf)
1648 return INSTALLSTATE_INVALIDARG;
1650 if (!squash_guid(szProduct, squished_pc) ||
1651 !squash_guid(szComponent, squished_comp))
1652 return INSTALLSTATE_INVALIDARG;
1654 state = INSTALLSTATE_UNKNOWN;
1656 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1657 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1659 path = msi_reg_get_val_str(hkey, squished_pc);
1660 RegCloseKey(hkey);
1662 state = INSTALLSTATE_ABSENT;
1664 if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1665 MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
1666 msi_reg_get_val_dword(hkey, wininstaller, &version) &&
1667 GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1669 RegCloseKey(hkey);
1670 state = INSTALLSTATE_LOCAL;
1674 if (state != INSTALLSTATE_LOCAL &&
1675 (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1676 MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS))
1678 RegCloseKey(hkey);
1680 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1681 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1683 msi_free(path);
1684 path = msi_reg_get_val_str(hkey, squished_pc);
1685 RegCloseKey(hkey);
1687 state = INSTALLSTATE_ABSENT;
1689 if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1690 state = INSTALLSTATE_LOCAL;
1694 if (!path)
1695 return INSTALLSTATE_UNKNOWN;
1697 if (state == INSTALLSTATE_LOCAL && !*path)
1698 state = INSTALLSTATE_NOTUSED;
1700 msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
1701 msi_free(path);
1702 return state;
1705 /******************************************************************
1706 * MsiGetComponentPathW [MSI.@]
1708 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1709 LPWSTR lpPathBuf, LPDWORD pcchBuf)
1711 awstring path;
1713 path.unicode = TRUE;
1714 path.str.w = lpPathBuf;
1716 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1719 /******************************************************************
1720 * MsiGetComponentPathA [MSI.@]
1722 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1723 LPSTR lpPathBuf, LPDWORD pcchBuf)
1725 LPWSTR szwProduct, szwComponent = NULL;
1726 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1727 awstring path;
1729 szwProduct = strdupAtoW( szProduct );
1730 if( szProduct && !szwProduct)
1731 goto end;
1733 szwComponent = strdupAtoW( szComponent );
1734 if( szComponent && !szwComponent )
1735 goto end;
1737 path.unicode = FALSE;
1738 path.str.a = lpPathBuf;
1740 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1742 end:
1743 msi_free( szwProduct );
1744 msi_free( szwComponent );
1746 return r;
1749 /******************************************************************
1750 * MsiQueryFeatureStateA [MSI.@]
1752 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1754 LPWSTR szwProduct = NULL, szwFeature= NULL;
1755 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1757 szwProduct = strdupAtoW( szProduct );
1758 if ( szProduct && !szwProduct )
1759 goto end;
1761 szwFeature = strdupAtoW( szFeature );
1762 if ( szFeature && !szwFeature )
1763 goto end;
1765 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1767 end:
1768 msi_free( szwProduct);
1769 msi_free( szwFeature);
1771 return rc;
1774 /******************************************************************
1775 * MsiQueryFeatureStateW [MSI.@]
1777 * Checks the state of a feature
1779 * PARAMS
1780 * szProduct [I] Product's GUID string
1781 * szFeature [I] Feature's GUID string
1783 * RETURNS
1784 * INSTALLSTATE_LOCAL Feature is installed and useable
1785 * INSTALLSTATE_ABSENT Feature is absent
1786 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1787 * INSTALLSTATE_UNKNOWN An error occurred
1788 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1791 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1793 WCHAR squishProduct[33], comp[GUID_SIZE];
1794 GUID guid;
1795 LPWSTR components, p, parent_feature, path;
1796 UINT rc;
1797 HKEY hkey;
1798 INSTALLSTATE r;
1799 BOOL missing = FALSE;
1801 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1803 if (!szProduct || !szFeature)
1804 return INSTALLSTATE_INVALIDARG;
1806 if (!squash_guid( szProduct, squishProduct ))
1807 return INSTALLSTATE_INVALIDARG;
1809 /* check that it's installed at all */
1810 rc = MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE);
1811 if (rc != ERROR_SUCCESS)
1812 return INSTALLSTATE_UNKNOWN;
1814 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1815 RegCloseKey(hkey);
1817 if (!parent_feature)
1818 return INSTALLSTATE_UNKNOWN;
1820 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1821 msi_free(parent_feature);
1822 if (r == INSTALLSTATE_ABSENT)
1823 return r;
1825 /* now check if it's complete or advertised */
1826 rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE);
1827 if (rc != ERROR_SUCCESS)
1828 return INSTALLSTATE_ADVERTISED;
1830 components = msi_reg_get_val_str( hkey, szFeature );
1831 RegCloseKey(hkey);
1833 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1835 if (!components)
1836 return INSTALLSTATE_ADVERTISED;
1838 for( p = components; *p && *p != 2 ; p += 20)
1840 if (!decode_base85_guid( p, &guid ))
1842 if (p != components)
1843 break;
1845 msi_free(components);
1846 return INSTALLSTATE_BADCONFIG;
1849 StringFromGUID2(&guid, comp, GUID_SIZE);
1850 rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1851 if (rc != ERROR_SUCCESS)
1853 msi_free(components);
1854 return INSTALLSTATE_ADVERTISED;
1857 path = msi_reg_get_val_str(hkey, squishProduct);
1858 if (!path)
1859 missing = TRUE;
1861 msi_free(path);
1864 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1865 msi_free(components);
1867 if (missing)
1868 return INSTALLSTATE_ADVERTISED;
1870 return INSTALLSTATE_LOCAL;
1873 /******************************************************************
1874 * MsiGetFileVersionA [MSI.@]
1876 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1877 LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
1879 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1880 UINT ret = ERROR_OUTOFMEMORY;
1882 if ((lpVersionBuf && !pcchVersionBuf) ||
1883 (lpLangBuf && !pcchLangBuf))
1884 return ERROR_INVALID_PARAMETER;
1886 if( szFilePath )
1888 szwFilePath = strdupAtoW( szFilePath );
1889 if( !szwFilePath )
1890 goto end;
1893 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1895 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1896 if( !lpwVersionBuff )
1897 goto end;
1900 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1902 lpwLangBuff = msi_alloc(*pcchLangBuf*sizeof(WCHAR));
1903 if( !lpwLangBuff )
1904 goto end;
1907 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1908 lpwLangBuff, pcchLangBuf);
1910 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwVersionBuff )
1911 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1912 lpVersionBuf, *pcchVersionBuf + 1, NULL, NULL);
1913 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwLangBuff )
1914 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1915 lpLangBuf, *pcchLangBuf + 1, NULL, NULL);
1917 end:
1918 msi_free(szwFilePath);
1919 msi_free(lpwVersionBuff);
1920 msi_free(lpwLangBuff);
1922 return ret;
1925 /******************************************************************
1926 * MsiGetFileVersionW [MSI.@]
1928 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1929 LPDWORD pcchVersionBuf, LPWSTR lpLangBuf, LPDWORD pcchLangBuf)
1931 static const WCHAR szVersionResource[] = {'\\',0};
1932 static const WCHAR szVersionFormat[] = {
1933 '%','d','.','%','d','.','%','d','.','%','d',0};
1934 static const WCHAR szLangResource[] = {
1935 '\\','V','a','r','F','i','l','e','I','n','f','o','\\',
1936 'T','r','a','n','s','l','a','t','i','o','n',0};
1937 static const WCHAR szLangFormat[] = {'%','d',0};
1938 UINT ret = 0;
1939 DWORD dwVerLen, gle;
1940 LPVOID lpVer = NULL;
1941 VS_FIXEDFILEINFO *ffi;
1942 USHORT *lang;
1943 UINT puLen;
1944 WCHAR tmp[32];
1946 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
1947 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1948 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1950 if ((lpVersionBuf && !pcchVersionBuf) ||
1951 (lpLangBuf && !pcchLangBuf))
1952 return ERROR_INVALID_PARAMETER;
1954 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1955 if( !dwVerLen )
1957 gle = GetLastError();
1958 if (gle == ERROR_BAD_PATHNAME)
1959 return ERROR_FILE_NOT_FOUND;
1960 else if (gle == ERROR_RESOURCE_DATA_NOT_FOUND)
1961 return ERROR_FILE_INVALID;
1963 return gle;
1966 lpVer = msi_alloc(dwVerLen);
1967 if( !lpVer )
1969 ret = ERROR_OUTOFMEMORY;
1970 goto end;
1973 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1975 ret = GetLastError();
1976 goto end;
1979 if (pcchVersionBuf)
1981 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1982 (puLen > 0) )
1984 wsprintfW(tmp, szVersionFormat,
1985 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1986 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1987 if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1989 if (lstrlenW(tmp) >= *pcchVersionBuf)
1990 ret = ERROR_MORE_DATA;
1992 *pcchVersionBuf = lstrlenW(tmp);
1994 else
1996 if (lpVersionBuf) *lpVersionBuf = 0;
1997 *pcchVersionBuf = 0;
2001 if (pcchLangBuf)
2003 if (VerQueryValueW(lpVer, szLangResource, (LPVOID*)&lang, &puLen) &&
2004 (puLen > 0))
2006 wsprintfW(tmp, szLangFormat, *lang);
2007 if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
2009 if (lstrlenW(tmp) >= *pcchLangBuf)
2010 ret = ERROR_MORE_DATA;
2012 *pcchLangBuf = lstrlenW(tmp);
2014 else
2016 if (lpLangBuf) *lpLangBuf = 0;
2017 *pcchLangBuf = 0;
2021 end:
2022 msi_free(lpVer);
2023 return ret;
2026 /***********************************************************************
2027 * MsiGetFeatureUsageW [MSI.@]
2029 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
2030 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2032 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
2033 pdwUseCount, pwDateUsed);
2034 return ERROR_CALL_NOT_IMPLEMENTED;
2037 /***********************************************************************
2038 * MsiGetFeatureUsageA [MSI.@]
2040 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
2041 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2043 LPWSTR prod = NULL, feat = NULL;
2044 UINT ret = ERROR_OUTOFMEMORY;
2046 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
2047 pdwUseCount, pwDateUsed);
2049 prod = strdupAtoW( szProduct );
2050 if (szProduct && !prod)
2051 goto end;
2053 feat = strdupAtoW( szFeature );
2054 if (szFeature && !feat)
2055 goto end;
2057 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
2059 end:
2060 msi_free( prod );
2061 msi_free( feat );
2063 return ret;
2066 /***********************************************************************
2067 * MsiUseFeatureExW [MSI.@]
2069 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
2070 DWORD dwInstallMode, DWORD dwReserved )
2072 INSTALLSTATE state;
2074 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2075 dwInstallMode, dwReserved);
2077 state = MsiQueryFeatureStateW( szProduct, szFeature );
2079 if (dwReserved)
2080 return INSTALLSTATE_INVALIDARG;
2082 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
2084 FIXME("mark product %s feature %s as used\n",
2085 debugstr_w(szProduct), debugstr_w(szFeature) );
2088 return state;
2091 /***********************************************************************
2092 * MsiUseFeatureExA [MSI.@]
2094 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
2095 DWORD dwInstallMode, DWORD dwReserved )
2097 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
2098 LPWSTR prod = NULL, feat = NULL;
2100 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2101 dwInstallMode, dwReserved);
2103 prod = strdupAtoW( szProduct );
2104 if (szProduct && !prod)
2105 goto end;
2107 feat = strdupAtoW( szFeature );
2108 if (szFeature && !feat)
2109 goto end;
2111 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
2113 end:
2114 msi_free( prod );
2115 msi_free( feat );
2117 return ret;
2120 /***********************************************************************
2121 * MsiUseFeatureW [MSI.@]
2123 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
2125 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
2128 /***********************************************************************
2129 * MsiUseFeatureA [MSI.@]
2131 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
2133 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
2136 /***********************************************************************
2137 * MSI_ProvideQualifiedComponentEx [internal]
2139 static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
2140 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2141 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
2142 LPDWORD pcchPathBuf)
2144 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
2145 feature[MAX_FEATURE_CHARS+1];
2146 LPWSTR info;
2147 HKEY hkey;
2148 DWORD sz;
2149 UINT rc;
2151 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
2152 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
2153 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2155 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
2156 if (rc != ERROR_SUCCESS)
2157 return ERROR_INDEX_ABSENT;
2159 info = msi_reg_get_val_str( hkey, szQualifier );
2160 RegCloseKey(hkey);
2162 if (!info)
2163 return ERROR_INDEX_ABSENT;
2165 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
2167 if (!szProduct)
2168 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
2169 else
2170 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
2172 msi_free( info );
2174 if (rc != INSTALLSTATE_LOCAL)
2175 return ERROR_FILE_NOT_FOUND;
2177 return ERROR_SUCCESS;
2180 /***********************************************************************
2181 * MsiProvideQualifiedComponentExW [MSI.@]
2183 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
2184 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2185 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
2186 LPDWORD pcchPathBuf)
2188 awstring path;
2190 path.unicode = TRUE;
2191 path.str.w = lpPathBuf;
2193 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
2194 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
2197 /***********************************************************************
2198 * MsiProvideQualifiedComponentExA [MSI.@]
2200 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
2201 LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
2202 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
2203 LPDWORD pcchPathBuf)
2205 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
2206 UINT r = ERROR_OUTOFMEMORY;
2207 awstring path;
2209 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
2210 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
2211 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2213 szwComponent = strdupAtoW( szComponent );
2214 if (szComponent && !szwComponent)
2215 goto end;
2217 szwQualifier = strdupAtoW( szQualifier );
2218 if (szQualifier && !szwQualifier)
2219 goto end;
2221 szwProduct = strdupAtoW( szProduct );
2222 if (szProduct && !szwProduct)
2223 goto end;
2225 path.unicode = FALSE;
2226 path.str.a = lpPathBuf;
2228 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
2229 dwInstallMode, szwProduct, Unused1,
2230 Unused2, &path, pcchPathBuf);
2231 end:
2232 msi_free(szwProduct);
2233 msi_free(szwComponent);
2234 msi_free(szwQualifier);
2236 return r;
2239 /***********************************************************************
2240 * MsiProvideQualifiedComponentW [MSI.@]
2242 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
2243 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
2244 LPDWORD pcchPathBuf)
2246 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
2247 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2250 /***********************************************************************
2251 * MsiProvideQualifiedComponentA [MSI.@]
2253 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
2254 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
2255 LPDWORD pcchPathBuf)
2257 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
2258 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2261 /***********************************************************************
2262 * MSI_GetUserInfo [internal]
2264 static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
2265 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
2266 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2267 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
2269 HKEY hkey;
2270 LPWSTR user, org, serial;
2271 UINT r;
2272 USERINFOSTATE state;
2274 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
2275 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
2276 pcchSerialBuf);
2278 if (!szProduct)
2279 return USERINFOSTATE_INVALIDARG;
2281 r = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
2282 if (r != ERROR_SUCCESS)
2283 return USERINFOSTATE_UNKNOWN;
2285 user = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGOWNERW );
2286 org = msi_reg_get_val_str( hkey, INSTALLPROPERTY_REGCOMPANYW );
2287 serial = msi_reg_get_val_str( hkey, INSTALLPROPERTY_PRODUCTIDW );
2289 RegCloseKey(hkey);
2291 state = USERINFOSTATE_PRESENT;
2293 if (user)
2295 r = msi_strcpy_to_awstring( user, lpUserNameBuf, pcchUserNameBuf );
2296 if (r == ERROR_MORE_DATA)
2297 state = USERINFOSTATE_MOREDATA;
2299 else
2300 state = USERINFOSTATE_ABSENT;
2301 if (org)
2303 r = msi_strcpy_to_awstring( org, lpOrgNameBuf, pcchOrgNameBuf );
2304 if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
2305 state = USERINFOSTATE_MOREDATA;
2307 /* msdn states: The user information is considered to be present even in the absence of a company name. */
2308 if (serial)
2310 r = msi_strcpy_to_awstring( serial, lpSerialBuf, pcchSerialBuf );
2311 if (r == ERROR_MORE_DATA && state == USERINFOSTATE_PRESENT)
2312 state = USERINFOSTATE_MOREDATA;
2314 else
2315 state = USERINFOSTATE_ABSENT;
2317 msi_free( user );
2318 msi_free( org );
2319 msi_free( serial );
2321 return state;
2324 /***********************************************************************
2325 * MsiGetUserInfoW [MSI.@]
2327 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
2328 LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2329 LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2330 LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2332 awstring user, org, serial;
2334 user.unicode = TRUE;
2335 user.str.w = lpUserNameBuf;
2336 org.unicode = TRUE;
2337 org.str.w = lpOrgNameBuf;
2338 serial.unicode = TRUE;
2339 serial.str.w = lpSerialBuf;
2341 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
2342 &org, pcchOrgNameBuf,
2343 &serial, pcchSerialBuf );
2346 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
2347 LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2348 LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2349 LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2351 awstring user, org, serial;
2352 LPWSTR prod;
2353 UINT r;
2355 prod = strdupAtoW( szProduct );
2356 if (szProduct && !prod)
2357 return ERROR_OUTOFMEMORY;
2359 user.unicode = FALSE;
2360 user.str.a = lpUserNameBuf;
2361 org.unicode = FALSE;
2362 org.str.a = lpOrgNameBuf;
2363 serial.unicode = FALSE;
2364 serial.str.a = lpSerialBuf;
2366 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
2367 &org, pcchOrgNameBuf,
2368 &serial, pcchSerialBuf );
2370 msi_free( prod );
2372 return r;
2375 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
2377 MSIHANDLE handle;
2378 UINT rc;
2379 MSIPACKAGE *package;
2380 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2382 TRACE("(%s)\n",debugstr_w(szProduct));
2384 rc = MsiOpenProductW(szProduct,&handle);
2385 if (rc != ERROR_SUCCESS)
2386 return ERROR_INVALID_PARAMETER;
2388 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2389 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2390 msiobj_release( &package->hdr );
2392 MsiCloseHandle(handle);
2394 return rc;
2397 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
2399 MSIHANDLE handle;
2400 UINT rc;
2401 MSIPACKAGE *package;
2402 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2404 TRACE("(%s)\n",debugstr_a(szProduct));
2406 rc = MsiOpenProductA(szProduct,&handle);
2407 if (rc != ERROR_SUCCESS)
2408 return ERROR_INVALID_PARAMETER;
2410 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2411 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2412 msiobj_release( &package->hdr );
2414 MsiCloseHandle(handle);
2416 return rc;
2419 /***********************************************************************
2420 * MsiConfigureFeatureA [MSI.@]
2422 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
2424 LPWSTR prod, feat = NULL;
2425 UINT r = ERROR_OUTOFMEMORY;
2427 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
2429 prod = strdupAtoW( szProduct );
2430 if (szProduct && !prod)
2431 goto end;
2433 feat = strdupAtoW( szFeature );
2434 if (szFeature && !feat)
2435 goto end;
2437 r = MsiConfigureFeatureW(prod, feat, eInstallState);
2439 end:
2440 msi_free(feat);
2441 msi_free(prod);
2443 return r;
2446 /***********************************************************************
2447 * MsiConfigureFeatureW [MSI.@]
2449 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
2451 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
2452 MSIPACKAGE *package = NULL;
2453 UINT r;
2454 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
2455 DWORD sz;
2457 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
2459 if (!szProduct || !szFeature)
2460 return ERROR_INVALID_PARAMETER;
2462 switch (eInstallState)
2464 case INSTALLSTATE_DEFAULT:
2465 /* FIXME: how do we figure out the default location? */
2466 eInstallState = INSTALLSTATE_LOCAL;
2467 break;
2468 case INSTALLSTATE_LOCAL:
2469 case INSTALLSTATE_SOURCE:
2470 case INSTALLSTATE_ABSENT:
2471 case INSTALLSTATE_ADVERTISED:
2472 break;
2473 default:
2474 return ERROR_INVALID_PARAMETER;
2477 r = MSI_OpenProductW( szProduct, &package );
2478 if (r != ERROR_SUCCESS)
2479 return r;
2481 sz = sizeof(sourcepath);
2482 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2483 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2485 sz = sizeof(filename);
2486 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2487 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2489 lstrcatW( sourcepath, filename );
2491 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
2493 r = ACTION_PerformUIAction( package, szCostInit, -1 );
2494 if (r != ERROR_SUCCESS)
2495 goto end;
2497 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
2498 if (r != ERROR_SUCCESS)
2499 goto end;
2501 r = MSI_InstallPackage( package, sourcepath, NULL );
2503 end:
2504 msiobj_release( &package->hdr );
2506 return r;
2509 /***********************************************************************
2510 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
2512 * Notes: undocumented
2514 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
2516 WCHAR path[MAX_PATH];
2518 TRACE("%d\n", dwReserved);
2520 if (dwReserved)
2522 FIXME("dwReserved=%d\n", dwReserved);
2523 return ERROR_INVALID_PARAMETER;
2526 if (!GetWindowsDirectoryW(path, MAX_PATH))
2527 return ERROR_FUNCTION_FAILED;
2529 lstrcatW(path, installerW);
2531 if (!CreateDirectoryW(path, NULL))
2532 return ERROR_FUNCTION_FAILED;
2534 return ERROR_SUCCESS;
2537 /***********************************************************************
2538 * MsiGetShortcutTargetA [MSI.@]
2540 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
2541 LPSTR szProductCode, LPSTR szFeatureId,
2542 LPSTR szComponentCode )
2544 LPWSTR target;
2545 const int len = MAX_FEATURE_CHARS+1;
2546 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
2547 UINT r;
2549 target = strdupAtoW( szShortcutTarget );
2550 if (szShortcutTarget && !target )
2551 return ERROR_OUTOFMEMORY;
2552 product[0] = 0;
2553 feature[0] = 0;
2554 component[0] = 0;
2555 r = MsiGetShortcutTargetW( target, product, feature, component );
2556 msi_free( target );
2557 if (r == ERROR_SUCCESS)
2559 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
2560 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
2561 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
2563 return r;
2566 /***********************************************************************
2567 * MsiGetShortcutTargetW [MSI.@]
2569 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
2570 LPWSTR szProductCode, LPWSTR szFeatureId,
2571 LPWSTR szComponentCode )
2573 IShellLinkDataList *dl = NULL;
2574 IPersistFile *pf = NULL;
2575 LPEXP_DARWIN_LINK darwin = NULL;
2576 HRESULT r, init;
2578 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
2579 szProductCode, szFeatureId, szComponentCode );
2581 init = CoInitialize(NULL);
2583 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2584 &IID_IPersistFile, (LPVOID*) &pf );
2585 if( SUCCEEDED( r ) )
2587 r = IPersistFile_Load( pf, szShortcutTarget,
2588 STGM_READ | STGM_SHARE_DENY_WRITE );
2589 if( SUCCEEDED( r ) )
2591 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
2592 (LPVOID*) &dl );
2593 if( SUCCEEDED( r ) )
2595 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
2596 (LPVOID) &darwin );
2597 IShellLinkDataList_Release( dl );
2600 IPersistFile_Release( pf );
2603 if (SUCCEEDED(init))
2604 CoUninitialize();
2606 TRACE("darwin = %p\n", darwin);
2608 if (darwin)
2610 DWORD sz;
2611 UINT ret;
2613 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
2614 szProductCode, szFeatureId, szComponentCode, &sz );
2615 LocalFree( darwin );
2616 return ret;
2619 return ERROR_FUNCTION_FAILED;
2622 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
2623 DWORD dwReinstallMode )
2625 MSIPACKAGE* package = NULL;
2626 UINT r;
2627 WCHAR sourcepath[MAX_PATH];
2628 WCHAR filename[MAX_PATH];
2629 static const WCHAR szLogVerbose[] = {
2630 ' ','L','O','G','V','E','R','B','O','S','E',0 };
2631 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
2632 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
2633 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
2634 static const WCHAR szOne[] = {'1',0};
2635 WCHAR reinstallmode[11];
2636 LPWSTR ptr;
2637 DWORD sz;
2639 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2640 dwReinstallMode);
2642 ptr = reinstallmode;
2644 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
2645 *ptr++ = 'p';
2646 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
2647 *ptr++ = 'o';
2648 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
2649 *ptr++ = 'w';
2650 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
2651 *ptr++ = 'd';
2652 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
2653 *ptr++ = 'c';
2654 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
2655 *ptr++ = 'a';
2656 if (dwReinstallMode & REINSTALLMODE_USERDATA)
2657 *ptr++ = 'u';
2658 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
2659 *ptr++ = 'm';
2660 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
2661 *ptr++ = 's';
2662 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2663 *ptr++ = 'v';
2664 *ptr = 0;
2666 sz = sizeof(sourcepath);
2667 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2668 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2670 sz = sizeof(filename);
2671 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2672 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2674 lstrcatW( sourcepath, filename );
2676 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2677 r = MSI_OpenPackageW( sourcepath, &package );
2678 else
2679 r = MSI_OpenProductW( szProduct, &package );
2681 if (r != ERROR_SUCCESS)
2682 return r;
2684 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
2685 MSI_SetPropertyW( package, szInstalled, szOne );
2686 MSI_SetPropertyW( package, szLogVerbose, szOne );
2687 MSI_SetPropertyW( package, szReinstall, szFeature );
2689 r = MSI_InstallPackage( package, sourcepath, NULL );
2691 msiobj_release( &package->hdr );
2693 return r;
2696 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
2697 DWORD dwReinstallMode )
2699 LPWSTR wszProduct;
2700 LPWSTR wszFeature;
2701 UINT rc;
2703 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2704 dwReinstallMode);
2706 wszProduct = strdupAtoW(szProduct);
2707 wszFeature = strdupAtoW(szFeature);
2709 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
2711 msi_free(wszProduct);
2712 msi_free(wszFeature);
2713 return rc;
2716 typedef struct
2718 unsigned int i[2];
2719 unsigned int buf[4];
2720 unsigned char in[64];
2721 unsigned char digest[16];
2722 } MD5_CTX;
2724 extern VOID WINAPI MD5Init( MD5_CTX *);
2725 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
2726 extern VOID WINAPI MD5Final( MD5_CTX *);
2728 /***********************************************************************
2729 * MsiGetFileHashW [MSI.@]
2731 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2732 PMSIFILEHASHINFO pHash )
2734 HANDLE handle, mapping;
2735 void *p;
2736 DWORD length;
2737 UINT r = ERROR_FUNCTION_FAILED;
2739 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2741 if (!szFilePath)
2742 return ERROR_INVALID_PARAMETER;
2744 if (!*szFilePath)
2745 return ERROR_PATH_NOT_FOUND;
2747 if (dwOptions)
2748 return ERROR_INVALID_PARAMETER;
2749 if (!pHash)
2750 return ERROR_INVALID_PARAMETER;
2751 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2752 return ERROR_INVALID_PARAMETER;
2754 handle = CreateFileW( szFilePath, GENERIC_READ,
2755 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2756 if (handle == INVALID_HANDLE_VALUE)
2757 return ERROR_FILE_NOT_FOUND;
2759 length = GetFileSize( handle, NULL );
2761 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2762 if (mapping)
2764 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2765 if (p)
2767 MD5_CTX ctx;
2769 MD5Init( &ctx );
2770 MD5Update( &ctx, p, length );
2771 MD5Final( &ctx );
2772 UnmapViewOfFile( p );
2774 memcpy( pHash->dwData, &ctx.digest, sizeof pHash->dwData );
2775 r = ERROR_SUCCESS;
2777 CloseHandle( mapping );
2779 CloseHandle( handle );
2781 return r;
2784 /***********************************************************************
2785 * MsiGetFileHashA [MSI.@]
2787 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2788 PMSIFILEHASHINFO pHash )
2790 LPWSTR file;
2791 UINT r;
2793 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2795 file = strdupAtoW( szFilePath );
2796 if (szFilePath && !file)
2797 return ERROR_OUTOFMEMORY;
2799 r = MsiGetFileHashW( file, dwOptions, pHash );
2800 msi_free( file );
2801 return r;
2804 /***********************************************************************
2805 * MsiAdvertiseScriptW [MSI.@]
2807 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2808 PHKEY phRegData, BOOL fRemoveItems )
2810 FIXME("%s %08x %p %d\n",
2811 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2812 return ERROR_CALL_NOT_IMPLEMENTED;
2815 /***********************************************************************
2816 * MsiAdvertiseScriptA [MSI.@]
2818 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2819 PHKEY phRegData, BOOL fRemoveItems )
2821 FIXME("%s %08x %p %d\n",
2822 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2823 return ERROR_CALL_NOT_IMPLEMENTED;
2826 /***********************************************************************
2827 * MsiIsProductElevatedW [MSI.@]
2829 UINT WINAPI MsiIsProductElevatedW( LPCWSTR szProduct, BOOL *pfElevated )
2831 FIXME("%s %p - stub\n",
2832 debugstr_w( szProduct ), pfElevated );
2833 *pfElevated = TRUE;
2834 return ERROR_SUCCESS;
2837 /***********************************************************************
2838 * MsiIsProductElevatedA [MSI.@]
2840 UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
2842 FIXME("%s %p - stub\n",
2843 debugstr_a( szProduct ), pfElevated );
2844 *pfElevated = TRUE;
2845 return ERROR_SUCCESS;