public override void Init(Object Host0) { StorageUnitHost Host = (StorageUnitHost)Host0; Host.Guid = Guid.NewGuid(); Host.BlockCount = _BlockCount; Host.BlockLength = _BlockLength; Host.MaxTransferLength = MaxTransferLength; }
public RawDisk(String RawDiskFile, UInt64 BlockCount, UInt32 BlockLength) { _BlockCount = BlockCount; _BlockLength = BlockLength; if (RawDiskFile.StartsWith("\\\\?\\")) { RawDiskFile = RawDiskFile.Substring(4); } _Stream = new FileStream(RawDiskFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, 0, (int)MaxTransferLength, false); FILE_SET_SPARSE_BUFFER Sparse; UInt32 BytesTransferred; Sparse.SetSparse = true; _Sparse = DeviceIoControl(_Stream.SafeFileHandle.DangerousGetHandle(), 0x900c4 /*FSCTL_SET_SPARSE*/, ref Sparse, (UInt32)Marshal.SizeOf(Sparse), IntPtr.Zero, 0, out BytesTransferred, IntPtr.Zero); UInt64 FileSize = (UInt64)_Stream.Length; bool ZeroSize = 0 == FileSize; if (ZeroSize) { FileSize = BlockCount * BlockLength; } if (0 == FileSize || BlockCount * BlockLength != FileSize) { throw new ArgumentException(); } _Stream.SetLength((long)FileSize); if (ZeroSize) { Partition[] Partitions = new Partition[1]; Byte[] Buffer = new Byte[512]; Partitions[0].Type = 7; Partitions[0].BlockAddress = 4096 >= BlockLength ? 4096 / BlockLength : 1; Partitions[0].BlockCount = BlockCount - Partitions[0].BlockAddress; if (0 == StorageUnitHost.SpdDefinePartitionTable(Partitions, Buffer)) { _Stream.Position = 0; _Stream.Write(Buffer, 0, Buffer.Length); _Stream.Flush(); } } }
static void Main(string[] Args) { try { String RawDiskFile = null; UInt32 BlockCount = 1024 * 1024; UInt32 BlockLength = 512; String ProductId = "RawDisk-dotnet"; String ProductRevision = "1.0"; UInt32 WriteAllowed = 1; UInt32 CacheSupported = 1; UInt32 UnmapSupported = 1; UInt32 DebugFlags = 0; String DebugLogFile = null; String PipeName = null; StorageUnitHost Host = null; RawDisk RawDisk = null; int I; for (I = 0; Args.Length > I; I++) { String Arg = Args[I]; if ('-' != Arg[0]) break; switch (Arg[1]) { case '?': throw new CommandLineUsageException(); case 'c': argtol(Args, ref I, ref BlockCount); break; case 'C': argtol(Args, ref I, ref CacheSupported); break; case 'd': argtol(Args, ref I, ref DebugFlags); break; case 'D': argtos(Args, ref I, ref DebugLogFile); break; case 'f': argtos(Args, ref I, ref RawDiskFile); break; case 'i': argtos(Args, ref I, ref ProductId); break; case 'l': argtol(Args, ref I, ref BlockLength); break; case 'p': argtos(Args, ref I, ref PipeName); break; case 'r': argtos(Args, ref I, ref ProductRevision); break; case 'U': argtol(Args, ref I, ref UnmapSupported); break; case 'W': argtol(Args, ref I, ref WriteAllowed); break; default: throw new CommandLineUsageException(); } } if (Args.Length > I) throw new CommandLineUsageException(); if (null == RawDiskFile) throw new CommandLineUsageException(); if (null != DebugLogFile) if (0 != StorageUnitHost.SetDebugLogFile(DebugLogFile)) throw new CommandLineUsageException("cannot open debug log file"); Host = new StorageUnitHost(RawDisk = new RawDisk(RawDiskFile, BlockCount, BlockLength)); Host.ProductId = ProductId; Host.ProductRevisionLevel = ProductRevision; Host.WriteProtected = 0 == WriteAllowed; Host.CacheSupported = 0 != CacheSupported; Host.UnmapSupported = 0 != UnmapSupported; if (0 != Host.Start(PipeName, DebugFlags)) throw new IOException("cannot start storage unit"); StorageUnitHost.Log(StorageUnitHost.EVENTLOG_INFORMATION_TYPE, String.Format( "{0} -f {1} -c {2} -l {3} -i {4} -r {5} -W {6} -C {7} -U {8}{9}{10}", PROGNAME, RawDiskFile, BlockCount, BlockLength, ProductId, ProductRevision, 0 != WriteAllowed ? 1 : 0, 0 != CacheSupported ? 1 : 0, 0 != UnmapSupported ? 1 : 0, null != PipeName ? " -p " : "", null != PipeName ? PipeName : "")); Console.CancelKeyPress += delegate (Object Sender, ConsoleCancelEventArgs Event) { Host.Shutdown(); Event.Cancel = true; }; Host.Wait(); } catch (CommandLineUsageException ex) { StorageUnitHost.Log(StorageUnitHost.EVENTLOG_ERROR_TYPE, String.Format( "{0}" + "usage: {1} OPTIONS\n" + "\n" + "options:\n" + " -f RawDiskFile Storage unit data file\n" + " -c BlockCount Storage unit size in blocks\n" + " -l BlockLength Storage unit block length\n" + " -i ProductId 1-16 chars\n" + " -r ProductRevision 1-4 chars\n" + " -W 0|1 Disable/enable writes (deflt: enable)\n" + " -C 0|1 Disable/enable cache (deflt: enable)\n" + " -U 0|1 Disable/enable unmap (deflt: enable)\n" + " -d -1 Debug flags\n" + " -D DebugLogFile Debug log file; - for stderr\n" + " -p \\\\.\\pipe\\PipeName Listen on pipe; omit to use driver\n", ex.HasMessage ? ex.Message + "\n" : "", PROGNAME)); Environment.ExitCode = 87/*ERROR_INVALID_PARAMETER*/; } catch (Exception ex) { if (ex is TypeInitializationException && null != ex.InnerException) ex = ex.InnerException; StorageUnitHost.Log(StorageUnitHost.EVENTLOG_ERROR_TYPE, ex.Message); int hr = Marshal.GetHRForException(ex); Environment.ExitCode = Marshal.GetHRForException(ex); if ((hr & 0xffff0000) == 0x80070000) Environment.ExitCode = hr & 0xffff; else Environment.ExitCode = 574/*ERROR_UNHANDLED_EXCEPTION*/; } }