Added minimal implementation of MsiCreateAndVerifyInstallerDirectory.
[wine/multimedia.git] / dlls / msi / msi.c
blob8f0fc80502ddd6d7c960a69949ae884ec2d1704d
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"
40 WINE_DEFAULT_DEBUG_CHANNEL(msi);
43 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
44 * which is a problem because LPCTSTR isn't defined when compiling wine.
45 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
46 * and make sure to only use it in W functions.
48 #define LPCTSTR LPCWSTR
50 /* the UI level */
51 INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
52 HWND gUIhwnd = 0;
53 INSTALLUI_HANDLERA gUIHandlerA = NULL;
54 INSTALLUI_HANDLERW gUIHandlerW = NULL;
55 DWORD gUIFilter = 0;
56 LPVOID gUIContext = NULL;
57 WCHAR gszLogFile[MAX_PATH];
58 HINSTANCE msi_hInstance;
60 static const WCHAR installerW[] = {'\\','I','n','s','t','a','l','l','e','r',0};
62 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
64 UINT r;
65 LPWSTR szwProd = NULL;
67 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
69 if( szProduct )
71 szwProd = strdupAtoW( szProduct );
72 if( !szwProd )
73 return ERROR_OUTOFMEMORY;
76 r = MsiOpenProductW( szwProd, phProduct );
78 HeapFree( GetProcessHeap(), 0, szwProd );
80 return r;
83 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
85 static const WCHAR szLocalPackage[] = {
86 'L','o','c','a','l','P','a','c','k','a','g','e', 0
88 LPWSTR path = NULL;
89 UINT r;
90 HKEY hKeyProduct = NULL;
91 DWORD count, type;
93 TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
95 r = MSIREG_OpenUninstallKey(szProduct,&hKeyProduct,FALSE);
96 if( r != ERROR_SUCCESS )
98 r = ERROR_UNKNOWN_PRODUCT;
99 goto end;
102 /* find the size of the path */
103 type = count = 0;
104 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
105 NULL, &type, NULL, &count );
106 if( r != ERROR_SUCCESS )
108 r = ERROR_UNKNOWN_PRODUCT;
109 goto end;
112 /* now alloc and fetch the path of the database to open */
113 path = HeapAlloc( GetProcessHeap(), 0, count );
114 if( !path )
115 goto end;
117 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
118 NULL, &type, (LPBYTE) path, &count );
119 if( r != ERROR_SUCCESS )
121 r = ERROR_UNKNOWN_PRODUCT;
122 goto end;
125 r = MsiOpenPackageW( path, phProduct );
127 end:
128 HeapFree( GetProcessHeap(), 0, path );
129 if( hKeyProduct )
130 RegCloseKey( hKeyProduct );
132 return r;
135 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
136 LPCSTR szTransforms, LANGID lgidLanguage)
138 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath),
139 debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
140 return ERROR_CALL_NOT_IMPLEMENTED;
143 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
144 LPCWSTR szTransforms, LANGID lgidLanguage)
146 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath),
147 debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
148 return ERROR_CALL_NOT_IMPLEMENTED;
151 UINT WINAPI MsiAdvertiseProductExA(LPCSTR szPackagePath, LPCSTR szScriptfilePath,
152 LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
154 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath),
155 debugstr_a(szScriptfilePath), debugstr_a(szTransforms),
156 lgidLanguage, dwPlatform, dwOptions);
157 return ERROR_CALL_NOT_IMPLEMENTED;
160 UINT WINAPI MsiAdvertiseProductExW( LPCWSTR szPackagePath, LPCWSTR szScriptfilePath,
161 LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
163 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath),
164 debugstr_w(szScriptfilePath), debugstr_w(szTransforms),
165 lgidLanguage, dwPlatform, dwOptions);
166 return ERROR_CALL_NOT_IMPLEMENTED;
169 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
171 LPWSTR szwPath = NULL, szwCommand = NULL;
172 UINT r = ERROR_OUTOFMEMORY;
174 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
176 if( szPackagePath )
178 szwPath = strdupAtoW( szPackagePath );
179 if( !szwPath )
180 goto end;
183 if( szCommandLine )
185 szwCommand = strdupAtoW( szCommandLine );
186 if( !szwCommand )
187 goto end;
190 r = MsiInstallProductW( szwPath, szwCommand );
192 end:
193 HeapFree( GetProcessHeap(), 0, szwPath );
194 HeapFree( GetProcessHeap(), 0, szwCommand );
196 return r;
199 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
201 MSIPACKAGE *package = NULL;
202 UINT r;
203 MSIHANDLE handle;
205 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
207 r = MsiVerifyPackageW(szPackagePath);
208 if (r != ERROR_SUCCESS)
209 return r;
211 r = MSI_OpenPackageW(szPackagePath,&package);
212 if (r != ERROR_SUCCESS)
213 return r;
215 handle = alloc_msihandle( &package->hdr );
217 r = ACTION_DoTopLevelINSTALL(package, szPackagePath, szCommandLine);
219 MsiCloseHandle(handle);
220 msiobj_release( &package->hdr );
221 return r;
224 UINT WINAPI MsiReinstallProductA(LPCSTR szProduct, DWORD dwReinstallMode)
226 FIXME("%s %08lx\n", debugstr_a(szProduct), dwReinstallMode);
227 return ERROR_CALL_NOT_IMPLEMENTED;
230 UINT WINAPI MsiReinstallProductW(LPCWSTR szProduct, DWORD dwReinstallMode)
232 FIXME("%s %08lx\n", debugstr_w(szProduct), dwReinstallMode);
233 return ERROR_CALL_NOT_IMPLEMENTED;
236 UINT WINAPI MsiApplyPatchA(LPCSTR szPatchPackage, LPCSTR szInstallPackage,
237 INSTALLTYPE eInstallType, LPCSTR szCommandLine)
239 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage), debugstr_a(szInstallPackage),
240 eInstallType, debugstr_a(szCommandLine));
241 return ERROR_CALL_NOT_IMPLEMENTED;
244 UINT WINAPI MsiApplyPatchW(LPCWSTR szPatchPackage, LPCWSTR szInstallPackage,
245 INSTALLTYPE eInstallType, LPCWSTR szCommandLine)
247 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage), debugstr_w(szInstallPackage),
248 eInstallType, debugstr_w(szCommandLine));
249 return ERROR_CALL_NOT_IMPLEMENTED;
252 UINT WINAPI MsiConfigureProductExW(LPCWSTR szProduct, int iInstallLevel,
253 INSTALLSTATE eInstallState, LPCWSTR szCommandLine)
255 MSIHANDLE handle;
256 MSIPACKAGE* package;
257 UINT rc;
258 HKEY hkey=0,hkey1=0;
259 DWORD sz;
260 static const WCHAR szSouceList[] = {
261 'S','o','u','r','c','e','L','i','s','t',0};
262 static const WCHAR szLUS[] = {
263 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
264 WCHAR sourcepath[0x200];
265 static const WCHAR szInstalled[] = {
266 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
267 LPWSTR commandline;
269 FIXME("%s %d %d %s\n",debugstr_w(szProduct), iInstallLevel, eInstallState,
270 debugstr_w(szCommandLine));
272 if (eInstallState != INSTALLSTATE_LOCAL &&
273 eInstallState != INSTALLSTATE_DEFAULT)
275 FIXME("Not implemented for anything other than local installs\n");
276 return ERROR_CALL_NOT_IMPLEMENTED;
279 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
280 if (rc != ERROR_SUCCESS)
281 goto end;
283 rc = RegOpenKeyW(hkey,szSouceList,&hkey1);
284 if (rc != ERROR_SUCCESS)
285 goto end;
287 sz = sizeof(sourcepath);
288 rc = RegQueryValueExW(hkey1, szLUS, NULL, NULL,(LPBYTE)sourcepath, &sz);
289 if (rc != ERROR_SUCCESS)
290 goto end;
292 RegCloseKey(hkey1);
294 * ok 1, we need to find the msi file for this product.
295 * 2, find the source dir for the files
296 * 3, do the configure/install.
297 * 4, cleanupany runonce entry.
300 rc = MsiOpenProductW(szProduct,&handle);
301 if (rc != ERROR_SUCCESS)
302 goto end;
304 package = msihandle2msiinfo(handle, MSIHANDLETYPE_PACKAGE);
305 if (!package)
307 rc = ERROR_INVALID_HANDLE;
308 goto end;
311 sz = lstrlenW(szInstalled);
313 if (szCommandLine)
314 sz += lstrlenW(szCommandLine);
316 commandline = HeapAlloc(GetProcessHeap(),0,sz * sizeof(WCHAR));
318 if (szCommandLine)
319 lstrcpyW(commandline,szCommandLine);
320 else
321 commandline[0] = 0;
323 if (MsiQueryProductStateW(szProduct) != INSTALLSTATE_UNKNOWN)
324 lstrcatW(commandline,szInstalled);
326 rc = ACTION_DoTopLevelINSTALL(package, sourcepath, commandline);
328 msiobj_release( &package->hdr );
330 HeapFree(GetProcessHeap(),0,commandline);
331 end:
332 RegCloseKey(hkey);
334 return rc;
337 UINT WINAPI MsiConfigureProductExA(LPCSTR szProduct, int iInstallLevel,
338 INSTALLSTATE eInstallState, LPCSTR szCommandLine)
340 LPWSTR szwProduct = NULL;
341 LPWSTR szwCommandLine = NULL;
342 UINT r = ERROR_OUTOFMEMORY;
344 if( szProduct )
346 szwProduct = strdupAtoW( szProduct );
347 if( !szwProduct )
348 goto end;
351 if( szCommandLine)
353 szwCommandLine = strdupAtoW( szCommandLine );
354 if( !szwCommandLine)
355 goto end;
358 r = MsiConfigureProductExW( szwProduct, iInstallLevel, eInstallState,
359 szwCommandLine );
360 end:
361 HeapFree( GetProcessHeap(), 0, szwProduct );
362 HeapFree( GetProcessHeap(), 0, szwCommandLine);
364 return r;
367 UINT WINAPI MsiConfigureProductA(LPCSTR szProduct, int iInstallLevel,
368 INSTALLSTATE eInstallState)
370 LPWSTR szwProduct = NULL;
371 UINT r;
373 TRACE("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
375 if( szProduct )
377 szwProduct = strdupAtoW( szProduct );
378 if( !szwProduct )
379 return ERROR_OUTOFMEMORY;
382 r = MsiConfigureProductW( szwProduct, iInstallLevel, eInstallState );
383 HeapFree( GetProcessHeap(), 0, szwProduct );
385 return r;
388 UINT WINAPI MsiConfigureProductW(LPCWSTR szProduct, int iInstallLevel,
389 INSTALLSTATE eInstallState)
391 FIXME("%s %d %d\n", debugstr_w(szProduct), iInstallLevel, eInstallState);
393 return MsiConfigureProductExW(szProduct, iInstallLevel, eInstallState, NULL);
396 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
398 LPWSTR szwComponent = NULL;
399 UINT r;
400 WCHAR szwBuffer[GUID_SIZE];
402 TRACE("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
404 if( szComponent )
406 szwComponent = strdupAtoW( szComponent );
407 if( !szwComponent )
408 return ERROR_OUTOFMEMORY;
411 r = MsiGetProductCodeW( szwComponent, szwBuffer );
413 if( ERROR_SUCCESS == r )
414 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, GUID_SIZE, NULL, NULL);
416 HeapFree( GetProcessHeap(), 0, szwComponent );
418 return r;
421 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
423 FIXME("%s %p\n",debugstr_w(szComponent), szBuffer);
425 if (NULL == szComponent)
426 return ERROR_INVALID_PARAMETER;
427 return ERROR_CALL_NOT_IMPLEMENTED;
430 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute,
431 LPSTR szBuffer, DWORD *pcchValueBuf)
433 LPWSTR szwProduct = NULL, szwAttribute = NULL, szwBuffer = NULL;
434 UINT r = ERROR_OUTOFMEMORY;
436 TRACE("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szAttribute),
437 szBuffer, pcchValueBuf);
439 if( szProduct )
441 szwProduct = strdupAtoW( szProduct );
442 if( !szwProduct )
443 goto end;
446 if( szAttribute )
448 szwAttribute = strdupAtoW( szAttribute );
449 if( !szwAttribute )
450 goto end;
453 if( szBuffer )
455 szwBuffer = HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf) * sizeof(WCHAR) );
456 if( !szwBuffer )
457 goto end;
460 r = MsiGetProductInfoW( szwProduct, szwAttribute, szwBuffer, pcchValueBuf );
462 if( ERROR_SUCCESS == r )
463 WideCharToMultiByte(CP_ACP, 0, szwBuffer, -1, szBuffer, *pcchValueBuf, NULL, NULL);
465 end:
466 HeapFree( GetProcessHeap(), 0, szwProduct );
467 HeapFree( GetProcessHeap(), 0, szwAttribute );
468 HeapFree( GetProcessHeap(), 0, szwBuffer );
470 return r;
473 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute,
474 LPWSTR szBuffer, DWORD *pcchValueBuf)
476 MSIHANDLE hProduct;
477 UINT r;
478 static const WCHAR szPackageCode[] =
479 {'P','a','c','k','a','g','e','C','o','d','e',0};
480 static const WCHAR szVersionString[] =
481 {'V','e','r','s','i','o','n','S','t','r','i','n','g',0};
482 static const WCHAR szProductVersion[] =
483 {'P','r','o','d','u','c','t','V','e','r','s','i','o','n',0};
484 static const WCHAR szAssignmentType[] =
485 {'A','s','s','i','g','n','m','e','n','t','T','y','p','e',0};
487 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute),
488 szBuffer, pcchValueBuf);
490 if (NULL != szBuffer && NULL == pcchValueBuf)
491 return ERROR_INVALID_PARAMETER;
492 if (NULL == szProduct || NULL == szAttribute)
493 return ERROR_INVALID_PARAMETER;
495 /* check for special properties */
496 if (strcmpW(szAttribute, szPackageCode)==0)
498 HKEY hkey;
499 WCHAR squished[GUID_SIZE];
500 WCHAR package[200];
501 DWORD sz = sizeof(squished);
503 r = MSIREG_OpenUserProductsKey(szProduct, &hkey, FALSE);
504 if (r != ERROR_SUCCESS)
505 return ERROR_UNKNOWN_PRODUCT;
507 r = RegQueryValueExW(hkey, szPackageCode, NULL, NULL,
508 (LPBYTE)squished, &sz);
509 if (r != ERROR_SUCCESS)
511 RegCloseKey(hkey);
512 return ERROR_UNKNOWN_PRODUCT;
515 unsquash_guid(squished, package);
516 *pcchValueBuf = strlenW(package);
517 if (strlenW(package) > *pcchValueBuf)
519 RegCloseKey(hkey);
520 return ERROR_MORE_DATA;
522 else
523 strcpyW(szBuffer, package);
525 RegCloseKey(hkey);
526 r = ERROR_SUCCESS;
528 else if (strcmpW(szAttribute, szVersionString)==0)
530 r = MsiOpenProductW(szProduct, &hProduct);
531 if (ERROR_SUCCESS != r)
532 return r;
534 r = MsiGetPropertyW(hProduct, szProductVersion, szBuffer, pcchValueBuf);
535 MsiCloseHandle(hProduct);
537 else if (strcmpW(szAttribute, szAssignmentType)==0)
539 FIXME("0 (zero) if advertised, 1(one) if per machine.\n");
540 if (szBuffer)
541 szBuffer[0] = 1;
542 r = ERROR_SUCCESS;
544 else
546 r = MsiOpenProductW(szProduct, &hProduct);
547 if (ERROR_SUCCESS != r)
548 return r;
550 r = MsiGetPropertyW(hProduct, szAttribute, szBuffer, pcchValueBuf);
551 MsiCloseHandle(hProduct);
554 return r;
557 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
559 LPWSTR szwLogFile = NULL;
560 UINT r;
562 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_a(szLogFile), attributes);
564 if( szLogFile )
566 szwLogFile = strdupAtoW( szLogFile );
567 if( !szwLogFile )
568 return ERROR_OUTOFMEMORY;
570 r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
571 HeapFree( GetProcessHeap(), 0, szwLogFile );
572 return r;
575 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
577 HANDLE file = INVALID_HANDLE_VALUE;
579 TRACE("%08lx %s %08lx\n", dwLogMode, debugstr_w(szLogFile), attributes);
581 lstrcpyW(gszLogFile,szLogFile);
582 if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
583 DeleteFileW(szLogFile);
584 file = CreateFileW(szLogFile, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS,
585 FILE_ATTRIBUTE_NORMAL, NULL);
586 if (file != INVALID_HANDLE_VALUE)
587 CloseHandle(file);
588 else
589 ERR("Unable to enable log %s\n",debugstr_w(szLogFile));
591 return ERROR_SUCCESS;
594 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
596 LPWSTR szwProduct = NULL;
597 INSTALLSTATE r;
599 if( szProduct )
601 szwProduct = strdupAtoW( szProduct );
602 if( !szwProduct )
603 return ERROR_OUTOFMEMORY;
605 r = MsiQueryProductStateW( szwProduct );
606 HeapFree( GetProcessHeap(), 0, szwProduct );
607 return r;
610 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
612 UINT rc;
613 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
614 HKEY hkey = 0;
615 static const WCHAR szWindowsInstaller[] = {
616 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
617 DWORD sz;
619 TRACE("%s\n", debugstr_w(szProduct));
621 rc = MSIREG_OpenUserProductsKey(szProduct,&hkey,FALSE);
622 if (rc != ERROR_SUCCESS)
623 goto end;
625 RegCloseKey(hkey);
627 rc = MSIREG_OpenUninstallKey(szProduct,&hkey,FALSE);
628 if (rc != ERROR_SUCCESS)
629 goto end;
631 sz = sizeof(rrc);
632 rc = RegQueryValueExW(hkey,szWindowsInstaller,NULL,NULL,(LPVOID)&rrc, &sz);
633 if (rc != ERROR_SUCCESS)
634 goto end;
636 switch (rrc)
638 case 1:
639 /* default */
640 rrc = INSTALLSTATE_DEFAULT;
641 break;
642 default:
643 FIXME("Unknown install state read from registry (%i)\n",rrc);
644 rrc = INSTALLSTATE_UNKNOWN;
645 break;
647 end:
648 RegCloseKey(hkey);
649 return rrc;
652 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
654 INSTALLUILEVEL old = gUILevel;
655 HWND oldwnd = gUIhwnd;
657 TRACE("%08x %p\n", dwUILevel, phWnd);
659 gUILevel = dwUILevel;
660 if (phWnd)
662 gUIhwnd = *phWnd;
663 *phWnd = oldwnd;
665 return old;
668 INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
669 DWORD dwMessageFilter, LPVOID pvContext)
671 INSTALLUI_HANDLERA prev = gUIHandlerA;
673 TRACE("%p %lx %p\n",puiHandler, dwMessageFilter,pvContext);
674 gUIHandlerA = puiHandler;
675 gUIFilter = dwMessageFilter;
676 gUIContext = pvContext;
678 return prev;
681 INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
682 DWORD dwMessageFilter, LPVOID pvContext)
684 INSTALLUI_HANDLERW prev = gUIHandlerW;
686 TRACE("%p %lx %p\n",puiHandler,dwMessageFilter,pvContext);
687 gUIHandlerW = puiHandler;
688 gUIFilter = dwMessageFilter;
689 gUIContext = pvContext;
691 return prev;
694 /******************************************************************
695 * MsiLoadStringW [MSI.@]
697 * Loads a string from MSI's string resources.
699 * PARAMS
701 * handle [I] only -1 is handled currently
702 * id [I] id of the string to be loaded
703 * lpBuffer [O] buffer for the string to be written to
704 * nBufferMax [I] maximum size of the buffer in characters
705 * lang [I] the preferred language for the string
707 * RETURNS
709 * If successful, this function returns the language id of the string loaded
710 * If the function fails, the function returns zero.
712 * NOTES
714 * The type of the first parameter is unknown. LoadString's prototype
715 * suggests that it might be a module handle. I have made it an MSI handle
716 * for starters, as -1 is an invalid MSI handle, but not an invalid module
717 * handle. Maybe strings can be stored in an MSI database somehow.
719 LANGID WINAPI MsiLoadStringW( MSIHANDLE handle, UINT id, LPWSTR lpBuffer,
720 int nBufferMax, LANGID lang )
722 HRSRC hres;
723 HGLOBAL hResData;
724 LPWSTR p;
725 DWORD i, len;
727 TRACE("%ld %u %p %d %d\n", handle, id, lpBuffer, nBufferMax, lang);
729 if( handle != -1 )
730 FIXME("don't know how to deal with handle = %08lx\n", handle);
732 if( !lang )
733 lang = GetUserDefaultLangID();
735 hres = FindResourceExW( msi_hInstance, (LPCWSTR) RT_STRING,
736 (LPWSTR)1, lang );
737 if( !hres )
738 return 0;
739 hResData = LoadResource( msi_hInstance, hres );
740 if( !hResData )
741 return 0;
742 p = LockResource( hResData );
743 if( !p )
744 return 0;
746 for (i = 0; i < (id&0xf); i++)
747 p += *p + 1;
748 len = *p;
750 if( nBufferMax <= len )
751 return 0;
753 memcpy( lpBuffer, p+1, len * sizeof(WCHAR));
754 lpBuffer[ len ] = 0;
756 TRACE("found -> %s\n", debugstr_w(lpBuffer));
758 return lang;
761 LANGID WINAPI MsiLoadStringA( MSIHANDLE handle, UINT id, LPSTR lpBuffer,
762 int nBufferMax, LANGID lang )
764 LPWSTR bufW;
765 LANGID r;
766 DWORD len;
768 bufW = HeapAlloc(GetProcessHeap(), 0, nBufferMax*sizeof(WCHAR));
769 r = MsiLoadStringW(handle, id, bufW, nBufferMax, lang);
770 if( r )
772 len = WideCharToMultiByte(CP_ACP, 0, bufW, -1, NULL, 0, NULL, NULL );
773 if( len <= nBufferMax )
774 WideCharToMultiByte( CP_ACP, 0, bufW, -1,
775 lpBuffer, nBufferMax, NULL, NULL );
776 else
777 r = 0;
779 HeapFree(GetProcessHeap(), 0, bufW);
780 return r;
783 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf,
784 DWORD *pcchBuf)
786 FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
787 return INSTALLSTATE_UNKNOWN;
790 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPSTR lpPathBuf,
791 DWORD *pcchBuf)
793 FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
794 return INSTALLSTATE_UNKNOWN;
797 UINT WINAPI MsiMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,
798 WORD wLanguageId, DWORD f)
800 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_a(lpText),debugstr_a(lpCaption),
801 uType,wLanguageId,f);
802 return ERROR_CALL_NOT_IMPLEMENTED;
805 UINT WINAPI MsiMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType,
806 WORD wLanguageId, DWORD f)
808 FIXME("%p %s %s %u %08x %08lx\n",hWnd,debugstr_w(lpText),debugstr_w(lpCaption),
809 uType,wLanguageId,f);
810 return ERROR_CALL_NOT_IMPLEMENTED;
813 UINT WINAPI MsiProvideAssemblyA( LPCSTR szAssemblyName, LPCSTR szAppContext,
814 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf,
815 DWORD* pcchPathBuf )
817 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName),
818 debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
819 pcchPathBuf);
820 return ERROR_CALL_NOT_IMPLEMENTED;
823 UINT WINAPI MsiProvideAssemblyW( LPCWSTR szAssemblyName, LPCWSTR szAppContext,
824 DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf,
825 DWORD* pcchPathBuf )
827 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName),
828 debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf,
829 pcchPathBuf);
830 return ERROR_CALL_NOT_IMPLEMENTED;
833 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor,
834 LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
836 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
837 return ERROR_CALL_NOT_IMPLEMENTED;
840 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor,
841 LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
843 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
844 return ERROR_CALL_NOT_IMPLEMENTED;
847 HRESULT WINAPI MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath,
848 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
849 DWORD* pcbHashData)
851 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags,
852 ppcCertContext, pbHashData, pcbHashData);
853 return ERROR_CALL_NOT_IMPLEMENTED;
856 HRESULT WINAPI MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath,
857 DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData,
858 DWORD* pcbHashData)
860 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags,
861 ppcCertContext, pbHashData, pcbHashData);
862 return ERROR_CALL_NOT_IMPLEMENTED;
865 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
866 LPSTR szValue, DWORD *pccbValue )
868 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
869 return ERROR_CALL_NOT_IMPLEMENTED;
872 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
873 LPWSTR szValue, DWORD *pccbValue )
875 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
876 return ERROR_CALL_NOT_IMPLEMENTED;
879 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
881 UINT r;
882 LPWSTR szPack = NULL;
884 TRACE("%s\n", debugstr_a(szPackage) );
886 if( szPackage )
888 szPack = strdupAtoW( szPackage );
889 if( !szPack )
890 return ERROR_OUTOFMEMORY;
893 r = MsiVerifyPackageW( szPack );
895 HeapFree( GetProcessHeap(), 0, szPack );
897 return r;
900 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
902 MSIHANDLE handle;
903 UINT r;
905 TRACE("%s\n", debugstr_w(szPackage) );
907 r = MsiOpenDatabaseW( szPackage, MSIDBOPEN_READONLY, &handle );
908 MsiCloseHandle( handle );
910 return r;
913 INSTALLSTATE WINAPI MsiGetComponentPathA(LPCSTR szProduct, LPCSTR szComponent,
914 LPSTR lpPathBuf, DWORD* pcchBuf)
916 LPWSTR szwProduct = NULL, szwComponent = NULL, lpwPathBuf= NULL;
917 INSTALLSTATE rc;
918 UINT incoming_len;
920 if( szProduct )
922 szwProduct = strdupAtoW( szProduct );
923 if( !szwProduct)
924 return ERROR_OUTOFMEMORY;
927 if( szComponent )
929 szwComponent = strdupAtoW( szComponent );
930 if( !szwComponent )
932 HeapFree( GetProcessHeap(), 0, szwProduct);
933 return ERROR_OUTOFMEMORY;
937 if( pcchBuf && *pcchBuf > 0 )
938 lpwPathBuf = HeapAlloc( GetProcessHeap(), 0, *pcchBuf * sizeof(WCHAR));
939 else
940 lpwPathBuf = NULL;
942 incoming_len = *pcchBuf;
943 rc = MsiGetComponentPathW(szwProduct, szwComponent, lpwPathBuf, pcchBuf);
945 HeapFree( GetProcessHeap(), 0, szwProduct);
946 HeapFree( GetProcessHeap(), 0, szwComponent);
947 if (lpwPathBuf)
949 if (rc != INSTALLSTATE_UNKNOWN)
950 WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, incoming_len,
951 lpPathBuf, incoming_len, NULL, NULL);
952 HeapFree( GetProcessHeap(), 0, lpwPathBuf);
955 return rc;
958 INSTALLSTATE WINAPI MsiGetComponentPathW(LPCWSTR szProduct, LPCWSTR szComponent,
959 LPWSTR lpPathBuf, DWORD* pcchBuf)
961 WCHAR squished_pc[GUID_SIZE];
962 UINT rc;
963 INSTALLSTATE rrc = INSTALLSTATE_UNKNOWN;
964 HKEY hkey = 0;
965 LPWSTR path = NULL;
966 DWORD sz, type;
968 TRACE("%s %s %p %p\n", debugstr_w(szProduct),
969 debugstr_w(szComponent), lpPathBuf, pcchBuf);
971 if( lpPathBuf && !pcchBuf )
972 return INSTALLSTATE_INVALIDARG;
974 squash_guid(szProduct,squished_pc);
976 rc = MSIREG_OpenProductsKey( szProduct, &hkey, FALSE);
977 if( rc != ERROR_SUCCESS )
978 goto end;
980 RegCloseKey(hkey);
982 rc = MSIREG_OpenComponentsKey( szComponent, &hkey, FALSE);
983 if( rc != ERROR_SUCCESS )
984 goto end;
986 sz = 0;
987 type = 0;
988 rc = RegQueryValueExW( hkey, squished_pc, NULL, &type, NULL, &sz );
989 if( rc != ERROR_SUCCESS )
990 goto end;
991 if( type != REG_SZ )
992 goto end;
994 sz += sizeof(WCHAR);
995 path = HeapAlloc( GetProcessHeap(), 0, sz );
996 if( !path )
997 goto end;
999 rc = RegQueryValueExW( hkey, squished_pc, NULL, NULL, (LPVOID) path, &sz );
1000 if( rc != ERROR_SUCCESS )
1001 goto end;
1003 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent),
1004 debugstr_w(szProduct), debugstr_w(path));
1006 if (path[0]=='0')
1008 FIXME("Registry entry.. check entry\n");
1009 rrc = INSTALLSTATE_LOCAL;
1011 else
1013 /* PROBABLY a file */
1014 if ( GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES )
1015 rrc = INSTALLSTATE_LOCAL;
1016 else
1017 rrc = INSTALLSTATE_ABSENT;
1020 if( pcchBuf )
1022 sz = sz / sizeof(WCHAR);
1023 if( *pcchBuf >= sz )
1024 lstrcpyW( lpPathBuf, path );
1025 *pcchBuf = sz;
1028 end:
1029 HeapFree(GetProcessHeap(), 0, path );
1030 RegCloseKey(hkey);
1031 return rrc;
1034 /******************************************************************
1035 * MsiQueryFeatureStateA [MSI.@]
1037 INSTALLSTATE WINAPI MsiQueryFeatureStateA(LPCSTR szProduct, LPCSTR szFeature)
1039 INSTALLSTATE rc;
1040 LPWSTR szwProduct= NULL;
1041 LPWSTR szwFeature= NULL;
1043 if( szProduct )
1045 szwProduct = strdupAtoW( szProduct );
1046 if( !szwProduct)
1047 return ERROR_OUTOFMEMORY;
1050 if( szFeature )
1052 szwFeature = strdupAtoW( szFeature );
1053 if( !szwFeature)
1055 HeapFree( GetProcessHeap(), 0, szwProduct);
1056 return ERROR_OUTOFMEMORY;
1060 rc = MsiQueryFeatureStateW(szwProduct, szwFeature);
1062 HeapFree( GetProcessHeap(), 0, szwProduct);
1063 HeapFree( GetProcessHeap(), 0, szwFeature);
1065 return rc;
1068 /******************************************************************
1069 * MsiQueryFeatureStateW [MSI.@]
1071 * This does not verify that the Feature is functional. So i am only going to
1072 * check the existence of the key in the registry. This should tell me if it is
1073 * installed.
1075 INSTALLSTATE WINAPI MsiQueryFeatureStateW(LPCWSTR szProduct, LPCWSTR szFeature)
1077 UINT rc;
1078 DWORD sz = 0;
1079 HKEY hkey;
1081 TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1083 rc = MSIREG_OpenFeaturesKey(szProduct, &hkey, FALSE);
1084 if (rc != ERROR_SUCCESS)
1085 return INSTALLSTATE_UNKNOWN;
1087 rc = RegQueryValueExW( hkey, szFeature, NULL, NULL, NULL, &sz);
1088 RegCloseKey(hkey);
1090 if (rc == ERROR_SUCCESS)
1091 return INSTALLSTATE_LOCAL;
1092 else
1093 return INSTALLSTATE_ABSENT;
1096 /******************************************************************
1097 * MsiGetFileVersionA [MSI.@]
1099 UINT WINAPI MsiGetFileVersionA(LPCSTR szFilePath, LPSTR lpVersionBuf,
1100 DWORD* pcchVersionBuf, LPSTR lpLangBuf, DWORD* pcchLangBuf)
1102 LPWSTR szwFilePath = NULL, lpwVersionBuff = NULL, lpwLangBuff = NULL;
1103 UINT ret = ERROR_OUTOFMEMORY;
1105 if( szFilePath )
1107 szwFilePath = strdupAtoW( szFilePath );
1108 if( !szwFilePath )
1109 goto end;
1112 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1114 lpwVersionBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1115 if( !lpwVersionBuff )
1116 goto end;
1119 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1121 lpwLangBuff = HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf*sizeof(WCHAR));
1122 if( !lpwLangBuff )
1123 goto end;
1126 ret = MsiGetFileVersionW(szwFilePath, lpwVersionBuff, pcchVersionBuf,
1127 lpwLangBuff, pcchLangBuf);
1129 if( lpwVersionBuff )
1130 WideCharToMultiByte(CP_ACP, 0, lpwVersionBuff, -1,
1131 lpVersionBuf, *pcchVersionBuf, NULL, NULL);
1132 if( lpwLangBuff )
1133 WideCharToMultiByte(CP_ACP, 0, lpwLangBuff, -1,
1134 lpLangBuf, *pcchLangBuf, NULL, NULL);
1136 end:
1137 HeapFree(GetProcessHeap(), 0, szwFilePath);
1138 HeapFree(GetProcessHeap(), 0, lpwVersionBuff);
1139 HeapFree(GetProcessHeap(), 0, lpwLangBuff);
1141 return ret;
1144 /******************************************************************
1145 * MsiGetFileVersionW [MSI.@]
1147 UINT WINAPI MsiGetFileVersionW(LPCWSTR szFilePath, LPWSTR lpVersionBuf,
1148 DWORD* pcchVersionBuf, LPWSTR lpLangBuf, DWORD* pcchLangBuf)
1150 static const WCHAR szVersionResource[] = {'\\',0};
1151 static const WCHAR szVersionFormat[] = {
1152 '%','d','.','%','d','.','%','d','.','%','d',0};
1153 static const WCHAR szLangFormat[] = {'%','d',0};
1154 UINT ret = 0;
1155 DWORD dwVerLen;
1156 LPVOID lpVer = NULL;
1157 VS_FIXEDFILEINFO *ffi;
1158 UINT puLen;
1159 WCHAR tmp[32];
1161 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath),
1162 lpVersionBuf, pcchVersionBuf?*pcchVersionBuf:0,
1163 lpLangBuf, pcchLangBuf?*pcchLangBuf:0);
1165 dwVerLen = GetFileVersionInfoSizeW(szFilePath, NULL);
1166 if( !dwVerLen )
1167 return GetLastError();
1169 lpVer = HeapAlloc(GetProcessHeap(), 0, dwVerLen);
1170 if( !lpVer )
1172 ret = ERROR_OUTOFMEMORY;
1173 goto end;
1176 if( !GetFileVersionInfoW(szFilePath, 0, dwVerLen, lpVer) )
1178 ret = GetLastError();
1179 goto end;
1181 if( lpVersionBuf && pcchVersionBuf && *pcchVersionBuf )
1183 if( VerQueryValueW(lpVer, szVersionResource, (LPVOID*)&ffi, &puLen) &&
1184 (puLen > 0) )
1186 wsprintfW(tmp, szVersionFormat,
1187 HIWORD(ffi->dwFileVersionMS), LOWORD(ffi->dwFileVersionMS),
1188 HIWORD(ffi->dwFileVersionLS), LOWORD(ffi->dwFileVersionLS));
1189 lstrcpynW(lpVersionBuf, tmp, *pcchVersionBuf);
1190 *pcchVersionBuf = lstrlenW(lpVersionBuf);
1192 else
1194 *lpVersionBuf = 0;
1195 *pcchVersionBuf = 0;
1199 if( lpLangBuf && pcchLangBuf && *pcchLangBuf )
1201 DWORD lang = GetUserDefaultLangID();
1203 FIXME("Retrieve language from file\n");
1204 wsprintfW(tmp, szLangFormat, lang);
1205 lstrcpynW(lpLangBuf, tmp, *pcchLangBuf);
1206 *pcchLangBuf = lstrlenW(lpLangBuf);
1209 end:
1210 HeapFree(GetProcessHeap(), 0, lpVer);
1211 return ret;
1215 /******************************************************************
1216 * DllMain
1218 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
1220 switch(fdwReason)
1222 case DLL_PROCESS_ATTACH:
1223 msi_hInstance = hinstDLL;
1224 DisableThreadLibraryCalls(hinstDLL);
1225 msi_dialog_register_class();
1226 break;
1227 case DLL_PROCESS_DETACH:
1228 msi_dialog_unregister_class();
1229 /* FIXME: Cleanup */
1230 break;
1232 return TRUE;
1235 typedef struct tagIClassFactoryImpl
1237 IClassFactoryVtbl *lpVtbl;
1238 } IClassFactoryImpl;
1240 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,
1241 REFIID riid,LPVOID *ppobj)
1243 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1244 FIXME("%p %s %p\n",This,debugstr_guid(riid),ppobj);
1245 return E_NOINTERFACE;
1248 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface)
1250 return 2;
1253 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface)
1255 return 1;
1258 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface,
1259 LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
1261 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1263 FIXME("%p %p %s %p\n", This, pOuter, debugstr_guid(riid), ppobj);
1264 return E_FAIL;
1267 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
1269 IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
1271 FIXME("%p %d\n", This, dolock);
1272 return S_OK;
1275 static IClassFactoryVtbl MsiCF_Vtbl =
1277 MsiCF_QueryInterface,
1278 MsiCF_AddRef,
1279 MsiCF_Release,
1280 MsiCF_CreateInstance,
1281 MsiCF_LockServer
1284 static IClassFactoryImpl Msi_CF = { &MsiCF_Vtbl };
1286 /******************************************************************
1287 * DllGetClassObject [MSI.@]
1289 HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
1291 TRACE("%s %s %p\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
1293 if( IsEqualCLSID (rclsid, &CLSID_IMsiServer) ||
1294 IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage) ||
1295 IsEqualCLSID (rclsid, &CLSID_IMsiServerX1) ||
1296 IsEqualCLSID (rclsid, &CLSID_IMsiServerX2) ||
1297 IsEqualCLSID (rclsid, &CLSID_IMsiServerX3) )
1299 *ppv = (LPVOID) &Msi_CF;
1300 return S_OK;
1302 return CLASS_E_CLASSNOTAVAILABLE;
1305 /******************************************************************
1306 * DllGetVersion [MSI.@]
1308 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
1310 TRACE("%p\n",pdvi);
1312 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
1313 return E_INVALIDARG;
1315 pdvi->dwMajorVersion = MSI_MAJORVERSION;
1316 pdvi->dwMinorVersion = MSI_MINORVERSION;
1317 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
1318 pdvi->dwPlatformID = 1;
1320 return S_OK;
1323 /******************************************************************
1324 * DllCanUnloadNow [MSI.@]
1326 BOOL WINAPI MSI_DllCanUnloadNow(void)
1328 return S_FALSE;
1331 UINT WINAPI MsiGetFeatureUsageW(LPCWSTR szProduct, LPCWSTR szFeature,
1332 DWORD* pdwUseCount, WORD* pwDateUsed)
1334 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szFeature),
1335 pdwUseCount, pwDateUsed);
1336 return ERROR_CALL_NOT_IMPLEMENTED;
1339 UINT WINAPI MsiGetFeatureUsageA(LPCSTR szProduct, LPCSTR szFeature,
1340 DWORD* pdwUseCount, WORD* pwDateUsed)
1342 FIXME("%s %s %p %p\n", debugstr_a(szProduct), debugstr_a(szFeature),
1343 pdwUseCount, pwDateUsed);
1344 return ERROR_CALL_NOT_IMPLEMENTED;
1347 INSTALLSTATE WINAPI MsiUseFeatureExW(LPCWSTR szProduct, LPCWSTR szFeature,
1348 DWORD dwInstallMode, DWORD dwReserved)
1350 FIXME("%s %s %li %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1351 dwInstallMode, dwReserved);
1354 * Polls all the components of the feature to find install state and then
1355 * writes:
1356 * Software\\Microsoft\\Windows\\CurrentVersion\\
1357 * Installer\\Products\\<squishguid>\\<feature>
1358 * "Usage"=dword:........
1361 return INSTALLSTATE_LOCAL;
1364 /***********************************************************************
1365 * MsiUseFeatureExA [MSI.@]
1367 INSTALLSTATE WINAPI MsiUseFeatureExA(LPCSTR szProduct, LPCSTR szFeature,
1368 DWORD dwInstallMode, DWORD dwReserved)
1370 FIXME("%s %s %li %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1371 dwInstallMode, dwReserved);
1373 return INSTALLSTATE_LOCAL;
1376 INSTALLSTATE WINAPI MsiUseFeatureW(LPCWSTR szProduct, LPCWSTR szFeature)
1378 FIXME("%s %s\n", debugstr_w(szProduct), debugstr_w(szFeature));
1380 return INSTALLSTATE_LOCAL;
1383 INSTALLSTATE WINAPI MsiUseFeatureA(LPCSTR szProduct, LPCSTR szFeature)
1385 FIXME("%s %s\n", debugstr_a(szProduct), debugstr_a(szFeature));
1387 return INSTALLSTATE_LOCAL;
1390 UINT WINAPI MsiProvideQualifiedComponentExW(LPCWSTR szComponent,
1391 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR szProduct,
1392 DWORD Unused1, DWORD Unused2, LPWSTR lpPathBuf,
1393 DWORD* pcchPathBuf)
1395 HKEY hkey;
1396 UINT rc;
1397 LPWSTR info;
1398 DWORD sz;
1399 LPWSTR product = NULL;
1400 LPWSTR component = NULL;
1401 LPWSTR ptr;
1402 GUID clsid;
1404 TRACE("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent),
1405 debugstr_w(szQualifier), dwInstallMode, debugstr_w(szProduct),
1406 Unused1, Unused2, lpPathBuf, pcchPathBuf);
1408 rc = MSIREG_OpenUserComponentsKey(szComponent, &hkey, FALSE);
1409 if (rc != ERROR_SUCCESS)
1410 return ERROR_INDEX_ABSENT;
1412 sz = 0;
1413 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, NULL, &sz);
1414 if (sz <= 0)
1416 RegCloseKey(hkey);
1417 return ERROR_INDEX_ABSENT;
1420 info = HeapAlloc(GetProcessHeap(),0,sz);
1421 rc = RegQueryValueExW( hkey, szQualifier, NULL, NULL, (LPBYTE)info, &sz);
1422 if (rc != ERROR_SUCCESS)
1424 RegCloseKey(hkey);
1425 HeapFree(GetProcessHeap(),0,info);
1426 return ERROR_INDEX_ABSENT;
1429 /* find the component */
1430 ptr = strchrW(&info[20],'>');
1431 if (ptr)
1432 ptr++;
1433 else
1435 RegCloseKey(hkey);
1436 HeapFree(GetProcessHeap(),0,info);
1437 return ERROR_INDEX_ABSENT;
1440 if (!szProduct)
1442 decode_base85_guid(info,&clsid);
1443 StringFromCLSID(&clsid, &product);
1445 decode_base85_guid(ptr,&clsid);
1446 StringFromCLSID(&clsid, &component);
1448 if (!szProduct)
1449 rc = MsiGetComponentPathW(product, component, lpPathBuf, pcchPathBuf);
1450 else
1451 rc = MsiGetComponentPathW(szProduct, component, lpPathBuf, pcchPathBuf);
1453 RegCloseKey(hkey);
1454 HeapFree(GetProcessHeap(),0,info);
1455 HeapFree(GetProcessHeap(),0,product);
1456 HeapFree(GetProcessHeap(),0,component);
1458 if (rc == INSTALLSTATE_LOCAL)
1459 return ERROR_SUCCESS;
1460 else
1461 return ERROR_FILE_NOT_FOUND;
1464 /***********************************************************************
1465 * MsiProvideQualifiedComponentW [MSI.@]
1467 UINT WINAPI MsiProvideQualifiedComponentW( LPCWSTR szComponent,
1468 LPCWSTR szQualifier, DWORD dwInstallMode, LPWSTR lpPathBuf,
1469 DWORD* pcchPathBuf)
1471 return MsiProvideQualifiedComponentExW(szComponent, szQualifier,
1472 dwInstallMode, NULL, 0, 0, lpPathBuf, pcchPathBuf);
1475 /***********************************************************************
1476 * MsiProvideQualifiedComponentA [MSI.@]
1478 UINT WINAPI MsiProvideQualifiedComponentA( LPCSTR szComponent,
1479 LPCSTR szQualifier, DWORD dwInstallMode, LPSTR lpPathBuf,
1480 DWORD* pcchPathBuf)
1482 LPWSTR szwComponent, szwQualifier, lpwPathBuf;
1483 DWORD pcchwPathBuf;
1484 UINT rc;
1486 TRACE("%s %s %li %p %p\n",szComponent, szQualifier,
1487 dwInstallMode, lpPathBuf, pcchPathBuf);
1489 szwComponent= strdupAtoW( szComponent);
1490 szwQualifier= strdupAtoW( szQualifier);
1492 lpwPathBuf = HeapAlloc(GetProcessHeap(),0,*pcchPathBuf * sizeof(WCHAR));
1494 pcchwPathBuf = *pcchPathBuf;
1496 rc = MsiProvideQualifiedComponentW(szwComponent, szwQualifier,
1497 dwInstallMode, lpwPathBuf, &pcchwPathBuf);
1499 HeapFree(GetProcessHeap(),0,szwComponent);
1500 HeapFree(GetProcessHeap(),0,szwQualifier);
1501 *pcchPathBuf = WideCharToMultiByte(CP_ACP, 0, lpwPathBuf, pcchwPathBuf,
1502 lpPathBuf, *pcchPathBuf, NULL, NULL);
1504 HeapFree(GetProcessHeap(),0,lpwPathBuf);
1505 return rc;
1508 USERINFOSTATE WINAPI MsiGetUserInfoW(LPCWSTR szProduct, LPWSTR lpUserNameBuf,
1509 DWORD* pcchUserNameBuf, LPWSTR lpOrgNameBuf,
1510 DWORD* pcchOrgNameBuf, LPWSTR lpSerialBuf, DWORD* pcchSerialBuf)
1512 FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct), lpUserNameBuf,
1513 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1514 pcchSerialBuf);
1516 return USERINFOSTATE_UNKNOWN;
1519 USERINFOSTATE WINAPI MsiGetUserInfoA(LPCSTR szProduct, LPSTR lpUserNameBuf,
1520 DWORD* pcchUserNameBuf, LPSTR lpOrgNameBuf,
1521 DWORD* pcchOrgNameBuf, LPSTR lpSerialBuf, DWORD* pcchSerialBuf)
1523 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct), lpUserNameBuf,
1524 pcchUserNameBuf, lpOrgNameBuf, pcchOrgNameBuf, lpSerialBuf,
1525 pcchSerialBuf);
1527 return USERINFOSTATE_UNKNOWN;
1530 UINT WINAPI MsiCollectUserInfoW(LPCWSTR szProduct)
1532 FIXME("%s\n",debugstr_w(szProduct));
1533 return ERROR_CALL_NOT_IMPLEMENTED;
1536 UINT WINAPI MsiCollectUserInfoA(LPCSTR szProduct)
1538 FIXME("%s\n",debugstr_a(szProduct));
1539 return ERROR_CALL_NOT_IMPLEMENTED;
1542 UINT WINAPI MsiCreateAndVerifyInstallerDirectory(DWORD dwReserved)
1544 WCHAR path[MAX_PATH];
1546 if(dwReserved) {
1547 FIXME("Don't know how to handle argument %ld\n", dwReserved);
1548 return ERROR_CALL_NOT_IMPLEMENTED;
1551 if(!GetWindowsDirectoryW(path, MAX_PATH)) {
1552 FIXME("GetWindowsDirectory failed unexpected! Error %ld\n",
1553 GetLastError());
1554 return ERROR_CALL_NOT_IMPLEMENTED;
1557 strcatW(path, installerW);
1559 CreateDirectoryW(path, NULL);
1561 return 0;
1564 UINT WINAPI MsiGetShortcutTargetA( LPCSTR szShortcutTarget,
1565 LPSTR szProductCode, LPSTR szFeatureId,
1566 LPSTR szComponentCode )
1568 FIXME("\n");
1569 return ERROR_CALL_NOT_IMPLEMENTED;
1572 UINT WINAPI MsiGetShortcutTargetW( LPCWSTR szShortcutTarget,
1573 LPWSTR szProductCode, LPWSTR szFeatureId,
1574 LPWSTR szComponentCode )
1576 FIXME("\n");
1577 return ERROR_CALL_NOT_IMPLEMENTED;
1580 UINT WINAPI MsiReinstallFeatureW( LPCWSTR szProduct, LPCWSTR szFeature,
1581 DWORD dwReinstallMode )
1583 FIXME("%s %s %li\n", debugstr_w(szProduct), debugstr_w(szFeature),
1584 dwReinstallMode);
1585 return ERROR_SUCCESS;
1588 UINT WINAPI MsiReinstallFeatureA( LPCSTR szProduct, LPCSTR szFeature,
1589 DWORD dwReinstallMode )
1591 FIXME("%s %s %li\n", debugstr_a(szProduct), debugstr_a(szFeature),
1592 dwReinstallMode);
1593 return ERROR_SUCCESS;