public HfsEntry(HfsEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } known = entry.known; name = entry.name; size = entry.size; compressedSize = entry.compressedSize; crc = entry.crc; dosTime = entry.dosTime; method = entry.method; comment = entry.comment; versionToExtract = entry.versionToExtract; versionMadeBy = entry.versionMadeBy; externalFileAttributes = entry.externalFileAttributes; flags = entry.flags; HfsFileIndex = entry.HfsFileIndex; offset = entry.offset; if (entry.extra != null) { extra = new byte[entry.extra.Length]; Array.Copy(entry.extra, 0, extra, 0, entry.extra.Length); } }
// Write the local file header // TODO: HfsHelperStream.WriteLocalHeader is not yet used and needs checking for HfsFile and HfsOuptutStream usage void WriteLocalHeader(HfsEntry entry, EntryPatchData patchData) { CompressionMethod method = entry.CompressionMethod; bool headerInfoAvailable = true; // How to get this? WriteLEInt(HfsConstants.LocalHeaderSignature); WriteLEShort(entry.Version); WriteLEShort(entry.Flags); WriteLEShort((byte)method); WriteLEInt((int)entry.DosTime); if (headerInfoAvailable == true) { WriteLEInt((int)entry.CompressedSize); WriteLEInt((int)entry.Size); } else { if (patchData != null) { patchData.CrcPatchOffset = stream_.Position; } WriteLEInt(0); // Crc if (patchData != null) { patchData.SizePatchOffset = stream_.Position; } WriteLEInt(0); // Compressed size WriteLEInt(0); // Uncompressed size } byte[] name = HfsConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new HfsException("Entry name too long."); } byte[] extra = new byte[0]; WriteLEShort(name.Length); WriteLEShort(extra.Length); if (name.Length > 0) { stream_.Write(name, 0, name.Length); } if (extra.Length > 0) { stream_.Write(extra, 0, extra.Length); } }
/// <summary> /// Creates a copy of this Hfs entry. /// </summary> /// <returns>An <see cref="Object"/> that is a copy of the current instance.</returns> public object Clone() { HfsEntry result = (HfsEntry)this.MemberwiseClone(); // Ensure extra data is unique if it exists. if (extra != null) { result.extra = new byte[extra.Length]; Array.Copy(extra, 0, result.extra, 0, extra.Length); } return(result); }
public HfsUpdate(IStaticDataSource dataSource, string entryName, CompressionMethod compressionMethod) { command_ = UpdateCommand.Add; entry_ = new HfsEntry(entryName); entry_.CompressionMethod = compressionMethod; dataSource_ = dataSource; }
public HfsUpdate(string fileName, string entryName, CompressionMethod compressionMethod) { command_ = UpdateCommand.Add; entry_ = new HfsEntry(entryName); entry_.CompressionMethod = compressionMethod; filename_ = fileName; }
/// <summary> /// Make a new <see cref="HfsEntry"></see> for a directory. /// </summary> /// <param name="directoryName">The raw untransformed name for the new directory</param> /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param> /// <returns>Returns a new <see cref="HfsEntry"></see> representing a directory.</returns> public HfsEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) { HfsEntry result = new HfsEntry(nameTransform_.TransformDirectory(directoryName)); result.Size = 0; int externalAttributes = 0; DirectoryInfo di = null; if (useFileSystem) { di = new DirectoryInfo(directoryName); } if ((di != null) && di.Exists) { switch (timeSetting_) { case TimeSetting.CreateTime: result.DateTime = di.CreationTime; break; case TimeSetting.CreateTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = di.CreationTime.ToUniversalTime(); #else result.DateTime = di.CreationTimeUtc; #endif break; case TimeSetting.LastAccessTime: result.DateTime = di.LastAccessTime; break; case TimeSetting.LastAccessTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = di.LastAccessTime.ToUniversalTime(); #else result.DateTime = di.LastAccessTimeUtc; #endif break; case TimeSetting.LastWriteTime: result.DateTime = di.LastWriteTime; break; case TimeSetting.LastWriteTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = di.LastWriteTime.ToUniversalTime(); #else result.DateTime = di.LastWriteTimeUtc; #endif break; case TimeSetting.Fixed: result.DateTime = fixedDateTime_; break; default: throw new HfsException("Unhandled time setting in MakeDirectoryEntry"); } externalAttributes = ((int)di.Attributes & getAttributes_); } else { if (timeSetting_ == TimeSetting.Fixed) { result.DateTime = fixedDateTime_; } } // Always set directory attribute on. externalAttributes |= (setAttributes_ | 16); result.ExternalFileAttributes = externalAttributes; return(result); }
/// <summary> /// Make a new <see cref="HfsEntry"></see> for a directory. /// </summary> /// <param name="directoryName">The raw untransformed name for the new directory</param> /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param> /// <returns>Returns a new <see cref="HfsEntry"></see> representing a directory.</returns> public HfsEntry MakeDirectoryEntry(string directoryName, bool useFileSystem) { HfsEntry result = new HfsEntry(nameTransform_.TransformDirectory(directoryName)); result.Size = 0; int externalAttributes = 0; DirectoryInfo di = null; if (useFileSystem) { di = new DirectoryInfo(directoryName); } if ((di != null) && di.Exists) { switch (timeSetting_) { case TimeSetting.CreateTime: result.DateTime = di.CreationTime; break; case TimeSetting.CreateTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = di.CreationTime.ToUniversalTime(); #else result.DateTime = di.CreationTimeUtc; #endif break; case TimeSetting.LastAccessTime: result.DateTime = di.LastAccessTime; break; case TimeSetting.LastAccessTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = di.LastAccessTime.ToUniversalTime(); #else result.DateTime = di.LastAccessTimeUtc; #endif break; case TimeSetting.LastWriteTime: result.DateTime = di.LastWriteTime; break; case TimeSetting.LastWriteTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = di.LastWriteTime.ToUniversalTime(); #else result.DateTime = di.LastWriteTimeUtc; #endif break; case TimeSetting.Fixed: result.DateTime = fixedDateTime_; break; default: throw new HfsException("Unhandled time setting in MakeDirectoryEntry"); } externalAttributes = ((int)di.Attributes & getAttributes_); } else { if (timeSetting_ == TimeSetting.Fixed) { result.DateTime = fixedDateTime_; } } // Always set directory attribute on. externalAttributes |= (setAttributes_ | 16); result.ExternalFileAttributes = externalAttributes; return result; }
internal void SetEntry(HfsEntry entry) { entry_ = entry; entryValid_ = true; bytesTested_ = 0; }
public HfsUpdate(UpdateCommand command, HfsEntry entry) { command_ = command; entry_ = (HfsEntry)entry.Clone(); }
/// <summary> /// Locate the data for a given entry. /// </summary> /// <returns> /// The start offset of the data. /// </returns> /// <exception cref="System.IO.EndOfStreamException"> /// The stream ends prematurely /// </exception> /// <exception cref="ICSharpCode.SharpZipLib.Hfs.HfsException"> /// The local header signature is invalid, the entry and central header file name lengths are different /// or the local and entry compression methods dont match /// </exception> long LocateEntry(HfsEntry entry) { return TestLocalHeader(entry, HeaderTest.Extract); }
/// <summary> /// Get an output stream for the specified <see cref="HfsEntry"/> /// </summary> /// <param name="entry">The entry to get an output stream for.</param> /// <returns>The output stream obtained for the entry.</returns> Stream GetOutputStream(HfsEntry entry) { Stream result = baseStream_; long start = result.Position; switch (entry.CompressionMethod) { case CompressionMethod.Stored: { Stream base_result = result; if (entry.Name.Substring(entry.Name.Length - 5) == ".comp") { start += 8; } result = new HFSXorStream(result, start, HfsXorCipher.XorTruths, false); // post process instead //if (obfuscationkey_ > 0) //{ // result = new HFSXorStream(result, start, bytekey_, true); //} if (entry.Name.Substring(entry.Name.Length - 5) == ".comp") { using (MemoryStream ms = new MemoryStream()) using (BinaryWriter writer = new BinaryWriter(ms)) { writer.Write((UInt32)HfsConstants.CompSignature); writer.Write((UInt32)entry.Size); ms.Seek(0, SeekOrigin.Begin); byte[] buff = new byte[ms.Length]; ms.Read(buff, 0, buff.Length); HfsXorCipher.XorBlockWithKey(buff, HfsXorCipher.XorTruths, (int)start - 8); //if (obfuscationkey_ > 0) //{ // HfsXorCipher.XorBlockWithKey(buff, bytekey_, (int)start - 8); //} start += buff.Length; base_result.Write(buff, 0, buff.Length); } DeflaterOutputStream dos = new DeflaterOutputStream(result, new Deflater(9, false)); result = dos; dos.IsStreamOwner = false; } } break; default: throw new HfsException("Unknown compression method " + entry.CompressionMethod); } return result; }
int FindExistingUpdate(HfsEntry entry) { int result = -1; string convertedName = GetTransformedFileName(entry.Name); if (updateIndex_.ContainsKey(convertedName)) { result = (int)updateIndex_[convertedName]; } /* // This is slow like the coming of the next ice age but takes less storage and may be useful // for CF? for (int index = 0; index < updates_.Count; ++index) { HfsUpdate zu = ( HfsUpdate )updates_[index]; if ( (zu.Entry.HfsFileIndex == entry.HfsFileIndex) && (string.Compare(convertedName, zu.Entry.Name, true, CultureInfo.InvariantCulture) == 0) ) { result = index; break; } } */ return result; }
/// <summary> /// Gets an input stream for reading the given Hfs entry data in an uncompressed form. /// Normally the <see cref="HfsEntry"/> should be an entry returned by GetEntry(). /// </summary> /// <param name="entry">The <see cref="HfsEntry"/> to obtain a data <see cref="Stream"/> for</param> /// <returns>An input <see cref="Stream"/> containing data for this <see cref="HfsEntry"/></returns> /// <exception cref="ObjectDisposedException"> /// The HfsFile has already been closed /// </exception> /// <exception cref="ICSharpCode.SharpZipLib.Hfs.HfsException"> /// The compression method for the entry is unknown /// </exception> /// <exception cref="IndexOutOfRangeException"> /// The entry is not found in the HfsFile /// </exception> public Stream GetInputStream(HfsEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } if (isDisposed_) { throw new ObjectDisposedException("HfsFile"); } long index = entry.HfsFileIndex; if ((index < 0) || (index >= entries_.Length) || (entries_[index].Name != entry.Name)) { index = FindEntry(entry.Name, true); if (index < 0) { throw new HfsException("Entry cannot be found"); } } return GetInputStream(index); }
/// <summary> /// Delete a <see cref="HfsEntry"/> from the archive. /// </summary> /// <param name="entry">The entry to delete.</param> public void Delete(HfsEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } CheckUpdating(); int index = FindExistingUpdate(entry); if (index >= 0) { contentsEdited_ = true; updates_[index] = null; updateCount_ -= 1; } else { throw new HfsException("Cannot find entry to delete"); } }
/// <summary> /// Add a <see cref="HfsEntry"/> that contains no data. /// </summary> /// <param name="entry">The entry to add.</param> /// <remarks>This can be used to add directories, volume labels, or empty file entries.</remarks> public void Add(HfsEntry entry) { if (entry == null) { throw new ArgumentNullException("entry"); } CheckUpdating(); if ((entry.Size != 0) || (entry.CompressedSize != 0)) { throw new HfsException("Entry cannot have any data"); } AddUpdate(new HfsUpdate(UpdateCommand.Add, entry)); }
public HfsUpdate(IStaticDataSource dataSource, HfsEntry entry) { command_ = UpdateCommand.Add; entry_ = entry; dataSource_ = dataSource; }
public HfsUpdate(HfsEntry original, HfsEntry updated) { throw new HfsException("Modify not currently supported"); /* command_ = UpdateCommand.Modify; entry_ = ( HfsEntry )original.Clone(); outEntry_ = ( HfsEntry )updated.Clone(); */ }
/// <summary> /// Search for and read the central directory of a Hfs file filling the entries array. /// </summary> /// <exception cref="System.IO.IOException"> /// An i/o error occurs. /// </exception> /// <exception cref="ICSharpCode.SharpZipLib.Hfs.HfsException"> /// The central directory is malformed or cannot be found /// </exception> void ReadEntries() { // Search for the End Of Central Directory. When a Hfs comment is // present the directory will start earlier // // The search is limited to 64K which is the maximum size of a trailing comment field to aid speed. // This should be compatible with both SFX and Hfs files but has only been tested for Hfs files // If a SFX file has the Hfs data attached as a resource and there are other resources occuring later then // this could be invalid. // Could also speed this up by reading memory in larger blocks. if (baseStream_.CanSeek == false) { throw new HfsException("HfsFile stream must be seekable"); } long locatedEndOfCentralDir = LocateBlockWithSignature(HfsConstants.EndOfCentralDirectorySignature, baseStream_.Length, HfsConstants.EndOfCentralRecordBaseSize, 0xffff); if (locatedEndOfCentralDir < 0) { throw new HfsException("Cannot find central directory"); } // Read end of central directory record ushort thisDiskNumber = ReadLEUshort(); ushort startCentralDirDisk = ReadLEUshort(); ulong entriesForThisDisk = ReadLEUshort(); ulong entriesForWholeCentralDir = ReadLEUshort(); ulong centralDirSize = ReadLEUint(); long offsetOfCentralDir = ReadLEUint(); uint commentSize = ReadLEUshort(); if (baseStream_.Position == (baseStream_.Length - 4)) { obfuscationkey_ = (UInt32)centralDirSize * (UInt32)offsetOfCentralDir; bytekey_ = BitConverter.GetBytes(obfuscationkey_); } if (commentSize > 0) { byte[] comment = new byte[commentSize]; StreamUtils.ReadFully(baseStream_, comment); comment_ = HfsConstants.ConvertToString(comment); } else { comment_ = string.Empty; } bool isHfs64 = false; entries_ = new HfsEntry[entriesForThisDisk]; // SFX/embedded support, find the offset of the first entry vis the start of the stream // This applies to Hfs files that are appended to the end of an SFX stub. // Or are appended as a resource to an executable. // Hfs files created by some archivers have the offsets altered to reflect the true offsets // and so dont require any adjustment here... // TODO: Difficulty with Hfs64 and SFX offset handling needs resolution - maths? if (!isHfs64 && (offsetOfCentralDir < locatedEndOfCentralDir - (4 + (long)centralDirSize))) { offsetOfFirstEntry = locatedEndOfCentralDir - (4 + (long)centralDirSize + offsetOfCentralDir); if (offsetOfFirstEntry <= 0) { throw new HfsException("Invalid embedded Hfs archive"); } } baseStream_.Seek(offsetOfFirstEntry + offsetOfCentralDir, SeekOrigin.Begin); for (ulong i = 0; i < entriesForThisDisk; i++) { if (ReadLEUint() != HfsConstants.CentralHeaderSignature) { throw new HfsException("Wrong Central Directory signature"); } int versionMadeBy = ReadLEUshort(); int versionToExtract = ReadLEUshort(); int bitFlags = ReadLEUshort(); int method = ReadLEUshort(); uint dostime = ReadLEUint(); uint crc = ReadLEUint(); long csize = (long)ReadLEUint(); long size = (long)ReadLEUint(); int nameLen = ReadLEUshort(); int extraLen = ReadLEUshort(); int commentLen = ReadLEUshort(); int diskStartNo = ReadLEUshort(); // Not currently used int internalAttributes = ReadLEUshort(); // Not currently used uint externalAttributes = ReadLEUint(); long offset = ReadLEUint(); byte[] buffer = new byte[Math.Max(nameLen, commentLen)]; long position = baseStream_.Position; StreamUtils.ReadFully(baseStream_, buffer, 0, nameLen); string name = HfsConstants.ConvertToStringObfs(buffer, nameLen, (int)position); HfsEntry entry = new HfsEntry(name, versionToExtract, versionMadeBy, (CompressionMethod)method); entry.Crc = crc & 0xffffffffL; entry.Size = size & 0xffffffffL; entry.CompressedSize = csize & 0xffffffffL; entry.Flags = bitFlags; entry.DosTime = (uint)dostime; entry.HfsFileIndex = (long)i; entry.Offset = offset; entry.ExternalFileAttributes = (int)externalAttributes; if (extraLen > 0) { byte[] extra = new byte[extraLen]; StreamUtils.ReadFully(baseStream_, extra); entry.ExtraData = extra; } if (commentLen > 0) { StreamUtils.ReadFully(baseStream_, buffer, 0, commentLen); entry.Comment = HfsConstants.ConvertToStringExt(bitFlags, buffer, commentLen); } entries_[i] = entry; } }
/// <summary> /// Copy an existing entry. /// </summary> /// <param name="entry">The existing entry to copy.</param> public HfsUpdate(HfsEntry entry) : this(UpdateCommand.Copy, entry) { // Do nothing. }
/// <summary> /// Test a local header against that provided from the central directory /// </summary> /// <param name="entry"> /// The entry to test against /// </param> /// <param name="tests">The type of <see cref="HeaderTest">tests</see> to carry out.</param> /// <returns>The offset of the entries data in the file</returns> long TestLocalHeader(HfsEntry entry, HeaderTest tests) { lock (baseStream_) { bool testHeader = (tests & HeaderTest.Header) != 0; bool testData = (tests & HeaderTest.Extract) != 0; baseStream_.Seek(offsetOfFirstEntry + entry.Offset, SeekOrigin.Begin); if ((int)ReadLEUint() != HfsConstants.LocalHeaderSignature) { throw new HfsException(string.Format("Wrong local header signature @{0:X}", offsetOfFirstEntry + entry.Offset)); } short extractVersion = (short)ReadLEUshort(); short localFlags = (short)ReadLEUshort(); short compressionMethod = (short)ReadLEUshort(); short fileTime = (short)ReadLEUshort(); short fileDate = (short)ReadLEUshort(); uint crcValue = ReadLEUint(); long compressedSize = ReadLEUint(); long size = ReadLEUint(); int storedNameLength = ReadLEUshort(); int extraDataLength = ReadLEUshort(); long base_buffpos = baseStream_.Position; byte[] nameData = new byte[storedNameLength]; StreamUtils.ReadFully(baseStream_, nameData); byte[] extraData = new byte[extraDataLength]; StreamUtils.ReadFully(baseStream_, extraData); if (testData) { if (entry.IsFile) { if (!entry.IsCompressionMethodSupported()) { throw new HfsException("Compression method not supported"); } if ((extractVersion > HfsConstants.VersionMadeBy)) { throw new HfsException(string.Format("Version required to extract this entry not supported ({0})", extractVersion)); } } } if (testHeader) { if ((extractVersion <= 63) && // Ignore later versions as we dont know about them.. (extractVersion != 10) && (extractVersion != 11) && (extractVersion != 20) && (extractVersion != 21) && (extractVersion != 25) && (extractVersion != 27) && (extractVersion != 45) && (extractVersion != 46) && (extractVersion != 50) && (extractVersion != 51) && (extractVersion != 52) && (extractVersion != 61) && (extractVersion != 62) && (extractVersion != 63) ) { throw new HfsException(string.Format("Version required to extract this entry is invalid ({0})", extractVersion)); } // Central header flags match local entry flags. if (localFlags != entry.Flags) { throw new HfsException("Central header/local header flags mismatch"); } // Central header compression method matches local entry if (entry.CompressionMethod != (CompressionMethod)compressionMethod) { throw new HfsException("Central header/local header compression method mismatch"); } if (entry.Version != extractVersion) { throw new HfsException("Extract version mismatch"); } // Crc valid for empty entry. // This will also apply to streamed entries where size isnt known and the header cant be patched if ((size == 0) && (compressedSize == 0)) { if (crcValue != 0) { throw new HfsException("Invalid CRC for empty entry"); } } // TODO: make test more correct... can't compare lengths as was done originally as this can fail for MBCS strings // Assuming a code page at this point is not valid? Best is to store the name length in the HfsEntry probably if (entry.Name.Length > storedNameLength) { throw new HfsException("File name length mismatch"); } // Name data has already been read convert it and compare. string localName = HfsConstants.ConvertToStringObfs(nameData, storedNameLength, (int)base_buffpos); // Central directory and local entry name match if (localName != entry.Name) { throw new HfsException("Central header and local header file name mismatch"); } // Directories have zero actual size but can have compressed size if (entry.IsDirectory) { if (size > 0) { throw new HfsException("Directory cannot have size"); } } if (!HfsNameTransform.IsValidName(localName, true)) { throw new HfsException("Name is invalid"); } } // Tests that apply to both data and header. // Size can be verified only if it is known in the local header. // it will always be known in the central header. if (((size > 0) || (compressedSize > 0))) { if (size != entry.Size) { throw new HfsException( string.Format("Size mismatch between central header({0}) and local header({1})", entry.Size, size)); } if (compressedSize != entry.CompressedSize && compressedSize != 0xFFFFFFFF && compressedSize != -1) { throw new HfsException( string.Format("Compressed size mismatch between central header({0}) and local header({1})", entry.CompressedSize, compressedSize)); } } int extraLength = storedNameLength + extraDataLength; return offsetOfFirstEntry + entry.Offset + HfsConstants.LocalHeaderBaseSize + extraLength; } }
/// <summary> /// Get a <see cref="Stream"/> providing data for an entry. /// </summary> /// <param name="entry">The entry to provide data for.</param> /// <param name="name">The file name for data if known.</param> /// <returns>Returns a stream providing data; or null if not available</returns> public Stream GetSource(HfsEntry entry, string name) { Stream result = null; if (name != null) { result = File.Open(name, FileMode.Open, FileAccess.Read, FileShare.Read); } return result; }
int WriteCentralDirectoryHeader(HfsEntry entry) { if (entry.CompressedSize < 0) { throw new HfsException("Attempt to write central directory entry with unknown csize"); } if (entry.Size < 0) { throw new HfsException("Attempt to write central directory entry with unknown size"); } if (entry.Crc < 0) { throw new HfsException("Attempt to write central directory entry with unknown crc"); } // Write the central file header WriteLEInt(HfsConstants.CentralHeaderSignature); // Version made by WriteLEShort(HfsConstants.VersionMadeBy); // Version required to extract WriteLEShort(entry.Version); WriteLEShort(entry.Flags); unchecked { WriteLEShort((byte)entry.CompressionMethod); WriteLEInt((int)entry.DosTime); WriteLEInt((int)entry.Crc); } WriteLEInt((int)(entry.CompressedSize & 0xffffffff)); WriteLEInt((int)entry.Size); byte[] name = HfsConstants.ConvertToArray(entry.Flags, entry.Name); if (name.Length > 0xFFFF) { throw new HfsException("Entry name is too long."); } WriteLEShort(name.Length); byte[] centralExtraData = new byte[0]; WriteLEShort(centralExtraData.Length); WriteLEShort(entry.Comment != null ? entry.Comment.Length : 0); WriteLEShort(0); // disk number WriteLEShort(0); // internal file attributes // External file attributes... if (entry.ExternalFileAttributes != -1) { WriteLEInt(entry.ExternalFileAttributes); } else { if (entry.IsDirectory) { WriteLEUint(16); } else { WriteLEUint(0); } } if (entry.Offset >= 0xffffffff) { WriteLEUint(0xffffffff); } else { WriteLEUint((uint)(int)entry.Offset); } HfsXorCipher.XorBlockWithKey(name, HfsXorCipher.XorTruths, (int)baseStream_.Position); if (name.Length > 0) { baseStream_.Write(name, 0, name.Length); } if (centralExtraData.Length > 0) { baseStream_.Write(centralExtraData, 0, centralExtraData.Length); } byte[] rawComment = (entry.Comment != null) ? Encoding.ASCII.GetBytes(entry.Comment) : new byte[0]; if (rawComment.Length > 0) { baseStream_.Write(rawComment, 0, rawComment.Length); } return HfsConstants.CentralHeaderBaseSize + name.Length + centralExtraData.Length + rawComment.Length; }
/// <summary> /// Make a new <see cref="HfsEntry"/> from a name. /// </summary> /// <param name="fileName">The name of the file to create a new entry for.</param> /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param> /// <returns>Returns a new <see cref="HfsEntry"/> based on the <paramref name="fileName"/>.</returns> public HfsEntry MakeFileEntry(string fileName, bool useFileSystem) { HfsEntry result = new HfsEntry(nameTransform_.TransformFile(fileName)); int externalAttributes = 0; bool useAttributes = (setAttributes_ != 0); FileInfo fi = null; if (useFileSystem) { fi = new FileInfo(fileName); } if ((fi != null) && fi.Exists) { switch (timeSetting_) { case TimeSetting.CreateTime: result.DateTime = fi.CreationTime; break; case TimeSetting.CreateTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = fi.CreationTime.ToUniversalTime(); #else result.DateTime = fi.CreationTimeUtc; #endif break; case TimeSetting.LastAccessTime: result.DateTime = fi.LastAccessTime; break; case TimeSetting.LastAccessTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = fi.LastAccessTime.ToUniversalTime(); #else result.DateTime = fi.LastAccessTimeUtc; #endif break; case TimeSetting.LastWriteTime: result.DateTime = fi.LastWriteTime; break; case TimeSetting.LastWriteTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = fi.LastWriteTime.ToUniversalTime(); #else result.DateTime = fi.LastWriteTimeUtc; #endif break; case TimeSetting.Fixed: result.DateTime = fixedDateTime_; break; default: throw new HfsException("Unhandled time setting in MakeFileEntry"); } result.Size = fi.Length; useAttributes = true; externalAttributes = ((int)fi.Attributes & getAttributes_); } else { if (timeSetting_ == TimeSetting.Fixed) { result.DateTime = fixedDateTime_; } } if (useAttributes) { externalAttributes |= setAttributes_; result.ExternalFileAttributes = externalAttributes; } return result; }
public HfsUpdate(string fileName, HfsEntry entry) { command_ = UpdateCommand.Add; entry_ = entry; filename_ = fileName; }
public HfsEntryEnumerator(HfsEntry[] entries) { array = entries; }
/// <summary> /// Make a new <see cref="HfsEntry"/> from a name. /// </summary> /// <param name="fileName">The name of the file to create a new entry for.</param> /// <param name="useFileSystem">If true entry detail is retrieved from the file system if the file exists.</param> /// <returns>Returns a new <see cref="HfsEntry"/> based on the <paramref name="fileName"/>.</returns> public HfsEntry MakeFileEntry(string fileName, bool useFileSystem) { HfsEntry result = new HfsEntry(nameTransform_.TransformFile(fileName)); int externalAttributes = 0; bool useAttributes = (setAttributes_ != 0); FileInfo fi = null; if (useFileSystem) { fi = new FileInfo(fileName); } if ((fi != null) && fi.Exists) { switch (timeSetting_) { case TimeSetting.CreateTime: result.DateTime = fi.CreationTime; break; case TimeSetting.CreateTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = fi.CreationTime.ToUniversalTime(); #else result.DateTime = fi.CreationTimeUtc; #endif break; case TimeSetting.LastAccessTime: result.DateTime = fi.LastAccessTime; break; case TimeSetting.LastAccessTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = fi.LastAccessTime.ToUniversalTime(); #else result.DateTime = fi.LastAccessTimeUtc; #endif break; case TimeSetting.LastWriteTime: result.DateTime = fi.LastWriteTime; break; case TimeSetting.LastWriteTimeUtc: #if NETCF_1_0 || NETCF_2_0 result.DateTime = fi.LastWriteTime.ToUniversalTime(); #else result.DateTime = fi.LastWriteTimeUtc; #endif break; case TimeSetting.Fixed: result.DateTime = fixedDateTime_; break; default: throw new HfsException("Unhandled time setting in MakeFileEntry"); } result.Size = fi.Length; useAttributes = true; externalAttributes = ((int)fi.Attributes & getAttributes_); } else { if (timeSetting_ == TimeSetting.Fixed) { result.DateTime = fixedDateTime_; } } if (useAttributes) { externalAttributes |= setAttributes_; result.ExternalFileAttributes = externalAttributes; } return(result); }