public Response RemoveVolume(VolumeName request, string traceId) { if (!this.VolumeExists(request.Name)) { string errorMessage = String.Format("Attempt to remove volume {0} that does not exist.", request.Name); TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage); return(new Response(errorMessage)); } this.volumeRWLock.EnterWriteLock(); try { if (!volumeMappings.ContainsKey(request.Name)) { string errorMessage = String.Format("Mapping for volume {0} was not found.", request.Name); TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage); return(new Response(errorMessage)); } if (this.volumeMappings[request.Name].NumberOfMounts != 0) { string errorMesg = String.Format("Cannot remove volume {0} since it is in use.", request.Name); TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMesg); return(new Response(errorMesg)); } // Remove the mountpoint. try { string pathMountpoint = this.volumeMappings[request.Name].Mountpoint; if (System.IO.Directory.Exists(pathMountpoint)) { System.IO.Directory.Delete(pathMountpoint); } // Remove the metadata file string metadataFilename = Path.Combine(this.serviceContext.CodePackageActivationContext.WorkDirectory, volumesMetadata, request.Name); if (System.IO.File.Exists(metadataFilename)) { System.IO.File.Delete(metadataFilename); } } catch (Exception ex) { TraceWriter.WriteWarningWithId(Constants.TraceSource, traceId, String.Format("{0}Unable to cleanup volume artifacts due to exception: {1}", traceId, ex.Message)); } this.volumeMappings.Remove(request.Name); return(new Response()); } finally { this.volumeRWLock.ExitWriteLock(); } }
public override int GetHashCode() { unchecked { int hashCode = VolumeName != null?VolumeName.ToUpper().GetHashCode() : 0; hashCode = (hashCode * 397) ^ (FilterQuery != null ? FilterQuery.GetHashCode() : 0); hashCode = (hashCode * 397) ^ (SortOrder != null ? SortOrder.ToUpper().GetHashCode() : 0); hashCode = (hashCode * 397) ^ (Search != null ? Search.GetHashCode() : 0); return(hashCode); } }
internal async Task <string> PrepForSnapshot(SnapSession session) { try { SnapShotPutBody body = new SnapShotPutBody(); body.RunAsNames = session.RunAsName; VolumeMapping vm = new VolumeMapping(); VolumeName vname = new VolumeName(); vname.Name = session.VolumeName; vm.VolumeName = vname; FootPrintObject fp = new FootPrintObject(); fp.SVMName = session.SvmName; fp.VolAndLunsMapping = new System.Collections.Generic.List <VolumeMapping>(); fp.VolAndLunsMapping.Add(vm); body.FootPrint = new System.Collections.Generic.List <FootPrintObject>(); body.FootPrint.Add(fp); PluginParams pluginParams = new PluginParams(); pluginParams.Data = new System.Collections.Generic.List <PluginData>(); PluginData port = new PluginData(); port.Key = "PORT"; port.Value = "3306"; pluginParams.Data.Add(port); PluginData ms = new PluginData(); ms.Key = "MASTER_SLAVE"; ms.Value = "N"; pluginParams.Data.Add(ms); PluginData host = new PluginData(); host.Key = "HOST"; host.Value = session.CloneHostName; pluginParams.Data.Add(host); PluginData uid = new PluginData(); uid.Key = "CLONE_UID"; uid.Value = SnapSession.BuildCloneName(session.DbName, session.AppName); pluginParams.Data.Add(uid); body.PluginParams = pluginParams; ClientResponse <SnapBackupResponse> response = await this.SendRequestAsync <SnapBackupResponse>(Method.PUT, $"api/3.0/plugins/{session.Plugin}/resources/{session.DbKey}", body, false); log.Info($"Payload PUT data Detail: {response.Payload}"); return(response.Response.StatusCode.ToString()); } catch (Exception ex) { this.log.Error($"Error executing PUT data for snapshot of clone with key {session.DbKey}: {ex}"); throw; } }
public Response GetVolumeMountPoint(VolumeName request) { this.rwLock.EnterReadLock(); try { if (!knownVolumeMappings.ContainsKey(request.Name)) { return(new Response("volume not found")); } return(new VolumeMountResponse(this.knownVolumeMappings[request.Name].Mountpoint)); } finally { this.rwLock.ExitReadLock(); } }
internal async Task <string> CreateResource(SnapSession session) { string answer = string.Empty; try { log.Info($"Token = {this.token}"); ResourceBody body = new ResourceBody(); body.ResourceName = session.DbName; body.ResourceType = "Database"; body.HostName = session.HostName; body.RunAsNames = $"{session.DbName}_{session.Plugin}"; body.MountPaths = new System.Collections.Generic.List <MountInfo>(); MountInfo mi = new MountInfo(); mi.MountPath = session.MountPath; body.MountPaths.Add(mi); VolumeMapping vm = new VolumeMapping(); VolumeName vname = new VolumeName(); vname.Name = session.VolumeName; vm.VolumeName = vname; FootPrintObject fp = new FootPrintObject(); fp.SVMName = session.SvmName; fp.VolAndLunsMapping = new System.Collections.Generic.List <VolumeMapping>(); fp.VolAndLunsMapping.Add(vm); body.FootPrint = new System.Collections.Generic.List <FootPrintObject>(); body.FootPrint.Add(fp); PluginParams pluginParams = new PluginParams(); pluginParams.Data = new System.Collections.Generic.List <PluginData>(); PluginData ms = new PluginData(); ms.Key = "MASTER_SLAVE"; ms.Value = "N"; pluginParams.Data.Add(ms); body.PluginParams = pluginParams; var response = await this.SendRequestAsync <dynamic>(Method.POST, $"api/3.0/plugins/MySQL/resources", body, false); log.Info($"Payload: {response.Payload}"); string dbKey = string.Empty; answer = response.Response.Content.ToString(); } catch (Exception ex) { this.log.Error($"Error while getting creating resource key: {ex}"); } return(answer); }
public NtfsFileSystem(string name) : base() { DirectoryRecordCount = 1; // root folder FileRecordCount = CurrentMftRecordNumber = 0; BytesPerFileRecord = 64_000; // 64 KB VolumeSize = 20_000_000; // 20 MB BytesOccupied = 0; CreateBoot(); CreateRoot(name); VolName = new VolumeName(); char[] arr = name.ToCharArray(); Array.Reverse(arr); VolName.Name = arr.ToString(); BytesOccupied += (uint)VolName.Name.Length; //BytesRemaining = VolumeSize - BytesOccupied; }
public Response GetVolumeMountPoint(VolumeName request, string traceId) { this.volumeRWLock.EnterReadLock(); try { if (!volumeMappings.ContainsKey(request.Name)) { string errorMessage = String.Format("Mapping for volume {0} was not found.", request.Name); TraceWriter.WriteErrorWithId(Constants.TraceSource, traceId, errorMessage); return(new Response(errorMessage)); } return(new VolumeMountResponse(this.volumeMappings[request.Name].Mountpoint)); } finally { this.volumeRWLock.ExitReadLock(); } }
public Response GetVolume(VolumeName request) { this.rwLock.EnterReadLock(); try { if (!knownVolumeMappings.ContainsKey(request.Name)) { return(new VolumeGetResponse("volume not found")); } return(new VolumeGetResponse( new VolumeMountDescription() { Name = request.Name, Mountpoint = knownVolumeMappings[request.Name].Mountpoint })); } finally { this.rwLock.ExitReadLock(); } }
public FileRecord(byte[] rawBytes, int offset) { Offset = offset; var sig = BitConverter.ToInt32(rawBytes, 0); if ((sig != _fileSig) && (sig != _baadSig) && (sig != 0x0)) { Logger.Fatal($"Invalid signature! 0x{sig:X}"); return; //throw new Exception("Invalid signature!"); } if (sig == _baadSig) { Logger.Warn($"Bad signature at offset 0x{offset:X}"); return; } Attributes = new List <Attribute>(); FixupOffset = BitConverter.ToInt16(rawBytes, 2); FixupEntryCount = BitConverter.ToInt16(rawBytes, 4); LogSequenceNumber = BitConverter.ToInt64(rawBytes, 0x8); SequenceNumber = BitConverter.ToInt16(rawBytes, 0x10); ReferenceCount = BitConverter.ToInt16(rawBytes, 0x12); FirstAttributeOffset = BitConverter.ToInt16(rawBytes, 0x14); EntryFlags = (EntryFlag)BitConverter.ToInt16(rawBytes, 0x16); Logger.Trace($"Entry flags: {EntryFlags}"); ActualRecordSize = BitConverter.ToInt32(rawBytes, 0x18); AllocatedRecordSize = BitConverter.ToInt32(rawBytes, 0x1c); var entryBytes = new byte[8]; Buffer.BlockCopy(rawBytes, 0x20, entryBytes, 0, 8); MFTRecordToBaseRecord = new MftEntryInfo(entryBytes); FirstAvailableAttribueId = BitConverter.ToInt16(rawBytes, 0x28); EntryNumber = BitConverter.ToInt32(rawBytes, 0x2c); var fixupExpectedBytes = new byte[2]; var fixupActual1 = new byte[2]; var fixupActual2 = new byte[2]; Buffer.BlockCopy(rawBytes, 0x30, fixupExpectedBytes, 0, 2); Buffer.BlockCopy(rawBytes, 0x32, fixupActual1, 0, 2); Buffer.BlockCopy(rawBytes, 0x34, fixupActual2, 0, 2); //verify this record looks ok based on fixup bytes //0x1FE and 0x3fe var expectedFixupVal = BitConverter.ToInt16(fixupExpectedBytes, 0); var x1FeValue = BitConverter.ToInt16(rawBytes, 0x1FE); var x3FeValue = BitConverter.ToInt16(rawBytes, 0x3FE); if ((x1FeValue != expectedFixupVal) && ((EntryFlags & EntryFlag.FileRecordSegmentInUse) == EntryFlag.FileRecordSegmentInUse)) { Logger.Warn( $"FILE record at offset 0x{offset:X}! Fixup values do not match at 0x1FE. Expected: {expectedFixupVal}, actual: {x1FeValue}, EntryFlags: {EntryFlags}"); } if ((x3FeValue != expectedFixupVal) && ((EntryFlags & EntryFlag.FileRecordSegmentInUse) == EntryFlag.FileRecordSegmentInUse)) { Logger.Warn( $"FILE record at offset 0x{offset:X}! Fixup values do not match at 0x3FE. Expected: {expectedFixupVal}, actual: {x3FeValue}, EntryFlags: {EntryFlags}"); } //header is done, replace fixup bytes with actual bytes //0x1fe and 0x3fe should contain fixup bytes Buffer.BlockCopy(fixupActual1, 0, rawBytes, 0x1fe, 2); Buffer.BlockCopy(fixupActual2, 0, rawBytes, 0x3fe, 2); //start attribute processing at FirstAttributeOffset var index = (int)FirstAttributeOffset; while (index < ActualRecordSize) { var attrType = BitConverter.ToInt32(rawBytes, index); var attrSize = BitConverter.ToInt32(rawBytes, index + 4); // Logger.Trace( // $"ActualRecordSize: {ActualRecordSize} attrType: 0x{attrType:X}, size: {attrSize}, index: {index}, offset: 0x{offset:x}, i+o: 0x{index + offset:X}"); if ((attrSize == 0) || (attrType == -1)) { index += 8; //skip -1 type and 0 size if (EntryFlags == 0) //this is a free record { break; } continue; } var rawAttr = new byte[attrSize]; Buffer.BlockCopy(rawBytes, index, rawAttr, 0, attrSize); switch ((AttributeType)attrType) { case AttributeType.StandardInformation: var si = new StandardInfo(rawAttr); Attributes.Add(si); SILastAccessedOn = si.LastAccessedOn; SICreatedOn = si.CreatedOn; SIRecordModifiedOn = si.RecordModifiedOn; SIContentModifiedOn = si.ContentModifiedOn; break; case AttributeType.FileName: var fi = new FileName(rawAttr); Attributes.Add(fi); if ((fi.FileInfo.NameType & NameTypes.Windows) == NameTypes.Windows) { FName = fi.FileInfo.FileName; } //if (fi.FileInfo.LastAccessedOn.UtcDateTime != SILastAccessedOn.UtcDateTime) //{ FNLastAccessedOn = fi.FileInfo.LastAccessedOn; //} //if (fi.FileInfo.CreatedOn.UtcDateTime != SICreatedOn.UtcDateTime) //{ FNCreatedOn = fi.FileInfo.CreatedOn; //} //if (fi.FileInfo.RecordModifiedOn.UtcDateTime != SIRecordModifiedOn.UtcDateTime) //{ FNRecordModifiedOn = fi.FileInfo.RecordModifiedOn; //} //if (fi.FileInfo.ContentModifiedOn.UtcDateTime != SIContentModifiedOn.UtcDateTime) //{ FNContentModifiedOn = fi.FileInfo.ContentModifiedOn; //} break; case AttributeType.Data: var data = new Data(rawAttr); Attributes.Add(data); break; case AttributeType.IndexAllocation: var ia = new IndexAllocation(rawAttr); Attributes.Add(ia); break; case AttributeType.IndexRoot: var ir = new IndexRoot(rawAttr); Attributes.Add(ir); break; case AttributeType.Bitmap: var bm = new Bitmap(rawAttr); Attributes.Add(bm); break; case AttributeType.VolumeVersionObjectId: var oi = new ObjectId(rawAttr); Attributes.Add(oi); break; case AttributeType.SecurityDescriptor: var sd = new SecurityDescriptor(rawAttr); Attributes.Add(sd); break; case AttributeType.VolumeName: var vn = new VolumeName(rawAttr); Attributes.Add(vn); break; case AttributeType.VolumeInformation: var vi = new VolumeInformation(rawAttr); Attributes.Add(vi); break; case AttributeType.LoggedUtilityStream: var lus = new LoggedUtilityStream(rawAttr); Attributes.Add(lus); break; case AttributeType.ReparsePoint: var rp = new ReparsePoint(rawAttr); Attributes.Add(rp); break; case AttributeType.AttributeList: var al = new AttributeList(rawAttr); Attributes.Add(al); break; case AttributeType.Ea: //TODO Finish this var ea = new ExtendedAttribute(rawAttr); Attributes.Add(ea); break; case AttributeType.EaInformation: var eai = new ExtendedAttributeInformation(rawAttr); Attributes.Add(eai); break; default: Logger.Warn($"Unhandled attribute type! Add me: {(AttributeType) attrType}"); throw new Exception($"Add me: {(AttributeType) attrType}"); break; } index += attrSize; } SlackStartOffset = index; //rest is slack. handle here? Logger.Trace($"Slack starts at {index} i+o: 0x{index + offset:X}"); }
public Response RemoveVolume(VolumeName request) { if (!this.VolumeExists(request.Name)) { return(new Response("volume not found")); } this.rwLock.EnterWriteLock(); try { if (!knownVolumeMappings.ContainsKey(request.Name)) { return(new Response("volume not found")); } if (this.knownVolumeMappings[request.Name].MountIDs.Count != 0) { return(new Response("volume in use")); } if (!this.DoUnmount(this.knownVolumeMappings[request.Name])) { TraceWriter.WriteErrorWithId( TraceType, this.serviceContext.TraceId, "unmount during remove failed"); return(new Response("unmount failed")); } string volumesMetadataFilename = Path.Combine(volumesMetadataPath, request.Name); if (System.IO.File.Exists(volumesMetadataFilename)) { System.IO.File.Delete(volumesMetadataFilename); } else { TraceWriter.WriteWarningWithId( TraceType, this.serviceContext.TraceId, $"Remove volume {request.Name} unexpected state: volumesMetadataFilename {volumesMetadataFilename} not exists"); } string mountMetadataDirectoryPath = Path.Combine(mountMetadataPath, request.Name); if (System.IO.Directory.Exists(mountMetadataDirectoryPath)) { System.IO.Directory.Delete(mountMetadataDirectoryPath); } else { TraceWriter.WriteWarningWithId( TraceType, this.serviceContext.TraceId, $"Remove volume {request.Name} unexpected state: mountMetadataDirectoryPath {mountMetadataDirectoryPath} not exists"); } this.knownVolumeMappings.Remove(request.Name); return(new Response()); } catch (Exception e) { TraceWriter.WriteErrorWithId( TraceType, this.serviceContext.TraceId, $"Remove volume {request.Name} failed with exception {e}."); return(new Response($"Remove volume {request.Name} failed with exception {e}.")); } finally { this.rwLock.ExitWriteLock(); } }
public FileRecord(byte[] rawBytes, int offset) { Offset = offset; var sig = BitConverter.ToInt32(rawBytes, 0); switch (sig) { case FileSig: break; case BaadSig: _logger.Debug($"Bad signature at offset 0x{offset:X}"); IsBad = true; return; default: //not initialized _logger.Debug($"Uninitialized entry (no signature) at offset 0x{offset:X}"); IsUninitialized = true; return; } _logger.Debug($"Processing FILE record at offset 0x{offset:X}"); Attributes = new List <Attribute>(); FixupOffset = BitConverter.ToInt16(rawBytes, 0x4); FixupEntryCount = BitConverter.ToInt16(rawBytes, 0x6); //to build fixup info, take FixupEntryCount x 2 bytes as each are 2 bytes long var fixupTotalLength = FixupEntryCount * 2; var fixupBuffer = new byte[fixupTotalLength]; Buffer.BlockCopy(rawBytes, FixupOffset, fixupBuffer, 0, fixupTotalLength); //pull this early so we can check if its free in our fix up value messages EntryFlags = (EntryFlag)BitConverter.ToInt16(rawBytes, 0x16); FixupData = new FixupData(fixupBuffer); FixupOk = true; //fixup verification var counter = 512; foreach (var bytese in FixupData.FixupActual) { //adjust the offset to where we need to check var fixupOffset = counter - 2; var expected = BitConverter.ToInt16(rawBytes, fixupOffset); if (expected != FixupData.FixupExpected && EntryFlags != 0x0) { FixupOk = false; _logger.Warn( $"Offset: 0x{Offset:X} Entry/seq: 0x{EntryNumber:X}/0x{SequenceNumber:X} Fixup values do not match at 0x{fixupOffset:X}. Expected: 0x{FixupData.FixupExpected:X2}, actual: 0x{expected:X2}"); } //replace fixup expected with actual bytes. bytese has actual replacement values in it. Buffer.BlockCopy(bytese, 0, rawBytes, fixupOffset, 2); counter += 512; } LogSequenceNumber = BitConverter.ToInt64(rawBytes, 0x8); SequenceNumber = BitConverter.ToUInt16(rawBytes, 0x10); ReferenceCount = BitConverter.ToInt16(rawBytes, 0x12); FirstAttributeOffset = BitConverter.ToInt16(rawBytes, 0x14); ActualRecordSize = BitConverter.ToInt32(rawBytes, 0x18); AllocatedRecordSize = BitConverter.ToInt32(rawBytes, 0x1c); var entryBytes = new byte[8]; Buffer.BlockCopy(rawBytes, 0x20, entryBytes, 0, 8); MftRecordToBaseRecord = new MftEntryInfo(entryBytes); FirstAvailablAttribueId = BitConverter.ToInt16(rawBytes, 0x28); EntryNumber = BitConverter.ToUInt32(rawBytes, 0x2c); //start attribute processing at FirstAttributeOffset var index = (int)FirstAttributeOffset; while (index < ActualRecordSize) { var attrType = (AttributeType)BitConverter.ToInt32(rawBytes, index); var attrSize = BitConverter.ToInt32(rawBytes, index + 4); if (attrSize == 0 || attrType == AttributeType.EndOfAttributes) { index += 8; //skip -1 type and 0 size if (index != ActualRecordSize) { _logger.Warn($"Slack space found in entry/seq: 0x{EntryNumber:X}/0x{SequenceNumber:X}"); } //TODO process slack here? break; } _logger.Debug( $"Found Attribute Type {attrType.ToString()} at absolute offset: 0x{index + offset:X}"); _logger.Trace( $"ActualRecordSize: 0x{ActualRecordSize:X}, size: 0x{attrSize:X}, index: 0x{index:X}"); var rawAttr = new byte[attrSize]; Buffer.BlockCopy(rawBytes, index, rawAttr, 0, attrSize); switch (attrType) { case AttributeType.StandardInformation: var si = new StandardInfo(rawAttr); Attributes.Add(si); break; case AttributeType.FileName: var fi = new FileName(rawAttr); Attributes.Add(fi); break; case AttributeType.Data: var d = new Data(rawAttr); Attributes.Add(d); break; case AttributeType.IndexAllocation: var ia = new IndexAllocation(rawAttr); Attributes.Add(ia); break; case AttributeType.IndexRoot: var ir = new IndexRoot(rawAttr); Attributes.Add(ir); break; case AttributeType.Bitmap: var bm = new Bitmap(rawAttr); Attributes.Add(bm); break; case AttributeType.VolumeVersionObjectId: var oi = new ObjectId_(rawAttr); Attributes.Add(oi); break; case AttributeType.SecurityDescriptor: var sd = new SecurityDescriptor(rawAttr); Attributes.Add(sd); break; case AttributeType.VolumeName: var vn = new VolumeName(rawAttr); Attributes.Add(vn); break; case AttributeType.VolumeInformation: var vi = new VolumeInformation(rawAttr); Attributes.Add(vi); break; case AttributeType.LoggedUtilityStream: var lus = new LoggedUtilityStream(rawAttr); Attributes.Add(lus); break; case AttributeType.ReparsePoint: try { var rp = new ReparsePoint(rawAttr); Attributes.Add(rp); } catch (Exception) { var l = LogManager.GetLogger("ReparsePoint"); l.Error( $"There was an error parsing a ReparsePoint in FILE record at offset 0x{Offset:X}. Please extract via --dd and --do and send to [email protected]"); } break; case AttributeType.AttributeList: var al = new AttributeList(rawAttr); Attributes.Add(al); break; case AttributeType.Ea: var ea = new ExtendedAttribute(rawAttr); Attributes.Add(ea); break; case AttributeType.EaInformation: var eai = new ExtendedAttributeInformation(rawAttr); Attributes.Add(eai); break; default: throw new Exception($"Add me: {attrType} (0x{attrType:X})"); } index += attrSize; } //rest is slack. handle here? _logger.Trace($"Slack starts at 0x{index:X} Absolute offset: 0x{index + offset:X}"); }