/// <summary> /// Reads the entire backup file and returns a root catalog node. /// The root node contains backup sets/volumes/directories/files /// as child nodes. /// </summary> public CCatalogNode ReadCatalog() { // Set to true to cancel reading mCancel = false; // Read the media header CTapeHeaderDescriptorBlock tape = (CTapeHeaderDescriptorBlock)mStream.ReadDBLK(); // Read soft file mark CSoftFilemarkDescriptorBlock file = (CSoftFilemarkDescriptorBlock)mStream.ReadDBLK(); // Create the root catalog node CCatalogNode node = new CCatalogNode(tape.MediaName, ENodeType.Root, 0); CCatalogNode nLastSet = null; CCatalogNode nLastVolume = null; CCatalogNode nLastDir = null; // Get next block type EBlockType bt = mStream.PeekNextBlockType(); while ((bt != EBlockType.MTF_EOTM) && (bt != 0) && (mCancel == false)) { // Read next block CDescriptorBlock block = mStream.ReadDBLK(); // Add to catalog if (bt == EBlockType.MTF_SSET) { CStartOfDataSetDescriptorBlock sset = (CStartOfDataSetDescriptorBlock)block; CCatalogNode cnode = node.AddSet("Set: " + sset.DataSetNumber + " - " + sset.DataSetName, block.StartPosition); nLastSet = cnode; } else if (bt == EBlockType.MTF_VOLB) { CVolumeDescriptorBlock vol = (CVolumeDescriptorBlock)block; CCatalogNode cnode = nLastSet.AddVolume(vol.DeviceName, block.StartPosition); nLastVolume = cnode; } else if (bt == EBlockType.MTF_DIRB) { CDirectoryDescriptorBlock dir = (CDirectoryDescriptorBlock)block; // Check if the directory name is contained in a data stream CCatalogNode cnode = null; if ((dir.DIRBAttributes & EDIRBAttributes.DIRB_PATH_IN_STREAM_BIT) != 0) { foreach (CDataStream data in dir.Streams) { if (data.Header.StreamID == "PNAM") { if (dir.StringType == EStringType.ANSI) { System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); string str = encoding.GetString(data.Data); str = str.Substring(0, str.Length - 1); cnode = nLastVolume.AddFolder(str, block.StartPosition); } else if (dir.StringType == EStringType.Unicode) { System.Text.UnicodeEncoding encoding = new System.Text.UnicodeEncoding(); string str = encoding.GetString(data.Data); str = str.Substring(0, str.Length - 1); cnode = nLastVolume.AddFolder(str, block.StartPosition); } } } } else { cnode = nLastVolume.AddFolder(dir.DirectoryName.Substring(0, dir.DirectoryName.Length - 1), block.StartPosition); } if (cnode != null) { nLastDir = cnode; } } else if (bt == EBlockType.MTF_FILE) { CFileDescriptorBlock fil = (CFileDescriptorBlock)block; // Check if the file name is contained in a data stream CCatalogNode cnode = null; if ((fil.FileAttributes & EFileAttributes.FILE_NAME_IN_STREAM_BIT) != 0) { foreach (CDataStream data in fil.Streams) { if (data.Header.StreamID == "FNAM") { if (fil.StringType == EStringType.ANSI) { System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); string str = encoding.GetString(data.Data); cnode = nLastDir.AddFile(str, block.StartPosition); } else if (fil.StringType == EStringType.Unicode) { System.Text.UnicodeEncoding encoding = new System.Text.UnicodeEncoding(); string str = encoding.GetString(data.Data); cnode = nLastDir.AddFile(str, block.StartPosition); } } } } else { cnode = nLastDir.AddFile(fil.FileName, block.StartPosition); } } // Get next block type bt = mStream.PeekNextBlockType(); // Check progress if (mStream.BaseStream.Position > mLastPos + mIncrement) { mLastPos = mStream.BaseStream.Position; OnProgressChange((int)((float)mLastPos / (float)mStream.BaseStream.Length * 100.0f)); } } return(node); }
/// <summary> /// Reads the entire backup file and returns a root catalog node. /// The root node contains backup sets/volumes/directories/files /// as child nodes. /// </summary> public CCatalogNode ReadCatalog() { // Set to true to cancel reading mCancel = false; // Read the media header var tapeHeaderDescriptorBlock = (CTapeHeaderDescriptorBlock)mStream.ReadDBLK(); // Read soft file mark var filemarkDescriptorBlock = (CSoftFilemarkDescriptorBlock)mStream.ReadDBLK(); // Create the root catalog node var node = new CCatalogNode(tapeHeaderDescriptorBlock, tapeHeaderDescriptorBlock.MediaName, ENodeType.Root); CCatalogNode lastSetNode = null; CCatalogNode lastVolumeNode = null; CCatalogNode lastFolderNode = null; // Get next block type var blockType = mStream.PeekNextBlockType(); while ((blockType != EBlockType.MTF_EOTM) && (blockType != 0) && (mCancel == false)) { // Read next block var block = mStream.ReadDBLK(); // Add to catalog if (blockType == EBlockType.MTF_SSET) { var dataSetDescriptorBlock = (CStartOfDataSetDescriptorBlock)block; var cnode = node.AddSet(dataSetDescriptorBlock); lastSetNode = cnode; } else if (blockType == EBlockType.MTF_VOLB) { var volumeDescriptorBlock = (CVolumeDescriptorBlock)block; var cnode = lastSetNode.AddVolume(volumeDescriptorBlock); lastVolumeNode = cnode; } else if (blockType == EBlockType.MTF_DIRB) { var directoryDescriptorBlock = (CDirectoryDescriptorBlock)block; // Check if the directory name is contained in a data stream CCatalogNode cnode = null; if ((directoryDescriptorBlock.DIRBAttributes & EDIRBAttributes.DIRB_PATH_IN_STREAM_BIT) != 0) { foreach (CDataStream data in directoryDescriptorBlock.Streams) { if (data.Header.StreamID == "PNAM") { if (directoryDescriptorBlock.StringType == EStringType.ANSI) { System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); var folderName = encoding.GetString(data.Data); folderName = folderName.Substring(0, folderName.Length - 1); cnode = lastVolumeNode.AddFolder(directoryDescriptorBlock, folderName); } else if (directoryDescriptorBlock.StringType == EStringType.Unicode) { System.Text.UnicodeEncoding encoding = new System.Text.UnicodeEncoding(); var folderName = encoding.GetString(data.Data); folderName = folderName.Substring(0, folderName.Length - 1); cnode = lastVolumeNode.AddFolder(directoryDescriptorBlock, folderName); } } } } else { var folderName = directoryDescriptorBlock.DirectoryName.Substring(0, directoryDescriptorBlock.DirectoryName.Length - 1); cnode = lastVolumeNode.AddFolder(directoryDescriptorBlock, folderName); } if (cnode != null) { lastFolderNode = cnode; } } else if (blockType == EBlockType.MTF_FILE) { var fileDescriptorBlock = (CFileDescriptorBlock)block; // Check if the file name is contained in a data stream CCatalogNode cnode = null; if ((fileDescriptorBlock.FileAttributes & EFileAttributes.FILE_NAME_IN_STREAM_BIT) != 0) { foreach (var data in fileDescriptorBlock.Streams) { if (data.Header.StreamID == "FNAM") { if (fileDescriptorBlock.StringType == EStringType.ANSI) { System.Text.ASCIIEncoding encoding = new System.Text.ASCIIEncoding(); var fileName = encoding.GetString(data.Data); lastFolderNode.AddFile(fileDescriptorBlock, fileName); } else if (fileDescriptorBlock.StringType == EStringType.Unicode) { System.Text.UnicodeEncoding encoding = new System.Text.UnicodeEncoding(); var fileName = encoding.GetString(data.Data); lastFolderNode.AddFile(fileDescriptorBlock, fileName); } } } } else { lastFolderNode.AddFile(fileDescriptorBlock, fileDescriptorBlock.FileName); } } else if (blockType == EBlockType.MTF_DBDB) { var databaseDescriptorBlock = (CDatabaseDescriptorBlock)block; var cnode = lastVolumeNode.AddDatabase(databaseDescriptorBlock); //lastVolumeNode = cnode; } // Get next block type blockType = mStream.PeekNextBlockType(); // Check progress if (mStream.BaseStream.Position > mLastPos + mIncrement) { mLastPos = mStream.BaseStream.Position; OnProgressChange((int)(mLastPos / (float)mStream.BaseStream.Length * 100.0f)); } } return(node); }