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
);
40 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
41 * which is a problem because LPCTSTR isn't defined when compiling wine.
42 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
43 * and make sure to only use it in W functions.
45 #define LPCTSTR LPCWSTR
47 const WCHAR szInstaller
[] = {
48 'S','o','f','t','w','a','r','e','\\',
49 'M','i','c','r','o','s','o','f','t','\\',
50 'W','i','n','d','o','w','s','\\',
51 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
52 'I','n','s','t','a','l','l','e','r',0 };
54 const WCHAR szFeatures
[] = {
55 'F','e','a','t','u','r','e','s',0 };
56 const WCHAR szComponents
[] = {
57 'C','o','m','p','o','n','e','n','t','s',0 };
62 * A .msi file is a structured storage file.
63 * It should contain a number of streams.
66 BOOL
unsquash_guid(LPCWSTR in
, LPWSTR out
)
82 out
[n
++] = in
[17+i
*2];
83 out
[n
++] = in
[16+i
*2];
88 out
[n
++] = in
[17+i
*2];
89 out
[n
++] = in
[16+i
*2];
96 BOOL
squash_guid(LPCWSTR in
, LPWSTR out
)
116 out
[17+i
*2] = in
[n
++];
117 out
[16+i
*2] = in
[n
++];
123 out
[17+i
*2] = in
[n
++];
124 out
[16+i
*2] = in
[n
++];
134 VOID
MSI_CloseDatabase( VOID
*arg
)
136 MSIDATABASE
*db
= (MSIDATABASE
*) arg
;
138 free_cached_tables( db
);
139 IStorage_Release( db
->storage
);
142 UINT WINAPI
MsiOpenDatabaseA(
143 LPCSTR szDBPath
, LPCSTR szPersist
, MSIHANDLE
*phDB
)
145 HRESULT r
= ERROR_FUNCTION_FAILED
;
146 LPWSTR szwDBPath
= NULL
, szwPersist
= NULL
;
149 TRACE("%s %s %p\n", debugstr_a(szDBPath
), debugstr_a(szPersist
), phDB
);
153 len
= MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, NULL
, 0 );
154 szwDBPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
157 MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, szwDBPath
, len
);
160 if( HIWORD(szPersist
) )
162 len
= MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, NULL
, 0 );
163 szwPersist
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
166 MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, szwPersist
, len
);
169 szwPersist
= (LPWSTR
) szPersist
;
171 r
= MsiOpenDatabaseW( szwDBPath
, szwPersist
, phDB
);
175 HeapFree( GetProcessHeap(), 0, szwPersist
);
177 HeapFree( GetProcessHeap(), 0, szwDBPath
);
182 UINT WINAPI
MsiOpenDatabaseW(
183 LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIHANDLE
*phDB
)
185 IStorage
*stg
= NULL
;
192 TRACE("%s %s %p\n",debugstr_w(szDBPath
),debugstr_w(szPersist
), phDB
);
195 return ERROR_INVALID_PARAMETER
;
197 szMode
= (LPWSTR
) szPersist
;
198 if( HIWORD( szPersist
) )
200 /* UINT len = lstrlenW( szPerist ) + 1; */
201 FIXME("don't support persist files yet\b");
202 return ERROR_INVALID_PARAMETER
;
203 /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
205 else if( szPersist
== MSIDBOPEN_READONLY
)
207 r
= StgOpenStorage( szDBPath
, NULL
,
208 STGM_DIRECT
|STGM_READ
|STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
210 else if( szPersist
== MSIDBOPEN_CREATE
)
212 r
= StgCreateDocfile( szDBPath
,
213 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, 0, &stg
);
214 if( r
== ERROR_SUCCESS
)
215 r
= init_string_table( stg
);
217 else if( szPersist
== MSIDBOPEN_TRANSACT
)
219 r
= StgOpenStorage( szDBPath
, NULL
,
220 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
224 ERR("unknown flag %p\n",szPersist
);
225 return ERROR_INVALID_PARAMETER
;
230 FIXME("open failed r = %08lx!\n",r
);
231 return ERROR_FUNCTION_FAILED
;
234 handle
= alloc_msihandle( MSIHANDLETYPE_DATABASE
, sizeof (MSIDATABASE
),
235 MSI_CloseDatabase
, (void**) &db
);
238 FIXME("Failed to allocate a handle\n");
239 ret
= ERROR_FUNCTION_FAILED
;
245 /* db->strings = NULL;
246 db->first_table = NULL;
247 db->last_table = NULL; */
249 ret
= load_string_table( db
);
250 if( ret
!= ERROR_SUCCESS
)
255 IStorage_AddRef( stg
);
258 IStorage_Release( stg
);
263 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
266 LPWSTR szwProd
= NULL
;
268 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
272 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
273 szwProd
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
275 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProd
, len
);
278 ret
= MsiOpenProductW( szwProd
, phProduct
);
281 HeapFree( GetProcessHeap(), 0, szwProd
);
286 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
288 const WCHAR szKey
[] = {
289 'S','o','f','t','w','a','r','e','\\',
290 'M','i','c','r','o','s','o','f','t','\\',
291 'W','i','n','d','o','w','s','\\',
292 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
293 'U','n','i','n','s','t','a','l','l',0 };
294 const WCHAR szLocalPackage
[] = {
295 'L','o','c','a','l','P','a','c','k','a','g','e', 0
299 HKEY hKeyProduct
= NULL
, hKeyUninstall
= NULL
;
302 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
304 r
= RegOpenKeyW( HKEY_LOCAL_MACHINE
, szKey
, &hKeyUninstall
);
305 if( r
!= ERROR_SUCCESS
)
308 r
= RegOpenKeyW( hKeyUninstall
, szProduct
, &hKeyProduct
);
309 if( r
!= ERROR_SUCCESS
)
312 /* find the size of the path */
314 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
315 NULL
, &type
, NULL
, &count
);
316 if( r
!= ERROR_SUCCESS
)
319 /* now alloc and fetch the path of the database to open */
320 path
= HeapAlloc( GetProcessHeap(), 0, count
);
324 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
325 NULL
, &type
, (LPBYTE
) path
, &count
);
326 if( r
!= ERROR_SUCCESS
)
329 r
= MsiOpenPackageW( path
, phProduct
);
333 HeapFree( GetProcessHeap(), 0, path
);
335 RegCloseKey( hKeyProduct
);
336 RegCloseKey( hKeyUninstall
);
341 UINT WINAPI
MsiOpenPackageA(LPCSTR szPackage
, MSIHANDLE
*phPackage
)
343 FIXME("%s %p\n",debugstr_a(szPackage
), phPackage
);
344 return ERROR_CALL_NOT_IMPLEMENTED
;
347 UINT WINAPI
MsiOpenPackageW(LPCWSTR szPackage
, MSIHANDLE
*phPackage
)
349 FIXME("%s %p\n",debugstr_w(szPackage
), phPackage
);
350 return ERROR_CALL_NOT_IMPLEMENTED
;
353 UINT WINAPI
MsiOpenPackageExA(LPCSTR szPackage
, DWORD dwOptions
, MSIHANDLE
*phPackage
)
355 FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage
), dwOptions
, phPackage
);
356 return ERROR_CALL_NOT_IMPLEMENTED
;
359 UINT WINAPI
MsiOpenPackageExW(LPCWSTR szPackage
, DWORD dwOptions
, MSIHANDLE
*phPackage
)
361 FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage
), dwOptions
, phPackage
);
362 return ERROR_CALL_NOT_IMPLEMENTED
;
365 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
, LPCSTR szTransforms
, LANGID lgidLanguage
)
367 FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath
), debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
368 return ERROR_CALL_NOT_IMPLEMENTED
;
371 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
, LPCWSTR szTransforms
, LANGID lgidLanguage
)
373 FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath
), debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
374 return ERROR_CALL_NOT_IMPLEMENTED
;
377 UINT WINAPI
MsiAdvertiseProductExA(
378 LPCSTR szPackagePath
, LPCSTR szScriptfilePath
, LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
380 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
381 debugstr_a(szPackagePath
), debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
, dwPlatform
, dwOptions
);
382 return ERROR_CALL_NOT_IMPLEMENTED
;
385 UINT WINAPI
MsiAdvertiseProductExW(
386 LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
, LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
388 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
389 debugstr_w(szPackagePath
), debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
, dwPlatform
, dwOptions
);
390 return ERROR_CALL_NOT_IMPLEMENTED
;
393 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
395 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
396 UINT r
= ERROR_FUNCTION_FAILED
; /* FIXME: check return code */
398 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
402 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, NULL
, 0 );
403 szwPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
406 MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, szwPath
, len
);
411 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, NULL
, 0 );
412 szwCommand
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
415 MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, szwCommand
, len
);
418 r
= MsiInstallProductW( szwPath
, szwCommand
);
422 HeapFree( GetProcessHeap(), 0, szwPath
);
425 HeapFree( GetProcessHeap(), 0, szwCommand
);
430 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
432 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
434 return ERROR_CALL_NOT_IMPLEMENTED
;
437 UINT WINAPI
MsiConfigureProductA(
438 LPCSTR szProduct
, int iInstallLevel
, INSTALLSTATE eInstallState
)
440 FIXME("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
441 return ERROR_CALL_NOT_IMPLEMENTED
;
444 UINT WINAPI
MsiConfigureProductW(
445 LPCWSTR szProduct
, int iInstallLevel
, INSTALLSTATE eInstallState
)
447 FIXME("%s %d %d\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
448 return ERROR_CALL_NOT_IMPLEMENTED
;
451 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
453 FIXME("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
454 return ERROR_CALL_NOT_IMPLEMENTED
;
457 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
459 FIXME("%s %s\n",debugstr_w(szComponent
), debugstr_w(szBuffer
));
460 return ERROR_CALL_NOT_IMPLEMENTED
;
463 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
, LPSTR szBuffer
, DWORD
*pcchValueBuf
)
465 FIXME("%s %s %p %p\n",debugstr_a(szProduct
), debugstr_a(szAttribute
), szBuffer
, pcchValueBuf
);
466 return ERROR_CALL_NOT_IMPLEMENTED
;
469 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
, LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
471 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
), szBuffer
, pcchValueBuf
);
472 return ERROR_CALL_NOT_IMPLEMENTED
;
475 UINT WINAPI
MsiDatabaseImportA(LPCSTR szFolderPath
, LPCSTR szFilename
)
477 FIXME("%s %s\n",debugstr_a(szFolderPath
), debugstr_a(szFilename
));
478 return ERROR_CALL_NOT_IMPLEMENTED
;
481 UINT WINAPI
MsiDatabaseImportW(LPCWSTR szFolderPath
, LPCWSTR szFilename
)
483 FIXME("%s %s\n",debugstr_w(szFolderPath
), debugstr_w(szFilename
));
484 return ERROR_CALL_NOT_IMPLEMENTED
;
487 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, BOOL fAppend
)
489 FIXME("%08lx %s %d\n", dwLogMode
, debugstr_a(szLogFile
), fAppend
);
490 return ERROR_SUCCESS
;
491 /* return ERROR_CALL_NOT_IMPLEMENTED; */
494 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, BOOL fAppend
)
496 FIXME("%08lx %s %d\n", dwLogMode
, debugstr_w(szLogFile
), fAppend
);
497 return ERROR_CALL_NOT_IMPLEMENTED
;
500 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
502 FIXME("%s\n", debugstr_a(szProduct
));
503 return INSTALLSTATE_UNKNOWN
;
506 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
508 FIXME("%s\n", debugstr_w(szProduct
));
509 return INSTALLSTATE_UNKNOWN
;
512 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
514 FIXME("%08x %p\n", dwUILevel
, phWnd
);
518 UINT WINAPI
MsiLoadStringA(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
520 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
521 return ERROR_CALL_NOT_IMPLEMENTED
;
524 UINT WINAPI
MsiLoadStringW(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
526 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
527 return ERROR_CALL_NOT_IMPLEMENTED
;
530 UINT WINAPI
MsiMessageBoxA(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
532 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
533 return ERROR_CALL_NOT_IMPLEMENTED
;
536 UINT WINAPI
MsiMessageBoxW(DWORD a
, DWORD b
, DWORD c
, DWORD d
, DWORD e
, DWORD f
)
538 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a
,b
,c
,d
,e
,f
);
539 return ERROR_CALL_NOT_IMPLEMENTED
;
542 UINT WINAPI
MsiEnumProductsA(DWORD index
, LPSTR lpguid
)
545 WCHAR szwGuid
[GUID_SIZE
];
547 TRACE("%ld %p\n",index
,lpguid
);
549 r
= MsiEnumProductsW(index
, szwGuid
);
550 if( r
== ERROR_SUCCESS
)
551 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
556 UINT WINAPI
MsiEnumProductsW(DWORD index
, LPWSTR lpguid
)
558 HKEY hkey
= 0, hkeyFeatures
= 0;
562 TRACE("%ld %p\n",index
,lpguid
);
564 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
565 if( r
!= ERROR_SUCCESS
)
568 r
= RegOpenKeyW(hkey
, szFeatures
, &hkeyFeatures
);
569 if( r
!= ERROR_SUCCESS
)
572 r
= RegEnumKeyW(hkeyFeatures
, index
, szKeyName
, GUID_SIZE
);
574 unsquash_guid(szKeyName
, lpguid
);
579 RegCloseKey(hkeyFeatures
);
586 UINT WINAPI
MsiEnumFeaturesA(LPCSTR szProduct
, DWORD index
,
587 LPSTR szFeature
, LPSTR szParent
)
590 WCHAR szwFeature
[GUID_SIZE
], szwParent
[GUID_SIZE
];
591 LPWSTR szwProduct
= NULL
;
593 TRACE("%s %ld %p %p\n",debugstr_a(szProduct
),index
,szFeature
,szParent
);
597 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
598 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
600 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
602 return ERROR_FUNCTION_FAILED
;
605 r
= MsiEnumFeaturesW(szwProduct
, index
, szwFeature
, szwParent
);
606 if( r
== ERROR_SUCCESS
)
608 WideCharToMultiByte(CP_ACP
, 0, szwFeature
, -1,
609 szFeature
, GUID_SIZE
, NULL
, NULL
);
610 WideCharToMultiByte(CP_ACP
, 0, szwParent
, -1,
611 szParent
, GUID_SIZE
, NULL
, NULL
);
615 HeapFree( GetProcessHeap(), 0, szwProduct
);
620 UINT WINAPI
MsiEnumFeaturesW(LPCWSTR szProduct
, DWORD index
,
621 LPWSTR szFeature
, LPWSTR szParent
)
623 HKEY hkey
= 0, hkeyFeatures
= 0, hkeyProduct
= 0;
625 WCHAR szRegName
[GUID_SIZE
];
627 TRACE("%s %ld %p %p\n",debugstr_w(szProduct
),index
,szFeature
,szParent
);
629 if( !squash_guid(szProduct
, szRegName
) )
630 return ERROR_INVALID_PARAMETER
;
632 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
633 if( r
!= ERROR_SUCCESS
)
636 r
= RegOpenKeyW(hkey
, szFeatures
, &hkeyFeatures
);
637 if( r
!= ERROR_SUCCESS
)
640 r
= RegOpenKeyW(hkeyFeatures
, szRegName
, &hkeyProduct
);
641 if( r
!= ERROR_SUCCESS
)
645 r
= RegEnumValueW(hkeyProduct
, index
, szFeature
, &sz
, NULL
, NULL
, NULL
, NULL
);
649 RegCloseKey(hkeyProduct
);
651 RegCloseKey(hkeyFeatures
);
658 UINT WINAPI
MsiEnumComponentsA(DWORD index
, LPSTR lpguid
)
661 WCHAR szwGuid
[GUID_SIZE
];
663 TRACE("%ld %p\n",index
,lpguid
);
665 r
= MsiEnumComponentsW(index
, szwGuid
);
666 if( r
== ERROR_SUCCESS
)
667 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
672 UINT WINAPI
MsiEnumComponentsW(DWORD index
, LPWSTR lpguid
)
674 HKEY hkey
= 0, hkeyComponents
= 0;
678 TRACE("%ld %p\n",index
,lpguid
);
680 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
681 if( r
!= ERROR_SUCCESS
)
684 r
= RegOpenKeyW(hkey
, szComponents
, &hkeyComponents
);
685 if( r
!= ERROR_SUCCESS
)
688 r
= RegEnumKeyW(hkeyComponents
, index
, szKeyName
, GUID_SIZE
);
690 unsquash_guid(szKeyName
, lpguid
);
695 RegCloseKey(hkeyComponents
);
702 UINT WINAPI
MsiEnumClientsA(LPCSTR szComponent
, DWORD index
, LPSTR szProduct
)
705 WCHAR szwProduct
[GUID_SIZE
];
706 LPWSTR szwComponent
= NULL
;
708 TRACE("%s %ld %p\n",debugstr_a(szComponent
),index
,szProduct
);
712 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
713 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
715 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
717 return ERROR_FUNCTION_FAILED
;
720 r
= MsiEnumClientsW(szComponent
?szwComponent
:NULL
, index
, szwProduct
);
721 if( r
== ERROR_SUCCESS
)
723 WideCharToMultiByte(CP_ACP
, 0, szwProduct
, -1,
724 szProduct
, GUID_SIZE
, NULL
, NULL
);
728 HeapFree( GetProcessHeap(), 0, szwComponent
);
733 UINT WINAPI
MsiEnumClientsW(LPCWSTR szComponent
, DWORD index
, LPWSTR szProduct
)
735 HKEY hkey
= 0, hkeyComponents
= 0, hkeyComp
= 0;
737 WCHAR szRegName
[GUID_SIZE
], szValName
[GUID_SIZE
];
739 TRACE("%s %ld %p\n",debugstr_w(szComponent
),index
,szProduct
);
741 if( !squash_guid(szComponent
, szRegName
) )
742 return ERROR_INVALID_PARAMETER
;
744 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
745 if( r
!= ERROR_SUCCESS
)
748 r
= RegOpenKeyW(hkey
, szComponents
, &hkeyComponents
);
749 if( r
!= ERROR_SUCCESS
)
752 r
= RegOpenKeyW(hkeyComponents
, szRegName
, &hkeyComp
);
753 if( r
!= ERROR_SUCCESS
)
757 r
= RegEnumValueW(hkeyComp
, index
, szValName
, &sz
, NULL
, NULL
, NULL
, NULL
);
758 if( r
!= ERROR_SUCCESS
)
761 unsquash_guid(szValName
, szProduct
);
765 RegCloseKey(hkeyComp
);
767 RegCloseKey(hkeyComponents
);
774 UINT WINAPI
MsiEnumComponentQualifiersA(
775 LPSTR szComponent
, DWORD iIndex
, LPSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
, LPSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
777 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_a(szComponent
), iIndex
, lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
, pcchApplicationDataBuf
);
778 return ERROR_CALL_NOT_IMPLEMENTED
;
781 UINT WINAPI
MsiEnumComponentQualifiersW(
782 LPWSTR szComponent
, DWORD iIndex
, LPWSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
, LPWSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
784 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_w(szComponent
), iIndex
, lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
, pcchApplicationDataBuf
);
785 return ERROR_CALL_NOT_IMPLEMENTED
;
788 UINT WINAPI
MsiProvideAssemblyA(
789 LPCSTR szAssemblyName
, LPCSTR szAppContext
, DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
, DWORD
* pcchPathBuf
)
791 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
792 debugstr_a(szAssemblyName
), debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
, pcchPathBuf
);
793 return ERROR_CALL_NOT_IMPLEMENTED
;
796 UINT WINAPI
MsiProvideAssemblyW(
797 LPCWSTR szAssemblyName
, LPCWSTR szAppContext
, DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
, DWORD
* pcchPathBuf
)
799 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
800 debugstr_w(szAssemblyName
), debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
, pcchPathBuf
);
801 return ERROR_CALL_NOT_IMPLEMENTED
;
804 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
, LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
806 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
807 return ERROR_CALL_NOT_IMPLEMENTED
;
810 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
, LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
812 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
813 return ERROR_CALL_NOT_IMPLEMENTED
;
816 HRESULT WINAPI
MsiGetFileSignatureInformationA(
817 LPCSTR szSignedObjectPath
, DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
, DWORD
* pcbHashData
)
819 FIXME("%s 0x%08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
, ppcCertContext
, pbHashData
, pcbHashData
);
820 return ERROR_CALL_NOT_IMPLEMENTED
;
823 HRESULT WINAPI
MsiGetFileSignatureInformationW(
824 LPCWSTR szSignedObjectPath
, DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
, DWORD
* pcbHashData
)
826 FIXME("%s 0x%08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
, ppcCertContext
, pbHashData
, pcbHashData
);
827 return ERROR_CALL_NOT_IMPLEMENTED
;
830 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
831 LPSTR szValue
, DWORD
*pccbValue
)
833 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
834 return ERROR_CALL_NOT_IMPLEMENTED
;
837 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
838 LPWSTR szValue
, DWORD
*pccbValue
)
840 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
841 return ERROR_CALL_NOT_IMPLEMENTED
;
844 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
846 FIXME("%s\n", debugstr_a(szPackage
) );
847 return ERROR_CALL_NOT_IMPLEMENTED
;
850 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
852 FIXME("%s\n", debugstr_w(szPackage
) );
853 return ERROR_CALL_NOT_IMPLEMENTED
;
856 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
860 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
863 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
864 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
865 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
866 pdvi
->dwPlatformID
= 1;
871 BOOL WINAPI
MSI_DllCanUnloadNow(void)
876 HRESULT WINAPI
MSI_DllRegisterServer(void)