2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003 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 #define NONAMELESSUNION
30 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(msi);
41 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
42 * which is a problem because LPCTSTR isn't defined when compiling wine.
43 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
44 * and make sure to only use it in W functions.
46 #define LPCTSTR LPCWSTR
48 static const WCHAR szInstaller[] = {
49 'S','o','f','t','w','a','r','e','\\',
50 'M','i','c','r','o','s','o','f','t','\\',
51 'W','i','n','d','o','w','s','\\',
52 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
53 'I','n','s','t','a','l','l','e','r',0 };
55 static const WCHAR szFeatures[] = {
56 'F','e','a','t','u','r','e','s',0 };
57 static const WCHAR szComponents[] = {
58 'C','o','m','p','o','n','e','n','t','s',0 };
63 * A .msi file is a structured storage file.
64 * It should contain a number of streams.
67 BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
83 out[n++] = in[17+i*2];
84 out[n++] = in[16+i*2];
89 out[n++] = in[17+i*2];
90 out[n++] = in[16+i*2];
97 BOOL squash_guid(LPCWSTR in, LPWSTR out)
117 out[17+i*2] = in[n++];
118 out[16+i*2] = in[n++];
124 out[17+i*2] = in[n++];
125 out[16+i*2] = in[n++];
135 VOID MSI_CloseDatabase( VOID *arg )
137 MSIDATABASE *db = (MSIDATABASE *) arg;
139 free_cached_tables( db );
140 IStorage_Release( db->storage );
143 UINT WINAPI MsiOpenDatabaseA(
144 LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
146 HRESULT r = ERROR_FUNCTION_FAILED;
147 LPWSTR szwDBPath = NULL, szwPersist = NULL;
150 TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
154 len = MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, NULL, 0 );
155 szwDBPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
158 MultiByteToWideChar( CP_ACP, 0, szDBPath, -1, szwDBPath, len );
161 if( HIWORD(szPersist) )
163 len = MultiByteToWideChar( CP_ACP, 0, szPersist, -1, NULL, 0 );
164 szwPersist = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
167 MultiByteToWideChar( CP_ACP, 0, szPersist, -1, szwPersist, len );
170 szwPersist = (LPWSTR) szPersist;
172 r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
176 HeapFree( GetProcessHeap(), 0, szwPersist );
178 HeapFree( GetProcessHeap(), 0, szwDBPath );
183 UINT WINAPI MsiOpenDatabaseW(
184 LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
186 IStorage *stg = NULL;
193 TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
196 return ERROR_INVALID_PARAMETER;
198 szMode = (LPWSTR) szPersist;
199 if( HIWORD( szPersist ) )
201 /* UINT len = lstrlenW( szPerist ) + 1; */
202 FIXME("don't support persist files yet\b");
203 return ERROR_INVALID_PARAMETER;
204 /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
206 else if( szPersist == MSIDBOPEN_READONLY )
208 r = StgOpenStorage( szDBPath, NULL,
209 STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
211 else if( szPersist == MSIDBOPEN_CREATE )
213 r = StgCreateDocfile( szDBPath,
214 STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, 0, &stg);
215 if( r == ERROR_SUCCESS )
216 r = init_string_table( stg );
218 else if( szPersist == MSIDBOPEN_TRANSACT )
220 r = StgOpenStorage( szDBPath, NULL,
221 STGM_DIRECT|STGM_READWRITE|STGM_SHARE_EXCLUSIVE, NULL, 0, &stg);
225 ERR("unknown flag %p\n",szPersist);
226 return ERROR_INVALID_PARAMETER;
231 FIXME("open failed r = %08lx!\n",r);
232 return ERROR_FUNCTION_FAILED;
235 handle = alloc_msihandle( MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE),
236 MSI_CloseDatabase, (void**) &db );
239 FIXME("Failed to allocate a handle\n");
240 ret = ERROR_FUNCTION_FAILED;
246 /* db->strings = NULL;
247 db->first_table = NULL;
248 db->last_table = NULL; */
250 ret = load_string_table( db );
251 if( ret != ERROR_SUCCESS )
256 IStorage_AddRef( stg );
259 IStorage_Release( stg );
264 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
267 LPWSTR szwProd = NULL;
269 TRACE("%s %p\n",debugstr_a(szProduct), phProduct);
273 len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
274 szwProd = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
276 MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProd, len );
279 ret = MsiOpenProductW( szwProd, phProduct );
282 HeapFree( GetProcessHeap(), 0, szwProd );
287 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
289 static const WCHAR szKey[] = {
290 'S','o','f','t','w','a','r','e','\\',
291 'M','i','c','r','o','s','o','f','t','\\',
292 'W','i','n','d','o','w','s','\\',
293 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
294 'U','n','i','n','s','t','a','l','l',0 };
295 static const WCHAR szLocalPackage[] = {
296 'L','o','c','a','l','P','a','c','k','a','g','e', 0
300 HKEY hKeyProduct = NULL, hKeyUninstall = NULL;
303 TRACE("%s %p\n",debugstr_w(szProduct), phProduct);
305 r = RegOpenKeyW( HKEY_LOCAL_MACHINE, szKey, &hKeyUninstall );
306 if( r != ERROR_SUCCESS )
309 r = RegOpenKeyW( hKeyUninstall, szProduct, &hKeyProduct );
310 if( r != ERROR_SUCCESS )
313 /* find the size of the path */
315 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
316 NULL, &type, NULL, &count );
317 if( r != ERROR_SUCCESS )
320 /* now alloc and fetch the path of the database to open */
321 path = HeapAlloc( GetProcessHeap(), 0, count );
325 r = RegQueryValueExW( hKeyProduct, szLocalPackage,
326 NULL, &type, (LPBYTE) path, &count );
327 if( r != ERROR_SUCCESS )
330 r = MsiOpenPackageW( path, phProduct );
334 HeapFree( GetProcessHeap(), 0, path );
336 RegCloseKey( hKeyProduct );
337 RegCloseKey( hKeyUninstall );
342 UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
344 FIXME("%s %p\n",debugstr_a(szPackage), phPackage);
345 return ERROR_CALL_NOT_IMPLEMENTED;
348 UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
350 FIXME("%s %p\n",debugstr_w(szPackage), phPackage);
351 return ERROR_CALL_NOT_IMPLEMENTED;
354 UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
356 FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage), dwOptions, phPackage);
357 return ERROR_CALL_NOT_IMPLEMENTED;
360 UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
362 FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
363 return ERROR_CALL_NOT_IMPLEMENTED;
366 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage)
368 FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
369 return ERROR_CALL_NOT_IMPLEMENTED;
372 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage)
374 FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
375 return ERROR_CALL_NOT_IMPLEMENTED;
378 UINT WINAPI MsiAdvertiseProductExA(
379 LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
381 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
382 debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage, dwPlatform, dwOptions);
383 return ERROR_CALL_NOT_IMPLEMENTED;
386 UINT WINAPI MsiAdvertiseProductExW(
387 LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
389 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
390 debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage, dwPlatform, dwOptions);
391 return ERROR_CALL_NOT_IMPLEMENTED;
394 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
396 LPWSTR szwPath = NULL, szwCommand = NULL;
397 UINT r = ERROR_FUNCTION_FAILED; /* FIXME: check return code */
399 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
403 UINT len = MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, NULL, 0 );
404 szwPath = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
407 MultiByteToWideChar( CP_ACP, 0, szPackagePath, -1, szwPath, len );
412 UINT len = MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, NULL, 0 );
413 szwCommand = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
416 MultiByteToWideChar( CP_ACP, 0, szCommandLine, -1, szwCommand, len );
419 r = MsiInstallProductW( szwPath, szwCommand );
423 HeapFree( GetProcessHeap(), 0, szwPath );
426 HeapFree( GetProcessHeap(), 0, szwCommand );
431 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
433 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
435 return ERROR_CALL_NOT_IMPLEMENTED;
438 UINT WINAPI MsiConfigureProductA(
439 LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
441 FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
442 return ERROR_CALL_NOT_IMPLEMENTED;
445 UINT WINAPI MsiConfigureProductW(
446 LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
448 FIXME("%s %d %d\n",debugstr_w(szProduct), iInstallLevel, eInstallState);
449 return ERROR_CALL_NOT_IMPLEMENTED;
452 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
454 FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
455 return ERROR_CALL_NOT_IMPLEMENTED;
458 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
460 FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
461 return ERROR_CALL_NOT_IMPLEMENTED;
464 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, DWORD *pcchValueBuf)
466 FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute), szBuffer, pcchValueBuf);
467 return ERROR_CALL_NOT_IMPLEMENTED;
470 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute, LPWSTR szBuffer, DWORD *pcchValueBuf)
472 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute), szBuffer, pcchValueBuf);
473 return ERROR_CALL_NOT_IMPLEMENTED;
476 UINT WINAPI MsiDatabaseImportA(LPCSTR szFolderPath, LPCSTR szFilename)
478 FIXME("%s %s\n",debugstr_a(szFolderPath), debugstr_a(szFilename));
479 return ERROR_CALL_NOT_IMPLEMENTED;
482 UINT WINAPI MsiDatabaseImportW(LPCWSTR szFolderPath, LPCWSTR szFilename)
484 FIXME("%s %s\n",debugstr_w(szFolderPath), debugstr_w(szFilename));
485 return ERROR_CALL_NOT_IMPLEMENTED;
488 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, BOOL fAppend)
490 FIXME("%08lx %s %d\n", dwLogMode, debugstr_a(szLogFile), fAppend);
491 return ERROR_SUCCESS;
492 /* return ERROR_CALL_NOT_IMPLEMENTED; */
495 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, BOOL fAppend)
497 FIXME("%08lx %s %d\n", dwLogMode, debugstr_w(szLogFile), fAppend);
498 return ERROR_CALL_NOT_IMPLEMENTED;
501 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
503 FIXME("%s\n", debugstr_a(szProduct));
504 return INSTALLSTATE_UNKNOWN;
507 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
509 FIXME("%s\n", debugstr_w(szProduct));
510 return INSTALLSTATE_UNKNOWN;
513 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
515 FIXME("%08x %p\n", dwUILevel, phWnd);
519 UINT WINAPI MsiLoadStringA(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e)
521 FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);
522 return ERROR_CALL_NOT_IMPLEMENTED;
525 UINT WINAPI MsiLoadStringW(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e)
527 FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);
528 return ERROR_CALL_NOT_IMPLEMENTED;
531 INSTALLSTATE WINAPI MsiLocateComponentA(LPCSTR szComponent, LPSTR lpPathBuf, DWORD *pcchBuf)
533 FIXME("%s %p %08lx\n", debugstr_a(szComponent), lpPathBuf, *pcchBuf);
534 return INSTALLSTATE_UNKNOWN;
537 INSTALLSTATE WINAPI MsiLocateComponentW(LPCWSTR szComponent, LPSTR lpPathBuf, DWORD *pcchBuf)
539 FIXME("%s %p %08lx\n", debugstr_w(szComponent), lpPathBuf, *pcchBuf);
540 return INSTALLSTATE_UNKNOWN;
543 UINT WINAPI MsiMessageBoxA(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f)
545 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);
546 return ERROR_CALL_NOT_IMPLEMENTED;
549 UINT WINAPI MsiMessageBoxW(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f)
551 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);
552 return ERROR_CALL_NOT_IMPLEMENTED;
555 UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
558 WCHAR szwGuid[GUID_SIZE];
560 TRACE("%ld %p\n",index,lpguid);
562 r = MsiEnumProductsW(index, szwGuid);
563 if( r == ERROR_SUCCESS )
564 WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
569 UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
571 HKEY hkey = 0, hkeyFeatures = 0;
575 TRACE("%ld %p\n",index,lpguid);
577 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
578 if( r != ERROR_SUCCESS )
581 r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
582 if( r != ERROR_SUCCESS )
585 r = RegEnumKeyW(hkeyFeatures, index, szKeyName, GUID_SIZE);
587 unsquash_guid(szKeyName, lpguid);
592 RegCloseKey(hkeyFeatures);
599 UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index,
600 LPSTR szFeature, LPSTR szParent)
603 WCHAR szwFeature[GUID_SIZE], szwParent[GUID_SIZE];
604 LPWSTR szwProduct = NULL;
606 TRACE("%s %ld %p %p\n",debugstr_a(szProduct),index,szFeature,szParent);
610 UINT len = MultiByteToWideChar( CP_ACP, 0, szProduct, -1, NULL, 0 );
611 szwProduct = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
613 MultiByteToWideChar( CP_ACP, 0, szProduct, -1, szwProduct, len );
615 return ERROR_FUNCTION_FAILED;
618 r = MsiEnumFeaturesW(szwProduct, index, szwFeature, szwParent);
619 if( r == ERROR_SUCCESS )
621 WideCharToMultiByte(CP_ACP, 0, szwFeature, -1,
622 szFeature, GUID_SIZE, NULL, NULL);
623 WideCharToMultiByte(CP_ACP, 0, szwParent, -1,
624 szParent, GUID_SIZE, NULL, NULL);
628 HeapFree( GetProcessHeap(), 0, szwProduct);
633 UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
634 LPWSTR szFeature, LPWSTR szParent)
636 HKEY hkey = 0, hkeyFeatures = 0, hkeyProduct = 0;
638 WCHAR szRegName[GUID_SIZE];
640 TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
642 if( !squash_guid(szProduct, szRegName) )
643 return ERROR_INVALID_PARAMETER;
645 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
646 if( r != ERROR_SUCCESS )
649 r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
650 if( r != ERROR_SUCCESS )
653 r = RegOpenKeyW(hkeyFeatures, szRegName, &hkeyProduct);
654 if( r != ERROR_SUCCESS )
658 r = RegEnumValueW(hkeyProduct, index, szFeature, &sz, NULL, NULL, NULL, NULL);
662 RegCloseKey(hkeyProduct);
664 RegCloseKey(hkeyFeatures);
671 UINT WINAPI MsiEnumComponentsA(DWORD index, LPSTR lpguid)
674 WCHAR szwGuid[GUID_SIZE];
676 TRACE("%ld %p\n",index,lpguid);
678 r = MsiEnumComponentsW(index, szwGuid);
679 if( r == ERROR_SUCCESS )
680 WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
685 UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
687 HKEY hkey = 0, hkeyComponents = 0;
691 TRACE("%ld %p\n",index,lpguid);
693 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
694 if( r != ERROR_SUCCESS )
697 r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
698 if( r != ERROR_SUCCESS )
701 r = RegEnumKeyW(hkeyComponents, index, szKeyName, GUID_SIZE);
703 unsquash_guid(szKeyName, lpguid);
708 RegCloseKey(hkeyComponents);
715 UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
718 WCHAR szwProduct[GUID_SIZE];
719 LPWSTR szwComponent = NULL;
721 TRACE("%s %ld %p\n",debugstr_a(szComponent),index,szProduct);
725 UINT len = MultiByteToWideChar( CP_ACP, 0, szComponent, -1, NULL, 0 );
726 szwComponent = HeapAlloc( GetProcessHeap(), 0, len * sizeof (WCHAR) );
728 MultiByteToWideChar( CP_ACP, 0, szComponent, -1, szwComponent, len );
730 return ERROR_FUNCTION_FAILED;
733 r = MsiEnumClientsW(szComponent?szwComponent:NULL, index, szwProduct);
734 if( r == ERROR_SUCCESS )
736 WideCharToMultiByte(CP_ACP, 0, szwProduct, -1,
737 szProduct, GUID_SIZE, NULL, NULL);
741 HeapFree( GetProcessHeap(), 0, szwComponent);
746 UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
748 HKEY hkey = 0, hkeyComponents = 0, hkeyComp = 0;
750 WCHAR szRegName[GUID_SIZE], szValName[GUID_SIZE];
752 TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);
754 if( !squash_guid(szComponent, szRegName) )
755 return ERROR_INVALID_PARAMETER;
757 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
758 if( r != ERROR_SUCCESS )
761 r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
762 if( r != ERROR_SUCCESS )
765 r = RegOpenKeyW(hkeyComponents, szRegName, &hkeyComp);
766 if( r != ERROR_SUCCESS )
770 r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);
771 if( r != ERROR_SUCCESS )
774 unsquash_guid(szValName, szProduct);
778 RegCloseKey(hkeyComp);
780 RegCloseKey(hkeyComponents);
787 UINT WINAPI MsiEnumComponentQualifiersA(
788 LPSTR szComponent, DWORD iIndex, LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf, LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
790 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex, lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf, pcchApplicationDataBuf);
791 return ERROR_CALL_NOT_IMPLEMENTED;
794 UINT WINAPI MsiEnumComponentQualifiersW(
795 LPWSTR szComponent, DWORD iIndex, LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf, LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
797 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex, lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf, pcchApplicationDataBuf);
798 return ERROR_CALL_NOT_IMPLEMENTED;
801 UINT WINAPI MsiProvideAssemblyA(
802 LPCSTR szAssemblyName, LPCSTR szAppContext, DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf, DWORD* pcchPathBuf)
804 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
805 debugstr_a(szAssemblyName), debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf, pcchPathBuf);
806 return ERROR_CALL_NOT_IMPLEMENTED;
809 UINT WINAPI MsiProvideAssemblyW(
810 LPCWSTR szAssemblyName, LPCWSTR szAppContext, DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf, DWORD* pcchPathBuf)
812 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
813 debugstr_w(szAssemblyName), debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf, pcchPathBuf);
814 return ERROR_CALL_NOT_IMPLEMENTED;
817 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor, LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
819 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
820 return ERROR_CALL_NOT_IMPLEMENTED;
823 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor, LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
825 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
826 return ERROR_CALL_NOT_IMPLEMENTED;
829 HRESULT WINAPI MsiGetFileSignatureInformationA(
830 LPCSTR szSignedObjectPath, DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData, DWORD* pcbHashData)
832 FIXME("%s 0x%08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags, ppcCertContext, pbHashData, pcbHashData);
833 return ERROR_CALL_NOT_IMPLEMENTED;
836 HRESULT WINAPI MsiGetFileSignatureInformationW(
837 LPCWSTR szSignedObjectPath, DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData, DWORD* pcbHashData)
839 FIXME("%s 0x%08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags, ppcCertContext, pbHashData, pcbHashData);
840 return ERROR_CALL_NOT_IMPLEMENTED;
843 UINT WINAPI MsiGetProductPropertyA( MSIHANDLE hProduct, LPCSTR szProperty,
844 LPSTR szValue, DWORD *pccbValue )
846 FIXME("%ld %s %p %p\n", hProduct, debugstr_a(szProperty), szValue, pccbValue);
847 return ERROR_CALL_NOT_IMPLEMENTED;
850 UINT WINAPI MsiGetProductPropertyW( MSIHANDLE hProduct, LPCWSTR szProperty,
851 LPWSTR szValue, DWORD *pccbValue )
853 FIXME("%ld %s %p %p\n", hProduct, debugstr_w(szProperty), szValue, pccbValue);
854 return ERROR_CALL_NOT_IMPLEMENTED;
857 UINT WINAPI MsiVerifyPackageA( LPCSTR szPackage )
859 FIXME("%s\n", debugstr_a(szPackage) );
860 return ERROR_CALL_NOT_IMPLEMENTED;
863 UINT WINAPI MsiVerifyPackageW( LPCWSTR szPackage )
865 FIXME("%s\n", debugstr_w(szPackage) );
866 return ERROR_CALL_NOT_IMPLEMENTED;
869 /******************************************************************
872 * @todo: maybe we can check here if MsiServer service is declared no ?
874 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
875 if (fdwReason == DLL_PROCESS_ATTACH) {
876 DisableThreadLibraryCalls(hinstDLL);
877 /* FIXME: Initialisation */
878 } else if (fdwReason == DLL_PROCESS_DETACH) {
882 static const WCHAR szMSIServerSvc[] = { 'M','S','I','S','e','r','v','e','r',0 };
883 static const WCHAR szNull[] = { 0 };
884 if (!strcmpW(lpServiceName, szMSIServerSvc)) {
885 hKey = CreateServiceW(hSCManager,
888 SC_MANAGER_ALL_ACCESS,
889 SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
891 SERVICE_ERROR_IGNORE,
903 /* IUnknown fields */
904 ICOM_VFIELD(IClassFactory);
908 static HRESULT WINAPI MsiCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
909 ICOM_THIS(IClassFactoryImpl,iface);
910 FIXME("(%p, %s, %p): stub\n",This,debugstr_guid(riid),ppobj);
911 return E_NOINTERFACE;
914 static ULONG WINAPI MsiCF_AddRef(LPCLASSFACTORY iface) {
915 ICOM_THIS(IClassFactoryImpl,iface);
916 return ++(This->ref);
919 static ULONG WINAPI MsiCF_Release(LPCLASSFACTORY iface) {
920 ICOM_THIS(IClassFactoryImpl,iface);
921 /* static class, won't be freed */
922 return --(This->ref);
925 static HRESULT WINAPI MsiCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj) {
926 ICOM_THIS(IClassFactoryImpl,iface);
927 FIXME ("(%p, %p, %s, %p): to implement\n", This, pOuter, debugstr_guid(riid), ppobj);
931 static HRESULT WINAPI MsiCF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
932 ICOM_THIS(IClassFactoryImpl,iface);
933 FIXME("(%p, %d): stub\n", This, dolock);
937 static ICOM_VTABLE(IClassFactory) MsiCF_Vtbl = {
938 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
939 MsiCF_QueryInterface,
942 MsiCF_CreateInstance,
946 static IClassFactoryImpl Msi_CF = {&MsiCF_Vtbl, 1 };
948 HRESULT WINAPI MSI_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) {
949 FIXME("(%s, %s, %p): almost a stub.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
950 if (IsEqualCLSID (rclsid, &CLSID_IMsiServer)) {
951 *ppv = (LPVOID) &Msi_CF;
952 IClassFactory_AddRef((IClassFactory*)*ppv);
954 } else if (IsEqualCLSID (rclsid, &CLSID_IMsiServerMessage)) {
955 *ppv = (LPVOID) &Msi_CF;
956 IClassFactory_AddRef((IClassFactory*)*ppv);
958 } else if (IsEqualCLSID (rclsid, &CLSID_IMsiServerX1)) {
959 *ppv = (LPVOID) &Msi_CF;
960 IClassFactory_AddRef((IClassFactory*)*ppv);
962 } else if (IsEqualCLSID (rclsid, &CLSID_IMsiServerX2)) {
963 *ppv = (LPVOID) &Msi_CF;
964 IClassFactory_AddRef((IClassFactory*)*ppv);
966 } else if (IsEqualCLSID (rclsid, &CLSID_IMsiServerX3)) {
967 *ppv = (LPVOID) &Msi_CF;
968 IClassFactory_AddRef((IClassFactory*)*ppv);
971 WARN("(%s, %s, %p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
972 return CLASS_E_CLASSNOTAVAILABLE;
975 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
979 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
982 pdvi->dwMajorVersion = MSI_MAJORVERSION;
983 pdvi->dwMinorVersion = MSI_MINORVERSION;
984 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
985 pdvi->dwPlatformID = 1;
990 BOOL WINAPI MSI_DllCanUnloadNow(void)