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 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
, DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
);
47 WINE_DEFAULT_DEBUG_CHANNEL(msi
);
50 * The MSVC headers define the MSIDBOPEN_* macros cast to LPCTSTR,
51 * which is a problem because LPCTSTR isn't defined when compiling wine.
52 * To work around this problem, we need to define LPCTSTR as LPCWSTR here,
53 * and make sure to only use it in W functions.
55 #define LPCTSTR LPCWSTR
57 DEFINE_GUID( CLSID_MsiDatabase
, 0x000c1084, 0x0000, 0x0000,
58 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
61 INSTALLUILEVEL gUILevel
= INSTALLUILEVEL_BASIC
;
63 INSTALLUI_HANDLERA gUIHandlerA
= NULL
;
64 INSTALLUI_HANDLERW gUIHandlerW
= NULL
;
66 LPVOID gUIContext
= NULL
;
67 WCHAR gszLogFile
[MAX_PATH
];
68 HINSTANCE msi_hInstance
;
73 * A .msi file is a structured storage file.
74 * It should contain a number of streams.
77 VOID
MSI_CloseDatabase( MSIOBJECTHDR
*arg
)
79 MSIDATABASE
*db
= (MSIDATABASE
*) arg
;
82 free_cached_tables( db
);
83 r
= IStorage_Release( db
->storage
);
85 ERR("database reference count was not zero (%ld)\n", r
);
88 UINT
MSI_OpenDatabaseW(LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIDATABASE
**pdb
)
92 MSIDATABASE
*db
= NULL
;
93 UINT ret
= ERROR_FUNCTION_FAILED
;
97 TRACE("%s %s\n",debugstr_w(szDBPath
),debugstr_w(szPersist
) );
100 return ERROR_INVALID_PARAMETER
;
102 szMode
= (LPWSTR
) szPersist
;
103 if( HIWORD( szPersist
) )
105 /* UINT len = lstrlenW( szPerist ) + 1; */
106 FIXME("don't support persist files yet\b");
107 return ERROR_INVALID_PARAMETER
;
108 /* szMode = HeapAlloc( GetProcessHeap(), 0, len * sizeof (DWORD) ); */
110 else if( szPersist
== MSIDBOPEN_READONLY
)
112 r
= StgOpenStorage( szDBPath
, NULL
,
113 STGM_DIRECT
|STGM_READ
|STGM_SHARE_DENY_WRITE
, NULL
, 0, &stg
);
115 else if( szPersist
== MSIDBOPEN_CREATE
)
117 r
= StgCreateDocfile( szDBPath
,
118 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, 0, &stg
);
119 if( r
== ERROR_SUCCESS
)
121 IStorage_SetClass( stg
, &CLSID_MsiDatabase
);
122 r
= init_string_table( stg
);
125 else if( szPersist
== MSIDBOPEN_TRANSACT
)
127 r
= StgOpenStorage( szDBPath
, NULL
,
128 STGM_DIRECT
|STGM_READWRITE
|STGM_SHARE_EXCLUSIVE
, NULL
, 0, &stg
);
132 ERR("unknown flag %p\n",szPersist
);
133 return ERROR_INVALID_PARAMETER
;
138 FIXME("open failed r = %08lx!\n",r
);
139 return ERROR_FUNCTION_FAILED
;
142 r
= IStorage_Stat( stg
, &stat
, STATFLAG_NONAME
);
145 FIXME("Failed to stat storage\n");
149 if( memcmp( &stat
.clsid
, &CLSID_MsiDatabase
, sizeof (GUID
) ) )
151 ERR("storage GUID is not a MSI database GUID %s\n",
152 debugstr_guid(&stat
.clsid
) );
157 db
= alloc_msiobject( MSIHANDLETYPE_DATABASE
, sizeof (MSIDATABASE
),
161 FIXME("Failed to allocate a handle\n");
165 if( TRACE_ON( msi
) )
166 enum_stream_names( stg
);
171 ret
= load_string_table( db
);
172 if( ret
!= ERROR_SUCCESS
)
175 msiobj_addref( &db
->hdr
);
176 IStorage_AddRef( stg
);
181 msiobj_release( &db
->hdr
);
183 IStorage_Release( stg
);
188 UINT WINAPI
MsiOpenDatabaseW(LPCWSTR szDBPath
, LPCWSTR szPersist
, MSIHANDLE
*phDB
)
193 TRACE("%s %s %p\n",debugstr_w(szDBPath
),debugstr_w(szPersist
), phDB
);
195 ret
= MSI_OpenDatabaseW( szDBPath
, szPersist
, &db
);
196 if( ret
== ERROR_SUCCESS
)
198 *phDB
= alloc_msihandle( &db
->hdr
);
199 msiobj_release( &db
->hdr
);
205 UINT WINAPI
MsiOpenDatabaseA(LPCSTR szDBPath
, LPCSTR szPersist
, MSIHANDLE
*phDB
)
207 HRESULT r
= ERROR_FUNCTION_FAILED
;
208 LPWSTR szwDBPath
= NULL
, szwPersist
= NULL
;
211 TRACE("%s %s %p\n", debugstr_a(szDBPath
), debugstr_a(szPersist
), phDB
);
215 len
= MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, NULL
, 0 );
216 szwDBPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
219 MultiByteToWideChar( CP_ACP
, 0, szDBPath
, -1, szwDBPath
, len
);
222 if( HIWORD(szPersist
) )
224 len
= MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, NULL
, 0 );
225 szwPersist
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
228 MultiByteToWideChar( CP_ACP
, 0, szPersist
, -1, szwPersist
, len
);
231 szwPersist
= (LPWSTR
) szPersist
;
233 r
= MsiOpenDatabaseW( szwDBPath
, szwPersist
, phDB
);
236 HeapFree( GetProcessHeap(), 0, szwPersist
);
237 HeapFree( GetProcessHeap(), 0, szwDBPath
);
242 UINT WINAPI
MsiOpenProductA(LPCSTR szProduct
, MSIHANDLE
*phProduct
)
245 LPWSTR szwProd
= NULL
;
247 TRACE("%s %p\n",debugstr_a(szProduct
), phProduct
);
251 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
252 szwProd
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof (WCHAR
) );
254 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProd
, len
);
257 ret
= MsiOpenProductW( szwProd
, phProduct
);
259 HeapFree( GetProcessHeap(), 0, szwProd
);
264 UINT WINAPI
MsiOpenProductW(LPCWSTR szProduct
, MSIHANDLE
*phProduct
)
266 static const WCHAR szLocalPackage
[] = {
267 'L','o','c','a','l','P','a','c','k','a','g','e', 0
271 HKEY hKeyProduct
= NULL
;
274 TRACE("%s %p\n",debugstr_w(szProduct
), phProduct
);
276 r
= MSIREG_OpenUninstallKey(szProduct
,&hKeyProduct
,FALSE
);
277 if( r
!= ERROR_SUCCESS
)
279 r
= ERROR_UNKNOWN_PRODUCT
;
283 /* find the size of the path */
285 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
286 NULL
, &type
, NULL
, &count
);
287 if( r
!= ERROR_SUCCESS
)
289 r
= ERROR_UNKNOWN_PRODUCT
;
293 /* now alloc and fetch the path of the database to open */
294 path
= HeapAlloc( GetProcessHeap(), 0, count
);
298 r
= RegQueryValueExW( hKeyProduct
, szLocalPackage
,
299 NULL
, &type
, (LPBYTE
) path
, &count
);
300 if( r
!= ERROR_SUCCESS
)
302 r
= ERROR_UNKNOWN_PRODUCT
;
306 r
= MsiOpenPackageW( path
, phProduct
);
309 HeapFree( GetProcessHeap(), 0, path
);
311 RegCloseKey( hKeyProduct
);
316 UINT WINAPI
MsiAdvertiseProductA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
317 LPCSTR szTransforms
, LANGID lgidLanguage
)
319 FIXME("%s %s %s %08x\n",debugstr_a(szPackagePath
),
320 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
), lgidLanguage
);
321 return ERROR_CALL_NOT_IMPLEMENTED
;
324 UINT WINAPI
MsiAdvertiseProductW(LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
325 LPCWSTR szTransforms
, LANGID lgidLanguage
)
327 FIXME("%s %s %s %08x\n",debugstr_w(szPackagePath
),
328 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
), lgidLanguage
);
329 return ERROR_CALL_NOT_IMPLEMENTED
;
332 UINT WINAPI
MsiAdvertiseProductExA(LPCSTR szPackagePath
, LPCSTR szScriptfilePath
,
333 LPCSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
335 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_a(szPackagePath
),
336 debugstr_a(szScriptfilePath
), debugstr_a(szTransforms
),
337 lgidLanguage
, dwPlatform
, dwOptions
);
338 return ERROR_CALL_NOT_IMPLEMENTED
;
341 UINT WINAPI
MsiAdvertiseProductExW( LPCWSTR szPackagePath
, LPCWSTR szScriptfilePath
,
342 LPCWSTR szTransforms
, LANGID lgidLanguage
, DWORD dwPlatform
, DWORD dwOptions
)
344 FIXME("%s %s %s %08x %08lx %08lx\n", debugstr_w(szPackagePath
),
345 debugstr_w(szScriptfilePath
), debugstr_w(szTransforms
),
346 lgidLanguage
, dwPlatform
, dwOptions
);
347 return ERROR_CALL_NOT_IMPLEMENTED
;
350 UINT WINAPI
MsiInstallProductA(LPCSTR szPackagePath
, LPCSTR szCommandLine
)
352 LPWSTR szwPath
= NULL
, szwCommand
= NULL
;
353 UINT r
= ERROR_FUNCTION_FAILED
; /* FIXME: check return code */
355 TRACE("%s %s\n",debugstr_a(szPackagePath
), debugstr_a(szCommandLine
));
359 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, NULL
, 0 );
360 szwPath
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
363 MultiByteToWideChar( CP_ACP
, 0, szPackagePath
, -1, szwPath
, len
);
368 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, NULL
, 0 );
369 szwCommand
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
372 MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, szwCommand
, len
);
375 r
= MsiInstallProductW( szwPath
, szwCommand
);
378 HeapFree( GetProcessHeap(), 0, szwPath
);
379 HeapFree( GetProcessHeap(), 0, szwCommand
);
384 UINT WINAPI
MsiInstallProductW(LPCWSTR szPackagePath
, LPCWSTR szCommandLine
)
386 MSIPACKAGE
*package
= NULL
;
387 UINT rc
= ERROR_SUCCESS
;
390 FIXME("%s %s\n",debugstr_w(szPackagePath
), debugstr_w(szCommandLine
));
392 rc
= MsiVerifyPackageW(szPackagePath
);
393 if (rc
!= ERROR_SUCCESS
)
396 rc
= MSI_OpenPackageW(szPackagePath
,&package
);
397 if (rc
!= ERROR_SUCCESS
)
400 handle
= alloc_msihandle( &package
->hdr
);
402 rc
= ACTION_DoTopLevelINSTALL(package
, szPackagePath
, szCommandLine
);
404 MsiCloseHandle(handle
);
405 msiobj_release( &package
->hdr
);
409 UINT WINAPI
MsiReinstallProductA(LPCSTR szProduct
, DWORD dwReinstallMode
)
411 FIXME("%s %08lx\n", debugstr_a(szProduct
), dwReinstallMode
);
412 return ERROR_CALL_NOT_IMPLEMENTED
;
415 UINT WINAPI
MsiReinstallProductW(LPCWSTR szProduct
, DWORD dwReinstallMode
)
417 FIXME("%s %08lx\n", debugstr_w(szProduct
), dwReinstallMode
);
418 return ERROR_CALL_NOT_IMPLEMENTED
;
421 UINT WINAPI
MsiApplyPatchA(LPCSTR szPatchPackage
, LPCSTR szInstallPackage
,
422 INSTALLTYPE eInstallType
, LPCSTR szCommandLine
)
424 FIXME("%s %s %d %s\n", debugstr_a(szPatchPackage
), debugstr_a(szInstallPackage
),
425 eInstallType
, debugstr_a(szCommandLine
));
426 return ERROR_CALL_NOT_IMPLEMENTED
;
429 UINT WINAPI
MsiApplyPatchW(LPCWSTR szPatchPackage
, LPCWSTR szInstallPackage
,
430 INSTALLTYPE eInstallType
, LPCWSTR szCommandLine
)
432 FIXME("%s %s %d %s\n", debugstr_w(szPatchPackage
), debugstr_w(szInstallPackage
),
433 eInstallType
, debugstr_w(szCommandLine
));
434 return ERROR_CALL_NOT_IMPLEMENTED
;
437 UINT WINAPI
MsiConfigureProductExW(LPCWSTR szProduct
, int iInstallLevel
,
438 INSTALLSTATE eInstallState
, LPCWSTR szCommandLine
)
445 static const WCHAR szSouceList
[] = {
446 'S','o','u','r','c','e','L','i','s','t',0};
447 static const WCHAR szLUS
[] = {
448 'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
449 WCHAR sourcepath
[0x200];
450 static const WCHAR szInstalled
[] = {
451 ' ','I','n','s','t','a','l','l','e','d','=','1',0};
454 FIXME("%s %d %d %s\n",debugstr_w(szProduct
), iInstallLevel
, eInstallState
,
455 debugstr_w(szCommandLine
));
457 if (eInstallState
!= INSTALLSTATE_LOCAL
&&
458 eInstallState
!= INSTALLSTATE_DEFAULT
)
460 FIXME("Not implemented for anything other than local installs\n");
461 return ERROR_CALL_NOT_IMPLEMENTED
;
464 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
465 if (rc
!= ERROR_SUCCESS
)
468 rc
= RegOpenKeyW(hkey
,szSouceList
,&hkey1
);
469 if (rc
!= ERROR_SUCCESS
)
472 sz
= sizeof(sourcepath
);
473 rc
= RegQueryValueExW(hkey1
, szLUS
, NULL
, NULL
,(LPBYTE
)sourcepath
, &sz
);
474 if (rc
!= ERROR_SUCCESS
)
479 * ok 1, we need to find the msi file for this product.
480 * 2, find the source dir for the files
481 * 3, do the configure/install.
482 * 4, cleanupany runonce entry.
485 rc
= MsiOpenProductW(szProduct
,&handle
);
486 if (rc
!= ERROR_SUCCESS
)
489 package
= msihandle2msiinfo(handle
, MSIHANDLETYPE_PACKAGE
);
492 rc
= ERROR_INVALID_HANDLE
;
496 sz
= strlenW(szInstalled
);
499 sz
+= strlenW(szCommandLine
);
501 commandline
= HeapAlloc(GetProcessHeap(),0,sz
* sizeof(WCHAR
));
504 strcpyW(commandline
,szCommandLine
);
508 if (MsiQueryProductStateW(szProduct
) != INSTALLSTATE_UNKNOWN
)
509 strcatW(commandline
,szInstalled
);
511 rc
= ACTION_DoTopLevelINSTALL(package
, sourcepath
, commandline
);
513 msiobj_release( &package
->hdr
);
515 HeapFree(GetProcessHeap(),0,commandline
);
522 UINT WINAPI
MsiConfigureProductExA(LPCSTR szProduct
, int iInstallLevel
,
523 INSTALLSTATE eInstallState
, LPCSTR szCommandLine
)
525 LPWSTR szwProduct
= NULL
;
526 LPWSTR szwCommandLine
= NULL
;
527 UINT hr
= ERROR_FUNCTION_FAILED
;
531 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
532 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
535 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
540 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, NULL
, 0 );
541 szwCommandLine
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
544 MultiByteToWideChar( CP_ACP
, 0, szCommandLine
, -1, szwCommandLine
, len
);
547 hr
= MsiConfigureProductExW( szwProduct
, iInstallLevel
, eInstallState
,
550 HeapFree( GetProcessHeap(), 0, szwProduct
);
551 HeapFree( GetProcessHeap(), 0, szwCommandLine
);
556 UINT WINAPI
MsiConfigureProductA(LPCSTR szProduct
, int iInstallLevel
,
557 INSTALLSTATE eInstallState
)
559 LPWSTR szwProduct
= NULL
;
560 UINT hr
= ERROR_SUCCESS
;
562 FIXME("%s %d %d\n",debugstr_a(szProduct
), iInstallLevel
, eInstallState
);
566 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
567 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
570 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
573 hr
= MsiConfigureProductW( szwProduct
, iInstallLevel
, eInstallState
);
576 HeapFree( GetProcessHeap(), 0, szwProduct
);
581 UINT WINAPI
MsiConfigureProductW(LPCWSTR szProduct
, int iInstallLevel
,
582 INSTALLSTATE eInstallState
)
584 FIXME("%s %d %d\n", debugstr_w(szProduct
), iInstallLevel
, eInstallState
);
586 return MsiConfigureProductExW(szProduct
, iInstallLevel
, eInstallState
,
590 UINT WINAPI
MsiGetProductCodeA(LPCSTR szComponent
, LPSTR szBuffer
)
592 LPWSTR szwComponent
= NULL
;
593 UINT hr
= ERROR_INSTALL_FAILURE
;
594 WCHAR szwBuffer
[GUID_SIZE
];
596 FIXME("%s %s\n",debugstr_a(szComponent
), debugstr_a(szBuffer
));
600 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
601 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
604 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
607 return ERROR_INVALID_PARAMETER
;
609 hr
= MsiGetProductCodeW( szwComponent
, szwBuffer
);
611 if( ERROR_SUCCESS
== hr
)
612 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, GUID_SIZE
, NULL
, NULL
);
615 HeapFree( GetProcessHeap(), 0, szwComponent
);
620 UINT WINAPI
MsiGetProductCodeW(LPCWSTR szComponent
, LPWSTR szBuffer
)
622 FIXME("%s %s\n",debugstr_w(szComponent
), debugstr_w(szBuffer
));
623 if (NULL
== szComponent
)
624 return ERROR_INVALID_PARAMETER
;
625 return ERROR_CALL_NOT_IMPLEMENTED
;
628 UINT WINAPI
MsiGetProductInfoA(LPCSTR szProduct
, LPCSTR szAttribute
,
629 LPSTR szBuffer
, DWORD
*pcchValueBuf
)
631 LPWSTR szwProduct
= NULL
, szwAttribute
= NULL
, szwBuffer
= NULL
;
632 UINT hr
= ERROR_INSTALL_FAILURE
;
634 FIXME("%s %s %p %p\n",debugstr_a(szProduct
), debugstr_a(szAttribute
),
635 szBuffer
, pcchValueBuf
);
637 if( NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
638 return ERROR_INVALID_PARAMETER
;
641 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
642 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
645 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
648 return ERROR_INVALID_PARAMETER
;
652 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szAttribute
, -1, NULL
, 0 );
653 szwAttribute
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
656 MultiByteToWideChar( CP_ACP
, 0, szAttribute
, -1, szwAttribute
, len
);
660 hr
= ERROR_INVALID_PARAMETER
;
666 szwBuffer
= HeapAlloc( GetProcessHeap(), 0, (*pcchValueBuf
) * sizeof(WCHAR
) );
671 hr
= MsiGetProductInfoW( szwProduct
, szwAttribute
, szwBuffer
, pcchValueBuf
);
673 if( ERROR_SUCCESS
== hr
)
674 WideCharToMultiByte(CP_ACP
, 0, szwBuffer
, -1, szBuffer
, *pcchValueBuf
, NULL
, NULL
);
677 HeapFree( GetProcessHeap(), 0, szwProduct
);
678 HeapFree( GetProcessHeap(), 0, szwAttribute
);
679 HeapFree( GetProcessHeap(), 0, szwBuffer
);
684 UINT WINAPI
MsiGetProductInfoW(LPCWSTR szProduct
, LPCWSTR szAttribute
,
685 LPWSTR szBuffer
, DWORD
*pcchValueBuf
)
690 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szAttribute
),
691 szBuffer
, pcchValueBuf
);
693 if (NULL
!= szBuffer
&& NULL
== pcchValueBuf
)
694 return ERROR_INVALID_PARAMETER
;
695 if (NULL
== szProduct
|| NULL
== szAttribute
)
696 return ERROR_INVALID_PARAMETER
;
698 hr
= MsiOpenProductW(szProduct
, &hProduct
);
699 if (ERROR_SUCCESS
!= hr
)
702 hr
= MsiGetPropertyW(hProduct
, szAttribute
, szBuffer
, pcchValueBuf
);
703 MsiCloseHandle(hProduct
);
707 UINT WINAPI
MsiDatabaseImportA(LPCSTR szFolderPath
, LPCSTR szFilename
)
709 FIXME("%s %s\n",debugstr_a(szFolderPath
), debugstr_a(szFilename
));
710 return ERROR_CALL_NOT_IMPLEMENTED
;
713 UINT WINAPI
MsiDatabaseImportW(LPCWSTR szFolderPath
, LPCWSTR szFilename
)
715 FIXME("%s %s\n",debugstr_w(szFolderPath
), debugstr_w(szFilename
));
716 return ERROR_CALL_NOT_IMPLEMENTED
;
719 UINT WINAPI
MsiEnableLogA(DWORD dwLogMode
, LPCSTR szLogFile
, DWORD attributes
)
721 LPWSTR szwLogFile
= NULL
;
722 UINT hr
= ERROR_INSTALL_FAILURE
;
724 FIXME("%08lx %s %08lx\n", dwLogMode
, debugstr_a(szLogFile
), attributes
);
728 UINT len
= MultiByteToWideChar( CP_ACP
, 0, szLogFile
, -1, NULL
, 0 );
729 szwLogFile
= HeapAlloc( GetProcessHeap(), 0, len
* sizeof(WCHAR
) );
732 MultiByteToWideChar( CP_ACP
, 0, szLogFile
, -1, szwLogFile
, len
);
735 return ERROR_INVALID_PARAMETER
;
737 hr
= MsiEnableLogW( dwLogMode
, szwLogFile
, attributes
);
740 HeapFree( GetProcessHeap(), 0, szwLogFile
);
745 UINT WINAPI
MsiEnableLogW(DWORD dwLogMode
, LPCWSTR szLogFile
, DWORD attributes
)
747 HANDLE file
= INVALID_HANDLE_VALUE
;
749 TRACE("%08lx %s %08lx\n", dwLogMode
, debugstr_w(szLogFile
), attributes
);
751 strcpyW(gszLogFile
,szLogFile
);
752 if (!(attributes
& INSTALLLOGATTRIBUTES_APPEND
))
753 DeleteFileW(szLogFile
);
754 file
= CreateFileW(szLogFile
, GENERIC_WRITE
, 0, NULL
, OPEN_ALWAYS
,
755 FILE_ATTRIBUTE_NORMAL
, NULL
);
756 if (file
!= INVALID_HANDLE_VALUE
)
759 ERR("Unable to enable log %s\n",debugstr_w(szLogFile
));
761 return ERROR_SUCCESS
;
764 INSTALLSTATE WINAPI
MsiQueryProductStateA(LPCSTR szProduct
)
770 len
= MultiByteToWideChar(CP_ACP
,0,szProduct
,-1,NULL
,0);
771 szwProduct
= HeapAlloc(GetProcessHeap(),0,len
*sizeof(WCHAR
));
772 MultiByteToWideChar(CP_ACP
,0,szProduct
,-1,szwProduct
,len
);
773 rc
= MsiQueryProductStateW(szwProduct
);
774 HeapFree(GetProcessHeap(),0,szwProduct
);
778 INSTALLSTATE WINAPI
MsiQueryProductStateW(LPCWSTR szProduct
)
781 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
783 static const WCHAR szWindowsInstaller
[] = {
784 'W','i','n','d','o','w','s','I','n','s','t','a','l','l','e','r',0 };
787 TRACE("%s\n", debugstr_w(szProduct
));
789 rc
= MSIREG_OpenUserProductsKey(szProduct
,&hkey
,FALSE
);
790 if (rc
!= ERROR_SUCCESS
)
795 rc
= MSIREG_OpenUninstallKey(szProduct
,&hkey
,FALSE
);
796 if (rc
!= ERROR_SUCCESS
)
800 rc
= RegQueryValueExW(hkey
,szWindowsInstaller
,NULL
,NULL
,(LPVOID
)&rrc
, &sz
);
801 if (rc
!= ERROR_SUCCESS
)
808 rrc
= INSTALLSTATE_DEFAULT
;
811 FIXME("Unknown install state read from registry (%i)\n",rrc
);
812 rrc
= INSTALLSTATE_UNKNOWN
;
820 INSTALLUILEVEL WINAPI
MsiSetInternalUI(INSTALLUILEVEL dwUILevel
, HWND
*phWnd
)
822 INSTALLUILEVEL old
= gUILevel
;
823 HWND oldwnd
= gUIhwnd
;
825 TRACE("%08x %p\n", dwUILevel
, phWnd
);
827 gUILevel
= dwUILevel
;
836 INSTALLUI_HANDLERA WINAPI
MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler
,
837 DWORD dwMessageFilter
, LPVOID pvContext
)
839 INSTALLUI_HANDLERA prev
= gUIHandlerA
;
841 TRACE("%p %lx %p\n",puiHandler
, dwMessageFilter
,pvContext
);
842 gUIHandlerA
= puiHandler
;
843 gUIFilter
= dwMessageFilter
;
844 gUIContext
= pvContext
;
849 INSTALLUI_HANDLERW WINAPI
MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler
,
850 DWORD dwMessageFilter
, LPVOID pvContext
)
852 INSTALLUI_HANDLERW prev
= gUIHandlerW
;
854 TRACE("%p %lx %p\n",puiHandler
,dwMessageFilter
,pvContext
);
855 gUIHandlerW
= puiHandler
;
856 gUIFilter
= dwMessageFilter
;
857 gUIContext
= pvContext
;
862 /******************************************************************
863 * MsiLoadStringW [MSI.@]
865 * Loads a string from MSI's string resources.
869 * handle [I] only -1 is handled currently
870 * id [I] id of the string to be loaded
871 * lpBuffer [O] buffer for the string to be written to
872 * nBufferMax [I] maximum size of the buffer in characters
873 * lang [I] the preferred language for the string
877 * If successful, this function returns the language id of the string loaded
878 * If the function fails, the function returns zero.
882 * The type of the first parameter is unknown. LoadString's prototype
883 * suggests that it might be a module handle. I have made it an MSI handle
884 * for starters, as -1 is an invalid MSI handle, but not an invalid module
885 * handle. Maybe strings can be stored in an MSI database somehow.
887 LANGID WINAPI
MsiLoadStringW( MSIHANDLE handle
, UINT id
, LPWSTR lpBuffer
,
888 int nBufferMax
, LANGID lang
)
895 TRACE("%ld %u %p %d %d\n", handle
, id
, lpBuffer
, nBufferMax
, lang
);
898 FIXME("don't know how to deal with handle = %08lx\n", handle
);
901 lang
= GetUserDefaultLangID();
903 hres
= FindResourceExW( msi_hInstance
, (LPCWSTR
) RT_STRING
,
907 hResData
= LoadResource( msi_hInstance
, hres
);
910 p
= LockResource( hResData
);
914 for (i
= 0; i
< (id
&0xf); i
++)
918 if( nBufferMax
<= len
)
921 memcpy( lpBuffer
, p
+1, len
* sizeof(WCHAR
));
924 TRACE("found -> %s\n", debugstr_w(lpBuffer
));
929 LANGID WINAPI
MsiLoadStringA( MSIHANDLE handle
, UINT id
, LPSTR lpBuffer
,
930 int nBufferMax
, LANGID lang
)
936 bufW
= HeapAlloc(GetProcessHeap(), 0, nBufferMax
*sizeof(WCHAR
));
937 r
= MsiLoadStringW(handle
, id
, bufW
, nBufferMax
, lang
);
940 len
= WideCharToMultiByte(CP_ACP
, 0, bufW
, -1, NULL
, 0, NULL
, NULL
);
941 if( len
<= nBufferMax
)
942 WideCharToMultiByte( CP_ACP
, 0, bufW
, -1,
943 lpBuffer
, nBufferMax
, NULL
, NULL
);
947 HeapFree(GetProcessHeap(), 0, bufW
);
951 INSTALLSTATE WINAPI
MsiLocateComponentA(LPCSTR szComponent
, LPSTR lpPathBuf
,
954 FIXME("%s %p %08lx\n", debugstr_a(szComponent
), lpPathBuf
, *pcchBuf
);
955 return INSTALLSTATE_UNKNOWN
;
958 INSTALLSTATE WINAPI
MsiLocateComponentW(LPCWSTR szComponent
, LPSTR lpPathBuf
,
961 FIXME("%s %p %08lx\n", debugstr_w(szComponent
), lpPathBuf
, *pcchBuf
);
962 return INSTALLSTATE_UNKNOWN
;
965 UINT WINAPI
MsiMessageBoxA(HWND hWnd
, LPCSTR lpText
, LPCSTR lpCaption
, UINT uType
,
966 WORD wLanguageId
, DWORD f
)
968 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_a(lpText
),debugstr_a(lpCaption
),
969 uType
,wLanguageId
,f
);
970 return ERROR_CALL_NOT_IMPLEMENTED
;
973 UINT WINAPI
MsiMessageBoxW(HWND hWnd
, LPCWSTR lpText
, LPCWSTR lpCaption
, UINT uType
,
974 WORD wLanguageId
, DWORD f
)
976 FIXME("%p %s %s %u %08x %08lx\n",hWnd
,debugstr_w(lpText
),debugstr_w(lpCaption
),
977 uType
,wLanguageId
,f
);
978 return ERROR_CALL_NOT_IMPLEMENTED
;
981 UINT WINAPI
MsiProvideAssemblyA( LPCSTR szAssemblyName
, LPCSTR szAppContext
,
982 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPSTR lpPathBuf
,
985 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_a(szAssemblyName
),
986 debugstr_a(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
988 return ERROR_CALL_NOT_IMPLEMENTED
;
991 UINT WINAPI
MsiProvideAssemblyW( LPCWSTR szAssemblyName
, LPCWSTR szAppContext
,
992 DWORD dwInstallMode
, DWORD dwAssemblyInfo
, LPWSTR lpPathBuf
,
995 FIXME("%s %s %08lx %08lx %p %p\n", debugstr_w(szAssemblyName
),
996 debugstr_w(szAppContext
), dwInstallMode
, dwAssemblyInfo
, lpPathBuf
,
998 return ERROR_CALL_NOT_IMPLEMENTED
;
1001 UINT WINAPI
MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor
,
1002 LPSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
1004 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
1005 return ERROR_CALL_NOT_IMPLEMENTED
;
1008 UINT WINAPI
MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor
,
1009 LPWSTR szPath
, DWORD
*pcchPath
, DWORD
*pcchArgs
)
1011 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor
), szPath
, pcchPath
, pcchArgs
);
1012 return ERROR_CALL_NOT_IMPLEMENTED
;
1015 HRESULT WINAPI
MsiGetFileSignatureInformationA( LPCSTR szSignedObjectPath
,
1016 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
1019 FIXME("%s %08lx %p %p %p\n", debugstr_a(szSignedObjectPath
), dwFlags
,
1020 ppcCertContext
, pbHashData
, pcbHashData
);
1021 return ERROR_CALL_NOT_IMPLEMENTED
;
1024 HRESULT WINAPI
MsiGetFileSignatureInformationW( LPCWSTR szSignedObjectPath
,
1025 DWORD dwFlags
, PCCERT_CONTEXT
* ppcCertContext
, BYTE
* pbHashData
,
1028 FIXME("%s %08lx %p %p %p\n", debugstr_w(szSignedObjectPath
), dwFlags
,
1029 ppcCertContext
, pbHashData
, pcbHashData
);
1030 return ERROR_CALL_NOT_IMPLEMENTED
;
1033 UINT WINAPI
MsiGetProductPropertyA( MSIHANDLE hProduct
, LPCSTR szProperty
,
1034 LPSTR szValue
, DWORD
*pccbValue
)
1036 FIXME("%ld %s %p %p\n", hProduct
, debugstr_a(szProperty
), szValue
, pccbValue
);
1037 return ERROR_CALL_NOT_IMPLEMENTED
;
1040 UINT WINAPI
MsiGetProductPropertyW( MSIHANDLE hProduct
, LPCWSTR szProperty
,
1041 LPWSTR szValue
, DWORD
*pccbValue
)
1043 FIXME("%ld %s %p %p\n", hProduct
, debugstr_w(szProperty
), szValue
, pccbValue
);
1044 return ERROR_CALL_NOT_IMPLEMENTED
;
1047 UINT WINAPI
MsiVerifyPackageA( LPCSTR szPackage
)
1050 LPWSTR szPack
= NULL
;
1052 TRACE("%s\n", debugstr_a(szPackage
) );
1056 len
= MultiByteToWideChar( CP_ACP
, 0, szPackage
, -1, NULL
, 0 );
1057 szPack
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1059 return ERROR_OUTOFMEMORY
;
1060 MultiByteToWideChar( CP_ACP
, 0, szPackage
, -1, szPack
, len
);
1063 r
= MsiVerifyPackageW( szPack
);
1065 HeapFree( GetProcessHeap(), 0, szPack
);
1070 UINT WINAPI
MsiVerifyPackageW( LPCWSTR szPackage
)
1075 TRACE("%s\n", debugstr_w(szPackage
) );
1077 r
= MsiOpenDatabaseW( szPackage
, MSIDBOPEN_READONLY
, &handle
);
1078 MsiCloseHandle( handle
);
1083 INSTALLSTATE WINAPI
MsiGetComponentPathA(LPCSTR szProduct
, LPCSTR szComponent
,
1084 LPSTR lpPathBuf
, DWORD
* pcchBuf
)
1086 LPWSTR szwProduct
= NULL
, szwComponent
= NULL
, lpwPathBuf
= NULL
;
1088 UINT len
, incoming_len
;
1092 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
1093 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1095 return ERROR_OUTOFMEMORY
;
1096 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
1101 len
= MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, NULL
, 0 );
1102 szwComponent
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1105 HeapFree( GetProcessHeap(), 0, szwProduct
);
1106 return ERROR_OUTOFMEMORY
;
1108 MultiByteToWideChar( CP_ACP
, 0, szComponent
, -1, szwComponent
, len
);
1111 if( pcchBuf
&& *pcchBuf
> 0 )
1112 lpwPathBuf
= HeapAlloc( GetProcessHeap(), 0, *pcchBuf
* sizeof(WCHAR
));
1116 incoming_len
= *pcchBuf
;
1117 rc
= MsiGetComponentPathW(szwProduct
, szwComponent
, lpwPathBuf
, pcchBuf
);
1119 HeapFree( GetProcessHeap(), 0, szwProduct
);
1120 HeapFree( GetProcessHeap(), 0, szwComponent
);
1123 if (rc
!= INSTALLSTATE_UNKNOWN
)
1124 WideCharToMultiByte(CP_ACP
, 0, lpwPathBuf
, incoming_len
,
1125 lpPathBuf
, incoming_len
, NULL
, NULL
);
1126 HeapFree( GetProcessHeap(), 0, lpwPathBuf
);
1132 INSTALLSTATE WINAPI
MsiGetComponentPathW(LPCWSTR szProduct
, LPCWSTR szComponent
,
1133 LPWSTR lpPathBuf
, DWORD
* pcchBuf
)
1135 WCHAR squished_pc
[GUID_SIZE
];
1137 INSTALLSTATE rrc
= INSTALLSTATE_UNKNOWN
;
1142 TRACE("%s %s %p %p\n", debugstr_w(szProduct
),
1143 debugstr_w(szComponent
), lpPathBuf
, pcchBuf
);
1145 if( lpPathBuf
&& !pcchBuf
)
1146 return INSTALLSTATE_INVALIDARG
;
1148 squash_guid(szProduct
,squished_pc
);
1150 rc
= MSIREG_OpenProductsKey( szProduct
, &hkey
, FALSE
);
1151 if( rc
!= ERROR_SUCCESS
)
1156 rc
= MSIREG_OpenComponentsKey( szComponent
, &hkey
, FALSE
);
1157 if( rc
!= ERROR_SUCCESS
)
1162 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, &type
, NULL
, &sz
);
1163 if( rc
!= ERROR_SUCCESS
)
1165 if( type
!= REG_SZ
)
1168 sz
+= sizeof(WCHAR
);
1169 path
= HeapAlloc( GetProcessHeap(), 0, sz
);
1173 rc
= RegQueryValueExW( hkey
, squished_pc
, NULL
, NULL
, (LPVOID
) path
, &sz
);
1174 if( rc
!= ERROR_SUCCESS
)
1177 TRACE("found path of (%s:%s)(%s)\n", debugstr_w(szComponent
),
1178 debugstr_w(szProduct
), debugstr_w(path
));
1182 FIXME("Registry entry.. check entry\n");
1183 rrc
= INSTALLSTATE_LOCAL
;
1187 /* PROBABLY a file */
1188 if ( GetFileAttributesW(path
) != INVALID_FILE_ATTRIBUTES
)
1189 rrc
= INSTALLSTATE_LOCAL
;
1191 rrc
= INSTALLSTATE_ABSENT
;
1196 sz
= sz
/ sizeof(WCHAR
);
1197 if( *pcchBuf
>= sz
)
1198 strcpyW( lpPathBuf
, path
);
1203 HeapFree(GetProcessHeap(), 0, path
);
1208 INSTALLSTATE WINAPI
MsiQueryFeatureStateA(LPCSTR szProduct
, LPCSTR szFeature
)
1212 LPWSTR szwProduct
= NULL
;
1213 LPWSTR szwFeature
= NULL
;
1217 len
= MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, NULL
, 0 );
1218 szwProduct
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1220 return ERROR_OUTOFMEMORY
;
1221 MultiByteToWideChar( CP_ACP
, 0, szProduct
, -1, szwProduct
, len
);
1226 len
= MultiByteToWideChar( CP_ACP
, 0, szFeature
, -1, NULL
, 0 );
1227 szwFeature
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1230 HeapFree( GetProcessHeap(), 0, szwProduct
);
1231 return ERROR_OUTOFMEMORY
;
1233 MultiByteToWideChar( CP_ACP
, 0, szFeature
, -1, szwFeature
, len
);
1236 rc
= MsiQueryFeatureStateW(szwProduct
, szwFeature
);
1238 HeapFree( GetProcessHeap(), 0, szwProduct
);
1239 HeapFree( GetProcessHeap(), 0, szwFeature
);
1244 INSTALLSTATE WINAPI
MsiQueryFeatureStateW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1246 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1248 * Iterates all the features components and the features parents components
1250 return INSTALLSTATE_LOCAL
;
1253 UINT WINAPI
MsiGetFileVersionA(LPCSTR szFilePath
, LPSTR lpVersionBuf
,
1254 DWORD
* pcchVersionBuf
, LPSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1256 LPWSTR szwFilePath
= NULL
, lpwVersionBuff
= NULL
, lpwLangBuff
= NULL
;
1257 UINT len
, ret
= ERROR_OUTOFMEMORY
;
1261 len
= MultiByteToWideChar( CP_ACP
, 0, szFilePath
, -1, NULL
, 0 );
1262 szwFilePath
= HeapAlloc( GetProcessHeap(), 0, len
*sizeof(WCHAR
) );
1265 MultiByteToWideChar( CP_ACP
, 0, szFilePath
, -1, szwFilePath
, len
);
1268 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1270 lpwVersionBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1271 if( !lpwVersionBuff
)
1275 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1277 lpwLangBuff
= HeapAlloc(GetProcessHeap(), 0, *pcchVersionBuf
*sizeof(WCHAR
));
1282 ret
= MsiGetFileVersionW(szwFilePath
, lpwVersionBuff
, pcchVersionBuf
,
1283 lpwLangBuff
, pcchLangBuf
);
1285 if( lpwVersionBuff
)
1286 WideCharToMultiByte(CP_ACP
, 0, lpwVersionBuff
, -1,
1287 lpVersionBuf
, *pcchVersionBuf
, NULL
, NULL
);
1289 WideCharToMultiByte(CP_ACP
, 0, lpwLangBuff
, -1,
1290 lpLangBuf
, *pcchLangBuf
, NULL
, NULL
);
1293 HeapFree(GetProcessHeap(), 0, szwFilePath
);
1294 HeapFree(GetProcessHeap(), 0, lpwVersionBuff
);
1295 HeapFree(GetProcessHeap(), 0, lpwLangBuff
);
1300 UINT WINAPI
MsiGetFileVersionW(LPCWSTR szFilePath
, LPWSTR lpVersionBuf
,
1301 DWORD
* pcchVersionBuf
, LPWSTR lpLangBuf
, DWORD
* pcchLangBuf
)
1303 static const WCHAR szVersionResource
[] = {'\\',0};
1304 static const WCHAR szVersionFormat
[] = {
1305 '%','d','.','%','d','.','%','d','.','%','d',0};
1306 static const WCHAR szLangFormat
[] = {'%','d',0};
1309 LPVOID lpVer
= NULL
;
1310 VS_FIXEDFILEINFO
*ffi
;
1314 TRACE("%s %p %ld %p %ld\n", debugstr_w(szFilePath
),
1315 lpVersionBuf
, pcchVersionBuf
?*pcchVersionBuf
:0,
1316 lpLangBuf
, pcchLangBuf
?*pcchLangBuf
:0);
1318 dwVerLen
= GetFileVersionInfoSizeW(szFilePath
, NULL
);
1320 return GetLastError();
1322 lpVer
= HeapAlloc(GetProcessHeap(), 0, dwVerLen
);
1325 ret
= ERROR_OUTOFMEMORY
;
1329 if( !GetFileVersionInfoW(szFilePath
, 0, dwVerLen
, lpVer
) )
1331 ret
= GetLastError();
1334 if( lpVersionBuf
&& pcchVersionBuf
&& *pcchVersionBuf
)
1336 if( VerQueryValueW(lpVer
, szVersionResource
, (LPVOID
*)&ffi
, &puLen
) &&
1339 wsprintfW(tmp
, szVersionFormat
,
1340 HIWORD(ffi
->dwFileVersionMS
), LOWORD(ffi
->dwFileVersionMS
),
1341 HIWORD(ffi
->dwFileVersionLS
), LOWORD(ffi
->dwFileVersionLS
));
1342 lstrcpynW(lpVersionBuf
, tmp
, *pcchVersionBuf
);
1343 *pcchVersionBuf
= strlenW(lpVersionBuf
);
1348 *pcchVersionBuf
= 0;
1352 if( lpLangBuf
&& pcchLangBuf
&& *pcchLangBuf
)
1354 DWORD lang
= GetUserDefaultLangID();
1356 FIXME("Retrieve language from file\n");
1357 wsprintfW(tmp
, szLangFormat
, lang
);
1358 lstrcpynW(lpLangBuf
, tmp
, *pcchLangBuf
);
1359 *pcchLangBuf
= strlenW(lpLangBuf
);
1363 HeapFree(GetProcessHeap(), 0, lpVer
);
1368 /******************************************************************
1371 BOOL WINAPI
DllMain(HINSTANCE hinstDLL
, DWORD fdwReason
, LPVOID lpvReserved
)
1375 case DLL_PROCESS_ATTACH
:
1376 msi_hInstance
= hinstDLL
;
1377 DisableThreadLibraryCalls(hinstDLL
);
1378 msi_dialog_register_class();
1380 case DLL_PROCESS_DETACH
:
1381 msi_dialog_unregister_class();
1382 /* FIXME: Cleanup */
1388 typedef struct tagIClassFactoryImpl
1390 IClassFactoryVtbl
*lpVtbl
;
1391 } IClassFactoryImpl
;
1393 static HRESULT WINAPI
MsiCF_QueryInterface(LPCLASSFACTORY iface
,
1394 REFIID riid
,LPVOID
*ppobj
)
1396 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1397 FIXME("%p %s %p\n",This
,debugstr_guid(riid
),ppobj
);
1398 return E_NOINTERFACE
;
1401 static ULONG WINAPI
MsiCF_AddRef(LPCLASSFACTORY iface
)
1406 static ULONG WINAPI
MsiCF_Release(LPCLASSFACTORY iface
)
1411 static HRESULT WINAPI
MsiCF_CreateInstance(LPCLASSFACTORY iface
,
1412 LPUNKNOWN pOuter
, REFIID riid
, LPVOID
*ppobj
)
1414 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1416 FIXME("%p %p %s %p\n", This
, pOuter
, debugstr_guid(riid
), ppobj
);
1420 static HRESULT WINAPI
MsiCF_LockServer(LPCLASSFACTORY iface
, BOOL dolock
)
1422 IClassFactoryImpl
*This
= (IClassFactoryImpl
*)iface
;
1424 FIXME("%p %d\n", This
, dolock
);
1428 static IClassFactoryVtbl MsiCF_Vtbl
=
1430 MsiCF_QueryInterface
,
1433 MsiCF_CreateInstance
,
1437 static IClassFactoryImpl Msi_CF
= { &MsiCF_Vtbl
};
1439 /******************************************************************
1440 * DllGetClassObject [MSI.@]
1442 HRESULT WINAPI
MSI_DllGetClassObject(REFCLSID rclsid
, REFIID riid
, LPVOID
*ppv
)
1444 TRACE("%s %s %p\n", debugstr_guid(rclsid
), debugstr_guid(riid
), ppv
);
1446 if( IsEqualCLSID (rclsid
, &CLSID_IMsiServer
) ||
1447 IsEqualCLSID (rclsid
, &CLSID_IMsiServerMessage
) ||
1448 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX1
) ||
1449 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX2
) ||
1450 IsEqualCLSID (rclsid
, &CLSID_IMsiServerX3
) )
1452 *ppv
= (LPVOID
) &Msi_CF
;
1455 return CLASS_E_CLASSNOTAVAILABLE
;
1458 /******************************************************************
1459 * DllGetVersion [MSI.@]
1461 HRESULT WINAPI
MSI_DllGetVersion(DLLVERSIONINFO
*pdvi
)
1465 if (pdvi
->cbSize
!= sizeof(DLLVERSIONINFO
))
1466 return E_INVALIDARG
;
1468 pdvi
->dwMajorVersion
= MSI_MAJORVERSION
;
1469 pdvi
->dwMinorVersion
= MSI_MINORVERSION
;
1470 pdvi
->dwBuildNumber
= MSI_BUILDNUMBER
;
1471 pdvi
->dwPlatformID
= 1;
1476 /******************************************************************
1477 * DllCanUnloadNow [MSI.@]
1479 BOOL WINAPI
MSI_DllCanUnloadNow(void)
1484 UINT WINAPI
MsiGetFeatureUsageW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1485 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1487 FIXME("%s %s %p %p\n",debugstr_w(szProduct
), debugstr_w(szFeature
),
1488 pdwUseCount
, pwDateUsed
);
1489 return ERROR_CALL_NOT_IMPLEMENTED
;
1492 UINT WINAPI
MsiGetFeatureUsageA(LPCSTR szProduct
, LPCSTR szFeature
,
1493 DWORD
* pdwUseCount
, WORD
* pwDateUsed
)
1495 FIXME("%s %s %p %p\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1496 pdwUseCount
, pwDateUsed
);
1497 return ERROR_CALL_NOT_IMPLEMENTED
;
1500 INSTALLSTATE WINAPI
MsiUseFeatureExW(LPCWSTR szProduct
, LPCWSTR szFeature
,
1501 DWORD dwInstallMode
, DWORD dwReserved
)
1503 FIXME("%s %s %li %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1504 dwInstallMode
, dwReserved
);
1507 * Polls all the components of the feature to find install state and then
1509 * Software\\Microsoft\\Windows\\CurrentVersion\\
1510 * Installer\\Products\\<squishguid>\\<feature>
1511 * "Usage"=dword:........
1514 return INSTALLSTATE_LOCAL
;
1517 INSTALLSTATE WINAPI
MsiUseFeatureExA(LPCSTR szProduct
, LPCSTR szFeature
,
1518 DWORD dwInstallMode
, DWORD dwReserved
)
1520 FIXME("%s %s %li %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1521 dwInstallMode
, dwReserved
);
1523 return INSTALLSTATE_LOCAL
;
1526 INSTALLSTATE WINAPI
MsiUseFeatureW(LPCWSTR szProduct
, LPCWSTR szFeature
)
1528 FIXME("%s %s\n", debugstr_w(szProduct
), debugstr_w(szFeature
));
1530 return INSTALLSTATE_LOCAL
;
1533 INSTALLSTATE WINAPI
MsiUseFeatureA(LPCSTR szProduct
, LPCSTR szFeature
)
1535 FIXME("%s %s\n", debugstr_a(szProduct
), debugstr_a(szFeature
));
1537 return INSTALLSTATE_LOCAL
;
1540 UINT WINAPI
MsiProvideQualifiedComponentExW(LPCWSTR szComponent
,
1541 LPCWSTR szQualifier
, DWORD dwInstallMode
, LPWSTR szProduct
,
1542 DWORD Unused1
, DWORD Unused2
, LPWSTR lpPathBuf
,
1545 FIXME("%s %s %li %s %li %li %p %p\n", debugstr_w(szComponent
),
1546 debugstr_w(szQualifier
), dwInstallMode
, debugstr_w(szProduct
),
1547 Unused1
, Unused2
, lpPathBuf
, pcchPathBuf
);
1549 return ERROR_INDEX_ABSENT
;
1552 USERINFOSTATE WINAPI
MsiGetUserInfoW(LPCWSTR szProduct
, LPWSTR lpUserNameBuf
,
1553 DWORD
* pcchUserNameBuf
, LPWSTR lpOrgNameBuf
,
1554 DWORD
* pcchOrgNameBuf
, LPWSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1556 FIXME("%s %p %p %p %p %p %p\n",debugstr_w(szProduct
), lpUserNameBuf
,
1557 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1560 return USERINFOSTATE_UNKNOWN
;
1563 USERINFOSTATE WINAPI
MsiGetUserInfoA(LPCSTR szProduct
, LPSTR lpUserNameBuf
,
1564 DWORD
* pcchUserNameBuf
, LPSTR lpOrgNameBuf
,
1565 DWORD
* pcchOrgNameBuf
, LPSTR lpSerialBuf
, DWORD
* pcchSerialBuf
)
1567 FIXME("%s %p %p %p %p %p %p\n",debugstr_a(szProduct
), lpUserNameBuf
,
1568 pcchUserNameBuf
, lpOrgNameBuf
, pcchOrgNameBuf
, lpSerialBuf
,
1571 return USERINFOSTATE_UNKNOWN
;
1574 UINT WINAPI
MsiCollectUserInfoW(LPCWSTR szProduct
)
1576 FIXME("%s\n",debugstr_w(szProduct
));
1577 return ERROR_CALL_NOT_IMPLEMENTED
;
1580 UINT WINAPI
MsiCollectUserInfoA(LPCSTR szProduct
)
1582 FIXME("%s\n",debugstr_a(szProduct
));
1583 return ERROR_CALL_NOT_IMPLEMENTED
;
1586 UINT WINAPI
MsiCreateAndVerifyInstallerDirectory(void)
1589 return ERROR_CALL_NOT_IMPLEMENTED
;
1592 UINT WINAPI
MsiGetShortcutTargetA( LPCSTR szShortcutTarget
,
1593 LPSTR szProductCode
, LPSTR szFeatureId
,
1594 LPSTR szComponentCode
)
1597 return ERROR_CALL_NOT_IMPLEMENTED
;
1600 UINT WINAPI
MsiGetShortcutTargetW( LPCWSTR szShortcutTarget
,
1601 LPWSTR szProductCode
, LPWSTR szFeatureId
,
1602 LPWSTR szComponentCode
)
1605 return ERROR_CALL_NOT_IMPLEMENTED
;
1608 UINT WINAPI
MsiReinstallFeatureW( LPCWSTR szProduct
, LPCWSTR szFeature
,
1609 DWORD dwReinstallMode
)
1611 FIXME("%s %s %li\n", debugstr_w(szProduct
), debugstr_w(szFeature
),
1613 return ERROR_SUCCESS
;
1616 UINT WINAPI
MsiReinstallFeatureA( LPCSTR szProduct
, LPCSTR szFeature
,
1617 DWORD dwReinstallMode
)
1619 FIXME("%s %s %li\n", debugstr_a(szProduct
), debugstr_a(szFeature
),
1621 return ERROR_SUCCESS
;