Add source.c to start handling the various MsiSourceList apis used in

v3 of MSI, and now internally.
Update files.c to use the MsiSourceList apis to make sure our
SourceList keys in the registry are included and correct.
This commit is contained in:
Aric Stewart 2005-07-05 21:00:06 +00:00 committed by Alexandre Julliard
parent b6b4787e95
commit b7dc53d462
5 changed files with 699 additions and 6 deletions

View File

@ -33,6 +33,7 @@ C_SRCS = \
registry.c \ registry.c \
regsvr.c \ regsvr.c \
select.c \ select.c \
source.c \
string.c \ string.c \
suminfo.c \ suminfo.c \
table.c \ table.c \

View File

@ -37,6 +37,7 @@
#include "winerror.h" #include "winerror.h"
#include "wine/debug.h" #include "wine/debug.h"
#include "fdi.h" #include "fdi.h"
#include "msi.h"
#include "msidefs.h" #include "msidefs.h"
#include "msvcrt/fcntl.h" #include "msvcrt/fcntl.h"
#include "msipriv.h" #include "msipriv.h"
@ -54,6 +55,8 @@ extern const WCHAR szRemoveDuplicateFiles[];
extern const WCHAR szRemoveFiles[]; extern const WCHAR szRemoveFiles[];
static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0}; static const WCHAR cszTempFolder[]= {'T','e','m','p','F','o','l','d','e','r',0};
static const WCHAR INSTALLPROPERTY_LASTUSEDSOURCE[] = {'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
static const WCHAR INSTALLPROPERTY_PACKAGENAME[] = {'P','a','c','k','a','g','e','N','a','m','e',0};
inline static UINT create_component_directory ( MSIPACKAGE* package, INT component) inline static UINT create_component_directory ( MSIPACKAGE* package, INT component)
{ {
@ -359,7 +362,8 @@ static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, MSICOMPONENT*
file->SourcePath = build_directory_name(2, path, file->File); file->SourcePath = build_directory_name(2, path, file->File);
} }
static BOOL check_volume(LPCWSTR path, LPCWSTR want_volume, LPWSTR volume) static BOOL check_volume(LPCWSTR path, LPCWSTR want_volume, LPWSTR volume,
UINT *intype)
{ {
WCHAR drive[4]; WCHAR drive[4];
WCHAR name[MAX_PATH]; WCHAR name[MAX_PATH];
@ -383,6 +387,8 @@ static BOOL check_volume(LPCWSTR path, LPCWSTR want_volume, LPWSTR volume)
GetVolumeInformationW(drive, name, MAX_PATH, NULL, NULL, NULL, NULL, 0); GetVolumeInformationW(drive, name, MAX_PATH, NULL, NULL, NULL, NULL, 0);
TRACE("Drive contains %s\n", debugstr_w(name)); TRACE("Drive contains %s\n", debugstr_w(name));
volume = strdupW(name); volume = strdupW(name);
if (*intype)
*intype=type;
return (strcmpiW(want_volume,name)==0); return (strcmpiW(want_volume,name)==0);
} }
@ -393,11 +399,11 @@ static BOOL check_for_sourcefile(LPCWSTR source)
} }
static UINT ready_volume(MSIPACKAGE* package, LPCWSTR path, LPWSTR last_volume, static UINT ready_volume(MSIPACKAGE* package, LPCWSTR path, LPWSTR last_volume,
MSIRECORD *row) MSIRECORD *row,UINT *type )
{ {
LPWSTR volume = NULL; LPWSTR volume = NULL;
LPCWSTR want_volume = MSI_RecordGetString(row, 5); LPCWSTR want_volume = MSI_RecordGetString(row, 5);
BOOL ok = check_volume(path, want_volume, volume); BOOL ok = check_volume(path, want_volume, volume, type);
TRACE("Readying Volume for %s (%s, %s)\n",debugstr_w(path), debugstr_w(want_volume), debugstr_w(last_volume)); TRACE("Readying Volume for %s (%s, %s)\n",debugstr_w(path), debugstr_w(want_volume), debugstr_w(last_volume));
@ -449,6 +455,9 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
static LPWSTR last_volume = NULL; static LPWSTR last_volume = NULL;
static LPWSTR last_path = NULL; static LPWSTR last_path = NULL;
MSIFILE* file = NULL; MSIFILE* file = NULL;
UINT type;
LPCWSTR prompt;
static DWORD count = 0;
/* cleanup signal */ /* cleanup signal */
if (!package) if (!package)
@ -467,6 +476,7 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
count ++;
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence); row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence);
if (!row) if (!row)
{ {
@ -478,6 +488,7 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
last_sequence = seq; last_sequence = seq;
volume = MSI_RecordGetString(row, 5); volume = MSI_RecordGetString(row, 5);
prompt = MSI_RecordGetString(row, 3);
HeapFree(GetProcessHeap(),0,last_path); HeapFree(GetProcessHeap(),0,last_path);
last_path = NULL; last_path = NULL;
@ -486,7 +497,23 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
{ {
last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL); last_path = resolve_folder(package, comp->Directory, TRUE, FALSE, NULL);
set_file_source(package,file,comp,last_path); set_file_source(package,file,comp,last_path);
rc = ready_volume(package, file->SourcePath, last_volume, row); rc = ready_volume(package, file->SourcePath, last_volume, row,&type);
MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count, volume,
prompt);
if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
type == DRIVE_RAMDISK)
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
INSTALLPROPERTY_LASTUSEDSOURCE, last_path);
else
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
INSTALLPROPERTY_LASTUSEDSOURCE, last_path);
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
return rc; return rc;
} }
@ -498,9 +525,25 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
/* the stream does not contain the # character */ /* the stream does not contain the # character */
if (cab[0]=='#') if (cab[0]=='#')
{ {
LPWSTR path;
writeout_cabinet_stream(package,&cab[1],source); writeout_cabinet_stream(package,&cab[1],source);
last_path = strdupW(source); last_path = strdupW(source);
*(strrchrW(last_path,'\\')+1)=0; *(strrchrW(last_path,'\\')+1)=0;
path = strdupW(package->PackagePath);
*strrchrW(path,'\\')=0;
MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count,
volume, prompt);
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
INSTALLPROPERTY_LASTUSEDSOURCE, path);
HeapFree(GetProcessHeap(),0,path);
} }
else else
{ {
@ -515,12 +558,25 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
{ {
strcpyW(last_path,source); strcpyW(last_path,source);
strcatW(source,cab); strcatW(source,cab);
rc = ready_volume(package, source, last_volume, row, &type);
if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
type == DRIVE_RAMDISK)
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
INSTALLPROPERTY_LASTUSEDSOURCE, last_path);
else
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
INSTALLPROPERTY_LASTUSEDSOURCE, last_path);
/* extract the cab file into a folder in the temp folder */ /* extract the cab file into a folder in the temp folder */
sz = MAX_PATH; sz = MAX_PATH;
if (MSI_GetPropertyW(package, cszTempFolder,last_path, &sz) if (MSI_GetPropertyW(package, cszTempFolder,last_path, &sz)
!= ERROR_SUCCESS) != ERROR_SUCCESS)
GetTempPathW(MAX_PATH,last_path); GetTempPathW(MAX_PATH,last_path);
rc = ready_volume(package, source, last_volume, row);
} }
} }
rc = !extract_cabinet_file(package, source, last_path); rc = !extract_cabinet_file(package, source, last_path);
@ -533,9 +589,26 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
last_path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR)); last_path = HeapAlloc(GetProcessHeap(),0,MAX_PATH*sizeof(WCHAR));
MSI_GetPropertyW(package,cszSourceDir,source,&sz); MSI_GetPropertyW(package,cszSourceDir,source,&sz);
strcpyW(last_path,source); strcpyW(last_path,source);
rc = ready_volume(package, last_path, last_volume, row); rc = ready_volume(package, last_path, last_volume, row, &type);
if (type == DRIVE_REMOVABLE || type == DRIVE_CDROM ||
type == DRIVE_RAMDISK)
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_MEDIA,
INSTALLPROPERTY_LASTUSEDSOURCE, last_path);
else
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT|MSISOURCETYPE_NETWORK,
INSTALLPROPERTY_LASTUSEDSOURCE, last_path);
} }
set_file_source(package, file, comp, last_path); set_file_source(package, file, comp, last_path);
MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count, volume,
prompt);
msiobj_release(&row->hdr); msiobj_release(&row->hdr);
return rc; return rc;
@ -577,6 +650,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
{ {
UINT rc = ERROR_SUCCESS; UINT rc = ERROR_SUCCESS;
DWORD index; DWORD index;
LPWSTR ptr;
if (!package) if (!package)
return ERROR_INVALID_HANDLE; return ERROR_INVALID_HANDLE;
@ -584,6 +658,18 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
/* increment progress bar each time action data is sent */ /* increment progress bar each time action data is sent */
ui_progress(package,1,1,0,0); ui_progress(package,1,1,0,0);
/* handle the keys for the SouceList */
ptr = strrchrW(package->PackagePath,'\\');
if (ptr)
{
ptr ++;
MsiSourceListSetInfoW(package->ProductCode, NULL,
MSIINSTALLCONTEXT_USERMANAGED,
MSICODE_PRODUCT,
INSTALLPROPERTY_PACKAGENAME, ptr);
}
FIXME("Write DiskPrompt\n");
/* Pass 1 */ /* Pass 1 */
for (index = 0; index < package->loaded_files; index++) for (index = 0; index < package->loaded_files; index++)
{ {

View File

@ -217,6 +217,7 @@ typedef struct tagMSIPACKAGE
LPWSTR PackagePath; LPWSTR PackagePath;
LPWSTR msiFilePath; LPWSTR msiFilePath;
LPWSTR ProductCode;
UINT CurrentInstallState; UINT CurrentInstallState;
msi_dialog *dialog; msi_dialog *dialog;

567
dlls/msi/source.c Normal file
View File

@ -0,0 +1,567 @@
/*
* Implementation of the Microsoft Installer (msi.dll)
*
* Copyright 2005 Aric Stewart for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <stdarg.h>
#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winnls.h"
#include "shlwapi.h"
#include "wine/debug.h"
#include "msi.h"
#include "msiquery.h"
#include "msipriv.h"
#include "wincrypt.h"
#include "winver.h"
#include "winuser.h"
#include "wine/unicode.h"
#include "action.h"
WINE_DEFAULT_DEBUG_CHANNEL(msi);
/*
* These apis are defined in MSI 3.0
*/
static const WCHAR INSTALLPROPERTY_MEDIAPACKAGEPATH[] = {'M','e','d','i','a','P','a','c','k','a','g','e','P','a','t','h',0};
static const WCHAR INSTALLPROPERTY_DISKPROMPT[] = {'D','i','s','k','P','r','o','m','p','t',0};
static const WCHAR INSTALLPROPERTY_LASTUSEDSOURCE[] = {'L','a','s','t','U','s','e','d','S','o','u','r','c','e',0};
static const WCHAR INSTALLPROPERTY_LASTUSEDTYPE[] = {'L','a','s','t','U','s','e','d','T','y','p','e',0};
static const WCHAR INSTALLPROPERTY_PACKAGENAME[] = {'P','a','c','k','a','g','e','N','a','m','e',0};
typedef struct tagMediaInfo
{
LPWSTR path;
WCHAR szIndex[10];
WCHAR type;
} media_info;
static UINT OpenSourceKey(LPCWSTR szProduct, HKEY* key, BOOL user, BOOL create)
{
HKEY rootkey = 0;
UINT rc;
static const WCHAR szSourceList[] = {'S','o','u','r','c','e','L','i','s','t',0};
if (user)
rc = MSIREG_OpenUserProductsKey(szProduct, &rootkey, create);
else
rc = MSIREG_OpenProductsKey(szProduct, &rootkey, create);
if (rc)
return rc;
if (create)
rc = RegCreateKeyW(rootkey, szSourceList, key);
else
rc = RegOpenKeyW(rootkey,szSourceList, key);
return rc;
}
static UINT OpenMediaSubkey(HKEY rootkey, HKEY *key, BOOL create)
{
UINT rc;
static const WCHAR media[] = {'M','e','d','i','a',0};
if (create)
rc = RegCreateKeyW(rootkey, media, key);
else
rc = RegOpenKeyW(rootkey,media, key);
return rc;
}
static UINT OpenNetworkSubkey(HKEY rootkey, HKEY *key, BOOL create)
{
UINT rc;
static const WCHAR net[] = {'N','e','t',0};
if (create)
rc = RegCreateKeyW(rootkey, net, key);
else
rc = RegOpenKeyW(rootkey, net, key);
return rc;
}
static UINT OpenURLSubkey(HKEY rootkey, HKEY *key, BOOL create)
{
UINT rc;
static const WCHAR URL[] = {'U','R','L',0};
if (create)
rc = RegCreateKeyW(rootkey, URL, key);
else
rc = RegOpenKeyW(rootkey, URL, key);
return rc;
}
static UINT find_given_source(HKEY key, LPCWSTR szSource, media_info *ss)
{
DWORD index = 0;
WCHAR szIndex[10];
DWORD size;
DWORD val_size;
LPWSTR val;
UINT rc = ERROR_SUCCESS;
while (rc == ERROR_SUCCESS)
{
val = NULL;
val_size = 0;
rc = RegEnumValueW(key, index, szIndex, &size, NULL, NULL, NULL, &val_size);
if (rc != ERROR_NO_MORE_ITEMS)
{
val = HeapAlloc(GetProcessHeap(),0,val_size);
RegEnumValueW(key, index, szIndex, &size, NULL, NULL, (LPBYTE)val,
&val_size);
if (lstrcmpiW(szSource,val)==0)
{
ss->path = val;
strcpyW(ss->szIndex,szIndex);
break;
}
else
strcpyW(ss->szIndex,szIndex);
HeapFree(GetProcessHeap(),0,val);
index ++;
}
}
return rc;
}
/******************************************************************
* MsiSourceListGetInfoW (MSI.@)
*/
UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
LPCWSTR szProperty, LPWSTR szValue,
LPDWORD pcchValue)
{
HKEY sourcekey;
UINT rc;
TRACE("%s %s\n", debugstr_w(szProduct), debugstr_w(szProperty));
if (!szProduct || lstrlenW(szProduct) > 39)
return ERROR_INVALID_PARAMETER;
if (szValue && !pcchValue)
return ERROR_INVALID_PARAMETER;
if (dwOptions == MSICODE_PATCH)
{
FIXME("Unhandled options MSICODE_PATCH\n");
return ERROR_FUNCTION_FAILED;
}
if (szUserSid)
FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
if (dwContext == MSIINSTALLCONTEXT_MACHINE)
rc = OpenSourceKey(szProduct, &sourcekey, FALSE, FALSE);
else
rc = OpenSourceKey(szProduct, &sourcekey, TRUE, FALSE);
if (rc != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATH) == 0)
{
HKEY key;
rc = OpenMediaSubkey(sourcekey, &key, FALSE);
if (rc == ERROR_SUCCESS)
rc = RegQueryValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATH, 0, 0,
(LPBYTE)szValue, pcchValue);
if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
rc = ERROR_UNKNOWN_PROPERTY;
RegCloseKey(key);
}
else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPT) ==0)
{
HKEY key;
rc = OpenMediaSubkey(sourcekey, &key, FALSE);
if (rc == ERROR_SUCCESS)
rc = RegQueryValueExW(key, INSTALLPROPERTY_DISKPROMPT, 0, 0,
(LPBYTE)szValue, pcchValue);
if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
rc = ERROR_UNKNOWN_PROPERTY;
RegCloseKey(key);
}
else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCE)==0)
{
LPWSTR buffer;
DWORD size = 0;
RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCE, 0, 0, NULL,
&size);
if (size == 0)
rc = ERROR_UNKNOWN_PROPERTY;
else
{
LPWSTR ptr;
buffer = HeapAlloc(GetProcessHeap(),0,size);
rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCE, 0,
0, (LPBYTE)buffer,&size);
ptr = strchrW(buffer,';');
ptr = strchrW(ptr,';');
if (!ptr)
rc = ERROR_UNKNOWN_PROPERTY;
else
{
ptr ++;
lstrcpynW(szValue, ptr, *pcchValue);
if (lstrlenW(ptr) > *pcchValue)
{
*pcchValue = lstrlenW(ptr)+1;
rc = ERROR_MORE_DATA;
}
else
rc = ERROR_SUCCESS;
}
HeapFree(GetProcessHeap(),0,buffer);
}
}
else if (strcmpW(INSTALLPROPERTY_LASTUSEDTYPE, szProperty)==0)
{
LPWSTR buffer;
DWORD size = 0;
RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCE, 0, 0, NULL,
&size);
if (size == 0)
rc = ERROR_UNKNOWN_PROPERTY;
else
{
buffer = HeapAlloc(GetProcessHeap(),0,size);
rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCE, 0,
0, (LPBYTE)buffer,&size);
if (*pcchValue < 1)
{
rc = ERROR_MORE_DATA;
*pcchValue = 1;
}
else
{
szValue[0] = buffer[0];
rc = ERROR_SUCCESS;
}
HeapFree(GetProcessHeap(),0,buffer);
}
}
else if (strcmpW(INSTALLPROPERTY_PACKAGENAME, szProperty)==0)
{
rc = RegQueryValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAME, 0, 0,
(LPBYTE)szValue, pcchValue);
if (rc != ERROR_SUCCESS && rc != ERROR_MORE_DATA)
rc = ERROR_UNKNOWN_PROPERTY;
}
else
{
FIXME("Unknown property %s\n",debugstr_w(szProperty));
rc = ERROR_UNKNOWN_PROPERTY;
}
RegCloseKey(sourcekey);
return rc;
}
/******************************************************************
* MsiSourceListSetInfoW (MSI.@)
*/
UINT WINAPI MsiSourceListSetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions,
LPCWSTR szProperty, LPCWSTR szValue)
{
HKEY sourcekey;
UINT rc;
TRACE("%s %s %x %lx %s %s\n", debugstr_w(szProduct), debugstr_w(szUserSid),
dwContext, dwOptions, debugstr_w(szProperty), debugstr_w(szValue));
if (!szProduct || lstrlenW(szProduct) > 39)
return ERROR_INVALID_PARAMETER;
if (dwOptions & MSICODE_PATCH)
{
FIXME("Unhandled options MSICODE_PATCH\n");
return ERROR_FUNCTION_FAILED;
}
if (szUserSid)
FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
if (dwContext == MSIINSTALLCONTEXT_MACHINE)
rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
else
rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
if (rc != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
if (strcmpW(szProperty, INSTALLPROPERTY_MEDIAPACKAGEPATH) == 0)
{
HKEY key;
DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
rc = OpenMediaSubkey(sourcekey, &key, FALSE);
if (rc == ERROR_SUCCESS)
rc = RegSetValueExW(key, INSTALLPROPERTY_MEDIAPACKAGEPATH, 0,
REG_SZ, (LPBYTE)szValue, size);
if (rc != ERROR_SUCCESS)
rc = ERROR_UNKNOWN_PROPERTY;
RegCloseKey(key);
}
else if (strcmpW(szProperty, INSTALLPROPERTY_DISKPROMPT) ==0)
{
HKEY key;
DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
rc = OpenMediaSubkey(sourcekey, &key, FALSE);
if (rc == ERROR_SUCCESS)
rc = RegSetValueExW(key, INSTALLPROPERTY_DISKPROMPT, 0, REG_SZ,
(LPBYTE)szValue, size);
if (rc != ERROR_SUCCESS)
rc = ERROR_UNKNOWN_PROPERTY;
RegCloseKey(key);
}
else if (strcmpW(szProperty, INSTALLPROPERTY_LASTUSEDSOURCE)==0)
{
LPWSTR buffer = NULL;
DWORD size;
WCHAR typechar = 'n';
static const WCHAR LastUsedSource_Fmt[] = {'%','c',';','%','i',';','%','s',0};
/* make sure the source is registered */
MsiSourceListAddSourceExW(szProduct, szUserSid, dwContext,
dwOptions, szValue, 0);
if (dwOptions & MSISOURCETYPE_NETWORK)
typechar = 'n';
else if (dwOptions & MSISOURCETYPE_URL)
typechar = 'u';
else if (dwOptions & MSISOURCETYPE_MEDIA)
typechar = 'm';
else
ERR("Unknown source type! 0x%lx\n",dwOptions);
size = (lstrlenW(szValue)+5)*sizeof(WCHAR);
buffer = HeapAlloc(GetProcessHeap(),0,size);
sprintfW(buffer, LastUsedSource_Fmt, typechar, 1, szValue);
rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_LASTUSEDSOURCE, 0,
REG_EXPAND_SZ, (LPBYTE)buffer, size);
if (rc != ERROR_SUCCESS)
rc = ERROR_UNKNOWN_PROPERTY;
HeapFree( GetProcessHeap(), 0, buffer );
}
else if (strcmpW(INSTALLPROPERTY_PACKAGENAME, szProperty)==0)
{
DWORD size = lstrlenW(szValue)*sizeof(WCHAR);
rc = RegSetValueExW(sourcekey, INSTALLPROPERTY_PACKAGENAME, 0, REG_SZ,
(LPBYTE)szValue, size);
if (rc != ERROR_SUCCESS)
rc = ERROR_UNKNOWN_PROPERTY;
}
else
{
FIXME("Unknown property %s\n",debugstr_w(szProperty));
rc = ERROR_UNKNOWN_PROPERTY;
}
RegCloseKey(sourcekey);
return rc;
}
/******************************************************************
* MsiSourceListAddSourceExW (MSI.@)
*/
UINT WINAPI MsiSourceListAddSourceExW( LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szSource,
DWORD dwIndex)
{
HKEY sourcekey;
HKEY typekey;
UINT rc;
media_info source_struct;
TRACE("%s, %s, %x, %lx, %s, %li\n", debugstr_w(szProduct),
debugstr_w(szUserSid), dwContext, dwOptions, debugstr_w(szSource),
dwIndex);
if (!szProduct)
return ERROR_INVALID_PARAMETER;
if (!szSource)
return ERROR_INVALID_PARAMETER;
if (dwOptions & MSICODE_PATCH)
{
FIXME("Unhandled options MSICODE_PATCH\n");
return ERROR_FUNCTION_FAILED;
}
if (szUserSid)
FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
if (dwContext == MSIINSTALLCONTEXT_MACHINE)
rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
else
rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
if (rc != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
if (dwOptions & MSISOURCETYPE_NETWORK)
rc = OpenNetworkSubkey(sourcekey, &typekey, TRUE);
else if (dwOptions & MSISOURCETYPE_URL)
rc = OpenURLSubkey(sourcekey, &typekey, TRUE);
else
{
ERR("Unknown media type!\n");
RegCloseKey(sourcekey);
return ERROR_FUNCTION_FAILED;
}
source_struct.szIndex[0] = 0;
if (find_given_source(typekey, szSource, &source_struct)==ERROR_SUCCESS)
{
DWORD current_index = atoiW(source_struct.szIndex);
/* found the source */
if (dwIndex > 0 && current_index != dwIndex)
FIXME("Need to reorder the souces! UNHANDLED\n");
}
else
{
DWORD current_index = 0;
static const WCHAR fmt[] = {'%','i',0};
DWORD size = lstrlenW(szSource)*sizeof(WCHAR);
if (source_struct.szIndex[0])
current_index = atoiW(source_struct.szIndex);
/* new source */
if (dwIndex > 0 && dwIndex < current_index)
FIXME("Need to reorder the souces! UNHANDLED\n");
current_index ++;
sprintfW(source_struct.szIndex,fmt,current_index);
rc = RegSetValueExW(typekey, source_struct.szIndex, 0, REG_EXPAND_SZ,
(LPBYTE)szSource, size);
}
RegCloseKey(typekey);
RegCloseKey(sourcekey);
return rc;
}
/******************************************************************
* MsiSourceListAddMediaDisk(MSI.@)
*/
UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR szProduct, LPCWSTR szUserSid,
MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwDiskId,
LPCWSTR szVolumeLabel, LPCWSTR szDiskPrompt)
{
HKEY sourcekey;
HKEY mediakey;
UINT rc;
WCHAR szIndex[10];
static const WCHAR fmt[] = {'%','i',0};
static const WCHAR disk_fmt[] = {'%','s',';','%','s',0};
static const WCHAR empty[1] = {0};
LPCWSTR pt1,pt2;
LPWSTR buffer;
DWORD size;
TRACE("%s %s %x %lx %li %s %s\n", debugstr_w(szProduct),
debugstr_w(szUserSid), dwContext, dwOptions, dwDiskId,
debugstr_w(szVolumeLabel), debugstr_w(szDiskPrompt));
if (!szProduct || lstrlenW(szProduct) > 39)
return ERROR_INVALID_PARAMETER;
if (dwOptions & MSICODE_PATCH)
{
FIXME("Unhandled options MSICODE_PATCH\n");
return ERROR_FUNCTION_FAILED;
}
if (szUserSid)
FIXME("Unhandled UserSid %s\n",debugstr_w(szUserSid));
if (dwContext == MSIINSTALLCONTEXT_USERUNMANAGED)
FIXME("Unknown context MSIINSTALLCONTEXT_USERUNMANAGED\n");
if (dwContext == MSIINSTALLCONTEXT_MACHINE)
rc = OpenSourceKey(szProduct, &sourcekey, FALSE, TRUE);
else
rc = OpenSourceKey(szProduct, &sourcekey, TRUE, TRUE);
if (rc != ERROR_SUCCESS)
return ERROR_UNKNOWN_PRODUCT;
OpenMediaSubkey(sourcekey,&mediakey,TRUE);
sprintfW(szIndex,fmt,dwDiskId);
size = 2;
if (szVolumeLabel)
{
size +=lstrlenW(szVolumeLabel);
pt1 = szVolumeLabel;
}
else
pt1 = empty;
if (szDiskPrompt)
{
size +=lstrlenW(szDiskPrompt);
pt2 = szDiskPrompt;
}
else
pt2 = empty;
size *=sizeof(WCHAR);
buffer = HeapAlloc(GetProcessHeap(),0,size);
sprintfW(buffer,disk_fmt,pt1,pt2);
RegSetValueExW(mediakey, szIndex, 0, REG_SZ, (LPBYTE)buffer, size);
HeapFree( GetProcessHeap(), 0, buffer );
RegCloseKey(sourcekey);
RegCloseKey(mediakey);
return ERROR_SUCCESS;
}

View File

@ -148,6 +148,31 @@ typedef enum tagINSTALLTYPE
INSTALLTYPE_NETWORK_IMAGE = 1 INSTALLTYPE_NETWORK_IMAGE = 1
} INSTALLTYPE; } INSTALLTYPE;
typedef enum tagMSIINSTALLCONTEXT
{
MSIINSTALLCONTEXT_FIRSTVISIBLE = 0,
MSIINSTALLCONTEXT_NONE = 0,
MSIINSTALLCONTEXT_USERMANAGED = 1,
MSIINSTALLCONTEXT_USERUNMANAGED = 2,
MSIINSTALLCONTEXT_MACHINE = 4,
MSIINSTALLCONTEXT_ALL = (MSIINSTALLCONTEXT_USERMANAGED | MSIINSTALLCONTEXT_USERUNMANAGED | MSIINSTALLCONTEXT_MACHINE),
MSIINSTALLCONTEXT_ALLUSERMANAGED= 8,
} MSIINSTALLCONTEXT;
typedef enum tagMSISOURCETYPE
{
MSISOURCETYPE_UNKNOWN = 0x00000000L,
MSISOURCETYPE_NETWORK = 0x00000001L,
MSISOURCETYPE_URL = 0x00000002L,
MSISOURCETYPE_MEDIA = 0x00000004
} MSISOURCETYPE;
typedef enum tagMSICODE
{
MSICODE_PRODUCT = 0x00000000L,
MSICODE_PATCH = 0x40000000L
} MSICODE;
#define MAX_FEATURE_CHARS 38 #define MAX_FEATURE_CHARS 38
typedef INT (CALLBACK *INSTALLUI_HANDLERA)(LPVOID, UINT, LPCSTR); typedef INT (CALLBACK *INSTALLUI_HANDLERA)(LPVOID, UINT, LPCSTR);
@ -326,6 +351,19 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE);
UINT WINAPI MsiCloseAllHandles(void); UINT WINAPI MsiCloseAllHandles(void);
INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL, HWND*); INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL, HWND*);
UINT WINAPI MsiSourceListGetInfoA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPSTR, LPDWORD);
UINT WINAPI MsiSourceListGetInfoW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR, LPWSTR, LPDWORD);
#define MsiSourceListGetInfo WINELIB_NAME_AW(MsiSourceListGetInfo)
UINT WINAPI MsiSourceListSetInfoA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, LPCSTR);
UINT WINAPI MsiSourceListSetInfoW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR, LPCWSTR);
#define MsiSourceListSetInfo WINELIB_NAME_AW(MsiSourceListSetInfo)
UINT WINAPI MsiSourceListAddSourceExA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, LPCSTR, DWORD);
UINT WINAPI MsiSourceListAddSourceExW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, LPCWSTR, DWORD);
#define MsiSourceListAddSourceEx WINELIB_NAME_AW(MsiSourceListAddSourceEx)
UINT WINAPI MsiSourceListAddMediaDiskA(LPCSTR, LPCSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPCSTR, LPCSTR);
UINT WINAPI MsiSourceListAddMediaDiskW(LPCWSTR, LPCWSTR, MSIINSTALLCONTEXT, DWORD, DWORD, LPCWSTR, LPCWSTR);
#define MsiSourceListAddMediaDisk WINELIB_NAME_AW(MsiSourceListAddMediaDisk)
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif