public static void DeletedRecordParserTail(NamespaceRecord ns, UInt32 dataFileNumber, UInt32 offset) { do { var dfilePath = Path.Combine(dataPath, $"{dbName}.{dataFileNumber}"); System.IO.MemoryMappedFiles.MemoryMappedFile dFile; if (!mmapFiles.ContainsKey((int)dataFileNumber)) { mmapFiles.Add((int)dataFileNumber, System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(dfilePath, System.IO.FileMode.Open)); } dFile = mmapFiles[(int)dataFileNumber]; UInt32 nextFileNumber = 0xffffffff; UInt32 nextOffset; using (var dStream = dFile.CreateViewStream(offset, 0, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.Read)) { byte[] bitbuf = new byte[8]; dStream.Read(bitbuf, 0, 4); var dataSize = BitConverter.ToUInt32(bitbuf, 0) - 0x10; dStream.Read(bitbuf, 0, 4); // discard dStream.Read(bitbuf, 0, 4); // file number nextFileNumber = BitConverter.ToUInt32(bitbuf, 0); dStream.Read(bitbuf, 0, 4); // offset nextOffset = BitConverter.ToUInt32(bitbuf, 0); byte[] BSONData = new byte[dataSize]; dStream.Read(BSONData, 0, (int)dataSize); if (BSONData.Length != 64) { //if(dataFileNumber == 7) Console.WriteLine($"BSON document @ f:{dataFileNumber}:{offset}+{dataSize}"); try { var b = BitConverter.GetBytes(dataSize); b.CopyTo(BSONData, 0); File.WriteAllBytes(Path.Combine(outputPathMethod1, $@"{OutputFile}.bson"), BSONData); OutputFile++; //ParseBSON(BSONData); } catch (Exception e) { Console.WriteLine($"Could not save BSON document: f:{dataFileNumber}:{offset}+{dataSize} - {e.Message}"); } } //var x = new MongoDB.Bson.BsonBinaryData(BSONData); //MongoDB.Bson.BsonBinaryReader } dataFileNumber = nextFileNumber; offset = nextOffset; }while (dataFileNumber != 0xffffffff); /*if () * DeletedRecordParserTail(ns, nextFileNumber, nextOffset);*/ }
public static void DeletedRecordParser(NamespaceRecord ns) { foreach (var deletedRecord in ns.DeletedRecordLocations) { Console.WriteLine($"Opening first deleted record chain: {ns.NsName}:{deletedRecord.FileNumber}:{deletedRecord.Offset}"); DeletedRecordParserTail(ns, deletedRecord.FileNumber, deletedRecord.Offset); } }
public static void Method1() { List <NamespaceRecord> nsRecords = new List <NamespaceRecord>(); using (var nsFile = System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile(System.IO.Path.Combine(dataPath, nsFileName), System.IO.FileMode.Open)) using (var nsStream = nsFile.CreateViewStream(0, 0, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.Read)) { var nsBuffer = new byte[1024 * 1024 * 1024]; var readCount = nsStream.Read(nsBuffer, 0, nsBuffer.Length); if (readCount == 0) { Console.WriteLine("I think we reached EOF!"); } var targetNsBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(targetNs); //targetNsBuffer = new byte[5] { 0, 0, 0 ,0 ,0}; int offset = 0; for (var i = 0; i < nsBuffer.Length; i++) { if (nsBuffer[i] == targetNsBuffer[0]) { offset = i; bool matched = true; for (var j = 0; j < targetNsBuffer.Length; j++) { if (nsBuffer[i + j] != targetNsBuffer[j]) { matched &= false; break; } } if (matched) { using (var nsView = nsFile.CreateViewStream(offset - 4, 0x158, System.IO.MemoryMappedFiles.MemoryMappedFileAccess.Read)) { byte[] bitbuf = new byte[8]; int pos = 0; var ns = new NamespaceRecord(); nsView.Read(ns.NsHash, 0, 4); pos += 4; nsView.Read(ns.NsNameArray, 0, 128); pos += 128; ns.NsName = System.Text.ASCIIEncoding.ASCII.GetString(ns.NsNameArray, 0, 128).Trim(new char[] { '\0' }); nsView.Read(bitbuf, 0, 8); ns.ExtentFirstFile = BitConverter.ToUInt32(bitbuf, 0); ns.ExtentFirst = BitConverter.ToUInt32(bitbuf, 4); nsView.Read(bitbuf, 0, 8); ns.ExtentLastFile = BitConverter.ToUInt32(bitbuf, 0); ns.ExtentLast = BitConverter.ToUInt32(bitbuf, 4); // deleted records for (int dri = 0; dri < 19; dri++) { nsView.Read(bitbuf, 0, 8); var del = new DeletedRecordLocation() { FileNumber = BitConverter.ToUInt32(bitbuf, 0), Offset = BitConverter.ToUInt32(bitbuf, 4) }; if (del.FileNumber != 0xffffffff) { ns.DeletedRecordLocations.Add(del); } } nsView.Read(bitbuf, 0, 8); ns.DataSize = BitConverter.ToUInt64(bitbuf, 0); nsView.Read(bitbuf, 0, 8); ns.RecordCount = BitConverter.ToUInt64(bitbuf, 0); nsView.Read(bitbuf, 0, 4); ns.SizeOfLastExtent = BitConverter.ToUInt32(bitbuf, 0); nsView.Read(bitbuf, 0, 4); ns.IndexCount = BitConverter.ToUInt32(bitbuf, 0); nsView.Read(ns.IndexData, 0, 304); offset -= 4; ns.Offset = (uint)offset; nsRecords.Add(ns); Console.WriteLine($"found namespace at offset: {offset}"); Console.WriteLine($"Name: {ns.NsName.Replace(targetNs + ".", "")}"); if (outputNamespaceInfo || ns.NsName.EndsWith(".chunks") || ns.NsName.EndsWith(".files")) { Console.WriteLine($"ExtentFirstFile: {ns.ExtentFirstFile}"); Console.WriteLine($"ExtentFirstOffset: {ns.ExtentFirst}"); Console.WriteLine($"ExtentLastFile: {ns.ExtentLastFile}"); Console.WriteLine($"ExtentLastOffset: {ns.ExtentLast}"); Console.WriteLine($"DataSize: {ns.DataSize}"); Console.WriteLine($"RecordCt: {ns.RecordCount}"); Console.WriteLine($"Last Ext Size: {ns.SizeOfLastExtent}"); Console.WriteLine($"Index Ct: {ns.IndexCount}"); Console.WriteLine("Deleted Records:"); foreach (var d in ns.DeletedRecordLocations) { Console.WriteLine($"File: {d.FileNumber}, Offset = {d.Offset}"); } if (pauseAfterEachNs) { Console.ReadLine(); } Console.WriteLine(); } } } } /* * if(match) * { * * match = false; * }*/ } } Console.WriteLine("Namespace search complete."); foreach (var ns in nsRecords.Where(n => n.NsName.EndsWith(".chunks.$_id_"))) { DeletedRecordParser(ns); } Console.WriteLine("Done with method 1 ;-;"); //Console.ReadLine(); }