ReactOS 0.4.16-dev-188-g678aa63
media.c File Reference
#include <fcntl.h>
#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
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (msi)
 
static BOOL source_matches_volume (MSIMEDIAINFO *mi, LPCWSTR source_root)
 
static UINT change_media (MSIPACKAGE *package, MSIMEDIAINFO *mi)
 
static MSICABINETSTREAMget_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 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

◆ COBJMACROS

#define COBJMACROS

Definition at line 24 of file media.c.

Function Documentation

◆ cabinet_alloc()

static void *CDECL cabinet_alloc ( ULONG  cb)
static

Definition at line 97 of file media.c.

98{
99 return malloc(cb);
100}
#define malloc
Definition: debug_ros.c:4
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33

Referenced by extract_cabinet(), and extract_cabinet_stream().

◆ cabinet_close()

static int CDECL cabinet_close ( INT_PTR  hf)
static

Definition at line 164 of file media.c.

165{
166 HANDLE handle = (HANDLE)hf;
167 return CloseHandle(handle) ? 0 : -1;
168}
#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 486 of file media.c.

488{
489 MSICABDATA *data = pfdin->pv;
490 FILETIME ft;
491 FILETIME ftLocal;
492 HANDLE handle = (HANDLE)pfdin->hf;
493
494 data->mi->is_continuous = FALSE;
495
496 if (!DosDateTimeToFileTime(pfdin->date, pfdin->time, &ft))
497 {
499 return -1;
500 }
501 if (!LocalFileTimeToFileTime(&ft, &ftLocal))
502 {
504 return -1;
505 }
506 if (!SetFileTime(handle, &ftLocal, 0, &ftLocal))
507 {
509 return -1;
510 }
511
513 data->cb(data->package, data->curfile, MSICABEXTRACT_FILEEXTRACTED, NULL, NULL, data->user);
514
515 free(data->curfile);
516 data->curfile = NULL;
517
518 return 1;
519}
#define free
Definition: debug_ros.c:5
#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
#define MSICABEXTRACT_FILEEXTRACTED
Definition: msipriv.h:1102
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 238 of file media.c.

239{
240 IStream *stm = (IStream *)hf;
241 IStream_Release( stm );
242 return 0;
243}

Referenced by extract_cabinet_stream().

◆ cabinet_copy_file()

static INT_PTR cabinet_copy_file ( FDINOTIFICATIONTYPE  fdint,
PFDINOTIFICATION  pfdin 
)
static

Definition at line 401 of file media.c.

403{
404 MSICABDATA *data = pfdin->pv;
405 HANDLE handle = 0;
406 LPWSTR path = NULL;
407 DWORD attrs;
408
409 data->curfile = strdupAtoW(pfdin->psz1);
410 if (!data->cb(data->package, data->curfile, MSICABEXTRACT_BEGINEXTRACT, &path,
411 &attrs, data->user))
412 {
413 /* We're not extracting this file, so free the filename. */
414 free(data->curfile);
415 data->curfile = NULL;
416 goto done;
417 }
418
419 TRACE("extracting %s -> %s\n", debugstr_w(data->curfile), debugstr_w(path));
420
422 if (!attrs) attrs = FILE_ATTRIBUTE_NORMAL;
423
426 {
428 DWORD attrs2 = msi_get_file_attributes( data->package, path );
429
430 if (attrs2 == INVALID_FILE_ATTRIBUTES)
431 {
432 ERR( "failed to create %s (error %lu)\n", debugstr_w(path), err );
433 goto done;
434 }
435 else if (err == ERROR_ACCESS_DENIED && (attrs2 & FILE_ATTRIBUTE_READONLY))
436 {
437 TRACE("removing read-only attribute on %s\n", debugstr_w(path));
440
441 if (handle != INVALID_HANDLE_VALUE) goto done;
442 err = GetLastError();
443 }
445 {
446 WCHAR *tmpfileW, *tmppathW, *p;
447 DWORD len;
448
449 TRACE("file in use, scheduling rename operation\n");
450
451 if (!(tmppathW = wcsdup(path))) return ERROR_OUTOFMEMORY;
452 if ((p = wcsrchr(tmppathW, '\\'))) *p = 0;
453 len = lstrlenW( tmppathW ) + 16;
454 if (!(tmpfileW = malloc(len * sizeof(WCHAR))))
455 {
456 free( tmppathW );
457 return ERROR_OUTOFMEMORY;
458 }
459 if (!msi_get_temp_file_name( data->package, tmppathW, L"msi", tmpfileW )) tmpfileW[0] = 0;
460 free( tmppathW );
461
462 handle = msi_create_file( data->package, tmpfileW, GENERIC_READ | GENERIC_WRITE, 0, CREATE_ALWAYS, attrs );
463
466 msi_move_file( data->package, tmpfileW, path, MOVEFILE_DELAY_UNTIL_REBOOT ))
467 {
468 data->package->need_reboot_at_end = 1;
469 }
470 else
471 {
472 WARN( "failed to schedule rename operation %s (error %lu)\n", debugstr_w(path), GetLastError() );
473 msi_delete_file( data->package, tmpfileW );
474 }
475 free(tmpfileW);
476 }
477 else WARN( "failed to create %s (error %lu)\n", debugstr_w(path), err );
478 }
479
480done:
481 free(path);
482
483 return (INT_PTR)handle;
484}
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#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 FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define lstrlenW
Definition: compat.h:750
BOOL msi_set_file_attributes(MSIPACKAGE *package, const WCHAR *filename, DWORD attrs)
Definition: files.c:106
HANDLE msi_create_file(MSIPACKAGE *package, const WCHAR *filename, DWORD access, DWORD sharing, DWORD creation, DWORD flags)
Definition: files.c:60
BOOL msi_delete_file(MSIPACKAGE *package, const WCHAR *filename)
Definition: files.c:79
BOOL msi_move_file(MSIPACKAGE *package, const WCHAR *from, const WCHAR *to, DWORD flags)
Definition: files.c:142
DWORD msi_get_file_attributes(MSIPACKAGE *package, const WCHAR *path)
Definition: files.c:115
BOOL msi_get_temp_file_name(MSIPACKAGE *package, const WCHAR *tmp_path, const WCHAR *prefix, WCHAR *tmp_filename)
Definition: files.c:51
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:1101
#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(...)
_Check_return_ _CRTIMP wchar_t *__cdecl wcsdup(_In_z_ const wchar_t *_Str)
#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 102 of file media.c.

103{
104 free(pv);
105}

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 301 of file media.c.

303{
304 MSICABDATA *data = pfdin->pv;
305 MSIMEDIAINFO *mi = data->mi;
306 LPWSTR cabinet_file = NULL, cab = strdupAtoW(pfdin->psz1);
307 INT_PTR res = -1;
308 UINT rc;
309
310 free(mi->disk_prompt);
311 free(mi->cabinet);
312 free(mi->volume_label);
313 mi->disk_prompt = NULL;
314 mi->cabinet = NULL;
315 mi->volume_label = NULL;
316
317 mi->disk_id++;
318 mi->is_continuous = TRUE;
319
320 rc = media_get_disk_info(data->package, mi);
321 if (rc != ERROR_SUCCESS)
322 {
323 ERR("Failed to get next cabinet information: %d\n", rc);
324 goto done;
325 }
326
327 if (wcsicmp( mi->cabinet, cab ))
328 {
329 char *next_cab;
331
332 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));
333
334 /* Use cabinet name from the media table */
335 next_cab = strdupWtoA(mi->cabinet);
336 /* Modify path to cabinet file with full filename (psz3 points to a 256 bytes buffer that can be modified contrary to psz1 and psz2) */
337 length = strlen(pfdin->psz3) + 1 + strlen(next_cab) + 1;
338 if (length > 256)
339 {
340 WARN( "cannot update next cabinet filename with a string size %lu > 256\n", length );
341 free(next_cab);
342 goto done;
343 }
344 else
345 {
346 strcat(pfdin->psz3, "\\");
347 strcat(pfdin->psz3, next_cab);
348 }
349 /* Path psz3 and cabinet psz1 are concatenated by FDI so just reset psz1 */
350 *pfdin->psz1 = 0;
351 free(next_cab);
352 }
353
354 if (!(cabinet_file = get_cabinet_filename(mi)))
355 goto done;
356
357 TRACE("Searching for %s\n", debugstr_w(cabinet_file));
358
359 res = 0;
360 if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES)
361 {
362 if (change_media(data->package, mi) != ERROR_SUCCESS)
363 res = -1;
364 }
365
366done:
367 free(cab);
368 free(cabinet_file);
369 return res;
370}
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 change_media(MSIPACKAGE *package, MSIMEDIAINFO *mi)
Definition: media.c:63
static WCHAR * get_cabinet_filename(MSIMEDIAINFO *mi)
Definition: media.c:289
static UINT media_get_disk_info(MSIPACKAGE *package, MSIMEDIAINFO *mi)
Definition: media.c:262
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 372 of file media.c.

374{
375 MSICABDATA *data = pfdin->pv;
376 MSIMEDIAINFO *mi = data->mi;
377 UINT rc;
378
379 free( mi->disk_prompt );
380 free( mi->cabinet );
381 free( mi->volume_label );
382 mi->disk_prompt = NULL;
383 mi->cabinet = NULL;
384 mi->volume_label = NULL;
385
386 mi->disk_id++;
387 mi->is_continuous = TRUE;
388
389 rc = media_get_disk_info( data->package, mi );
390 if (rc != ERROR_SUCCESS)
391 {
392 ERR("Failed to get next cabinet information: %u\n", rc);
393 return -1;
394 }
395 package_disk.id = mi->disk_id;
396
397 TRACE("next cabinet is %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
398 return 0;
399}
UINT id
Definition: media.c:180

Referenced by cabinet_notify_stream().

◆ cabinet_notify()

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

Definition at line 521 of file media.c.

522{
523 switch (fdint)
524 {
526 return cabinet_partial_file(fdint, pfdin);
527
529 return cabinet_next_cabinet(fdint, pfdin);
530
531 case fdintCOPY_FILE:
532 return cabinet_copy_file(fdint, pfdin);
533
535 return cabinet_close_file_info(fdint, pfdin);
536
537 default:
538 return 0;
539 }
540}
static INT_PTR cabinet_partial_file(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:281
static INT_PTR cabinet_close_file_info(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:486
static INT_PTR cabinet_copy_file(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:401
static INT_PTR cabinet_next_cabinet(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:301
@ 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 542 of file media.c.

543{
544 switch (fdint)
545 {
547 return cabinet_partial_file( fdint, pfdin );
548
550 return cabinet_next_cabinet_stream( fdint, pfdin );
551
552 case fdintCOPY_FILE:
553 return cabinet_copy_file( fdint, pfdin );
554
556 return cabinet_close_file_info( fdint, pfdin );
557
559 return 0;
560
561 default:
562 ERR("Unexpected notification %d\n", fdint);
563 return 0;
564 }
565}
static INT_PTR cabinet_next_cabinet_stream(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:372
@ 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 107 of file media.c.

108{
109 DWORD dwAccess = 0;
110 DWORD dwShareMode = 0;
111 DWORD dwCreateDisposition = OPEN_EXISTING;
113 WCHAR *path;
114
115 switch (oflag & _O_ACCMODE)
116 {
117 case _O_RDONLY:
118 dwAccess = GENERIC_READ;
119 dwShareMode = FILE_SHARE_READ | FILE_SHARE_DELETE;
120 break;
121 case _O_WRONLY:
122 dwAccess = GENERIC_WRITE;
124 break;
125 case _O_RDWR:
126 dwAccess = GENERIC_READ | GENERIC_WRITE;
128 break;
129 }
130
131 if ((oflag & (_O_CREAT | _O_EXCL)) == (_O_CREAT | _O_EXCL))
132 dwCreateDisposition = CREATE_NEW;
133 else if (oflag & _O_CREAT)
134 dwCreateDisposition = CREATE_ALWAYS;
135
136 path = strdupUtoW(pszFile);
137 handle = CreateFileW(path, dwAccess, dwShareMode, NULL, dwCreateDisposition, 0, NULL);
138 free(path);
139 return (INT_PTR)handle;
140}
#define _O_RDWR
Definition: cabinet.h:39
#define _O_ACCMODE
Definition: cabinet.h:40
#define _O_RDONLY
Definition: cabinet.h:37
#define _O_CREAT
Definition: cabinet.h:46
#define _O_EXCL
Definition: cabinet.h:48
#define _O_WRONLY
Definition: cabinet.h:38
#define OPEN_EXISTING
Definition: compat.h:775
#define CreateFileW
Definition: compat.h:741
#define FILE_SHARE_READ
Definition: compat.h:136
#define CREATE_NEW
Definition: disk.h:69
static LPWSTR strdupUtoW(LPCSTR str)
Definition: msipriv.h:1185
#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 185 of file media.c.

186{
187 MSICABINETSTREAM *cab;
189
191 {
192 WARN("failed to get cabinet stream\n");
193 return -1;
194 }
195 if (cab->storage == package_disk.package->db->storage)
196 {
198 if (r != ERROR_SUCCESS)
199 {
200 WARN("failed to get stream %u\n", r);
201 return -1;
202 }
203 }
204 else /* patch storage */
205 {
206 HRESULT hr;
207 WCHAR *encoded;
208
209 if (!(encoded = encode_streamname( FALSE, cab->stream + 1 )))
210 {
211 WARN("failed to encode stream name\n");
212 return -1;
213 }
214 hr = IStorage_OpenStream( cab->storage, encoded, NULL, STGM_READ|STGM_SHARE_EXCLUSIVE, 0, &stream );
215 free( encoded );
216 if (FAILED(hr))
217 {
218 WARN( "failed to open stream %#lx\n", hr );
219 return -1;
220 }
221 }
222 return (INT_PTR)stream;
223}
static MSICABINETSTREAM * get_cabinet_stream(MSIPACKAGE *package, UINT disk_id)
Definition: media.c:86
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
#define FAILED(hr)
Definition: intsafe.h:51
WCHAR * encode_streamname(BOOL is_table, const WCHAR *in)
UINT msi_get_stream(MSIDATABASE *, const WCHAR *, IStream **)
Definition: streams.c:499
#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:179
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 281 of file media.c.

283{
284 MSICABDATA *data = pfdin->pv;
285 data->mi->is_continuous = FALSE;
286 return 0;
287}

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 142 of file media.c.

143{
144 HANDLE handle = (HANDLE)hf;
145 DWORD read;
146
147 if (ReadFile(handle, pv, cb, &read, NULL))
148 return read;
149
150 return 0;
151}
#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 225 of file media.c.

226{
227 IStream *stm = (IStream *)hf;
228 DWORD read;
229 HRESULT hr;
230
231 hr = IStream_Read( stm, pv, cb, &read );
232 if (hr == S_OK || hr == S_FALSE)
233 return read;
234
235 return 0;
236}
#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 170 of file media.c.

171{
172 HANDLE handle = (HANDLE)hf;
173 /* flags are compatible and so are passed straight through */
174 return SetFilePointer(handle, dist, NULL, seektype);
175}
#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 245 of file media.c.

246{
247 IStream *stm = (IStream *)hf;
248 LARGE_INTEGER move;
249 ULARGE_INTEGER newpos;
250 HRESULT hr;
251
252 move.QuadPart = dist;
253 hr = IStream_Seek( stm, move, seektype, &newpos );
254 if (SUCCEEDED(hr))
255 {
256 if (newpos.QuadPart <= MAXLONG) return newpos.QuadPart;
257 ERR("Too big!\n");
258 }
259 return -1;
260}
#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 153 of file media.c.

154{
155 HANDLE handle = (HANDLE)hf;
156 DWORD written;
157
158 if (WriteFile(handle, pv, cb, &written, NULL))
159 return written;
160
161 return 0;
162}
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().

◆ change_media()

static UINT change_media ( MSIPACKAGE package,
MSIMEDIAINFO mi 
)
static

Definition at line 63 of file media.c.

64{
66 LPWSTR source_dir;
67 UINT r = IDRETRY;
68
69 source_dir = msi_dup_property(package->db, L"SourceDir");
71
72 while (r == IDRETRY && !source_matches_volume(mi, source_dir))
73 {
76 MSI_RecordSetStringW(record, 2, mi->disk_prompt);
78 }
79
81 free(source_dir);
82
84}
int msiobj_release(MSIOBJECTHDR *info)
Definition: handle.c:241
static BOOL source_matches_volume(MSIMEDIAINFO *mi, LPCWSTR source_root)
Definition: media.c:39
#define MSIERR_CABNOTFOUND
Definition: resource.h:31
@ INSTALLMESSAGE_ERROR
Definition: msi.h:95
UINT MSI_RecordSetInteger(MSIRECORD *, UINT, int)
Definition: record.c:280
WCHAR * msi_dup_property(MSIDATABASE *db, const WCHAR *prop)
INT MSI_ProcessMessage(MSIPACKAGE *, INSTALLMESSAGE, MSIRECORD *)
Definition: package.c:1909
UINT MSI_RecordSetStringW(MSIRECORD *, UINT, LPCWSTR)
Definition: record.c:597
MSIRECORD * MSI_CreateRecord(UINT)
Definition: record.c:76
#define ERROR_INSTALL_SOURCE_ABSENT
Definition: winerror.h:970
#define MB_RETRYCANCEL
Definition: winuser.h:808
#define IDRETRY
Definition: winuser.h:836

Referenced by cabinet_next_cabinet(), and ready_media().

◆ extract_cabinet()

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

Definition at line 567 of file media.c.

568{
569 LPSTR cabinet, cab_path = NULL;
570 HFDI hfdi;
571 ERF erf;
572 BOOL ret = FALSE;
573
574 TRACE("extracting %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
575
578 if (!hfdi)
579 {
580 ERR("FDICreate failed\n");
581 return FALSE;
582 }
583
584 cabinet = strdupWtoU( mi->cabinet );
585 if (!cabinet)
586 goto done;
587
588 cab_path = strdupWtoU( mi->sourcedir );
589 if (!cab_path)
590 goto done;
591
592 ret = FDICopy( hfdi, cabinet, cab_path, 0, cabinet_notify, NULL, data );
593 if (!ret)
594 ERR("FDICopy failed\n");
595
596done:
597 FDIDestroy( hfdi );
598 free( cabinet );
599 free( cab_path );
600
601 if (ret)
602 mi->is_extracted = TRUE;
603
604 return ret;
605}
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:142
static void CDECL cabinet_free(void *pv)
Definition: media.c:102
static INT_PTR CDECL cabinet_open(char *pszFile, int oflag, int pmode)
Definition: media.c:107
static void *CDECL cabinet_alloc(ULONG cb)
Definition: media.c:97
static int CDECL cabinet_close(INT_PTR hf)
Definition: media.c:164
static LONG CDECL cabinet_seek(INT_PTR hf, LONG dist, int seektype)
Definition: media.c:170
static UINT CDECL cabinet_write(INT_PTR hf, void *pv, UINT cb)
Definition: media.c:153
static INT_PTR CDECL cabinet_notify(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:521
unsigned int BOOL
Definition: ntddk_ex.h:94
double __cdecl erf(double)
static char * strdupWtoU(LPCWSTR str)
Definition: msipriv.h:1172
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 607 of file media.c.

608{
609 static char filename[] = {'<','S','T','R','E','A','M','>',0};
610 HFDI hfdi;
611 ERF erf;
612 BOOL ret = FALSE;
613
614 TRACE("extracting %s disk id %u\n", debugstr_w(mi->cabinet), mi->disk_id);
615
618 if (!hfdi)
619 {
620 ERR("FDICreate failed\n");
621 return FALSE;
622 }
623
624 package_disk.package = package;
625 package_disk.id = mi->disk_id;
626
628 if (!ret) ERR("FDICopy failed\n");
629
630 FDIDestroy( hfdi );
631 if (ret) mi->is_extracted = TRUE;
632 return ret;
633}
static int CDECL cabinet_close_stream(INT_PTR hf)
Definition: media.c:238
static INT_PTR CDECL cabinet_notify_stream(FDINOTIFICATIONTYPE fdint, PFDINOTIFICATION pfdin)
Definition: media.c:542
static INT_PTR CDECL cabinet_open_stream(char *pszFile, int oflag, int pmode)
Definition: media.c:185
static LONG CDECL cabinet_seek_stream(INT_PTR hf, LONG dist, int seektype)
Definition: media.c:245
static UINT CDECL cabinet_read_stream(INT_PTR hf, void *pv, UINT cb)
Definition: media.c:225
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 742 of file media.c.

743{
746 WCHAR prompt[MAX_PATH];
747 DWORD volumesz, promptsz;
748 DWORD index, size, id;
749 WCHAR last_type[2];
750 UINT r;
751
752 size = 2;
754 package->Context, MSICODE_PRODUCT,
756 if (r != ERROR_SUCCESS)
757 return r;
758
759 size = MAX_PATH;
761 package->Context, MSICODE_PRODUCT,
763 if (r != ERROR_SUCCESS)
764 return r;
765
766 if (last_type[0] == 'n')
767 {
768 WCHAR cabinet_file[MAX_PATH];
769 BOOL check_all = FALSE;
770
771 while(TRUE)
772 {
773 index = 0;
774 volumesz = MAX_PATH;
776 package->Context,
778 volume, &volumesz) == ERROR_SUCCESS)
779 {
780 if (check_all || !wcsnicmp(source, volume, lstrlenW(source)))
781 {
782 lstrcpyW(cabinet_file, volume);
783 PathAddBackslashW(cabinet_file);
784 lstrcatW(cabinet_file, mi->cabinet);
785
786 if (GetFileAttributesW(cabinet_file) == INVALID_FILE_ATTRIBUTES)
787 {
788 volumesz = MAX_PATH;
789 if(!check_all)
790 break;
791 continue;
792 }
793
794 lstrcpyW(mi->sourcedir, volume);
795 PathAddBackslashW(mi->sourcedir);
796 TRACE("Found network source %s\n", debugstr_w(mi->sourcedir));
797 return ERROR_SUCCESS;
798 }
799 }
800
801 if (!check_all)
802 check_all = TRUE;
803 else
804 break;
805 }
806 }
807
808 index = 0;
809 volumesz = MAX_PATH;
810 promptsz = MAX_PATH;
812 package->Context,
813 MSICODE_PRODUCT, index++, &id,
814 volume, &volumesz, prompt, &promptsz) == ERROR_SUCCESS)
815 {
816 mi->disk_id = id;
817 free( mi->volume_label );
818 if (!(mi->volume_label = malloc( ++volumesz * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
819 lstrcpyW( mi->volume_label, volume );
820
821 free( mi->disk_prompt );
822 if (!(mi->disk_prompt = malloc( ++promptsz * sizeof(WCHAR) ))) return ERROR_OUTOFMEMORY;
823 lstrcpyW( mi->disk_prompt, prompt );
824
826 {
827 /* FIXME: what about SourceDir */
828 lstrcpyW(mi->sourcedir, source);
829 PathAddBackslashW(mi->sourcedir);
830 TRACE("Found disk source %s\n", debugstr_w(mi->sourcedir));
831 return ERROR_SUCCESS;
832 }
833 }
834
836}
#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
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
MSIINSTALLCONTEXT 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 669 of file media.c.

670{
671 WCHAR *p, *ret = NULL, *orig_db = msi_dup_property( db, L"OriginalDatabase" );
672 if (UrlIsW( orig_db, URLIS_URL ) && (ret = wcsdup( orig_db )) && (p = wcsrchr( ret, '/' ))) p[1] = 0;
673 free( orig_db );
674 return ret;
675}
BOOL WINAPI UrlIsW(LPCWSTR pszUrl, URLIS Urlis)
Definition: url.c:1933
@ URLIS_URL
Definition: shlwapi.h:1217

Referenced by msi_load_media_info(), and ready_media().

◆ get_cabinet_filename()

static WCHAR * get_cabinet_filename ( MSIMEDIAINFO mi)
static

Definition at line 289 of file media.c.

290{
291 int len;
292 WCHAR *ret;
293
294 len = lstrlenW(mi->sourcedir) + lstrlenW(mi->cabinet) + 1;
295 if (!(ret = malloc(len * sizeof(WCHAR)))) return NULL;
296 lstrcpyW(ret, mi->sourcedir);
297 lstrcatW(ret, mi->cabinet);
298 return ret;
299}

Referenced by cabinet_next_cabinet(), and ready_media().

◆ get_cabinet_stream()

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

Definition at line 86 of file media.c.

87{
89
91 {
92 if (cab->disk_id == disk_id) return cab;
93 }
94 return NULL;
95}
uint32_t entry
Definition: isohybrid.c:63
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
struct list cabinet_streams
Definition: msipriv.h:408

Referenced by cabinet_open_stream().

◆ get_drive_type()

static UINT get_drive_type ( const WCHAR path)
static

Definition at line 658 of file media.c.

659{
660 WCHAR root[MAX_PATH + 1];
661
665
666 return GetDriveTypeW(root);
667}
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().

◆ media_get_disk_info()

static UINT media_get_disk_info ( MSIPACKAGE package,
MSIMEDIAINFO mi 
)
static

Definition at line 262 of file media.c.

263{
264 MSIRECORD *row;
265
266 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `DiskId` = %d", mi->disk_id);
267 if (!row)
268 {
269 TRACE("Unable to query row\n");
271 }
272
273 mi->disk_prompt = wcsdup(MSI_RecordGetString(row, 3));
274 mi->cabinet = wcsdup(MSI_RecordGetString(row, 4));
275 mi->volume_label = wcsdup(MSI_RecordGetString(row, 5));
276
277 msiobj_release(&row->hdr);
278 return ERROR_SUCCESS;
279}
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
const WCHAR * MSI_RecordGetString(const MSIRECORD *, UINT)
Definition: record.c:433
MSIRECORD *WINAPIV MSI_QueryGetRecord(MSIDATABASE *db, LPCWSTR query,...)
Definition: msiquery.c:201

Referenced by cabinet_next_cabinet(), and cabinet_next_cabinet_stream().

◆ msi_add_cabinet_stream()

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

Definition at line 923 of file media.c.

924{
925 MSICABINETSTREAM *cab, *item;
926
927 TRACE("%p, %u, %p, %s\n", package, disk_id, storage, debugstr_w(name));
928
930 {
931 if (item->disk_id == disk_id)
932 {
933 TRACE("duplicate disk id %u\n", disk_id);
935 }
936 }
937 if (!(cab = malloc( sizeof(*cab) ))) return ERROR_OUTOFMEMORY;
938 if (!(cab->stream = malloc( (wcslen( name ) + 1) * sizeof(WCHAR) )))
939 {
940 free( cab );
941 return ERROR_OUTOFMEMORY;
942 }
943 lstrcpyW( cab->stream, name );
944 cab->disk_id = disk_id;
945 cab->storage = storage;
946 IStorage_AddRef( storage );
947 list_add_tail( &package->cabinet_streams, &cab->entry );
948
949 return ERROR_SUCCESS;
950}
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
static ATOM item
Definition: dde.c:856
Definition: name.c:39
struct list entry
Definition: msipriv.h:192

Referenced by load_media(), and patch_add_media().

◆ msi_cabextract()

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

Definition at line 640 of file media.c.

641{
642 if (mi->cabinet[0] == '#')
643 {
644 return extract_cabinet_stream( package, mi, data );
645 }
646 return extract_cabinet( package, mi, data );
647}
static BOOL extract_cabinet(MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data)
Definition: media.c:567
static BOOL extract_cabinet_stream(MSIPACKAGE *package, MSIMEDIAINFO *mi, LPVOID data)
Definition: media.c:607

Referenced by ACTION_InstallFiles(), and ACTION_PatchFiles().

◆ msi_free_media_info()

void msi_free_media_info ( MSIMEDIAINFO mi)

Definition at line 649 of file media.c.

650{
651 free(mi->disk_prompt);
652 free(mi->cabinet);
653 free(mi->volume_label);
654 free(mi->last_volume);
655 free(mi);
656}

Referenced by ACTION_InstallFiles(), and ACTION_PatchFiles().

◆ msi_load_media_info()

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

Definition at line 677 of file media.c.

678{
679 MSIRECORD *row;
680 WCHAR *source_dir, *source, *base_url = NULL;
682
683 if (Sequence <= mi->last_sequence) /* already loaded */
684 return ERROR_SUCCESS;
685
686 row = MSI_QueryGetRecord(package->db, L"SELECT * FROM `Media` WHERE `LastSequence` >= %d ORDER BY `DiskId`", Sequence);
687 if (!row)
688 {
689 TRACE("Unable to query row\n");
691 }
692
693 mi->is_extracted = FALSE;
694 mi->disk_id = MSI_RecordGetInteger(row, 1);
695 mi->last_sequence = MSI_RecordGetInteger(row, 2);
696 free(mi->disk_prompt);
697 mi->disk_prompt = wcsdup(MSI_RecordGetString(row, 3));
698 free(mi->cabinet);
699 mi->cabinet = wcsdup(MSI_RecordGetString(row, 4));
700 free(mi->volume_label);
701 mi->volume_label = wcsdup(MSI_RecordGetString(row, 5));
702 msiobj_release(&row->hdr);
703
705 source_dir = msi_dup_property(package->db, L"SourceDir");
706 lstrcpyW(mi->sourcedir, source_dir);
707 PathAddBackslashW(mi->sourcedir);
708 mi->type = get_drive_type(source_dir);
709
711 if (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE)
712 {
713 source = source_dir;
715 }
716 else if ((base_url = get_base_url(package->db)))
717 {
720 }
721 else
722 {
723 source = mi->sourcedir;
725 }
726
727 msi_package_add_media_disk(package, package->Context,
728 MSICODE_PRODUCT, mi->disk_id,
729 mi->volume_label, mi->disk_prompt);
730
731 msi_package_add_info(package, package->Context,
733
734 TRACE("sequence %u -> cabinet %s disk id %u\n", Sequence, debugstr_w(mi->cabinet), mi->disk_id);
735
736 free(base_url);
737 free(source_dir);
738 return ERROR_SUCCESS;
739}
UINT msi_set_sourcedir_props(MSIPACKAGE *package, BOOL replace)
Definition: action.c:352
static WCHAR * get_base_url(MSIDATABASE *db)
Definition: media.c:669
static UINT get_drive_type(const WCHAR *path)
Definition: media.c:658
#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
int MSI_RecordGetInteger(MSIRECORD *, UINT)
Definition: record.c:213
UINT msi_package_add_media_disk(MSIPACKAGE *, DWORD, DWORD, DWORD, LPWSTR, LPWSTR)
Definition: package.c:2648
UINT msi_package_add_info(MSIPACKAGE *, DWORD, DWORD, LPCWSTR, LPWSTR)
Definition: package.c:2625
#define DRIVE_REMOVABLE
Definition: winbase.h:251

Referenced by ACTION_InstallFiles(), and ACTION_PatchFiles().

◆ ready_media()

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

Definition at line 838 of file media.c.

839{
840 UINT rc;
841 WCHAR *cabinet_file = NULL;
842
843 /* media info for continuous cabinet is already loaded */
844 if (mi->is_continuous) return ERROR_SUCCESS;
845
846 if (mi->cabinet)
847 {
849
850 /* cabinet is internal, no checks needed */
851 if (mi->cabinet[0] == '#') return ERROR_SUCCESS;
852
853 if (!(cabinet_file = get_cabinet_filename( mi ))) return ERROR_OUTOFMEMORY;
854
855 /* package should be downloaded */
856 if (compressed && GetFileAttributesW( cabinet_file ) == INVALID_FILE_ATTRIBUTES &&
857 (base_url = get_base_url( package->db )))
858 {
859 WCHAR temppath[MAX_PATH], *p, *url;
860
861 free( cabinet_file );
862 if (!(url = realloc( base_url, (wcslen( base_url ) + wcslen( mi->cabinet ) + 1) * sizeof(WCHAR) )))
863 {
864 free( base_url );
865 return ERROR_OUTOFMEMORY;
866 }
867 lstrcatW( url, mi->cabinet );
868 if ((rc = msi_download_file( url, temppath )) != ERROR_SUCCESS)
869 {
870 ERR("failed to download %s (%u)\n", debugstr_w(url), rc);
871 free( url );
872 return rc;
873 }
874 if ((p = wcsrchr( temppath, '\\' ))) *p = 0;
875 lstrcpyW( mi->sourcedir, temppath );
876 PathAddBackslashW( mi->sourcedir );
877 free( mi->cabinet );
878 mi->cabinet = wcsdup( p + 1 );
879
880 free( url );
881 return ERROR_SUCCESS;
882 }
883 }
884 /* check volume matches, change media if not */
885 if (mi->volume_label)
886 {
887 /* assume first volume is in the drive */
888 if (mi->last_volume && wcsicmp( mi->last_volume, mi->volume_label ))
889 {
890 WCHAR *source = msi_dup_property( package->db, L"SourceDir" );
892 free( source );
893
894 if (!match && (mi->type == DRIVE_CDROM || mi->type == DRIVE_REMOVABLE))
895 {
896 if ((rc = change_media( package, mi )) != ERROR_SUCCESS)
897 {
898 free( cabinet_file );
899 return rc;
900 }
901 }
902 }
903
904 free(mi->last_volume);
905 mi->last_volume = wcsdup(mi->volume_label);
906 }
907 if (mi->cabinet)
908 {
909 if (compressed && GetFileAttributesW( cabinet_file ) == INVALID_FILE_ATTRIBUTES)
910 {
911 if ((rc = find_published_source( package, mi )) != ERROR_SUCCESS)
912 {
913 ERR("cabinet not found: %s\n", debugstr_w(cabinet_file));
914 free( cabinet_file );
916 }
917 }
918 }
919 free( cabinet_file );
920 return ERROR_SUCCESS;
921}
#define realloc
Definition: debug_ros.c:6
static UINT find_published_source(MSIPACKAGE *package, MSIMEDIAINFO *mi)
Definition: media.c:742
static const WCHAR url[]
Definition: encode.c:1432
UINT msi_download_file(LPCWSTR szUrl, LPWSTR filename)
Definition: package.c:1026
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 39 of file media.c.

40{
42 const WCHAR *p;
43 int len, len2;
44
45 lstrcpyW(root, source_root);
48
50 {
51 WARN( "failed to get volume information for %s (%lu)\n", debugstr_w(root), GetLastError() );
52 return FALSE;
53 }
54
56 len2 = lstrlenW( mi->volume_label );
57 if (len2 > len) return FALSE;
58 p = volume_name + len - len2;
59
60 return !wcsicmp( mi->volume_label, p );
61}
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 change_media(), find_published_source(), and ready_media().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( msi  )

Variable Documentation

◆ package_disk

Definition at line 183 of file media.c.