2 * Implementation of the Microsoft Installer (msi.dll)
4 * Copyright 2002 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
27 #include "wine/debug.h"
34 WINE_DEFAULT_DEBUG_CHANNEL(msi);
36 const WCHAR szInstaller[] = {
37 'S','o','f','t','w','a','r','e','\\',
38 'M','i','c','r','o','s','o','f','t','\\',
39 'W','i','n','d','o','w','s','\\',
40 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
41 'I','n','s','t','a','l','l','e','r',0 };
43 const WCHAR szFeatures[] = {
44 'F','e','a','t','u','r','e','s',0 };
45 const WCHAR szComponents[] = {
46 'C','o','m','p','o','n','e','n','t','s',0 };
51 * A .msi file is a structured storage file.
52 * It should contain a number of streams.
55 BOOL unsquash_guid(LPCWSTR in, LPWSTR out)
71 out[n++] = in[17+i*2];
72 out[n++] = in[16+i*2];
77 out[n++] = in[17+i*2];
78 out[n++] = in[16+i*2];
85 BOOL squash_guid(LPCWSTR in, LPWSTR out)
105 out[17+i*2] = in[n++];
106 out[16+i*2] = in[n++];
112 out[17+i*2] = in[n++];
113 out[16+i*2] = in[n++];
123 VOID MSI_CloseDatabase( VOID *arg )
125 MSIDATABASE *db = (MSIDATABASE *) arg;
127 free_cached_tables( db );
128 IStorage_Release( db->storage );
131 UINT WINAPI MsiOpenDatabaseA(
132 LPCSTR szDBPath, LPCSTR szPersist, MSIHANDLE *phDB)
134 HRESULT r = ERROR_FUNCTION_FAILED;
135 LPWSTR szwDBPath = NULL, szwPersist = NULL;
137 TRACE("%s %s %p\n", debugstr_a(szDBPath), debugstr_a(szPersist), phDB);
141 szwDBPath = HEAP_strdupAtoW( GetProcessHeap(), 0, szDBPath );
148 szwPersist = HEAP_strdupAtoW( GetProcessHeap(), 0, szPersist );
153 r = MsiOpenDatabaseW( szwDBPath, szwPersist, phDB );
157 HeapFree( GetProcessHeap(), 0, szwPersist );
159 HeapFree( GetProcessHeap(), 0, szwDBPath );
164 UINT WINAPI MsiOpenDatabaseW(
165 LPCWSTR szDBPath, LPCWSTR szPersist, MSIHANDLE *phDB)
167 IStorage *stg = NULL;
173 TRACE("%s %s %p\n",debugstr_w(szDBPath),debugstr_w(szPersist), phDB);
176 return ERROR_INVALID_PARAMETER;
178 r = StgOpenStorage( szDBPath, NULL, STGM_DIRECT|STGM_READ|STGM_SHARE_DENY_WRITE, NULL, 0, &stg);
181 FIXME("open failed r = %08lx!\n",r);
182 return ERROR_FUNCTION_FAILED;
185 handle = alloc_msihandle(MSIHANDLETYPE_DATABASE, sizeof (MSIDATABASE), MSI_CloseDatabase );
188 FIXME("Failed to allocate a handle\n");
189 ret = ERROR_FUNCTION_FAILED;
193 db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
196 FIXME("Failed to get handle pointer \n");
197 ret = ERROR_FUNCTION_FAILED;
201 ret = load_string_table( db, &db->strings);
202 if( ret != ERROR_SUCCESS )
207 IStorage_AddRef( stg );
210 IStorage_Release( stg );
215 UINT WINAPI MsiOpenProductA(LPCSTR szProduct, MSIHANDLE *phProduct)
217 FIXME("%s %p\n",debugstr_a(szProduct), phProduct);
218 return ERROR_CALL_NOT_IMPLEMENTED;
221 UINT WINAPI MsiOpenProductW(LPCWSTR szProduct, MSIHANDLE *phProduct)
223 FIXME("%s %p\n",debugstr_w(szProduct), phProduct);
224 return ERROR_CALL_NOT_IMPLEMENTED;
227 UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
229 FIXME("%s %p\n",debugstr_a(szPackage), phPackage);
230 return ERROR_CALL_NOT_IMPLEMENTED;
233 UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
235 FIXME("%s %p\n",debugstr_w(szPackage), phPackage);
236 return ERROR_CALL_NOT_IMPLEMENTED;
239 UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
241 FIXME("%s 0x%08lx %p\n",debugstr_a(szPackage), dwOptions, phPackage);
242 return ERROR_CALL_NOT_IMPLEMENTED;
245 UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
247 FIXME("%s 0x%08lx %p\n",debugstr_w(szPackage), dwOptions, phPackage);
248 return ERROR_CALL_NOT_IMPLEMENTED;
251 UINT WINAPI MsiAdvertiseProductA(LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage)
253 FIXME("%s %s %s 0x%08x\n",debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage);
254 return ERROR_CALL_NOT_IMPLEMENTED;
257 UINT WINAPI MsiAdvertiseProductW(LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage)
259 FIXME("%s %s %s 0x%08x\n",debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage);
260 return ERROR_CALL_NOT_IMPLEMENTED;
263 UINT WINAPI MsiAdvertiseProductExA(
264 LPCSTR szPackagePath, LPCSTR szScriptfilePath, LPCSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
266 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
267 debugstr_a(szPackagePath), debugstr_a(szScriptfilePath), debugstr_a(szTransforms), lgidLanguage, dwPlatform, dwOptions);
268 return ERROR_CALL_NOT_IMPLEMENTED;
271 UINT WINAPI MsiAdvertiseProductExW(
272 LPCWSTR szPackagePath, LPCWSTR szScriptfilePath, LPCWSTR szTransforms, LANGID lgidLanguage, DWORD dwPlatform, DWORD dwOptions)
274 FIXME("%s %s %s 0x%08x 0x%08lx 0x%08lx\n",
275 debugstr_w(szPackagePath), debugstr_w(szScriptfilePath), debugstr_w(szTransforms), lgidLanguage, dwPlatform, dwOptions);
276 return ERROR_CALL_NOT_IMPLEMENTED;
279 UINT WINAPI MsiInstallProductA(LPCSTR szPackagePath, LPCSTR szCommandLine)
281 LPWSTR szwPath = NULL, szwCommand = NULL;
282 UINT r = ERROR_FUNCTION_FAILED; /* FIXME: check return code */
284 TRACE("%s %s\n",debugstr_a(szPackagePath), debugstr_a(szCommandLine));
288 szwPath = HEAP_strdupAtoW(GetProcessHeap(),0,szPackagePath);
289 if( szwPath == NULL )
295 szwCommand = HEAP_strdupAtoW(GetProcessHeap(),0,szCommandLine);
296 if( szwCommand == NULL )
300 r = MsiInstallProductW( szwPath, szwCommand );
304 HeapFree( GetProcessHeap(), 0, szwPath );
307 HeapFree( GetProcessHeap(), 0, szwCommand );
312 UINT WINAPI MsiInstallProductW(LPCWSTR szPackagePath, LPCWSTR szCommandLine)
314 FIXME("%s %s\n",debugstr_w(szPackagePath), debugstr_w(szCommandLine));
316 return ERROR_CALL_NOT_IMPLEMENTED;
319 UINT WINAPI MsiConfigureProductA(
320 LPCSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
322 FIXME("%s %d %d\n",debugstr_a(szProduct), iInstallLevel, eInstallState);
323 return ERROR_CALL_NOT_IMPLEMENTED;
326 UINT WINAPI MsiConfigureProductW(
327 LPCWSTR szProduct, int iInstallLevel, INSTALLSTATE eInstallState)
329 FIXME("%s %d %d\n",debugstr_w(szProduct), iInstallLevel, eInstallState);
330 return ERROR_CALL_NOT_IMPLEMENTED;
333 UINT WINAPI MsiGetProductCodeA(LPCSTR szComponent, LPSTR szBuffer)
335 FIXME("%s %s\n",debugstr_a(szComponent), debugstr_a(szBuffer));
336 return ERROR_CALL_NOT_IMPLEMENTED;
339 UINT WINAPI MsiGetProductCodeW(LPCWSTR szComponent, LPWSTR szBuffer)
341 FIXME("%s %s\n",debugstr_w(szComponent), debugstr_w(szBuffer));
342 return ERROR_CALL_NOT_IMPLEMENTED;
345 UINT WINAPI MsiGetProductInfoA(LPCSTR szProduct, LPCSTR szAttribute, LPSTR szBuffer, DWORD *pcchValueBuf)
347 FIXME("%s %s %p %p\n",debugstr_a(szProduct), debugstr_a(szAttribute), szBuffer, pcchValueBuf);
348 return ERROR_CALL_NOT_IMPLEMENTED;
351 UINT WINAPI MsiGetProductInfoW(LPCWSTR szProduct, LPCWSTR szAttribute, LPWSTR szBuffer, DWORD *pcchValueBuf)
353 FIXME("%s %s %p %p\n",debugstr_w(szProduct), debugstr_w(szAttribute), szBuffer, pcchValueBuf);
354 return ERROR_CALL_NOT_IMPLEMENTED;
357 UINT WINAPI MsiDatabaseImportA(LPCSTR szFolderPath, LPCSTR szFilename)
359 FIXME("%s %s\n",debugstr_a(szFolderPath), debugstr_a(szFilename));
360 return ERROR_CALL_NOT_IMPLEMENTED;
363 UINT WINAPI MsiDatabaseImportW(LPCWSTR szFolderPath, LPCWSTR szFilename)
365 FIXME("%s %s\n",debugstr_w(szFolderPath), debugstr_w(szFilename));
366 return ERROR_CALL_NOT_IMPLEMENTED;
369 UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, BOOL fAppend)
371 FIXME("%08lx %s %d\n", dwLogMode, debugstr_a(szLogFile), fAppend);
372 return ERROR_SUCCESS;
373 /* return ERROR_CALL_NOT_IMPLEMENTED; */
376 UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, BOOL fAppend)
378 FIXME("%08lx %s %d\n", dwLogMode, debugstr_w(szLogFile), fAppend);
379 return ERROR_CALL_NOT_IMPLEMENTED;
382 INSTALLSTATE WINAPI MsiQueryProductStateA(LPCSTR szProduct)
384 FIXME("%s\n", debugstr_a(szProduct));
388 INSTALLSTATE WINAPI MsiQueryProductStateW(LPCWSTR szProduct)
390 FIXME("%s\n", debugstr_w(szProduct));
394 INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
396 FIXME("%08x %p\n", dwUILevel, phWnd);
400 UINT WINAPI MsiLoadStringA(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f)
402 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);
403 return ERROR_CALL_NOT_IMPLEMENTED;
406 UINT WINAPI MsiLoadStringW(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f)
408 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);
409 return ERROR_CALL_NOT_IMPLEMENTED;
412 UINT WINAPI MsiMessageBoxA(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f)
414 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);
415 return ERROR_CALL_NOT_IMPLEMENTED;
418 UINT WINAPI MsiMessageBoxW(DWORD a, DWORD b, DWORD c, DWORD d, DWORD e, DWORD f)
420 FIXME("%08lx %08lx %08lx %08lx %08lx %08lx\n",a,b,c,d,e,f);
421 return ERROR_CALL_NOT_IMPLEMENTED;
424 UINT WINAPI MsiEnumProductsA(DWORD index, LPSTR lpguid)
427 WCHAR szwGuid[GUID_SIZE];
429 TRACE("%ld %p\n",index,lpguid);
431 r = MsiEnumProductsW(index, szwGuid);
432 if( r == ERROR_SUCCESS )
433 WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
438 UINT WINAPI MsiEnumProductsW(DWORD index, LPWSTR lpguid)
440 HKEY hkey = 0, hkeyFeatures = 0;
444 TRACE("%ld %p\n",index,lpguid);
446 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
447 if( r != ERROR_SUCCESS )
450 r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
451 if( r != ERROR_SUCCESS )
454 r = RegEnumKeyW(hkeyFeatures, index, szKeyName, GUID_SIZE);
456 unsquash_guid(szKeyName, lpguid);
461 RegCloseKey(hkeyFeatures);
468 UINT WINAPI MsiEnumFeaturesA(LPCSTR szProduct, DWORD index,
469 LPSTR szFeature, LPSTR szParent)
472 WCHAR szwFeature[GUID_SIZE], szwParent[GUID_SIZE];
473 LPWSTR szwProduct = NULL;
475 TRACE("%s %ld %p %p\n",debugstr_a(szProduct),index,szFeature,szParent);
479 szwProduct = HEAP_strdupAtoW(GetProcessHeap(),0,szProduct);
481 return ERROR_FUNCTION_FAILED;
484 r = MsiEnumFeaturesW(szProduct?szwProduct:NULL,
485 index, szwFeature, szwParent);
486 if( r == ERROR_SUCCESS )
488 WideCharToMultiByte(CP_ACP, 0, szwFeature, -1,
489 szFeature, GUID_SIZE, NULL, NULL);
490 WideCharToMultiByte(CP_ACP, 0, szwParent, -1,
491 szParent, GUID_SIZE, NULL, NULL);
495 HeapFree( GetProcessHeap(), 0, szwProduct);
500 UINT WINAPI MsiEnumFeaturesW(LPCWSTR szProduct, DWORD index,
501 LPWSTR szFeature, LPWSTR szParent)
503 HKEY hkey = 0, hkeyFeatures = 0, hkeyProduct = 0;
505 WCHAR szRegName[GUID_SIZE];
507 TRACE("%s %ld %p %p\n",debugstr_w(szProduct),index,szFeature,szParent);
509 if( !squash_guid(szProduct, szRegName) )
510 return ERROR_INVALID_PARAMETER;
512 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
513 if( r != ERROR_SUCCESS )
516 r = RegOpenKeyW(hkey, szFeatures, &hkeyFeatures);
517 if( r != ERROR_SUCCESS )
520 r = RegOpenKeyW(hkeyFeatures, szRegName, &hkeyProduct);
521 if( r != ERROR_SUCCESS )
525 r = RegEnumValueW(hkeyProduct, index, szFeature, &sz, NULL, NULL, NULL, NULL);
529 RegCloseKey(hkeyProduct);
531 RegCloseKey(hkeyFeatures);
538 UINT WINAPI MsiEnumComponentsA(DWORD index, LPSTR lpguid)
541 WCHAR szwGuid[GUID_SIZE];
543 TRACE("%ld %p\n",index,lpguid);
545 r = MsiEnumComponentsW(index, szwGuid);
546 if( r == ERROR_SUCCESS )
547 WideCharToMultiByte(CP_ACP, 0, szwGuid, -1, lpguid, GUID_SIZE, NULL, NULL);
552 UINT WINAPI MsiEnumComponentsW(DWORD index, LPWSTR lpguid)
554 HKEY hkey = 0, hkeyComponents = 0;
558 TRACE("%ld %p\n",index,lpguid);
560 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
561 if( r != ERROR_SUCCESS )
564 r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
565 if( r != ERROR_SUCCESS )
568 r = RegEnumKeyW(hkeyComponents, index, szKeyName, GUID_SIZE);
570 unsquash_guid(szKeyName, lpguid);
575 RegCloseKey(hkeyComponents);
582 UINT WINAPI MsiEnumClientsA(LPCSTR szComponent, DWORD index, LPSTR szProduct)
585 WCHAR szwProduct[GUID_SIZE];
586 LPWSTR szwComponent = NULL;
588 TRACE("%s %ld %p\n",debugstr_a(szComponent),index,szProduct);
592 szwComponent = HEAP_strdupAtoW(GetProcessHeap(),0,szComponent);
594 return ERROR_FUNCTION_FAILED;
597 r = MsiEnumClientsW(szComponent?szwComponent:NULL, index, szwProduct);
598 if( r == ERROR_SUCCESS )
600 WideCharToMultiByte(CP_ACP, 0, szwProduct, -1,
601 szProduct, GUID_SIZE, NULL, NULL);
605 HeapFree( GetProcessHeap(), 0, szwComponent);
610 UINT WINAPI MsiEnumClientsW(LPCWSTR szComponent, DWORD index, LPWSTR szProduct)
612 HKEY hkey = 0, hkeyComponents = 0, hkeyComp = 0;
614 WCHAR szRegName[GUID_SIZE], szValName[GUID_SIZE];
616 TRACE("%s %ld %p\n",debugstr_w(szComponent),index,szProduct);
618 if( !squash_guid(szComponent, szRegName) )
619 return ERROR_INVALID_PARAMETER;
621 r = RegOpenKeyW(HKEY_LOCAL_MACHINE, szInstaller, &hkey);
622 if( r != ERROR_SUCCESS )
625 r = RegOpenKeyW(hkey, szComponents, &hkeyComponents);
626 if( r != ERROR_SUCCESS )
629 r = RegOpenKeyW(hkeyComponents, szRegName, &hkeyComp);
630 if( r != ERROR_SUCCESS )
634 r = RegEnumValueW(hkeyComp, index, szValName, &sz, NULL, NULL, NULL, NULL);
635 if( r != ERROR_SUCCESS )
638 unsquash_guid(szValName, szProduct);
642 RegCloseKey(hkeyComp);
644 RegCloseKey(hkeyComponents);
651 UINT WINAPI MsiEnumComponentQualifiersA(
652 LPSTR szComponent, DWORD iIndex, LPSTR lpQualifierBuf, DWORD* pcchQualifierBuf, LPSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
654 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_a(szComponent), iIndex, lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf, pcchApplicationDataBuf);
655 return ERROR_CALL_NOT_IMPLEMENTED;
658 UINT WINAPI MsiEnumComponentQualifiersW(
659 LPWSTR szComponent, DWORD iIndex, LPWSTR lpQualifierBuf, DWORD* pcchQualifierBuf, LPWSTR lpApplicationDataBuf, DWORD* pcchApplicationDataBuf)
661 FIXME("%s 0x%08lx %p %p %p %p\n", debugstr_w(szComponent), iIndex, lpQualifierBuf, pcchQualifierBuf, lpApplicationDataBuf, pcchApplicationDataBuf);
662 return ERROR_CALL_NOT_IMPLEMENTED;
665 UINT WINAPI MsiProvideAssemblyA(
666 LPCSTR szAssemblyName, LPCSTR szAppContext, DWORD dwInstallMode, DWORD dwAssemblyInfo, LPSTR lpPathBuf, DWORD* pcchPathBuf)
668 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
669 debugstr_a(szAssemblyName), debugstr_a(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf, pcchPathBuf);
670 return ERROR_CALL_NOT_IMPLEMENTED;
673 UINT WINAPI MsiProvideAssemblyW(
674 LPCWSTR szAssemblyName, LPCWSTR szAppContext, DWORD dwInstallMode, DWORD dwAssemblyInfo, LPWSTR lpPathBuf, DWORD* pcchPathBuf)
676 FIXME("%s %s 0x%08lx 0x%08lx %p %p\n",
677 debugstr_w(szAssemblyName), debugstr_w(szAppContext), dwInstallMode, dwAssemblyInfo, lpPathBuf, pcchPathBuf);
678 return ERROR_CALL_NOT_IMPLEMENTED;
681 UINT WINAPI MsiProvideComponentFromDescriptorA( LPCSTR szDescriptor, LPSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
683 FIXME("%s %p %p %p\n", debugstr_a(szDescriptor), szPath, pcchPath, pcchArgs );
684 return ERROR_CALL_NOT_IMPLEMENTED;
687 UINT WINAPI MsiProvideComponentFromDescriptorW( LPCWSTR szDescriptor, LPWSTR szPath, DWORD *pcchPath, DWORD *pcchArgs )
689 FIXME("%s %p %p %p\n", debugstr_w(szDescriptor), szPath, pcchPath, pcchArgs );
690 return ERROR_CALL_NOT_IMPLEMENTED;
693 HRESULT WINAPI MsiGetFileSignatureInformationA(
694 LPCSTR szSignedObjectPath, DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData, DWORD* pcbHashData)
696 FIXME("%s 0x%08lx %p %p %p\n", debugstr_a(szSignedObjectPath), dwFlags, ppcCertContext, pbHashData, pcbHashData);
697 return ERROR_CALL_NOT_IMPLEMENTED;
700 HRESULT WINAPI MsiGetFileSignatureInformationW(
701 LPCWSTR szSignedObjectPath, DWORD dwFlags, PCCERT_CONTEXT* ppcCertContext, BYTE* pbHashData, DWORD* pcbHashData)
703 FIXME("%s 0x%08lx %p %p %p\n", debugstr_w(szSignedObjectPath), dwFlags, ppcCertContext, pbHashData, pcbHashData);
704 return ERROR_CALL_NOT_IMPLEMENTED;
707 HRESULT WINAPI MSI_DllGetVersion(DLLVERSIONINFO *pdvi)
711 if (pdvi->cbSize != sizeof(DLLVERSIONINFO))
714 pdvi->dwMajorVersion = MSI_MAJORVERSION;
715 pdvi->dwMinorVersion = MSI_MINORVERSION;
716 pdvi->dwBuildNumber = MSI_BUILDNUMBER;
717 pdvi->dwPlatformID = 1;
722 BOOL WINAPI MSI_DllCanUnloadNow(void)