summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2012-10-22 15:44:18 +0200
committerPaolo Bonzini <pbonzini@redhat.com>2012-12-06 20:25:49 +0100
commita8361b5fd3774ba66dae76a56ba0ebd51c3631e8 (patch)
tree20d1972b3c9ceeb41913d480a1ec3005d2e2fce5
parentb8e118094c1698a49e0dcaa4d1fad864169e8042 (diff)
downloadmsitools-a8361b5fd3774ba66dae76a56ba0ebd51c3631e8.tar.gz
msitools-a8361b5fd3774ba66dae76a56ba0ebd51c3631e8.tar.xz
msitools-a8361b5fd3774ba66dae76a56ba0ebd51c3631e8.zip
kill package.c and more
-rw-r--r--libmsi/Makefile.am3
-rw-r--r--libmsi/media.c618
-rw-r--r--libmsi/msi.c217
-rw-r--r--libmsi/msi_main.c48
-rw-r--r--libmsi/package.c1195
5 files changed, 1 insertions, 2080 deletions
diff --git a/libmsi/Makefile.am b/libmsi/Makefile.am
index 565fa48..25bd8a0 100644
--- a/libmsi/Makefile.am
+++ b/libmsi/Makefile.am
@@ -13,8 +13,7 @@ noinst_HEADERS = \
query.h
libmsi_la_SOURCES = alter.c create.c database.c delete.c distinct.c \
- drop.c handle.c insert.c media.c msi.c msi_main.c msiquery.c \
- package.c record.c select.c \
+ drop.c handle.c insert.c msi.c msiquery.c record.c select.c \
storages.c streams.c string.c suminfo.c table.c tokenize.c update.c \
where.c \
sql-parser.y \
diff --git a/libmsi/media.c b/libmsi/media.c
deleted file mode 100644
index 10d7fe8..0000000
--- a/libmsi/media.c
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * Implementation of the Microsoft Installer (msi.dll)
- *
- * Copyright 2008 James Hawkins
- *
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-
-#define COBJMACROS
-
-#include "windef.h"
-#include "winerror.h"
-#include "wine/debug.h"
-#include "fdi.h"
-#include "msipriv.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "winreg.h"
-#include "shlwapi.h"
-#include "objidl.h"
-#include "wine/unicode.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(msi);
-
-/* from msvcrt/fcntl.h */
-#define _O_RDONLY 0
-#define _O_WRONLY 1
-#define _O_RDWR 2
-#define _O_ACCMODE (_O_RDONLY|_O_WRONLY|_O_RDWR)
-#define _O_APPEND 0x0008
-#define _O_RANDOM 0x0010
-#define _O_SEQUENTIAL 0x0020
-#define _O_TEMPORARY 0x0040
-#define _O_NOINHERIT 0x0080
-#define _O_CREAT 0x0100
-#define _O_TRUNC 0x0200
-#define _O_EXCL 0x0400
-#define _O_SHORT_LIVED 0x1000
-#define _O_TEXT 0x4000
-#define _O_BINARY 0x8000
-
-static MSICABINETSTREAM *msi_get_cabinet_stream( MSIPACKAGE *package, UINT disk_id )
-{
- MSICABINETSTREAM *cab;
-
- LIST_FOR_EACH_ENTRY( cab, &package->cabinet_streams, MSICABINETSTREAM, entry )
- {
- if (cab->disk_id == disk_id) return cab;
- }
- return NULL;
-}
-
-static void * CDECL cabinet_alloc(ULONG cb)
-{
- return msi_alloc(cb);
-}
-
-static void CDECL cabinet_free(void *pv)
-{
- msi_free(pv);
-}
-
-static INT_PTR CDECL cabinet_open(char *pszFile, int oflag, int pmode)
-{
- HANDLE handle;
- DWORD dwAccess = 0;
- DWORD dwShareMode = 0;
- DWORD dwCreateDisposition = OPEN_EXISTING;
-
- switch (oflag & _O_ACCMODE)
- {
- case _O_RDONLY:
- dwAccess = GENERIC_READ;
- dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
- break;
- case _O_WRONLY:
- dwAccess = GENERIC_WRITE;
- dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- case _O_RDWR:
- dwAccess = GENERIC_READ | GENERIC_WRITE;
- dwShareMode = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
- break;
- }
-
- if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
- dwCreateDisposition = CREATE_NEW;
- else if (oflag & _O_CREAT)
- dwCreateDisposition = CREATE_ALWAYS;
-
- handle = CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
- dwCreateDisposition, 0, NULL);
- if (handle == INVALID_HANDLE_VALUE)
- return 0;
-
- return (INT_PTR)handle;
-}
-
-static UINT CDECL cabinet_read(INT_PTR hf, void *pv, UINT cb)
-{
- HANDLE handle = (HANDLE)hf;
- DWORD read;
-
- if (ReadFile(handle, pv, cb, &read, NULL))
- return read;
-
- return 0;
-}
-
-static UINT CDECL cabinet_write(INT_PTR hf, void *pv, UINT cb)
-{
- HANDLE handle = (HANDLE)hf;
- DWORD written;
-
- if (WriteFile(handle, pv, cb, &written, NULL))
- return written;
-
- return 0;
-}
-
-static int CDECL cabinet_close(INT_PTR hf)
-{
- HANDLE handle = (HANDLE)hf;
- return CloseHandle(handle) ? 0 : -1;
-}
-
-static LONG CDECL cabinet_seek(INT_PTR hf, LONG dist, int seektype)
-{
- HANDLE handle = (HANDLE)hf;
- /* flags are compatible and so are passed straight through */
- return SetFilePointer(handle, dist, NULL, seektype);
-}
-
-struct package_disk
-{
- MSIPACKAGE *package;
- UINT id;
-};
-
-static struct package_disk package_disk;
-
-static INT_PTR CDECL cabinet_open_stream( char *pszFile, int oflag, int pmode )
-{
- MSICABINETSTREAM *cab;
- IStream *stream;
- WCHAR *encoded;
- HRESULT hr;
-
- cab = msi_get_cabinet_stream( package_disk.package, package_disk.id );
- if (!cab)
- {
- WARN("failed to get cabinet stream\n");
- return 0;
- }
- if (!cab->stream[0] || !(encoded = encode_streamname( FALSE, cab->stream + 1 )))
- {
- WARN("failed to encode stream name\n");
- return 0;
- }
- if (msi_clone_open_stream( package_disk.package->db, cab->storage, encoded, &stream ) != ERROR_SUCCESS)
- {
- hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream );
- if (FAILED(hr))
- {
- WARN("failed to open stream 0x%08x\n", hr);
- msi_free( encoded );
- return 0;
- }
- }
- msi_free( encoded );
- return (INT_PTR)stream;
-}
-
-static UINT CDECL cabinet_read_stream( INT_PTR hf, void *pv, UINT cb )
-{
- IStream *stm = (IStream *)hf;
- DWORD read;
- HRESULT hr;
-
- hr = IStream_Read( stm, pv, cb, &read );
- if (hr == S_OK || hr == S_FALSE)
- return read;
-
- return 0;
-}
-
-static int CDECL cabinet_close_stream( INT_PTR hf )
-{
- IStream *stm = (IStream *)hf;
- IStream_Release( stm );
- return 0;
-}
-
-static LONG CDECL cabinet_seek_stream( INT_PTR hf, LONG dist, int seektype )
-{
- IStream *stm = (IStream *)hf;
- LARGE_INTEGER move;
- ULARGE_INTEGER newpos;
- HRESULT hr;
-
- move.QuadPart = dist;
- hr = IStream_Seek( stm, move, seektype, &newpos );
- if (SUCCEEDED(hr))
- {
- if (newpos.QuadPart <= MAXLONG) return newpos.QuadPart;
- ERR("Too big!\n");
- }
- return -1;
-}
-
-static UINT CDECL msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi)
-{
- MSIRECORD *row;
-
- static const WCHAR query[] = {
- 'S','E','L','E','C','T',' ','*',' ', 'F','R','O','M',' ',
- '`','M','e','d','i','a','`',' ','W','H','E','R','E',' ',
- '`','D','i','s','k','I','d','`',' ','=',' ','%','i',0};
-
- row = MSI_QueryGetRecord(package->db, query, mi->disk_id);
- if (!row)
- {
- TRACE("Unable to query row\n");
- return ERROR_FUNCTION_FAILED;
- }
-
- mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
- mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
- mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
-
- if (!mi->first_volume)
- mi->first_volume = strdupW(mi->volume_label);
-
- msiobj_release(&row->hdr);
- return ERROR_SUCCESS;
-}
-
-static INT_PTR cabinet_partial_file(FDINOTIFICATIONTYPE fdint,
- PFDINOTIFICATION pfdin)
-{
- MSICABDATA *data = pfdin->pv;
- data->mi->is_continuous = FALSE;
- return 0;
-}
-
-static WCHAR *get_cabinet_filename(MSIMEDIAINFO *mi)
-{
- int len;
- WCHAR *ret;
-
- len = strlenW(mi->sourcedir) + strlenW(mi->cabinet) + 1;
- if (!(ret = msi_alloc(len * sizeof(WCHAR)))) return NULL;
- strcpyW(ret, mi->sourcedir);
- strcatW(ret, mi->cabinet);
- return ret;
-}
-
-static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint,
- PFDINOTIFICATION pfdin)
-{
- MSICABDATA *data = pfdin->pv;
- MSIMEDIAINFO *mi = data->mi;
- LPWSTR cabinet_file = NULL, cab = strdupAtoW(pfdin->psz1);
- INT_PTR res = -1;
- UINT rc;
-
- msi_free(mi->disk_prompt);
- msi_free(mi->cabinet);
- msi_free(mi->volume_label);
- mi->disk_prompt = NULL;
- mi->cabinet = NULL;
- mi->volume_label = NULL;
-
- mi->disk_id++;
- mi->is_continuous = TRUE;
-
- rc = msi_media_get_disk_info(data->package, mi);
- if (rc != ERROR_SUCCESS)
- {
- ERR("Failed to get next cabinet information: %d\n", rc);
- goto done;
- }
-
- if (strcmpiW( mi->cabinet, cab ))
- {
- ERR("Continuous cabinet does not match the next cabinet in the Media table\n");
- goto done;
- }
-
- if (!(cabinet_file = get_cabinet_filename(mi)))
- goto done;
-
- TRACE("Searching for %s\n", debugstr_w(cabinet_file));
-
- res = 0;
- if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES)
- res = -1;
-
-done:
- msi_free(cab);
- msi_free(cabinet_file);
- return res;
-}
-
-static INT_PTR cabinet_next_cabinet_stream( FDINOTIFICATIONTYPE fdint,
- PFDINOTIFICATION pfdin )
-{
- MSICABDATA *data = pfdin->pv;
- MSIMEDIAINFO *mi = data->mi;
- UINT rc;
-
- msi_free( mi->disk_prompt );
- msi_free( mi->cabinet );
- msi_free( mi->volume_label );
- mi->disk_prompt = NULL;
- mi->cabinet = NULL;
- mi->volume_label = NULL;
-
- mi->disk_id++;
- mi->is_continuous = TRUE;
-
- rc = msi_media_get_disk_info( data->package, mi );
- if (rc != ERROR_SUCCESS)
- {
- ERR("Failed to get next cabinet information: %u\n", rc);
- return -1;
- }
- package_disk.id = mi->disk_id;
-
- TRACE("next cabinet is %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
- return 0;
-}
-
-static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint,
- PFDINOTIFICATION pfdin)
-{
- MSICABDATA *data = pfdin->pv;
- HANDLE handle = 0;
- LPWSTR path = NULL;
- DWORD attrs;
-
- data->curfile = strdupAtoW(pfdin->psz1);
- if (!data->cb(data->package, data->curfile, MSICABEXTRACT_BEGINEXTRACT, &path,
- &attrs, data->user))
- {
- /* We're not extracting this file, so free the filename. */
- msi_free(data->curfile);
- data->curfile = NULL;
- goto done;
- }
-
- TRACE("extracting %s -> %s\n", debugstr_w(data->curfile), debugstr_w(path));
-
- attrs = attrs & (FILE_ATTRIBUTE_READONLY|FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM);
- if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
-
- handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0,
- NULL, CREATE_ALWAYS, attrs, NULL);
- if (handle == INVALID_HANDLE_VALUE)
- {
- DWORD err = GetLastError();
- DWORD attrs2 = GetFileAttributesW(path);
-
- if (attrs2 == INVALID_FILE_ATTRIBUTES)
- {
- ERR("failed to create %s (error %d)\n", debugstr_w(path), err);
- goto done;
- }
- else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY))
- {
- TRACE("removing read-only attribute on %s\n", debugstr_w(path));
- SetFileAttributesW( path, attrs2 & ~FILE_ATTRIBUTE_READONLY );
- handle = CreateFileW(path, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs2, NULL);
-
- if (handle != INVALID_HANDLE_VALUE) goto done;
- err = GetLastError();
- }
- if (err == ERROR_SHARING_VIOLATION || err == ERROR_USER_MAPPED_FILE)
- {
- WCHAR *tmpfileW, *tmppathW, *p;
- DWORD len;
-
- TRACE("file in use, scheduling rename operation\n");
-
- if (!(tmppathW = strdupW( path ))) return ERROR_OUTOFMEMORY;
- if ((p = strrchrW(tmppathW, '\\'))) *p = 0;
- len = strlenW( tmppathW ) + 16;
- if (!(tmpfileW = msi_alloc(len * sizeof(WCHAR))))
- {
- msi_free( tmppathW );
- return ERROR_OUTOFMEMORY;
- }
- if (!GetTempFileNameW(tmppathW, szMsi, 0, tmpfileW)) tmpfileW[0] = 0;
- msi_free( tmppathW );
-
- handle = CreateFileW(tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, attrs, NULL);
-
- if (handle != INVALID_HANDLE_VALUE &&
- MoveFileExW(path, NULL, MOVEFILE_DELAY_UNTIL_REBOOT) &&
- MoveFileExW(tmpfileW, path, MOVEFILE_DELAY_UNTIL_REBOOT))
- {
- data->package->need_reboot_at_end = 1;
- }
- else
- {
- WARN("failed to schedule rename operation %s (error %d)\n", debugstr_w(path), GetLastError());
- DeleteFileW( tmpfileW );
- }
- msi_free(tmpfileW);
- }
- else
- WARN("failed to create %s (error %d)\n", debugstr_w(path), err);
- }
-
-done:
- msi_free(path);
-
- return (INT_PTR)handle;
-}
-
-static INT_PTR cabinet_close_file_info(FDINOTIFICATIONTYPE fdint,
- PFDINOTIFICATION pfdin)
-{
- MSICABDATA *data = pfdin->pv;
- FILETIME ft;
- FILETIME ftLocal;
- HANDLE handle = (HANDLE)pfdin->hf;
-
- data->mi->is_continuous = FALSE;
-
- if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
- return -1;
- if (!LocalFileTimeToFileTime(&ft, &ftLocal))
- return -1;
- if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
- return -1;
-
- CloseHandle(handle);
-
- data->cb(data->package, data->curfile, MSICABEXTRACT_FILEEXTRACTED, NULL, NULL,
- data->user);
-
- msi_free(data->curfile);
- data->curfile = NULL;
-
- return 1;
-}
-
-static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
-{
- switch (fdint)
- {
- case fdintPARTIAL_FILE:
- return cabinet_partial_file(fdint, pfdin);
-
- case fdintNEXT_CABINET:
- return cabinet_next_cabinet(fdint, pfdin);
-
- case fdintCOPY_FILE:
- return cabinet_copy_file(fdint, pfdin);
-
- case fdintCLOSE_FILE_INFO:
- return cabinet_close_file_info(fdint, pfdin);
-
- default:
- return 0;
- }
-}
-
-static INT_PTR CDECL cabinet_notify_stream( FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin )
-{
- switch (fdint)
- {
- case fdintPARTIAL_FILE:
- return cabinet_partial_file( fdint, pfdin );
-
- case fdintNEXT_CABINET:
- return cabinet_next_cabinet_stream( fdint, pfdin );
-
- case fdintCOPY_FILE:
- return cabinet_copy_file( fdint, pfdin );
-
- case fdintCLOSE_FILE_INFO:
- return cabinet_close_file_info( fdint, pfdin );
-
- case fdintCABINET_INFO:
- return 0;
-
- default:
- ERR("Unexpected notification %d\n", fdint);
- return 0;
- }
-}
-
-static BOOL extract_cabinet( MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data )
-{
- LPSTR cabinet, cab_path = NULL;
- HFDI hfdi;
- ERF erf;
- BOOL ret = FALSE;
-
- TRACE("extracting %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
-
- hfdi = FDICreate( cabinet_alloc, cabinet_free, cabinet_open, cabinet_read,
- cabinet_write, cabinet_close, cabinet_seek, 0, &erf );
- if (!hfdi)
- {
- ERR("FDICreate failed\n");
- return FALSE;
- }
-
- cabinet = strdupWtoA( mi->cabinet );
- if (!cabinet)
- goto done;
-
- cab_path = strdupWtoA( mi->sourcedir );
- if (!cab_path)
- goto done;
-
- ret = FDICopy( hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data );
- if (!ret)
- ERR("FDICopy failed\n");
-
-done:
- FDIDestroy( hfdi );
- msi_free(cabinet );
- msi_free( cab_path );
-
- if (ret)
- mi->is_extracted = TRUE;
-
- return ret;
-}
-
-static BOOL extract_cabinet_stream( MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data )
-{
- static char filename[] = {'<','S','T','R','E','A','M','>',0};
- HFDI hfdi;
- ERF erf;
- BOOL ret = FALSE;
-
- TRACE("extracting %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
-
- hfdi = FDICreate( cabinet_alloc, cabinet_free, cabinet_open_stream, cabinet_read_stream,
- cabinet_write, cabinet_close_stream, cabinet_seek_stream, 0, &erf );
- if (!hfdi)
- {
- ERR("FDICreate failed\n");
- return FALSE;
- }
-
- package_disk.package = package;
- package_disk.id = mi->disk_id;
-
- ret = FDICopy( hfdi, filename, NULL, 0, cabinet_notify_stream, NULL, data );
- if (!ret) ERR("FDICopy failed\n");
-
- FDIDestroy( hfdi );
- if (ret) mi->is_extracted = TRUE;
- return ret;
-}
-
-/***********************************************************************
- * msi_cabextract
- *
- * Extract files from a cabinet file or stream.
- */
-BOOL msi_cabextract(MSIPACKAGE* package, MSIMEDIAINFO *mi, LPVOID data)
-{
- if (mi->cabinet[0] == '#')
- {
- return extract_cabinet_stream( package, mi, data );
- }
- return extract_cabinet( package, mi, data );
-}
-
-UINT msi_add_cabinet_stream( MSIPACKAGE *package, UINT disk_id, IStorage *storage, const WCHAR *name )
-{
- MSICABINETSTREAM *cab, *item;
-
- TRACE("%p, %u, %p, %s\n", package, disk_id, storage, debugstr_w(name));
-
- LIST_FOR_EACH_ENTRY( item, &package->cabinet_streams, MSICABINETSTREAM, entry )
- {
- if (item->disk_id == disk_id)
- {
- TRACE("duplicate disk id %u\n", disk_id);
- return ERROR_FUNCTION_FAILED;
- }
- }
- if (!(cab = msi_alloc( sizeof(*cab) ))) return ERROR_OUTOFMEMORY;
- if (!(cab->stream = msi_alloc( (strlenW( name ) + 1) * sizeof(WCHAR ) )))
- {
- msi_free( cab );
- return ERROR_OUTOFMEMORY;
- }
- strcpyW( cab->stream, name );
- cab->disk_id = disk_id;
- cab->storage = storage;
- IStorage_AddRef( storage );
- list_add_tail( &package->cabinet_streams, &cab->entry );
-
- return ERROR_SUCCESS;
-}
diff --git a/libmsi/msi.c b/libmsi/msi.c
index 4ebf576..0a388b5 100644
--- a/libmsi/msi.c
+++ b/libmsi/msi.c
@@ -85,204 +85,6 @@ UINT msi_strcpy_to_awstring( LPCWSTR str, awstring *awbuf, DWORD *sz )
return r;
}
-UINT WINAPI MsiEnableLogA(DWORD dwLogMode, LPCSTR szLogFile, DWORD attributes)
-{
- LPWSTR szwLogFile = NULL;
- UINT r;
-
- TRACE("%08x %s %08x\n", dwLogMode, debugstr_a(szLogFile), attributes);
-
- if( szLogFile )
- {
- szwLogFile = strdupAtoW( szLogFile );
- if( !szwLogFile )
- return ERROR_OUTOFMEMORY;
- }
- r = MsiEnableLogW( dwLogMode, szwLogFile, attributes );
- msi_free( szwLogFile );
- return r;
-}
-
-UINT WINAPI MsiEnableLogW(DWORD dwLogMode, LPCWSTR szLogFile, DWORD attributes)
-{
- TRACE("%08x %s %08x\n", dwLogMode, debugstr_w(szLogFile), attributes);
-
- msi_free(gszLogFile);
- gszLogFile = NULL;
- if (szLogFile)
- {
- HANDLE file;
-
- if (!(attributes & INSTALLLOGATTRIBUTES_APPEND))
- DeleteFileW(szLogFile);
- file = CreateFileW(szLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_ALWAYS,
- FILE_ATTRIBUTE_NORMAL, NULL);
- if (file != INVALID_HANDLE_VALUE)
- {
- gszLogFile = strdupW(szLogFile);
- CloseHandle(file);
- }
- else
- ERR("Unable to enable log %s (%u)\n", debugstr_w(szLogFile), GetLastError());
- }
-
- return ERROR_SUCCESS;
-}
-
-UINT WINAPI MsiEnumComponentCostsA( MSIHANDLE handle, LPCSTR component, DWORD index,
- INSTALLSTATE state, LPSTR drive, DWORD *buflen,
- int *cost, int *temp )
-{
- UINT r;
- DWORD len;
- WCHAR *driveW, *componentW = NULL;
-
- TRACE("%d, %s, %u, %d, %p, %p, %p %p\n", handle, debugstr_a(component), index,
- state, drive, buflen, cost, temp);
-
- if (!drive || !buflen) return ERROR_INVALID_PARAMETER;
- if (component && !(componentW = strdupAtoW( component ))) return ERROR_OUTOFMEMORY;
-
- len = *buflen;
- if (!(driveW = msi_alloc( len * sizeof(WCHAR) )))
- {
- msi_free( componentW );
- return ERROR_OUTOFMEMORY;
- }
- r = MsiEnumComponentCostsW( handle, componentW, index, state, driveW, buflen, cost, temp );
- if (!r)
- {
- WideCharToMultiByte( CP_ACP, 0, driveW, -1, drive, len, NULL, NULL );
- }
- msi_free( componentW );
- msi_free( driveW );
- return r;
-}
-
-static UINT set_drive( WCHAR *buffer, WCHAR letter )
-{
- buffer[0] = letter;
- buffer[1] = ':';
- buffer[2] = 0;
- return 2;
-}
-
-UINT WINAPI MsiEnumComponentCostsW( MSIHANDLE handle, LPCWSTR component, DWORD index,
- INSTALLSTATE state, LPWSTR drive, DWORD *buflen,
- int *cost, int *temp )
-{
- UINT r = ERROR_NO_MORE_ITEMS;
- MSICOMPONENT *comp = NULL;
- MSIPACKAGE *package;
- MSIFILE *file;
- STATSTG stat = {0};
- WCHAR path[MAX_PATH];
-
- TRACE("%d, %s, %u, %d, %p, %p, %p %p\n", handle, debugstr_w(component), index,
- state, drive, buflen, cost, temp);
-
- if (!drive || !buflen || !cost || !temp) return ERROR_INVALID_PARAMETER;
- package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE );
- if ( !package )
- return ERROR_INVALID_HANDLE;
-
- if (!msi_get_property_int( package->db, szCostingComplete, 0 ))
- {
- msiobj_release( &package->hdr );
- return ERROR_FUNCTION_NOT_CALLED;
- }
- if (component && component[0] && !(comp = msi_get_loaded_component( package, component )))
- {
- msiobj_release( &package->hdr );
- return ERROR_UNKNOWN_COMPONENT;
- }
- if (*buflen < 3)
- {
- *buflen = 2;
- msiobj_release( &package->hdr );
- return ERROR_MORE_DATA;
- }
- if (index)
- {
- msiobj_release( &package->hdr );
- return ERROR_NO_MORE_ITEMS;
- }
-
- drive[0] = 0;
- *cost = *temp = 0;
- GetWindowsDirectoryW( path, MAX_PATH );
- if (component && component[0])
- {
- if (comp->assembly && !comp->assembly->application) *temp = comp->Cost;
- if (!comp->Enabled || !comp->KeyPath)
- {
- *cost = 0;
- *buflen = set_drive( drive, path[0] );
- r = ERROR_SUCCESS;
- }
- else if ((file = msi_get_loaded_file( package, comp->KeyPath )))
- {
- *cost = max( 8, comp->Cost / 512 );
- *buflen = set_drive( drive, file->TargetPath[0] );
- r = ERROR_SUCCESS;
- }
- }
- else if (IStorage_Stat( package->db->storage, &stat, STATFLAG_NONAME ) == S_OK)
- {
- *temp = max( 8, stat.cbSize.QuadPart / 512 );
- *buflen = set_drive( drive, path[0] );
- r = ERROR_SUCCESS;
- }
- msiobj_release( &package->hdr );
- return r;
-}
-
-INSTALLUILEVEL WINAPI MsiSetInternalUI(INSTALLUILEVEL dwUILevel, HWND *phWnd)
-{
- INSTALLUILEVEL old = gUILevel;
- HWND oldwnd = gUIhwnd;
-
- TRACE("%08x %p\n", dwUILevel, phWnd);
-
- gUILevel = dwUILevel;
- if (phWnd)
- {
- gUIhwnd = *phWnd;
- *phWnd = oldwnd;
- }
- return old;
-}
-
-INSTALLUI_HANDLERA WINAPI MsiSetExternalUIA(INSTALLUI_HANDLERA puiHandler,
- DWORD dwMessageFilter, LPVOID pvContext)
-{
- INSTALLUI_HANDLERA prev = gUIHandlerA;
-
- TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
-
- gUIHandlerA = puiHandler;
- gUIHandlerW = NULL;
- gUIFilter = dwMessageFilter;
- gUIContext = pvContext;
-
- return prev;
-}
-
-INSTALLUI_HANDLERW WINAPI MsiSetExternalUIW(INSTALLUI_HANDLERW puiHandler,
- DWORD dwMessageFilter, LPVOID pvContext)
-{
- INSTALLUI_HANDLERW prev = gUIHandlerW;
-
- TRACE("%p %08x %p\n", puiHandler, dwMessageFilter, pvContext);
-
- gUIHandlerA = NULL;
- gUIHandlerW = puiHandler;
- gUIFilter = dwMessageFilter;
- gUIContext = pvContext;
-
- return prev;
-}
-
/******************************************************************
* MsiGetProductPropertyA [MSI.@]
*/
@@ -586,25 +388,6 @@ UINT WINAPI MsiGetFileHashA( LPCSTR szFilePath, DWORD dwOptions,
}
/***********************************************************************
- * MsiSetExternalUIRecord [MSI.@]
- */
-UINT WINAPI MsiSetExternalUIRecord( INSTALLUI_HANDLER_RECORD handler,
- DWORD filter, LPVOID context,
- PINSTALLUI_HANDLER_RECORD prev )
-{
- TRACE("%p %08x %p %p\n", handler, filter, context, prev);
-
- if (prev)
- *prev = gUIHandlerRecord;
-
- gUIHandlerRecord = handler;
- gUIFilter = filter;
- gUIContext = context;
-
- return ERROR_SUCCESS;
-}
-
-/***********************************************************************
* MsiInstallMissingComponentA [MSI.@]
*/
UINT WINAPI MsiInstallMissingComponentA( LPCSTR product, LPCSTR component, INSTALLSTATE state )
diff --git a/libmsi/msi_main.c b/libmsi/msi_main.c
deleted file mode 100644
index 17c3238..0000000
--- a/libmsi/msi_main.c
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Implementation of the Microsoft Installer (msi.dll)
- *
- * Copyright 2006 Mike McCormack 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include <stdarg.h>
-
-#define COBJMACROS
-#define NONAMELESSUNION
-
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "shlwapi.h"
-#include "oleauto.h"
-#include "rpcproxy.h"
-#include "msipriv.h"
-#include "msiserver.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(msi);
-
-/* the UI level */
-INSTALLUILEVEL gUILevel = INSTALLUILEVEL_BASIC;
-HWND gUIhwnd = 0;
-INSTALLUI_HANDLERA gUIHandlerA = NULL;
-INSTALLUI_HANDLERW gUIHandlerW = NULL;
-INSTALLUI_HANDLER_RECORD gUIHandlerRecord = NULL;
-DWORD gUIFilter = 0;
-LPVOID gUIContext = NULL;
-WCHAR *gszLogFile = NULL;
-HINSTANCE msi_hInstance;
diff --git a/libmsi/package.c b/libmsi/package.c
deleted file mode 100644
index 0503211..0000000
--- a/libmsi/package.c
+++ /dev/null
@@ -1,1195 +0,0 @@
-/*
- * Implementation of the Microsoft Installer (msi.dll)
- *
- * Copyright 2004 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#define NONAMELESSUNION
-#define NONAMELESSSTRUCT
-#define COBJMACROS
-
-#include <stdarg.h>
-#include "windef.h"
-#include "winbase.h"
-#include "winreg.h"
-#include "winnls.h"
-#include "shlwapi.h"
-#include "wingdi.h"
-#include "wine/debug.h"
-#include "msi.h"
-#include "msiquery.h"
-#include "objidl.h"
-#include "wincrypt.h"
-#include "wingdi.h"
-#include "winuser.h"
-#include "wininet.h"
-#include "winver.h"
-#include "urlmon.h"
-#include "shlobj.h"
-#include "wine/unicode.h"
-#include "objbase.h"
-#include "msidefs.h"
-#include "sddl.h"
-
-#include "msipriv.h"
-#include "msiserver.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(msi);
-
-MSICOMPONENT *msi_get_loaded_component( MSIPACKAGE *package, const WCHAR *Component )
-{
- MSICOMPONENT *comp;
-
- LIST_FOR_EACH_ENTRY( comp, &package->components, MSICOMPONENT, entry )
- {
- if (!strcmpW( Component, comp->Component )) return comp;
- }
- return NULL;
-}
-
-MSIFEATURE *msi_get_loaded_feature(MSIPACKAGE* package, const WCHAR *Feature )
-{
- MSIFEATURE *feature;
-
- LIST_FOR_EACH_ENTRY( feature, &package->features, MSIFEATURE, entry )
- {
- if (!strcmpW( Feature, feature->Feature )) return feature;
- }
- return NULL;
-}
-
-MSIFILE *msi_get_loaded_file( MSIPACKAGE *package, const WCHAR *key )
-{
- MSIFILE *file;
-
- LIST_FOR_EACH_ENTRY( file, &package->files, MSIFILE, entry )
- {
- if (!strcmpW( key, file->File )) return file;
- }
- return NULL;
-}
-
-MSIFILEPATCH *msi_get_loaded_filepatch( MSIPACKAGE *package, const WCHAR *key )
-{
- MSIFILEPATCH *patch;
-
- /* FIXME: There might be more than one patch */
- LIST_FOR_EACH_ENTRY( patch, &package->filepatches, MSIFILEPATCH, entry )
- {
- if (!strcmpW( key, patch->File->File )) return patch;
- }
- return NULL;
-}
-
-MSIFOLDER *msi_get_loaded_folder( MSIPACKAGE *package, const WCHAR *dir )
-{
- MSIFOLDER *folder;
-
- LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
- {
- if (!strcmpW( dir, folder->Directory )) return folder;
- }
- return NULL;
-}
-
-
-static void remove_tracked_tempfiles( MSIPACKAGE *package )
-{
- struct list *item, *cursor;
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->tempfiles )
- {
- MSITEMPFILE *temp = LIST_ENTRY( item, MSITEMPFILE, entry );
-
- list_remove( &temp->entry );
- TRACE("deleting temp file %s\n", debugstr_w( temp->Path ));
- DeleteFileW( temp->Path );
- msi_free( temp->Path );
- msi_free( temp );
- }
-}
-
-static void free_feature( MSIFEATURE *feature )
-{
- struct list *item, *cursor;
-
- LIST_FOR_EACH_SAFE( item, cursor, &feature->Children )
- {
- FeatureList *fl = LIST_ENTRY( item, FeatureList, entry );
- list_remove( &fl->entry );
- msi_free( fl );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &feature->Components )
- {
- ComponentList *cl = LIST_ENTRY( item, ComponentList, entry );
- list_remove( &cl->entry );
- msi_free( cl );
- }
- msi_free( feature->Feature );
- msi_free( feature->Feature_Parent );
- msi_free( feature->Directory );
- msi_free( feature->Description );
- msi_free( feature->Title );
- msi_free( feature );
-}
-
-static void free_folder( MSIFOLDER *folder )
-{
- struct list *item, *cursor;
-
- LIST_FOR_EACH_SAFE( item, cursor, &folder->children )
- {
- FolderList *fl = LIST_ENTRY( item, FolderList, entry );
- list_remove( &fl->entry );
- msi_free( fl );
- }
- msi_free( folder->Parent );
- msi_free( folder->Directory );
- msi_free( folder->TargetDefault );
- msi_free( folder->SourceLongPath );
- msi_free( folder->SourceShortPath );
- msi_free( folder->ResolvedTarget );
- msi_free( folder->ResolvedSource );
- msi_free( folder );
-}
-
-static void free_extension( MSIEXTENSION *ext )
-{
- struct list *item, *cursor;
-
- LIST_FOR_EACH_SAFE( item, cursor, &ext->verbs )
- {
- MSIVERB *verb = LIST_ENTRY( item, MSIVERB, entry );
-
- list_remove( &verb->entry );
- msi_free( verb->Verb );
- msi_free( verb->Command );
- msi_free( verb->Argument );
- msi_free( verb );
- }
-
- msi_free( ext->Extension );
- msi_free( ext->ProgIDText );
- msi_free( ext );
-}
-
-static void free_assembly( MSIASSEMBLY *assembly )
-{
- msi_free( assembly->feature );
- msi_free( assembly->manifest );
- msi_free( assembly->application );
- msi_free( assembly->display_name );
- if (assembly->tempdir) RemoveDirectoryW( assembly->tempdir );
- msi_free( assembly->tempdir );
- msi_free( assembly );
-}
-
-void msi_free_action_script( MSIPACKAGE *package, UINT script )
-{
- UINT i;
- for (i = 0; i < package->script->ActionCount[script]; i++)
- msi_free( package->script->Actions[script][i] );
-
- msi_free( package->script->Actions[script] );
- package->script->Actions[script] = NULL;
- package->script->ActionCount[script] = 0;
-}
-
-static void free_package_structures( MSIPACKAGE *package )
-{
- INT i;
- struct list *item, *cursor;
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->features )
- {
- MSIFEATURE *feature = LIST_ENTRY( item, MSIFEATURE, entry );
- list_remove( &feature->entry );
- free_feature( feature );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->folders )
- {
- MSIFOLDER *folder = LIST_ENTRY( item, MSIFOLDER, entry );
- list_remove( &folder->entry );
- free_folder( folder );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->components )
- {
- MSICOMPONENT *comp = LIST_ENTRY( item, MSICOMPONENT, entry );
-
- list_remove( &comp->entry );
- msi_free( comp->Component );
- msi_free( comp->ComponentId );
- msi_free( comp->Directory );
- msi_free( comp->Condition );
- msi_free( comp->KeyPath );
- msi_free( comp->FullKeypath );
- if (comp->assembly) free_assembly( comp->assembly );
- msi_free( comp );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->files )
- {
- MSIFILE *file = LIST_ENTRY( item, MSIFILE, entry );
-
- list_remove( &file->entry );
- msi_free( file->File );
- msi_free( file->FileName );
- msi_free( file->ShortName );
- msi_free( file->LongName );
- msi_free( file->Version );
- msi_free( file->Language );
- msi_free( file->TargetPath );
- msi_free( file );
- }
-
- /* clean up extension, progid, class and verb structures */
- LIST_FOR_EACH_SAFE( item, cursor, &package->classes )
- {
- MSICLASS *cls = LIST_ENTRY( item, MSICLASS, entry );
-
- list_remove( &cls->entry );
- msi_free( cls->clsid );
- msi_free( cls->Context );
- msi_free( cls->Description );
- msi_free( cls->FileTypeMask );
- msi_free( cls->IconPath );
- msi_free( cls->DefInprocHandler );
- msi_free( cls->DefInprocHandler32 );
- msi_free( cls->Argument );
- msi_free( cls->ProgIDText );
- msi_free( cls );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->extensions )
- {
- MSIEXTENSION *ext = LIST_ENTRY( item, MSIEXTENSION, entry );
-
- list_remove( &ext->entry );
- free_extension( ext );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->progids )
- {
- MSIPROGID *progid = LIST_ENTRY( item, MSIPROGID, entry );
-
- list_remove( &progid->entry );
- msi_free( progid->ProgID );
- msi_free( progid->Description );
- msi_free( progid->IconPath );
- msi_free( progid );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->mimes )
- {
- MSIMIME *mt = LIST_ENTRY( item, MSIMIME, entry );
-
- list_remove( &mt->entry );
- msi_free( mt->suffix );
- msi_free( mt->clsid );
- msi_free( mt->ContentType );
- msi_free( mt );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->appids )
- {
- MSIAPPID *appid = LIST_ENTRY( item, MSIAPPID, entry );
-
- list_remove( &appid->entry );
- msi_free( appid->AppID );
- msi_free( appid->RemoteServerName );
- msi_free( appid->LocalServer );
- msi_free( appid->ServiceParameters );
- msi_free( appid->DllSurrogate );
- msi_free( appid );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_info )
- {
- MSISOURCELISTINFO *info = LIST_ENTRY( item, MSISOURCELISTINFO, entry );
-
- list_remove( &info->entry );
- msi_free( info->value );
- msi_free( info );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->sourcelist_media )
- {
- MSIMEDIADISK *info = LIST_ENTRY( item, MSIMEDIADISK, entry );
-
- list_remove( &info->entry );
- msi_free( info->volume_label );
- msi_free( info->disk_prompt );
- msi_free( info );
- }
-
- if (package->script)
- {
- for (i = 0; i < SCRIPT_MAX; i++)
- msi_free_action_script( package, i );
-
- for (i = 0; i < package->script->UniqueActionsCount; i++)
- msi_free( package->script->UniqueActions[i] );
-
- msi_free( package->script->UniqueActions );
- msi_free( package->script );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->binaries )
- {
- MSIBINARY *binary = LIST_ENTRY( item, MSIBINARY, entry );
-
- list_remove( &binary->entry );
- if (binary->module)
- FreeLibrary( binary->module );
- if (!DeleteFileW( binary->tmpfile ))
- ERR("failed to delete %s (%u)\n", debugstr_w(binary->tmpfile), GetLastError());
- msi_free( binary->source );
- msi_free( binary->tmpfile );
- msi_free( binary );
- }
-
- LIST_FOR_EACH_SAFE( item, cursor, &package->cabinet_streams )
- {
- MSICABINETSTREAM *cab = LIST_ENTRY( item, MSICABINETSTREAM, entry );
-
- list_remove( &cab->entry );
- IStorage_Release( cab->storage );
- msi_free( cab->stream );
- msi_free( cab );
- }
-
- msi_free( package->BaseURL );
- msi_free( package->PackagePath );
- msi_free( package->ProductCode );
- msi_free( package->ActionFormat );
- msi_free( package->LastAction );
- msi_free( package->langids );
-
- remove_tracked_tempfiles(package);
-}
-
-static void MSI_FreePackage( MSIOBJECTHDR *arg)
-{
- MSIPACKAGE *package = (MSIPACKAGE *)arg;
-
- msiobj_release( &package->db->hdr );
- free_package_structures(package);
- CloseHandle( package->log_file );
-
- if (package->delete_on_close) DeleteFileW( package->localfile );
- msi_free( package->localfile );
-}
-
-typedef struct tagLANGANDCODEPAGE
-{
- WORD wLanguage;
- WORD wCodePage;
-} LANGANDCODEPAGE;
-
-static UINT msi_load_summary_properties( MSIPACKAGE *package )
-{
- UINT rc;
- MSIHANDLE suminfo;
- MSIHANDLE hdb = alloc_msihandle( &package->db->hdr );
- INT count;
- DWORD len;
- LPWSTR package_code;
- static const WCHAR szPackageCode[] = {
- 'P','a','c','k','a','g','e','C','o','d','e',0};
-
- if (!hdb) {
- ERR("Unable to allocate handle\n");
- return ERROR_OUTOFMEMORY;
- }
-
- rc = MsiGetSummaryInformationW( hdb, NULL, 0, &suminfo );
- MsiCloseHandle(hdb);
- if (rc != ERROR_SUCCESS)
- {
- ERR("Unable to open Summary Information\n");
- return rc;
- }
-
- rc = MsiSummaryInfoGetPropertyW( suminfo, PID_PAGECOUNT, NULL,
- &count, NULL, NULL, NULL );
- if (rc != ERROR_SUCCESS)
- {
- WARN("Unable to query page count: %d\n", rc);
- goto done;
- }
-
- /* load package code property */
- len = 0;
- rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL,
- NULL, NULL, NULL, &len );
- if (rc != ERROR_MORE_DATA)
- {
- WARN("Unable to query revision number: %d\n", rc);
- rc = ERROR_FUNCTION_FAILED;
- goto done;
- }
-
- len++;
- package_code = msi_alloc( len * sizeof(WCHAR) );
- rc = MsiSummaryInfoGetPropertyW( suminfo, PID_REVNUMBER, NULL,
- NULL, NULL, package_code, &len );
- if (rc != ERROR_SUCCESS)
- {
- WARN("Unable to query rev number: %d\n", rc);
- goto done;
- }
-
- msi_set_property( package->db, szPackageCode, package_code );
- msi_free( package_code );
-
- /* load package attributes */
- count = 0;
- MsiSummaryInfoGetPropertyW( suminfo, PID_WORDCOUNT, NULL,
- &count, NULL, NULL, NULL );
- package->WordCount = count;
-
-done:
- MsiCloseHandle(suminfo);
- return rc;
-}
-
-static MSIPACKAGE *msi_alloc_package( void )
-{
- MSIPACKAGE *package;
-
- package = alloc_msiobject( MSIHANDLETYPE_PACKAGE, sizeof (MSIPACKAGE),
- MSI_FreePackage );
- if( package )
- {
- list_init( &package->components );
- list_init( &package->features );
- list_init( &package->files );
- list_init( &package->filepatches );
- list_init( &package->tempfiles );
- list_init( &package->folders );
- list_init( &package->subscriptions );
- list_init( &package->appids );
- list_init( &package->classes );
- list_init( &package->mimes );
- list_init( &package->extensions );
- list_init( &package->progids );
- list_init( &package->RunningActions );
- list_init( &package->sourcelist_info );
- list_init( &package->sourcelist_media );
- list_init( &package->binaries );
- list_init( &package->cabinet_streams );
- }
-
- return package;
-}
-
-static UINT msi_load_admin_properties(MSIPACKAGE *package)
-{
-#if 0
- BYTE *data;
- UINT r, sz;
-
- static const WCHAR stmname[] = {'A','d','m','i','n','P','r','o','p','e','r','t','i','e','s',0};
-
- r = read_stream_data(package->db->storage, stmname, FALSE, &data, &sz);
- if (r != ERROR_SUCCESS)
- return r;
-
- r = msi_parse_command_line(package, (WCHAR *)data, TRUE);
-
- msi_free(data);
- return r;
-#endif
-}
-
-MSIPACKAGE *MSI_CreatePackage( MSIDATABASE *db, LPCWSTR base_url )
-{
- static const WCHAR fmtW[] = {'%','u',0};
- MSIPACKAGE *package;
- WCHAR uilevel[11];
- UINT r;
-
- TRACE("%p\n", db);
-
- package = msi_alloc_package();
- if (package)
- {
- msiobj_addref( &db->hdr );
- package->db = db;
-
- package->WordCount = 0;
- package->PackagePath = strdupW( db->path );
- package->BaseURL = strdupW( base_url );
-
- package->ProductCode = msi_dup_property( package->db, szProductCode );
- package->script = msi_alloc_zero( sizeof(MSISCRIPT) );
-
- package->ui_level = gUILevel;
- sprintfW( uilevel, fmtW, gUILevel & INSTALLUILEVEL_MASK );
- msi_set_property(package->db, szUILevel, uilevel);
-
- r = msi_load_summary_properties( package );
- if (r != ERROR_SUCCESS)
- {
- msiobj_release( &package->hdr );
- return NULL;
- }
-
- if (package->WordCount & msidbSumInfoSourceTypeAdminImage)
- msi_load_admin_properties( package );
-
- package->log_file = INVALID_HANDLE_VALUE;
- }
- return package;
-}
-
-UINT msi_create_empty_local_file( LPWSTR path, LPCWSTR suffix )
-{
- static const WCHAR szInstaller[] = {
- '\\','I','n','s','t','a','l','l','e','r','\\',0};
- static const WCHAR fmt[] = {'%','x',0};
- DWORD time, len, i, offset;
- HANDLE handle;
-
- time = GetTickCount();
- GetWindowsDirectoryW( path, MAX_PATH );
- strcatW( path, szInstaller );
- CreateDirectoryW( path, NULL );
-
- len = strlenW(path);
- for (i = 0; i < 0x10000; i++)
- {
- offset = snprintfW( path + len, MAX_PATH - len, fmt, (time + i) & 0xffff );
- memcpy( path + len + offset, suffix, (strlenW( suffix ) + 1) * sizeof(WCHAR) );
- handle = CreateFileW( path, GENERIC_WRITE, 0, NULL,
- CREATE_NEW, FILE_ATTRIBUTE_NORMAL, 0 );
- if (handle != INVALID_HANDLE_VALUE)
- {
- CloseHandle(handle);
- break;
- }
- if (GetLastError() != ERROR_FILE_EXISTS &&
- GetLastError() != ERROR_SHARING_VIOLATION)
- return ERROR_FUNCTION_FAILED;
- }
-
- return ERROR_SUCCESS;
-}
-
-static UINT msi_parse_summary( MSISUMMARYINFO *si, MSIPACKAGE *package )
-{
- WCHAR *template, *p, *q;
- DWORD i, count;
-
- package->version = msi_suminfo_get_int32( si, PID_PAGECOUNT );
- TRACE("version: %d\n", package->version);
-
- template = msi_suminfo_dup_string( si, PID_TEMPLATE );
- if (!template)
- return ERROR_SUCCESS; /* native accepts missing template property */
-
- TRACE("template: %s\n", debugstr_w(template));
-
- p = strchrW( template, ';' );
- if (!p)
- {
- WARN("invalid template string %s\n", debugstr_w(template));
- msi_free( template );
- return ERROR_PATCH_PACKAGE_INVALID;
- }
- *p = 0;
- if ((q = strchrW( template, ',' ))) *q = 0;
- if (!template[0] || !strcmpW( template, szIntel ))
- package->platform = PLATFORM_INTEL;
- else if (!strcmpW( template, szIntel64 ))
- package->platform = PLATFORM_INTEL64;
- else if (!strcmpW( template, szX64 ) || !strcmpW( template, szAMD64 ))
- package->platform = PLATFORM_X64;
- else if (!strcmpW( template, szARM ))
- package->platform = PLATFORM_ARM;
- else
- {
- WARN("unknown platform %s\n", debugstr_w(template));
- msi_free( template );
- return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
- }
- p++;
- if (!*p)
- {
- msi_free( template );
- return ERROR_SUCCESS;
- }
- count = 1;
- for (q = p; (q = strchrW( q, ',' )); q++) count++;
-
- package->langids = msi_alloc( count * sizeof(LANGID) );
- if (!package->langids)
- {
- msi_free( template );
- return ERROR_OUTOFMEMORY;
- }
-
- i = 0;
- while (*p)
- {
- q = strchrW( p, ',' );
- if (q) *q = 0;
- package->langids[i] = atoiW( p );
- if (!q) break;
- p = q + 1;
- i++;
- }
- package->num_langids = i + 1;
-
- msi_free( template );
- return ERROR_SUCCESS;
-}
-
-static UINT validate_package( MSIPACKAGE *package )
-{
- UINT i;
-
- if (package->platform == PLATFORM_INTEL64)
- return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
-#ifndef __arm__
- if (package->platform == PLATFORM_ARM)
- return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
-#endif
- if (package->platform == PLATFORM_X64)
- {
- if (!is_64bit && !is_wow64)
- return ERROR_INSTALL_PLATFORM_UNSUPPORTED;
- if (package->version < 200)
- return ERROR_INSTALL_PACKAGE_INVALID;
- }
- if (!package->num_langids)
- {
- return ERROR_SUCCESS;
- }
- for (i = 0; i < package->num_langids; i++)
- {
- LANGID langid = package->langids[i];
-
- if (PRIMARYLANGID( langid ) == LANG_NEUTRAL)
- {
- langid = MAKELANGID( PRIMARYLANGID( GetSystemDefaultLangID() ), SUBLANGID( langid ) );
- }
- if (SUBLANGID( langid ) == SUBLANG_NEUTRAL)
- {
- langid = MAKELANGID( PRIMARYLANGID( langid ), SUBLANGID( GetSystemDefaultLangID() ) );
- }
- if (IsValidLocale( langid, LCID_INSTALLED ))
- return ERROR_SUCCESS;
- }
- return ERROR_INSTALL_LANGUAGE_UNSUPPORTED;
-}
-
-int msi_track_tempfile( MSIPACKAGE *package, const WCHAR *path )
-{
- MSITEMPFILE *temp;
-
- TRACE("%s\n", debugstr_w(path));
-
- LIST_FOR_EACH_ENTRY( temp, &package->tempfiles, MSITEMPFILE, entry )
- {
- if (!strcmpW( path, temp->Path )) return 0;
- }
- if (!(temp = msi_alloc_zero( sizeof (MSITEMPFILE) ))) return -1;
- list_add_head( &package->tempfiles, &temp->entry );
- temp->Path = strdupW( path );
- return 0;
-}
-
-UINT MSI_OpenPackageW(LPCWSTR szPackage, MSIPACKAGE **pPackage)
-{
- MSIDATABASE *db;
- MSIPACKAGE *package;
- MSIHANDLE handle;
- LPWSTR base_url = NULL;
- UINT r;
- WCHAR localfile[MAX_PATH];
- LPCWSTR file = szPackage;
- MSISUMMARYINFO *si;
- BOOL delete_on_close = FALSE;
-
- TRACE("%s %p\n", debugstr_w(szPackage), pPackage);
-
- localfile[0] = 0;
- if( szPackage[0] == '#' )
- {
- handle = atoiW(&szPackage[1]);
- db = msihandle2msiinfo( handle, MSIHANDLETYPE_DATABASE );
- if( !db )
- return ERROR_INVALID_HANDLE;
- }
- else
- {
- r = MSI_OpenDatabaseW( file, MSIDBOPEN_TRANSACT, &db );
- if (r != ERROR_SUCCESS)
- return r;
- }
- package = MSI_CreatePackage( db, base_url );
- msi_free( base_url );
- msiobj_release( &db->hdr );
- if (!package) return ERROR_INSTALL_PACKAGE_INVALID;
- package->localfile = strdupW( localfile );
- package->delete_on_close = delete_on_close;
-
- si = MSI_GetSummaryInformationW( db->storage, 0 );
- if (!si)
- {
- WARN("failed to load summary info\n");
- msiobj_release( &package->hdr );
- return ERROR_INSTALL_PACKAGE_INVALID;
- }
- r = msi_parse_summary( si, package );
- msiobj_release( &si->hdr );
- if (r != ERROR_SUCCESS)
- {
- WARN("failed to parse summary info %u\n", r);
- msiobj_release( &package->hdr );
- return r;
- }
- r = validate_package( package );
- if (r != ERROR_SUCCESS)
- {
- msiobj_release( &package->hdr );
- return r;
- }
- msi_set_property( package->db, szDatabase, db->path );
-
- if( szPackage[0] == '#' )
- msi_set_property( package->db, szOriginalDatabase, db->path );
- else
- {
- WCHAR fullpath[MAX_PATH];
-
- GetFullPathNameW( szPackage, MAX_PATH, fullpath, NULL );
- msi_set_property( package->db, szOriginalDatabase, fullpath );
- }
-
- if (gszLogFile)
- package->log_file = CreateFileW( gszLogFile, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
- OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
- *pPackage = package;
- return ERROR_SUCCESS;
-}
-
-UINT WINAPI MsiOpenPackageExW(LPCWSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
-{
- MSIPACKAGE *package = NULL;
- UINT ret;
-
- TRACE("%s %08x %p\n", debugstr_w(szPackage), dwOptions, phPackage );
-
- if( !szPackage || !phPackage )
- return ERROR_INVALID_PARAMETER;
-
- if ( !*szPackage )
- {
- FIXME("Should create an empty database and package\n");
- return ERROR_FUNCTION_FAILED;
- }
-
- if( dwOptions )
- FIXME("dwOptions %08x not supported\n", dwOptions);
-
- ret = MSI_OpenPackageW( szPackage, &package );
- if( ret == ERROR_SUCCESS )
- {
- *phPackage = alloc_msihandle( &package->hdr );
- if (! *phPackage)
- ret = ERROR_NOT_ENOUGH_MEMORY;
- msiobj_release( &package->hdr );
- }
-
- return ret;
-}
-
-UINT WINAPI MsiOpenPackageW(LPCWSTR szPackage, MSIHANDLE *phPackage)
-{
- return MsiOpenPackageExW( szPackage, 0, phPackage );
-}
-
-UINT WINAPI MsiOpenPackageExA(LPCSTR szPackage, DWORD dwOptions, MSIHANDLE *phPackage)
-{
- LPWSTR szwPack = NULL;
- UINT ret;
-
- if( szPackage )
- {
- szwPack = strdupAtoW( szPackage );
- if( !szwPack )
- return ERROR_OUTOFMEMORY;
- }
-
- ret = MsiOpenPackageExW( szwPack, dwOptions, phPackage );
-
- msi_free( szwPack );
-
- return ret;
-}
-
-UINT WINAPI MsiOpenPackageA(LPCSTR szPackage, MSIHANDLE *phPackage)
-{
- return MsiOpenPackageExA( szPackage, 0, phPackage );
-}
-
-MSIHANDLE WINAPI MsiGetActiveDatabase(MSIHANDLE hInstall)
-{
- MSIPACKAGE *package;
- MSIHANDLE handle = 0;
-
- TRACE("(%d)\n",hInstall);
-
- package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
- if( package)
- {
- handle = alloc_msihandle( &package->db->hdr );
- msiobj_release( &package->hdr );
- }
-
- return handle;
-}
-
-/* property code */
-
-UINT WINAPI MsiSetPropertyA( MSIHANDLE hInstall, LPCSTR szName, LPCSTR szValue )
-{
- LPWSTR szwName = NULL, szwValue = NULL;
- UINT r = ERROR_OUTOFMEMORY;
-
- szwName = strdupAtoW( szName );
- if( szName && !szwName )
- goto end;
-
- szwValue = strdupAtoW( szValue );
- if( szValue && !szwValue )
- goto end;
-
- r = MsiSetPropertyW( hInstall, szwName, szwValue);
-
-end:
- msi_free( szwName );
- msi_free( szwValue );
-
- return r;
-}
-
-void msi_reset_folders( MSIPACKAGE *package, BOOL source )
-{
- MSIFOLDER *folder;
-
- LIST_FOR_EACH_ENTRY( folder, &package->folders, MSIFOLDER, entry )
- {
- if ( source )
- {
- msi_free( folder->ResolvedSource );
- folder->ResolvedSource = NULL;
- }
- else
- {
- msi_free( folder->ResolvedTarget );
- folder->ResolvedTarget = NULL;
- }
- }
-}
-
-UINT msi_set_property( MSIDATABASE *db, LPCWSTR szName, LPCWSTR szValue )
-{
- static const WCHAR insert_query[] = {
- 'I','N','S','E','R','T',' ','I','N','T','O',' ',
- '`','_','P','r','o','p','e','r','t','y','`',' ',
- '(','`','_','P','r','o','p','e','r','t','y','`',',','`','V','a','l','u','e','`',')',' ',
- 'V','A','L','U','E','S',' ','(','?',',','?',')',0};
- static const WCHAR update_query[] = {
- 'U','P','D','A','T','E',' ','`','_','P','r','o','p','e','r','t','y','`',' ',
- 'S','E','T',' ','`','V','a','l','u','e','`',' ','=',' ','?',' ','W','H','E','R','E',' ',
- '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
- static const WCHAR delete_query[] = {
- 'D','E','L','E','T','E',' ','F','R','O','M',' ',
- '`','_','P','r','o','p','e','r','t','y','`',' ','W','H','E','R','E',' ',
- '`','_','P','r','o','p','e','r','t','y','`',' ','=',' ','\'','%','s','\'',0};
- MSIQUERY *view;
- MSIRECORD *row = NULL;
- DWORD sz = 0;
- WCHAR query[1024];
- UINT rc;
-
- TRACE("%p %s %s\n", db, debugstr_w(szName), debugstr_w(szValue));
-
- if (!szName)
- return ERROR_INVALID_PARAMETER;
-
- /* this one is weird... */
- if (!szName[0])
- return szValue ? ERROR_FUNCTION_FAILED : ERROR_SUCCESS;
-
- rc = msi_get_property(db, szName, 0, &sz);
- if (!szValue || !*szValue)
- {
- sprintfW(query, delete_query, szName);
- }
- else if (rc == ERROR_MORE_DATA || rc == ERROR_SUCCESS)
- {
- sprintfW(query, update_query, szName);
-
- row = MSI_CreateRecord(1);
- MSI_RecordSetStringW(row, 1, szValue);
- }
- else
- {
- strcpyW(query, insert_query);
-
- row = MSI_CreateRecord(2);
- MSI_RecordSetStringW(row, 1, szName);
- MSI_RecordSetStringW(row, 2, szValue);
- }
-
- rc = MSI_DatabaseOpenViewW(db, query, &view);
- if (rc == ERROR_SUCCESS)
- {
- rc = MSI_ViewExecute(view, row);
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- }
- if (row) msiobj_release(&row->hdr);
- return rc;
-}
-
-UINT WINAPI MsiSetPropertyW( MSIHANDLE hInstall, LPCWSTR szName, LPCWSTR szValue)
-{
- MSIPACKAGE *package;
- UINT ret;
-
- package = msihandle2msiinfo( hInstall, MSIHANDLETYPE_PACKAGE);
- if( !package )
- return ERROR_INVALID_HANDLE;
- ret = msi_set_property( package->db, szName, szValue );
- if (ret == ERROR_SUCCESS && !strcmpW( szName, szSourceDir ))
- msi_reset_folders( package, TRUE );
-
- msiobj_release( &package->hdr );
- return ret;
-}
-
-static MSIRECORD *msi_get_property_row( MSIDATABASE *db, LPCWSTR name )
-{
- static const WCHAR query[]= {
- 'S','E','L','E','C','T',' ','`','V','a','l','u','e','`',' ',
- 'F','R','O','M',' ' ,'`','_','P','r','o','p','e','r','t','y','`',' ',
- 'W','H','E','R','E',' ' ,'`','_','P','r','o','p','e','r','t','y','`','=','?',0};
- MSIRECORD *rec, *row = NULL;
- MSIQUERY *view;
- UINT r;
-
- if (!name || !*name)
- return NULL;
-
- rec = MSI_CreateRecord(1);
- if (!rec)
- return NULL;
-
- MSI_RecordSetStringW(rec, 1, name);
-
- r = MSI_DatabaseOpenViewW(db, query, &view);
- if (r == ERROR_SUCCESS)
- {
- MSI_ViewExecute(view, rec);
- MSI_ViewFetch(view, &row);
- MSI_ViewClose(view);
- msiobj_release(&view->hdr);
- }
- msiobj_release(&rec->hdr);
- return row;
-}
-
-/* internal function, not compatible with MsiGetPropertyW */
-UINT msi_get_property( MSIDATABASE *db, LPCWSTR szName,
- LPWSTR szValueBuf, LPDWORD pchValueBuf )
-{
- MSIRECORD *row;
- UINT rc = ERROR_FUNCTION_FAILED;
-
- row = msi_get_property_row( db, szName );
-
- if (*pchValueBuf > 0)
- szValueBuf[0] = 0;
-
- if (row)
- {
- rc = MSI_RecordGetStringW(row, 1, szValueBuf, pchValueBuf);
- msiobj_release(&row->hdr);
- }
-
- if (rc == ERROR_SUCCESS)
- TRACE("returning %s for property %s\n", debugstr_w(szValueBuf),
- debugstr_w(szName));
- else if (rc == ERROR_MORE_DATA)
- TRACE("need %d sized buffer for %s\n", *pchValueBuf,
- debugstr_w(szName));
- else
- {
- *pchValueBuf = 0;
- TRACE("property %s not found\n", debugstr_w(szName));
- }
-
- return rc;
-}
-
-LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop)
-{
- DWORD sz = 0;
- LPWSTR str;
- UINT r;
-
- r = msi_get_property(db, prop, NULL, &sz);
- if (r != ERROR_SUCCESS && r != ERROR_MORE_DATA)
- return NULL;
-
- sz++;
- str = msi_alloc(sz * sizeof(WCHAR));
- r = msi_get_property(db, prop, str, &sz);
- if (r != ERROR_SUCCESS)
- {
- msi_free(str);
- str = NULL;
- }
-
- return str;
-}
-
-int msi_get_property_int( MSIDATABASE *db, LPCWSTR prop, int def )
-{
- LPWSTR str = msi_dup_property( db, prop );
- int val = str ? atoiW(str) : def;
- msi_free(str);
- return val;
-}
-
-static UINT MSI_GetProperty( MSIHANDLE handle, LPCWSTR name,
- awstring *szValueBuf, LPDWORD pchValueBuf )
-{
- MSIPACKAGE *package;
- MSIRECORD *row = NULL;
- UINT r = ERROR_FUNCTION_FAILED;
- LPCWSTR val = NULL;
-
- TRACE("%u %s %p %p\n", handle, debugstr_w(name),
- szValueBuf->str.w, pchValueBuf );
-
- if (!name)
- return ERROR_INVALID_PARAMETER;
-
- package = msihandle2msiinfo( handle, MSIHANDLETYPE_PACKAGE );
- if (!package)
- return ERROR_INVALID_HANDLE;
- row = msi_get_property_row( package->db, name );
- if (row)
- val = MSI_RecordGetString( row, 1 );
-
- if (!val)
- val = szEmpty;
-
- r = msi_strcpy_to_awstring( val, szValueBuf, pchValueBuf );
-
- if (row)
- msiobj_release( &row->hdr );
- msiobj_release( &package->hdr );
-
- return r;
-}
-
-UINT WINAPI MsiGetPropertyA( MSIHANDLE hInstall, LPCSTR szName,
- LPSTR szValueBuf, LPDWORD pchValueBuf )
-{
- awstring val;
- LPWSTR name;
- UINT r;
-
- val.unicode = FALSE;
- val.str.a = szValueBuf;
-
- name = strdupAtoW( szName );
- if (szName && !name)
- return ERROR_OUTOFMEMORY;
-
- r = MSI_GetProperty( hInstall, name, &val, pchValueBuf );
- msi_free( name );
- return r;
-}
-
-UINT WINAPI MsiGetPropertyW( MSIHANDLE hInstall, LPCWSTR szName,
- LPWSTR szValueBuf, LPDWORD pchValueBuf )
-{
- awstring val;
-
- val.unicode = TRUE;
- val.str.w = szValueBuf;
-
- return MSI_GetProperty( hInstall, szName, &val, pchValueBuf );
-}
-
-UINT msi_package_add_info(MSIPACKAGE *package, DWORD context, DWORD options,
- LPCWSTR property, LPWSTR value)
-{
- MSISOURCELISTINFO *info;
-
- LIST_FOR_EACH_ENTRY( info, &package->sourcelist_info, MSISOURCELISTINFO, entry )
- {
- if (!strcmpW( info->value, value )) return ERROR_SUCCESS;
- }
-
- info = msi_alloc(sizeof(MSISOURCELISTINFO));
- if (!info)
- return ERROR_OUTOFMEMORY;
-
- info->context = context;
- info->options = options;
- info->property = property;
- info->value = strdupW(value);
- list_add_head(&package->sourcelist_info, &info->entry);
-
- return ERROR_SUCCESS;
-}
-
-UINT msi_package_add_media_disk(MSIPACKAGE *package, DWORD context, DWORD options,
- DWORD disk_id, LPWSTR volume_label, LPWSTR disk_prompt)
-{
- MSIMEDIADISK *disk;
-
- LIST_FOR_EACH_ENTRY( disk, &package->sourcelist_media, MSIMEDIADISK, entry )
- {
- if (disk->disk_id == disk_id) return ERROR_SUCCESS;
- }
-
- disk = msi_alloc(sizeof(MSIMEDIADISK));
- if (!disk)
- return ERROR_OUTOFMEMORY;
-
- disk->context = context;
- disk->options = options;
- disk->disk_id = disk_id;
- disk->volume_label = strdupW(volume_label);
- disk->disk_prompt = strdupW(disk_prompt);
- list_add_head(&package->sourcelist_media, &disk->entry);
-
- return ERROR_SUCCESS;
-}