ReactOS 0.4.15-dev-7961-gdcf9eb0
media.c File Reference
#include <stdarg.h>
#include "windef.h"
#include "winerror.h"
#include "wine/debug.h"
#include "fdi.h"
#include "msipriv.h"
#include "winuser.h"
#include "winreg.h"
#include "shlwapi.h"
#include "objidl.h"
#include "resource.h"
Include dependency graph for media.c:

Go to the source code of this file.

Classes

struct  package_disk
 

Macros

#define COBJMACROS
 
#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
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msi)
 
static BOOL source_matches_volume (MSIMEDIAINFO *mi, LPCWSTR source_root)
 
static UINT msi_change_media (MSIPACKAGE *package, MSIMEDIAINFO *mi)
 
static MSICABINETSTREAMmsi_get_cabinet_stream (MSIPACKAGE *package, UINT disk_id)
 
static void *CDECL cabinet_alloc (ULONG cb)
 
static void CDECL cabinet_free (void *pv)
 
static INT_PTR CDECL cabinet_open (char *pszFile, int oflag, int pmode)
 
static UINT CDECL cabinet_read (INT_PTR hf, void *pv, UINT cb)
 
static UINT CDECL cabinet_write (INT_PTR hf, void *pv, UINT cb)
 
static int CDECL cabinet_close (INT_PTR hf)
 
static LONG CDECL cabinet_seek (INT_PTR hf, LONG dist, int seektype)
 
static INT_PTR CDECL cabinet_open_stream (char *pszFile, int oflag, int pmode)
 
static UINT CDECL cabinet_read_stream (INT_PTR hf, void *pv, UINT cb)
 
static int CDECL cabinet_close_stream (INT_PTR hf)
 
static LONG CDECL cabinet_seek_stream (INT_PTR hf, LONG dist, int seektype)
 
static UINT msi_media_get_disk_info (MSIPACKAGE *package, MSIMEDIAINFO *mi)
 
static INT_PTR cabinet_partial_file (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
 
static WCHARget_cabinet_filename (MSIMEDIAINFO *mi)
 
static INT_PTR cabinet_next_cabinet (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
 
static INT_PTR cabinet_next_cabinet_stream (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
 
static INT_PTR cabinet_copy_file (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
 
static INT_PTR cabinet_close_file_info (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
 
static INT_PTR CDECL cabinet_notify (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
 
static INT_PTR CDECL cabinet_notify_stream (FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
 
static BOOL extract_cabinet (MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data)
 
static BOOL extract_cabinet_stream (MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data)
 
BOOL msi_cabextract (MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data)
 
void msi_free_media_info (MSIMEDIAINFO *mi)
 
static UINT get_drive_type (const WCHAR *path)
 
static WCHARget_base_url (MSIDATABASE *db)
 
UINT msi_load_media_info (MSIPACKAGE *package, UINT Sequence, MSIMEDIAINFO *mi)
 
static UINT find_published_source (MSIPACKAGE *package, MSIMEDIAINFO *mi)
 
UINT ready_media (MSIPACKAGE *package, BOOL compressed, MSIMEDIAINFO *mi)
 
UINT msi_add_cabinet_stream (MSIPACKAGE *package, UINT disk_id, IStorage *storage, const WCHAR *name)
 

Variables

static struct package_disk package_disk
 

Macro Definition Documentation

◆ _O_ACCMODE

#define _O_ACCMODE   (_O_RDONLY|_O_WRONLY|_O_RDWR)

Definition at line 42 of file media.c.

◆ _O_APPEND

#define _O_APPEND   0x0008

Definition at line 43 of file media.c.

◆ _O_BINARY

#define _O_BINARY   0x8000

Definition at line 53 of file media.c.

◆ _O_CREAT

#define _O_CREAT   0x0100

Definition at line 48 of file media.c.

◆ _O_EXCL

#define _O_EXCL   0x0400

Definition at line 50 of file media.c.

◆ _O_NOINHERIT

#define _O_NOINHERIT   0x0080

Definition at line 47 of file media.c.

◆ _O_RANDOM

#define _O_RANDOM   0x0010

Definition at line 44 of file media.c.

◆ _O_RDONLY

#define _O_RDONLY   0

Definition at line 39 of file media.c.

◆ _O_RDWR

#define _O_RDWR   2

Definition at line 41 of file media.c.

◆ _O_SEQUENTIAL

#define _O_SEQUENTIAL   0x0020

Definition at line 45 of file media.c.

◆ _O_SHORT_LIVED

#define _O_SHORT_LIVED   0x1000

Definition at line 51 of file media.c.

◆ _O_TEMPORARY

#define _O_TEMPORARY   0x0040

Definition at line 46 of file media.c.

◆ _O_TEXT

#define _O_TEXT   0x4000

Definition at line 52 of file media.c.

◆ _O_TRUNC

#define _O_TRUNC   0x0200

Definition at line 49 of file media.c.

◆ _O_WRONLY

#define _O_WRONLY   1

Definition at line 40 of file media.c.

◆ COBJMACROS

#define COBJMACROS

Definition at line 23 of file media.c.

Function Documentation

◆ cabinet_alloc()

static void *CDECL cabinet_alloc ( ULONG  cb)
static

Definition at line 113 of file media.c.

114{
115 return msi_alloc(cb);
116}
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static void * msi_alloc(size_t len) __WINE_ALLOC_SIZE(1)
Definition: msipriv.h:1142

Referenced by extract_cabinet(), and extract_cabinet_stream().

◆ cabinet_close()

static int CDECL cabinet_close ( INT_PTR  hf)
static

Definition at line 176 of file media.c.

177{
178 HANDLE handle = (HANDLE)hf;
179 return CloseHandle(handle) ? 0 : -1;
180}
#define CloseHandle
Definition: compat.h:739
PVOID HANDLE
Definition: typedefs.h:73

Referenced by extract_cabinet().

◆ cabinet_close_file_info()

static INT_PTR cabinet_close_file_info ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 498 of file media.c.

500{
501 MSICABDATA *data = pfdin->pv;
502 FILETIME ft;
503 FILETIME ftLocal;
504 HANDLE handle = (HANDLE)pfdin->hf;
505
506 data->mi->is_continuous = FALSE;
507
508 if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
509 {
511 return -1;
512 }
513 if (!LocalFileTimeToFileTime(&ft, &ftLocal))
514 {
516 return -1;
517 }
518 if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
519 {
521 return -1;
522 }
523
525 data->cb(data->package, data->curfile, MSICABEXTRACT_FILEEXTRACTED, NULL, NULL, data->user);
526
527 msi_free(data->curfile);
528 data->curfile = NULL;
529
530 return 1;
531}
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
BOOL WINAPI SetFileTime(IN HANDLE hFile, CONST FILETIME *lpCreationTime OPTIONAL, CONST FILETIME *lpLastAccessTime OPTIONAL, CONST FILETIME *lpLastWriteTime OPTIONAL)
Definition: fileinfo.c:948
BOOL WINAPI DosDateTimeToFileTime(IN WORD wFatDate, IN WORD wFatTime, OUT LPFILETIME lpFileTime)
Definition: time.c:75
BOOL WINAPI LocalFileTimeToFileTime(IN CONST FILETIME *lpLocalFileTime, OUT LPFILETIME lpFileTime)
Definition: time.c:253
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
if(dx< 0)
Definition: linetemp.h:194
static void msi_free(void *mem)
Definition: msipriv.h:1159
#define MSICABEXTRACT_FILEEXTRACTED
Definition: msipriv.h:1096
USHORT time
Definition: fdi.h:236
void * pv
Definition: fdi.h:231
INT_PTR hf
Definition: fdi.h:233
USHORT date
Definition: fdi.h:235

Referenced by cabinet_notify(), and cabinet_notify_stream().

◆ cabinet_close_stream()

static int CDECL cabinet_close_stream ( INT_PTR  hf)
static

Definition at line 250 of file media.c.

251{
252 IStream *stm = (IStream *)hf;
253 IStream_Release( stm );
254 return 0;
255}

Referenced by extract_cabinet_stream().

◆ cabinet_copy_file()

static INT_PTR cabinet_copy_file ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 413 of file media.c.

415{
416 MSICABDATA *data = pfdin->pv;
417 HANDLE handle = 0;
418 LPWSTR path = NULL;
419 DWORD attrs;
420
421 data->curfile = strdupAtoW(pfdin->psz1);
422 if (!data->cb(data->package, data->curfile, MSICABEXTRACT_BEGINEXTRACT, &path,
423 &attrs, data->user))
424 {
425 /* We're not extracting this file, so free the filename. */
426 msi_free(data->curfile);
427 data->curfile = NULL;
428 goto done;
429 }
430
431 TRACE("extracting %s -> %s\n", debugstr_w(data->curfile), debugstr_w(path));
432
434 if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
435
438 {
440 DWORD attrs2 = msi_get_file_attributes( data->package, path );
441
442 if (attrs2 == INVALID_FILE_ATTRIBUTES)
443 {
444 ERR( "failed to create %s (error %lu)\n", debugstr_w(path), err );
445 goto done;
446 }
447 else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY))
448 {
449 TRACE("removing read-only attribute on %s\n", debugstr_w(path));
452
453 if (handle != INVALID_HANDLE_VALUE) goto done;
454 err = GetLastError();
455 }
457 {
458 WCHAR *tmpfileW, *tmppathW, *p;
459 DWORD len;
460
461 TRACE("file in use, scheduling rename operation\n");
462
463 if (!(tmppathW = strdupW( path ))) return ERROR_OUTOFMEMORY;
464 if ((p = wcsrchr(tmppathW, '\\'))) *p = 0;
465 len = lstrlenW( tmppathW ) + 16;
466 if (!(tmpfileW = msi_alloc(len * sizeof(WCHAR))))
467 {
468 msi_free( tmppathW );
469 return ERROR_OUTOFMEMORY;
470 }
471 if (!GetTempFileNameW(tmppathW, L"msi", 0, tmpfileW)) tmpfileW[0] = 0;
472 msi_free( tmppathW );
473
475
478 msi_move_file( data->package, tmpfileW, path, MOVEFILE_DELAY_UNTIL_REBOOT ))
479 {
480 data->package->need_reboot_at_end = 1;
481 }
482 else
483 {
484 WARN( "failed to schedule rename operation %s (error %lu)\n", debugstr_w(path), GetLastError() );
485 DeleteFileW( tmpfileW );
486 }
487 msi_free(tmpfileW);
488 }
489 else WARN( "failed to create %s (error %lu)\n", debugstr_w(path), err );
490 }
491
492done:
493 msi_free(path);
494
495 return (INT_PTR)handle;
496}
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
static WCHAR * strdupAtoW(const char *str)
Definition: main.c:65
#define wcsrchr
Definition: compat.h:16
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define GENERIC_READ
Definition: compat.h:135
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI DeleteFileW(IN LPCWSTR lpFileName)
Definition: delete.c:39
BOOL msi_set_file_attributes(MSIPACKAGE *package, const WCHAR *filename, DWORD attrs)
Definition: files.c:97
HANDLE msi_create_file(MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: files.c:51
BOOL msi_move_file(MSIPACKAGE *package, const WCHAR *from, const WCHAR *to, DWORD flags)
Definition: files.c:133
DWORD msi_get_file_attributes(MSIPACKAGE *package, const WCHAR *path)
Definition: files.c:106
UINT WINAPI GetTempFileNameW(IN LPCWSTR lpPathName, IN LPCWSTR lpPrefixString, IN UINT uUnique, OUT LPWSTR lpTempFileName)
Definition: filename.c:84
unsigned long DWORD
Definition: ntddk_ex.h:95
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
#define debugstr_w
Definition: kernel32.h:32
#define CREATE_ALWAYS
Definition: disk.h:72
#define MSICABEXTRACT_BEGINEXTRACT
Definition: msipriv.h:1095
#define FILE_ATTRIBUTE_READONLY
Definition: nt_native.h:702
#define FILE_ATTRIBUTE_HIDDEN
Definition: nt_native.h:703
#define FILE_ATTRIBUTE_SYSTEM
Definition: nt_native.h:704
#define GENERIC_WRITE
Definition: nt_native.h:90
#define L(x)
Definition: ntvdm.h:50
#define err(...)
#define TRACE(s)
Definition: solgame.cpp:4
char * psz1
Definition: fdi.h:228
int32_t INT_PTR
Definition: typedefs.h:64
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define MOVEFILE_DELAY_UNTIL_REBOOT
Definition: winbase.h:400
#define ERROR_SHARING_VIOLATION
Definition: winerror.h:135
#define ERROR_USER_MAPPED_FILE
Definition: winerror.h:727
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by cabinet_notify(), and cabinet_notify_stream().

◆ cabinet_free()

static void CDECL cabinet_free ( void pv)
static

Definition at line 118 of file media.c.

119{
120 msi_free(pv);
121}

Referenced by extract_cabinet(), and extract_cabinet_stream().

◆ cabinet_next_cabinet()

static INT_PTR cabinet_next_cabinet ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 313 of file media.c.

315{
316 MSICABDATA *data = pfdin->pv;
317 MSIMEDIAINFO *mi = data->mi;
318 LPWSTR cabinet_file = NULL, cab = strdupAtoW(pfdin->psz1);
319 INT_PTR res = -1;
320 UINT rc;
321
322 msi_free(mi->disk_prompt);
323 msi_free(mi->cabinet);
324 msi_free(mi->volume_label);
325 mi->disk_prompt = NULL;
326 mi->cabinet = NULL;
327 mi->volume_label = NULL;
328
329 mi->disk_id++;
330 mi->is_continuous = TRUE;
331
332 rc = msi_media_get_disk_info(data->package, mi);
333 if (rc != ERROR_SUCCESS)
334 {
335 ERR("Failed to get next cabinet information: %d\n", rc);
336 goto done;
337 }
338
339 if (wcsicmp( mi->cabinet, cab ))
340 {
341 char *next_cab;
343
344 WARN("Continuous cabinet %s does not match the next cabinet %s in the media table => use latter one\n", debugstr_w(cab), debugstr_w(mi->cabinet));
345
346 /* Use cabinet name from the media table */
347 next_cab = strdupWtoA(mi->cabinet);
348 /* Modify path to cabinet file with full filename (psz3 points to a 256 bytes buffer that can be modified contrary to psz1 and psz2) */
349 length = strlen(pfdin->psz3) + 1 + strlen(next_cab) + 1;
350 if (length > 256)
351 {
352 WARN( "cannot update next cabinet filename with a string size %lu > 256\n", length );
353 msi_free(next_cab);
354 goto done;
355 }
356 else
357 {
358 strcat(pfdin->psz3, "\\");
359 strcat(pfdin->psz3, next_cab);
360 }
361 /* Path psz3 and cabinet psz1 are concatenated by FDI so just reset psz1 */
362 *pfdin->psz1 = 0;
363 msi_free(next_cab);
364 }
365
366 if (!(cabinet_file = get_cabinet_filename(mi)))
367 goto done;
368
369 TRACE("Searching for %s\n", debugstr_w(cabinet_file));
370
371 res = 0;
372 if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES)
373 {
374 if (msi_change_media(data->package, mi) != ERROR_SUCCESS)
375 res = -1;
376 }
377
378done:
379 msi_free(cab);
380 msi_free(cabinet_file);
381 return res;
382}
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
#define wcsicmp
Definition: compat.h:15
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
static UINT msi_media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi)
Definition: media.c:274
static WCHAR * get_cabinet_filename(MSIMEDIAINFO *mi)
Definition: media.c:301
static UINT msi_change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
Definition: media.c:79
GLuint res
Definition: glext.h:9613
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
static LPSTR strdupWtoA(LPCWSTR str)
Definition: hhctrl.h:299
unsigned int UINT
Definition: ndis.h:50
char * psz3
Definition: fdi.h:230
uint32_t ULONG
Definition: typedefs.h:59
static MONITORINFO mi
Definition: win.c:7338

Referenced by cabinet_notify().

◆ cabinet_next_cabinet_stream()

static INT_PTR cabinet_next_cabinet_stream ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 384 of file media.c.

386{
387 MSICABDATA *data = pfdin->pv;
388 MSIMEDIAINFO *mi = data->mi;
389 UINT rc;
390
391 msi_free( mi->disk_prompt );
392 msi_free( mi->cabinet );
393 msi_free( mi->volume_label );
394 mi->disk_prompt = NULL;
395 mi->cabinet = NULL;
396 mi->volume_label = NULL;
397
398 mi->disk_id++;
399 mi->is_continuous = TRUE;
400
401 rc = msi_media_get_disk_info( data->package, mi );
402 if (rc != ERROR_SUCCESS)
403 {
404 ERR("Failed to get next cabinet information: %u\n", rc);
405 return -1;
406 }
407 package_disk.id = mi->disk_id;
408
409 TRACE("next cabinet is %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
410 return 0;
411}
UINT id
Definition: media.c:192

Referenced by cabinet_notify_stream().

◆ cabinet_notify()

static INT_PTR CDECL cabinet_notify ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 533 of file media.c.

534{
535 switch (fdint)
536 {
538 return cabinet_partial_file(fdint, pfdin);
539
541 return cabinet_next_cabinet(fdint, pfdin);
542
543 case fdintCOPY_FILE:
544 return cabinet_copy_file(fdint, pfdin);
545
547 return cabinet_close_file_info(fdint, pfdin);
548
549 default:
550 return 0;
551 }
552}
static INT_PTR cabinet_partial_file(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:293
static INT_PTR cabinet_close_file_info(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:498
static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:413
static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:313
@ fdintCOPY_FILE
Definition: fdi.h:249
@ fdintPARTIAL_FILE
Definition: fdi.h:248
@ fdintCLOSE_FILE_INFO
Definition: fdi.h:250
@ fdintNEXT_CABINET
Definition: fdi.h:251

Referenced by extract_cabinet().

◆ cabinet_notify_stream()

static INT_PTR CDECL cabinet_notify_stream ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 554 of file media.c.

555{
556 switch (fdint)
557 {
559 return cabinet_partial_file( fdint, pfdin );
560
562 return cabinet_next_cabinet_stream( fdint, pfdin );
563
564 case fdintCOPY_FILE:
565 return cabinet_copy_file( fdint, pfdin );
566
568 return cabinet_close_file_info( fdint, pfdin );
569
571 return 0;
572
573 default:
574 ERR("Unexpected notification %d\n", fdint);
575 return 0;
576 }
577}
static INT_PTR cabinet_next_cabinet_stream(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:384
@ fdintCABINET_INFO
Definition: fdi.h:247

Referenced by extract_cabinet_stream().

◆ cabinet_open()

static INT_PTR CDECL cabinet_open ( char pszFile,
int  oflag,
int  pmode 
)
static

Definition at line 123 of file media.c.

124{
125 DWORD dwAccess = 0;
126 DWORD dwShareMode = 0;
127 DWORD dwCreateDisposition = OPEN_EXISTING;
128
129 switch (oflag & _O_ACCMODE)
130 {
131 case _O_RDONLY:
132 dwAccess = GENERIC_READ;
133 dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
134 break;
135 case _O_WRONLY:
136 dwAccess = GENERIC_WRITE;
138 break;
139 case _O_RDWR:
140 dwAccess = GENERIC_READ | GENERIC_WRITE;
142 break;
143 }
144
145 if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
146 dwCreateDisposition = CREATE_NEW;
147 else if (oflag & _O_CREAT)
148 dwCreateDisposition = CREATE_ALWAYS;
149
150 return (INT_PTR)CreateFileA(pszFile, dwAccess, dwShareMode, NULL,
151 dwCreateDisposition, 0, NULL);
152}
#define OPEN_EXISTING
Definition: compat.h:775
#define CreateFileA(a, b, c, d, e, f, g)
Definition: compat.h:740
#define FILE_SHARE_READ
Definition: compat.h:136
#define _O_RDWR
Definition: media.c:41
#define _O_ACCMODE
Definition: media.c:42
#define _O_RDONLY
Definition: media.c:39
#define _O_CREAT
Definition: media.c:48
#define _O_EXCL
Definition: media.c:50
#define _O_WRONLY
Definition: media.c:40
#define CREATE_NEW
Definition: disk.h:69
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define FILE_SHARE_DELETE
Definition: nt_native.h:682

Referenced by extract_cabinet().

◆ cabinet_open_stream()

static INT_PTR CDECL cabinet_open_stream ( char pszFile,
int  oflag,
int  pmode 
)
static

Definition at line 197 of file media.c.

198{
199 MSICABINETSTREAM *cab;
201
203 {
204 WARN("failed to get cabinet stream\n");
205 return -1;
206 }
207 if (cab->storage == package_disk.package->db->storage)
208 {
210 if (r != ERROR_SUCCESS)
211 {
212 WARN("failed to get stream %u\n", r);
213 return -1;
214 }
215 }
216 else /* patch storage */
217 {
218 HRESULT hr;
219 WCHAR *encoded;
220
221 if (!(encoded = encode_streamname( FALSE, cab->stream + 1 )))
222 {
223 WARN("failed to encode stream name\n");
224 return -1;
225 }
226 hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream );
227 msi_free( encoded );
228 if (FAILED(hr))
229 {
230 WARN( "failed to open stream %#lx\n", hr );
231 return -1;
232 }
233 }
234 return (INT_PTR)stream;
235}
static MSICABINETSTREAM * msi_get_cabinet_stream(MSIPACKAGE *package, UINT disk_id)
Definition: media.c:102
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define FAILED(hr)
Definition: intsafe.h:51
UINT msi_get_stream(MSIDATABASE *, const WCHAR *, IStream **) DECLSPEC_HIDDEN
Definition: streams.c:499
LPWSTR encode_streamname(BOOL bTable, LPCWSTR in) DECLSPEC_HIDDEN
Definition: table.c:119
#define STGM_SHARE_EXCLUSIVE
Definition: objbase.h:923
#define STGM_READ
Definition: objbase.h:917
HRESULT hr
Definition: shlfolder.c:183
MSIPACKAGE * package
Definition: media.c:191
Definition: parse.h:23
IStorage * storage
Definition: msipriv.h:194
IStorage * storage
Definition: msipriv.h:109
MSIDATABASE * db
Definition: msipriv.h:394

Referenced by extract_cabinet_stream().

◆ cabinet_partial_file()

static INT_PTR cabinet_partial_file ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 293 of file media.c.

295{
296 MSICABDATA *data = pfdin->pv;
297 data->mi->is_continuous = FALSE;
298 return 0;
299}

Referenced by cabinet_notify(), and cabinet_notify_stream().

◆ cabinet_read()

static UINT CDECL cabinet_read ( INT_PTR  hf,
void pv,
UINT  cb 
)
static

Definition at line 154 of file media.c.

155{
156 HANDLE handle = (HANDLE)hf;
157 DWORD read;
158
159 if (ReadFile(handle, pv, cb, &read, NULL))
160 return read;
161
162 return 0;
163}
#define read
Definition: acwin.h:96
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742

Referenced by extract_cabinet().

◆ cabinet_read_stream()

static UINT CDECL cabinet_read_stream ( INT_PTR  hf,
void pv,
UINT  cb 
)
static

Definition at line 237 of file media.c.

238{
239 IStream *stm = (IStream *)hf;
240 DWORD read;
241 HRESULT hr;
242
243 hr = IStream_Read( stm, pv, cb, &read );
244 if (hr == S_OK || hr == S_FALSE)
245 return read;
246
247 return 0;
248}
#define S_OK
Definition: intsafe.h:52
#define S_FALSE
Definition: winerror.h:2357

Referenced by extract_cabinet_stream().

◆ cabinet_seek()

static LONG CDECL cabinet_seek ( INT_PTR  hf,
LONG  dist,
int  seektype 
)
static

Definition at line 182 of file media.c.

183{
184 HANDLE handle = (HANDLE)hf;
185 /* flags are compatible and so are passed straight through */
186 return SetFilePointer(handle, dist, NULL, seektype);
187}
#define SetFilePointer
Definition: compat.h:743

Referenced by extract_cabinet().

◆ cabinet_seek_stream()

static LONG CDECL cabinet_seek_stream ( INT_PTR  hf,
LONG  dist,
int  seektype 
)
static

Definition at line 257 of file media.c.

258{
259 IStream *stm = (IStream *)hf;
260 LARGE_INTEGER move;
261 ULARGE_INTEGER newpos;
262 HRESULT hr;
263
264 move.QuadPart = dist;
265 hr = IStream_Seek( stm, move, seektype, &newpos );
266 if (SUCCEEDED(hr))
267 {
268 if (newpos.QuadPart <= MAXLONG) return newpos.QuadPart;
269 ERR("Too big!\n");
270 }
271 return -1;
272}
#define SUCCEEDED(hr)
Definition: intsafe.h:50
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
#define MAXLONG
Definition: umtypes.h:116
LONGLONG QuadPart
Definition: typedefs.h:114

Referenced by extract_cabinet_stream().

◆ cabinet_write()

static UINT CDECL cabinet_write ( INT_PTR  hf,
void pv,
UINT  cb 
)
static

Definition at line 165 of file media.c.

166{
167 HANDLE handle = (HANDLE)hf;
168 DWORD written;
169
170 if (WriteFile(handle, pv, cb, &written, NULL))
171 return written;
172
173 return 0;
174}
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24

Referenced by extract_cabinet(), and extract_cabinet_stream().

◆ extract_cabinet()

static BOOL extract_cabinet ( MSIPACKAGE package,
MSIMEDIAINFO mi,
LPVOID  data 
)
static

Definition at line 579 of file media.c.

580{
581 LPSTR cabinet, cab_path = NULL;
582 HFDI hfdi;
583 ERF erf;
584 BOOL ret = FALSE;
585
586 TRACE("extracting %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
587
590 if (!hfdi)
591 {
592 ERR("FDICreate failed\n");
593 return FALSE;
594 }
595
596 cabinet = strdupWtoA( mi->cabinet );
597 if (!cabinet)
598 goto done;
599
600 cab_path = strdupWtoA( mi->sourcedir );
601 if (!cab_path)
602 goto done;
603
604 ret = FDICopy( hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data );
605 if (!ret)
606 ERR("FDICopy failed\n");
607
608done:
609 FDIDestroy( hfdi );
611 msi_free( cab_path );
612
613 if (ret)
614 mi->is_extracted = TRUE;
615
616 return ret;
617}
HFDI __cdecl FDICreate(PFNALLOC pfnalloc, PFNFREE pfnfree, PFNOPEN pfnopen, PFNREAD pfnread, PFNWRITE pfnwrite, PFNCLOSE pfnclose, PFNSEEK pfnseek, int cpuType, PERF perf)
Definition: fdi.c:412
BOOL __cdecl FDICopy(HFDI hfdi, char *pszCabinet, char *pszCabPath, int flags, PFNFDINOTIFY pfnfdin, PFNFDIDECRYPT pfnfdid, void *pvUser)
Definition: fdi.c:2431
BOOL __cdecl FDIDestroy(HFDI hfdi)
Definition: fdi.c:2831
static UINT CDECL cabinet_read(INT_PTR hf, void *pv, UINT cb)
Definition: media.c:154
static void CDECL cabinet_free(void *pv)
Definition: media.c:118
static INT_PTR CDECL cabinet_open(char *pszFile, int oflag, int pmode)
Definition: media.c:123
static void *CDECL cabinet_alloc(ULONG cb)
Definition: media.c:113
static int CDECL cabinet_close(INT_PTR hf)
Definition: media.c:176
static LONG CDECL cabinet_seek(INT_PTR hf, LONG dist, int seektype)
Definition: media.c:182
static UINT CDECL cabinet_write(INT_PTR hf, void *pv, UINT cb)
Definition: media.c:165
static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:533
unsigned int BOOL
Definition: ntddk_ex.h:94
double __cdecl erf(double)
Definition: fci.h:44
int ret
char * LPSTR
Definition: xmlstorage.h:182

Referenced by msi_cabextract().

◆ extract_cabinet_stream()

static BOOL extract_cabinet_stream ( MSIPACKAGE package,
MSIMEDIAINFO mi,
LPVOID  data 
)
static

Definition at line 619 of file media.c.

620{
621 static char filename[] = {'<','S','T','R','E','A','M','>',0};
622 HFDI hfdi;
623 ERF erf;
624 BOOL ret = FALSE;
625
626 TRACE("extracting %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
627
630 if (!hfdi)
631 {
632 ERR("FDICreate failed\n");
633 return FALSE;
634 }
635
636 package_disk.package = package;
637 package_disk.id = mi->disk_id;
638
640 if (!ret) ERR("FDICopy failed\n");
641
642 FDIDestroy( hfdi );
643 if (ret) mi->is_extracted = TRUE;
644 return ret;
645}
static int CDECL cabinet_close_stream(INT_PTR hf)
Definition: media.c:250
static INT_PTR CDECL cabinet_notify_stream(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:554
static INT_PTR CDECL cabinet_open_stream(char *pszFile, int oflag, int pmode)
Definition: media.c:197
static LONG CDECL cabinet_seek_stream(INT_PTR hf, LONG dist, int seektype)
Definition: media.c:257
static UINT CDECL cabinet_read_stream(INT_PTR hf, void *pv, UINT cb)
Definition: media.c:237
const char * filename
Definition: ioapi.h:137

Referenced by msi_cabextract().

◆ find_published_source()

static UINT find_published_source ( MSIPACKAGE package,
MSIMEDIAINFO mi 
)
static

Definition at line 754 of file media.c.

755{
758 WCHAR prompt[MAX_PATH];
759 DWORD volumesz, promptsz;
760 DWORD index, size, id;
761 WCHAR last_type[2];
762 UINT r;
763
764 size = 2;
766 package->Context, MSICODE_PRODUCT,
768 if (r != ERROR_SUCCESS)
769 return r;
770
771 size = MAX_PATH;
773 package->Context, MSICODE_PRODUCT,
775 if (r != ERROR_SUCCESS)
776 return r;
777
778 if (last_type[0] == 'n')
779 {
780 WCHAR cabinet_file[MAX_PATH];
781 BOOL check_all = FALSE;
782
783 while(TRUE)
784 {
785 index = 0;
786 volumesz = MAX_PATH;
788 package->Context,
790 volume, &volumesz) == ERROR_SUCCESS)
791 {
792 if (check_all || !wcsnicmp(source, volume, lstrlenW(source)))
793 {
794 lstrcpyW(cabinet_file, volume);
795 PathAddBackslashW(cabinet_file);
796 lstrcatW(cabinet_file, mi->cabinet);
797
798 if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES)
799 {
800 volumesz = MAX_PATH;
801 if(!check_all)
802 break;
803 continue;
804 }
805
806 lstrcpyW(mi->sourcedir, volume);
807 PathAddBackslashW(mi->sourcedir);
808 TRACE("Found network source %s\n", debugstr_w(mi->sourcedir));
809 return ERROR_SUCCESS;
810 }
811 }
812
813 if (!check_all)
814 check_all = TRUE;
815 else
816 break;
817 }
818 }
819
820 index = 0;
821 volumesz = MAX_PATH;
822 promptsz = MAX_PATH;
824 package->Context,
825 MSICODE_PRODUCT, index++, &id,
826 volume, &volumesz, prompt, &promptsz) == ERROR_SUCCESS)
827 {
828 mi->disk_id = id;
829 msi_free( mi->volume_label );
830 if (!(mi->volume_label = msi_alloc( ++volumesz * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
831 lstrcpyW( mi->volume_label, volume );
832
833 msi_free( mi->disk_prompt );
834 if (!(mi->disk_prompt = msi_alloc( ++promptsz * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
835 lstrcpyW( mi->disk_prompt, prompt );
836
838 {
839 /* FIXME: what about SourceDir */
840 lstrcpyW(mi->sourcedir, source);
841 PathAddBackslashW(mi->sourcedir);
842 TRACE("Found disk source %s\n", debugstr_w(mi->sourcedir));
843 return ERROR_SUCCESS;
844 }
845 }
846
848}
#define index(s, c)
Definition: various.h:29
#define wcsnicmp
Definition: compat.h:14
#define MAX_PATH
Definition: compat.h:34
#define lstrcpyW
Definition: compat.h:749
static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
Definition: media.c:55
UINT WINAPI MsiSourceListEnumMediaDisksW(const WCHAR *szProductCodeOrPatchCode, const WCHAR *szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwIndex, DWORD *pdwDiskId, WCHAR *szVolumeLabel, DWORD *pcchVolumeLabel, WCHAR *szDiskPrompt, DWORD *pcchDiskPrompt)
Definition: source.c:198
UINT WINAPI MsiSourceListGetInfoW(LPCWSTR szProduct, LPCWSTR szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, LPCWSTR szProperty, LPWSTR szValue, LPDWORD pcchValue)
Definition: source.c:523
UINT WINAPI MsiSourceListEnumSourcesW(const WCHAR *szProductCodeOrPatch, const WCHAR *szUserSid, MSIINSTALLCONTEXT dwContext, DWORD dwOptions, DWORD dwIndex, WCHAR *szSource, DWORD *pcchSource)
Definition: source.c:398
GLsizeiptr size
Definition: glext.h:5919
GLuint index
Definition: glext.h:6031
GLuint id
Definition: glext.h:5910
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274
static const WCHAR INSTALLPROPERTY_LASTUSEDTYPEW[]
Definition: msi.h:409
@ MSICODE_PRODUCT
Definition: msi.h:215
@ MSISOURCETYPE_NETWORK
Definition: msi.h:208
static const WCHAR INSTALLPROPERTY_LASTUSEDSOURCEW[]
Definition: msi.h:405
#define PathAddBackslashW
Definition: pathcch.h:301
LPWSTR ProductCode
Definition: msipriv.h:448
UINT Context
Definition: msipriv.h:459
#define ERROR_FUNCTION_FAILED
Definition: winerror.h:985

Referenced by ready_media().

◆ get_base_url()

static WCHAR * get_base_url ( MSIDATABASE db)
static

Definition at line 681 of file media.c.

682{
683 WCHAR *p, *ret = NULL, *orig_db = msi_dup_property( db, L"OriginalDatabase" );
684 if (UrlIsW( orig_db, URLIS_URL ) && (ret = strdupW( orig_db )) && (p = wcsrchr( ret, '/'))) p[1] = 0;
685 msi_free( orig_db );
686 return ret;
687}
BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
Definition: url.c:1933
LPWSTR msi_dup_property(MSIDATABASE *db, LPCWSTR prop) DECLSPEC_HIDDEN
Definition: package.c:2283
@ URLIS_URL
Definition: shlwapi.h:1191

Referenced by msi_load_media_info(), and ready_media().

◆ get_cabinet_filename()

static WCHAR * get_cabinet_filename ( MSIMEDIAINFO mi)
static

Definition at line 301 of file media.c.

302{
303 int len;
304 WCHAR *ret;
305
306 len = lstrlenW(mi->sourcedir) + lstrlenW(mi->cabinet) + 1;
307 if (!(ret = msi_alloc(len * sizeof(WCHAR)))) return NULL;
308 lstrcpyW(ret, mi->sourcedir);
309 lstrcatW(ret, mi->cabinet);
310 return ret;
311}

Referenced by cabinet_next_cabinet(), and ready_media().

◆ get_drive_type()

static UINT get_drive_type ( const WCHAR path)
static

Definition at line 670 of file media.c.

671{
672 WCHAR root[MAX_PATH + 1];
673
677
678 return GetDriveTypeW(root);
679}
UINT WINAPI GetDriveTypeW(IN LPCWSTR lpRootPathName)
Definition: disk.c:497
BOOL WINAPI PathStripToRootW(LPWSTR lpszPath)
Definition: path.c:733

Referenced by msi_load_media_info().

◆ msi_add_cabinet_stream()

UINT msi_add_cabinet_stream ( MSIPACKAGE package,
UINT  disk_id,
IStorage storage,
const WCHAR name 
)

Definition at line 935 of file media.c.

936{
937 MSICABINETSTREAM *cab, *item;
938
939 TRACE("%p, %u, %p, %s\n", package, disk_id, storage, debugstr_w(name));
940
942 {
943 if (item->disk_id == disk_id)
944 {
945 TRACE("duplicate disk id %u\n", disk_id);
947 }
948 }
949 if (!(cab = msi_alloc( sizeof(*cab) ))) return ERROR_OUTOFMEMORY;
950 if (!(cab->stream = msi_alloc( (lstrlenW( name ) + 1) * sizeof(WCHAR ) )))
951 {
952 msi_free( cab );
953 return ERROR_OUTOFMEMORY;
954 }
955 lstrcpyW( cab->stream, name );
956 cab->disk_id = disk_id;
957 cab->storage = storage;
958 IStorage_AddRef( storage );
959 list_add_tail( &package->cabinet_streams, &cab->entry );
960
961 return ERROR_SUCCESS;
962}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
uint32_t entry
Definition: isohybrid.c:63
static ATOM item
Definition: dde.c:856
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
Definition: name.c:39
struct list entry
Definition: msipriv.h:192
struct list cabinet_streams
Definition: msipriv.h:408

Referenced by load_media(), and patch_add_media().

◆ msi_cabextract()

BOOL msi_cabextract ( MSIPACKAGE package,
MSIMEDIAINFO mi,
LPVOID  data 
)

Definition at line 652 of file media.c.

653{
654 if (mi->cabinet[0] == '#')
655 {
656 return extract_cabinet_stream( package, mi, data );
657 }
658 return extract_cabinet( package, mi, data );
659}
static BOOL extract_cabinet(MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data)
Definition: media.c:579
static BOOL extract_cabinet_stream(MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data)
Definition: media.c:619

Referenced by ACTION_InstallFiles(), and ACTION_PatchFiles().

◆ msi_change_media()

static UINT msi_change_media ( MSIPACKAGE package,
MSIMEDIAINFO mi 
)
static

Definition at line 79 of file media.c.

80{
82 LPWSTR source_dir;
83 UINT r = IDRETRY;
84
85 source_dir = msi_dup_property(package->db, L"SourceDir");
87
88 while (r == IDRETRY && !source_matches_volume(mi, source_dir))
89 {
92 MSI_RecordSetStringW(record, 2, mi->disk_prompt);
94 }
95
97 msi_free(source_dir);
98
100}
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
#define MSIERR_CABNOTFOUND
Definition: resource.h:31
@ INSTALLMESSAGE_ERROR
Definition: msi.h:95
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int) DECLSPEC_HIDDEN
Definition: record.c:280
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *) DECLSPEC_HIDDEN
Definition: package.c:1914
MSIRECORD * MSI_CreateRecord(UINT) DECLSPEC_HIDDEN
Definition: record.c:76
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR) DECLSPEC_HIDDEN
Definition: record.c:597
#define ERROR_INSTALL_SOURCE_ABSENT
Definition: winerror.h:970
#define MB_RETRYCANCEL
Definition: winuser.h:805
#define IDRETRY
Definition: winuser.h:833

Referenced by cabinet_next_cabinet(), and ready_media().

◆ msi_free_media_info()

void msi_free_media_info ( MSIMEDIAINFO mi)

Definition at line 661 of file media.c.

662{
663 msi_free(mi->disk_prompt);
664 msi_free(mi->cabinet);
665 msi_free(mi->volume_label);
666 msi_free(mi->last_volume);
667 msi_free(mi);
668}

Referenced by ACTION_InstallFiles(), and ACTION_PatchFiles().

◆ msi_get_cabinet_stream()

static MSICABINETSTREAM * msi_get_cabinet_stream ( MSIPACKAGE package,
UINT  disk_id 
)
static

Definition at line 102 of file media.c.

103{
104 MSICABINETSTREAM *cab;
105
107 {
108 if (cab->disk_id == disk_id) return cab;
109 }
110 return NULL;
111}

Referenced by cabinet_open_stream().

◆ msi_load_media_info()

UINT msi_load_media_info ( MSIPACKAGE package,
UINT  Sequence,
MSIMEDIAINFO mi 
)

Definition at line 689 of file media.c.

690{
691 MSIRECORD *row;
692 WCHAR *source_dir, *source, *base_url = NULL;
694
695 if (Sequence <= mi->last_sequence) /* already loaded */
696 return ERROR_SUCCESS;
697
698 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `LastSequence` >= %d ORDER BY `DiskId`", Sequence);
699 if (!row)
700 {
701 TRACE("Unable to query row\n");
703 }
704
705 mi->is_extracted = FALSE;
706 mi->disk_id = MSI_RecordGetInteger(row, 1);
707 mi->last_sequence = MSI_RecordGetInteger(row, 2);
708 msi_free(mi->disk_prompt);
709 mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
710 msi_free(mi->cabinet);
711 mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
712 msi_free(mi->volume_label);
713 mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
714 msiobj_release(&row->hdr);
715
717 source_dir = msi_dup_property(package->db, L"SourceDir");
718 lstrcpyW(mi->sourcedir, source_dir);
719 PathAddBackslashW(mi->sourcedir);
720 mi->type = get_drive_type(source_dir);
721
723 if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE)
724 {
725 source = source_dir;
727 }
728 else if ((base_url = get_base_url(package->db)))
729 {
732 }
733 else
734 {
735 source = mi->sourcedir;
737 }
738
739 msi_package_add_media_disk(package, package->Context,
740 MSICODE_PRODUCT, mi->disk_id,
741 mi->volume_label, mi->disk_prompt);
742
743 msi_package_add_info(package, package->Context,
745
746 TRACE("sequence %u -> cabinet %s disk id %u\n", Sequence, debugstr_w(mi->cabinet), mi->disk_id);
747
749 msi_free(source_dir);
750 return ERROR_SUCCESS;
751}
UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
Definition: action.c:354
static WCHAR * get_base_url(MSIDATABASE *db)
Definition: media.c:681
static UINT get_drive_type(const WCHAR *path)
Definition: media.c:670
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define DRIVE_CDROM
Definition: machpc98.h:119
const char * base_url
Definition: mimeole.c:1466
@ MSISOURCETYPE_URL
Definition: msi.h:209
@ MSISOURCETYPE_MEDIA
Definition: msi.h:210
UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR) DECLSPEC_HIDDEN
Definition: package.c:2625
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...) DECLSPEC_HIDDEN
Definition: msiquery.c:201
int MSI_RecordGetInteger(MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:213
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT) DECLSPEC_HIDDEN
Definition: record.c:433
UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR) DECLSPEC_HIDDEN
Definition: package.c:2648
#define DRIVE_REMOVABLE
Definition: winbase.h:251

Referenced by ACTION_InstallFiles(), and ACTION_PatchFiles().

◆ msi_media_get_disk_info()

static UINT msi_media_get_disk_info ( MSIPACKAGE package,
MSIMEDIAINFO mi 
)
static

Definition at line 274 of file media.c.

275{
276 MSIRECORD *row;
277
278 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `DiskId` = %d", mi->disk_id);
279 if (!row)
280 {
281 TRACE("Unable to query row\n");
283 }
284
285 mi->disk_prompt = strdupW(MSI_RecordGetString(row, 3));
286 mi->cabinet = strdupW(MSI_RecordGetString(row, 4));
287 mi->volume_label = strdupW(MSI_RecordGetString(row, 5));
288
289 msiobj_release(&row->hdr);
290 return ERROR_SUCCESS;
291}

Referenced by cabinet_next_cabinet(), and cabinet_next_cabinet_stream().

◆ ready_media()

UINT ready_media ( MSIPACKAGE package,
BOOL  compressed,
MSIMEDIAINFO mi 
)

Definition at line 850 of file media.c.

851{
852 UINT rc;
853 WCHAR *cabinet_file = NULL;
854
855 /* media info for continuous cabinet is already loaded */
856 if (mi->is_continuous) return ERROR_SUCCESS;
857
858 if (mi->cabinet)
859 {
861
862 /* cabinet is internal, no checks needed */
863 if (mi->cabinet[0] == '#') return ERROR_SUCCESS;
864
865 if (!(cabinet_file = get_cabinet_filename( mi ))) return ERROR_OUTOFMEMORY;
866
867 /* package should be downloaded */
868 if (compressed && GetFileAttributesW( cabinet_file ) == INVALID_FILE_ATTRIBUTES &&
869 (base_url = get_base_url( package->db )))
870 {
871 WCHAR temppath[MAX_PATH], *p, *url;
872
873 msi_free( cabinet_file );
874 if (!(url = msi_alloc( (lstrlenW( base_url ) + lstrlenW( mi->cabinet ) + 1) * sizeof(WCHAR) )))
875 {
876 return ERROR_OUTOFMEMORY;
877 }
879 lstrcatW( url, mi->cabinet );
880 if ((rc = msi_download_file( url, temppath )) != ERROR_SUCCESS)
881 {
882 ERR("failed to download %s (%u)\n", debugstr_w(url), rc);
883 msi_free( url );
884 return rc;
885 }
886 if ((p = wcsrchr( temppath, '\\' ))) *p = 0;
887 lstrcpyW( mi->sourcedir, temppath );
888 PathAddBackslashW( mi->sourcedir );
889 msi_free( mi->cabinet );
890 mi->cabinet = strdupW( p + 1 );
891
892 msi_free( url );
893 return ERROR_SUCCESS;
894 }
895 }
896 /* check volume matches, change media if not */
897 if (mi->volume_label)
898 {
899 /* assume first volume is in the drive */
900 if (mi->last_volume && wcsicmp( mi->last_volume, mi->volume_label ))
901 {
902 WCHAR *source = msi_dup_property( package->db, L"SourceDir" );
904 msi_free( source );
905
906 if (!match && (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE))
907 {
908 if ((rc = msi_change_media( package, mi )) != ERROR_SUCCESS)
909 {
910 msi_free( cabinet_file );
911 return rc;
912 }
913 }
914 }
915
916 msi_free(mi->last_volume);
917 mi->last_volume = strdupW(mi->volume_label);
918 }
919 if (mi->cabinet)
920 {
921 if (compressed && GetFileAttributesW( cabinet_file ) == INVALID_FILE_ATTRIBUTES)
922 {
923 if ((rc = find_published_source( package, mi )) != ERROR_SUCCESS)
924 {
925 ERR("cabinet not found: %s\n", debugstr_w(cabinet_file));
926 msi_free( cabinet_file );
928 }
929 }
930 }
931 msi_free( cabinet_file );
932 return ERROR_SUCCESS;
933}
static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi)
Definition: media.c:754
static const WCHAR url[]
Definition: encode.c:1432
UINT msi_download_file(LPCWSTR szUrl, LPWSTR filename) DECLSPEC_HIDDEN
Definition: package.c:1027
Definition: match.c:28
#define ERROR_INSTALL_FAILURE
Definition: winerror.h:961

Referenced by ACTION_InstallFiles(), and ACTION_PatchFiles().

◆ source_matches_volume()

static BOOL source_matches_volume ( MSIMEDIAINFO mi,
LPCWSTR  source_root 
)
static

Definition at line 55 of file media.c.

56{
58 const WCHAR *p;
59 int len, len2;
60
61 lstrcpyW(root, source_root);
64
66 {
67 WARN( "failed to get volume information for %s (%lu)\n", debugstr_w(root), GetLastError() );
68 return FALSE;
69 }
70
72 len2 = lstrlenW( mi->volume_label );
73 if (len2 > len) return FALSE;
74 p = volume_name + len - len2;
75
76 return !wcsicmp( mi->volume_label, p );
77}
BOOL WINAPI GetVolumeInformationW(IN LPCWSTR lpRootPathName, IN LPWSTR lpVolumeNameBuffer, IN DWORD nVolumeNameSize, OUT LPDWORD lpVolumeSerialNumber OPTIONAL, OUT LPDWORD lpMaximumComponentLength OPTIONAL, OUT LPDWORD lpFileSystemFlags OPTIONAL, OUT LPWSTR lpFileSystemNameBuffer OPTIONAL, IN DWORD nFileSystemNameSize)
Definition: volume.c:226
static char volume_name[]
Definition: mkdosfs.c:526

Referenced by find_published_source(), msi_change_media(), and ready_media().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msi  )

Variable Documentation

◆ package_disk

Definition at line 195 of file media.c.