push 5b66f3b36e7323272378316c923222b908f6e2d3
[wine/hacks.git] / dlls / msi / msi.c
blobc5dd57da07eca2fa09fcb4394b0fcade4c9dceb0
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 static UINT msi_locate_product(LPCWSTR szProduct, MSIINSTALLCONTEXT *context)
50 HKEY hkey = NULL;
52 *context = MSIINSTALLCONTEXT_NONE;
54 if (MSIREG_OpenLocalManagedProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS)
55 *context = MSIINSTALLCONTEXT_USERMANAGED;
56 else if (MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS)
57 *context = MSIINSTALLCONTEXT_MACHINE;
58 else if (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS)
59 *context = MSIINSTALLCONTEXT_USERUNMANAGED;
61 RegCloseKey(hkey);
63 if (*context == MSIINSTALLCONTEXT_NONE)
64 return ERROR_UNKNOWN_PRODUCT;
66 return ERROR_SUCCESS;
69 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
71 UINT r;
72 LPWSTR szwProd = NULL;
74 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
76 if( szProduct )
78 szwProd = strdupAtoW( szProduct );
79 if( !szwProd )
80 return ERROR_OUTOFMEMORY;
83 r = MsiOpenProductW( szwProd, phProduct );
85 msi_free( szwProd );
87 return r;
90 static UINT MSI_OpenProductW(LPCWSTR szProduct, MSIPACKAGE **package)
92 UINT r;
93 HKEY props;
94 LPWSTR path;
95 MSIINSTALLCONTEXT context;
97 static const WCHAR managed[] = {
98 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0};
99 static const WCHAR local[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
101 TRACE("%s %p\n", debugstr_w(szProduct), package);
103 r = msi_locate_product(szProduct, &context);
104 if (r != ERROR_SUCCESS)
105 return r;
107 if (context == MSIINSTALLCONTEXT_MACHINE)
108 r = MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE);
109 else if (context == MSIINSTALLCONTEXT_USERMANAGED ||
110 context == MSIINSTALLCONTEXT_USERUNMANAGED)
111 r = MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE);
113 if (r != ERROR_SUCCESS)
114 return ERROR_UNKNOWN_PRODUCT;
116 if (context == MSIINSTALLCONTEXT_USERMANAGED)
117 path = msi_reg_get_val_str(props, managed);
118 else
119 path = msi_reg_get_val_str(props, local);
121 r = ERROR_UNKNOWN_PRODUCT;
123 if (!path || GetFileAttributesW(path) == INVALID_FILE_ATTRIBUTES)
124 goto done;
126 if (PathIsRelativeW(path))
128 r = ERROR_INSTALL_PACKAGE_OPEN_FAILED;
129 goto done;
132 r = MSI_OpenPackageW(path, package);
134 done:
135 RegCloseKey(props);
136 msi_free(path);
137 return r;
140 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
142 MSIPACKAGE *package = NULL;
143 WCHAR squished_pc[GUID_SIZE];
144 UINT r;
146 if (!szProduct || !squash_guid(szProduct, squished_pc))
147 return ERROR_INVALID_PARAMETER;
149 if (!phProduct)
150 return ERROR_INVALID_PARAMETER;
152 r = MSI_OpenProductW(szProduct, &package);
153 if (r != ERROR_SUCCESS)
154 return r;
156 *phProduct = alloc_msihandle(&package->hdr);
157 if (!*phProduct)
158 r = ERROR_NOT_ENOUGH_MEMORY;
160 msiobj_release(&package->hdr);
161 return r;
164 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
165 LPCSTR szTransforms, LANGID lgidLanguage)
167 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
168 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
169 return ERROR_CALL_NOT_IMPLEMENTED;
172 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
173 LPCWSTR szTransforms, LANGID lgidLanguage)
175 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
176 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
177 return ERROR_CALL_NOT_IMPLEMENTED;
180 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
181 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
183 FIXME("%s %s %s %08x %08x %08x\n", debugstr_a(szPackagePath),
184 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
185 lgidLanguage, dwPlatform, dwOptions);
186 return ERROR_CALL_NOT_IMPLEMENTED;
189 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
190 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
192 FIXME("%s %s %s %08x %08x %08x\n", debugstr_w(szPackagePath),
193 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
194 lgidLanguage, dwPlatform, dwOptions);
195 return ERROR_CALL_NOT_IMPLEMENTED;
198 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
200 LPWSTR szwPath = NULL, szwCommand = NULL;
201 UINT r = ERROR_OUTOFMEMORY;
203 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
205 if( szPackagePath )
207 szwPath = strdupAtoW( szPackagePath );
208 if( !szwPath )
209 goto end;
212 if( szCommandLine )
214 szwCommand = strdupAtoW( szCommandLine );
215 if( !szwCommand )
216 goto end;
219 r = MsiInstallProductW( szwPath, szwCommand );
221 end:
222 msi_free( szwPath );
223 msi_free( szwCommand );
225 return r;
228 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
230 MSIPACKAGE *package = NULL;
231 UINT r;
233 TRACE("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
235 r = MSI_OpenPackageW( szPackagePath, &package );
236 if (r == ERROR_SUCCESS)
238 r = MSI_InstallPackage( package, szPackagePath, szCommandLine );
239 msiobj_release( &package->hdr );
242 return r;
245 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
247 FIXME("%s %08x\n", debugstr_a(szProduct), dwReinstallMode);
248 return ERROR_CALL_NOT_IMPLEMENTED;
251 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
253 FIXME("%s %08x\n", debugstr_w(szProduct), dwReinstallMode);
254 return ERROR_CALL_NOT_IMPLEMENTED;
257 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
258 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
260 LPWSTR patch_package = NULL;
261 LPWSTR install_package = NULL;
262 LPWSTR command_line = NULL;
263 UINT r = ERROR_OUTOFMEMORY;
265 TRACE("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
266 eInstallType, debugstr_a(szCommandLine));
268 if (szPatchPackage && !(patch_package = strdupAtoW(szPatchPackage)))
269 goto done;
271 if (szInstallPackage && !(install_package = strdupAtoW(szInstallPackage)))
272 goto done;
274 if (szCommandLine && !(command_line = strdupAtoW(szCommandLine)))
275 goto done;
277 r = MsiApplyPatchW(patch_package, install_package, eInstallType, command_line);
279 done:
280 msi_free(patch_package);
281 msi_free(install_package);
282 msi_free(command_line);
284 return r;
287 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
288 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
290 MSIHANDLE patch, info;
291 UINT r, type;
292 DWORD size = 0;
293 LPCWSTR cmd_ptr = szCommandLine;
294 LPWSTR beg, end;
295 LPWSTR cmd = NULL, codes = NULL;
297 static const WCHAR space[] = {' ',0};
298 static const WCHAR patcheq[] = {'P','A','T','C','H','=',0};
299 static WCHAR empty[] = {0};
301 TRACE("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
302 eInstallType, debugstr_w(szCommandLine));
304 if (szInstallPackage || eInstallType == INSTALLTYPE_NETWORK_IMAGE ||
305 eInstallType == INSTALLTYPE_SINGLE_INSTANCE)
307 FIXME("Only reading target products from patch\n");
308 return ERROR_CALL_NOT_IMPLEMENTED;
311 r = MsiOpenDatabaseW(szPatchPackage, MSIDBOPEN_READONLY, &patch);
312 if (r != ERROR_SUCCESS)
313 return r;
315 r = MsiGetSummaryInformationW(patch, NULL, 0, &info);
316 if (r != ERROR_SUCCESS)
317 goto done;
319 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, empty, &size);
320 if (r != ERROR_MORE_DATA || !size || type != VT_LPSTR)
322 ERR("Failed to read product codes from patch\n");
323 goto done;
326 codes = msi_alloc(++size * sizeof(WCHAR));
327 if (!codes)
329 r = ERROR_OUTOFMEMORY;
330 goto done;
333 r = MsiSummaryInfoGetPropertyW(info, PID_TEMPLATE, &type, NULL, NULL, codes, &size);
334 if (r != ERROR_SUCCESS)
335 goto done;
337 if (!szCommandLine)
338 cmd_ptr = empty;
340 size = lstrlenW(cmd_ptr) + lstrlenW(patcheq) + lstrlenW(szPatchPackage) + 1;
341 cmd = msi_alloc(size * sizeof(WCHAR));
342 if (!cmd)
344 r = ERROR_OUTOFMEMORY;
345 goto done;
348 lstrcpyW(cmd, cmd_ptr);
349 if (szCommandLine) lstrcatW(cmd, space);
350 lstrcatW(cmd, patcheq);
351 lstrcatW(cmd, szPatchPackage);
353 beg = codes;
354 while ((end = strchrW(beg, '}')))
356 *(end + 1) = '\0';
358 r = MsiConfigureProductExW(beg, INSTALLLEVEL_DEFAULT, INSTALLSTATE_DEFAULT, cmd);
359 if (r != ERROR_SUCCESS)
360 goto done;
362 beg = end + 2;
365 done:
366 msi_free(cmd);
367 msi_free(codes);
369 MsiCloseHandle(info);
370 MsiCloseHandle(patch);
372 return r;
375 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
376 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
378 MSIPACKAGE* package = NULL;
379 MSIINSTALLCONTEXT context;
380 UINT r;
381 DWORD sz;
382 WCHAR sourcepath[MAX_PATH];
383 WCHAR filename[MAX_PATH];
384 LPWSTR commandline;
386 static const WCHAR szInstalled[] = {
387 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
388 static const WCHAR szRemoveAll[] = {
389 ' ','R','E','M','O','V','E','=','A','L','L',0};
390 static const WCHAR szMachine[] = {
391 ' ','A','L','L','U','S','E','R','S','=','1',0};
393 TRACE("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
394 debugstr_w(szCommandLine));
396 if (!szProduct || lstrlenW(szProduct) != GUID_SIZE - 1)
397 return ERROR_INVALID_PARAMETER;
399 if (eInstallState == INSTALLSTATE_ADVERTISED ||
400 eInstallState == INSTALLSTATE_SOURCE)
402 FIXME("State %d not implemented\n", eInstallState);
403 return ERROR_CALL_NOT_IMPLEMENTED;
406 r = msi_locate_product(szProduct, &context);
407 if (r != ERROR_SUCCESS)
408 return r;
410 sz = sizeof(sourcepath);
411 MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
412 INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
414 sz = sizeof(filename);
415 MsiSourceListGetInfoW(szProduct, NULL, context, MSICODE_PRODUCT,
416 INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
418 lstrcatW(sourcepath, filename);
419 r = MSI_OpenPackageW(sourcepath, &package);
420 if (r != ERROR_SUCCESS)
421 return r;
423 sz = lstrlenW(szInstalled) + 1;
425 if (szCommandLine)
426 sz += lstrlenW(szCommandLine);
428 if (eInstallState == INSTALLSTATE_ABSENT)
429 sz += lstrlenW(szRemoveAll);
431 if (context == MSIINSTALLCONTEXT_MACHINE)
432 sz += lstrlenW(szMachine);
434 commandline = msi_alloc(sz * sizeof(WCHAR));
435 if (!commandline)
437 r = ERROR_OUTOFMEMORY;
438 goto end;
441 commandline[0] = 0;
442 if (szCommandLine)
443 lstrcpyW(commandline,szCommandLine);
445 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
446 lstrcatW(commandline,szInstalled);
448 if (eInstallState == INSTALLSTATE_ABSENT)
449 lstrcatW(commandline, szRemoveAll);
451 if (context == MSIINSTALLCONTEXT_MACHINE)
452 lstrcatW(commandline, szMachine);
454 r = MSI_InstallPackage( package, sourcepath, commandline );
456 msi_free(commandline);
458 end:
459 msiobj_release( &package->hdr );
461 return r;
464 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
465 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
467 LPWSTR szwProduct = NULL;
468 LPWSTR szwCommandLine = NULL;
469 UINT r = ERROR_OUTOFMEMORY;
471 if( szProduct )
473 szwProduct = strdupAtoW( szProduct );
474 if( !szwProduct )
475 goto end;
478 if( szCommandLine)
480 szwCommandLine = strdupAtoW( szCommandLine );
481 if( !szwCommandLine)
482 goto end;
485 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
486 szwCommandLine );
487 end:
488 msi_free( szwProduct );
489 msi_free( szwCommandLine);
491 return r;
494 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
495 INSTALLSTATE eInstallState)
497 LPWSTR szwProduct = NULL;
498 UINT r;
500 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
502 if( szProduct )
504 szwProduct = strdupAtoW( szProduct );
505 if( !szwProduct )
506 return ERROR_OUTOFMEMORY;
509 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
510 msi_free( szwProduct );
512 return r;
515 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
516 INSTALLSTATE eInstallState)
518 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
521 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
523 LPWSTR szwComponent = NULL;
524 UINT r;
525 WCHAR szwBuffer[GUID_SIZE];
527 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
529 if( szComponent )
531 szwComponent = strdupAtoW( szComponent );
532 if( !szwComponent )
533 return ERROR_OUTOFMEMORY;
536 *szwBuffer = '\0';
537 r = MsiGetProductCodeW( szwComponent, szwBuffer );
539 if(*szwBuffer)
540 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
542 msi_free( szwComponent );
544 return r;
547 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
549 UINT rc, index;
550 HKEY compkey, prodkey;
551 WCHAR squished_comp[GUID_SIZE];
552 WCHAR squished_prod[GUID_SIZE];
553 DWORD sz = GUID_SIZE;
555 TRACE("%s %p\n", debugstr_w(szComponent), szBuffer);
557 if (!szComponent || !*szComponent)
558 return ERROR_INVALID_PARAMETER;
560 if (!squash_guid(szComponent, squished_comp))
561 return ERROR_INVALID_PARAMETER;
563 if (MSIREG_OpenUserDataComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS &&
564 MSIREG_OpenLocalSystemComponentKey(szComponent, &compkey, FALSE) != ERROR_SUCCESS)
566 return ERROR_UNKNOWN_COMPONENT;
569 rc = RegEnumValueW(compkey, 0, squished_prod, &sz, NULL, NULL, NULL, NULL);
570 if (rc != ERROR_SUCCESS)
572 RegCloseKey(compkey);
573 return ERROR_UNKNOWN_COMPONENT;
576 /* check simple case, only one product */
577 rc = RegEnumValueW(compkey, 1, squished_prod, &sz, NULL, NULL, NULL, NULL);
578 if (rc == ERROR_NO_MORE_ITEMS)
580 rc = ERROR_SUCCESS;
581 goto done;
584 index = 0;
585 while ((rc = RegEnumValueW(compkey, index, squished_prod, &sz,
586 NULL, NULL, NULL, NULL)) != ERROR_NO_MORE_ITEMS)
588 index++;
589 sz = GUID_SIZE;
590 unsquash_guid(squished_prod, szBuffer);
592 if (MSIREG_OpenLocalManagedProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
593 MSIREG_OpenUserProductsKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS ||
594 MSIREG_OpenLocalClassesProductKey(szBuffer, &prodkey, FALSE) == ERROR_SUCCESS)
596 RegCloseKey(prodkey);
597 rc = ERROR_SUCCESS;
598 goto done;
602 rc = ERROR_INSTALL_FAILURE;
604 done:
605 RegCloseKey(compkey);
606 unsquash_guid(squished_prod, szBuffer);
607 return rc;
610 static LPWSTR msi_reg_get_value(HKEY hkey, LPCWSTR name, DWORD *type)
612 DWORD dval;
613 LONG res;
614 WCHAR temp[20];
616 static const WCHAR format[] = {'%','d',0};
618 res = RegQueryValueExW(hkey, name, NULL, type, NULL, NULL);
619 if (res != ERROR_SUCCESS)
620 return NULL;
622 if (*type == REG_SZ)
623 return msi_reg_get_val_str(hkey, name);
625 if (!msi_reg_get_val_dword(hkey, name, &dval))
626 return NULL;
628 sprintfW(temp, format, dval);
629 return strdupW(temp);
632 static UINT WINAPI MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
633 awstring *szValue, LPDWORD pcchValueBuf)
635 UINT r = ERROR_UNKNOWN_PROPERTY;
636 HKEY prodkey, userdata, source;
637 LPWSTR val = NULL;
638 WCHAR squished_pc[GUID_SIZE];
639 WCHAR packagecode[GUID_SIZE];
640 BOOL classes = FALSE;
641 BOOL badconfig = FALSE;
642 LONG res;
643 DWORD save, type = REG_NONE;
645 static WCHAR empty[] = {0};
646 static const WCHAR sourcelist[] = {
647 'S','o','u','r','c','e','L','i','s','t',0};
648 static const WCHAR display_name[] = {
649 'D','i','s','p','l','a','y','N','a','m','e',0};
650 static const WCHAR display_version[] = {
651 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
652 static const WCHAR assignment[] = {
653 'A','s','s','i','g','n','m','e','n','t',0};
655 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
656 debugstr_w(szAttribute), szValue, pcchValueBuf);
658 if ((szValue->str.w && !pcchValueBuf) || !szProduct || !szAttribute)
659 return ERROR_INVALID_PARAMETER;
661 if (!squash_guid(szProduct, squished_pc))
662 return ERROR_INVALID_PARAMETER;
664 r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
665 if (r != ERROR_SUCCESS)
667 r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
668 if (r != ERROR_SUCCESS)
670 r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
671 if (r == ERROR_SUCCESS)
672 classes = TRUE;
676 if (classes)
677 MSIREG_OpenLocalSystemProductKey(szProduct, &userdata, FALSE);
678 else
679 MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
681 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_HELPLINKW) ||
682 !lstrcmpW(szAttribute, INSTALLPROPERTY_HELPTELEPHONEW) ||
683 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLDATEW) ||
684 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
685 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLLOCATIONW) ||
686 !lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLSOURCEW) ||
687 !lstrcmpW(szAttribute, INSTALLPROPERTY_LOCALPACKAGEW) ||
688 !lstrcmpW(szAttribute, INSTALLPROPERTY_PUBLISHERW) ||
689 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLINFOABOUTW) ||
690 !lstrcmpW(szAttribute, INSTALLPROPERTY_URLUPDATEINFOW) ||
691 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMINORW) ||
692 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONMAJORW) ||
693 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW) ||
694 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTIDW) ||
695 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGCOMPANYW) ||
696 !lstrcmpW(szAttribute, INSTALLPROPERTY_REGOWNERW))
698 if (!prodkey)
700 r = ERROR_UNKNOWN_PRODUCT;
701 goto done;
704 if (!userdata)
705 return ERROR_UNKNOWN_PROPERTY;
707 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
708 szAttribute = display_name;
709 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONSTRINGW))
710 szAttribute = display_version;
712 val = msi_reg_get_value(userdata, szAttribute, &type);
713 if (!val)
714 val = empty;
716 else if (!lstrcmpW(szAttribute, INSTALLPROPERTY_INSTANCETYPEW) ||
717 !lstrcmpW(szAttribute, INSTALLPROPERTY_TRANSFORMSW) ||
718 !lstrcmpW(szAttribute, INSTALLPROPERTY_LANGUAGEW) ||
719 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTNAMEW) ||
720 !lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW) ||
721 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW) ||
722 !lstrcmpW(szAttribute, INSTALLPROPERTY_VERSIONW) ||
723 !lstrcmpW(szAttribute, INSTALLPROPERTY_PRODUCTICONW) ||
724 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW) ||
725 !lstrcmpW(szAttribute, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
727 if (!prodkey)
729 r = ERROR_UNKNOWN_PRODUCT;
730 goto done;
733 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_ASSIGNMENTTYPEW))
734 szAttribute = assignment;
736 if (!lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGENAMEW))
738 res = RegOpenKeyW(prodkey, sourcelist, &source);
739 if (res == ERROR_SUCCESS)
740 val = msi_reg_get_value(source, szAttribute, &type);
742 RegCloseKey(source);
744 else
746 val = msi_reg_get_value(prodkey, szAttribute, &type);
747 if (!val)
748 val = empty;
751 if (val != empty && type != REG_DWORD &&
752 !lstrcmpW(szAttribute, INSTALLPROPERTY_PACKAGECODEW))
754 if (lstrlenW(val) != SQUISH_GUID_SIZE - 1)
755 badconfig = TRUE;
756 else
758 unsquash_guid(val, packagecode);
759 msi_free(val);
760 val = strdupW(packagecode);
765 if (!val)
767 r = ERROR_UNKNOWN_PROPERTY;
768 goto done;
771 if (pcchValueBuf)
773 save = *pcchValueBuf;
775 if (lstrlenW(val) < *pcchValueBuf)
776 r = msi_strcpy_to_awstring(val, szValue, pcchValueBuf);
777 else if (szValue->str.a || szValue->str.w)
778 r = ERROR_MORE_DATA;
780 if (!badconfig)
781 *pcchValueBuf = lstrlenW(val);
782 else if (r == ERROR_SUCCESS)
784 *pcchValueBuf = save;
785 r = ERROR_BAD_CONFIGURATION;
788 else if (badconfig)
789 r = ERROR_BAD_CONFIGURATION;
791 if (val != empty)
792 msi_free(val);
794 done:
795 RegCloseKey(prodkey);
796 RegCloseKey(userdata);
797 return r;
800 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
801 LPSTR szBuffer, LPDWORD pcchValueBuf)
803 LPWSTR szwProduct, szwAttribute = NULL;
804 UINT r = ERROR_OUTOFMEMORY;
805 awstring buffer;
807 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
808 szBuffer, pcchValueBuf);
810 szwProduct = strdupAtoW( szProduct );
811 if( szProduct && !szwProduct )
812 goto end;
814 szwAttribute = strdupAtoW( szAttribute );
815 if( szAttribute && !szwAttribute )
816 goto end;
818 buffer.unicode = FALSE;
819 buffer.str.a = szBuffer;
821 r = MSI_GetProductInfo( szwProduct, szwAttribute,
822 &buffer, pcchValueBuf );
824 end:
825 msi_free( szwProduct );
826 msi_free( szwAttribute );
828 return r;
831 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
832 LPWSTR szBuffer, LPDWORD pcchValueBuf)
834 awstring buffer;
836 TRACE("%s %s %p %p\n", debugstr_w(szProduct), debugstr_w(szAttribute),
837 szBuffer, pcchValueBuf);
839 buffer.unicode = TRUE;
840 buffer.str.w = szBuffer;
842 return MSI_GetProductInfo( szProduct, szAttribute,
843 &buffer, pcchValueBuf );
846 UINT WINAPI MsiGetProductInfoExA(LPCSTR szProductCode, LPCSTR szUserSid,
847 MSIINSTALLCONTEXT dwContext, LPCSTR szProperty,
848 LPSTR szValue, LPDWORD pcchValue)
850 LPWSTR product = NULL;
851 LPWSTR usersid = NULL;
852 LPWSTR property = NULL;
853 LPWSTR value = NULL;
854 DWORD len = 0;
855 UINT r;
857 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_a(szProductCode),
858 debugstr_a(szUserSid), dwContext, debugstr_a(szProperty),
859 szValue, pcchValue);
861 if (szValue && !pcchValue)
862 return ERROR_INVALID_PARAMETER;
864 if (szProductCode) product = strdupAtoW(szProductCode);
865 if (szUserSid) usersid = strdupAtoW(szUserSid);
866 if (szProperty) property = strdupAtoW(szProperty);
868 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
869 NULL, &len);
870 if (r != ERROR_SUCCESS)
871 goto done;
873 value = msi_alloc(++len * sizeof(WCHAR));
874 if (!value)
876 r = ERROR_OUTOFMEMORY;
877 goto done;
880 r = MsiGetProductInfoExW(product, usersid, dwContext, property,
881 value, &len);
882 if (r != ERROR_SUCCESS)
883 goto done;
885 if (!pcchValue)
886 goto done;
888 len = WideCharToMultiByte(CP_ACP, 0, value, -1, NULL, 0, NULL, NULL);
889 if (*pcchValue >= len)
890 WideCharToMultiByte(CP_ACP, 0, value, -1, szValue, len, NULL, NULL);
891 else if (szValue)
893 r = ERROR_MORE_DATA;
894 if (*pcchValue > 0)
895 *szValue = '\0';
898 if (*pcchValue <= len || !szValue)
899 len = len * sizeof(WCHAR) - 1;
901 *pcchValue = len - 1;
903 done:
904 msi_free(product);
905 msi_free(usersid);
906 msi_free(property);
907 msi_free(value);
909 return r;
912 static UINT msi_copy_outval(LPWSTR val, LPWSTR out, LPDWORD size)
914 UINT r;
916 if (!val)
917 return ERROR_UNKNOWN_PROPERTY;
919 if (out)
921 if (lstrlenW(val) >= *size)
923 r = ERROR_MORE_DATA;
924 if (*size > 0)
925 *out = '\0';
927 else
928 lstrcpyW(out, val);
931 if (size)
932 *size = lstrlenW(val);
934 return ERROR_SUCCESS;
937 UINT WINAPI MsiGetProductInfoExW(LPCWSTR szProductCode, LPCWSTR szUserSid,
938 MSIINSTALLCONTEXT dwContext, LPCWSTR szProperty,
939 LPWSTR szValue, LPDWORD pcchValue)
941 WCHAR squished_pc[GUID_SIZE];
942 LPWSTR val = NULL;
943 LPCWSTR package = NULL;
944 HKEY props = NULL, prod;
945 HKEY classes = NULL, managed;
946 HKEY hkey = NULL;
947 DWORD type;
948 UINT r = ERROR_UNKNOWN_PRODUCT;
950 static const WCHAR one[] = {'1',0};
951 static const WCHAR five[] = {'5',0};
952 static const WCHAR empty[] = {0};
953 static const WCHAR displayname[] = {
954 'D','i','s','p','l','a','y','N','a','m','e',0};
955 static const WCHAR displayversion[] = {
956 'D','i','s','p','l','a','y','V','e','r','s','i','o','n',0};
957 static const WCHAR managed_local_package[] = {
958 'M','a','n','a','g','e','d','L','o','c','a','l',
959 'P','a','c','k','a','g','e',0};
961 TRACE("(%s, %s, %d, %s, %p, %p)\n", debugstr_w(szProductCode),
962 debugstr_w(szUserSid), dwContext, debugstr_w(szProperty),
963 szValue, pcchValue);
965 if (!szProductCode || !squash_guid(szProductCode, squished_pc))
966 return ERROR_INVALID_PARAMETER;
968 if (szValue && !pcchValue)
969 return ERROR_INVALID_PARAMETER;
971 if (dwContext != MSIINSTALLCONTEXT_USERUNMANAGED &&
972 dwContext != MSIINSTALLCONTEXT_USERMANAGED &&
973 dwContext != MSIINSTALLCONTEXT_MACHINE)
974 return ERROR_INVALID_PARAMETER;
976 if (!szProperty || !*szProperty)
977 return ERROR_INVALID_PARAMETER;
979 if (dwContext == MSIINSTALLCONTEXT_MACHINE && szUserSid)
980 return ERROR_INVALID_PARAMETER;
982 MSIREG_OpenLocalManagedProductKey(szProductCode, &managed, FALSE);
983 MSIREG_OpenUserProductsKey(szProductCode, &prod, FALSE);
985 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
987 package = INSTALLPROPERTY_LOCALPACKAGEW;
988 MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
990 if (!props && !prod)
991 goto done;
993 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
995 package = managed_local_package;
996 MSIREG_OpenCurrentUserInstallProps(szProductCode, &props, FALSE);
998 if (!props && !managed)
999 goto done;
1001 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1003 package = INSTALLPROPERTY_LOCALPACKAGEW;
1004 MSIREG_OpenLocalSystemProductKey(szProductCode, &props, FALSE);
1005 MSIREG_OpenLocalClassesProductKey(szProductCode, &classes, FALSE);
1007 if (!props && !classes)
1008 goto done;
1011 if (!lstrcmpW(szProperty, INSTALLPROPERTY_HELPLINKW) ||
1012 !lstrcmpW(szProperty, INSTALLPROPERTY_HELPTELEPHONEW) ||
1013 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLDATEW) ||
1014 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW) ||
1015 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLLOCATIONW) ||
1016 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLSOURCEW) ||
1017 !lstrcmpW(szProperty, INSTALLPROPERTY_LOCALPACKAGEW) ||
1018 !lstrcmpW(szProperty, INSTALLPROPERTY_PUBLISHERW) ||
1019 !lstrcmpW(szProperty, INSTALLPROPERTY_URLINFOABOUTW) ||
1020 !lstrcmpW(szProperty, INSTALLPROPERTY_URLUPDATEINFOW) ||
1021 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMINORW) ||
1022 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONMAJORW) ||
1023 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW) ||
1024 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTIDW) ||
1025 !lstrcmpW(szProperty, INSTALLPROPERTY_REGCOMPANYW) ||
1026 !lstrcmpW(szProperty, INSTALLPROPERTY_REGOWNERW) ||
1027 !lstrcmpW(szProperty, INSTALLPROPERTY_INSTANCETYPEW))
1029 val = msi_reg_get_value(props, package, &type);
1030 if (!val)
1032 if (prod || classes)
1033 r = ERROR_UNKNOWN_PROPERTY;
1035 goto done;
1038 msi_free(val);
1040 if (!lstrcmpW(szProperty, INSTALLPROPERTY_INSTALLEDPRODUCTNAMEW))
1041 szProperty = displayname;
1042 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONSTRINGW))
1043 szProperty = displayversion;
1045 val = msi_reg_get_value(props, szProperty, &type);
1046 if (!val)
1047 val = strdupW(empty);
1049 r = msi_copy_outval(val, szValue, pcchValue);
1051 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_TRANSFORMSW) ||
1052 !lstrcmpW(szProperty, INSTALLPROPERTY_LANGUAGEW) ||
1053 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTNAMEW) ||
1054 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGECODEW) ||
1055 !lstrcmpW(szProperty, INSTALLPROPERTY_VERSIONW) ||
1056 !lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTICONW) ||
1057 !lstrcmpW(szProperty, INSTALLPROPERTY_PACKAGENAMEW) ||
1058 !lstrcmpW(szProperty, INSTALLPROPERTY_AUTHORIZED_LUA_APPW))
1060 if (!prod && !classes)
1061 goto done;
1063 if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
1064 hkey = prod;
1065 else if (dwContext == MSIINSTALLCONTEXT_USERMANAGED)
1066 hkey = managed;
1067 else if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1068 hkey = classes;
1070 val = msi_reg_get_value(hkey, szProperty, &type);
1071 if (!val)
1072 val = strdupW(empty);
1074 r = msi_copy_outval(val, szValue, pcchValue);
1076 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_PRODUCTSTATEW))
1078 if (dwContext == MSIINSTALLCONTEXT_MACHINE)
1080 if (props)
1082 val = msi_reg_get_value(props, package, &type);
1083 if (!val)
1084 goto done;
1086 msi_free(val);
1087 val = strdupW(five);
1089 else
1090 val = strdupW(one);
1092 r = msi_copy_outval(val, szValue, pcchValue);
1093 goto done;
1095 else if (props && (val = msi_reg_get_value(props, package, &type)))
1097 msi_free(val);
1098 val = strdupW(five);
1099 r = msi_copy_outval(val, szValue, pcchValue);
1100 goto done;
1103 if (prod || managed)
1104 val = strdupW(one);
1105 else
1106 goto done;
1108 r = msi_copy_outval(val, szValue, pcchValue);
1110 else if (!lstrcmpW(szProperty, INSTALLPROPERTY_ASSIGNMENTTYPEW))
1112 if (!prod && !classes)
1113 goto done;
1115 /* FIXME */
1116 val = strdupW(empty);
1117 r = msi_copy_outval(val, szValue, pcchValue);
1119 else
1120 r = ERROR_UNKNOWN_PROPERTY;
1122 done:
1123 RegCloseKey(props);
1124 RegCloseKey(prod);
1125 RegCloseKey(managed);
1126 RegCloseKey(classes);
1127 msi_free(val);
1129 return r;
1132 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
1134 LPWSTR szwLogFile = NULL;
1135 UINT r;
1137 TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
1139 if( szLogFile )
1141 szwLogFile = strdupAtoW( szLogFile );
1142 if( !szwLogFile )
1143 return ERROR_OUTOFMEMORY;
1145 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
1146 msi_free( szwLogFile );
1147 return r;
1150 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
1152 HANDLE file = INVALID_HANDLE_VALUE;
1154 TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
1156 if (szLogFile)
1158 lstrcpyW(gszLogFile,szLogFile);
1159 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
1160 DeleteFileW(szLogFile);
1161 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
1162 FILE_ATTRIBUTE_NORMAL, NULL);
1163 if (file != INVALID_HANDLE_VALUE)
1164 CloseHandle(file);
1165 else
1166 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
1168 else
1169 gszLogFile[0] = '\0';
1171 return ERROR_SUCCESS;
1174 UINT WINAPI MsiEnumComponentCostsW(MSIHANDLE hInstall, LPCWSTR szComponent,
1175 DWORD dwIndex, INSTALLSTATE iState,
1176 LPWSTR lpDriveBuf, DWORD *pcchDriveBuf,
1177 int *piCost, int *pTempCost)
1179 FIXME("(%ld, %s, %d, %d, %p, %p, %p %p): stub!\n", hInstall,
1180 debugstr_w(szComponent), dwIndex, iState, lpDriveBuf,
1181 pcchDriveBuf, piCost, pTempCost);
1183 return ERROR_NO_MORE_ITEMS;
1186 UINT WINAPI MsiQueryComponentStateA(LPCSTR szProductCode,
1187 LPCSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1188 LPCSTR szComponent, INSTALLSTATE *pdwState)
1190 LPWSTR prodcode = NULL, usersid = NULL, comp = NULL;
1191 UINT r;
1193 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_a(szProductCode),
1194 debugstr_a(szUserSid), dwContext, debugstr_a(szComponent), pdwState);
1196 if (szProductCode && !(prodcode = strdupAtoW(szProductCode)))
1197 return ERROR_OUTOFMEMORY;
1199 if (szUserSid && !(usersid = strdupAtoW(szUserSid)))
1200 return ERROR_OUTOFMEMORY;
1202 if (szComponent && !(comp = strdupAtoW(szComponent)))
1203 return ERROR_OUTOFMEMORY;
1205 r = MsiQueryComponentStateW(prodcode, usersid, dwContext, comp, pdwState);
1207 msi_free(prodcode);
1208 msi_free(usersid);
1209 msi_free(comp);
1211 return r;
1214 static BOOL msi_comp_find_prod_key(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1216 UINT r;
1217 HKEY hkey;
1219 if (context == MSIINSTALLCONTEXT_MACHINE)
1220 r = MSIREG_OpenLocalClassesProductKey(prodcode, &hkey, FALSE);
1221 else if (context == MSIINSTALLCONTEXT_USERUNMANAGED)
1222 r = MSIREG_OpenUserProductsKey(prodcode, &hkey, FALSE);
1223 else
1224 r = MSIREG_OpenLocalManagedProductKey(prodcode, &hkey, FALSE);
1226 RegCloseKey(hkey);
1227 return (r == ERROR_SUCCESS);
1230 static BOOL msi_comp_find_package(LPCWSTR prodcode, MSIINSTALLCONTEXT context)
1232 LPCWSTR package;
1233 HKEY hkey;
1234 DWORD sz;
1235 LONG res;
1236 UINT r;
1238 static const WCHAR local_package[] = {'L','o','c','a','l','P','a','c','k','a','g','e',0};
1239 static const WCHAR managed_local_package[] = {
1240 'M','a','n','a','g','e','d','L','o','c','a','l','P','a','c','k','a','g','e',0
1243 if (context == MSIINSTALLCONTEXT_MACHINE)
1244 r = MSIREG_OpenLocalSystemProductKey(prodcode, &hkey, FALSE);
1245 else
1246 r = MSIREG_OpenCurrentUserInstallProps(prodcode, &hkey, FALSE);
1248 if (r != ERROR_SUCCESS)
1249 return FALSE;
1251 if (context == MSIINSTALLCONTEXT_USERMANAGED)
1252 package = managed_local_package;
1253 else
1254 package = local_package;
1256 sz = 0;
1257 res = RegQueryValueExW(hkey, package, NULL, NULL, NULL, &sz);
1258 RegCloseKey(hkey);
1260 return (res == ERROR_SUCCESS);
1263 static BOOL msi_comp_find_prodcode(LPWSTR squished_pc,
1264 MSIINSTALLCONTEXT context,
1265 LPCWSTR comp, DWORD *sz)
1267 HKEY hkey;
1268 LONG res;
1269 UINT r;
1271 if (context == MSIINSTALLCONTEXT_MACHINE)
1272 r = MSIREG_OpenLocalSystemComponentKey(comp, &hkey, FALSE);
1273 else
1274 r = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1276 if (r != ERROR_SUCCESS)
1277 return FALSE;
1279 *sz = 0;
1280 res = RegQueryValueExW(hkey, squished_pc, NULL, NULL, NULL, sz);
1281 if (res != ERROR_SUCCESS)
1282 return FALSE;
1284 RegCloseKey(hkey);
1285 return TRUE;
1288 UINT WINAPI MsiQueryComponentStateW(LPCWSTR szProductCode,
1289 LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext,
1290 LPCWSTR szComponent, INSTALLSTATE *pdwState)
1292 WCHAR squished_pc[GUID_SIZE];
1293 BOOL found;
1294 DWORD sz;
1296 TRACE("(%s, %s, %d, %s, %p)\n", debugstr_w(szProductCode),
1297 debugstr_w(szUserSid), dwContext, debugstr_w(szComponent), pdwState);
1299 if (!pdwState)
1300 return ERROR_INVALID_PARAMETER;
1302 if (!szProductCode || !*szProductCode || lstrlenW(szProductCode) != GUID_SIZE - 1)
1303 return ERROR_INVALID_PARAMETER;
1305 if (!squash_guid(szProductCode, squished_pc))
1306 return ERROR_INVALID_PARAMETER;
1308 found = msi_comp_find_prod_key(szProductCode, dwContext);
1310 if (!msi_comp_find_package(szProductCode, dwContext))
1312 if (found)
1314 *pdwState = INSTALLSTATE_UNKNOWN;
1315 return ERROR_UNKNOWN_COMPONENT;
1318 return ERROR_UNKNOWN_PRODUCT;
1321 *pdwState = INSTALLSTATE_UNKNOWN;
1323 if (!msi_comp_find_prodcode(squished_pc, dwContext, szComponent, &sz))
1324 return ERROR_UNKNOWN_COMPONENT;
1326 if (sz == 0)
1327 *pdwState = INSTALLSTATE_NOTUSED;
1328 else
1329 *pdwState = INSTALLSTATE_LOCAL;
1331 return ERROR_SUCCESS;
1334 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
1336 LPWSTR szwProduct = NULL;
1337 INSTALLSTATE r;
1339 if( szProduct )
1341 szwProduct = strdupAtoW( szProduct );
1342 if( !szwProduct )
1343 return ERROR_OUTOFMEMORY;
1345 r = MsiQueryProductStateW( szwProduct );
1346 msi_free( szwProduct );
1347 return r;
1350 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
1352 INSTALLSTATE state = INSTALLSTATE_ADVERTISED;
1353 HKEY prodkey = 0, userdata = 0;
1354 BOOL user = TRUE;
1355 DWORD val;
1356 UINT r;
1358 static const WCHAR szWindowsInstaller[] = {
1359 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1361 TRACE("%s\n", debugstr_w(szProduct));
1363 if (!szProduct || !*szProduct)
1364 return INSTALLSTATE_INVALIDARG;
1366 if (lstrlenW(szProduct) != GUID_SIZE - 1)
1367 return INSTALLSTATE_INVALIDARG;
1369 r = MSIREG_OpenLocalManagedProductKey(szProduct, &prodkey, FALSE);
1370 if (r != ERROR_SUCCESS)
1372 r = MSIREG_OpenUserProductsKey(szProduct, &prodkey, FALSE);
1373 if (r != ERROR_SUCCESS)
1375 r = MSIREG_OpenLocalClassesProductKey(szProduct, &prodkey, FALSE);
1376 if (r == ERROR_SUCCESS)
1377 user = FALSE;
1381 if (user)
1383 r = MSIREG_OpenCurrentUserInstallProps(szProduct, &userdata, FALSE);
1384 if (r != ERROR_SUCCESS)
1385 goto done;
1387 else
1389 r = MSIREG_OpenLocalSystemInstallProps(szProduct, &userdata, FALSE);
1390 if (r != ERROR_SUCCESS)
1391 goto done;
1394 if (!msi_reg_get_val_dword(userdata, szWindowsInstaller, &val))
1395 goto done;
1397 if (val)
1398 state = INSTALLSTATE_DEFAULT;
1399 else
1400 state = INSTALLSTATE_UNKNOWN;
1402 done:
1403 if (!prodkey)
1405 state = INSTALLSTATE_UNKNOWN;
1407 if (userdata)
1408 state = INSTALLSTATE_ABSENT;
1411 RegCloseKey(prodkey);
1412 RegCloseKey(userdata);
1413 return state;
1416 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
1418 INSTALLUILEVEL old = gUILevel;
1419 HWND oldwnd = gUIhwnd;
1421 TRACE("%08x %p\n", dwUILevel, phWnd);
1423 gUILevel = dwUILevel;
1424 if (phWnd)
1426 gUIhwnd = *phWnd;
1427 *phWnd = oldwnd;
1429 return old;
1432 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
1433 DWORD dwMessageFilter, LPVOID pvContext)
1435 INSTALLUI_HANDLERA prev = gUIHandlerA;
1437 TRACE("%p %x %p\n",puiHandler, dwMessageFilter,pvContext);
1438 gUIHandlerA = puiHandler;
1439 gUIFilter = dwMessageFilter;
1440 gUIContext = pvContext;
1442 return prev;
1445 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
1446 DWORD dwMessageFilter, LPVOID pvContext)
1448 INSTALLUI_HANDLERW prev = gUIHandlerW;
1450 TRACE("%p %x %p\n",puiHandler,dwMessageFilter,pvContext);
1451 gUIHandlerW = puiHandler;
1452 gUIFilter = dwMessageFilter;
1453 gUIContext = pvContext;
1455 return prev;
1458 /******************************************************************
1459 * MsiLoadStringW [MSI.@]
1461 * Loads a string from MSI's string resources.
1463 * PARAMS
1465 * handle [I] only -1 is handled currently
1466 * id [I] id of the string to be loaded
1467 * lpBuffer [O] buffer for the string to be written to
1468 * nBufferMax [I] maximum size of the buffer in characters
1469 * lang [I] the preferred language for the string
1471 * RETURNS
1473 * If successful, this function returns the language id of the string loaded
1474 * If the function fails, the function returns zero.
1476 * NOTES
1478 * The type of the first parameter is unknown. LoadString's prototype
1479 * suggests that it might be a module handle. I have made it an MSI handle
1480 * for starters, as -1 is an invalid MSI handle, but not an invalid module
1481 * handle. Maybe strings can be stored in an MSI database somehow.
1483 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
1484 int nBufferMax, LANGID lang )
1486 HRSRC hres;
1487 HGLOBAL hResData;
1488 LPWSTR p;
1489 DWORD i, len;
1491 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
1493 if( handle != -1 )
1494 FIXME("don't know how to deal with handle = %08lx\n", handle);
1496 if( !lang )
1497 lang = GetUserDefaultLangID();
1499 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
1500 (LPWSTR)1, lang );
1501 if( !hres )
1502 return 0;
1503 hResData = LoadResource( msi_hInstance, hres );
1504 if( !hResData )
1505 return 0;
1506 p = LockResource( hResData );
1507 if( !p )
1508 return 0;
1510 for (i = 0; i < (id&0xf); i++)
1511 p += *p + 1;
1512 len = *p;
1514 if( nBufferMax <= len )
1515 return 0;
1517 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
1518 lpBuffer[ len ] = 0;
1520 TRACE("found -> %s\n", debugstr_w(lpBuffer));
1522 return lang;
1525 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
1526 int nBufferMax, LANGID lang )
1528 LPWSTR bufW;
1529 LANGID r;
1530 DWORD len;
1532 bufW = msi_alloc(nBufferMax*sizeof(WCHAR));
1533 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
1534 if( r )
1536 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
1537 if( len <= nBufferMax )
1538 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
1539 lpBuffer, nBufferMax, NULL, NULL );
1540 else
1541 r = 0;
1543 msi_free(bufW);
1544 return r;
1547 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
1548 LPDWORD pcchBuf)
1550 char szProduct[GUID_SIZE];
1552 TRACE("%s %p %p\n", debugstr_a(szComponent), lpPathBuf, pcchBuf);
1554 if (MsiGetProductCodeA( szComponent, szProduct ) != ERROR_SUCCESS)
1555 return INSTALLSTATE_UNKNOWN;
1557 return MsiGetComponentPathA( szProduct, szComponent, lpPathBuf, pcchBuf );
1560 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
1561 LPDWORD pcchBuf)
1563 WCHAR szProduct[GUID_SIZE];
1565 TRACE("%s %p %p\n", debugstr_w(szComponent), lpPathBuf, pcchBuf);
1567 if (MsiGetProductCodeW( szComponent, szProduct ) != ERROR_SUCCESS)
1568 return INSTALLSTATE_UNKNOWN;
1570 return MsiGetComponentPathW( szProduct, szComponent, lpPathBuf, pcchBuf );
1573 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
1574 WORD wLanguageId, DWORD f)
1576 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_a(lpText), debugstr_a(lpCaption),
1577 uType, wLanguageId, f);
1578 return MessageBoxExA(hWnd,lpText,lpCaption,uType,wLanguageId);
1581 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
1582 WORD wLanguageId, DWORD f)
1584 FIXME("%p %s %s %u %08x %08x\n", hWnd, debugstr_w(lpText), debugstr_w(lpCaption),
1585 uType, wLanguageId, f);
1586 return MessageBoxExW(hWnd,lpText,lpCaption,uType,wLanguageId);
1589 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
1590 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
1591 LPDWORD pcchPathBuf )
1593 FIXME("%s %s %08x %08x %p %p\n", debugstr_a(szAssemblyName),
1594 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1595 pcchPathBuf);
1596 return ERROR_CALL_NOT_IMPLEMENTED;
1599 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
1600 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
1601 LPDWORD pcchPathBuf )
1603 FIXME("%s %s %08x %08x %p %p\n", debugstr_w(szAssemblyName),
1604 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
1605 pcchPathBuf);
1606 return ERROR_CALL_NOT_IMPLEMENTED;
1609 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
1610 LPSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1612 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
1613 return ERROR_CALL_NOT_IMPLEMENTED;
1616 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
1617 LPWSTR szPath, LPDWORD pcchPath, LPDWORD pcchArgs )
1619 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
1620 return ERROR_CALL_NOT_IMPLEMENTED;
1623 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
1624 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1625 LPDWORD pcbHashData)
1627 FIXME("%s %08x %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
1628 ppcCertContext, pbHashData, pcbHashData);
1629 return ERROR_CALL_NOT_IMPLEMENTED;
1632 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
1633 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, LPBYTE pbHashData,
1634 LPDWORD pcbHashData)
1636 FIXME("%s %08x %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
1637 ppcCertContext, pbHashData, pcbHashData);
1638 return ERROR_CALL_NOT_IMPLEMENTED;
1641 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
1642 LPSTR szValue, LPDWORD pccbValue )
1644 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
1645 return ERROR_CALL_NOT_IMPLEMENTED;
1648 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
1649 LPWSTR szValue, LPDWORD pccbValue )
1651 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
1652 return ERROR_CALL_NOT_IMPLEMENTED;
1655 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
1657 UINT r;
1658 LPWSTR szPack = NULL;
1660 TRACE("%s\n", debugstr_a(szPackage) );
1662 if( szPackage )
1664 szPack = strdupAtoW( szPackage );
1665 if( !szPack )
1666 return ERROR_OUTOFMEMORY;
1669 r = MsiVerifyPackageW( szPack );
1671 msi_free( szPack );
1673 return r;
1676 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
1678 MSIHANDLE handle;
1679 UINT r;
1681 TRACE("%s\n", debugstr_w(szPackage) );
1683 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
1684 MsiCloseHandle( handle );
1686 return r;
1689 static INSTALLSTATE WINAPI MSI_GetComponentPath(LPCWSTR szProduct, LPCWSTR szComponent,
1690 awstring* lpPathBuf, LPDWORD pcchBuf)
1692 WCHAR squished_pc[GUID_SIZE];
1693 WCHAR squished_comp[GUID_SIZE];
1694 HKEY hkey;
1695 LPWSTR path = NULL;
1696 INSTALLSTATE state;
1697 DWORD version;
1699 static const WCHAR wininstaller[] = {
1700 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0};
1702 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
1703 debugstr_w(szComponent), lpPathBuf->str.w, pcchBuf);
1705 if (!szProduct || !szComponent)
1706 return INSTALLSTATE_INVALIDARG;
1708 if (lpPathBuf->str.w && !pcchBuf)
1709 return INSTALLSTATE_INVALIDARG;
1711 if (!squash_guid(szProduct, squished_pc) ||
1712 !squash_guid(szComponent, squished_comp))
1713 return INSTALLSTATE_INVALIDARG;
1715 state = INSTALLSTATE_UNKNOWN;
1717 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1718 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1720 path = msi_reg_get_val_str(hkey, squished_pc);
1721 RegCloseKey(hkey);
1723 state = INSTALLSTATE_ABSENT;
1725 if ((MSIREG_OpenLocalSystemProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1726 MSIREG_OpenUserDataProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS) &&
1727 msi_reg_get_val_dword(hkey, wininstaller, &version) &&
1728 GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1730 RegCloseKey(hkey);
1731 state = INSTALLSTATE_LOCAL;
1735 if (state != INSTALLSTATE_LOCAL &&
1736 (MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS ||
1737 MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) == ERROR_SUCCESS))
1739 RegCloseKey(hkey);
1741 if (MSIREG_OpenLocalSystemComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS ||
1742 MSIREG_OpenUserDataComponentKey(szComponent, &hkey, FALSE) == ERROR_SUCCESS)
1744 msi_free(path);
1745 path = msi_reg_get_val_str(hkey, squished_pc);
1746 RegCloseKey(hkey);
1748 state = INSTALLSTATE_ABSENT;
1750 if (GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES)
1751 state = INSTALLSTATE_LOCAL;
1755 if (!path)
1756 return INSTALLSTATE_UNKNOWN;
1758 if (state == INSTALLSTATE_LOCAL && !*path)
1759 state = INSTALLSTATE_NOTUSED;
1761 msi_strcpy_to_awstring(path, lpPathBuf, pcchBuf);
1762 msi_free(path);
1763 return state;
1766 /******************************************************************
1767 * MsiGetComponentPathW [MSI.@]
1769 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
1770 LPWSTR lpPathBuf, LPDWORD pcchBuf)
1772 awstring path;
1774 path.unicode = TRUE;
1775 path.str.w = lpPathBuf;
1777 return MSI_GetComponentPath( szProduct, szComponent, &path, pcchBuf );
1780 /******************************************************************
1781 * MsiGetComponentPathA [MSI.@]
1783 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
1784 LPSTR lpPathBuf, LPDWORD pcchBuf)
1786 LPWSTR szwProduct, szwComponent = NULL;
1787 INSTALLSTATE r = INSTALLSTATE_UNKNOWN;
1788 awstring path;
1790 szwProduct = strdupAtoW( szProduct );
1791 if( szProduct && !szwProduct)
1792 goto end;
1794 szwComponent = strdupAtoW( szComponent );
1795 if( szComponent && !szwComponent )
1796 goto end;
1798 path.unicode = FALSE;
1799 path.str.a = lpPathBuf;
1801 r = MSI_GetComponentPath( szwProduct, szwComponent, &path, pcchBuf );
1803 end:
1804 msi_free( szwProduct );
1805 msi_free( szwComponent );
1807 return r;
1810 /******************************************************************
1811 * MsiQueryFeatureStateA [MSI.@]
1813 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1815 LPWSTR szwProduct = NULL, szwFeature= NULL;
1816 INSTALLSTATE rc = INSTALLSTATE_UNKNOWN;
1818 szwProduct = strdupAtoW( szProduct );
1819 if ( szProduct && !szwProduct )
1820 goto end;
1822 szwFeature = strdupAtoW( szFeature );
1823 if ( szFeature && !szwFeature )
1824 goto end;
1826 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1828 end:
1829 msi_free( szwProduct);
1830 msi_free( szwFeature);
1832 return rc;
1835 /******************************************************************
1836 * MsiQueryFeatureStateW [MSI.@]
1838 * Checks the state of a feature
1840 * PARAMS
1841 * szProduct [I] Product's GUID string
1842 * szFeature [I] Feature's GUID string
1844 * RETURNS
1845 * INSTALLSTATE_LOCAL Feature is installed and usable
1846 * INSTALLSTATE_ABSENT Feature is absent
1847 * INSTALLSTATE_ADVERTISED Feature should be installed on demand
1848 * INSTALLSTATE_UNKNOWN An error occurred
1849 * INSTALLSTATE_INVALIDARG One of the GUIDs was invalid
1852 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1854 WCHAR squishProduct[33], comp[GUID_SIZE];
1855 GUID guid;
1856 LPWSTR components, p, parent_feature, path;
1857 UINT rc;
1858 HKEY hkey;
1859 INSTALLSTATE r;
1860 BOOL missing = FALSE;
1861 BOOL machine = FALSE;
1863 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1865 if (!szProduct || !szFeature)
1866 return INSTALLSTATE_INVALIDARG;
1868 if (!squash_guid( szProduct, squishProduct ))
1869 return INSTALLSTATE_INVALIDARG;
1871 if (MSIREG_OpenManagedFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
1872 MSIREG_OpenUserFeaturesKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
1874 rc = MSIREG_OpenLocalClassesFeaturesKey(szProduct, &hkey, FALSE);
1875 if (rc != ERROR_SUCCESS)
1876 return INSTALLSTATE_UNKNOWN;
1878 machine = TRUE;
1881 parent_feature = msi_reg_get_val_str( hkey, szFeature );
1882 RegCloseKey(hkey);
1884 if (!parent_feature)
1885 return INSTALLSTATE_UNKNOWN;
1887 r = (parent_feature[0] == 6) ? INSTALLSTATE_ABSENT : INSTALLSTATE_LOCAL;
1888 msi_free(parent_feature);
1889 if (r == INSTALLSTATE_ABSENT)
1890 return r;
1892 if (machine)
1893 rc = MSIREG_OpenLocalUserDataFeaturesKey(szProduct, &hkey, FALSE);
1894 else
1895 rc = MSIREG_OpenUserDataFeaturesKey(szProduct, &hkey, FALSE);
1897 if (rc != ERROR_SUCCESS)
1898 return INSTALLSTATE_ADVERTISED;
1900 components = msi_reg_get_val_str( hkey, szFeature );
1901 RegCloseKey(hkey);
1903 TRACE("rc = %d buffer = %s\n", rc, debugstr_w(components));
1905 if (!components)
1906 return INSTALLSTATE_ADVERTISED;
1908 for( p = components; *p && *p != 2 ; p += 20)
1910 if (!decode_base85_guid( p, &guid ))
1912 if (p != components)
1913 break;
1915 msi_free(components);
1916 return INSTALLSTATE_BADCONFIG;
1919 StringFromGUID2(&guid, comp, GUID_SIZE);
1921 if (machine)
1922 rc = MSIREG_OpenLocalUserDataComponentKey(comp, &hkey, FALSE);
1923 else
1924 rc = MSIREG_OpenUserDataComponentKey(comp, &hkey, FALSE);
1926 if (rc != ERROR_SUCCESS)
1928 msi_free(components);
1929 return INSTALLSTATE_ADVERTISED;
1932 path = msi_reg_get_val_str(hkey, squishProduct);
1933 if (!path)
1934 missing = TRUE;
1936 msi_free(path);
1939 TRACE("%s %s -> %d\n", debugstr_w(szProduct), debugstr_w(szFeature), r);
1940 msi_free(components);
1942 if (missing)
1943 return INSTALLSTATE_ADVERTISED;
1945 return INSTALLSTATE_LOCAL;
1948 /******************************************************************
1949 * MsiGetFileVersionA [MSI.@]
1951 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1952 LPDWORD pcchVersionBuf, LPSTR lpLangBuf, LPDWORD pcchLangBuf)
1954 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1955 UINT ret = ERROR_OUTOFMEMORY;
1957 if ((lpVersionBuf && !pcchVersionBuf) ||
1958 (lpLangBuf && !pcchLangBuf))
1959 return ERROR_INVALID_PARAMETER;
1961 if( szFilePath )
1963 szwFilePath = strdupAtoW( szFilePath );
1964 if( !szwFilePath )
1965 goto end;
1968 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1970 lpwVersionBuff = msi_alloc(*pcchVersionBuf*sizeof(WCHAR));
1971 if( !lpwVersionBuff )
1972 goto end;
1975 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1977 lpwLangBuff = msi_alloc(*pcchLangBuf*sizeof(WCHAR));
1978 if( !lpwLangBuff )
1979 goto end;
1982 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1983 lpwLangBuff, pcchLangBuf);
1985 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwVersionBuff )
1986 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1987 lpVersionBuf, *pcchVersionBuf + 1, NULL, NULL);
1988 if( (ret == ERROR_SUCCESS || ret == ERROR_MORE_DATA) && lpwLangBuff )
1989 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1990 lpLangBuf, *pcchLangBuf + 1, NULL, NULL);
1992 end:
1993 msi_free(szwFilePath);
1994 msi_free(lpwVersionBuff);
1995 msi_free(lpwLangBuff);
1997 return ret;
2000 /******************************************************************
2001 * MsiGetFileVersionW [MSI.@]
2003 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
2004 LPDWORD pcchVersionBuf, LPWSTR lpLangBuf, LPDWORD pcchLangBuf)
2006 static const WCHAR szVersionResource[] = {'\\',0};
2007 static const WCHAR szVersionFormat[] = {
2008 '%','d','.','%','d','.','%','d','.','%','d',0};
2009 static const WCHAR szLangResource[] = {
2010 '\\','V','a','r','F','i','l','e','I','n','f','o','\\',
2011 'T','r','a','n','s','l','a','t','i','o','n',0};
2012 static const WCHAR szLangFormat[] = {'%','d',0};
2013 UINT ret = 0;
2014 DWORD dwVerLen, gle;
2015 LPVOID lpVer = NULL;
2016 VS_FIXEDFILEINFO *ffi;
2017 USHORT *lang;
2018 UINT puLen;
2019 WCHAR tmp[32];
2021 TRACE("%s %p %d %p %d\n", debugstr_w(szFilePath),
2022 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
2023 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
2025 if ((lpVersionBuf && !pcchVersionBuf) ||
2026 (lpLangBuf && !pcchLangBuf))
2027 return ERROR_INVALID_PARAMETER;
2029 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
2030 if( !dwVerLen )
2032 gle = GetLastError();
2033 if (gle == ERROR_BAD_PATHNAME)
2034 return ERROR_FILE_NOT_FOUND;
2035 else if (gle == ERROR_RESOURCE_DATA_NOT_FOUND)
2036 return ERROR_FILE_INVALID;
2038 return gle;
2041 lpVer = msi_alloc(dwVerLen);
2042 if( !lpVer )
2044 ret = ERROR_OUTOFMEMORY;
2045 goto end;
2048 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
2050 ret = GetLastError();
2051 goto end;
2054 if (pcchVersionBuf)
2056 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
2057 (puLen > 0) )
2059 wsprintfW(tmp, szVersionFormat,
2060 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
2061 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
2062 if (lpVersionBuf) lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
2064 if (lstrlenW(tmp) >= *pcchVersionBuf)
2065 ret = ERROR_MORE_DATA;
2067 *pcchVersionBuf = lstrlenW(tmp);
2069 else
2071 if (lpVersionBuf) *lpVersionBuf = 0;
2072 *pcchVersionBuf = 0;
2076 if (pcchLangBuf)
2078 if (VerQueryValueW(lpVer, szLangResource, (LPVOID*)&lang, &puLen) &&
2079 (puLen > 0))
2081 wsprintfW(tmp, szLangFormat, *lang);
2082 if (lpLangBuf) lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
2084 if (lstrlenW(tmp) >= *pcchLangBuf)
2085 ret = ERROR_MORE_DATA;
2087 *pcchLangBuf = lstrlenW(tmp);
2089 else
2091 if (lpLangBuf) *lpLangBuf = 0;
2092 *pcchLangBuf = 0;
2096 end:
2097 msi_free(lpVer);
2098 return ret;
2101 /***********************************************************************
2102 * MsiGetFeatureUsageW [MSI.@]
2104 UINT WINAPI MsiGetFeatureUsageW( LPCWSTR szProduct, LPCWSTR szFeature,
2105 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2107 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
2108 pdwUseCount, pwDateUsed);
2109 return ERROR_CALL_NOT_IMPLEMENTED;
2112 /***********************************************************************
2113 * MsiGetFeatureUsageA [MSI.@]
2115 UINT WINAPI MsiGetFeatureUsageA( LPCSTR szProduct, LPCSTR szFeature,
2116 LPDWORD pdwUseCount, LPWORD pwDateUsed )
2118 LPWSTR prod = NULL, feat = NULL;
2119 UINT ret = ERROR_OUTOFMEMORY;
2121 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
2122 pdwUseCount, pwDateUsed);
2124 prod = strdupAtoW( szProduct );
2125 if (szProduct && !prod)
2126 goto end;
2128 feat = strdupAtoW( szFeature );
2129 if (szFeature && !feat)
2130 goto end;
2132 ret = MsiGetFeatureUsageW( prod, feat, pdwUseCount, pwDateUsed );
2134 end:
2135 msi_free( prod );
2136 msi_free( feat );
2138 return ret;
2141 /***********************************************************************
2142 * MsiUseFeatureExW [MSI.@]
2144 INSTALLSTATE WINAPI MsiUseFeatureExW( LPCWSTR szProduct, LPCWSTR szFeature,
2145 DWORD dwInstallMode, DWORD dwReserved )
2147 INSTALLSTATE state;
2149 TRACE("%s %s %i %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2150 dwInstallMode, dwReserved);
2152 state = MsiQueryFeatureStateW( szProduct, szFeature );
2154 if (dwReserved)
2155 return INSTALLSTATE_INVALIDARG;
2157 if (state == INSTALLSTATE_LOCAL && dwInstallMode != INSTALLMODE_NODETECTION)
2159 FIXME("mark product %s feature %s as used\n",
2160 debugstr_w(szProduct), debugstr_w(szFeature) );
2163 return state;
2166 /***********************************************************************
2167 * MsiUseFeatureExA [MSI.@]
2169 INSTALLSTATE WINAPI MsiUseFeatureExA( LPCSTR szProduct, LPCSTR szFeature,
2170 DWORD dwInstallMode, DWORD dwReserved )
2172 INSTALLSTATE ret = INSTALLSTATE_UNKNOWN;
2173 LPWSTR prod = NULL, feat = NULL;
2175 TRACE("%s %s %i %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2176 dwInstallMode, dwReserved);
2178 prod = strdupAtoW( szProduct );
2179 if (szProduct && !prod)
2180 goto end;
2182 feat = strdupAtoW( szFeature );
2183 if (szFeature && !feat)
2184 goto end;
2186 ret = MsiUseFeatureExW( prod, feat, dwInstallMode, dwReserved );
2188 end:
2189 msi_free( prod );
2190 msi_free( feat );
2192 return ret;
2195 /***********************************************************************
2196 * MsiUseFeatureW [MSI.@]
2198 INSTALLSTATE WINAPI MsiUseFeatureW( LPCWSTR szProduct, LPCWSTR szFeature )
2200 return MsiUseFeatureExW(szProduct, szFeature, 0, 0);
2203 /***********************************************************************
2204 * MsiUseFeatureA [MSI.@]
2206 INSTALLSTATE WINAPI MsiUseFeatureA( LPCSTR szProduct, LPCSTR szFeature )
2208 return MsiUseFeatureExA(szProduct, szFeature, 0, 0);
2211 /***********************************************************************
2212 * MSI_ProvideQualifiedComponentEx [internal]
2214 static UINT WINAPI MSI_ProvideQualifiedComponentEx(LPCWSTR szComponent,
2215 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2216 DWORD Unused1, DWORD Unused2, awstring *lpPathBuf,
2217 LPDWORD pcchPathBuf)
2219 WCHAR product[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1],
2220 feature[MAX_FEATURE_CHARS+1];
2221 LPWSTR info;
2222 HKEY hkey;
2223 DWORD sz;
2224 UINT rc;
2226 TRACE("%s %s %i %s %i %i %p %p\n", debugstr_w(szComponent),
2227 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
2228 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2230 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
2231 if (rc != ERROR_SUCCESS)
2232 return ERROR_INDEX_ABSENT;
2234 info = msi_reg_get_val_str( hkey, szQualifier );
2235 RegCloseKey(hkey);
2237 if (!info)
2238 return ERROR_INDEX_ABSENT;
2240 MsiDecomposeDescriptorW(info, product, feature, component, &sz);
2242 if (!szProduct)
2243 rc = MSI_GetComponentPath(product, component, lpPathBuf, pcchPathBuf);
2244 else
2245 rc = MSI_GetComponentPath(szProduct, component, lpPathBuf, pcchPathBuf);
2247 msi_free( info );
2249 if (rc != INSTALLSTATE_LOCAL)
2250 return ERROR_FILE_NOT_FOUND;
2252 return ERROR_SUCCESS;
2255 /***********************************************************************
2256 * MsiProvideQualifiedComponentExW [MSI.@]
2258 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
2259 LPCWSTR szQualifier, DWORD dwInstallMode, LPCWSTR szProduct,
2260 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
2261 LPDWORD pcchPathBuf)
2263 awstring path;
2265 path.unicode = TRUE;
2266 path.str.w = lpPathBuf;
2268 return MSI_ProvideQualifiedComponentEx(szComponent, szQualifier,
2269 dwInstallMode, szProduct, Unused1, Unused2, &path, pcchPathBuf);
2272 /***********************************************************************
2273 * MsiProvideQualifiedComponentExA [MSI.@]
2275 UINT WINAPI MsiProvideQualifiedComponentExA(LPCSTR szComponent,
2276 LPCSTR szQualifier, DWORD dwInstallMode, LPCSTR szProduct,
2277 DWORD Unused1, DWORD Unused2, LPSTR lpPathBuf,
2278 LPDWORD pcchPathBuf)
2280 LPWSTR szwComponent, szwQualifier = NULL, szwProduct = NULL;
2281 UINT r = ERROR_OUTOFMEMORY;
2282 awstring path;
2284 TRACE("%s %s %u %s %u %u %p %p\n", debugstr_a(szComponent),
2285 debugstr_a(szQualifier), dwInstallMode, debugstr_a(szProduct),
2286 Unused1, Unused2, lpPathBuf, pcchPathBuf);
2288 szwComponent = strdupAtoW( szComponent );
2289 if (szComponent && !szwComponent)
2290 goto end;
2292 szwQualifier = strdupAtoW( szQualifier );
2293 if (szQualifier && !szwQualifier)
2294 goto end;
2296 szwProduct = strdupAtoW( szProduct );
2297 if (szProduct && !szwProduct)
2298 goto end;
2300 path.unicode = FALSE;
2301 path.str.a = lpPathBuf;
2303 r = MSI_ProvideQualifiedComponentEx(szwComponent, szwQualifier,
2304 dwInstallMode, szwProduct, Unused1,
2305 Unused2, &path, pcchPathBuf);
2306 end:
2307 msi_free(szwProduct);
2308 msi_free(szwComponent);
2309 msi_free(szwQualifier);
2311 return r;
2314 /***********************************************************************
2315 * MsiProvideQualifiedComponentW [MSI.@]
2317 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
2318 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
2319 LPDWORD pcchPathBuf)
2321 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
2322 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2325 /***********************************************************************
2326 * MsiProvideQualifiedComponentA [MSI.@]
2328 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
2329 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
2330 LPDWORD pcchPathBuf)
2332 return MsiProvideQualifiedComponentExA(szComponent, szQualifier,
2333 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
2336 /***********************************************************************
2337 * MSI_GetUserInfo [internal]
2339 static USERINFOSTATE WINAPI MSI_GetUserInfo(LPCWSTR szProduct,
2340 awstring *lpUserNameBuf, LPDWORD pcchUserNameBuf,
2341 awstring *lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2342 awstring *lpSerialBuf, LPDWORD pcchSerialBuf)
2344 WCHAR squished_pc[SQUISH_GUID_SIZE];
2345 LPWSTR user, org, serial;
2346 USERINFOSTATE state;
2347 HKEY hkey, props;
2348 LPCWSTR orgptr;
2349 UINT r;
2351 static const WCHAR szEmpty[] = {0};
2353 TRACE("%s %p %p %p %p %p %p\n", debugstr_w(szProduct), lpUserNameBuf,
2354 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
2355 pcchSerialBuf);
2357 if (!szProduct || !squash_guid(szProduct, squished_pc))
2358 return USERINFOSTATE_INVALIDARG;
2360 if (MSIREG_OpenLocalManagedProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
2361 MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS &&
2362 MSIREG_OpenLocalClassesProductKey(szProduct, &hkey, FALSE) != ERROR_SUCCESS)
2364 return USERINFOSTATE_UNKNOWN;
2367 if (MSIREG_OpenCurrentUserInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS &&
2368 MSIREG_OpenLocalSystemInstallProps(szProduct, &props, FALSE) != ERROR_SUCCESS)
2370 RegCloseKey(hkey);
2371 return USERINFOSTATE_ABSENT;
2374 user = msi_reg_get_val_str(props, INSTALLPROPERTY_REGOWNERW);
2375 org = msi_reg_get_val_str(props, INSTALLPROPERTY_REGCOMPANYW);
2376 serial = msi_reg_get_val_str(props, INSTALLPROPERTY_PRODUCTIDW);
2377 state = USERINFOSTATE_ABSENT;
2379 RegCloseKey(hkey);
2380 RegCloseKey(props);
2382 if (user && serial)
2383 state = USERINFOSTATE_PRESENT;
2385 if (pcchUserNameBuf)
2387 if (lpUserNameBuf && !user)
2389 (*pcchUserNameBuf)--;
2390 goto done;
2393 r = msi_strcpy_to_awstring(user, lpUserNameBuf, pcchUserNameBuf);
2394 if (r == ERROR_MORE_DATA)
2396 state = USERINFOSTATE_MOREDATA;
2397 goto done;
2401 if (pcchOrgNameBuf)
2403 orgptr = org;
2404 if (!orgptr) orgptr = szEmpty;
2406 r = msi_strcpy_to_awstring(orgptr, lpOrgNameBuf, pcchOrgNameBuf);
2407 if (r == ERROR_MORE_DATA)
2409 state = USERINFOSTATE_MOREDATA;
2410 goto done;
2414 if (pcchSerialBuf)
2416 if (!serial)
2418 (*pcchSerialBuf)--;
2419 goto done;
2422 r = msi_strcpy_to_awstring(serial, lpSerialBuf, pcchSerialBuf);
2423 if (r == ERROR_MORE_DATA)
2424 state = USERINFOSTATE_MOREDATA;
2427 done:
2428 msi_free(user);
2429 msi_free(org);
2430 msi_free(serial);
2432 return state;
2435 /***********************************************************************
2436 * MsiGetUserInfoW [MSI.@]
2438 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct,
2439 LPWSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2440 LPWSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2441 LPWSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2443 awstring user, org, serial;
2445 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2446 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2447 (lpSerialBuf && !pcchSerialBuf))
2448 return USERINFOSTATE_INVALIDARG;
2450 user.unicode = TRUE;
2451 user.str.w = lpUserNameBuf;
2452 org.unicode = TRUE;
2453 org.str.w = lpOrgNameBuf;
2454 serial.unicode = TRUE;
2455 serial.str.w = lpSerialBuf;
2457 return MSI_GetUserInfo( szProduct, &user, pcchUserNameBuf,
2458 &org, pcchOrgNameBuf,
2459 &serial, pcchSerialBuf );
2462 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct,
2463 LPSTR lpUserNameBuf, LPDWORD pcchUserNameBuf,
2464 LPSTR lpOrgNameBuf, LPDWORD pcchOrgNameBuf,
2465 LPSTR lpSerialBuf, LPDWORD pcchSerialBuf)
2467 awstring user, org, serial;
2468 LPWSTR prod;
2469 UINT r;
2471 if ((lpUserNameBuf && !pcchUserNameBuf) ||
2472 (lpOrgNameBuf && !pcchOrgNameBuf) ||
2473 (lpSerialBuf && !pcchSerialBuf))
2474 return USERINFOSTATE_INVALIDARG;
2476 prod = strdupAtoW( szProduct );
2477 if (szProduct && !prod)
2478 return ERROR_OUTOFMEMORY;
2480 user.unicode = FALSE;
2481 user.str.a = lpUserNameBuf;
2482 org.unicode = FALSE;
2483 org.str.a = lpOrgNameBuf;
2484 serial.unicode = FALSE;
2485 serial.str.a = lpSerialBuf;
2487 r = MSI_GetUserInfo( prod, &user, pcchUserNameBuf,
2488 &org, pcchOrgNameBuf,
2489 &serial, pcchSerialBuf );
2491 msi_free( prod );
2493 return r;
2496 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
2498 MSIHANDLE handle;
2499 UINT rc;
2500 MSIPACKAGE *package;
2501 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2503 TRACE("(%s)\n",debugstr_w(szProduct));
2505 rc = MsiOpenProductW(szProduct,&handle);
2506 if (rc != ERROR_SUCCESS)
2507 return ERROR_INVALID_PARAMETER;
2509 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2510 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2511 msiobj_release( &package->hdr );
2513 MsiCloseHandle(handle);
2515 return rc;
2518 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
2520 MSIHANDLE handle;
2521 UINT rc;
2522 MSIPACKAGE *package;
2523 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
2525 TRACE("(%s)\n",debugstr_a(szProduct));
2527 rc = MsiOpenProductA(szProduct,&handle);
2528 if (rc != ERROR_SUCCESS)
2529 return ERROR_INVALID_PARAMETER;
2531 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
2532 rc = ACTION_PerformUIAction(package, szFirstRun, -1);
2533 msiobj_release( &package->hdr );
2535 MsiCloseHandle(handle);
2537 return rc;
2540 /***********************************************************************
2541 * MsiConfigureFeatureA [MSI.@]
2543 UINT WINAPI MsiConfigureFeatureA(LPCSTR szProduct, LPCSTR szFeature, INSTALLSTATE eInstallState)
2545 LPWSTR prod, feat = NULL;
2546 UINT r = ERROR_OUTOFMEMORY;
2548 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature), eInstallState);
2550 prod = strdupAtoW( szProduct );
2551 if (szProduct && !prod)
2552 goto end;
2554 feat = strdupAtoW( szFeature );
2555 if (szFeature && !feat)
2556 goto end;
2558 r = MsiConfigureFeatureW(prod, feat, eInstallState);
2560 end:
2561 msi_free(feat);
2562 msi_free(prod);
2564 return r;
2567 /***********************************************************************
2568 * MsiConfigureFeatureW [MSI.@]
2570 UINT WINAPI MsiConfigureFeatureW(LPCWSTR szProduct, LPCWSTR szFeature, INSTALLSTATE eInstallState)
2572 static const WCHAR szCostInit[] = { 'C','o','s','t','I','n','i','t','i','a','l','i','z','e',0 };
2573 MSIPACKAGE *package = NULL;
2574 UINT r;
2575 WCHAR sourcepath[MAX_PATH], filename[MAX_PATH];
2576 DWORD sz;
2578 TRACE("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature), eInstallState);
2580 if (!szProduct || !szFeature)
2581 return ERROR_INVALID_PARAMETER;
2583 switch (eInstallState)
2585 case INSTALLSTATE_DEFAULT:
2586 /* FIXME: how do we figure out the default location? */
2587 eInstallState = INSTALLSTATE_LOCAL;
2588 break;
2589 case INSTALLSTATE_LOCAL:
2590 case INSTALLSTATE_SOURCE:
2591 case INSTALLSTATE_ABSENT:
2592 case INSTALLSTATE_ADVERTISED:
2593 break;
2594 default:
2595 return ERROR_INVALID_PARAMETER;
2598 r = MSI_OpenProductW( szProduct, &package );
2599 if (r != ERROR_SUCCESS)
2600 return r;
2602 sz = sizeof(sourcepath);
2603 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2604 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2606 sz = sizeof(filename);
2607 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2608 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2610 lstrcatW( sourcepath, filename );
2612 MsiSetInternalUI( INSTALLUILEVEL_BASIC, NULL );
2614 r = ACTION_PerformUIAction( package, szCostInit, -1 );
2615 if (r != ERROR_SUCCESS)
2616 goto end;
2618 r = MSI_SetFeatureStateW( package, szFeature, eInstallState);
2619 if (r != ERROR_SUCCESS)
2620 goto end;
2622 r = MSI_InstallPackage( package, sourcepath, NULL );
2624 end:
2625 msiobj_release( &package->hdr );
2627 return r;
2630 /***********************************************************************
2631 * MsiCreateAndVerifyInstallerDirectory [MSI.@]
2633 * Notes: undocumented
2635 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
2637 WCHAR path[MAX_PATH];
2639 TRACE("%d\n", dwReserved);
2641 if (dwReserved)
2643 FIXME("dwReserved=%d\n", dwReserved);
2644 return ERROR_INVALID_PARAMETER;
2647 if (!GetWindowsDirectoryW(path, MAX_PATH))
2648 return ERROR_FUNCTION_FAILED;
2650 lstrcatW(path, installerW);
2652 if (!CreateDirectoryW(path, NULL))
2653 return ERROR_FUNCTION_FAILED;
2655 return ERROR_SUCCESS;
2658 /***********************************************************************
2659 * MsiGetShortcutTargetA [MSI.@]
2661 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
2662 LPSTR szProductCode, LPSTR szFeatureId,
2663 LPSTR szComponentCode )
2665 LPWSTR target;
2666 const int len = MAX_FEATURE_CHARS+1;
2667 WCHAR product[MAX_FEATURE_CHARS+1], feature[MAX_FEATURE_CHARS+1], component[MAX_FEATURE_CHARS+1];
2668 UINT r;
2670 target = strdupAtoW( szShortcutTarget );
2671 if (szShortcutTarget && !target )
2672 return ERROR_OUTOFMEMORY;
2673 product[0] = 0;
2674 feature[0] = 0;
2675 component[0] = 0;
2676 r = MsiGetShortcutTargetW( target, product, feature, component );
2677 msi_free( target );
2678 if (r == ERROR_SUCCESS)
2680 WideCharToMultiByte( CP_ACP, 0, product, -1, szProductCode, len, NULL, NULL );
2681 WideCharToMultiByte( CP_ACP, 0, feature, -1, szFeatureId, len, NULL, NULL );
2682 WideCharToMultiByte( CP_ACP, 0, component, -1, szComponentCode, len, NULL, NULL );
2684 return r;
2687 /***********************************************************************
2688 * MsiGetShortcutTargetW [MSI.@]
2690 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
2691 LPWSTR szProductCode, LPWSTR szFeatureId,
2692 LPWSTR szComponentCode )
2694 IShellLinkDataList *dl = NULL;
2695 IPersistFile *pf = NULL;
2696 LPEXP_DARWIN_LINK darwin = NULL;
2697 HRESULT r, init;
2699 TRACE("%s %p %p %p\n", debugstr_w(szShortcutTarget),
2700 szProductCode, szFeatureId, szComponentCode );
2702 init = CoInitialize(NULL);
2704 r = CoCreateInstance( &CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER,
2705 &IID_IPersistFile, (LPVOID*) &pf );
2706 if( SUCCEEDED( r ) )
2708 r = IPersistFile_Load( pf, szShortcutTarget,
2709 STGM_READ | STGM_SHARE_DENY_WRITE );
2710 if( SUCCEEDED( r ) )
2712 r = IPersistFile_QueryInterface( pf, &IID_IShellLinkDataList,
2713 (LPVOID*) &dl );
2714 if( SUCCEEDED( r ) )
2716 IShellLinkDataList_CopyDataBlock( dl, EXP_DARWIN_ID_SIG,
2717 (LPVOID) &darwin );
2718 IShellLinkDataList_Release( dl );
2721 IPersistFile_Release( pf );
2724 if (SUCCEEDED(init))
2725 CoUninitialize();
2727 TRACE("darwin = %p\n", darwin);
2729 if (darwin)
2731 DWORD sz;
2732 UINT ret;
2734 ret = MsiDecomposeDescriptorW( darwin->szwDarwinID,
2735 szProductCode, szFeatureId, szComponentCode, &sz );
2736 LocalFree( darwin );
2737 return ret;
2740 return ERROR_FUNCTION_FAILED;
2743 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
2744 DWORD dwReinstallMode )
2746 MSIPACKAGE* package = NULL;
2747 UINT r;
2748 WCHAR sourcepath[MAX_PATH];
2749 WCHAR filename[MAX_PATH];
2750 static const WCHAR szLogVerbose[] = {
2751 ' ','L','O','G','V','E','R','B','O','S','E',0 };
2752 static const WCHAR szInstalled[] = { 'I','n','s','t','a','l','l','e','d',0};
2753 static const WCHAR szReinstall[] = {'R','E','I','N','S','T','A','L','L',0};
2754 static const WCHAR szReinstallMode[] = {'R','E','I','N','S','T','A','L','L','M','O','D','E',0};
2755 static const WCHAR szOne[] = {'1',0};
2756 WCHAR reinstallmode[11];
2757 LPWSTR ptr;
2758 DWORD sz;
2760 FIXME("%s %s %i\n", debugstr_w(szProduct), debugstr_w(szFeature),
2761 dwReinstallMode);
2763 ptr = reinstallmode;
2765 if (dwReinstallMode & REINSTALLMODE_FILEMISSING)
2766 *ptr++ = 'p';
2767 if (dwReinstallMode & REINSTALLMODE_FILEOLDERVERSION)
2768 *ptr++ = 'o';
2769 if (dwReinstallMode & REINSTALLMODE_FILEEQUALVERSION)
2770 *ptr++ = 'w';
2771 if (dwReinstallMode & REINSTALLMODE_FILEEXACT)
2772 *ptr++ = 'd';
2773 if (dwReinstallMode & REINSTALLMODE_FILEVERIFY)
2774 *ptr++ = 'c';
2775 if (dwReinstallMode & REINSTALLMODE_FILEREPLACE)
2776 *ptr++ = 'a';
2777 if (dwReinstallMode & REINSTALLMODE_USERDATA)
2778 *ptr++ = 'u';
2779 if (dwReinstallMode & REINSTALLMODE_MACHINEDATA)
2780 *ptr++ = 'm';
2781 if (dwReinstallMode & REINSTALLMODE_SHORTCUT)
2782 *ptr++ = 's';
2783 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2784 *ptr++ = 'v';
2785 *ptr = 0;
2787 sz = sizeof(sourcepath);
2788 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2789 MSICODE_PRODUCT, INSTALLPROPERTY_LASTUSEDSOURCEW, sourcepath, &sz);
2791 sz = sizeof(filename);
2792 MsiSourceListGetInfoW(szProduct, NULL, MSIINSTALLCONTEXT_USERUNMANAGED,
2793 MSICODE_PRODUCT, INSTALLPROPERTY_PACKAGENAMEW, filename, &sz);
2795 lstrcatW( sourcepath, filename );
2797 if (dwReinstallMode & REINSTALLMODE_PACKAGE)
2798 r = MSI_OpenPackageW( sourcepath, &package );
2799 else
2800 r = MSI_OpenProductW( szProduct, &package );
2802 if (r != ERROR_SUCCESS)
2803 return r;
2805 MSI_SetPropertyW( package, szReinstallMode, reinstallmode );
2806 MSI_SetPropertyW( package, szInstalled, szOne );
2807 MSI_SetPropertyW( package, szLogVerbose, szOne );
2808 MSI_SetPropertyW( package, szReinstall, szFeature );
2810 r = MSI_InstallPackage( package, sourcepath, NULL );
2812 msiobj_release( &package->hdr );
2814 return r;
2817 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
2818 DWORD dwReinstallMode )
2820 LPWSTR wszProduct;
2821 LPWSTR wszFeature;
2822 UINT rc;
2824 TRACE("%s %s %i\n", debugstr_a(szProduct), debugstr_a(szFeature),
2825 dwReinstallMode);
2827 wszProduct = strdupAtoW(szProduct);
2828 wszFeature = strdupAtoW(szFeature);
2830 rc = MsiReinstallFeatureW(wszProduct, wszFeature, dwReinstallMode);
2832 msi_free(wszProduct);
2833 msi_free(wszFeature);
2834 return rc;
2837 typedef struct
2839 unsigned int i[2];
2840 unsigned int buf[4];
2841 unsigned char in[64];
2842 unsigned char digest[16];
2843 } MD5_CTX;
2845 extern VOID WINAPI MD5Init( MD5_CTX *);
2846 extern VOID WINAPI MD5Update( MD5_CTX *, const unsigned char *, unsigned int );
2847 extern VOID WINAPI MD5Final( MD5_CTX *);
2849 /***********************************************************************
2850 * MsiGetFileHashW [MSI.@]
2852 UINT WINAPI MsiGetFileHashW( LPCWSTR szFilePath, DWORD dwOptions,
2853 PMSIFILEHASHINFO pHash )
2855 HANDLE handle, mapping;
2856 void *p;
2857 DWORD length;
2858 UINT r = ERROR_FUNCTION_FAILED;
2860 TRACE("%s %08x %p\n", debugstr_w(szFilePath), dwOptions, pHash );
2862 if (!szFilePath)
2863 return ERROR_INVALID_PARAMETER;
2865 if (!*szFilePath)
2866 return ERROR_PATH_NOT_FOUND;
2868 if (dwOptions)
2869 return ERROR_INVALID_PARAMETER;
2870 if (!pHash)
2871 return ERROR_INVALID_PARAMETER;
2872 if (pHash->dwFileHashInfoSize < sizeof *pHash)
2873 return ERROR_INVALID_PARAMETER;
2875 handle = CreateFileW( szFilePath, GENERIC_READ,
2876 FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, 0, NULL );
2877 if (handle == INVALID_HANDLE_VALUE)
2878 return ERROR_FILE_NOT_FOUND;
2880 length = GetFileSize( handle, NULL );
2882 mapping = CreateFileMappingW( handle, NULL, PAGE_READONLY, 0, 0, NULL );
2883 if (mapping)
2885 p = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, length );
2886 if (p)
2888 MD5_CTX ctx;
2890 MD5Init( &ctx );
2891 MD5Update( &ctx, p, length );
2892 MD5Final( &ctx );
2893 UnmapViewOfFile( p );
2895 memcpy( pHash->dwData, ctx.digest, sizeof pHash->dwData );
2896 r = ERROR_SUCCESS;
2898 CloseHandle( mapping );
2900 CloseHandle( handle );
2902 return r;
2905 /***********************************************************************
2906 * MsiGetFileHashA [MSI.@]
2908 UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
2909 PMSIFILEHASHINFO pHash )
2911 LPWSTR file;
2912 UINT r;
2914 TRACE("%s %08x %p\n", debugstr_a(szFilePath), dwOptions, pHash );
2916 file = strdupAtoW( szFilePath );
2917 if (szFilePath && !file)
2918 return ERROR_OUTOFMEMORY;
2920 r = MsiGetFileHashW( file, dwOptions, pHash );
2921 msi_free( file );
2922 return r;
2925 /***********************************************************************
2926 * MsiAdvertiseScriptW [MSI.@]
2928 UINT WINAPI MsiAdvertiseScriptW( LPCWSTR szScriptFile, DWORD dwFlags,
2929 PHKEY phRegData, BOOL fRemoveItems )
2931 FIXME("%s %08x %p %d\n",
2932 debugstr_w( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2933 return ERROR_CALL_NOT_IMPLEMENTED;
2936 /***********************************************************************
2937 * MsiAdvertiseScriptA [MSI.@]
2939 UINT WINAPI MsiAdvertiseScriptA( LPCSTR szScriptFile, DWORD dwFlags,
2940 PHKEY phRegData, BOOL fRemoveItems )
2942 FIXME("%s %08x %p %d\n",
2943 debugstr_a( szScriptFile ), dwFlags, phRegData, fRemoveItems );
2944 return ERROR_CALL_NOT_IMPLEMENTED;
2947 /***********************************************************************
2948 * MsiIsProductElevatedW [MSI.@]
2950 UINT WINAPI MsiIsProductElevatedW( LPCWSTR szProduct, BOOL *pfElevated )
2952 FIXME("%s %p - stub\n",
2953 debugstr_w( szProduct ), pfElevated );
2954 *pfElevated = TRUE;
2955 return ERROR_SUCCESS;
2958 /***********************************************************************
2959 * MsiIsProductElevatedA [MSI.@]
2961 UINT WINAPI MsiIsProductElevatedA( LPCSTR szProduct, BOOL *pfElevated )
2963 FIXME("%s %p - stub\n",
2964 debugstr_a( szProduct ), pfElevated );
2965 *pfElevated = TRUE;
2966 return ERROR_SUCCESS;