comctl32: Remove unused parameter from _read_bitmap().
[wine/wine-gecko.git] / dlls / msi / msi.c
blob359698abba4660fa9f7a223c338a24d1cae19243
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 /* FIXME: user-managed installs not located */
49 static UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
51 HKEY hkey = NULL;
52 UINT r;
54 *context = MSIINSTALLCONTEXT_NONE;
56 r = MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE);
57 if (r == ERROR_SUCCESS)
58 *context = MSIINSTALLCONTEXT_MACHINE;
59 else
61 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
62 if (r == ERROR_SUCCESS)
63 *context = MSIINSTALLCONTEXT_USERUNMANAGED;
66 RegCloseKey(hkey);
67 return ERROR_SUCCESS;
70 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
72 UINT r;
73 LPWSTR szwProd = NULL;
75 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
77 if( szProduct )
79 szwProd = strdupAtoW( szProduct );
80 if( !szwProd )
81 return ERROR_OUTOFMEMORY;
84 r = MsiOpenProductW( szwProd, phProduct );
86 msi_free( szwProd );
88 return r;
91 static UINT MSI_OpenProductW( LPCWSTR szProduct, MSIPACKAGE **ppackage )
93 LPWSTR path = NULL;
94 UINT r;
95 HKEY hKeyProduct = NULL;
96 DWORD count, type;
98 TRACE("%s %p\n", debugstr_w(szProduct), ppackage );
100 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
101 if( r != ERROR_SUCCESS )
103 r = ERROR_UNKNOWN_PRODUCT;
104 goto end;
107 /* find the size of the path */
108 type = count = 0;
109 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
110 NULL, &type, NULL, &count );
111 if( r != ERROR_SUCCESS )
113 r = ERROR_UNKNOWN_PRODUCT;
114 goto end;
117 /* now alloc and fetch the path of the database to open */
118 path = msi_alloc( count );
119 if( !path )
120 goto end;
122 r = RegQueryValueExW( hKeyProduct, INSTALLPROPERTY_LOCALPACKAGEW,
123 NULL, &type, (LPBYTE) path, &count );
124 if( r != ERROR_SUCCESS )
126 r = ERROR_UNKNOWN_PRODUCT;
127 goto end;
130 r = MSI_OpenPackageW( path, ppackage );
132 end:
133 msi_free( path );
134 if( hKeyProduct )
135 RegCloseKey( hKeyProduct );
137 return r;
140 UINT WINAPI MsiOpenProductW( LPCWSTR szProduct, MSIHANDLE *phProduct )
142 MSIPACKAGE *package = NULL;
143 UINT r;
145 r = MSI_OpenProductW( szProduct, &package );
146 if( r == ERROR_SUCCESS )
148 *phProduct = alloc_msihandle( &package->hdr );
149 if (! *phProduct)
150 r = ERROR_NOT_ENOUGH_MEMORY;
151 msiobj_release( &package->hdr );
153 return r;
156 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
157 LPCSTR szTransforms, LANGID lgidLanguage)
159 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
160 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
161 return ERROR_CALL_NOT_IMPLEMENTED;
164 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
165 LPCWSTR szTransforms, LANGID lgidLanguage)
167 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
168 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
169 return ERROR_CALL_NOT_IMPLEMENTED;
172 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
173 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
175 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
176 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
177 lgidLanguage, dwPlatform, dwOptions);
178 return ERROR_CALL_NOT_IMPLEMENTED;
181 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
182 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
184 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
185 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
186 lgidLanguage, dwPlatform, dwOptions);
187 return ERROR_CALL_NOT_IMPLEMENTED;
190 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
192 LPWSTR szwPath = NULL, szwCommand = NULL;
193 UINT r = ERROR_OUTOFMEMORY;
195 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
197 if( szPackagePath )
199 szwPath = strdupAtoW( szPackagePath );
200 if( !szwPath )
201 goto end;
204 if( szCommandLine )
206 szwCommand = strdupAtoW( szCommandLine );
207 if( !szwCommand )
208 goto end;
211 r = MsiInstallProductW( szwPath, szwCommand );
213 end:
214 msi_free( szwPath );
215 msi_free( szwCommand );
217 return r;
220 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
222 MSIPACKAGE *package = NULL;
223 UINT r;
225 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
227 r = MSI_OpenPackageW( szPackagePath, &package );
228 if (r == ERROR_SUCCESS)
230 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
231 msiobj_release( &package->hdr );
234 return r;
237 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
239 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
240 return ERROR_CALL_NOT_IMPLEMENTED;
243 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
245 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
246 return ERROR_CALL_NOT_IMPLEMENTED;
249 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
250 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
252 LPWSTR patch_package = NULL;
253 LPWSTR install_package = NULL;
254 LPWSTR command_line = NULL;
255 UINT r = ERROR_OUTOFMEMORY;
257 TRACE("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
258 eInstallType, debugstr_a(szCommandLine));
260 if (szPatchPackage && !(patch_package = strdupAtoW(szPatchPackage)))
261 goto done;
263 if (szInstallPackage && !(install_package = strdupAtoW(szInstallPackage)))
264 goto done;
266 if (szCommandLine && !(command_line = strdupAtoW(szCommandLine)))
267 goto done;
269 r = MsiApplyPatchW(patch_package, install_package, eInstallType, command_line);
271 done:
272 msi_free(patch_package);
273 msi_free(install_package);
274 msi_free(command_line);
276 return r;
279 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
280 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
282 MSIHANDLE patch, info;
283 UINT r, type;
284 DWORD size = 0;
285 LPCWSTR cmd_ptr = szCommandLine;
286 LPWSTR beg, end;
287 LPWSTR cmd = NULL, codes = NULL;
289 static const WCHAR space[] = {' ',0};
290 static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
291 static WCHAR empty[] = {0};
293 TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
294 eInstallType, debugstr_w(szCommandLine));
296 if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
297 eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
299 FIXME("Only reading target products from patch\n");
300 return ERROR_CALL_NOT_IMPLEMENTED;
303 r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
304 if (r != ERROR_SUCCESS)
305 return r;
307 r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
308 if (r != ERROR_SUCCESS)
309 goto done;
311 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
312 if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
314 ERR("Failed to read product codes from patch\n");
315 goto done;
318 codes = msi_alloc(++size * sizeof(WCHAR));
319 if (!codes)
321 r = ERROR_OUTOFMEMORY;
322 goto done;
325 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
326 if (r != ERROR_SUCCESS)
327 goto done;
329 if (!szCommandLine)
330 cmd_ptr = empty;
332 size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
333 cmd = msi_alloc(size * sizeof(WCHAR));
334 if (!cmd)
336 r = ERROR_OUTOFMEMORY;
337 goto done;
340 lstrcpyW(cmd, cmd_ptr);
341 if (szCommandLine) lstrcatW(cmd, space);
342 lstrcatW(cmd, patcheq);
343 lstrcatW(cmd, szPatchPackage);
345 beg = codes;
346 while ((end = strchrW(beg, '}')))
348 *(end + 1) = '\0';
350 r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
351 if (r != ERROR_SUCCESS)
352 goto done;
354 beg = end + 2;
357 done:
358 msi_free(cmd);
359 msi_free(codes);
361 MsiCloseHandle(info);
362 MsiCloseHandle(patch);
364 return r;
367 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
368 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
370 MSIPACKAGE* package = NULL;
371 MSIINSTALLCONTEXT context;
372 UINT r;
373 DWORD sz;
374 WCHAR sourcepath[MAX_PATH];
375 WCHAR filename[MAX_PATH];
376 LPWSTR commandline;
378 static const WCHAR szInstalled[] = {
379 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
380 static const WCHAR szRemoveAll[] = {
381 ' ','R','E','M','O','V','E','=','A','L','L',0};
382 static const WCHAR szMachine[] = {
383 ' ','A','L','L','U','S','E','R','S','=','1',0};
385 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
386 debugstr_w(szCommandLine));
388 if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
389 return ERROR_INVALID_PARAMETER;
391 if (eInstallState == INSTALLSTATE_ADVERTISED ||
392 eInstallState == INSTALLSTATE_SOURCE)
394 FIXME("State %d not implemented\n", eInstallState);
395 return ERROR_CALL_NOT_IMPLEMENTED;
398 r = msi_locate_product(szProduct, &context);
399 if (r != ERROR_SUCCESS)
400 return r;
402 if (context == MSIINSTALLCONTEXT_NONE)
403 return ERROR_UNKNOWN_PRODUCT;
405 sz = sizeof(sourcepath);
406 MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
407 INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
409 sz = sizeof(filename);
410 MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
411 INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
413 lstrcatW(sourcepath, filename);
414 r = MSI_OpenPackageW(sourcepath, &package);
415 if (r != ERROR_SUCCESS)
416 return r;
418 sz = lstrlenW(szInstalled) + 1;
420 if (szCommandLine)
421 sz += lstrlenW(szCommandLine);
423 if (eInstallState == INSTALLSTATE_ABSENT)
424 sz += lstrlenW(szRemoveAll);
426 if (context == MSIINSTALLCONTEXT_MACHINE)
427 sz += lstrlenW(szMachine);
429 commandline = msi_alloc(sz * sizeof(WCHAR));
430 if (!commandline)
432 r = ERROR_OUTOFMEMORY;
433 goto end;
436 commandline[0] = 0;
437 if (szCommandLine)
438 lstrcpyW(commandline,szCommandLine);
440 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
441 lstrcatW(commandline,szInstalled);
443 if (eInstallState == INSTALLSTATE_ABSENT)
444 lstrcatW(commandline, szRemoveAll);
446 if (context == MSIINSTALLCONTEXT_MACHINE)
447 lstrcatW(commandline, szMachine);
449 r = MSI_InstallPackage( package, sourcepath, commandline );
451 msi_free(commandline);
453 end:
454 msiobj_release( &package->hdr );
456 return r;
459 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
460 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
462 LPWSTR szwProduct = NULL;
463 LPWSTR szwCommandLine = NULL;
464 UINT r = ERROR_OUTOFMEMORY;
466 if( szProduct )
468 szwProduct = strdupAtoW( szProduct );
469 if( !szwProduct )
470 goto end;
473 if( szCommandLine)
475 szwCommandLine = strdupAtoW( szCommandLine );
476 if( !szwCommandLine)
477 goto end;
480 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
481 szwCommandLine );
482 end:
483 msi_free( szwProduct );
484 msi_free( szwCommandLine);
486 return r;
489 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
490 INSTALLSTATE eInstallState)
492 LPWSTR szwProduct = NULL;
493 UINT r;
495 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
497 if( szProduct )
499 szwProduct = strdupAtoW( szProduct );
500 if( !szwProduct )
501 return ERROR_OUTOFMEMORY;
504 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
505 msi_free( szwProduct );
507 return r;
510 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
511 INSTALLSTATE eInstallState)
513 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
516 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
518 LPWSTR szwComponent = NULL;
519 UINT r;
520 WCHAR szwBuffer[GUID_SIZE];
522 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
524 if( szComponent )
526 szwComponent = strdupAtoW( szComponent );
527 if( !szwComponent )
528 return ERROR_OUTOFMEMORY;
531 *szwBuffer = '\0';
532 r = MsiGetProductCodeW( szwComponent, szwBuffer );
534 if(*szwBuffer)
535 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
537 msi_free( szwComponent );
539 return r;
542 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
544 UINT rc, index;
545 HKEY compkey, prodkey;
546 WCHAR squished_comp[GUID_SIZE];
547 WCHAR squished_prod[GUID_SIZE];
548 DWORD sz = GUID_SIZE;
550 TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
552 if (!szComponent || !*szComponent)
553 return ERROR_INVALID_PARAMETER;
555 if (!squash_guid(szComponent, squished_comp))
556 return ERROR_INVALID_PARAMETER;
558 if (MSIREG_OpenUserDataComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS &&
559 MSIREG_OpenLocalSystemComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS)
561 return ERROR_UNKNOWN_COMPONENT;
564 rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
565 if (rc != ERROR_SUCCESS)
567 RegCloseKey(compkey);
568 return ERROR_UNKNOWN_COMPONENT;
571 /* check simple case, only one product */
572 rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
573 if (rc == ERROR_NO_MORE_ITEMS)
575 rc = ERROR_SUCCESS;
576 goto done;
579 index = 0;
580 while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
581 NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
583 index++;
584 sz = GUID_SIZE;
585 unsquash_guid(squished_prod, szBuffer);
587 if (MSIREG_OpenLocalManagedProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
588 MSIREG_OpenUserProductsKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
589 MSIREG_OpenLocalClassesProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS)
591 RegCloseKey(prodkey);
592 rc = ERROR_SUCCESS;
593 goto done;
597 rc = ERROR_INSTALL_FAILURE;
599 done:
600 RegCloseKey(compkey);
601 unsquash_guid(squished_prod, szBuffer);
602 return rc;
605 static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
607 DWORD dval;
608 LONG res;
609 WCHAR temp[20];
611 static const WCHAR format[] = {'%','d',0};
613 res = RegQueryValueExW(hkey, name, NULL, type, NULL, NULL);
614 if (res != ERROR_SUCCESS)
615 return NULL;
617 if (*type == REG_SZ)
618 return msi_reg_get_val_str(hkey, name);
620 if (!msi_reg_get_val_dword(hkey, name, &dval))
621 return NULL;
623 sprintfW(temp, format, dval);
624 return strdupW(temp);
627 static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
628 awstring *szValue, LPDWORD pcchValueBuf)
630 UINT r = ERROR_UNKNOWN_PROPERTY;
631 HKEY prodkey, userdata, source;
632 LPWSTR val = NULL;
633 WCHAR squished_pc[GUID_SIZE];
634 WCHAR packagecode[GUID_SIZE];
635 BOOL classes = FALSE;
636 BOOL badconfig = FALSE;
637 LONG res;
638 DWORD save, type = REG_NONE;
640 static WCHAR empty[] = {0};
641 static const WCHAR sourcelist[] = {
642 'S','o','u','r','c','e','L','i','s','t',0};
643 static const WCHAR display_name[] = {
644 'D','i','s','p','l','a','y','N','a','m','e',0};
645 static const WCHAR display_version[] = {
646 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
647 static const WCHAR assignment[] = {
648 'A','s','s','i','g','n','m','e','n','t',0};
650 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
651 debugstr_w(szAttribute), szValue, pcchValueBuf);
653 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
654 return ERROR_INVALID_PARAMETER;
656 if (!squash_guid(szProduct, squished_pc))
657 return ERROR_INVALID_PARAMETER;
659 r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
660 if (r != ERROR_SUCCESS)
662 r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
663 if (r != ERROR_SUCCESS)
665 r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
666 if (r == ERROR_SUCCESS)
667 classes = TRUE;
671 if (classes)
672 MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
673 else
674 MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
676 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
677 !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
678 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
679 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
680 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
681 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
682 !lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
683 !lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
684 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
685 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
686 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
687 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
688 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
689 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
690 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
691 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
693 if (!prodkey)
695 r = ERROR_UNKNOWN_PRODUCT;
696 goto done;
699 if (!userdata)
700 return ERROR_UNKNOWN_PROPERTY;
702 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
703 szAttribute = display_name;
704 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
705 szAttribute = display_version;
707 val = msi_reg_get_value(userdata, szAttribute, &type);
708 if (!val)
709 val = empty;
711 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
712 !lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
713 !lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
714 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
715 !lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
716 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
717 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
718 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
719 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
720 !lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
722 if (!prodkey)
724 r = ERROR_UNKNOWN_PRODUCT;
725 goto done;
728 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
729 szAttribute = assignment;
731 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
733 res = RegOpenKeyW(prodkey, sourcelist, &source);
734 if (res == ERROR_SUCCESS)
735 val = msi_reg_get_value(source, szAttribute, &type);
737 RegCloseKey(source);
739 else
741 val = msi_reg_get_value(prodkey, szAttribute, &type);
742 if (!val)
743 val = empty;
746 if (val != empty && type != REG_DWORD &&
747 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
749 if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
750 badconfig = TRUE;
751 else
753 unsquash_guid(val, packagecode);
754 msi_free(val);
755 val = strdupW(packagecode);
760 if (!val)
762 r = ERROR_UNKNOWN_PROPERTY;
763 goto done;
766 if (pcchValueBuf)
768 save = *pcchValueBuf;
770 if (lstrlenW(val) < *pcchValueBuf)
771 r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
772 else if (szValue->str.a || szValue->str.w)
773 r = ERROR_MORE_DATA;
775 if (!badconfig)
776 *pcchValueBuf = lstrlenW(val);
777 else if (r == ERROR_SUCCESS)
779 *pcchValueBuf = save;
780 r = ERROR_BAD_CONFIGURATION;
783 else if (badconfig)
784 r = ERROR_BAD_CONFIGURATION;
786 if (val != empty)
787 msi_free(val);
789 done:
790 RegCloseKey(prodkey);
791 RegCloseKey(userdata);
792 return r;
795 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
796 LPSTR szBuffer, LPDWORD pcchValueBuf)
798 LPWSTR szwProduct, szwAttribute = NULL;
799 UINT r = ERROR_OUTOFMEMORY;
800 awstring buffer;
802 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
803 szBuffer, pcchValueBuf);
805 szwProduct = strdupAtoW( szProduct );
806 if( szProduct && !szwProduct )
807 goto end;
809 szwAttribute = strdupAtoW( szAttribute );
810 if( szAttribute && !szwAttribute )
811 goto end;
813 buffer.unicode = FALSE;
814 buffer.str.a = szBuffer;
816 r = MSI_GetProductInfo( szwProduct, szwAttribute,
817 &buffer, pcchValueBuf );
819 end:
820 msi_free( szwProduct );
821 msi_free( szwAttribute );
823 return r;
826 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
827 LPWSTR szBuffer, LPDWORD pcchValueBuf)
829 awstring buffer;
831 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
832 szBuffer, pcchValueBuf);
834 buffer.unicode = TRUE;
835 buffer.str.w = szBuffer;
837 return MSI_GetProductInfo( szProduct, szAttribute,
838 &buffer, pcchValueBuf );
841 UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid,
842 MSIINSTALLCONTEXT dwContext, LPCSTR szProperty,
843 LPSTR szValue, LPDWORD pcchValue)
845 LPWSTR product = NULL;
846 LPWSTR usersid = NULL;
847 LPWSTR property = NULL;
848 LPWSTR value = NULL;
849 DWORD len = 0;
850 UINT r;
852 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_a(szProductCode),
853 debugstr_a(szUserSid), dwContext, debugstr_a(szProperty),
854 szValue, pcchValue);
856 if (szValue && !pcchValue)
857 return ERROR_INVALID_PARAMETER;
859 if (szProductCode) product = strdupAtoW(szProductCode);
860 if (szUserSid) usersid = strdupAtoW(szUserSid);
861 if (szProperty) property = strdupAtoW(szProperty);
863 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
864 NULL, &len);
865 if (r != ERROR_SUCCESS)
866 goto done;
868 value = msi_alloc(++len * sizeof(WCHAR));
869 if (!value)
871 r = ERROR_OUTOFMEMORY;
872 goto done;
875 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
876 value, &len);
877 if (r != ERROR_SUCCESS)
878 goto done;
880 if (!pcchValue)
881 goto done;
883 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
884 if (*pcchValue >= len)
885 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
886 else if (szValue)
888 r = ERROR_MORE_DATA;
889 if (*pcchValue > 0)
890 *szValue = '\0';
893 if (*pcchValue <= len || !szValue)
894 len = len * sizeof(WCHAR) - 1;
896 *pcchValue = len - 1;
898 done:
899 msi_free(product);
900 msi_free(usersid);
901 msi_free(property);
902 msi_free(value);
904 return r;
907 static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
909 UINT r;
911 if (!val)
912 return ERROR_UNKNOWN_PROPERTY;
914 if (out)
916 if (lstrlenW(val) >= *size)
918 r = ERROR_MORE_DATA;
919 if (*size > 0)
920 *out = '\0';
922 else
923 lstrcpyW(out, val);
926 if (size)
927 *size = lstrlenW(val);
929 return ERROR_SUCCESS;
932 UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
933 MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty,
934 LPWSTR szValue, LPDWORD pcchValue)
936 WCHAR squished_pc[GUID_SIZE];
937 LPWSTR val = NULL;
938 LPCWSTR package = NULL;
939 HKEY props = NULL, prod;
940 HKEY classes = NULL, managed;
941 HKEY hkey = NULL;
942 DWORD type;
943 UINT r = ERROR_UNKNOWN_PRODUCT;
945 static const WCHAR one[] = {'1',0};
946 static const WCHAR five[] = {'5',0};
947 static const WCHAR empty[] = {0};
948 static const WCHAR displayname[] = {
949 'D','i','s','p','l','a','y','N','a','m','e',0};
950 static const WCHAR displayversion[] = {
951 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
952 static const WCHAR managed_local_package[] = {
953 'M','a','n','a','g','e','d','L','o','c','a','l',
954 'P','a','c','k','a','g','e',0};
956 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_w(szProductCode),
957 debugstr_w(szUserSid), dwContext, debugstr_w(szProperty),
958 szValue, pcchValue);
960 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
961 return ERROR_INVALID_PARAMETER;
963 if (szValue && !pcchValue)
964 return ERROR_INVALID_PARAMETER;
966 if (dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
967 dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
968 dwContext != MSIINSTALLCONTEXT_MACHINE)
969 return ERROR_INVALID_PARAMETER;
971 if (!szProperty || !*szProperty)
972 return ERROR_INVALID_PARAMETER;
974 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
975 return ERROR_INVALID_PARAMETER;
977 MSIREG_OpenLocalManagedProductKey(szProductCode, &managed, FALSE);
978 MSIREG_OpenUserProductsKey(szProductCode, &prod, FALSE);
980 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
982 package = INSTALLPROPERTY_LOCALPACKAGEW;
983 MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
985 if (!props && !prod)
986 goto done;
988 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
990 package = managed_local_package;
991 MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
993 if (!props && !managed)
994 goto done;
996 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
998 package = INSTALLPROPERTY_LOCALPACKAGEW;
999 MSIREG_OpenLocalSystemProductKey(szProductCode, &props, FALSE);
1000 MSIREG_OpenLocalClassesProductKey(szProductCode, &classes, FALSE);
1002 if (!props && !classes)
1003 goto done;
1006 if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) ||
1007 !lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) ||
1008 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) ||
1009 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
1010 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) ||
1011 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) ||
1012 !lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) ||
1013 !lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) ||
1014 !lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) ||
1015 !lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) ||
1016 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) ||
1017 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) ||
1018 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) ||
1019 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) ||
1020 !lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) ||
1021 !lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) ||
1022 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW))
1024 val = msi_reg_get_value(props, package, &type);
1025 if (!val)
1027 if (prod || classes)
1028 r = ERROR_UNKNOWN_PROPERTY;
1030 goto done;
1033 msi_free(val);
1035 if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
1036 szProperty = displayname;
1037 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW))
1038 szProperty = displayversion;
1040 val = msi_reg_get_value(props, szProperty, &type);
1041 if (!val)
1042 val = strdupW(empty);
1044 r = msi_copy_outval(val, szValue, pcchValue);
1046 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
1047 !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
1048 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
1049 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
1050 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
1051 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
1052 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
1053 !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
1055 if (!prod && !classes)
1056 goto done;
1058 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1059 hkey = prod;
1060 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1061 hkey = managed;
1062 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1063 hkey = classes;
1065 val = msi_reg_get_value(hkey, szProperty, &type);
1066 if (!val)
1067 val = strdupW(empty);
1069 r = msi_copy_outval(val, szValue, pcchValue);
1071 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
1073 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1075 if (props)
1077 val = msi_reg_get_value(props, package, &type);
1078 if (!val)
1079 goto done;
1081 msi_free(val);
1082 val = strdupW(five);
1084 else
1085 val = strdupW(one);
1087 r = msi_copy_outval(val, szValue, pcchValue);
1088 goto done;
1090 else if (props && (val = msi_reg_get_value(props, package, &type)))
1092 msi_free(val);
1093 val = strdupW(five);
1094 r = msi_copy_outval(val, szValue, pcchValue);
1095 goto done;
1098 if (prod || managed)
1099 val = strdupW(one);
1100 else
1101 goto done;
1103 r = msi_copy_outval(val, szValue, pcchValue);
1105 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
1107 if (!prod && !classes)
1108 goto done;
1110 /* FIXME */
1111 val = strdupW(empty);
1112 r = msi_copy_outval(val, szValue, pcchValue);
1114 else
1115 r = ERROR_UNKNOWN_PROPERTY;
1117 done:
1118 RegCloseKey(props);
1119 RegCloseKey(prod);
1120 RegCloseKey(managed);
1121 RegCloseKey(classes);
1122 msi_free(val);
1124 return r;
1127 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
1129 LPWSTR szwLogFile = NULL;
1130 UINT r;
1132 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
1134 if( szLogFile )
1136 szwLogFile = strdupAtoW( szLogFile );
1137 if( !szwLogFile )
1138 return ERROR_OUTOFMEMORY;
1140 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
1141 msi_free( szwLogFile );
1142 return r;
1145 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
1147 HANDLE file = INVALID_HANDLE_VALUE;
1149 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
1151 if (szLogFile)
1153 lstrcpyW(gszLogFile,szLogFile);
1154 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
1155 DeleteFileW(szLogFile);
1156 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
1157 FILE_ATTRIBUTE_NORMAL, NULL);
1158 if (file != INVALID_HANDLE_VALUE)
1159 CloseHandle(file);
1160 else
1161 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
1163 else
1164 gszLogFile[0] = '\0';
1166 return ERROR_SUCCESS;
1169 UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
1170 DWORD dwIndex, INSTALLSTATE iState,
1171 LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
1172 int *piCost, int *pTempCost)
1174 FIXME("(%ld, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
1175 debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
1176 pcchDriveBuf, piCost, pTempCost);
1178 return ERROR_NO_MORE_ITEMS;
1181 UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
1182 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1183 LPCSTR szComponent, INSTALLSTATE *pdwState)
1185 LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
1186 UINT r;
1188 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
1189 debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
1191 if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
1192 return ERROR_OUTOFMEMORY;
1194 if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
1195 return ERROR_OUTOFMEMORY;
1197 if (szComponent && !(comp = strdupAtoW(szComponent)))
1198 return ERROR_OUTOFMEMORY;
1200 r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
1202 msi_free(prodcode);
1203 msi_free(usersid);
1204 msi_free(comp);
1206 return r;
1209 static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1211 UINT r;
1212 HKEY hkey;
1214 if (context == MSIINSTALLCONTEXT_MACHINE)
1215 r = MSIREG_OpenLocalClassesProductKey(prodcode, &hkey, FALSE);
1216 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
1217 r = MSIREG_OpenUserProductsKey(prodcode, &hkey, FALSE);
1218 else
1219 r = MSIREG_OpenLocalManagedProductKey(prodcode, &hkey, FALSE);
1221 RegCloseKey(hkey);
1222 return (r == ERROR_SUCCESS);
1225 static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1227 LPCWSTR package;
1228 HKEY hkey;
1229 DWORD sz;
1230 LONG res;
1231 UINT r;
1233 static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
1234 static const WCHAR managed_local_package[] = {
1235 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
1238 if (context == MSIINSTALLCONTEXT_MACHINE)
1239 r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
1240 else
1241 r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
1243 if (r != ERROR_SUCCESS)
1244 return FALSE;
1246 if (context == MSIINSTALLCONTEXT_USERMANAGED)
1247 package = managed_local_package;
1248 else
1249 package = local_package;
1251 sz = 0;
1252 res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
1253 RegCloseKey(hkey);
1255 return (res == ERROR_SUCCESS);
1258 static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
1259 MSIINSTALLCONTEXT context,
1260 LPCWSTR comp, DWORD *sz)
1262 HKEY hkey;
1263 LONG res;
1264 UINT r;
1266 if (context == MSIINSTALLCONTEXT_MACHINE)
1267 r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
1268 else
1269 r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1271 if (r != ERROR_SUCCESS)
1272 return FALSE;
1274 *sz = 0;
1275 res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, sz);
1276 if (res != ERROR_SUCCESS)
1277 return FALSE;
1279 RegCloseKey(hkey);
1280 return TRUE;
1283 UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
1284 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1285 LPCWSTR szComponent, INSTALLSTATE *pdwState)
1287 WCHAR squished_pc[GUID_SIZE];
1288 BOOL found;
1289 DWORD sz;
1291 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
1292 debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
1294 if (!pdwState)
1295 return ERROR_INVALID_PARAMETER;
1297 if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
1298 return ERROR_INVALID_PARAMETER;
1300 if (!squash_guid(szProductCode, squished_pc))
1301 return ERROR_INVALID_PARAMETER;
1303 found = msi_comp_find_prod_key(szProductCode, dwContext);
1305 if (!msi_comp_find_package(szProductCode, dwContext))
1307 if (found)
1309 *pdwState = INSTALLSTATE_UNKNOWN;
1310 return ERROR_UNKNOWN_COMPONENT;
1313 return ERROR_UNKNOWN_PRODUCT;
1316 *pdwState = INSTALLSTATE_UNKNOWN;
1318 if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, &sz))
1319 return ERROR_UNKNOWN_COMPONENT;
1321 if (sz == 0)
1322 *pdwState = INSTALLSTATE_NOTUSED;
1323 else
1324 *pdwState = INSTALLSTATE_LOCAL;
1326 return ERROR_SUCCESS;
1329 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
1331 LPWSTR szwProduct = NULL;
1332 INSTALLSTATE r;
1334 if( szProduct )
1336 szwProduct = strdupAtoW( szProduct );
1337 if( !szwProduct )
1338 return ERROR_OUTOFMEMORY;
1340 r = MsiQueryProductStateW( szwProduct );
1341 msi_free( szwProduct );
1342 return r;
1345 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
1347 INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
1348 HKEY prodkey = 0, userdata = 0;
1349 BOOL user = TRUE;
1350 DWORD val;
1351 UINT r;
1353 static const WCHAR szWindowsInstaller[] = {
1354 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1356 TRACE("%s\n", debugstr_w(szProduct));
1358 if (!szProduct || !*szProduct)
1359 return INSTALLSTATE_INVALIDARG;
1361 if (lstrlenW(szProduct) != GUID_SIZE - 1)
1362 return INSTALLSTATE_INVALIDARG;
1364 r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
1365 if (r != ERROR_SUCCESS)
1367 r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
1368 if (r != ERROR_SUCCESS)
1370 r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
1371 if (r == ERROR_SUCCESS)
1372 user = FALSE;
1376 if (user)
1378 r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
1379 if (r != ERROR_SUCCESS)
1380 goto done;
1382 else
1384 r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
1385 if (r != ERROR_SUCCESS)
1386 goto done;
1389 if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
1390 goto done;
1392 if (val)
1393 state = INSTALLSTATE_DEFAULT;
1394 else
1395 state = INSTALLSTATE_UNKNOWN;
1397 done:
1398 if (!prodkey)
1400 state = INSTALLSTATE_UNKNOWN;
1402 if (userdata)
1403 state = INSTALLSTATE_ABSENT;
1406 RegCloseKey(prodkey);
1407 RegCloseKey(userdata);
1408 return state;
1411 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
1413 INSTALLUILEVEL old = gUILevel;
1414 HWND oldwnd = gUIhwnd;
1416 TRACE("%08x %p\n", dwUILevel, phWnd);
1418 gUILevel = dwUILevel;
1419 if (phWnd)
1421 gUIhwnd = *phWnd;
1422 *phWnd = oldwnd;
1424 return old;
1427 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
1428 DWORD dwMessageFilter, LPVOID pvContext)
1430 INSTALLUI_HANDLERA prev = gUIHandlerA;
1432 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
1433 gUIHandlerA = puiHandler;
1434 gUIFilter = dwMessageFilter;
1435 gUIContext = pvContext;
1437 return prev;
1440 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
1441 DWORD dwMessageFilter, LPVOID pvContext)
1443 INSTALLUI_HANDLERW prev = gUIHandlerW;
1445 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
1446 gUIHandlerW = puiHandler;
1447 gUIFilter = dwMessageFilter;
1448 gUIContext = pvContext;
1450 return prev;
1453 /******************************************************************
1454 * MsiLoadStringW [MSI.@]
1456 * Loads a string from MSI's string resources.
1458 * PARAMS
1460 * handle [I] only -1 is handled currently
1461 * id [I] id of the string to be loaded
1462 * lpBuffer [O] buffer for the string to be written to
1463 * nBufferMax [I] maximum size of the buffer in characters
1464 * lang [I] the preferred language for the string
1466 * RETURNS
1468 * If successful, this function returns the language id of the string loaded
1469 * If the function fails, the function returns zero.
1471 * NOTES
1473 * The type of the first parameter is unknown. LoadString's prototype
1474 * suggests that it might be a module handle. I have made it an MSI handle
1475 * for starters, as -1 is an invalid MSI handle, but not an invalid module
1476 * handle. Maybe strings can be stored in an MSI database somehow.
1478 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
1479 int nBufferMax, LANGID lang )
1481 HRSRC hres;
1482 HGLOBAL hResData;
1483 LPWSTR p;
1484 DWORD i, len;
1486 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
1488 if( handle != -1 )
1489 FIXME("don't know how to deal with handle = %08lx\n", handle);
1491 if( !lang )
1492 lang = GetUserDefaultLangID();
1494 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
1495 (LPWSTR)1, lang );
1496 if( !hres )
1497 return 0;
1498 hResData = LoadResource( msi_hInstance, hres );
1499 if( !hResData )
1500 return 0;
1501 p = LockResource( hResData );
1502 if( !p )
1503 return 0;
1505 for (i = 0; i < (id&0xf); i++)
1506 p += *p + 1;
1507 len = *p;
1509 if( nBufferMax <= len )
1510 return 0;
1512 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
1513 lpBuffer[ len ] = 0;
1515 TRACE("found -> %s\n", debugstr_w(lpBuffer));
1517 return lang;
1520 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
1521 int nBufferMax, LANGID lang )
1523 LPWSTR bufW;
1524 LANGID r;
1525 DWORD len;
1527 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
1528 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
1529 if( r )
1531 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
1532 if( len <= nBufferMax )
1533 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
1534 lpBuffer, nBufferMax, NULL, NULL );
1535 else
1536 r = 0;
1538 msi_free(bufW);
1539 return r;
1542 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
1543 LPDWORD pcchBuf)
1545 char szProduct[GUID_SIZE];
1547 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
1549 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
1550 return INSTALLSTATE_UNKNOWN;
1552 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
1555 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
1556 LPDWORD pcchBuf)
1558 WCHAR szProduct[GUID_SIZE];
1560 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
1562 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
1563 return INSTALLSTATE_UNKNOWN;
1565 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
1568 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
1569 WORD wLanguageId, DWORD f)
1571 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
1572 uType, wLanguageId, f);
1573 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
1576 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
1577 WORD wLanguageId, DWORD f)
1579 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
1580 uType, wLanguageId, f);
1581 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
1584 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
1585 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
1586 LPDWORD pcchPathBuf )
1588 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
1589 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1590 pcchPathBuf);
1591 return ERROR_CALL_NOT_IMPLEMENTED;
1594 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
1595 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
1596 LPDWORD pcchPathBuf )
1598 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
1599 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1600 pcchPathBuf);
1601 return ERROR_CALL_NOT_IMPLEMENTED;
1604 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
1605 LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1607 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
1608 return ERROR_CALL_NOT_IMPLEMENTED;
1611 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
1612 LPWSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1614 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
1615 return ERROR_CALL_NOT_IMPLEMENTED;
1618 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
1619 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1620 LPDWORD pcbHashData)
1622 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
1623 ppcCertContext, pbHashData, pcbHashData);
1624 return ERROR_CALL_NOT_IMPLEMENTED;
1627 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1628 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1629 LPDWORD pcbHashData)
1631 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1632 ppcCertContext, pbHashData, pcbHashData);
1633 return ERROR_CALL_NOT_IMPLEMENTED;
1636 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
1637 LPSTR szValue, LPDWORD pccbValue )
1639 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
1640 return ERROR_CALL_NOT_IMPLEMENTED;
1643 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
1644 LPWSTR szValue, LPDWORD pccbValue )
1646 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
1647 return ERROR_CALL_NOT_IMPLEMENTED;
1650 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
1652 UINT r;
1653 LPWSTR szPack = NULL;
1655 TRACE("%s\n", debugstr_a(szPackage) );
1657 if( szPackage )
1659 szPack = strdupAtoW( szPackage );
1660 if( !szPack )
1661 return ERROR_OUTOFMEMORY;
1664 r = MsiVerifyPackageW( szPack );
1666 msi_free( szPack );
1668 return r;
1671 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
1673 MSIHANDLE handle;
1674 UINT r;
1676 TRACE("%s\n", debugstr_w(szPackage) );
1678 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
1679 MsiCloseHandle( handle );
1681 return r;
1684 static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
1685 awstring* lpPathBuf, LPDWORD pcchBuf)
1687 WCHAR squished_pc[GUID_SIZE];
1688 WCHAR squished_comp[GUID_SIZE];
1689 HKEY hkey;
1690 LPWSTR path = NULL;
1691 INSTALLSTATE state;
1692 DWORD version;
1694 static const WCHAR wininstaller[] = {
1695 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1697 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1698 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
1700 if (!szProduct || !szComponent)
1701 return INSTALLSTATE_INVALIDARG;
1703 if (lpPathBuf->str.w && !pcchBuf)
1704 return INSTALLSTATE_INVALIDARG;
1706 if (!squash_guid(szProduct, squished_pc) ||
1707 !squash_guid(szComponent, squished_comp))
1708 return INSTALLSTATE_INVALIDARG;
1710 state = INSTALLSTATE_UNKNOWN;
1712 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1713 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1715 path = msi_reg_get_val_str(hkey, squished_pc);
1716 RegCloseKey(hkey);
1718 state = INSTALLSTATE_ABSENT;
1720 if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1721 MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
1722 msi_reg_get_val_dword(hkey, wininstaller, &version) &&
1723 GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1725 RegCloseKey(hkey);
1726 state = INSTALLSTATE_LOCAL;
1730 if (state != INSTALLSTATE_LOCAL &&
1731 (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1732 MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS))
1734 RegCloseKey(hkey);
1736 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1737 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1739 msi_free(path);
1740 path = msi_reg_get_val_str(hkey, squished_pc);
1741 RegCloseKey(hkey);
1743 state = INSTALLSTATE_ABSENT;
1745 if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1746 state = INSTALLSTATE_LOCAL;
1750 if (!path)
1751 return INSTALLSTATE_UNKNOWN;
1753 if (state == INSTALLSTATE_LOCAL && !*path)
1754 state = INSTALLSTATE_NOTUSED;
1756 msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
1757 msi_free(path);
1758 return state;
1761 /******************************************************************
1762 * MsiGetComponentPathW [MSI.@]
1764 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1765 LPWSTR lpPathBuf, LPDWORD pcchBuf)
1767 awstring path;
1769 path.unicode = TRUE;
1770 path.str.w = lpPathBuf;
1772 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1775 /******************************************************************
1776 * MsiGetComponentPathA [MSI.@]
1778 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1779 LPSTR lpPathBuf, LPDWORD pcchBuf)
1781 LPWSTR szwProduct, szwComponent = NULL;
1782 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1783 awstring path;
1785 szwProduct = strdupAtoW( szProduct );
1786 if( szProduct && !szwProduct)
1787 goto end;
1789 szwComponent = strdupAtoW( szComponent );
1790 if( szComponent && !szwComponent )
1791 goto end;
1793 path.unicode = FALSE;
1794 path.str.a = lpPathBuf;
1796 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1798 end:
1799 msi_free( szwProduct );
1800 msi_free( szwComponent );
1802 return r;
1805 /******************************************************************
1806 * MsiQueryFeatureStateA [MSI.@]
1808 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1810 LPWSTR szwProduct = NULL, szwFeature= NULL;
1811 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1813 szwProduct = strdupAtoW( szProduct );
1814 if ( szProduct && !szwProduct )
1815 goto end;
1817 szwFeature = strdupAtoW( szFeature );
1818 if ( szFeature && !szwFeature )
1819 goto end;
1821 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1823 end:
1824 msi_free( szwProduct);
1825 msi_free( szwFeature);
1827 return rc;
1830 /******************************************************************
1831 * MsiQueryFeatureStateW [MSI.@]
1833 * Checks the state of a feature
1835 * PARAMS
1836 * szProduct [I] Product's GUID string
1837 * szFeature [I] Feature's GUID string
1839 * RETURNS
1840 * INSTALLSTATE_LOCAL Feature is installed and usable
1841 * INSTALLSTATE_ABSENT Feature is absent
1842 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1843 * INSTALLSTATE_UNKNOWN An error occurred
1844 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1847 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1849 WCHAR squishProduct[33], comp[GUID_SIZE];
1850 GUID guid;
1851 LPWSTR components, p, parent_feature, path;
1852 UINT rc;
1853 HKEY hkey;
1854 INSTALLSTATE r;
1855 BOOL missing = FALSE;
1856 BOOL machine = FALSE;
1858 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1860 if (!szProduct || !szFeature)
1861 return INSTALLSTATE_INVALIDARG;
1863 if (!squash_guid( szProduct, squishProduct ))
1864 return INSTALLSTATE_INVALIDARG;
1866 if (MSIREG_OpenManagedFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
1867 MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
1869 rc = MSIREG_OpenLocalClassesFeaturesKey(szProduct, &hkey, FALSE);
1870 if (rc != ERROR_SUCCESS)
1871 return INSTALLSTATE_UNKNOWN;
1873 machine = TRUE;
1876 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1877 RegCloseKey(hkey);
1879 if (!parent_feature)
1880 return INSTALLSTATE_UNKNOWN;
1882 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1883 msi_free(parent_feature);
1884 if (r == INSTALLSTATE_ABSENT)
1885 return r;
1887 if (machine)
1888 rc = MSIREG_OpenLocalUserDataFeaturesKey(szProduct, &hkey, FALSE);
1889 else
1890 rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE);
1892 if (rc != ERROR_SUCCESS)
1893 return INSTALLSTATE_ADVERTISED;
1895 components = msi_reg_get_val_str( hkey, szFeature );
1896 RegCloseKey(hkey);
1898 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1900 if (!components)
1901 return INSTALLSTATE_ADVERTISED;
1903 for( p = components; *p && *p != 2 ; p += 20)
1905 if (!decode_base85_guid( p, &guid ))
1907 if (p != components)
1908 break;
1910 msi_free(components);
1911 return INSTALLSTATE_BADCONFIG;
1914 StringFromGUID2(&guid, comp, GUID_SIZE);
1916 if (machine)
1917 rc = MSIREG_OpenLocalUserDataComponentKey(comp, &hkey, FALSE);
1918 else
1919 rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1921 if (rc != ERROR_SUCCESS)
1923 msi_free(components);
1924 return INSTALLSTATE_ADVERTISED;
1927 path = msi_reg_get_val_str(hkey, squishProduct);
1928 if (!path)
1929 missing = TRUE;
1931 msi_free(path);
1934 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1935 msi_free(components);
1937 if (missing)
1938 return INSTALLSTATE_ADVERTISED;
1940 return INSTALLSTATE_LOCAL;
1943 /******************************************************************
1944 * MsiGetFileVersionA [MSI.@]
1946 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1947 LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
1949 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1950 UINT ret = ERROR_OUTOFMEMORY;
1952 if ((lpVersionBuf && !pcchVersionBuf) ||
1953 (lpLangBuf && !pcchLangBuf))
1954 return ERROR_INVALID_PARAMETER;
1956 if( szFilePath )
1958 szwFilePath = strdupAtoW( szFilePath );
1959 if( !szwFilePath )
1960 goto end;
1963 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1965 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1966 if( !lpwVersionBuff )
1967 goto end;
1970 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1972 lpwLangBuff = msi_alloc(*pcchLangBuf*sizeof(WCHAR));
1973 if( !lpwLangBuff )
1974 goto end;
1977 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1978 lpwLangBuff, pcchLangBuf);
1980 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwVersionBuff )
1981 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1982 lpVersionBuf, *pcchVersionBuf + 1, NULL, NULL);
1983 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwLangBuff )
1984 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1985 lpLangBuf, *pcchLangBuf + 1, NULL, NULL);
1987 end:
1988 msi_free(szwFilePath);
1989 msi_free(lpwVersionBuff);
1990 msi_free(lpwLangBuff);
1992 return ret;
1995 /******************************************************************
1996 * MsiGetFileVersionW [MSI.@]
1998 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1999 LPDWORD pcchVersionBuf, LPWSTR lpLangBuf, LPDWORD pcchLangBuf)
2001 static const WCHAR szVersionResource[] = {'\\',0};
2002 static const WCHAR szVersionFormat[] = {
2003 '%','d','.','%','d','.','%','d','.','%','d',0};
2004 static const WCHAR szLangResource[] = {
2005 '\\','V','a','r','F','i','l','e','I','n','f','o','\\',
2006 'T','r','a','n','s','l','a','t','i','o','n',0};
2007 static const WCHAR szLangFormat[] = {'%','d',0};
2008 UINT ret = 0;
2009 DWORD dwVerLen, gle;
2010 LPVOID lpVer = NULL;
2011 VS_FIXEDFILEINFO *ffi;
2012 USHORT *lang;
2013 UINT puLen;
2014 WCHAR tmp[32];
2016 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
2017 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
2018 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
2020 if ((lpVersionBuf && !pcchVersionBuf) ||
2021 (lpLangBuf && !pcchLangBuf))
2022 return ERROR_INVALID_PARAMETER;
2024 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
2025 if( !dwVerLen )
2027 gle = GetLastError();
2028 if (gle == ERROR_BAD_PATHNAME)
2029 return ERROR_FILE_NOT_FOUND;
2030 else if (gle == ERROR_RESOURCE_DATA_NOT_FOUND)
2031 return ERROR_FILE_INVALID;
2033 return gle;
2036 lpVer = msi_alloc(dwVerLen);
2037 if( !lpVer )
2039 ret = ERROR_OUTOFMEMORY;
2040 goto end;
2043 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
2045 ret = GetLastError();
2046 goto end;
2049 if (pcchVersionBuf)
2051 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
2052 (puLen > 0) )
2054 wsprintfW(tmp, szVersionFormat,
2055 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
2056 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
2057 if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
2059 if (lstrlenW(tmp) >= *pcchVersionBuf)
2060 ret = ERROR_MORE_DATA;
2062 *pcchVersionBuf = lstrlenW(tmp);
2064 else
2066 if (lpVersionBuf) *lpVersionBuf = 0;
2067 *pcchVersionBuf = 0;
2071 if (pcchLangBuf)
2073 if (VerQueryValueW(lpVer, szLangResource, (LPVOID*)&lang, &puLen) &&
2074 (puLen > 0))
2076 wsprintfW(tmp, szLangFormat, *lang);
2077 if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
2079 if (lstrlenW(tmp) >= *pcchLangBuf)
2080 ret = ERROR_MORE_DATA;
2082 *pcchLangBuf = lstrlenW(tmp);
2084 else
2086 if (lpLangBuf) *lpLangBuf = 0;
2087 *pcchLangBuf = 0;
2091 end:
2092 msi_free(lpVer);
2093 return ret;
2096 /***********************************************************************
2097 * MsiGetFeatureUsageW [MSI.@]
2099 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
2100 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2102 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
2103 pdwUseCount, pwDateUsed);
2104 return ERROR_CALL_NOT_IMPLEMENTED;
2107 /***********************************************************************
2108 * MsiGetFeatureUsageA [MSI.@]
2110 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
2111 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2113 LPWSTR prod = NULL, feat = NULL;
2114 UINT ret = ERROR_OUTOFMEMORY;
2116 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
2117 pdwUseCount, pwDateUsed);
2119 prod = strdupAtoW( szProduct );
2120 if (szProduct && !prod)
2121 goto end;
2123 feat = strdupAtoW( szFeature );
2124 if (szFeature && !feat)
2125 goto end;
2127 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
2129 end:
2130 msi_free( prod );
2131 msi_free( feat );
2133 return ret;
2136 /***********************************************************************
2137 * MsiUseFeatureExW [MSI.@]
2139 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
2140 DWORD dwInstallMode, DWORD dwReserved )
2142 INSTALLSTATE state;
2144 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2145 dwInstallMode, dwReserved);
2147 state = MsiQueryFeatureStateW( szProduct, szFeature );
2149 if (dwReserved)
2150 return INSTALLSTATE_INVALIDARG;
2152 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
2154 FIXME("mark product %s feature %s as used\n",
2155 debugstr_w(szProduct), debugstr_w(szFeature) );
2158 return state;
2161 /***********************************************************************
2162 * MsiUseFeatureExA [MSI.@]
2164 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
2165 DWORD dwInstallMode, DWORD dwReserved )
2167 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
2168 LPWSTR prod = NULL, feat = NULL;
2170 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2171 dwInstallMode, dwReserved);
2173 prod = strdupAtoW( szProduct );
2174 if (szProduct && !prod)
2175 goto end;
2177 feat = strdupAtoW( szFeature );
2178 if (szFeature && !feat)
2179 goto end;
2181 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
2183 end:
2184 msi_free( prod );
2185 msi_free( feat );
2187 return ret;
2190 /***********************************************************************
2191 * MsiUseFeatureW [MSI.@]
2193 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
2195 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
2198 /***********************************************************************
2199 * MsiUseFeatureA [MSI.@]
2201 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
2203 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
2206 /***********************************************************************
2207 * MSI_ProvideQualifiedComponentEx [internal]
2209 static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
2210 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2211 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
2212 LPDWORD pcchPathBuf)
2214 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
2215 feature[MAX_FEATURE_CHARS+1];
2216 LPWSTR info;
2217 HKEY hkey;
2218 DWORD sz;
2219 UINT rc;
2221 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
2222 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
2223 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2225 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
2226 if (rc != ERROR_SUCCESS)
2227 return ERROR_INDEX_ABSENT;
2229 info = msi_reg_get_val_str( hkey, szQualifier );
2230 RegCloseKey(hkey);
2232 if (!info)
2233 return ERROR_INDEX_ABSENT;
2235 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
2237 if (!szProduct)
2238 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
2239 else
2240 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
2242 msi_free( info );
2244 if (rc != INSTALLSTATE_LOCAL)
2245 return ERROR_FILE_NOT_FOUND;
2247 return ERROR_SUCCESS;
2250 /***********************************************************************
2251 * MsiProvideQualifiedComponentExW [MSI.@]
2253 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
2254 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2255 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
2256 LPDWORD pcchPathBuf)
2258 awstring path;
2260 path.unicode = TRUE;
2261 path.str.w = lpPathBuf;
2263 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
2264 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
2267 /***********************************************************************
2268 * MsiProvideQualifiedComponentExA [MSI.@]
2270 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
2271 LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
2272 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
2273 LPDWORD pcchPathBuf)
2275 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
2276 UINT r = ERROR_OUTOFMEMORY;
2277 awstring path;
2279 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
2280 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
2281 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2283 szwComponent = strdupAtoW( szComponent );
2284 if (szComponent && !szwComponent)
2285 goto end;
2287 szwQualifier = strdupAtoW( szQualifier );
2288 if (szQualifier && !szwQualifier)
2289 goto end;
2291 szwProduct = strdupAtoW( szProduct );
2292 if (szProduct && !szwProduct)
2293 goto end;
2295 path.unicode = FALSE;
2296 path.str.a = lpPathBuf;
2298 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
2299 dwInstallMode, szwProduct, Unused1,
2300 Unused2, &path, pcchPathBuf);
2301 end:
2302 msi_free(szwProduct);
2303 msi_free(szwComponent);
2304 msi_free(szwQualifier);
2306 return r;
2309 /***********************************************************************
2310 * MsiProvideQualifiedComponentW [MSI.@]
2312 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
2313 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
2314 LPDWORD pcchPathBuf)
2316 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
2317 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2320 /***********************************************************************
2321 * MsiProvideQualifiedComponentA [MSI.@]
2323 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
2324 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
2325 LPDWORD pcchPathBuf)
2327 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
2328 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2331 /***********************************************************************
2332 * MSI_GetUserInfo [internal]
2334 static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
2335 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
2336 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2337 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
2339 WCHAR squished_pc[SQUISH_GUID_SIZE];
2340 LPWSTR user, org, serial;
2341 USERINFOSTATE state;
2342 HKEY hkey, props;
2343 LPCWSTR orgptr;
2344 UINT r;
2346 static const WCHAR szEmpty[] = {0};
2348 TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
2349 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
2350 pcchSerialBuf);
2352 if (!szProduct || !squash_guid(szProduct, squished_pc))
2353 return USERINFOSTATE_INVALIDARG;
2355 if (MSIREG_OpenLocalManagedProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
2356 MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
2357 MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
2359 return USERINFOSTATE_UNKNOWN;
2362 if (MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS &&
2363 MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS)
2365 RegCloseKey(hkey);
2366 return USERINFOSTATE_ABSENT;
2369 user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW);
2370 org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW);
2371 serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW);
2372 state = USERINFOSTATE_ABSENT;
2374 RegCloseKey(hkey);
2375 RegCloseKey(props);
2377 if (user && serial)
2378 state = USERINFOSTATE_PRESENT;
2380 if (pcchUserNameBuf)
2382 if (lpUserNameBuf && !user)
2384 (*pcchUserNameBuf)--;
2385 goto done;
2388 r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf);
2389 if (r == ERROR_MORE_DATA)
2391 state = USERINFOSTATE_MOREDATA;
2392 goto done;
2396 if (pcchOrgNameBuf)
2398 orgptr = org;
2399 if (!orgptr) orgptr = szEmpty;
2401 r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf);
2402 if (r == ERROR_MORE_DATA)
2404 state = USERINFOSTATE_MOREDATA;
2405 goto done;
2409 if (pcchSerialBuf)
2411 if (!serial)
2413 (*pcchSerialBuf)--;
2414 goto done;
2417 r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf);
2418 if (r == ERROR_MORE_DATA)
2419 state = USERINFOSTATE_MOREDATA;
2422 done:
2423 msi_free(user);
2424 msi_free(org);
2425 msi_free(serial);
2427 return state;
2430 /***********************************************************************
2431 * MsiGetUserInfoW [MSI.@]
2433 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
2434 LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2435 LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2436 LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2438 awstring user, org, serial;
2440 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2441 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2442 (lpSerialBuf && !pcchSerialBuf))
2443 return USERINFOSTATE_INVALIDARG;
2445 user.unicode = TRUE;
2446 user.str.w = lpUserNameBuf;
2447 org.unicode = TRUE;
2448 org.str.w = lpOrgNameBuf;
2449 serial.unicode = TRUE;
2450 serial.str.w = lpSerialBuf;
2452 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
2453 &org, pcchOrgNameBuf,
2454 &serial, pcchSerialBuf );
2457 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
2458 LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2459 LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2460 LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2462 awstring user, org, serial;
2463 LPWSTR prod;
2464 UINT r;
2466 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2467 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2468 (lpSerialBuf && !pcchSerialBuf))
2469 return USERINFOSTATE_INVALIDARG;
2471 prod = strdupAtoW( szProduct );
2472 if (szProduct && !prod)
2473 return ERROR_OUTOFMEMORY;
2475 user.unicode = FALSE;
2476 user.str.a = lpUserNameBuf;
2477 org.unicode = FALSE;
2478 org.str.a = lpOrgNameBuf;
2479 serial.unicode = FALSE;
2480 serial.str.a = lpSerialBuf;
2482 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
2483 &org, pcchOrgNameBuf,
2484 &serial, pcchSerialBuf );
2486 msi_free( prod );
2488 return r;
2491 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
2493 MSIHANDLE handle;
2494 UINT rc;
2495 MSIPACKAGE *package;
2496 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2498 TRACE("(%s)\n",debugstr_w(szProduct));
2500 rc = MsiOpenProductW(szProduct,&handle);
2501 if (rc != ERROR_SUCCESS)
2502 return ERROR_INVALID_PARAMETER;
2504 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2505 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2506 msiobj_release( &package->hdr );
2508 MsiCloseHandle(handle);
2510 return rc;
2513 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
2515 MSIHANDLE handle;
2516 UINT rc;
2517 MSIPACKAGE *package;
2518 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2520 TRACE("(%s)\n",debugstr_a(szProduct));
2522 rc = MsiOpenProductA(szProduct,&handle);
2523 if (rc != ERROR_SUCCESS)
2524 return ERROR_INVALID_PARAMETER;
2526 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2527 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2528 msiobj_release( &package->hdr );
2530 MsiCloseHandle(handle);
2532 return rc;
2535 /***********************************************************************
2536 * MsiConfigureFeatureA [MSI.@]
2538 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
2540 LPWSTR prod, feat = NULL;
2541 UINT r = ERROR_OUTOFMEMORY;
2543 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
2545 prod = strdupAtoW( szProduct );
2546 if (szProduct && !prod)
2547 goto end;
2549 feat = strdupAtoW( szFeature );
2550 if (szFeature && !feat)
2551 goto end;
2553 r = MsiConfigureFeatureW(prod, feat, eInstallState);
2555 end:
2556 msi_free(feat);
2557 msi_free(prod);
2559 return r;
2562 /***********************************************************************
2563 * MsiConfigureFeatureW [MSI.@]
2565 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
2567 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
2568 MSIPACKAGE *package = NULL;
2569 UINT r;
2570 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
2571 DWORD sz;
2573 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
2575 if (!szProduct || !szFeature)
2576 return ERROR_INVALID_PARAMETER;
2578 switch (eInstallState)
2580 case INSTALLSTATE_DEFAULT:
2581 /* FIXME: how do we figure out the default location? */
2582 eInstallState = INSTALLSTATE_LOCAL;
2583 break;
2584 case INSTALLSTATE_LOCAL:
2585 case INSTALLSTATE_SOURCE:
2586 case INSTALLSTATE_ABSENT:
2587 case INSTALLSTATE_ADVERTISED:
2588 break;
2589 default:
2590 return ERROR_INVALID_PARAMETER;
2593 r = MSI_OpenProductW( szProduct, &package );
2594 if (r != ERROR_SUCCESS)
2595 return r;
2597 sz = sizeof(sourcepath);
2598 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2599 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2601 sz = sizeof(filename);
2602 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2603 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2605 lstrcatW( sourcepath, filename );
2607 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
2609 r = ACTION_PerformUIAction( package, szCostInit, -1 );
2610 if (r != ERROR_SUCCESS)
2611 goto end;
2613 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
2614 if (r != ERROR_SUCCESS)
2615 goto end;
2617 r = MSI_InstallPackage( package, sourcepath, NULL );
2619 end:
2620 msiobj_release( &package->hdr );
2622 return r;
2625 /***********************************************************************
2626 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
2628 * Notes: undocumented
2630 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
2632 WCHAR path[MAX_PATH];
2634 TRACE("%d\n", dwReserved);
2636 if (dwReserved)
2638 FIXME("dwReserved=%d\n", dwReserved);
2639 return ERROR_INVALID_PARAMETER;
2642 if (!GetWindowsDirectoryW(path, MAX_PATH))
2643 return ERROR_FUNCTION_FAILED;
2645 lstrcatW(path, installerW);
2647 if (!CreateDirectoryW(path, NULL))
2648 return ERROR_FUNCTION_FAILED;
2650 return ERROR_SUCCESS;
2653 /***********************************************************************
2654 * MsiGetShortcutTargetA [MSI.@]
2656 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
2657 LPSTR szProductCode, LPSTR szFeatureId,
2658 LPSTR szComponentCode )
2660 LPWSTR target;
2661 const int len = MAX_FEATURE_CHARS+1;
2662 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
2663 UINT r;
2665 target = strdupAtoW( szShortcutTarget );
2666 if (szShortcutTarget && !target )
2667 return ERROR_OUTOFMEMORY;
2668 product[0] = 0;
2669 feature[0] = 0;
2670 component[0] = 0;
2671 r = MsiGetShortcutTargetW( target, product, feature, component );
2672 msi_free( target );
2673 if (r == ERROR_SUCCESS)
2675 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
2676 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
2677 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
2679 return r;
2682 /***********************************************************************
2683 * MsiGetShortcutTargetW [MSI.@]
2685 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
2686 LPWSTR szProductCode, LPWSTR szFeatureId,
2687 LPWSTR szComponentCode )
2689 IShellLinkDataList *dl = NULL;
2690 IPersistFile *pf = NULL;
2691 LPEXP_DARWIN_LINK darwin = NULL;
2692 HRESULT r, init;
2694 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
2695 szProductCode, szFeatureId, szComponentCode );
2697 init = CoInitialize(NULL);
2699 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2700 &IID_IPersistFile, (LPVOID*) &pf );
2701 if( SUCCEEDED( r ) )
2703 r = IPersistFile_Load( pf, szShortcutTarget,
2704 STGM_READ | STGM_SHARE_DENY_WRITE );
2705 if( SUCCEEDED( r ) )
2707 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
2708 (LPVOID*) &dl );
2709 if( SUCCEEDED( r ) )
2711 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
2712 (LPVOID) &darwin );
2713 IShellLinkDataList_Release( dl );
2716 IPersistFile_Release( pf );
2719 if (SUCCEEDED(init))
2720 CoUninitialize();
2722 TRACE("darwin = %p\n", darwin);
2724 if (darwin)
2726 DWORD sz;
2727 UINT ret;
2729 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
2730 szProductCode, szFeatureId, szComponentCode, &sz );
2731 LocalFree( darwin );
2732 return ret;
2735 return ERROR_FUNCTION_FAILED;
2738 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
2739 DWORD dwReinstallMode )
2741 MSIPACKAGE* package = NULL;
2742 UINT r;
2743 WCHAR sourcepath[MAX_PATH];
2744 WCHAR filename[MAX_PATH];
2745 static const WCHAR szLogVerbose[] = {
2746 ' ','L','O','G','V','E','R','B','O','S','E',0 };
2747 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
2748 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
2749 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
2750 static const WCHAR szOne[] = {'1',0};
2751 WCHAR reinstallmode[11];
2752 LPWSTR ptr;
2753 DWORD sz;
2755 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2756 dwReinstallMode);
2758 ptr = reinstallmode;
2760 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
2761 *ptr++ = 'p';
2762 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
2763 *ptr++ = 'o';
2764 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
2765 *ptr++ = 'w';
2766 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
2767 *ptr++ = 'd';
2768 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
2769 *ptr++ = 'c';
2770 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
2771 *ptr++ = 'a';
2772 if (dwReinstallMode & REINSTALLMODE_USERDATA)
2773 *ptr++ = 'u';
2774 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
2775 *ptr++ = 'm';
2776 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
2777 *ptr++ = 's';
2778 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2779 *ptr++ = 'v';
2780 *ptr = 0;
2782 sz = sizeof(sourcepath);
2783 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2784 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2786 sz = sizeof(filename);
2787 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2788 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2790 lstrcatW( sourcepath, filename );
2792 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2793 r = MSI_OpenPackageW( sourcepath, &package );
2794 else
2795 r = MSI_OpenProductW( szProduct, &package );
2797 if (r != ERROR_SUCCESS)
2798 return r;
2800 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
2801 MSI_SetPropertyW( package, szInstalled, szOne );
2802 MSI_SetPropertyW( package, szLogVerbose, szOne );
2803 MSI_SetPropertyW( package, szReinstall, szFeature );
2805 r = MSI_InstallPackage( package, sourcepath, NULL );
2807 msiobj_release( &package->hdr );
2809 return r;
2812 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
2813 DWORD dwReinstallMode )
2815 LPWSTR wszProduct;
2816 LPWSTR wszFeature;
2817 UINT rc;
2819 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2820 dwReinstallMode);
2822 wszProduct = strdupAtoW(szProduct);
2823 wszFeature = strdupAtoW(szFeature);
2825 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
2827 msi_free(wszProduct);
2828 msi_free(wszFeature);
2829 return rc;
2832 typedef struct
2834 unsigned int i[2];
2835 unsigned int buf[4];
2836 unsigned char in[64];
2837 unsigned char digest[16];
2838 } MD5_CTX;
2840 extern VOID WINAPI MD5Init( MD5_CTX *);
2841 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
2842 extern VOID WINAPI MD5Final( MD5_CTX *);
2844 /***********************************************************************
2845 * MsiGetFileHashW [MSI.@]
2847 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2848 PMSIFILEHASHINFO pHash )
2850 HANDLE handle, mapping;
2851 void *p;
2852 DWORD length;
2853 UINT r = ERROR_FUNCTION_FAILED;
2855 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2857 if (!szFilePath)
2858 return ERROR_INVALID_PARAMETER;
2860 if (!*szFilePath)
2861 return ERROR_PATH_NOT_FOUND;
2863 if (dwOptions)
2864 return ERROR_INVALID_PARAMETER;
2865 if (!pHash)
2866 return ERROR_INVALID_PARAMETER;
2867 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2868 return ERROR_INVALID_PARAMETER;
2870 handle = CreateFileW( szFilePath, GENERIC_READ,
2871 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2872 if (handle == INVALID_HANDLE_VALUE)
2873 return ERROR_FILE_NOT_FOUND;
2875 length = GetFileSize( handle, NULL );
2877 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2878 if (mapping)
2880 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2881 if (p)
2883 MD5_CTX ctx;
2885 MD5Init( &ctx );
2886 MD5Update( &ctx, p, length );
2887 MD5Final( &ctx );
2888 UnmapViewOfFile( p );
2890 memcpy( pHash->dwData, ctx.digest, sizeof pHash->dwData );
2891 r = ERROR_SUCCESS;
2893 CloseHandle( mapping );
2895 CloseHandle( handle );
2897 return r;
2900 /***********************************************************************
2901 * MsiGetFileHashA [MSI.@]
2903 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2904 PMSIFILEHASHINFO pHash )
2906 LPWSTR file;
2907 UINT r;
2909 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2911 file = strdupAtoW( szFilePath );
2912 if (szFilePath && !file)
2913 return ERROR_OUTOFMEMORY;
2915 r = MsiGetFileHashW( file, dwOptions, pHash );
2916 msi_free( file );
2917 return r;
2920 /***********************************************************************
2921 * MsiAdvertiseScriptW [MSI.@]
2923 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2924 PHKEY phRegData, BOOL fRemoveItems )
2926 FIXME("%s %08x %p %d\n",
2927 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2928 return ERROR_CALL_NOT_IMPLEMENTED;
2931 /***********************************************************************
2932 * MsiAdvertiseScriptA [MSI.@]
2934 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2935 PHKEY phRegData, BOOL fRemoveItems )
2937 FIXME("%s %08x %p %d\n",
2938 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2939 return ERROR_CALL_NOT_IMPLEMENTED;
2942 /***********************************************************************
2943 * MsiIsProductElevatedW [MSI.@]
2945 UINT WINAPI MsiIsProductElevatedW( LPCWSTR szProduct, BOOL *pfElevated )
2947 FIXME("%s %p - stub\n",
2948 debugstr_w( szProduct ), pfElevated );
2949 *pfElevated = TRUE;
2950 return ERROR_SUCCESS;
2953 /***********************************************************************
2954 * MsiIsProductElevatedA [MSI.@]
2956 UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
2958 FIXME("%s %p - stub\n",
2959 debugstr_a( szProduct ), pfElevated );
2960 *pfElevated = TRUE;
2961 return ERROR_SUCCESS;