Add and correct some function declarations.
[wine/wine64.git] / dlls / msi / msi.c
blobd7ce2c01d603ef6bd7dd5231af3997be0e3ae109
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include <stdarg.h>
23 #define COBJMACROS
24 #define NONAMELESSUNION
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winreg.h"
29 #include "winnls.h"
30 #include "shlwapi.h"
31 #include "wine/debug.h"
32 #include "msi.h"
33 #include "msiquery.h"
34 #include "msipriv.h"
35 #include "wincrypt.h"
36 #include "winver.h"
37 #include "winuser.h"
38 #include "wine/unicode.h"
39 #include "action.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi);
44 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
45 * which is a problem because LPCTSTR isn't defined when compiling wine.
46 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
47 * and make sure to only use it in W functions.
49 #define LPCTSTR LPCWSTR
51 /* the UI level */
52 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
53 HWND gUIhwnd = 0;
54 INSTALLUI_HANDLERA gUIHandlerA = NULL;
55 INSTALLUI_HANDLERW gUIHandlerW = NULL;
56 DWORD gUIFilter = 0;
57 LPVOID gUIContext = NULL;
58 WCHAR gszLogFile[MAX_PATH];
59 HINSTANCE msi_hInstance;
61 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
63 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
65 UINT r;
66 LPWSTR szwProd = NULL;
68 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
70 if( szProduct )
72 szwProd = strdupAtoW( szProduct );
73 if( !szwProd )
74 return ERROR_OUTOFMEMORY;
77 r = MsiOpenProductW( szwProd, phProduct );
79 HeapFree( GetProcessHeap(), 0, szwProd );
81 return r;
84 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
86 static const WCHAR szLocalPackage[] = {
87 'L','o','c','a','l','P','a','c','k','a','g','e', 0
89 LPWSTR path = NULL;
90 UINT r;
91 HKEY hKeyProduct = NULL;
92 DWORD count, type;
94 TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
96 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
97 if( r != ERROR_SUCCESS )
99 r = ERROR_UNKNOWN_PRODUCT;
100 goto end;
103 /* find the size of the path */
104 type = count = 0;
105 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
106 NULL, &type, NULL, &count );
107 if( r != ERROR_SUCCESS )
109 r = ERROR_UNKNOWN_PRODUCT;
110 goto end;
113 /* now alloc and fetch the path of the database to open */
114 path = HeapAlloc( GetProcessHeap(), 0, count );
115 if( !path )
116 goto end;
118 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
119 NULL, &type, (LPBYTE) path, &count );
120 if( r != ERROR_SUCCESS )
122 r = ERROR_UNKNOWN_PRODUCT;
123 goto end;
126 r = MsiOpenPackageW( path, phProduct );
128 end:
129 HeapFree( GetProcessHeap(), 0, path );
130 if( hKeyProduct )
131 RegCloseKey( hKeyProduct );
133 return r;
136 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
137 LPCSTR szTransforms, LANGID lgidLanguage)
139 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
140 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
141 return ERROR_CALL_NOT_IMPLEMENTED;
144 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
145 LPCWSTR szTransforms, LANGID lgidLanguage)
147 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
148 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
149 return ERROR_CALL_NOT_IMPLEMENTED;
152 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
153 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
155 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
156 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
157 lgidLanguage, dwPlatform, dwOptions);
158 return ERROR_CALL_NOT_IMPLEMENTED;
161 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
162 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
164 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
165 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
166 lgidLanguage, dwPlatform, dwOptions);
167 return ERROR_CALL_NOT_IMPLEMENTED;
170 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
172 LPWSTR szwPath = NULL, szwCommand = NULL;
173 UINT r = ERROR_OUTOFMEMORY;
175 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
177 if( szPackagePath )
179 szwPath = strdupAtoW( szPackagePath );
180 if( !szwPath )
181 goto end;
184 if( szCommandLine )
186 szwCommand = strdupAtoW( szCommandLine );
187 if( !szwCommand )
188 goto end;
191 r = MsiInstallProductW( szwPath, szwCommand );
193 end:
194 HeapFree( GetProcessHeap(), 0, szwPath );
195 HeapFree( GetProcessHeap(), 0, szwCommand );
197 return r;
200 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
202 MSIPACKAGE *package = NULL;
203 UINT r;
204 MSIHANDLE handle;
206 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
208 r = MsiVerifyPackageW(szPackagePath);
209 if (r != ERROR_SUCCESS)
210 return r;
212 r = MSI_OpenPackageW(szPackagePath,&package);
213 if (r != ERROR_SUCCESS)
214 return r;
216 handle = alloc_msihandle( &package->hdr );
218 r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
220 MsiCloseHandle(handle);
221 msiobj_release( &package->hdr );
222 return r;
225 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
227 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
228 return ERROR_CALL_NOT_IMPLEMENTED;
231 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
233 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
234 return ERROR_CALL_NOT_IMPLEMENTED;
237 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
238 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
240 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
241 eInstallType, debugstr_a(szCommandLine));
242 return ERROR_CALL_NOT_IMPLEMENTED;
245 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
246 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
248 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
249 eInstallType, debugstr_w(szCommandLine));
250 return ERROR_CALL_NOT_IMPLEMENTED;
253 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
254 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
256 MSIHANDLE handle = -1;
257 MSIPACKAGE* package;
258 UINT rc;
259 HKEY hkey=0,hkey1=0;
260 DWORD sz;
261 static const WCHAR szSouceList[] = {
262 'S','o','u','r','c','e','L','i','s','t',0};
263 static const WCHAR szLUS[] = {
264 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
265 WCHAR sourcepath[0x200];
266 static const WCHAR szInstalled[] = {
267 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
268 LPWSTR commandline;
270 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
271 debugstr_w(szCommandLine));
273 if (eInstallState != INSTALLSTATE_LOCAL &&
274 eInstallState != INSTALLSTATE_DEFAULT)
276 FIXME("Not implemented for anything other than local installs\n");
277 return ERROR_CALL_NOT_IMPLEMENTED;
280 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
281 if (rc != ERROR_SUCCESS)
282 goto end;
284 rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
285 if (rc != ERROR_SUCCESS)
286 goto end;
288 sz = sizeof(sourcepath);
289 rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
290 if (rc != ERROR_SUCCESS)
291 goto end;
293 RegCloseKey(hkey1);
295 * ok 1, we need to find the msi file for this product.
296 * 2, find the source dir for the files
297 * 3, do the configure/install.
298 * 4, cleanupany runonce entry.
301 rc = MsiOpenProductW(szProduct,&handle);
302 if (rc != ERROR_SUCCESS)
303 goto end;
305 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
306 if (!package)
308 rc = ERROR_INVALID_HANDLE;
309 goto end;
312 sz = lstrlenW(szInstalled);
314 if (szCommandLine)
315 sz += lstrlenW(szCommandLine);
317 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
319 if (szCommandLine)
320 lstrcpyW(commandline,szCommandLine);
321 else
322 commandline[0] = 0;
324 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
325 lstrcatW(commandline,szInstalled);
327 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
329 msiobj_release( &package->hdr );
331 HeapFree(GetProcessHeap(),0,commandline);
332 end:
333 RegCloseKey(hkey);
334 if (handle != -1)
335 MsiCloseHandle(handle);
337 return rc;
340 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
341 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
343 LPWSTR szwProduct = NULL;
344 LPWSTR szwCommandLine = NULL;
345 UINT r = ERROR_OUTOFMEMORY;
347 if( szProduct )
349 szwProduct = strdupAtoW( szProduct );
350 if( !szwProduct )
351 goto end;
354 if( szCommandLine)
356 szwCommandLine = strdupAtoW( szCommandLine );
357 if( !szwCommandLine)
358 goto end;
361 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
362 szwCommandLine );
363 end:
364 HeapFree( GetProcessHeap(), 0, szwProduct );
365 HeapFree( GetProcessHeap(), 0, szwCommandLine);
367 return r;
370 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
371 INSTALLSTATE eInstallState)
373 LPWSTR szwProduct = NULL;
374 UINT r;
376 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
378 if( szProduct )
380 szwProduct = strdupAtoW( szProduct );
381 if( !szwProduct )
382 return ERROR_OUTOFMEMORY;
385 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
386 HeapFree( GetProcessHeap(), 0, szwProduct );
388 return r;
391 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
392 INSTALLSTATE eInstallState)
394 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
396 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
399 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
401 LPWSTR szwComponent = NULL;
402 UINT r;
403 WCHAR szwBuffer[GUID_SIZE];
405 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
407 if( szComponent )
409 szwComponent = strdupAtoW( szComponent );
410 if( !szwComponent )
411 return ERROR_OUTOFMEMORY;
414 r = MsiGetProductCodeW( szwComponent, szwBuffer );
416 if( ERROR_SUCCESS == r )
417 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
419 HeapFree( GetProcessHeap(), 0, szwComponent );
421 return r;
424 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
426 UINT rc;
427 HKEY hkey;
428 WCHAR szSquished[GUID_SIZE];
429 DWORD sz = GUID_SIZE;
430 static const WCHAR szPermKey[] =
431 { '0','0','0','0','0','0','0','0','0','0','0','0',
432 '0','0','0','0','0','0','0', '0','0','0','0','0',
433 '0','0','0','0','0','0','0','0',0};
435 TRACE("%s %p\n",debugstr_w(szComponent), szBuffer);
437 if (NULL == szComponent)
438 return ERROR_INVALID_PARAMETER;
440 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
441 if (rc != ERROR_SUCCESS)
442 return ERROR_UNKNOWN_COMPONENT;
444 rc = RegEnumValueW(hkey, 0, szSquished, &sz, NULL, NULL, NULL, NULL);
445 if (rc == ERROR_SUCCESS && strcmpW(szSquished,szPermKey)==0)
447 sz = GUID_SIZE;
448 rc = RegEnumValueW(hkey, 1, szSquished, &sz, NULL, NULL, NULL, NULL);
451 RegCloseKey(hkey);
453 if (rc != ERROR_SUCCESS)
454 return ERROR_INSTALL_FAILURE;
456 unsquash_guid(szSquished, szBuffer);
457 return ERROR_SUCCESS;
460 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
461 LPSTR szBuffer, DWORD *pcchValueBuf)
463 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
464 UINT r = ERROR_OUTOFMEMORY;
466 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
467 szBuffer, pcchValueBuf);
469 if( szProduct )
471 szwProduct = strdupAtoW( szProduct );
472 if( !szwProduct )
473 goto end;
476 if( szAttribute )
478 szwAttribute = strdupAtoW( szAttribute );
479 if( !szwAttribute )
480 goto end;
483 if( szBuffer )
485 szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
486 if( !szwBuffer )
487 goto end;
490 r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
492 if( ERROR_SUCCESS == r )
493 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);
495 end:
496 HeapFree( GetProcessHeap(), 0, szwProduct );
497 HeapFree( GetProcessHeap(), 0, szwAttribute );
498 HeapFree( GetProcessHeap(), 0, szwBuffer );
500 return r;
503 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
504 LPWSTR szBuffer, DWORD *pcchValueBuf)
506 MSIHANDLE hProduct;
507 UINT r;
508 static const WCHAR szPackageCode[] =
509 {'P','a','c','k','a','g','e','C','o','d','e',0};
510 static const WCHAR szVersionString[] =
511 {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
512 static const WCHAR szProductVersion[] =
513 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
514 static const WCHAR szAssignmentType[] =
515 {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
517 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
518 szBuffer, pcchValueBuf);
520 if (NULL != szBuffer && NULL == pcchValueBuf)
521 return ERROR_INVALID_PARAMETER;
522 if (NULL == szProduct || NULL == szAttribute)
523 return ERROR_INVALID_PARAMETER;
525 /* check for special properties */
526 if (strcmpW(szAttribute, szPackageCode)==0)
528 HKEY hkey;
529 WCHAR squished[GUID_SIZE];
530 WCHAR package[200];
531 DWORD sz = sizeof(squished);
533 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
534 if (r != ERROR_SUCCESS)
535 return ERROR_UNKNOWN_PRODUCT;
537 r = RegQueryValueExW(hkey, szPackageCode, NULL, NULL,
538 (LPBYTE)squished, &sz);
539 if (r != ERROR_SUCCESS)
541 RegCloseKey(hkey);
542 return ERROR_UNKNOWN_PRODUCT;
545 unsquash_guid(squished, package);
546 *pcchValueBuf = strlenW(package);
547 if (strlenW(package) > *pcchValueBuf)
549 RegCloseKey(hkey);
550 return ERROR_MORE_DATA;
552 else
553 strcpyW(szBuffer, package);
555 RegCloseKey(hkey);
556 r = ERROR_SUCCESS;
558 else if (strcmpW(szAttribute, szVersionString)==0)
560 r = MsiOpenProductW(szProduct, &hProduct);
561 if (ERROR_SUCCESS != r)
562 return r;
564 r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf);
565 MsiCloseHandle(hProduct);
567 else if (strcmpW(szAttribute, szAssignmentType)==0)
569 FIXME("0 (zero) if advertised, 1(one) if per machine.\n");
570 if (szBuffer)
571 szBuffer[0] = 1;
572 r = ERROR_SUCCESS;
574 else
576 r = MsiOpenProductW(szProduct, &hProduct);
577 if (ERROR_SUCCESS != r)
578 return r;
580 r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
581 MsiCloseHandle(hProduct);
584 return r;
587 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
589 LPWSTR szwLogFile = NULL;
590 UINT r;
592 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
594 if( szLogFile )
596 szwLogFile = strdupAtoW( szLogFile );
597 if( !szwLogFile )
598 return ERROR_OUTOFMEMORY;
600 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
601 HeapFree( GetProcessHeap(), 0, szwLogFile );
602 return r;
605 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
607 HANDLE file = INVALID_HANDLE_VALUE;
609 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
611 lstrcpyW(gszLogFile,szLogFile);
612 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
613 DeleteFileW(szLogFile);
614 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
615 FILE_ATTRIBUTE_NORMAL, NULL);
616 if (file != INVALID_HANDLE_VALUE)
617 CloseHandle(file);
618 else
619 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
621 return ERROR_SUCCESS;
624 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
626 LPWSTR szwProduct = NULL;
627 INSTALLSTATE r;
629 if( szProduct )
631 szwProduct = strdupAtoW( szProduct );
632 if( !szwProduct )
633 return ERROR_OUTOFMEMORY;
635 r = MsiQueryProductStateW( szwProduct );
636 HeapFree( GetProcessHeap(), 0, szwProduct );
637 return r;
640 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
642 UINT rc;
643 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
644 HKEY hkey = 0;
645 static const WCHAR szWindowsInstaller[] = {
646 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
647 DWORD sz;
649 TRACE("%s\n", debugstr_w(szProduct));
651 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
652 if (rc != ERROR_SUCCESS)
653 goto end;
655 RegCloseKey(hkey);
657 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
658 if (rc != ERROR_SUCCESS)
659 goto end;
661 sz = sizeof(rrc);
662 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
663 if (rc != ERROR_SUCCESS)
664 goto end;
666 switch (rrc)
668 case 1:
669 /* default */
670 rrc = INSTALLSTATE_DEFAULT;
671 break;
672 default:
673 FIXME("Unknown install state read from registry (%i)\n",rrc);
674 rrc = INSTALLSTATE_UNKNOWN;
675 break;
677 end:
678 RegCloseKey(hkey);
679 return rrc;
682 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
684 INSTALLUILEVEL old = gUILevel;
685 HWND oldwnd = gUIhwnd;
687 TRACE("%08x %p\n", dwUILevel, phWnd);
689 gUILevel = dwUILevel;
690 if (phWnd)
692 gUIhwnd = *phWnd;
693 *phWnd = oldwnd;
695 return old;
698 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
699 DWORD dwMessageFilter, LPVOID pvContext)
701 INSTALLUI_HANDLERA prev = gUIHandlerA;
703 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
704 gUIHandlerA = puiHandler;
705 gUIFilter = dwMessageFilter;
706 gUIContext = pvContext;
708 return prev;
711 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
712 DWORD dwMessageFilter, LPVOID pvContext)
714 INSTALLUI_HANDLERW prev = gUIHandlerW;
716 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
717 gUIHandlerW = puiHandler;
718 gUIFilter = dwMessageFilter;
719 gUIContext = pvContext;
721 return prev;
724 /******************************************************************
725 * MsiLoadStringW [MSI.@]
727 * Loads a string from MSI's string resources.
729 * PARAMS
731 * handle [I] only -1 is handled currently
732 * id [I] id of the string to be loaded
733 * lpBuffer [O] buffer for the string to be written to
734 * nBufferMax [I] maximum size of the buffer in characters
735 * lang [I] the preferred language for the string
737 * RETURNS
739 * If successful, this function returns the language id of the string loaded
740 * If the function fails, the function returns zero.
742 * NOTES
744 * The type of the first parameter is unknown. LoadString's prototype
745 * suggests that it might be a module handle. I have made it an MSI handle
746 * for starters, as -1 is an invalid MSI handle, but not an invalid module
747 * handle. Maybe strings can be stored in an MSI database somehow.
749 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
750 int nBufferMax, LANGID lang )
752 HRSRC hres;
753 HGLOBAL hResData;
754 LPWSTR p;
755 DWORD i, len;
757 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
759 if( handle != -1 )
760 FIXME("don't know how to deal with handle = %08lx\n", handle);
762 if( !lang )
763 lang = GetUserDefaultLangID();
765 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
766 (LPWSTR)1, lang );
767 if( !hres )
768 return 0;
769 hResData = LoadResource( msi_hInstance, hres );
770 if( !hResData )
771 return 0;
772 p = LockResource( hResData );
773 if( !p )
774 return 0;
776 for (i = 0; i < (id&0xf); i++)
777 p += *p + 1;
778 len = *p;
780 if( nBufferMax <= len )
781 return 0;
783 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
784 lpBuffer[ len ] = 0;
786 TRACE("found -> %s\n", debugstr_w(lpBuffer));
788 return lang;
791 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
792 int nBufferMax, LANGID lang )
794 LPWSTR bufW;
795 LANGID r;
796 DWORD len;
798 bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
799 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
800 if( r )
802 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
803 if( len <= nBufferMax )
804 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
805 lpBuffer, nBufferMax, NULL, NULL );
806 else
807 r = 0;
809 HeapFree(GetProcessHeap(), 0, bufW);
810 return r;
813 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
814 DWORD *pcchBuf)
816 FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
817 return INSTALLSTATE_UNKNOWN;
820 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPWSTR lpPathBuf,
821 DWORD *pcchBuf)
823 FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
824 return INSTALLSTATE_UNKNOWN;
827 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
828 WORD wLanguageId, DWORD f)
830 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
831 uType,wLanguageId,f);
832 return ERROR_CALL_NOT_IMPLEMENTED;
835 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
836 WORD wLanguageId, DWORD f)
838 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
839 uType,wLanguageId,f);
840 return ERROR_CALL_NOT_IMPLEMENTED;
843 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
844 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
845 DWORD* pcchPathBuf )
847 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
848 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
849 pcchPathBuf);
850 return ERROR_CALL_NOT_IMPLEMENTED;
853 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
854 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
855 DWORD* pcchPathBuf )
857 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
858 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
859 pcchPathBuf);
860 return ERROR_CALL_NOT_IMPLEMENTED;
863 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
864 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
866 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
867 return ERROR_CALL_NOT_IMPLEMENTED;
870 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
871 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
873 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
874 return ERROR_CALL_NOT_IMPLEMENTED;
877 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
878 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
879 DWORD* pcbHashData)
881 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
882 ppcCertContext, pbHashData, pcbHashData);
883 return ERROR_CALL_NOT_IMPLEMENTED;
886 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
887 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
888 DWORD* pcbHashData)
890 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
891 ppcCertContext, pbHashData, pcbHashData);
892 return ERROR_CALL_NOT_IMPLEMENTED;
895 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
896 LPSTR szValue, DWORD *pccbValue )
898 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
899 return ERROR_CALL_NOT_IMPLEMENTED;
902 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
903 LPWSTR szValue, DWORD *pccbValue )
905 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
906 return ERROR_CALL_NOT_IMPLEMENTED;
909 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
911 UINT r;
912 LPWSTR szPack = NULL;
914 TRACE("%s\n", debugstr_a(szPackage) );
916 if( szPackage )
918 szPack = strdupAtoW( szPackage );
919 if( !szPack )
920 return ERROR_OUTOFMEMORY;
923 r = MsiVerifyPackageW( szPack );
925 HeapFree( GetProcessHeap(), 0, szPack );
927 return r;
930 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
932 MSIHANDLE handle;
933 UINT r;
935 TRACE("%s\n", debugstr_w(szPackage) );
937 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
938 MsiCloseHandle( handle );
940 return r;
943 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
944 LPSTR lpPathBuf, DWORD* pcchBuf)
946 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
947 INSTALLSTATE rc;
948 UINT incoming_len;
950 if( szProduct )
952 szwProduct = strdupAtoW( szProduct );
953 if( !szwProduct)
954 return ERROR_OUTOFMEMORY;
957 if( szComponent )
959 szwComponent = strdupAtoW( szComponent );
960 if( !szwComponent )
962 HeapFree( GetProcessHeap(), 0, szwProduct);
963 return ERROR_OUTOFMEMORY;
967 if( pcchBuf && *pcchBuf > 0 )
968 lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
969 else
970 lpwPathBuf = NULL;
972 incoming_len = *pcchBuf;
973 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
975 HeapFree( GetProcessHeap(), 0, szwProduct);
976 HeapFree( GetProcessHeap(), 0, szwComponent);
977 if (lpwPathBuf)
979 if (rc != INSTALLSTATE_UNKNOWN)
980 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
981 lpPathBuf, incoming_len, NULL, NULL);
982 HeapFree( GetProcessHeap(), 0, lpwPathBuf);
985 return rc;
988 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
989 LPWSTR lpPathBuf, DWORD* pcchBuf)
991 WCHAR squished_pc[GUID_SIZE];
992 UINT rc;
993 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
994 HKEY hkey = 0;
995 LPWSTR path = NULL;
996 DWORD sz, type;
998 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
999 debugstr_w(szComponent), lpPathBuf, pcchBuf);
1001 if( lpPathBuf && !pcchBuf )
1002 return INSTALLSTATE_INVALIDARG;
1004 squash_guid(szProduct,squished_pc);
1006 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
1007 if( rc != ERROR_SUCCESS )
1008 goto end;
1010 RegCloseKey(hkey);
1012 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
1013 if( rc != ERROR_SUCCESS )
1014 goto end;
1016 sz = 0;
1017 type = 0;
1018 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
1019 if( rc != ERROR_SUCCESS )
1020 goto end;
1021 if( type != REG_SZ )
1022 goto end;
1024 sz += sizeof(WCHAR);
1025 path = HeapAlloc( GetProcessHeap(), 0, sz );
1026 if( !path )
1027 goto end;
1029 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
1030 if( rc != ERROR_SUCCESS )
1031 goto end;
1033 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1034 debugstr_w(szProduct), debugstr_w(path));
1036 if (path[0]=='0')
1038 FIXME("Registry entry.. check entry\n");
1039 rrc = INSTALLSTATE_LOCAL;
1041 else
1043 /* PROBABLY a file */
1044 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
1045 rrc = INSTALLSTATE_LOCAL;
1046 else
1047 rrc = INSTALLSTATE_ABSENT;
1050 if( pcchBuf )
1052 sz = sz / sizeof(WCHAR);
1053 if( *pcchBuf >= sz )
1054 lstrcpyW( lpPathBuf, path );
1055 *pcchBuf = sz;
1058 end:
1059 HeapFree(GetProcessHeap(), 0, path );
1060 RegCloseKey(hkey);
1061 return rrc;
1064 /******************************************************************
1065 * MsiQueryFeatureStateA [MSI.@]
1067 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1069 INSTALLSTATE rc;
1070 LPWSTR szwProduct= NULL;
1071 LPWSTR szwFeature= NULL;
1073 if( szProduct )
1075 szwProduct = strdupAtoW( szProduct );
1076 if( !szwProduct)
1077 return ERROR_OUTOFMEMORY;
1080 if( szFeature )
1082 szwFeature = strdupAtoW( szFeature );
1083 if( !szwFeature)
1085 HeapFree( GetProcessHeap(), 0, szwProduct);
1086 return ERROR_OUTOFMEMORY;
1090 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1092 HeapFree( GetProcessHeap(), 0, szwProduct);
1093 HeapFree( GetProcessHeap(), 0, szwFeature);
1095 return rc;
1098 /******************************************************************
1099 * MsiQueryFeatureStateW [MSI.@]
1101 * This does not verify that the Feature is functional. So i am only going to
1102 * check the existence of the key in the registry. This should tell me if it is
1103 * installed.
1105 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1107 UINT rc;
1108 DWORD sz = 0;
1109 HKEY hkey;
1111 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1113 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1114 if (rc != ERROR_SUCCESS)
1115 return INSTALLSTATE_UNKNOWN;
1117 rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz);
1118 RegCloseKey(hkey);
1120 if (rc == ERROR_SUCCESS)
1121 return INSTALLSTATE_LOCAL;
1122 else
1123 return INSTALLSTATE_ABSENT;
1126 /******************************************************************
1127 * MsiGetFileVersionA [MSI.@]
1129 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1130 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1132 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1133 UINT ret = ERROR_OUTOFMEMORY;
1135 if( szFilePath )
1137 szwFilePath = strdupAtoW( szFilePath );
1138 if( !szwFilePath )
1139 goto end;
1142 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1144 lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1145 if( !lpwVersionBuff )
1146 goto end;
1149 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1151 lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1152 if( !lpwLangBuff )
1153 goto end;
1156 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1157 lpwLangBuff, pcchLangBuf);
1159 if( lpwVersionBuff )
1160 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1161 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1162 if( lpwLangBuff )
1163 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1164 lpLangBuf, *pcchLangBuf, NULL, NULL);
1166 end:
1167 HeapFree(GetProcessHeap(), 0, szwFilePath);
1168 HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
1169 HeapFree(GetProcessHeap(), 0, lpwLangBuff);
1171 return ret;
1174 /******************************************************************
1175 * MsiGetFileVersionW [MSI.@]
1177 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1178 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1180 static const WCHAR szVersionResource[] = {'\\',0};
1181 static const WCHAR szVersionFormat[] = {
1182 '%','d','.','%','d','.','%','d','.','%','d',0};
1183 static const WCHAR szLangFormat[] = {'%','d',0};
1184 UINT ret = 0;
1185 DWORD dwVerLen;
1186 LPVOID lpVer = NULL;
1187 VS_FIXEDFILEINFO *ffi;
1188 UINT puLen;
1189 WCHAR tmp[32];
1191 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1192 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1193 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1195 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1196 if( !dwVerLen )
1197 return GetLastError();
1199 lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
1200 if( !lpVer )
1202 ret = ERROR_OUTOFMEMORY;
1203 goto end;
1206 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1208 ret = GetLastError();
1209 goto end;
1211 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1213 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1214 (puLen > 0) )
1216 wsprintfW(tmp, szVersionFormat,
1217 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1218 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1219 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1220 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1222 else
1224 *lpVersionBuf = 0;
1225 *pcchVersionBuf = 0;
1229 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1231 DWORD lang = GetUserDefaultLangID();
1233 FIXME("Retrieve language from file\n");
1234 wsprintfW(tmp, szLangFormat, lang);
1235 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1236 *pcchLangBuf = lstrlenW(lpLangBuf);
1239 end:
1240 HeapFree(GetProcessHeap(), 0, lpVer);
1241 return ret;
1245 /******************************************************************
1246 * DllMain
1248 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1250 switch(fdwReason)
1252 case DLL_PROCESS_ATTACH:
1253 msi_hInstance = hinstDLL;
1254 DisableThreadLibraryCalls(hinstDLL);
1255 msi_dialog_register_class();
1256 break;
1257 case DLL_PROCESS_DETACH:
1258 msi_dialog_unregister_class();
1259 /* FIXME: Cleanup */
1260 break;
1262 return TRUE;
1265 typedef struct tagIClassFactoryImpl
1267 IClassFactoryVtbl *lpVtbl;
1268 } IClassFactoryImpl;
1270 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1271 REFIID riid,LPVOID *ppobj)
1273 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1274 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1275 return E_NOINTERFACE;
1278 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1280 return 2;
1283 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1285 return 1;
1288 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1289 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1291 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1293 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1294 return E_FAIL;
1297 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1299 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1301 FIXME("%p %d\n", This, dolock);
1302 return S_OK;
1305 static IClassFactoryVtbl MsiCF_Vtbl =
1307 MsiCF_QueryInterface,
1308 MsiCF_AddRef,
1309 MsiCF_Release,
1310 MsiCF_CreateInstance,
1311 MsiCF_LockServer
1314 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1316 /******************************************************************
1317 * DllGetClassObject [MSI.@]
1319 HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1321 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1323 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1324 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1325 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1326 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1327 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1329 *ppv = (LPVOID) &Msi_CF;
1330 return S_OK;
1332 return CLASS_E_CLASSNOTAVAILABLE;
1335 /******************************************************************
1336 * DllGetVersion [MSI.@]
1338 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
1340 TRACE("%p\n",pdvi);
1342 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1343 return E_INVALIDARG;
1345 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1346 pdvi->dwMinorVersion = MSI_MINORVERSION;
1347 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1348 pdvi->dwPlatformID = 1;
1350 return S_OK;
1353 /******************************************************************
1354 * DllCanUnloadNow [MSI.@]
1356 BOOL WINAPI MSI_DllCanUnloadNow(void)
1358 return S_FALSE;
1361 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1362 DWORD* pdwUseCount, WORD* pwDateUsed)
1364 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1365 pdwUseCount, pwDateUsed);
1366 return ERROR_CALL_NOT_IMPLEMENTED;
1369 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1370 DWORD* pdwUseCount, WORD* pwDateUsed)
1372 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1373 pdwUseCount, pwDateUsed);
1374 return ERROR_CALL_NOT_IMPLEMENTED;
1377 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1378 DWORD dwInstallMode, DWORD dwReserved)
1380 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1381 dwInstallMode, dwReserved);
1384 * Polls all the components of the feature to find install state and then
1385 * writes:
1386 * Software\\Microsoft\\Windows\\CurrentVersion\\
1387 * Installer\\Products\\<squishguid>\\<feature>
1388 * "Usage"=dword:........
1391 return INSTALLSTATE_LOCAL;
1394 /***********************************************************************
1395 * MsiUseFeatureExA [MSI.@]
1397 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1398 DWORD dwInstallMode, DWORD dwReserved)
1400 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1401 dwInstallMode, dwReserved);
1403 return INSTALLSTATE_LOCAL;
1406 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1408 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1410 return INSTALLSTATE_LOCAL;
1413 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1415 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1417 return INSTALLSTATE_LOCAL;
1420 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1421 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1422 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1423 DWORD* pcchPathBuf)
1425 HKEY hkey;
1426 UINT rc;
1427 LPWSTR info;
1428 DWORD sz;
1429 LPWSTR product = NULL;
1430 LPWSTR component = NULL;
1431 LPWSTR ptr;
1432 GUID clsid;
1434 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1435 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1436 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1438 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1439 if (rc != ERROR_SUCCESS)
1440 return ERROR_INDEX_ABSENT;
1442 sz = 0;
1443 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
1444 if (sz <= 0)
1446 RegCloseKey(hkey);
1447 return ERROR_INDEX_ABSENT;
1450 info = HeapAlloc(GetProcessHeap(),0,sz);
1451 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
1452 if (rc != ERROR_SUCCESS)
1454 RegCloseKey(hkey);
1455 HeapFree(GetProcessHeap(),0,info);
1456 return ERROR_INDEX_ABSENT;
1459 /* find the component */
1460 ptr = strchrW(&info[20],'>');
1461 if (ptr)
1462 ptr++;
1463 else
1465 RegCloseKey(hkey);
1466 HeapFree(GetProcessHeap(),0,info);
1467 return ERROR_INDEX_ABSENT;
1470 if (!szProduct)
1472 decode_base85_guid(info,&clsid);
1473 StringFromCLSID(&clsid, &product);
1475 decode_base85_guid(ptr,&clsid);
1476 StringFromCLSID(&clsid, &component);
1478 if (!szProduct)
1479 rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
1480 else
1481 rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
1483 RegCloseKey(hkey);
1484 HeapFree(GetProcessHeap(),0,info);
1485 HeapFree(GetProcessHeap(),0,product);
1486 HeapFree(GetProcessHeap(),0,component);
1488 if (rc == INSTALLSTATE_LOCAL)
1489 return ERROR_SUCCESS;
1490 else
1491 return ERROR_FILE_NOT_FOUND;
1494 /***********************************************************************
1495 * MsiProvideQualifiedComponentW [MSI.@]
1497 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1498 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1499 DWORD* pcchPathBuf)
1501 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1502 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1505 /***********************************************************************
1506 * MsiProvideQualifiedComponentA [MSI.@]
1508 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1509 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1510 DWORD* pcchPathBuf)
1512 LPWSTR szwComponent, szwQualifier, lpwPathBuf;
1513 DWORD pcchwPathBuf;
1514 UINT rc;
1516 TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
1517 dwInstallMode, lpPathBuf, pcchPathBuf);
1519 szwComponent= strdupAtoW( szComponent);
1520 szwQualifier= strdupAtoW( szQualifier);
1522 lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR));
1524 pcchwPathBuf = *pcchPathBuf;
1526 rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
1527 dwInstallMode, lpwPathBuf, &pcchwPathBuf);
1529 HeapFree(GetProcessHeap(),0,szwComponent);
1530 HeapFree(GetProcessHeap(),0,szwQualifier);
1531 *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
1532 lpPathBuf, *pcchPathBuf, NULL, NULL);
1534 HeapFree(GetProcessHeap(),0,lpwPathBuf);
1535 return rc;
1538 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1539 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1540 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1542 HKEY hkey;
1543 DWORD sz;
1544 UINT rc = ERROR_SUCCESS,rc2 = ERROR_SUCCESS;
1545 static const WCHAR szOwner[] = {'R','e','g','O','w','n','e','r',0};
1546 static const WCHAR szCompany[] = {'R','e','g','C','o','m','p','a','n','y',0};
1547 static const WCHAR szSerial[] = {'P','r','o','d','u','c','t','I','D',0};
1549 TRACE("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1550 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1551 pcchSerialBuf);
1553 rc = MSIREG_OpenUninstallKey(szProduct, &hkey, FALSE);
1554 if (rc != ERROR_SUCCESS)
1555 return USERINFOSTATE_UNKNOWN;
1557 if (lpUserNameBuf)
1559 sz = *lpUserNameBuf * sizeof(WCHAR);
1560 rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, (LPBYTE)lpUserNameBuf,
1561 &sz);
1563 if (!lpUserNameBuf && pcchUserNameBuf)
1565 sz = 0;
1566 rc = RegQueryValueExW( hkey, szOwner, NULL, NULL, NULL, &sz);
1569 if (pcchUserNameBuf)
1570 *pcchUserNameBuf = sz / sizeof(WCHAR);
1572 if (lpOrgNameBuf)
1574 sz = *pcchOrgNameBuf * sizeof(WCHAR);
1575 rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL,
1576 (LPBYTE)lpOrgNameBuf, &sz);
1578 if (!lpOrgNameBuf && pcchOrgNameBuf)
1580 sz = 0;
1581 rc2 = RegQueryValueExW( hkey, szCompany, NULL, NULL, NULL, &sz);
1584 if (pcchOrgNameBuf)
1585 *pcchOrgNameBuf = sz / sizeof(WCHAR);
1587 if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA &&
1588 rc2 != ERROR_SUCCESS && rc2 != ERROR_MORE_DATA)
1590 RegCloseKey(hkey);
1591 return USERINFOSTATE_ABSENT;
1594 if (lpSerialBuf)
1596 sz = *pcchSerialBuf * sizeof(WCHAR);
1597 RegQueryValueExW( hkey, szSerial, NULL, NULL, (LPBYTE)lpSerialBuf,
1598 &sz);
1600 if (!lpSerialBuf && pcchSerialBuf)
1602 sz = 0;
1603 rc = RegQueryValueExW( hkey, szSerial, NULL, NULL, NULL, &sz);
1605 if (pcchSerialBuf)
1606 *pcchSerialBuf = sz / sizeof(WCHAR);
1608 RegCloseKey(hkey);
1609 return USERINFOSTATE_PRESENT;
1612 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1613 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1614 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1616 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1617 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1618 pcchSerialBuf);
1620 return USERINFOSTATE_UNKNOWN;
1623 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1625 MSIHANDLE handle;
1626 UINT rc;
1627 MSIPACKAGE *package;
1628 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1630 TRACE("(%s)\n",debugstr_w(szProduct));
1632 rc = MsiOpenProductW(szProduct,&handle);
1633 if (rc != ERROR_SUCCESS)
1634 return ERROR_INVALID_PARAMETER;
1636 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1637 rc = ACTION_PerformUIAction(package, szFirstRun);
1638 msiobj_release( &package->hdr );
1640 MsiCloseHandle(handle);
1642 return rc;
1645 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1647 MSIHANDLE handle;
1648 UINT rc;
1649 MSIPACKAGE *package;
1650 static const WCHAR szFirstRun[] = {'F','i','r','s','t','R','u','n',0};
1652 TRACE("(%s)\n",debugstr_a(szProduct));
1654 rc = MsiOpenProductA(szProduct,&handle);
1655 if (rc != ERROR_SUCCESS)
1656 return ERROR_INVALID_PARAMETER;
1658 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
1659 rc = ACTION_PerformUIAction(package, szFirstRun);
1660 msiobj_release( &package->hdr );
1662 MsiCloseHandle(handle);
1664 return rc;
1667 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1669 WCHAR path[MAX_PATH];
1671 if(dwReserved) {
1672 FIXME("Don't know how to handle argument %ld\n", dwReserved);
1673 return ERROR_CALL_NOT_IMPLEMENTED;
1676 if(!GetWindowsDirectoryW(path, MAX_PATH)) {
1677 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1678 GetLastError());
1679 return ERROR_CALL_NOT_IMPLEMENTED;
1682 strcatW(path, installerW);
1684 CreateDirectoryW(path, NULL);
1686 return 0;
1689 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1690 LPSTR szProductCode, LPSTR szFeatureId,
1691 LPSTR szComponentCode )
1693 FIXME("\n");
1694 return ERROR_CALL_NOT_IMPLEMENTED;
1697 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1698 LPWSTR szProductCode, LPWSTR szFeatureId,
1699 LPWSTR szComponentCode )
1701 FIXME("\n");
1702 return ERROR_CALL_NOT_IMPLEMENTED;
1705 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1706 DWORD dwReinstallMode )
1708 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1709 dwReinstallMode);
1710 return ERROR_SUCCESS;
1713 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1714 DWORD dwReinstallMode )
1716 FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1717 dwReinstallMode);
1718 return ERROR_SUCCESS;