2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004 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"
36 #include "wine/unicode.h"
41 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
44 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
45 * which is a problem because LPCTSTR isn't defined when compiling wine.
46 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
47 * and make sure to only use it in W functions.
49 #define LPCTSTR LPCWSTR
51 DEFINE_GUID( CLSID_MsiDatabase
, 0x000c1084, 0x0000, 0x0000, 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
53 static const WCHAR szInstaller
[] = {
54 'S','o','f','t','w','a','r','e','\\',
55 'M','i','c','r','o','s','o','f','t','\\',
56 'W','i','n','d','o','w','s','\\',
57 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
58 'I','n','s','t','a','l','l','e','r',0 };
60 static const WCHAR szFeatures
[] = {
61 'F','e','a','t','u','r','e','s',0 };
62 static const WCHAR szComponents
[] = {
63 'C','o','m','p','o','n','e','n','t','s',0 };
66 INSTALLUILEVEL gUILevel
;
68 INSTALLUI_HANDLERA gUIHandler
;
71 WCHAR gszLogFile
[MAX_PATH
];
76 * A .msi file is a structured storage file.
77 * It should contain a number of streams.
80 BOOL
unsquash_guid(LPCWSTR in
, LPWSTR out
)
96 out
[n
++] = in
[17+i
*2];
97 out
[n
++] = in
[16+i
*2];
102 out
[n
++] = in
[17+i
*2];
103 out
[n
++] = in
[16+i
*2];
110 BOOL
squash_guid(LPCWSTR in
, LPWSTR out
)
130 out
[17+i
*2] = in
[n
++];
131 out
[16+i
*2] = in
[n
++];
137 out
[17+i
*2] = in
[n
++];
138 out
[16+i
*2] = in
[n
++];
148 /* tables for encoding and decoding base85 */
149 static const unsigned char table_dec85
[0x80] = {
150 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
151 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
152 0xff,0x00,0xff,0xff,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0xff,
153 0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0xff,0xff,0xff,0x16,0xff,0x17,
154 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
155 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x30,0x31,0x32,0x33,0xff,0x34,0x35,0x36,
156 0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,0x40,0x41,0x42,0x43,0x44,0x45,0x46,
157 0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,0x50,0x51,0x52,0xff,0x53,0x54,0xff,
160 static const char table_enc85
[] =
161 "!$%&'()*+,-.0123456789=?@ABCDEFGHIJKLMNO"
162 "PQRSTUVWXYZ[]^_`abcdefghijklmnopqrstuvwx"
166 * Converts a base85 encoded guid into a GUID pointer
167 * Base85 encoded GUIDs should be 20 characters long.
169 * returns TRUE if successful, FALSE if not
171 BOOL
decode_base85_guid( LPCWSTR str
, GUID
*guid
)
173 DWORD i
, val
= 0, base
= 1, *p
;
176 for( i
=0; i
<20; i
++ )
183 val
+= table_dec85
[str
[i
]] * base
;
186 if( table_dec85
[str
[i
]] == 0xff )
196 * Encodes a base85 guid given a GUID pointer
197 * Caller should provide a 21 character buffer for the encoded string.
199 * returns TRUE if successful, FALSE if not
201 BOOL
encode_base85_guid( GUID
*guid
, LPWSTR str
)
203 unsigned int x
, *p
, i
;
205 p
= (unsigned int*) guid
;
209 *str
++ = table_enc85
[x
%85];
211 *str
++ = table_enc85
[x
%85];
213 *str
++ = table_enc85
[x
%85];
215 *str
++ = table_enc85
[x
%85];
217 *str
++ = table_enc85
[x
%85];
225 VOID
MSI_CloseDatabase( MSIOBJECTHDR
*arg
)
227 MSIDATABASE
*db
= (MSIDATABASE
*) arg
;
229 free_cached_tables( db
);
230 IStorage_Release( db
->storage
);
233 UINT
MSI_OpenDatabaseW(LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIDATABASE
**pdb
)
235 IStorage
*stg
= NULL
;
237 MSIDATABASE
*db
= NULL
;
238 UINT ret
= ERROR_FUNCTION_FAILED
;
242 TRACE("%s %s\n",debugstr_w(szDBPath
),debugstr_w(szPersist
) );
245 return ERROR_INVALID_PARAMETER
;
247 szMode
= (LPWSTR
) szPersist
;
248 if( HIWORD( szPersist
) )
250 /* UINT len = lstrlenW( szPerist ) + 1; */
251 FIXME("don't support persist files yet\b");
252 return ERROR_INVALID_PARAMETER
;
253 /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
255 else if( szPersist
== MSIDBOPEN_READONLY
)
257 r
= StgOpenStorage( szDBPath
, NULL
,
258 STGM_DIRECT
|STGM_READ
|STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
260 else if( szPersist
== MSIDBOPEN_CREATE
)
262 r
= StgCreateDocfile( szDBPath
,
263 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, 0, &stg
);
264 if( r
== ERROR_SUCCESS
)
266 IStorage_SetClass( stg
, &CLSID_MsiDatabase
);
267 r
= init_string_table( stg
);
270 else if( szPersist
== MSIDBOPEN_TRANSACT
)
272 r
= StgOpenStorage( szDBPath
, NULL
,
273 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
277 ERR("unknown flag %p\n",szPersist
);
278 return ERROR_INVALID_PARAMETER
;
283 FIXME("open failed r = %08lx!\n",r
);
284 return ERROR_FUNCTION_FAILED
;
287 r
= IStorage_Stat( stg
, &stat
, STATFLAG_NONAME
);
290 FIXME("Failed to stat storage\n");
294 if( memcmp( &stat
.clsid
, &CLSID_MsiDatabase
, sizeof (GUID
) ) )
296 ERR("storage GUID is not a MSI database GUID %s\n",
297 debugstr_guid(&stat
.clsid
) );
302 db
= alloc_msiobject( MSIHANDLETYPE_DATABASE
, sizeof (MSIDATABASE
),
306 FIXME("Failed to allocate a handle\n");
310 if( TRACE_ON( msi
) )
311 enum_stream_names( stg
);
316 ret
= load_string_table( db
);
317 if( ret
!= ERROR_SUCCESS
)
320 msiobj_addref( &db
->hdr
);
321 IStorage_AddRef( stg
);
326 msiobj_release( &db
->hdr
);
328 IStorage_Release( stg
);
333 UINT WINAPI
MsiOpenDatabaseW(LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIHANDLE
*phDB
)
338 TRACE("%s %s %p\n",debugstr_w(szDBPath
),debugstr_w(szPersist
), phDB
);
340 ret
= MSI_OpenDatabaseW( szDBPath
, szPersist
, &db
);
341 if( ret
== ERROR_SUCCESS
)
343 *phDB
= alloc_msihandle( &db
->hdr
);
344 msiobj_release( &db
->hdr
);
350 UINT WINAPI
MsiOpenDatabaseA(LPCSTR szDBPath
, LPCSTR szPersist
, MSIHANDLE
*phDB
)
352 HRESULT r
= ERROR_FUNCTION_FAILED
;
353 LPWSTR szwDBPath
= NULL
, szwPersist
= NULL
;
356 TRACE("%s %s %p\n", debugstr_a(szDBPath
), debugstr_a(szPersist
), phDB
);
360 len
= MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, NULL
, 0 );
361 szwDBPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
364 MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, szwDBPath
, len
);
367 if( HIWORD(szPersist
) )
369 len
= MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, NULL
, 0 );
370 szwPersist
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
373 MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, szwPersist
, len
);
376 szwPersist
= (LPWSTR
) szPersist
;
378 r
= MsiOpenDatabaseW( szwDBPath
, szwPersist
, phDB
);
382 HeapFree( GetProcessHeap(), 0, szwPersist
);
384 HeapFree( GetProcessHeap(), 0, szwDBPath
);
389 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
392 LPWSTR szwProd
= NULL
;
394 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
398 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
399 szwProd
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
401 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProd
, len
);
404 ret
= MsiOpenProductW( szwProd
, phProduct
);
407 HeapFree( GetProcessHeap(), 0, szwProd
);
412 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
414 static const WCHAR szKey
[] = {
415 'S','o','f','t','w','a','r','e','\\',
416 'M','i','c','r','o','s','o','f','t','\\',
417 'W','i','n','d','o','w','s','\\',
418 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
419 'U','n','i','n','s','t','a','l','l',0 };
420 static const WCHAR szLocalPackage
[] = {
421 'L','o','c','a','l','P','a','c','k','a','g','e', 0
425 HKEY hKeyProduct
= NULL
, hKeyUninstall
= NULL
;
428 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
430 r
= RegOpenKeyW( HKEY_LOCAL_MACHINE
, szKey
, &hKeyUninstall
);
431 if( r
!= ERROR_SUCCESS
)
432 return ERROR_UNKNOWN_PRODUCT
;
434 r
= RegOpenKeyW( hKeyUninstall
, szProduct
, &hKeyProduct
);
435 if( r
!= ERROR_SUCCESS
)
437 r
= ERROR_UNKNOWN_PRODUCT
;
441 /* find the size of the path */
443 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
444 NULL
, &type
, NULL
, &count
);
445 if( r
!= ERROR_SUCCESS
)
447 r
= ERROR_UNKNOWN_PRODUCT
;
451 /* now alloc and fetch the path of the database to open */
452 path
= HeapAlloc( GetProcessHeap(), 0, count
);
456 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
457 NULL
, &type
, (LPBYTE
) path
, &count
);
458 if( r
!= ERROR_SUCCESS
)
460 r
= ERROR_UNKNOWN_PRODUCT
;
464 r
= MsiOpenPackageW( path
, phProduct
);
468 HeapFree( GetProcessHeap(), 0, path
);
470 RegCloseKey( hKeyProduct
);
471 RegCloseKey( hKeyUninstall
);
476 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
, LPCSTR szTransforms
, LANGID lgidLanguage
)
478 FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath
), debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
479 return ERROR_CALL_NOT_IMPLEMENTED
;
482 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
, LPCWSTR szTransforms
, LANGID lgidLanguage
)
484 FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath
), debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
485 return ERROR_CALL_NOT_IMPLEMENTED
;
488 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
, LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
490 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
491 debugstr_a(szPackagePath
), debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
, dwPlatform
, dwOptions
);
492 return ERROR_CALL_NOT_IMPLEMENTED
;
495 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
, LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
497 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
498 debugstr_w(szPackagePath
), debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
, dwPlatform
, dwOptions
);
499 return ERROR_CALL_NOT_IMPLEMENTED
;
502 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
504 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
505 UINT r
= ERROR_FUNCTION_FAILED
; /* FIXME: check return code */
507 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
511 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, NULL
, 0 );
512 szwPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
515 MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, szwPath
, len
);
520 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, NULL
, 0 );
521 szwCommand
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
524 MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, szwCommand
, len
);
527 r
= MsiInstallProductW( szwPath
, szwCommand
);
531 HeapFree( GetProcessHeap(), 0, szwPath
);
534 HeapFree( GetProcessHeap(), 0, szwCommand
);
539 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
541 MSIPACKAGE
*package
= NULL
;
542 UINT rc
= ERROR_SUCCESS
;
545 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
547 rc
= MsiVerifyPackageW(szPackagePath
);
548 if (rc
!= ERROR_SUCCESS
)
551 rc
= MSI_OpenPackageW(szPackagePath
,&package
);
552 if (rc
!= ERROR_SUCCESS
)
555 handle
= alloc_msihandle( &package
->hdr
);
557 rc
= ACTION_DoTopLevelINSTALL(package
, szPackagePath
, szCommandLine
);
559 MsiCloseHandle(handle
);
560 msiobj_release( &package
->hdr
);
564 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
566 FIXME("%s 0x%08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
567 return ERROR_CALL_NOT_IMPLEMENTED
;
570 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
572 FIXME("%s 0x%08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
573 return ERROR_CALL_NOT_IMPLEMENTED
;
576 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
, INSTALLSTATE eInstallState
)
578 LPWSTR szwProduct
= NULL
;
579 UINT hr
= ERROR_SUCCESS
;
581 FIXME("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
585 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
586 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
589 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
592 hr
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
596 HeapFree( GetProcessHeap(), 0, szwProduct
);
601 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
, INSTALLSTATE eInstallState
)
603 FIXME("%s %d %d\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
604 return ERROR_CALL_NOT_IMPLEMENTED
;
607 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
609 LPWSTR szwComponent
= NULL
, szwBuffer
= NULL
;
610 UINT hr
= ERROR_INSTALL_FAILURE
;
612 FIXME("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
616 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
617 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
620 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
622 return ERROR_INVALID_PARAMETER
;
626 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, GUID_SIZE
* sizeof(WCHAR
) );
631 hr
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
633 if( ERROR_SUCCESS
== hr
)
635 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
640 HeapFree( GetProcessHeap(), 0, szwComponent
);
642 HeapFree( GetProcessHeap(), 0, szwBuffer
);
647 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
649 FIXME("%s %s\n",debugstr_w(szComponent
), debugstr_w(szBuffer
));
650 if (NULL
== szComponent
) {
651 return ERROR_INVALID_PARAMETER
;
653 return ERROR_CALL_NOT_IMPLEMENTED
;
659 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
, LPSTR szBuffer
, DWORD
*pcchValueBuf
)
661 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
662 UINT hr
= ERROR_INSTALL_FAILURE
;
664 FIXME("%s %s %p %p\n",debugstr_a(szProduct
), debugstr_a(szAttribute
), szBuffer
, pcchValueBuf
);
666 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
) {
667 return ERROR_INVALID_PARAMETER
;
671 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
672 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
675 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
677 return ERROR_INVALID_PARAMETER
;
682 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szAttribute
, -1, NULL
, 0 );
683 szwAttribute
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
686 MultiByteToWideChar( CP_ACP
, 0, szAttribute
, -1, szwAttribute
, len
);
688 return ERROR_INVALID_PARAMETER
;
693 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf
) * sizeof(WCHAR
) );
698 hr
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
, pcchValueBuf
);
700 if( ERROR_SUCCESS
== hr
)
702 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, *pcchValueBuf
, NULL
, NULL
);
707 HeapFree( GetProcessHeap(), 0, szwProduct
);
709 HeapFree( GetProcessHeap(), 0, szwAttribute
);
711 HeapFree( GetProcessHeap(), 0, szwBuffer
);
716 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
, LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
721 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
), szBuffer
, pcchValueBuf
);
723 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
) {
724 return ERROR_INVALID_PARAMETER
;
726 if (NULL
== szProduct
|| NULL
== szAttribute
) {
727 return ERROR_INVALID_PARAMETER
;
730 hr
= MsiOpenProductW(szProduct
, &hProduct
);
731 if (ERROR_SUCCESS
!= hr
) return hr
;
733 hr
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
734 MsiCloseHandle(hProduct
);
738 UINT WINAPI
MsiDatabaseImportA(LPCSTR szFolderPath
, LPCSTR szFilename
)
740 FIXME("%s %s\n",debugstr_a(szFolderPath
), debugstr_a(szFilename
));
741 return ERROR_CALL_NOT_IMPLEMENTED
;
744 UINT WINAPI
MsiDatabaseImportW(LPCWSTR szFolderPath
, LPCWSTR szFilename
)
746 FIXME("%s %s\n",debugstr_w(szFolderPath
), debugstr_w(szFilename
));
747 return ERROR_CALL_NOT_IMPLEMENTED
;
750 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, BOOL fAppend
)
752 LPWSTR szwLogFile
= NULL
;
753 UINT hr
= ERROR_INSTALL_FAILURE
;
755 FIXME("%08lx %s %d\n", dwLogMode
, debugstr_a(szLogFile
), fAppend
);
759 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szLogFile
, -1, NULL
, 0 );
760 szwLogFile
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
763 MultiByteToWideChar( CP_ACP
, 0, szLogFile
, -1, szwLogFile
, len
);
765 return ERROR_INVALID_PARAMETER
;
768 hr
= MsiEnableLogW( dwLogMode
, szwLogFile
, fAppend
);
772 HeapFree( GetProcessHeap(), 0, szwLogFile
);
777 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, BOOL fAppend
)
779 HANDLE the_file
= INVALID_HANDLE_VALUE
;
780 TRACE("%08lx %s %d\n", dwLogMode
, debugstr_w(szLogFile
), fAppend
);
781 strcpyW(gszLogFile
,szLogFile
);
783 DeleteFileW(szLogFile
);
784 the_file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
785 FILE_ATTRIBUTE_NORMAL
, NULL
);
786 if (the_file
!= INVALID_HANDLE_VALUE
)
787 CloseHandle(the_file
);
789 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
791 return ERROR_SUCCESS
;
794 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
796 FIXME("%s\n", debugstr_a(szProduct
));
797 return INSTALLSTATE_UNKNOWN
;
800 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
802 FIXME("%s\n", debugstr_w(szProduct
));
803 return INSTALLSTATE_UNKNOWN
;
806 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
808 INSTALLUILEVEL old
= gUILevel
;
809 HWND oldwnd
= gUIhwnd
;
810 TRACE("%08x %p\n", dwUILevel
, phWnd
);
812 gUILevel
= dwUILevel
;
821 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
822 DWORD dwMessageFilter
, LPVOID pvContext
)
824 INSTALLUI_HANDLERA prev
= gUIHandler
;
826 TRACE("(%p %lx %p)\n",puiHandler
,dwMessageFilter
,pvContext
);
827 gUIHandler
= puiHandler
;
828 gUIFilter
= dwMessageFilter
;
829 gUIContext
= pvContext
;
834 UINT WINAPI
MsiLoadStringA(HINSTANCE hInstance
, UINT uID
, LPSTR lpBuffer
, int nBufferMax
, DWORD e
)
836 /*FIXME("%08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e);*/
837 FIXME("%p %u %p %d %08lx\n",hInstance
,uID
,lpBuffer
,nBufferMax
,e
);
838 return ERROR_CALL_NOT_IMPLEMENTED
;
841 UINT WINAPI
MsiLoadStringW(HINSTANCE hInstance
, UINT uID
, LPWSTR lpBuffer
, int nBufferMax
, DWORD e
)
843 FIXME("%p %u %p %d %08lx\n",hInstance
,uID
,lpBuffer
,nBufferMax
,e
);
845 int ret = LoadStringW(hInstance,uID,lpBuffer,nBufferMax);
846 FIXME("%s\n",debugstr_w(lpBuffer));
849 return ERROR_CALL_NOT_IMPLEMENTED
;
852 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
, DWORD
*pcchBuf
)
854 FIXME("%s %p %08lx\n", debugstr_a(szComponent
), lpPathBuf
, *pcchBuf
);
855 return INSTALLSTATE_UNKNOWN
;
858 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPSTR lpPathBuf
, DWORD
*pcchBuf
)
860 FIXME("%s %p %08lx\n", debugstr_w(szComponent
), lpPathBuf
, *pcchBuf
);
861 return INSTALLSTATE_UNKNOWN
;
866 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
, WORD wLanguageId
, DWORD f
)
868 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),uType
,wLanguageId
,f
);
870 MessageBoxExA(hWnd,lpText,lpCaption,uType|MB_OK,wLanguageId);
872 return ERROR_CALL_NOT_IMPLEMENTED
;
875 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
, WORD wLanguageId
, DWORD f
)
877 /*FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);*/
878 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),uType
,wLanguageId
,f
);
880 MessageBoxExW(hWnd,lpText,lpCaption,uType|MB_OK,wLanguageId);
882 return ERROR_CALL_NOT_IMPLEMENTED
;
885 UINT WINAPI
MsiEnumProductsA(DWORD index
, LPSTR lpguid
)
888 WCHAR szwGuid
[GUID_SIZE
];
890 TRACE("%ld %p\n",index
,lpguid
);
892 if (NULL
== lpguid
) {
893 return ERROR_INVALID_PARAMETER
;
895 r
= MsiEnumProductsW(index
, szwGuid
);
896 if( r
== ERROR_SUCCESS
)
897 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
902 UINT WINAPI
MsiEnumProductsW(DWORD index
, LPWSTR lpguid
)
904 HKEY hkey
= 0, hkeyFeatures
= 0;
908 TRACE("%ld %p\n",index
,lpguid
);
910 if (NULL
== lpguid
) {
911 return ERROR_INVALID_PARAMETER
;
913 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
914 if( r
!= ERROR_SUCCESS
)
917 r
= RegOpenKeyW(hkey
, szFeatures
, &hkeyFeatures
);
918 if( r
!= ERROR_SUCCESS
)
921 r
= RegEnumKeyW(hkeyFeatures
, index
, szKeyName
, GUID_SIZE
);
923 unsquash_guid(szKeyName
, lpguid
);
928 RegCloseKey(hkeyFeatures
);
935 UINT WINAPI
MsiEnumFeaturesA(LPCSTR szProduct
, DWORD index
,
936 LPSTR szFeature
, LPSTR szParent
)
939 WCHAR szwFeature
[GUID_SIZE
], szwParent
[GUID_SIZE
];
940 LPWSTR szwProduct
= NULL
;
942 TRACE("%s %ld %p %p\n",debugstr_a(szProduct
),index
,szFeature
,szParent
);
946 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
947 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
949 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
951 return ERROR_FUNCTION_FAILED
;
954 r
= MsiEnumFeaturesW(szwProduct
, index
, szwFeature
, szwParent
);
955 if( r
== ERROR_SUCCESS
)
957 WideCharToMultiByte(CP_ACP
, 0, szwFeature
, -1,
958 szFeature
, GUID_SIZE
, NULL
, NULL
);
959 WideCharToMultiByte(CP_ACP
, 0, szwParent
, -1,
960 szParent
, GUID_SIZE
, NULL
, NULL
);
964 HeapFree( GetProcessHeap(), 0, szwProduct
);
969 UINT WINAPI
MsiEnumFeaturesW(LPCWSTR szProduct
, DWORD index
,
970 LPWSTR szFeature
, LPWSTR szParent
)
972 HKEY hkey
= 0, hkeyFeatures
= 0, hkeyProduct
= 0;
974 WCHAR szRegName
[GUID_SIZE
];
976 TRACE("%s %ld %p %p\n",debugstr_w(szProduct
),index
,szFeature
,szParent
);
978 if( !squash_guid(szProduct
, szRegName
) )
979 return ERROR_INVALID_PARAMETER
;
981 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
982 if( r
!= ERROR_SUCCESS
)
985 r
= RegOpenKeyW(hkey
, szFeatures
, &hkeyFeatures
);
986 if( r
!= ERROR_SUCCESS
)
989 r
= RegOpenKeyW(hkeyFeatures
, szRegName
, &hkeyProduct
);
990 if( r
!= ERROR_SUCCESS
)
994 r
= RegEnumValueW(hkeyProduct
, index
, szFeature
, &sz
, NULL
, NULL
, NULL
, NULL
);
998 RegCloseKey(hkeyProduct
);
1000 RegCloseKey(hkeyFeatures
);
1007 UINT WINAPI
MsiEnumComponentsA(DWORD index
, LPSTR lpguid
)
1010 WCHAR szwGuid
[GUID_SIZE
];
1012 TRACE("%ld %p\n",index
,lpguid
);
1014 r
= MsiEnumComponentsW(index
, szwGuid
);
1015 if( r
== ERROR_SUCCESS
)
1016 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
1021 UINT WINAPI
MsiEnumComponentsW(DWORD index
, LPWSTR lpguid
)
1023 HKEY hkey
= 0, hkeyComponents
= 0;
1025 WCHAR szKeyName
[33];
1027 TRACE("%ld %p\n",index
,lpguid
);
1029 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
1030 if( r
!= ERROR_SUCCESS
)
1033 r
= RegOpenKeyW(hkey
, szComponents
, &hkeyComponents
);
1034 if( r
!= ERROR_SUCCESS
)
1037 r
= RegEnumKeyW(hkeyComponents
, index
, szKeyName
, GUID_SIZE
);
1039 unsquash_guid(szKeyName
, lpguid
);
1043 if( hkeyComponents
)
1044 RegCloseKey(hkeyComponents
);
1051 UINT WINAPI
MsiEnumClientsA(LPCSTR szComponent
, DWORD index
, LPSTR szProduct
)
1054 WCHAR szwProduct
[GUID_SIZE
];
1055 LPWSTR szwComponent
= NULL
;
1057 TRACE("%s %ld %p\n",debugstr_a(szComponent
),index
,szProduct
);
1061 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
1062 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
1064 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
1066 return ERROR_FUNCTION_FAILED
;
1069 r
= MsiEnumClientsW(szComponent
?szwComponent
:NULL
, index
, szwProduct
);
1070 if( r
== ERROR_SUCCESS
)
1072 WideCharToMultiByte(CP_ACP
, 0, szwProduct
, -1,
1073 szProduct
, GUID_SIZE
, NULL
, NULL
);
1077 HeapFree( GetProcessHeap(), 0, szwComponent
);
1082 UINT WINAPI
MsiEnumClientsW(LPCWSTR szComponent
, DWORD index
, LPWSTR szProduct
)
1084 HKEY hkey
= 0, hkeyComponents
= 0, hkeyComp
= 0;
1086 WCHAR szRegName
[GUID_SIZE
], szValName
[GUID_SIZE
];
1088 TRACE("%s %ld %p\n",debugstr_w(szComponent
),index
,szProduct
);
1090 if( !squash_guid(szComponent
, szRegName
) )
1091 return ERROR_INVALID_PARAMETER
;
1093 r
= RegOpenKeyW(HKEY_LOCAL_MACHINE
, szInstaller
, &hkey
);
1094 if( r
!= ERROR_SUCCESS
)
1097 r
= RegOpenKeyW(hkey
, szComponents
, &hkeyComponents
);
1098 if( r
!= ERROR_SUCCESS
)
1101 r
= RegOpenKeyW(hkeyComponents
, szRegName
, &hkeyComp
);
1102 if( r
!= ERROR_SUCCESS
)
1106 r
= RegEnumValueW(hkeyComp
, index
, szValName
, &sz
, NULL
, NULL
, NULL
, NULL
);
1107 if( r
!= ERROR_SUCCESS
)
1110 unsquash_guid(szValName
, szProduct
);
1114 RegCloseKey(hkeyComp
);
1115 if( hkeyComponents
)
1116 RegCloseKey(hkeyComponents
);
1123 UINT WINAPI
MsiEnumComponentQualifiersA(
1124 LPSTR szComponent
, DWORD iIndex
, LPSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
, LPSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
1126 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_a(szComponent
), iIndex
, lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
, pcchApplicationDataBuf
);
1127 return ERROR_CALL_NOT_IMPLEMENTED
;
1130 UINT WINAPI
MsiEnumComponentQualifiersW(
1131 LPWSTR szComponent
, DWORD iIndex
, LPWSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
, LPWSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
1133 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_w(szComponent
), iIndex
, lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
, pcchApplicationDataBuf
);
1134 return ERROR_CALL_NOT_IMPLEMENTED
;
1137 UINT WINAPI
MsiProvideAssemblyA(
1138 LPCSTR szAssemblyName
, LPCSTR szAppContext
, DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
, DWORD
* pcchPathBuf
)
1140 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
1141 debugstr_a(szAssemblyName
), debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
, pcchPathBuf
);
1142 return ERROR_CALL_NOT_IMPLEMENTED
;
1145 UINT WINAPI
MsiProvideAssemblyW(
1146 LPCWSTR szAssemblyName
, LPCWSTR szAppContext
, DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
, DWORD
* pcchPathBuf
)
1148 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
1149 debugstr_w(szAssemblyName
), debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
, pcchPathBuf
);
1150 return ERROR_CALL_NOT_IMPLEMENTED
;
1153 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
, LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
1155 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
1156 return ERROR_CALL_NOT_IMPLEMENTED
;
1159 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
, LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
1161 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
1162 return ERROR_CALL_NOT_IMPLEMENTED
;
1165 HRESULT WINAPI
MsiGetFileSignatureInformationA(
1166 LPCSTR szSignedObjectPath
, DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
, DWORD
* pcbHashData
)
1168 FIXME("%s 0x%08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
, ppcCertContext
, pbHashData
, pcbHashData
);
1169 return ERROR_CALL_NOT_IMPLEMENTED
;
1172 HRESULT WINAPI
MsiGetFileSignatureInformationW(
1173 LPCWSTR szSignedObjectPath
, DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
, DWORD
* pcbHashData
)
1175 FIXME("%s 0x%08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
, ppcCertContext
, pbHashData
, pcbHashData
);
1176 return ERROR_CALL_NOT_IMPLEMENTED
;
1179 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
1180 LPSTR szValue
, DWORD
*pccbValue
)
1182 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
1183 return ERROR_CALL_NOT_IMPLEMENTED
;
1186 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
1187 LPWSTR szValue
, DWORD
*pccbValue
)
1189 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
1190 return ERROR_CALL_NOT_IMPLEMENTED
;
1193 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
1196 LPWSTR szPack
= NULL
;
1198 TRACE("%s\n", debugstr_a(szPackage
) );
1202 len
= MultiByteToWideChar( CP_ACP
, 0, szPackage
, -1, NULL
, 0 );
1203 szPack
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1205 return ERROR_OUTOFMEMORY
;
1206 MultiByteToWideChar( CP_ACP
, 0, szPackage
, -1, szPack
, len
);
1209 r
= MsiVerifyPackageW( szPack
);
1211 HeapFree( GetProcessHeap(), 0, szPack
);
1216 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
1221 TRACE("%s\n", debugstr_w(szPackage
) );
1223 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
1224 MsiCloseHandle( handle
);
1229 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
1230 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
1234 LPWSTR szwProduct
= NULL
;
1235 LPWSTR szwComponent
= NULL
;
1236 LPWSTR lpwPathBuf
= NULL
;
1240 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
1241 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1243 return ERROR_OUTOFMEMORY
;
1244 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
1249 len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
1250 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1252 return ERROR_OUTOFMEMORY
;
1253 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
1256 if (pcchBuf
&& *pcchBuf
> 0)
1257 lpwPathBuf
= HeapAlloc( GetProcessHeap(), 0, *pcchBuf
* sizeof(WCHAR
));
1261 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
1263 HeapFree( GetProcessHeap(), 0, szwProduct
);
1264 HeapFree( GetProcessHeap(), 0, szwComponent
);
1267 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, *pcchBuf
,
1268 lpPathBuf
, GUID_SIZE
, NULL
, NULL
);
1269 HeapFree( GetProcessHeap(), 0, lpwPathBuf
);
1275 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1276 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1278 FIXME("STUB: (%s %s %p %p)\n", debugstr_w(szProduct
),
1279 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1281 return INSTALLSTATE_UNKNOWN
;
1284 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1288 LPWSTR szwProduct
= NULL
;
1289 LPWSTR szwFeature
= NULL
;
1293 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
1294 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1296 return ERROR_OUTOFMEMORY
;
1297 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
1302 len
= MultiByteToWideChar( CP_ACP
, 0, szFeature
, -1, NULL
, 0 );
1303 szwFeature
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1305 return ERROR_OUTOFMEMORY
;
1306 MultiByteToWideChar( CP_ACP
, 0, szFeature
, -1, szwFeature
, len
);
1309 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1311 HeapFree( GetProcessHeap(), 0, szwProduct
);
1312 HeapFree( GetProcessHeap(), 0, szwFeature
);
1317 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1319 FIXME("STUB: (%s %s)\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1320 return INSTALLSTATE_UNKNOWN
;
1324 /******************************************************************
1327 * @todo: maybe we can check here if MsiServer service is declared no ?
1329 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
) {
1330 if (fdwReason
== DLL_PROCESS_ATTACH
) {
1331 DisableThreadLibraryCalls(hinstDLL
);
1335 gUILevel
= INSTALLUILEVEL_BASIC
;
1341 /* FIXME: Initialisation */
1342 } else if (fdwReason
== DLL_PROCESS_DETACH
) {
1343 /* FIXME: Cleanup */
1346 static const WCHAR szMSIServerSvc[] = { 'M','S','I','S','e','r','v','e','r',0 };
1347 static const WCHAR szNull[] = { 0 };
1348 if (!strcmpW(lpServiceName, szMSIServerSvc)) {
1349 hKey = CreateServiceW(hSCManager,
1352 SC_MANAGER_ALL_ACCESS,
1353 SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS,
1355 SERVICE_ERROR_IGNORE,
1367 /* IUnknown fields */
1368 ICOM_VFIELD(IClassFactory
);
1370 } IClassFactoryImpl
;
1372 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,REFIID riid
,LPVOID
*ppobj
) {
1373 ICOM_THIS(IClassFactoryImpl
,iface
);
1374 FIXME("(%p, %s, %p): stub\n",This
,debugstr_guid(riid
),ppobj
);
1375 return E_NOINTERFACE
;
1378 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
) {
1379 ICOM_THIS(IClassFactoryImpl
,iface
);
1380 return ++(This
->ref
);
1383 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
) {
1384 ICOM_THIS(IClassFactoryImpl
,iface
);
1385 /* static class, won't be freed */
1386 return --(This
->ref
);
1389 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
, LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
) {
1390 ICOM_THIS(IClassFactoryImpl
,iface
);
1391 FIXME ("(%p, %p, %s, %p): to implement\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1395 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
,BOOL dolock
) {
1396 ICOM_THIS(IClassFactoryImpl
,iface
);
1397 FIXME("(%p, %d): stub\n", This
, dolock
);
1401 static ICOM_VTABLE(IClassFactory
) MsiCF_Vtbl
= {
1402 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
1403 MsiCF_QueryInterface
,
1406 MsiCF_CreateInstance
,
1410 static IClassFactoryImpl Msi_CF
= {&MsiCF_Vtbl
, 1 };
1412 /******************************************************************
1413 * DllGetClassObject (MSI.@)
1415 HRESULT WINAPI
MSI_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
) {
1416 FIXME("(%s, %s, %p): almost a stub.\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1417 if (IsEqualCLSID (rclsid
, &CLSID_IMsiServer
)) {
1418 *ppv
= (LPVOID
) &Msi_CF
;
1419 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1421 } else if (IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
)) {
1422 *ppv
= (LPVOID
) &Msi_CF
;
1423 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1425 } else if (IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
)) {
1426 *ppv
= (LPVOID
) &Msi_CF
;
1427 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1429 } else if (IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
)) {
1430 *ppv
= (LPVOID
) &Msi_CF
;
1431 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1433 } else if (IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
)) {
1434 *ppv
= (LPVOID
) &Msi_CF
;
1435 IClassFactory_AddRef((IClassFactory
*)*ppv
);
1438 WARN("(%s, %s, %p): no interface found.\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1439 return CLASS_E_CLASSNOTAVAILABLE
;
1442 /******************************************************************
1443 * DllGetVersion (MSI.@)
1445 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
1449 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1450 return E_INVALIDARG
;
1452 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1453 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1454 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1455 pdvi
->dwPlatformID
= 1;
1460 /******************************************************************
1461 * DllCanUnloadNow (MSI.@)
1463 BOOL WINAPI
MSI_DllCanUnloadNow(void)
1468 UINT WINAPI
MsiEnumRelatedProductsA (LPCSTR lpUpgradeCode
, DWORD dwReserved
,
1469 DWORD iProductIndex
, LPSTR lpProductBuf
)
1471 FIXME("STUB: (%s, %li %li %s)\n",lpUpgradeCode
, dwReserved
, iProductIndex
,
1473 return ERROR_CALL_NOT_IMPLEMENTED
;