/// <summary> /// Delegate that's called for every file in cabinet. /// </summary> /// <param name="fdint">NOTIFICATIONTYPE</param> /// <param name="pfdin">NOTIFICATION</param> /// <returns>System.Int32</returns> internal Handle Notify(CabInterop.NOTIFICATIONTYPE fdint, CabInterop.NOTIFICATION pfdin) { if (fdint == CabInterop.NOTIFICATIONTYPE.COPY_FILE) { CabinetFileInfo fileInfo = new CabinetFileInfo(pfdin.Psz1, pfdin.Cb, pfdin.Date, pfdin.Time); this.fileInfoList.Add(fileInfo); } return(0); // tell cabinet api to skip this file }
/// <summary> /// Delegate that's called for every file in cabinet. /// </summary> /// <param name="fdint">NOTIFICATIONTYPE</param> /// <param name="pfdin">NOTIFICATION</param> /// <returns>System.Int32</returns> internal Handle Notify(CabInterop.NOTIFICATIONTYPE fdint, CabInterop.NOTIFICATION pfdin) { // This is FDI's way of notifying us of how many files total are in the cab, accurate even // if the files are split into multiple folders - use it to allocate the precise size we need if (CabInterop.NOTIFICATIONTYPE.ENUMERATE == fdint && 0 == this.fileInfoList.Count) { this.fileInfoList.Capacity = pfdin.Folder; } if (fdint == CabInterop.NOTIFICATIONTYPE.COPY_FILE) { CabinetFileInfo fileInfo = new CabinetFileInfo(pfdin.Psz1, pfdin.Date, pfdin.Time, pfdin.Cb); this.fileInfoList.Add(fileInfo); } return(0); // tell cabinet api to skip this file }
/// <summary> /// Refreshes the attributes and other cached information about the file, /// by re-reading the information from the cabinet. /// </summary> public new void Refresh() { base.Refresh(); string filePath = System.IO.Path.Combine(this.Path, this.Name); CabinetFileInfo updatedFile = Cabinet.GetFile(filePath); if (updatedFile == null) { throw new FileNotFoundException("File not found in cabinet.", filePath); } this.exists = updatedFile.exists; this.length = updatedFile.length; this.attributes = updatedFile.attributes; this.lastWriteTime = updatedFile.lastWriteTime; this.cabFolderNumber = updatedFile.cabFolderNumber; }
/// <summary> /// Delegate that's called for every file in cabinet. /// </summary> /// <param name="fdint">NOTIFICATIONTYPE</param> /// <param name="pfdin">NOTIFICATION</param> /// <returns>System.Int32</returns> internal Handle Notify(CabInterop.NOTIFICATIONTYPE fdint, CabInterop.NOTIFICATION pfdin) { // This is FDI's way of notifying us of how many files total are in the cab, accurate even // if the files are split into multiple folders - use it to allocate the precise size we need if (CabInterop.NOTIFICATIONTYPE.ENUMERATE == fdint && 0 == this.fileInfoList.Count) { this.fileInfoList.Capacity = pfdin.Folder; } if (fdint == CabInterop.NOTIFICATIONTYPE.COPY_FILE) { CabinetFileInfo fileInfo = new CabinetFileInfo(pfdin.Psz1, pfdin.Date, pfdin.Time); this.fileInfoList.Add(fileInfo); } return 0; // tell cabinet api to skip this file }
public ResolvedCabinet ResolveCabinet(string cabinetPath, IEnumerable <FileFacade> fileFacades) { var filesWithPath = fileFacades.Select(f => new BindFileWithPath() { Id = f.File.File, Path = f.WixFile.Source.Path }).ToList(); ResolvedCabinet resolved = null; foreach (var extension in this.BackendExtensions) { resolved = extension.ResolveCabinet(cabinetPath, filesWithPath); if (null != resolved) { return(resolved); } } // By default cabinet should be built and moved to the suggested location. resolved = new ResolvedCabinet() { BuildOption = CabinetBuildOption.BuildAndMove, Path = cabinetPath }; // If a cabinet cache path was provided, change the location for the cabinet // to be built to and check if there is a cabinet that can be reused. if (!String.IsNullOrEmpty(this.CabCachePath)) { string cabinetName = Path.GetFileName(cabinetPath); resolved.Path = Path.Combine(this.CabCachePath, cabinetName); if (CheckFileExists(resolved.Path)) { // Assume that none of the following are true: // 1. any files are added or removed // 2. order of files changed or names changed // 3. modified time changed bool cabinetValid = true; var cabinet = new Cabinet(resolved.Path); List <CabinetFileInfo> fileList = cabinet.Enumerate(); if (filesWithPath.Count() != fileList.Count) { cabinetValid = false; } else { int i = 0; foreach (BindFileWithPath file in filesWithPath) { // First check that the file identifiers match because that is quick and easy. CabinetFileInfo cabFileInfo = fileList[i]; cabinetValid = (cabFileInfo.FileId == file.Id); if (cabinetValid) { // Still valid so ensure the file sizes are the same. FileInfo fileInfo = new FileInfo(file.Path); cabinetValid = (cabFileInfo.Size == fileInfo.Length); if (cabinetValid) { // Still valid so ensure the source time stamp hasn't changed. cabinetValid = cabFileInfo.SameAsDateTime(fileInfo.LastWriteTime); } } if (!cabinetValid) { break; } i++; } } resolved.BuildOption = cabinetValid ? CabinetBuildOption.Copy : CabinetBuildOption.BuildAndCopy; } } return(resolved); }
internal Handle CabExtractListNotify(FDI.NOTIFICATIONTYPE notificationType, FDI.NOTIFICATION notification) { try { switch (notificationType) { case FDI.NOTIFICATIONTYPE.CABINET_INFO: { this.nextCabinetName = (notification.psz1.Length != 0 ? notification.psz1 : null); return((Handle)0); // Continue } case FDI.NOTIFICATIONTYPE.ENUMERATE: { return((Handle)0); // Continue } case FDI.NOTIFICATIONTYPE.PARTIAL_FILE: { // This notification can occur when examining the contents of a non-first cab file. return((Handle)0); // Continue } case FDI.NOTIFICATIONTYPE.COPY_FILE: { if (notification.iFolder != this.folderId || this.folderCount == 0) { this.folderId = notification.iFolder; this.folderCount++; } bool utfName = (notification.attribs & (ushort)FileAttributes.Normal) != 0; // _A_NAME_IS_UTF //bool execute = (notification.attribs & (ushort) FileAttributes.Device) != 0; // _A_EXEC string name = notification.psz1; if (utfName) { byte[] nameBytes = Encoding.Default.GetBytes(name); name = Encoding.UTF8.GetString(nameBytes); } if (this.filterFileHandler == null || this.filterFileHandler(this.folderCount - 1, name, filterFileContext)) { if (this.listFiles != null) { #if !CABMINIMAL FileAttributes attributes = (FileAttributes)notification.attribs & (FileAttributes.Archive | FileAttributes.Hidden | FileAttributes.ReadOnly | FileAttributes.System); if (attributes == (FileAttributes)0) { attributes = FileAttributes.Normal; } DateTime lastWriteTime; FDI.CabDateAndTimeToDateTime(notification.date, notification.time, out lastWriteTime); long length = notification.cb; CabinetFileInfo fileInfo = new CabinetFileInfo(Path.GetFileName(name), Path.GetDirectoryName(name), this.folderCount - 1, notification.iCabinet, attributes, lastWriteTime, length); listFiles.Add(fileInfo); #else listFiles.Add(name); #endif // CABMINIMAL } } return((Handle)0); // Continue } default: { // Should never get any other notification types here. throw new CabinetExtractException((int)FDI.ERROR.UNKNOWN_CABINET_VERSION, 0); } } } catch (Exception ex) { if (this.abortException == null) { this.abortException = ex; } return((Handle)(-1)); } }