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"
37 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
39 const WCHAR szInstaller
[] = {
40 'S','o','f','t','w','a','r','e','\\',
41 'M','i','c','r','o','s','o','f','t','\\',
42 'W','i','n','d','o','w','s','\\',
43 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
44 'I','n','s','t','a','l','l','e','r',0 };
46 const WCHAR szFeatures
[] = {
47 'F','e','a','t','u','r','e','s',0 };
48 const WCHAR szComponents
[] = {
49 'C','o','m','p','o','n','e','n','t','s',0 };
54 * A .msi file is a structured storage file.
55 * It should contain a number of streams.
58 BOOL
unsquash_guid(LPCWSTR in
, LPWSTR out
)
74 out
[n
++] = in
[17+i
*2];
75 out
[n
++] = in
[16+i
*2];
80 out
[n
++] = in
[17+i
*2];
81 out
[n
++] = in
[16+i
*2];
88 BOOL
squash_guid(LPCWSTR in
, LPWSTR out
)
108 out
[17+i
*2] = in
[n
++];
109 out
[16+i
*2] = in
[n
++];
115 out
[17+i
*2] = in
[n
++];
116 out
[16+i
*2] = in
[n
++];
126 VOID
MSI_CloseDatabase( VOID
*arg
)
128 MSIDATABASE
*db
= (MSIDATABASE
*) arg
;
130 free_cached_tables( db
);
131 IStorage_Release( db
->storage
);
134 UINT WINAPI
MsiOpenDatabaseA(
135 LPCSTR szDBPath
, LPCSTR szPersist
, MSIHANDLE
*phDB
)
137 HRESULT r
= ERROR_FUNCTION_FAILED
;
138 LPWSTR szwDBPath
= NULL
, szwPersist
= NULL
;
141 TRACE("%s %s %p\n", debugstr_a(szDBPath
), debugstr_a(szPersist
), phDB
);
145 len
= MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, NULL
, 0 );
146 szwDBPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
149 MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, szwDBPath
, len
);
152 if( HIWORD(szPersist
) )
154 len
= MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, NULL
, 0 );
155 szwPersist
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
158 MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, szwPersist
, len
);
161 szwPersist
= (LPWSTR
) szPersist
;
163 r
= MsiOpenDatabaseW( szwDBPath
, szwPersist
, phDB
);
167 HeapFree( GetProcessHeap(), 0, szwPersist
);
169 HeapFree( GetProcessHeap(), 0, szwDBPath
);
174 UINT WINAPI
MsiOpenDatabaseW(
175 LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIHANDLE
*phDB
)
177 IStorage
*stg
= NULL
;
183 TRACE("%s %s %p\n",debugstr_w(szDBPath
),debugstr_w(szPersist
), phDB
);
186 return ERROR_INVALID_PARAMETER
;
188 r
= StgOpenStorage( szDBPath
, NULL
, STGM_DIRECT
|STGM_READ
|STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
191 FIXME("open failed r = %08lx!\n",r
);
192 return ERROR_FUNCTION_FAILED
;
195 handle
= alloc_msihandle(MSIHANDLETYPE_DATABASE
, sizeof (MSIDATABASE
), MSI_CloseDatabase
);
198 FIXME("Failed to allocate a handle\n");
199 ret
= ERROR_FUNCTION_FAILED
;
203 db
= msihandle2msiinfo( handle
, MSIHANDLETYPE_DATABASE
);
206 FIXME("Failed to get handle pointer \n");
207 ret
= ERROR_FUNCTION_FAILED
;
211 ret
= load_string_table( db
, &db
->strings
);
212 if( ret
!= ERROR_SUCCESS
)
217 IStorage_AddRef( stg
);
220 IStorage_Release( stg
);
225 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
228 LPWSTR szwProd
= NULL
;
230 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
234 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
235 szwProd
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
237 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProd
, len
);
240 ret
= MsiOpenProductW( szwProd
, phProduct
);
243 HeapFree( GetProcessHeap(), 0, szwProd
);
248 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
250 const WCHAR szKey
[] = {
251 'S','o','f','t','w','a','r','e','\\',
252 'M','i','c','r','o','s','o','f','t','\\',
253 'W','i','n','d','o','w','s','\\',
254 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
255 'U','n','i','n','s','t','a','l','l',0 };
256 const WCHAR szLocalPackage
[] = {
257 'L','o','c','a','l','P','a','c','k','a','g','e', 0
261 HKEY hKeyProduct
= NULL
, hKeyUninstall
= NULL
;
264 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
266 r
= RegOpenKeyW( HKEY_LOCAL_MACHINE
, szKey
, &hKeyUninstall
);
267 if( r
!= ERROR_SUCCESS
)
270 r
= RegOpenKeyW( hKeyUninstall
, szProduct
, &hKeyProduct
);
271 if( r
!= ERROR_SUCCESS
)
274 /* find the size of the path */
276 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
277 NULL
, &type
, NULL
, &count
);
278 if( r
!= ERROR_SUCCESS
)
281 /* now alloc and fetch the path of the database to open */
282 path
= HeapAlloc( GetProcessHeap(), 0, count
);
286 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
287 NULL
, &type
, (LPBYTE
) path
, &count
);
288 if( r
!= ERROR_SUCCESS
)
291 r
= MsiOpenPackageW( path
, phProduct
);
295 HeapFree( GetProcessHeap(), 0, path
);
297 RegCloseKey( hKeyProduct
);
298 RegCloseKey( hKeyUninstall
);
303 UINT WINAPI
MsiOpenPackageA(LPCSTR szPackage
, MSIHANDLE
*phPackage
)
305 FIXME("%s %p\n",debugstr_a(szPackage
), phPackage
);
306 return ERROR_CALL_NOT_IMPLEMENTED
;
309 UINT WINAPI
MsiOpenPackageW(LPCWSTR szPackage
, MSIHANDLE
*phPackage
)
311 FIXME("%s %p\n",debugstr_w(szPackage
), phPackage
);
312 return ERROR_CALL_NOT_IMPLEMENTED
;
315 UINT WINAPI
MsiOpenPackageExA(LPCSTR szPackage
, DWORD dwOptions
, MSIHANDLE
*phPackage
)
317 FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage
), dwOptions
, phPackage
);
318 return ERROR_CALL_NOT_IMPLEMENTED
;
321 UINT WINAPI
MsiOpenPackageExW(LPCWSTR szPackage
, DWORD dwOptions
, MSIHANDLE
*phPackage
)
323 FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage
), dwOptions
, phPackage
);
324 return ERROR_CALL_NOT_IMPLEMENTED
;
327 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
, LPCSTR szTransforms
, LANGID lgidLanguage
)
329 FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath
), debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
330 return ERROR_CALL_NOT_IMPLEMENTED
;
333 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
, LPCWSTR szTransforms
, LANGID lgidLanguage
)
335 FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath
), debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
336 return ERROR_CALL_NOT_IMPLEMENTED
;
339 UINT WINAPI
MsiAdvertiseProductExA(
340 LPCSTR szPackagePath
, LPCSTR szScriptfilePath
, LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
342 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
343 debugstr_a(szPackagePath
), debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
, dwPlatform
, dwOptions
);
344 return ERROR_CALL_NOT_IMPLEMENTED
;
347 UINT WINAPI
MsiAdvertiseProductExW(
348 LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
, LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
350 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
351 debugstr_w(szPackagePath
), debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
, dwPlatform
, dwOptions
);
352 return ERROR_CALL_NOT_IMPLEMENTED
;
355 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
357 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
358 UINT r
= ERROR_FUNCTION_FAILED
; /* FIXME: check return code */
360 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
364 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, NULL
, 0 );
365 szwPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
368 MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, szwPath
, len
);
373 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, NULL
, 0 );
374 szwCommand
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
377 MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, szwCommand
, len
);
380 r
= MsiInstallProductW( szwPath
, szwCommand
);
384 HeapFree( GetProcessHeap(), 0, szwPath
);
387 HeapFree( GetProcessHeap(), 0, szwCommand
);
392 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
394 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
396 return ERROR_CALL_NOT_IMPLEMENTED
;
399 UINT WINAPI
MsiConfigureProductA(
400 LPCSTR szProduct
, int iInstallLevel
, INSTALLSTATE eInstallState
)
402 FIXME("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
403 return ERROR_CALL_NOT_IMPLEMENTED
;
406 UINT WINAPI
MsiConfigureProductW(
407 LPCWSTR szProduct
, int iInstallLevel
, INSTALLSTATE eInstallState
)
409 FIXME("%s %d %d\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
410 return ERROR_CALL_NOT_IMPLEMENTED
;
413 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
415 FIXME("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
416 return ERROR_CALL_NOT_IMPLEMENTED
;
419 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
421 FIXME("%s %s\n",debugstr_w(szComponent
), debugstr_w(szBuffer
));
422 return ERROR_CALL_NOT_IMPLEMENTED
;
425 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
, LPSTR szBuffer
, DWORD
*pcchValueBuf
)
427 FIXME("%s %s %p %p\n",debugstr_a(szProduct
), debugstr_a(szAttribute
), szBuffer
, pcchValueBuf
);
428 return ERROR_CALL_NOT_IMPLEMENTED
;
431 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
, LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
433 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
), szBuffer
, pcchValueBuf
);
434 return ERROR_CALL_NOT_IMPLEMENTED
;
437 UINT WINAPI
MsiDatabaseImportA(LPCSTR szFolderPath
, LPCSTR szFilename
)
439 FIXME("%s %s\n",debugstr_a(szFolderPath
), debugstr_a(szFilename
));
440 return ERROR_CALL_NOT_IMPLEMENTED
;
443 UINT WINAPI
MsiDatabaseImportW(LPCWSTR szFolderPath
, LPCWSTR szFilename
)
445 FIXME("%s %s\n",debugstr_w(szFolderPath
), debugstr_w(szFilename
));
446 return ERROR_CALL_NOT_IMPLEMENTED
;
449 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, BOOL fAppend
)
451 FIXME("%08lx %s %d\n", dwLogMode
, debugstr_a(szLogFile
), fAppend
);
452 return ERROR_SUCCESS
;
453 /* return ERROR_CALL_NOT_IMPLEMENTED; */
456 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, BOOL fAppend
)
458 FIXME("%08lx %s %d\n", dwLogMode
, debugstr_w(szLogFile
), fAppend
);
459 return ERROR_CALL_NOT_IMPLEMENTED
;
462 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
464 FIXME("%s\n", debugstr_a(szProduct
));
468 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
470 FIXME("%s\n", debugstr_w(szProduct
));
474 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
476 FIXME("%08x %p\n", dwUILevel
, phWnd
);
480 UINT WINAPI
MsiLoadStringA(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
482 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
483 return ERROR_CALL_NOT_IMPLEMENTED
;
486 UINT WINAPI
MsiLoadStringW(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
488 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
489 return ERROR_CALL_NOT_IMPLEMENTED
;
492 UINT WINAPI
MsiMessageBoxA(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
494 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
495 return ERROR_CALL_NOT_IMPLEMENTED
;
498 UINT WINAPI
MsiMessageBoxW(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
500 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
501 return ERROR_CALL_NOT_IMPLEMENTED
;
504 UINT WINAPI
MsiEnumProductsA(DWORD index
, LPSTR lpguid
)
507 WCHAR szwGuid
[GUID_SIZE
];
509 TRACE("%ld %p\n",index
,lpguid
);
511 r
= MsiEnumProductsW(index
, szwGuid
);
512 if( r
== ERROR_SUCCESS
)
513 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
518 UINT WINAPI
MsiEnumProductsW(DWORD index
, LPWSTR lpguid
)
520 HKEY hkey
= 0, hkeyFeatures
= 0;
524 TRACE("%ld %p\n",index
,lpguid
);
526 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
527 if( r
!= ERROR_SUCCESS
)
530 r
= RegOpenKeyW(hkey
, szFeatures
, &hkeyFeatures
);
531 if( r
!= ERROR_SUCCESS
)
534 r
= RegEnumKeyW(hkeyFeatures
, index
, szKeyName
, GUID_SIZE
);
536 unsquash_guid(szKeyName
, lpguid
);
541 RegCloseKey(hkeyFeatures
);
548 UINT WINAPI
MsiEnumFeaturesA(LPCSTR szProduct
, DWORD index
,
549 LPSTR szFeature
, LPSTR szParent
)
552 WCHAR szwFeature
[GUID_SIZE
], szwParent
[GUID_SIZE
];
553 LPWSTR szwProduct
= NULL
;
555 TRACE("%s %ld %p %p\n",debugstr_a(szProduct
),index
,szFeature
,szParent
);
559 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
560 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
562 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
564 return ERROR_FUNCTION_FAILED
;
567 r
= MsiEnumFeaturesW(szwProduct
, index
, szwFeature
, szwParent
);
568 if( r
== ERROR_SUCCESS
)
570 WideCharToMultiByte(CP_ACP
, 0, szwFeature
, -1,
571 szFeature
, GUID_SIZE
, NULL
, NULL
);
572 WideCharToMultiByte(CP_ACP
, 0, szwParent
, -1,
573 szParent
, GUID_SIZE
, NULL
, NULL
);
577 HeapFree( GetProcessHeap(), 0, szwProduct
);
582 UINT WINAPI
MsiEnumFeaturesW(LPCWSTR szProduct
, DWORD index
,
583 LPWSTR szFeature
, LPWSTR szParent
)
585 HKEY hkey
= 0, hkeyFeatures
= 0, hkeyProduct
= 0;
587 WCHAR szRegName
[GUID_SIZE
];
589 TRACE("%s %ld %p %p\n",debugstr_w(szProduct
),index
,szFeature
,szParent
);
591 if( !squash_guid(szProduct
, szRegName
) )
592 return ERROR_INVALID_PARAMETER
;
594 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
595 if( r
!= ERROR_SUCCESS
)
598 r
= RegOpenKeyW(hkey
, szFeatures
, &hkeyFeatures
);
599 if( r
!= ERROR_SUCCESS
)
602 r
= RegOpenKeyW(hkeyFeatures
, szRegName
, &hkeyProduct
);
603 if( r
!= ERROR_SUCCESS
)
607 r
= RegEnumValueW(hkeyProduct
, index
, szFeature
, &sz
, NULL
, NULL
, NULL
, NULL
);
611 RegCloseKey(hkeyProduct
);
613 RegCloseKey(hkeyFeatures
);
620 UINT WINAPI
MsiEnumComponentsA(DWORD index
, LPSTR lpguid
)
623 WCHAR szwGuid
[GUID_SIZE
];
625 TRACE("%ld %p\n",index
,lpguid
);
627 r
= MsiEnumComponentsW(index
, szwGuid
);
628 if( r
== ERROR_SUCCESS
)
629 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
634 UINT WINAPI
MsiEnumComponentsW(DWORD index
, LPWSTR lpguid
)
636 HKEY hkey
= 0, hkeyComponents
= 0;
640 TRACE("%ld %p\n",index
,lpguid
);
642 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
643 if( r
!= ERROR_SUCCESS
)
646 r
= RegOpenKeyW(hkey
, szComponents
, &hkeyComponents
);
647 if( r
!= ERROR_SUCCESS
)
650 r
= RegEnumKeyW(hkeyComponents
, index
, szKeyName
, GUID_SIZE
);
652 unsquash_guid(szKeyName
, lpguid
);
657 RegCloseKey(hkeyComponents
);
664 UINT WINAPI
MsiEnumClientsA(LPCSTR szComponent
, DWORD index
, LPSTR szProduct
)
667 WCHAR szwProduct
[GUID_SIZE
];
668 LPWSTR szwComponent
= NULL
;
670 TRACE("%s %ld %p\n",debugstr_a(szComponent
),index
,szProduct
);
674 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
675 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
677 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
679 return ERROR_FUNCTION_FAILED
;
682 r
= MsiEnumClientsW(szComponent
?szwComponent
:NULL
, index
, szwProduct
);
683 if( r
== ERROR_SUCCESS
)
685 WideCharToMultiByte(CP_ACP
, 0, szwProduct
, -1,
686 szProduct
, GUID_SIZE
, NULL
, NULL
);
690 HeapFree( GetProcessHeap(), 0, szwComponent
);
695 UINT WINAPI
MsiEnumClientsW(LPCWSTR szComponent
, DWORD index
, LPWSTR szProduct
)
697 HKEY hkey
= 0, hkeyComponents
= 0, hkeyComp
= 0;
699 WCHAR szRegName
[GUID_SIZE
], szValName
[GUID_SIZE
];
701 TRACE("%s %ld %p\n",debugstr_w(szComponent
),index
,szProduct
);
703 if( !squash_guid(szComponent
, szRegName
) )
704 return ERROR_INVALID_PARAMETER
;
706 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
707 if( r
!= ERROR_SUCCESS
)
710 r
= RegOpenKeyW(hkey
, szComponents
, &hkeyComponents
);
711 if( r
!= ERROR_SUCCESS
)
714 r
= RegOpenKeyW(hkeyComponents
, szRegName
, &hkeyComp
);
715 if( r
!= ERROR_SUCCESS
)
719 r
= RegEnumValueW(hkeyComp
, index
, szValName
, &sz
, NULL
, NULL
, NULL
, NULL
);
720 if( r
!= ERROR_SUCCESS
)
723 unsquash_guid(szValName
, szProduct
);
727 RegCloseKey(hkeyComp
);
729 RegCloseKey(hkeyComponents
);
736 UINT WINAPI
MsiEnumComponentQualifiersA(
737 LPSTR szComponent
, DWORD iIndex
, LPSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
, LPSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
739 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_a(szComponent
), iIndex
, lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
, pcchApplicationDataBuf
);
740 return ERROR_CALL_NOT_IMPLEMENTED
;
743 UINT WINAPI
MsiEnumComponentQualifiersW(
744 LPWSTR szComponent
, DWORD iIndex
, LPWSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
, LPWSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
746 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_w(szComponent
), iIndex
, lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
, pcchApplicationDataBuf
);
747 return ERROR_CALL_NOT_IMPLEMENTED
;
750 UINT WINAPI
MsiProvideAssemblyA(
751 LPCSTR szAssemblyName
, LPCSTR szAppContext
, DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
, DWORD
* pcchPathBuf
)
753 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
754 debugstr_a(szAssemblyName
), debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
, pcchPathBuf
);
755 return ERROR_CALL_NOT_IMPLEMENTED
;
758 UINT WINAPI
MsiProvideAssemblyW(
759 LPCWSTR szAssemblyName
, LPCWSTR szAppContext
, DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
, DWORD
* pcchPathBuf
)
761 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
762 debugstr_w(szAssemblyName
), debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
, pcchPathBuf
);
763 return ERROR_CALL_NOT_IMPLEMENTED
;
766 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
, LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
768 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
769 return ERROR_CALL_NOT_IMPLEMENTED
;
772 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
, LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
774 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
775 return ERROR_CALL_NOT_IMPLEMENTED
;
778 HRESULT WINAPI
MsiGetFileSignatureInformationA(
779 LPCSTR szSignedObjectPath
, DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
, DWORD
* pcbHashData
)
781 FIXME("%s 0x%08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
, ppcCertContext
, pbHashData
, pcbHashData
);
782 return ERROR_CALL_NOT_IMPLEMENTED
;
785 HRESULT WINAPI
MsiGetFileSignatureInformationW(
786 LPCWSTR szSignedObjectPath
, DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
, DWORD
* pcbHashData
)
788 FIXME("%s 0x%08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
, ppcCertContext
, pbHashData
, pcbHashData
);
789 return ERROR_CALL_NOT_IMPLEMENTED
;
792 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
793 LPSTR szValue
, DWORD
*pccbValue
)
795 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
796 return ERROR_CALL_NOT_IMPLEMENTED
;
799 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
800 LPWSTR szValue
, DWORD
*pccbValue
)
802 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
803 return ERROR_CALL_NOT_IMPLEMENTED
;
806 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
808 FIXME("%s\n", debugstr_a(szPackage
) );
809 return ERROR_CALL_NOT_IMPLEMENTED
;
812 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
814 FIXME("%s\n", debugstr_w(szPackage
) );
815 return ERROR_CALL_NOT_IMPLEMENTED
;
818 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
822 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
825 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
826 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
827 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
828 pdvi
->dwPlatformID
= 1;
833 BOOL WINAPI
MSI_DllCanUnloadNow(void)
838 HRESULT WINAPI
MSI_DllRegisterServer(void)