2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002,2003,2004,2005 Mike McCormack for CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #define NONAMELESSUNION
31 #include "wine/debug.h"
37 #include "wine/unicode.h"
44 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
47 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
48 * which is a problem because LPCTSTR isn't defined when compiling wine.
49 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
50 * and make sure to only use it in W functions.
52 #define LPCTSTR LPCWSTR
54 DEFINE_GUID( CLSID_MsiDatabase
, 0x000c1084, 0x0000, 0x0000,
55 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
58 INSTALLUILEVEL gUILevel
= INSTALLUILEVEL_BASIC
;
60 INSTALLUI_HANDLERA gUIHandlerA
= NULL
;
61 INSTALLUI_HANDLERW gUIHandlerW
= NULL
;
63 LPVOID gUIContext
= NULL
;
64 WCHAR gszLogFile
[MAX_PATH
];
69 * A .msi file is a structured storage file.
70 * It should contain a number of streams.
73 VOID
MSI_CloseDatabase( MSIOBJECTHDR
*arg
)
75 MSIDATABASE
*db
= (MSIDATABASE
*) arg
;
78 free_cached_tables( db
);
79 r
= IStorage_Release( db
->storage
);
81 ERR("database reference count was not zero (%ld)\n", r
);
84 UINT
MSI_OpenDatabaseW(LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIDATABASE
**pdb
)
88 MSIDATABASE
*db
= NULL
;
89 UINT ret
= ERROR_FUNCTION_FAILED
;
93 TRACE("%s %s\n",debugstr_w(szDBPath
),debugstr_w(szPersist
) );
96 return ERROR_INVALID_PARAMETER
;
98 szMode
= (LPWSTR
) szPersist
;
99 if( HIWORD( szPersist
) )
101 /* UINT len = lstrlenW( szPerist ) + 1; */
102 FIXME("don't support persist files yet\b");
103 return ERROR_INVALID_PARAMETER
;
104 /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
106 else if( szPersist
== MSIDBOPEN_READONLY
)
108 r
= StgOpenStorage( szDBPath
, NULL
,
109 STGM_DIRECT
|STGM_READ
|STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
111 else if( szPersist
== MSIDBOPEN_CREATE
)
113 r
= StgCreateDocfile( szDBPath
,
114 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, 0, &stg
);
115 if( r
== ERROR_SUCCESS
)
117 IStorage_SetClass( stg
, &CLSID_MsiDatabase
);
118 r
= init_string_table( stg
);
121 else if( szPersist
== MSIDBOPEN_TRANSACT
)
123 r
= StgOpenStorage( szDBPath
, NULL
,
124 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
128 ERR("unknown flag %p\n",szPersist
);
129 return ERROR_INVALID_PARAMETER
;
134 FIXME("open failed r = %08lx!\n",r
);
135 return ERROR_FUNCTION_FAILED
;
138 r
= IStorage_Stat( stg
, &stat
, STATFLAG_NONAME
);
141 FIXME("Failed to stat storage\n");
145 if( memcmp( &stat
.clsid
, &CLSID_MsiDatabase
, sizeof (GUID
) ) )
147 ERR("storage GUID is not a MSI database GUID %s\n",
148 debugstr_guid(&stat
.clsid
) );
153 db
= alloc_msiobject( MSIHANDLETYPE_DATABASE
, sizeof (MSIDATABASE
),
157 FIXME("Failed to allocate a handle\n");
161 if( TRACE_ON( msi
) )
162 enum_stream_names( stg
);
167 ret
= load_string_table( db
);
168 if( ret
!= ERROR_SUCCESS
)
171 msiobj_addref( &db
->hdr
);
172 IStorage_AddRef( stg
);
177 msiobj_release( &db
->hdr
);
179 IStorage_Release( stg
);
184 UINT WINAPI
MsiOpenDatabaseW(LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIHANDLE
*phDB
)
189 TRACE("%s %s %p\n",debugstr_w(szDBPath
),debugstr_w(szPersist
), phDB
);
191 ret
= MSI_OpenDatabaseW( szDBPath
, szPersist
, &db
);
192 if( ret
== ERROR_SUCCESS
)
194 *phDB
= alloc_msihandle( &db
->hdr
);
195 msiobj_release( &db
->hdr
);
201 UINT WINAPI
MsiOpenDatabaseA(LPCSTR szDBPath
, LPCSTR szPersist
, MSIHANDLE
*phDB
)
203 HRESULT r
= ERROR_FUNCTION_FAILED
;
204 LPWSTR szwDBPath
= NULL
, szwPersist
= NULL
;
207 TRACE("%s %s %p\n", debugstr_a(szDBPath
), debugstr_a(szPersist
), phDB
);
211 len
= MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, NULL
, 0 );
212 szwDBPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
215 MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, szwDBPath
, len
);
218 if( HIWORD(szPersist
) )
220 len
= MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, NULL
, 0 );
221 szwPersist
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
224 MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, szwPersist
, len
);
227 szwPersist
= (LPWSTR
) szPersist
;
229 r
= MsiOpenDatabaseW( szwDBPath
, szwPersist
, phDB
);
232 HeapFree( GetProcessHeap(), 0, szwPersist
);
233 HeapFree( GetProcessHeap(), 0, szwDBPath
);
238 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
241 LPWSTR szwProd
= NULL
;
243 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
247 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
248 szwProd
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
250 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProd
, len
);
253 ret
= MsiOpenProductW( szwProd
, phProduct
);
255 HeapFree( GetProcessHeap(), 0, szwProd
);
260 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
262 static const WCHAR szLocalPackage
[] = {
263 'L','o','c','a','l','P','a','c','k','a','g','e', 0
267 HKEY hKeyProduct
= NULL
;
270 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
272 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
273 if( r
!= ERROR_SUCCESS
)
275 r
= ERROR_UNKNOWN_PRODUCT
;
279 /* find the size of the path */
281 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
282 NULL
, &type
, NULL
, &count
);
283 if( r
!= ERROR_SUCCESS
)
285 r
= ERROR_UNKNOWN_PRODUCT
;
289 /* now alloc and fetch the path of the database to open */
290 path
= HeapAlloc( GetProcessHeap(), 0, count
);
294 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
295 NULL
, &type
, (LPBYTE
) path
, &count
);
296 if( r
!= ERROR_SUCCESS
)
298 r
= ERROR_UNKNOWN_PRODUCT
;
302 r
= MsiOpenPackageW( path
, phProduct
);
305 HeapFree( GetProcessHeap(), 0, path
);
307 RegCloseKey( hKeyProduct
);
312 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
313 LPCSTR szTransforms
, LANGID lgidLanguage
)
315 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
316 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
317 return ERROR_CALL_NOT_IMPLEMENTED
;
320 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
321 LPCWSTR szTransforms
, LANGID lgidLanguage
)
323 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
324 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
325 return ERROR_CALL_NOT_IMPLEMENTED
;
328 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
329 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
331 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
332 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
333 lgidLanguage
, dwPlatform
, dwOptions
);
334 return ERROR_CALL_NOT_IMPLEMENTED
;
337 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
338 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
340 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
341 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
342 lgidLanguage
, dwPlatform
, dwOptions
);
343 return ERROR_CALL_NOT_IMPLEMENTED
;
346 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
348 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
349 UINT r
= ERROR_FUNCTION_FAILED
; /* FIXME: check return code */
351 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
355 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, NULL
, 0 );
356 szwPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
359 MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, szwPath
, len
);
364 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, NULL
, 0 );
365 szwCommand
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
368 MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, szwCommand
, len
);
371 r
= MsiInstallProductW( szwPath
, szwCommand
);
374 HeapFree( GetProcessHeap(), 0, szwPath
);
375 HeapFree( GetProcessHeap(), 0, szwCommand
);
380 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
382 MSIPACKAGE
*package
= NULL
;
383 UINT rc
= ERROR_SUCCESS
;
386 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
388 rc
= MsiVerifyPackageW(szPackagePath
);
389 if (rc
!= ERROR_SUCCESS
)
392 rc
= MSI_OpenPackageW(szPackagePath
,&package
);
393 if (rc
!= ERROR_SUCCESS
)
396 handle
= alloc_msihandle( &package
->hdr
);
398 rc
= ACTION_DoTopLevelINSTALL(package
, szPackagePath
, szCommandLine
);
400 MsiCloseHandle(handle
);
401 msiobj_release( &package
->hdr
);
405 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
407 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
408 return ERROR_CALL_NOT_IMPLEMENTED
;
411 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
413 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
414 return ERROR_CALL_NOT_IMPLEMENTED
;
417 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
418 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
420 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
421 eInstallType
, debugstr_a(szCommandLine
));
422 return ERROR_CALL_NOT_IMPLEMENTED
;
425 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
426 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
428 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
429 eInstallType
, debugstr_w(szCommandLine
));
430 return ERROR_CALL_NOT_IMPLEMENTED
;
433 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
434 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
441 static const WCHAR szSouceList
[] = {
442 'S','o','u','r','c','e','L','i','s','t',0};
443 static const WCHAR szLUS
[] = {
444 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
445 WCHAR sourcepath
[0x200];
446 static const WCHAR szInstalled
[] = {
447 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
450 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
451 debugstr_w(szCommandLine
));
453 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
454 eInstallState
!= INSTALLSTATE_DEFAULT
)
456 FIXME("Not implemented for anything other than local installs\n");
457 return ERROR_CALL_NOT_IMPLEMENTED
;
460 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
461 if (rc
!= ERROR_SUCCESS
)
464 rc
= RegOpenKeyW(hkey
,szSouceList
,&hkey1
);
465 if (rc
!= ERROR_SUCCESS
)
468 sz
= sizeof(sourcepath
);
469 rc
= RegQueryValueExW(hkey1
, szLUS
, NULL
, NULL
,(LPBYTE
)sourcepath
, &sz
);
470 if (rc
!= ERROR_SUCCESS
)
475 * ok 1, we need to find the msi file for this product.
476 * 2, find the source dir for the files
477 * 3, do the configure/install.
478 4, cleanupany runonce entry.
481 rc
= MsiOpenProductW(szProduct
,&handle
);
482 if (rc
!= ERROR_SUCCESS
)
485 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
487 sz
= strlenW(szInstalled
);
490 sz
+= strlenW(szCommandLine
);
492 commandline
= HeapAlloc(GetProcessHeap(),0,sz
* sizeof(WCHAR
));
495 strcpyW(commandline
,szCommandLine
);
499 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
500 strcatW(commandline
,szInstalled
);
502 rc
= ACTION_DoTopLevelINSTALL(package
, sourcepath
, commandline
);
504 HeapFree(GetProcessHeap(),0,commandline
);
511 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
512 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
514 LPWSTR szwProduct
= NULL
;
515 LPWSTR szwCommandLine
= NULL
;
516 UINT hr
= ERROR_FUNCTION_FAILED
;
520 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
521 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
524 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
529 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, NULL
, 0 );
530 szwCommandLine
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
533 MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, szwCommandLine
, len
);
536 hr
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
539 HeapFree( GetProcessHeap(), 0, szwProduct
);
540 HeapFree( GetProcessHeap(), 0, szwCommandLine
);
545 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
546 INSTALLSTATE eInstallState
)
548 LPWSTR szwProduct
= NULL
;
549 UINT hr
= ERROR_SUCCESS
;
551 FIXME("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
555 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
556 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
559 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
562 hr
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
565 HeapFree( GetProcessHeap(), 0, szwProduct
);
570 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
571 INSTALLSTATE eInstallState
)
573 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
575 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
,
579 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
581 LPWSTR szwComponent
= NULL
;
582 UINT hr
= ERROR_INSTALL_FAILURE
;
583 WCHAR szwBuffer
[GUID_SIZE
];
585 FIXME("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
589 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
590 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
593 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
596 return ERROR_INVALID_PARAMETER
;
598 hr
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
600 if( ERROR_SUCCESS
== hr
)
601 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
604 HeapFree( GetProcessHeap(), 0, szwComponent
);
609 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
611 FIXME("%s %s\n",debugstr_w(szComponent
), debugstr_w(szBuffer
));
612 if (NULL
== szComponent
)
613 return ERROR_INVALID_PARAMETER
;
614 return ERROR_CALL_NOT_IMPLEMENTED
;
617 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
618 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
620 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
621 UINT hr
= ERROR_INSTALL_FAILURE
;
623 FIXME("%s %s %p %p\n",debugstr_a(szProduct
), debugstr_a(szAttribute
),
624 szBuffer
, pcchValueBuf
);
626 if( NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
627 return ERROR_INVALID_PARAMETER
;
630 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
631 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
634 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
637 return ERROR_INVALID_PARAMETER
;
641 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szAttribute
, -1, NULL
, 0 );
642 szwAttribute
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
645 MultiByteToWideChar( CP_ACP
, 0, szAttribute
, -1, szwAttribute
, len
);
649 hr
= ERROR_INVALID_PARAMETER
;
655 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf
) * sizeof(WCHAR
) );
660 hr
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
, pcchValueBuf
);
662 if( ERROR_SUCCESS
== hr
)
663 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, *pcchValueBuf
, NULL
, NULL
);
666 HeapFree( GetProcessHeap(), 0, szwProduct
);
667 HeapFree( GetProcessHeap(), 0, szwAttribute
);
668 HeapFree( GetProcessHeap(), 0, szwBuffer
);
673 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
674 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
679 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
680 szBuffer
, pcchValueBuf
);
682 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
683 return ERROR_INVALID_PARAMETER
;
684 if (NULL
== szProduct
|| NULL
== szAttribute
)
685 return ERROR_INVALID_PARAMETER
;
687 hr
= MsiOpenProductW(szProduct
, &hProduct
);
688 if (ERROR_SUCCESS
!= hr
)
691 hr
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
692 MsiCloseHandle(hProduct
);
696 UINT WINAPI
MsiDatabaseImportA(LPCSTR szFolderPath
, LPCSTR szFilename
)
698 FIXME("%s %s\n",debugstr_a(szFolderPath
), debugstr_a(szFilename
));
699 return ERROR_CALL_NOT_IMPLEMENTED
;
702 UINT WINAPI
MsiDatabaseImportW(LPCWSTR szFolderPath
, LPCWSTR szFilename
)
704 FIXME("%s %s\n",debugstr_w(szFolderPath
), debugstr_w(szFilename
));
705 return ERROR_CALL_NOT_IMPLEMENTED
;
708 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
710 LPWSTR szwLogFile
= NULL
;
711 UINT hr
= ERROR_INSTALL_FAILURE
;
713 FIXME("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
717 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szLogFile
, -1, NULL
, 0 );
718 szwLogFile
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
721 MultiByteToWideChar( CP_ACP
, 0, szLogFile
, -1, szwLogFile
, len
);
724 return ERROR_INVALID_PARAMETER
;
726 hr
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
729 HeapFree( GetProcessHeap(), 0, szwLogFile
);
734 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
736 HANDLE file
= INVALID_HANDLE_VALUE
;
738 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
740 strcpyW(gszLogFile
,szLogFile
);
741 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
742 DeleteFileW(szLogFile
);
743 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
744 FILE_ATTRIBUTE_NORMAL
, NULL
);
745 if (file
!= INVALID_HANDLE_VALUE
)
748 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
750 return ERROR_SUCCESS
;
753 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
759 len
= MultiByteToWideChar(CP_ACP
,0,szProduct
,-1,NULL
,0);
760 szwProduct
= HeapAlloc(GetProcessHeap(),0,len
*sizeof(WCHAR
));
761 MultiByteToWideChar(CP_ACP
,0,szProduct
,-1,szwProduct
,len
);
762 rc
= MsiQueryProductStateW(szwProduct
);
763 HeapFree(GetProcessHeap(),0,szwProduct
);
767 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
770 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
772 static const WCHAR szWindowsInstaller
[] = {
773 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
776 TRACE("%s\n", debugstr_w(szProduct
));
778 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
779 if (rc
!= ERROR_SUCCESS
)
784 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
785 if (rc
!= ERROR_SUCCESS
)
789 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
790 if (rc
!= ERROR_SUCCESS
)
797 rrc
= INSTALLSTATE_DEFAULT
;
800 FIXME("Unknown install state read from registry (%i)\n",rrc
);
801 rrc
= INSTALLSTATE_UNKNOWN
;
809 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
811 INSTALLUILEVEL old
= gUILevel
;
812 HWND oldwnd
= gUIhwnd
;
814 TRACE("%08x %p\n", dwUILevel
, phWnd
);
816 gUILevel
= dwUILevel
;
825 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
826 DWORD dwMessageFilter
, LPVOID pvContext
)
828 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
830 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
831 gUIHandlerA
= puiHandler
;
832 gUIFilter
= dwMessageFilter
;
833 gUIContext
= pvContext
;
838 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
839 DWORD dwMessageFilter
, LPVOID pvContext
)
841 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
843 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
844 gUIHandlerW
= puiHandler
;
845 gUIFilter
= dwMessageFilter
;
846 gUIContext
= pvContext
;
851 UINT WINAPI
MsiLoadStringA(HINSTANCE hInstance
, UINT uID
, LPSTR lpBuffer
,
852 int nBufferMax
, DWORD e
)
854 FIXME("%p %u %p %d %08lx\n",hInstance
,uID
,lpBuffer
,nBufferMax
,e
);
855 return ERROR_CALL_NOT_IMPLEMENTED
;
858 UINT WINAPI
MsiLoadStringW(HINSTANCE hInstance
, UINT uID
, LPWSTR lpBuffer
,
859 int nBufferMax
, DWORD e
)
861 FIXME("%p %u %p %d %08lx\n",hInstance
,uID
,lpBuffer
,nBufferMax
,e
);
862 return ERROR_CALL_NOT_IMPLEMENTED
;
865 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
868 FIXME("%s %p %08lx\n", debugstr_a(szComponent
), lpPathBuf
, *pcchBuf
);
869 return INSTALLSTATE_UNKNOWN
;
872 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPSTR lpPathBuf
,
875 FIXME("%s %p %08lx\n", debugstr_w(szComponent
), lpPathBuf
, *pcchBuf
);
876 return INSTALLSTATE_UNKNOWN
;
879 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
880 WORD wLanguageId
, DWORD f
)
882 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
883 uType
,wLanguageId
,f
);
884 return ERROR_CALL_NOT_IMPLEMENTED
;
887 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
888 WORD wLanguageId
, DWORD f
)
890 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
891 uType
,wLanguageId
,f
);
892 return ERROR_CALL_NOT_IMPLEMENTED
;
895 UINT WINAPI
MsiEnumProductsA(DWORD index
, LPSTR lpguid
)
898 WCHAR szwGuid
[GUID_SIZE
];
900 TRACE("%ld %p\n",index
,lpguid
);
902 if (NULL
== lpguid
) {
903 return ERROR_INVALID_PARAMETER
;
905 r
= MsiEnumProductsW(index
, szwGuid
);
906 if( r
== ERROR_SUCCESS
)
907 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
912 UINT WINAPI
MsiEnumProductsW(DWORD index
, LPWSTR lpguid
)
914 HKEY hkeyFeatures
= 0;
918 TRACE("%ld %p\n",index
,lpguid
);
921 return ERROR_INVALID_PARAMETER
;
923 r
= MSIREG_OpenFeatures(&hkeyFeatures
);
924 if( r
!= ERROR_SUCCESS
)
927 r
= RegEnumKeyW(hkeyFeatures
, index
, szKeyName
, GUID_SIZE
);
929 unsquash_guid(szKeyName
, lpguid
);
934 RegCloseKey(hkeyFeatures
);
939 UINT WINAPI
MsiEnumFeaturesA(LPCSTR szProduct
, DWORD index
,
940 LPSTR szFeature
, LPSTR szParent
)
943 WCHAR szwFeature
[GUID_SIZE
], szwParent
[GUID_SIZE
];
944 LPWSTR szwProduct
= NULL
;
946 TRACE("%s %ld %p %p\n",debugstr_a(szProduct
),index
,szFeature
,szParent
);
950 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
951 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
953 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
955 return ERROR_FUNCTION_FAILED
;
958 r
= MsiEnumFeaturesW(szwProduct
, index
, szwFeature
, szwParent
);
959 if( r
== ERROR_SUCCESS
)
961 WideCharToMultiByte(CP_ACP
, 0, szwFeature
, -1,
962 szFeature
, GUID_SIZE
, NULL
, NULL
);
963 WideCharToMultiByte(CP_ACP
, 0, szwParent
, -1,
964 szParent
, GUID_SIZE
, NULL
, NULL
);
967 HeapFree( GetProcessHeap(), 0, szwProduct
);
972 UINT WINAPI
MsiEnumFeaturesW(LPCWSTR szProduct
, DWORD index
,
973 LPWSTR szFeature
, LPWSTR szParent
)
975 HKEY hkeyProduct
= 0;
978 TRACE("%s %ld %p %p\n",debugstr_w(szProduct
),index
,szFeature
,szParent
);
980 r
= MSIREG_OpenFeaturesKey(szProduct
,&hkeyProduct
,FALSE
);
981 if( r
!= ERROR_SUCCESS
)
985 r
= RegEnumValueW(hkeyProduct
, index
, szFeature
, &sz
, NULL
, NULL
, NULL
, NULL
);
989 RegCloseKey(hkeyProduct
);
994 UINT WINAPI
MsiEnumComponentsA(DWORD index
, LPSTR lpguid
)
997 WCHAR szwGuid
[GUID_SIZE
];
999 TRACE("%ld %p\n",index
,lpguid
);
1001 r
= MsiEnumComponentsW(index
, szwGuid
);
1002 if( r
== ERROR_SUCCESS
)
1003 WideCharToMultiByte(CP_ACP
, 0, szwGuid
, -1, lpguid
, GUID_SIZE
, NULL
, NULL
);
1008 UINT WINAPI
MsiEnumComponentsW(DWORD index
, LPWSTR lpguid
)
1010 HKEY hkeyComponents
= 0;
1012 WCHAR szKeyName
[33];
1014 TRACE("%ld %p\n",index
,lpguid
);
1016 r
= MSIREG_OpenComponents(&hkeyComponents
);
1017 if( r
!= ERROR_SUCCESS
)
1020 r
= RegEnumKeyW(hkeyComponents
, index
, szKeyName
, GUID_SIZE
);
1022 unsquash_guid(szKeyName
, lpguid
);
1026 if( hkeyComponents
)
1027 RegCloseKey(hkeyComponents
);
1032 UINT WINAPI
MsiEnumClientsA(LPCSTR szComponent
, DWORD index
, LPSTR szProduct
)
1035 WCHAR szwProduct
[GUID_SIZE
];
1036 LPWSTR szwComponent
= NULL
;
1038 TRACE("%s %ld %p\n",debugstr_a(szComponent
),index
,szProduct
);
1042 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
1043 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
1045 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
1047 return ERROR_FUNCTION_FAILED
;
1050 r
= MsiEnumClientsW(szComponent
?szwComponent
:NULL
, index
, szwProduct
);
1051 if( r
== ERROR_SUCCESS
)
1053 WideCharToMultiByte(CP_ACP
, 0, szwProduct
, -1,
1054 szProduct
, GUID_SIZE
, NULL
, NULL
);
1057 HeapFree( GetProcessHeap(), 0, szwComponent
);
1062 UINT WINAPI
MsiEnumClientsW(LPCWSTR szComponent
, DWORD index
, LPWSTR szProduct
)
1066 WCHAR szValName
[GUID_SIZE
];
1068 TRACE("%s %ld %p\n",debugstr_w(szComponent
),index
,szProduct
);
1070 r
= MSIREG_OpenComponentsKey(szComponent
,&hkeyComp
,FALSE
);
1071 if( r
!= ERROR_SUCCESS
)
1075 r
= RegEnumValueW(hkeyComp
, index
, szValName
, &sz
, NULL
, NULL
, NULL
, NULL
);
1076 if( r
!= ERROR_SUCCESS
)
1079 unsquash_guid(szValName
, szProduct
);
1083 RegCloseKey(hkeyComp
);
1088 UINT WINAPI
MsiEnumComponentQualifiersA( LPSTR szComponent
, DWORD iIndex
,
1089 LPSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
,
1090 LPSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
1092 FIXME("%s %08lx %p %p %p %p\n", debugstr_a(szComponent
), iIndex
,
1093 lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
,
1094 pcchApplicationDataBuf
);
1095 return ERROR_CALL_NOT_IMPLEMENTED
;
1098 UINT WINAPI
MsiEnumComponentQualifiersW( LPWSTR szComponent
, DWORD iIndex
,
1099 LPWSTR lpQualifierBuf
, DWORD
* pcchQualifierBuf
,
1100 LPWSTR lpApplicationDataBuf
, DWORD
* pcchApplicationDataBuf
)
1102 FIXME("%s %08lx %p %p %p %p\n", debugstr_w(szComponent
), iIndex
,
1103 lpQualifierBuf
, pcchQualifierBuf
, lpApplicationDataBuf
,
1104 pcchApplicationDataBuf
);
1105 return ERROR_CALL_NOT_IMPLEMENTED
;
1108 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
1109 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
1110 DWORD
* pcchPathBuf
)
1112 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
1113 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
1115 return ERROR_CALL_NOT_IMPLEMENTED
;
1118 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
1119 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
1120 DWORD
* pcchPathBuf
)
1122 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
1123 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
1125 return ERROR_CALL_NOT_IMPLEMENTED
;
1128 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
1129 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
1131 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
1132 return ERROR_CALL_NOT_IMPLEMENTED
;
1135 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
1136 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
1138 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
1139 return ERROR_CALL_NOT_IMPLEMENTED
;
1142 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
1143 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
1146 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
1147 ppcCertContext
, pbHashData
, pcbHashData
);
1148 return ERROR_CALL_NOT_IMPLEMENTED
;
1151 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
1152 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
1155 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
1156 ppcCertContext
, pbHashData
, pcbHashData
);
1157 return ERROR_CALL_NOT_IMPLEMENTED
;
1160 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
1161 LPSTR szValue
, DWORD
*pccbValue
)
1163 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
1164 return ERROR_CALL_NOT_IMPLEMENTED
;
1167 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
1168 LPWSTR szValue
, DWORD
*pccbValue
)
1170 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
1171 return ERROR_CALL_NOT_IMPLEMENTED
;
1174 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
1177 LPWSTR szPack
= NULL
;
1179 TRACE("%s\n", debugstr_a(szPackage
) );
1183 len
= MultiByteToWideChar( CP_ACP
, 0, szPackage
, -1, NULL
, 0 );
1184 szPack
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1186 return ERROR_OUTOFMEMORY
;
1187 MultiByteToWideChar( CP_ACP
, 0, szPackage
, -1, szPack
, len
);
1190 r
= MsiVerifyPackageW( szPack
);
1192 HeapFree( GetProcessHeap(), 0, szPack
);
1197 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
1202 TRACE("%s\n", debugstr_w(szPackage
) );
1204 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
1205 MsiCloseHandle( handle
);
1210 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
1211 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
1213 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
1215 UINT len
, incoming_len
;
1219 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
1220 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1222 return ERROR_OUTOFMEMORY
;
1223 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
1228 len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
1229 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1232 HeapFree( GetProcessHeap(), 0, szwProduct
);
1233 return ERROR_OUTOFMEMORY
;
1235 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
1238 if( pcchBuf
&& *pcchBuf
> 0 )
1239 lpwPathBuf
= HeapAlloc( GetProcessHeap(), 0, *pcchBuf
* sizeof(WCHAR
));
1243 incoming_len
= *pcchBuf
;
1244 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
1246 HeapFree( GetProcessHeap(), 0, szwProduct
);
1247 HeapFree( GetProcessHeap(), 0, szwComponent
);
1250 if (rc
!= INSTALLSTATE_UNKNOWN
)
1251 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
1252 lpPathBuf
, incoming_len
, NULL
, NULL
);
1253 HeapFree( GetProcessHeap(), 0, lpwPathBuf
);
1259 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1260 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1262 WCHAR squished_pc
[GUID_SIZE
];
1264 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1267 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1268 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1270 squash_guid(szProduct
,squished_pc
);
1272 rc
= MSIREG_OpenProductsKey(szProduct
,&hkey
,FALSE
);
1273 if (rc
!= ERROR_SUCCESS
)
1278 rc
= MSIREG_OpenComponentsKey(szComponent
,&hkey
,FALSE
);
1279 if (rc
!= ERROR_SUCCESS
)
1282 *pcchBuf
*= sizeof(WCHAR
);
1283 rc
= RegQueryValueExW(hkey
,squished_pc
,NULL
,NULL
,(LPVOID
)lpPathBuf
,
1285 *pcchBuf
/= sizeof(WCHAR
);
1287 if (rc
!= ERROR_SUCCESS
)
1290 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1291 debugstr_w(szProduct
), debugstr_w(lpPathBuf
));
1293 FIXME("Only working for installed files, not registry keys\n");
1294 if (GetFileAttributesW(lpPathBuf
) != INVALID_FILE_ATTRIBUTES
)
1295 rrc
= INSTALLSTATE_LOCAL
;
1297 rrc
= INSTALLSTATE_ABSENT
;
1304 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1308 LPWSTR szwProduct
= NULL
;
1309 LPWSTR szwFeature
= NULL
;
1313 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
1314 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1316 return ERROR_OUTOFMEMORY
;
1317 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
1322 len
= MultiByteToWideChar( CP_ACP
, 0, szFeature
, -1, NULL
, 0 );
1323 szwFeature
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1326 HeapFree( GetProcessHeap(), 0, szwProduct
);
1327 return ERROR_OUTOFMEMORY
;
1329 MultiByteToWideChar( CP_ACP
, 0, szFeature
, -1, szwFeature
, len
);
1332 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1334 HeapFree( GetProcessHeap(), 0, szwProduct
);
1335 HeapFree( GetProcessHeap(), 0, szwFeature
);
1340 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1342 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1343 return INSTALLSTATE_UNKNOWN
;
1346 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1347 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1349 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1350 UINT len
, ret
= ERROR_OUTOFMEMORY
;
1354 len
= MultiByteToWideChar( CP_ACP
, 0, szFilePath
, -1, NULL
, 0 );
1355 szwFilePath
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1358 MultiByteToWideChar( CP_ACP
, 0, szFilePath
, -1, szwFilePath
, len
);
1361 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1363 lpwVersionBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1364 if( !lpwVersionBuff
)
1368 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1370 lpwLangBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1375 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1376 lpwLangBuff
, pcchLangBuf
);
1378 if( lpwVersionBuff
)
1379 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1380 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1382 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1383 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1386 HeapFree(GetProcessHeap(), 0, szwFilePath
);
1387 HeapFree(GetProcessHeap(), 0, lpwVersionBuff
);
1388 HeapFree(GetProcessHeap(), 0, lpwLangBuff
);
1393 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1394 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1396 static const WCHAR szVersionResource
[] = {'\\',0};
1397 static const WCHAR szVersionFormat
[] = {
1398 '%','d','.','%','d','.','%','d','.','%','d',0};
1399 static const WCHAR szLangFormat
[] = {'%','d',0};
1402 LPVOID lpVer
= NULL
;
1403 VS_FIXEDFILEINFO
*ffi
;
1407 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1408 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1409 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1411 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1413 return GetLastError();
1415 lpVer
= HeapAlloc(GetProcessHeap(), 0, dwVerLen
);
1418 ret
= ERROR_OUTOFMEMORY
;
1422 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1424 ret
= GetLastError();
1427 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1429 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1432 wsprintfW(tmp
, szVersionFormat
,
1433 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1434 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1435 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1436 *pcchVersionBuf
= strlenW(lpVersionBuf
);
1441 *pcchVersionBuf
= 0;
1445 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1447 DWORD lang
= GetUserDefaultLangID();
1449 FIXME("Retrieve language from file\n");
1450 wsprintfW(tmp
, szLangFormat
, lang
);
1451 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1452 *pcchLangBuf
= strlenW(lpLangBuf
);
1456 HeapFree(GetProcessHeap(), 0, lpVer
);
1461 /******************************************************************
1464 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1468 case DLL_PROCESS_ATTACH
:
1469 DisableThreadLibraryCalls(hinstDLL
);
1471 case DLL_PROCESS_DETACH
:
1472 /* FIXME: Cleanup */
1478 typedef struct tagIClassFactoryImpl
1480 IClassFactoryVtbl
*lpVtbl
;
1481 } IClassFactoryImpl
;
1483 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1484 REFIID riid
,LPVOID
*ppobj
)
1486 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1487 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1488 return E_NOINTERFACE
;
1491 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1496 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1501 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1502 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1504 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1506 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1510 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1512 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1514 FIXME("%p %d\n", This
, dolock
);
1518 static IClassFactoryVtbl MsiCF_Vtbl
=
1520 MsiCF_QueryInterface
,
1523 MsiCF_CreateInstance
,
1527 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1529 /******************************************************************
1530 * DllGetClassObject [MSI.@]
1532 HRESULT WINAPI
MSI_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1534 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1536 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1537 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1538 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1539 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1540 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1542 *ppv
= (LPVOID
) &Msi_CF
;
1545 return CLASS_E_CLASSNOTAVAILABLE
;
1548 /******************************************************************
1549 * DllGetVersion [MSI.@]
1551 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
1555 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1556 return E_INVALIDARG
;
1558 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1559 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1560 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1561 pdvi
->dwPlatformID
= 1;
1566 /******************************************************************
1567 * DllCanUnloadNow [MSI.@]
1569 BOOL WINAPI
MSI_DllCanUnloadNow(void)
1574 UINT WINAPI
MsiEnumRelatedProductsW(LPCWSTR szUpgradeCode
, DWORD dwReserved
,
1575 DWORD iProductIndex
, LPWSTR lpProductBuf
)
1577 FIXME("%s %lu %lu %p\n", debugstr_w(szUpgradeCode
), dwReserved
,
1578 iProductIndex
, lpProductBuf
);
1579 return ERROR_CALL_NOT_IMPLEMENTED
;
1582 UINT WINAPI
MsiEnumRelatedProductsA(LPCSTR szUpgradeCode
, DWORD dwReserved
,
1583 DWORD iProductIndex
, LPSTR lpProductBuf
)
1585 FIXME("%s %lu %lu %p\n", debugstr_a(szUpgradeCode
), dwReserved
,
1586 iProductIndex
, lpProductBuf
);
1587 return ERROR_CALL_NOT_IMPLEMENTED
;
1590 UINT WINAPI
MsiGetFeatureUsageW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1591 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1593 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1594 pdwUseCount
, pwDateUsed
);
1595 return ERROR_CALL_NOT_IMPLEMENTED
;
1598 UINT WINAPI
MsiGetFeatureUsageA(LPCSTR szProduct
, LPCSTR szFeature
,
1599 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1601 FIXME("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1602 pdwUseCount
, pwDateUsed
);
1603 return ERROR_CALL_NOT_IMPLEMENTED
;
1606 UINT WINAPI
MsiUseFeatureExW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1607 DWORD dwInstallMode
, DWORD dwReserved
)
1609 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1610 dwInstallMode
, dwReserved
);
1612 return INSTALLSTATE_LOCAL
;
1615 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1616 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1617 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1620 FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1621 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1622 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1624 return ERROR_INDEX_ABSENT
;
1627 UINT WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1628 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1629 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1631 FIXME("%s, %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1632 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1635 return USERINFOSTATE_UNKNOWN
;
1638 UINT WINAPI
MsiCollectUserInfoW(LPWSTR szProduct
)
1640 FIXME("%s\n",debugstr_w(szProduct
));
1641 return ERROR_FUNCTION_FAILED
;