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:
parent
b6b4787e95
commit
b7dc53d462
|
@ -33,6 +33,7 @@ C_SRCS = \
|
|||
registry.c \
|
||||
regsvr.c \
|
||||
select.c \
|
||||
source.c \
|
||||
string.c \
|
||||
suminfo.c \
|
||||
table.c \
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
#include "winerror.h"
|
||||
#include "wine/debug.h"
|
||||
#include "fdi.h"
|
||||
#include "msi.h"
|
||||
#include "msidefs.h"
|
||||
#include "msvcrt/fcntl.h"
|
||||
#include "msipriv.h"
|
||||
|
@ -54,6 +55,8 @@ extern const WCHAR szRemoveDuplicateFiles[];
|
|||
extern const WCHAR szRemoveFiles[];
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -359,7 +362,8 @@ static VOID set_file_source(MSIPACKAGE* package, MSIFILE* file, MSICOMPONENT*
|
|||
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 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);
|
||||
TRACE("Drive contains %s\n", debugstr_w(name));
|
||||
volume = strdupW(name);
|
||||
if (*intype)
|
||||
*intype=type;
|
||||
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,
|
||||
MSIRECORD *row)
|
||||
MSIRECORD *row,UINT *type )
|
||||
{
|
||||
LPWSTR volume = NULL;
|
||||
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));
|
||||
|
||||
|
@ -449,6 +455,9 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
|
|||
static LPWSTR last_volume = NULL;
|
||||
static LPWSTR last_path = NULL;
|
||||
MSIFILE* file = NULL;
|
||||
UINT type;
|
||||
LPCWSTR prompt;
|
||||
static DWORD count = 0;
|
||||
|
||||
/* cleanup signal */
|
||||
if (!package)
|
||||
|
@ -467,6 +476,7 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
|
|||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
count ++;
|
||||
row = MSI_QueryGetRecord(package->db, ExecSeqQuery, file->Sequence);
|
||||
if (!row)
|
||||
{
|
||||
|
@ -478,6 +488,7 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
|
|||
last_sequence = seq;
|
||||
|
||||
volume = MSI_RecordGetString(row, 5);
|
||||
prompt = MSI_RecordGetString(row, 3);
|
||||
|
||||
HeapFree(GetProcessHeap(),0,last_path);
|
||||
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);
|
||||
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);
|
||||
return rc;
|
||||
}
|
||||
|
@ -498,9 +525,25 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
|
|||
/* the stream does not contain the # character */
|
||||
if (cab[0]=='#')
|
||||
{
|
||||
LPWSTR path;
|
||||
|
||||
writeout_cabinet_stream(package,&cab[1],source);
|
||||
last_path = strdupW(source);
|
||||
*(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
|
||||
{
|
||||
|
@ -515,12 +558,25 @@ static UINT ready_media_for_file(MSIPACKAGE *package, int fileindex,
|
|||
{
|
||||
strcpyW(last_path,source);
|
||||
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 */
|
||||
sz = MAX_PATH;
|
||||
if (MSI_GetPropertyW(package, cszTempFolder,last_path, &sz)
|
||||
!= ERROR_SUCCESS)
|
||||
GetTempPathW(MAX_PATH,last_path);
|
||||
rc = ready_volume(package, source, last_volume, row);
|
||||
}
|
||||
}
|
||||
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));
|
||||
MSI_GetPropertyW(package,cszSourceDir,source,&sz);
|
||||
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);
|
||||
|
||||
MsiSourceListAddMediaDiskW(package->ProductCode, NULL,
|
||||
MSIINSTALLCONTEXT_USERMANAGED, MSICODE_PRODUCT, count, volume,
|
||||
prompt);
|
||||
|
||||
msiobj_release(&row->hdr);
|
||||
|
||||
return rc;
|
||||
|
@ -577,6 +650,7 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
|||
{
|
||||
UINT rc = ERROR_SUCCESS;
|
||||
DWORD index;
|
||||
LPWSTR ptr;
|
||||
|
||||
if (!package)
|
||||
return ERROR_INVALID_HANDLE;
|
||||
|
@ -584,6 +658,18 @@ UINT ACTION_InstallFiles(MSIPACKAGE *package)
|
|||
/* increment progress bar each time action data is sent */
|
||||
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 */
|
||||
for (index = 0; index < package->loaded_files; index++)
|
||||
{
|
||||
|
|
|
@ -217,6 +217,7 @@ typedef struct tagMSIPACKAGE
|
|||
|
||||
LPWSTR PackagePath;
|
||||
LPWSTR msiFilePath;
|
||||
LPWSTR ProductCode;
|
||||
|
||||
UINT CurrentInstallState;
|
||||
msi_dialog *dialog;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -148,6 +148,31 @@ typedef enum tagINSTALLTYPE
|
|||
INSTALLTYPE_NETWORK_IMAGE = 1
|
||||
} 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
|
||||
|
||||
typedef INT (CALLBACK *INSTALLUI_HANDLERA)(LPVOID, UINT, LPCSTR);
|
||||
|
@ -326,6 +351,19 @@ UINT WINAPI MsiCloseHandle(MSIHANDLE);
|
|||
UINT WINAPI MsiCloseAllHandles(void);
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue