public PrimaryVolumeDescriptor(Hardware.Devices.DiskDevice disk, uint startBlock, uint numBlocks, byte[] data) : base(disk, startBlock, numBlocks, data) { SystemIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 8, 32); VolumeIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 40, 32); VolumeSpaceSize = ByteConverter.ToUInt32(data, 80); VolumeSetSize = ByteConverter.ToUInt16(data, 120); VolumeSequenceNumber = ByteConverter.ToUInt16(data, 124); LogicalBlockSize = ByteConverter.ToUInt16(data, 128); PathTableSize = ByteConverter.ToUInt32(data, 132); Location_PathTable_TypeL = ByteConverter.ToUInt32(data, 140); Location_PathTable_Optional_TypeL = ByteConverter.ToUInt32(data, 144); RootDirectory = new DirectoryRecord(data, 156, true); VolumeSetIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 190, 128); PublisherIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 318, 128); DataPreparerIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 446, 128); ApplicationIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 574, 128); CopyrightFileIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 702, 38); AbstractFileIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 740, 36); BibliographicFileIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 776, 37); VolumeCreationDateTime = new DateTime(data, 813); VolumeModificationDateTime = new DateTime(data, 830); VolumeExpirationDateTime = new DateTime(data, 847); VolumeEffectiveDateTime = new DateTime(data, 864); FileStructureVersion = data[881]; }
public FOS_System.String TrimEnd() { // All characters in the Zs, Zp and Zl Unicode categories, plus U+0009 CHARACTER TABULATION, U+000A LINE FEED, U+000B LINE TABULATION, U+000C FORM FEED, U+000D CARRIAGE RETURN and U+0085 NEXT LINE FOS_System.String TrimChars = "\u0009\u000A\u000B\u000C\u000D\u0020\u0085\u00A0\u1680\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u2028\u2029\u202F\u205F\u3000"; int removeEnd = 0; for (int i = this.length - 1; i > -1; removeEnd++, i--) { bool ShouldBreak = true; for (int j = 0; j < TrimChars.length; j++) { if (this[i] == TrimChars[j]) { ShouldBreak = false; } } if (ShouldBreak) { break; } } FOS_System.String result = New(this.length - removeEnd); for (int i = 0; i < this.length - removeEnd; i++) { result[i] = this[i]; } return(result); }
/// <summary> /// Attempts to find the specified directory within any file system. /// </summary> /// <param name="directoryName">The full path and name of the directory to find.</param> /// <returns>The directory or null if it isn't found.</returns> public static Directory Find(FOS_System.String directoryName) { FileSystemMapping theMapping = FileSystemManager.GetMapping(directoryName); if (theMapping == null) { return(null); } directoryName = theMapping.RemoveMappingPrefix(directoryName); directoryName = directoryName.ToUpper(); Base baseListing = theMapping.TheFileSystem.GetListing(directoryName); if (baseListing == null) { return(null); } else { if (baseListing is Directory) { return((Directory)baseListing); } else { return(null); } } }
public static void DBGERR(FOS_System.String testName, FOS_System.String msg) { BasicConsole.SetTextColour(BasicConsole.error_colour); DBGMSG(testName, msg); BasicConsole.SetTextColour(BasicConsole.default_colour); errors++; }
public VolumeDescriptor(Hardware.Devices.DiskDevice disk, uint startBlock, uint numBlocks, byte[] data) : base(disk, 0, 0) { Code = (TypeCodes)data[0]; Id = ByteConverter.GetASCIIStringFromASCII(data, 1, 5); Version = data[6]; }
private static void EnterCritical(FOS_System.String caller) { //BasicConsole.WriteLine("Entering critical section..."); if (AccessLockInitialised) { if (AccessLock == null) { BasicConsole.WriteLine("HeapAccessLock is initialised but null?!"); BasicConsole.DelayOutput(10); } else { if (AccessLock.Locked && OutputTrace) { BasicConsole.SetTextColour(BasicConsole.warning_colour); BasicConsole.WriteLine("Warning: Heap about to try to re-enter spin lock..."); BasicConsole.Write("Enter lock caller: "); BasicConsole.WriteLine(caller); BasicConsole.SetTextColour(BasicConsole.default_colour); } AccessLock.Enter(); } } //else //{ // BasicConsole.WriteLine("HeapAccessLock not initialised - ignoring lock conditions."); // BasicConsole.DelayOutput(5); //} }
public virtual Thread CreateThread(ThreadStartMethod MainMethod, FOS_System.String Name) { #if PROCESS_TRACE BasicConsole.WriteLine("Process: CreateThread: Creating thread..."); #endif //TODO: Wrap EnableKernelAccessToProcessMemory in try-finally blocks // Required so that page allocations by new Thread don't create conflicts ProcessManager.EnableKernelAccessToProcessMemory(this); Thread newThread = new Thread(this, MainMethod, ThreadIdGenerator++, UserMode, Name); #if PROCESS_TRACE BasicConsole.WriteLine("Adding data page..."); #endif // Add the page to the processes memory layout uint threadStackVirtAddr = (uint)newThread.State->ThreadStackTop - 4092; uint threadStackPhysAddr = (uint)VirtMemManager.GetPhysicalAddress(newThread.State->ThreadStackTop - 4092); TheMemoryLayout.AddDataPage(threadStackPhysAddr, threadStackVirtAddr); ProcessManager.DisableKernelAccessToProcessMemory(this); #if PROCESS_TRACE BasicConsole.WriteLine("Adding thread..."); #endif Threads.Add(newThread); if (Registered) { Scheduler.InitThread(this, newThread); } return(newThread); }
/// <summary> /// Initializes a new base listing. /// </summary> /// <param name="aFileSystem">The file system to which the listing belongs.</param> /// <param name="parent">The parent directory of the listing.</param> /// <param name="aName">The name of the listing.</param> /// <param name="isDirectory">Whether the listing is a directory or not.</param> protected Base(FileSystem aFileSystem, Directory parent, FOS_System.String aName, bool isDirectory) { TheFileSystem = aFileSystem; Name = aName; IsDirectory = isDirectory; Parent = parent; }
public FOS_System.String ToString() { FOS_System.String result = ""; result = result + "Code pages:\r\n"; UInt32Dictionary.Iterator iterator = CodePages.GetIterator(); while (iterator.HasNext()) { UInt32Dictionary.KeyValuePair pair = iterator.Next(); uint vAddr = pair.Key; uint pAddr = pair.Value; result = result + vAddr + " -> " + pAddr + "\r\n"; } result = result + "\r\n"; result = result + "Data pages:\r\n"; iterator = DataPages.GetIterator(); while (iterator.HasNext()) { UInt32Dictionary.KeyValuePair pair = iterator.Next(); uint vAddr = pair.Key; uint pAddr = pair.Value; result = result + vAddr + " -> " + pAddr + "\r\n"; } return(result); }
public FOS_System.String ToString() { FOS_System.String result = ""; result = result + "Code pages:\r\n"; for (int i = 0; i < CodePages.Keys.Count; i++) { uint vAddr = CodePages.Keys[i]; uint pAddr = CodePages[vAddr]; result = result + vAddr + " -> " + pAddr + "\r\n"; } result = result + "\r\n"; result = result + "Data pages:\r\n"; for (int i = 0; i < DataPages.Keys.Count; i++) { uint vAddr = DataPages.Keys[i]; uint pAddr = DataPages[vAddr]; result = result + vAddr + " -> " + pAddr + "\r\n"; } return(result); }
public virtual Thread CreateThread(ThreadStartMethod MainMethod, FOS_System.String Name) { #if PROCESS_TRACE BasicConsole.WriteLine("Creating thread..."); #endif Thread newThread = new Thread(this, MainMethod, ThreadIdGenerator++, UserMode, Name); #if PROCESS_TRACE BasicConsole.WriteLine("Adding data page..."); #endif // Add the page to the processes memory layout uint threadStackVirtAddr = (uint)newThread.State->ThreadStackTop - 4092; uint threadStackPhysAddr = (uint)VirtMemManager.GetPhysicalAddress(newThread.State->ThreadStackTop - 4092); TheMemoryLayout.AddDataPage(threadStackPhysAddr, threadStackVirtAddr); if (ProcessManager.KernelProcess != null) { ProcessManager.KernelProcess.TheMemoryLayout.AddDataPage(threadStackPhysAddr, threadStackVirtAddr); } #if PROCESS_TRACE BasicConsole.WriteLine("Adding thread..."); #endif Threads.Add(newThread); if (Registered) { Scheduler.InitThread(this, newThread); } return(newThread); }
public void Write(FOS_System.String str) { for (int i = 0; i < str.length; i++) { Write((byte)str[i]); } }
/// <summary> /// Parses a string as an unsigned hexadecimal integer. /// </summary> /// <param name="str">The string to parse.</param> /// <param name="offset">The offset into the string at which to start parsing.</param> /// <returns>The parsed uint.</returns> public static uint Parse_HexadecimalUnsigned(FOS_System.String str, int offset) { str = str.ToLower(); if (str.length - offset >= 2) { if (str[offset] == '0' && str[offset + 1] == 'x') { offset += 2; } } uint result = 0; for (int i = offset; i < str.length; i++) { char c = str[i]; if ((c < '0' || c > '9') && (c < 'a' || c > 'f')) { break; } result *= 16; if (c >= '0' && c <= '9') { result += (uint)(c - '0'); } else { result += (uint)(c - 'a') + 10; } } return(result); }
/// <summary> /// Opens the specified file. /// </summary> /// <param name="fileName">The full path to the file to open.</param> /// <returns>The file listing or null if not found.</returns> public static File Open(FOS_System.String fileName) { FileSystemMapping theMapping = FileSystemManager.GetMapping(fileName); if (theMapping == null) { return(null); } fileName = theMapping.RemoveMappingPrefix(fileName); fileName = fileName.ToUpper(); Base baseListing = theMapping.TheFileSystem.GetListing(fileName); if (baseListing == null) { return(null); } else { if (baseListing is File) { return((File)baseListing); } else { return(null); } } }
public static Process CreateProcess(ThreadStartMethod MainMethod, FOS_System.String Name, bool UserMode, bool CreateHeap) { #if PROCESSMANAGER_TRACE BasicConsole.WriteLine("Creating process object..."); #endif return(new Process(MainMethod, ProcessIdGenerator++, Name, UserMode, CreateHeap)); }
public FOS_System.String PadLeft(int totalLength, char padChar) { FOS_System.String result = New(totalLength); if (this.length >= totalLength) { for (int i = 0; i < result.length; i++) { result[i] = this[i]; } return(result); } int offset = totalLength - this.length; for (int i = 0; i < this.length; i++) { result[i + offset] = this[i]; } for (int i = 0; i < offset; i++) { result[i] = padChar; } return(result); }
/// <summary> /// Initializes a new FAT directory. /// </summary> /// <param name="aFileSystem">The FAT file system to which the directory belongs.</param> /// <param name="parent">The FAT directory which is the parent of the directory. Null for the root directory.</param> /// <param name="aName">The name of the directory.</param> /// <param name="aFirstCluster">The first cluster number of the directory.</param> public FATDirectory(FATFileSystem aFileSystem, FATDirectory parent, FOS_System.String aName, UInt32 aFirstCluster) : base(aFileSystem, parent, aName) { _theFile = new FATFile(aFileSystem, parent, Name, 0, aFirstCluster) { IsDirectoryFile = true }; }
public uint GetSymbolAddress(ELFDynamicSymbolTableSection.Symbol theSymbol, FOS_System.String theSymbolName) { uint address = 0; uint size = 0; GetSymbolAddressAndSize(theSymbol, theSymbolName, ref address, ref size); return(address); }
/// <summary> /// Initialises new partition information using the specified data. /// </summary> /// <param name="data">The data to read the partition info from.</param> /// <param name="offset">The offset in the data at which to start reading.</param> /// <param name="entrySize">The size of a partition entry.</param> public PartitionInfo(byte[] data, uint offset, uint entrySize) { //There is an underlying assumption here that the // supplied data is of sufficient length (including the // extra length required for any specified offset). //TODO: Check the entry size is valid //TODO: Throw an exception if data.length + offset < entrySize //Copy in Type ID data TypeID[0] = data[offset + 0]; TypeID[1] = data[offset + 1]; TypeID[2] = data[offset + 2]; TypeID[3] = data[offset + 3]; TypeID[4] = data[offset + 4]; TypeID[5] = data[offset + 5]; TypeID[6] = data[offset + 6]; TypeID[7] = data[offset + 7]; TypeID[8] = data[offset + 8]; TypeID[9] = data[offset + 9]; TypeID[10] = data[offset + 10]; TypeID[11] = data[offset + 11]; TypeID[12] = data[offset + 12]; TypeID[13] = data[offset + 13]; TypeID[14] = data[offset + 14]; TypeID[15] = data[offset + 15]; //Copy in the partition ID data ID[0] = data[offset + 16]; ID[1] = data[offset + 17]; ID[2] = data[offset + 18]; ID[3] = data[offset + 19]; ID[4] = data[offset + 20]; ID[5] = data[offset + 21]; ID[6] = data[offset + 22]; ID[7] = data[offset + 23]; ID[8] = data[offset + 24]; ID[9] = data[offset + 25]; ID[10] = data[offset + 26]; ID[11] = data[offset + 27]; ID[12] = data[offset + 28]; ID[13] = data[offset + 29]; ID[14] = data[offset + 30]; ID[15] = data[offset + 31]; //Parse the other partition data FirstLBA = ByteConverter.ToUInt32(data, offset + 32); LastLBA = ByteConverter.ToUInt32(data, offset + 40); Attributes = ByteConverter.ToUInt32(data, offset + 48); Name = ByteConverter.GetASCIIStringFromUTF16(data, offset + 56, 36).Trim(); #if GPT_TRACE BasicConsole.WriteLine(((FOS_System.String) "First LBA : ") + FirstLBA); BasicConsole.WriteLine(((FOS_System.String) "Last LBA : ") + LastLBA); BasicConsole.WriteLine(((FOS_System.String) "Attributes : ") + Attributes); BasicConsole.WriteLine(((FOS_System.String) "Name : ") + Name); #endif }
public static void Disable(FOS_System.String caller) { //BasicConsole.Write(caller); //BasicConsole.WriteLine(" disabling GC."); //BasicConsole.DelayOutput(2); lastDisabler = caller; GC.Enabled = false; }
public static byte[] GetASCIIBytes(FOS_System.String asciiString) { byte[] result = new byte[asciiString.length]; for (int i = 0; i < asciiString.length; i++) { result[i] = (byte)asciiString[i]; } return(result); }
public static void *AllocZeroed(UInt32 size, UInt32 boundary, FOS_System.String caller) { void *result = Alloc(size, boundary, caller); if (result == null) { return(null); } return(Utilities.MemoryUtils.ZeroMem(result, size)); }
public DateTime(byte[] data, uint offset) { Year = ByteConverter.GetASCIIStringFromASCII(data, offset + 0, 4); Month = ByteConverter.GetASCIIStringFromASCII(data, offset + 4, 2).TrimEnd().PadLeft(2, '0'); Day = ByteConverter.GetASCIIStringFromASCII(data, offset + 6, 2).TrimEnd().PadLeft(2, '0'); Hour = ByteConverter.GetASCIIStringFromASCII(data, offset + 8, 2).TrimEnd().PadLeft(2, '0'); Minute = ByteConverter.GetASCIIStringFromASCII(data, offset + 10, 2).TrimEnd().PadLeft(2, '0'); Second = ByteConverter.GetASCIIStringFromASCII(data, offset + 12, 2).TrimEnd().PadLeft(2, '0'); HundrethsSecond = ByteConverter.GetASCIIStringFromASCII(data, offset + 14, 2); Timezone = data[offset + 16]; }
/// <summary> /// Parses a string as an signed decimal integer. /// </summary> /// <param name="str">The string to parse.</param> /// <returns>The parsed int.</returns> public static int Parse_DecimalSigned(FOS_System.String str) { bool neg = str.StartsWith("-"); int result = (int)Parse_DecimalUnsigned(str, (neg ? 1 : 0)); if (neg) { result *= -1; } return(result); }
/// <summary> /// Deletes the specified file within the file system. /// </summary> /// <param name="name">The name of the file to delete.</param> /// <returns>True if the file was found and deleted. Otherwise, false.</returns> public static bool Delete(FOS_System.String name) { File theFile = Open(name); if (theFile == null) { return(false); } return(theFile.Delete()); }
public FOS_System.String ToString() { FOS_System.String result = ""; for (int i = 0; i < ImplicitHeap.Count; i++) { result += ((FOS_System.String)((Comparable)ImplicitHeap[i]).Key).PadRight(20, ' '); } return(result); }
/// <summary> /// Deletes the specified directory within the file system. /// </summary> /// <param name="name">The name of the directory to delete.</param> /// <returns>True if the directory was found and deleted. Otherwise, false.</returns> public static bool Delete(FOS_System.String name) { Directory theDir = Find(name); if (theDir == null) { return(false); } return(theDir.Delete()); }
/// <summary> /// Determines whether the specified listing exists or not within this directory or its sub-directories. /// </summary> /// <param name="name">The full path and name of the listing to check for.</param> /// <param name="listings">The list of listings to search through.</param> /// <returns>Whether the listing exists or not.</returns> public static bool ListingExists(FOS_System.String name, List listings) { for (int i = 0; i < listings.Count; i++) { if (((Base)listings[i]).Name == name) { return(true); } } return(false); }
public FOS_System.String this[uint offset] { get { FOS_System.String currString = ""; if (offset < data.Length) { currString = ByteConverter.GetASCIIStringFromASCII(data, offset, (uint)(data.Length - offset)); } return(currString); } }
public static unsafe FOS_System.String Concat(FOS_System.String str1, FOS_System.String str2) { FOS_System.String newStr = New(str1.length + str2.length); for (int i = 0; i < str1.length; i++) { newStr[i] = str1[i]; } for (int i = 0; i < str2.length; i++) { newStr[i + str1.length] = str2[i]; } return(newStr); }
public Process(ThreadStartMethod MainMethod, uint AnId, FOS_System.String AName, bool userMode) { #if PROCESS_TRACE BasicConsole.WriteLine("Constructing process object..."); #endif Id = AnId; Name = AName; UserMode = userMode; #if PROCESS_TRACE BasicConsole.WriteLine("Creating thread..."); #endif CreateThread(MainMethod); }
/// <summary> /// Creates a new exception with specified message. /// </summary> /// <param name="aMessage">The exception message.</param> public Exception(FOS_System.String aMessage) : base() { Message = aMessage; }
public Thread(Process AnOwner, ThreadStartMethod StartMethod, uint AnId, bool UserMode, FOS_System.String AName) { #if THREAD_TRACE BasicConsole.WriteLine("Constructing thread object..."); #endif LastActiveState = ActiveStates.NotStarted; Owner = AnOwner; //Init thread state #if THREAD_TRACE BasicConsole.WriteLine("Allocating state memory..."); #endif State = (ThreadState*)FOS_System.Heap.Alloc((uint)sizeof(ThreadState), "Thread : Thread() (1)"); // Init Id and EIP // Set EIP to the first instruction of the main method #if THREAD_TRACE BasicConsole.WriteLine("Setting thread info..."); #endif Id = AnId; Name = AName; State->StartEIP = (uint)Utilities.ObjectUtilities.GetHandle(StartMethod); // Allocate kernel memory for the kernel stack for this thread // Used when this thread is preempted or does a sys call. Stack is switched to // this thread-specific kernel stack #if THREAD_TRACE BasicConsole.WriteLine("Allocating kernel stack..."); #endif // TODO: Allocate using virt mem manager not the heap (see ThreadStackTop below) State->KernelStackTop = (byte*)FOS_System.Heap.Alloc(0x1000, 4) + 0xFFC; //4KiB, 4-byte aligned // Allocate free memory for the user stack for this thread // Used by this thread in normal execution #if THREAD_TRACE BasicConsole.WriteLine("Mapping thread stack page..."); #endif State->UserMode = UserMode; State->ThreadStackTop = (byte*)Hardware.VirtMemManager.MapFreePage( UserMode ? Hardware.VirtMem.VirtMemImpl.PageFlags.None : Hardware.VirtMem.VirtMemImpl.PageFlags.KernelOnly) + 4092; //4 KiB, page-aligned // Set ESP to the top of the stack - 4 byte aligned, high address since x86 stack works // downwards #if THREAD_TRACE BasicConsole.WriteLine("Setting ESP..."); #endif State->ESP = (uint)State->ThreadStackTop; // TimeToRun and TimeToRunReload are set up in Scheduler.InitProcess which // is called when a process is registered. // Init SS // Stack Segment = User or Kernel space data segment selector offset // Kernel data segment selector offset (offset in GDT) = 0x10 (16) // User data segment selector offset (offset in GDT) = 0x23 (32|3) // User data segment selector must also be or'ed with 3 for User Privilege level #if THREAD_TRACE BasicConsole.WriteLine("Setting SS..."); #endif State->SS = UserMode ? (ushort)0x23 : (ushort)0x10; // Init Started // Not started yet so set to false #if THREAD_TRACE BasicConsole.WriteLine("Setting started..."); #endif State->Started = false; #if THREAD_TRACE BasicConsole.WriteLine("Allocating exception state..."); #endif //TODO: This is currently incorrectly allocated from the current process's heap instead of the heap of the owner process // Init Exception State State->ExState = (ExceptionState*)FOS_System.Heap.AllocZeroed((uint)sizeof(ExceptionState), "Thread : Thread() (2)"); #if THREAD_TRACE BasicConsole.WriteLine("Done."); #endif }
/// <summary> /// See base class. /// </summary> public override void Execute() { try { Hardware.DeviceManager.AddDeviceAddedListener(MainShell.DeviceManager_DeviceAdded, this); try { // Auto-init all to save us writing the command //InitPCI(); } catch { console.WriteLine(); console.WarningColour(); console.WriteLine("Error initialising PCI subsystem:"); OutputExceptionInfo(ExceptionMethods.CurrentException); } try { // Auto-init all to save us writing the command //InitATA(); } catch { console.WriteLine(); console.WarningColour(); console.WriteLine("Error initialising ATA subsystem:"); OutputExceptionInfo(ExceptionMethods.CurrentException); } #if PERIODIC_REBOOT // 60 seconds Hardware.Timers.PIT.Default.RegisterHandler(TriggerPeriodicReboot, 60000000000L, true, this); #endif //Endlessly wait for commands until we hit a total failure condition // or the user instructs us to halt while (!terminating) { try { //Output the current command line console.Write(CurrentDir + " > "); //List of supported commands /* Command { Req Arg } [Opt Arg] *Default val*: * - Halt * - ExInfo * - Init { ALL / PCI / ATA / USB / FS } * - Output { PCI / ATA / USB / FS / Memory } * - CheckDisk/ChkD { Drive# } * - FormatDisk/FmtD { Drive# } * - Dir { List / Open / New / Delete / Copy } * - File { Open/Delete/Copy } * - Test { Interrupts / Delegates / FileSystems / * ULLTComp / StringConcat/ ObjArray / * IntArray / DummyObj / DivideBy0 / * Exceptions1 / Exceptions2 / PCBeep / * Timer / Keyboard / FieldsTable / * IsInst / VirtMem / Longs / * ThreadSleep / Heap / GC / * ATA / USB } * - GC { Cleanup } * - USB { Update / Eject } * - Start { Filename } [*KM* / UM] [*Raw* / ELF] * - ILY * - Show { c / w } * - Help { <Command Name> } * - Clear * - Easter * - Reboot */ //Get the current input line from the user FOS_System.String line = ReadLine(); //Split the input into command, arguments and options // All parts are in lower case List cmdParts = SplitCommand(line); //Check the user didn't just press enter without any text if (cmdParts.Count > 0) { //Get the command to run - first part of the command FOS_System.String cmd = (FOS_System.String)cmdParts[0]; //Determine which command we are to run if (cmd == "halt") { //Cleanup devices console.WriteLine("Ejecting MSDs..."); CleanDiskCaches(); console.WriteLine("Ejected."); console.WriteLine("Closing..."); //Halt execution of the current shell terminating = true; } else if (cmd == "exinfo") { //Output information about the current exception, if any. // TODO - This should be changed to Last exception. // Because of the try-catch block inside the loop, there // will never be a current exception to output. OutputExceptionInfo(ExceptionMethods.CurrentException); } else if (cmd == "init") { //Initialise the specified sub-system. #region Init //The user may have forgotten to input an option. Assume they // haven't, then fill in if they have. FOS_System.String opt1 = null; //We don't know how many extra options there might be, so we test // for greater-than instead of equal to. It should be noted that > // is more efficient than >=. Also, the command is in the cmdParts // not just the options. //So, we want the 1st option, which is the 2nd command part. This // means we need > 1 command part and index 1 in the command parts // list. if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } //If the user gave us an option if (opt1 != null) { //Determine which option that was if (opt1 == "all") { //Initialise all sub-systems in order InitATA(); InitPCI(); InitUSB(); InitFS(); } else if (opt1 == "pci") { //Initialise the PCI sub-system InitPCI(); } else if (opt1 == "ata") { //Initialise the ATA sub-system InitATA(); } else if (opt1 == "usb") { //Initialise the USB sub-system // This is dependent upon the PCI sub-system // but we assume the user was intelligent // enough to have already initialised PCI. // (Probably a bad assumption really... ;p ) InitUSB(); } else if (opt1 == "fs") { //Initialise the file (sub-)system // This is dependent upon the USB or ATA // sub-system but we assume the user was intelligent // enough to have already initialised these. // (Probably a bad assumption really... ;p ) InitFS(); } else { UnrecognisedOption(opt1); } } else { console.WriteLine("You must specify what to init. { PCI/ATA/USB/FS }"); } #endregion } else if (cmd == "output") { //For details on how the code here works, see Init #region Output FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { if (opt1 == "pci") { OutputPCI(); } else if (opt1 == "ata") { OutputATA(); } else if (opt1 == "usb") { OutputUSB(); } else if (opt1 == "fs") { OutputFS(); } else if (opt1 == "memory" || opt1 == "mem") { OutputMemory(); } else { UnrecognisedOption(opt1); } } else { console.WriteLine("You must specify what to output. { PCI/ATA/USB/FS }"); } #endregion } else if (cmd == "checkdisk" || cmd == "chkd") { //For details on how the code here works, see Init #region Check Disk FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { int diskNum = (int)FOS_System.Int32.Parse_DecimalUnsigned(opt1, 0); if (Hardware.DeviceManager.Devices[diskNum] is Hardware.Devices.DiskDevice) { console.Write("Checking disk "); console.Write_AsDecimal(diskNum); console.WriteLine("..."); CheckDiskFormatting((Hardware.Devices.DiskDevice)Hardware.DeviceManager.Devices[diskNum]); } else { console.WriteLine("Cancelled - Specified device is not a disk device."); } } else { console.WriteLine("You must specify which disk to check."); } #endregion } else if (cmd == "formatdisk" || cmd == "fmtd") { //For details on how the code here works, see Init #region Format Disk FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { int diskNum = (int)FOS_System.Int32.Parse_DecimalUnsigned(opt1, 0); if (Hardware.DeviceManager.Devices[diskNum] is Hardware.Devices.DiskDevice) { console.Write("Are you sure you wish to continue? (Y/N) : "); FOS_System.String str = ReadLine().ToLower(); if (str == "y") { console.Write("Formatting disk "); console.Write_AsDecimal(diskNum); console.WriteLine("..."); FormatDisk((Hardware.Devices.DiskDevice)Hardware.DeviceManager.Devices[diskNum]); } else { console.WriteLine("Cancelled."); } } else { console.WriteLine("Cancelled - Specified device is not a disk device."); } } else { console.WriteLine("You must specify which disk to check."); } #endregion } else if (cmd == "gc") { //For details on how the code here works, see Init #region GC FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { if (opt1 == "cleanup") { FOS_System.GC.Cleanup(); } else { UnrecognisedOption(opt1); } } else { console.WriteLine("You must specify what to do. { Cleanup }"); } #endregion } else if (cmd == "usb") { //For details on how the code here works, see Init #region USB FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { if (opt1 == "update") { Hardware.USB.USBManager.Update(); } else if (opt1 == "eject") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2 == "msd") { FOS_System.String opt3 = null; if (cmdParts.Count > 3) { opt3 = (FOS_System.String)cmdParts[3]; } if (opt3 != null) { EjectMSD(FOS_System.Int32.Parse_DecimalSigned(opt3)); } else { console.WriteLine("You must specify a device number!"); } } else { console.WriteLine("Unrecognised device type!"); } } else { console.WriteLine("You must specify a device type! (msd)"); } } else { UnrecognisedOption(opt1); } } else { console.WriteLine("You must specify what to do. { Update }"); } #endregion } else if (cmd == "dir") { //For details on how the code here works, see Init //Note: "./" prefix on a dir/file path means current // directory so it must be replaced by the // current directory. #region Dir FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { if (opt1 == "list") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } console.WriteLine("Listing dir: " + opt2); OutputDirectoryContents(opt2); } else { console.WriteLine("You must specify a directory path."); } } else if (opt1 == "open") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } Directory aDir = Directory.Find(opt2); if (aDir != null) { CurrentDir = aDir.GetFullPath(); } else { console.WriteLine("Directory not found!"); } } else { console.WriteLine("You must specify a directory path."); } } else if (opt1 == "new") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } console.WriteLine("Creating dir: " + opt2); NewDirectory(opt2); } else { console.WriteLine("You must specify a directory path."); } } else if (opt1 == "delete") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } console.WriteLine("Deleting dir: " + opt2); DeleteDirectory(opt2); } else { console.WriteLine("You must specify a directory path."); } } else if (opt1 == "copy") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } FOS_System.String opt3 = null; if (cmdParts.Count > 3) { opt3 = (FOS_System.String)cmdParts[3]; } if (opt3 != null) { if (opt3.StartsWith("./")) { opt3 = CurrentDir + opt3.Substring(2, opt3.length - 2); } console.WriteLine("Copy cmd, opt2=\"" + opt2 + "\", opt3=\"" + opt3 + "\""); CopyDirectory(opt2, opt3); } else { console.WriteLine("You must specify a destination path."); } } else { console.WriteLine("You must specify a source path."); } } else { UnrecognisedOption(opt1); } } else { console.WriteLine("You must specify what to do. { List/Open/New/Delete/Copy }"); } #endregion } else if (cmd == "file") { //For details on how the code here works, see Init //Note: "./" prefix on a dir/file path means current // directory so it must be replaced by the // current directory. #region File FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { if (opt1 == "open") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } OutputFileContents(opt2); } else { console.WriteLine("You must specify a file path."); } } else if (opt1 == "delete") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } DeleteFile(opt2); } else { console.WriteLine("You must specify a file path."); } } else if (opt1 == "copy") { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2.StartsWith("./")) { opt2 = CurrentDir + opt2.Substring(2, opt2.length - 2); } FOS_System.String opt3 = null; if (cmdParts.Count > 3) { opt3 = (FOS_System.String)cmdParts[3]; } if (opt3 != null) { if (opt3.StartsWith("./")) { opt3 = CurrentDir + opt3.Substring(2, opt3.length - 2); } console.WriteLine("Copy cmd, opt2=\"" + opt2 + "\", opt3=\"" + opt3 + "\""); CopyFile(opt2, opt3); } else { console.WriteLine("You must specify a destination path."); } } else { console.WriteLine("You must specify a source path."); } } else { UnrecognisedOption(opt1); } } else { console.WriteLine("You must specify what to do. { Open/Delete/Copy }"); } #endregion } else if (cmd == "test") { //For details on how the code here works, see Init #region Test FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { if (opt1 == "interrupts") { InterruptsTest(); } else if (opt1 == "delegates") { DelegateTest(); } else if (opt1 == "filesystems") { FileSystemTests(); } else if (opt1 == "ulltcomp") { ULongLTComparisonTest(); } else if (opt1 == "stringconcat") { StringConcatTest(); } else if (opt1 == "objarray") { ObjectArrayTest(); } else if (opt1 == "intarray") { IntArrayTest(); } else if (opt1 == "dummyobj") { DummyObjectTest(); } else if (opt1 == "divideby0") { DivideByZeroTest(); } else if (opt1 == "exceptions1") { ExceptionsTestP1(); } else if (opt1 == "exceptions2") { ExceptionsTestP2(); } else if (opt1 == "pcbeep") { PCBeepTest(); } else if (opt1 == "timer") { TimerTest(); } else if (opt1 == "keyboard") { KeyboardTest(); } else if (opt1 == "fieldstable") { FieldsTableTest(); } else if (opt1 == "isinst") { IsInstTest(); } else if (opt1 == "virtmem") { Hardware.VirtMemManager.Test(); } else if (opt1 == "longs") { LongsTest(); } else if (opt1 == "threadsleep") { ThreadSleepTest(); } else if (opt1 == "heap") { HeapTest(); } else if (opt1 == "gc") { GCTest(); } else if (opt1 == "ata") { ATATest(); } else if (opt1 == "usb") { USBTest(); } else { UnrecognisedOption(opt1); } } else { console.WriteLine("You must specify which test. { Interrupts / Delegates / FileSystems /\n" + " ULLTComp / StringConcat / ObjArray /\n" + " IntArray / DummyObj / DivideBy0 /\n" + " Exceptions1 / Exceptions2 / PCBeep /\n" + " Timer / Keyboard / FieldsTable /\n" + " IsInst / VirtMem }"); } #endregion } else if (cmd == "start") { //For details on how the code here works, see Init #region Start FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } if (opt1 != null) { if (opt1.StartsWith("./")) { opt1 = CurrentDir + opt1.Substring(2, opt1.length - 2); } File aFile = File.Open(opt1); if (aFile != null) { FOS_System.String opt2 = null; if (cmdParts.Count > 2) { opt2 = (FOS_System.String)cmdParts[2]; } if (opt2 != null) { if (opt2 == "km") { FOS_System.String opt3 = null; if (cmdParts.Count > 3) { opt3 = (FOS_System.String)cmdParts[3]; } if (opt3 != null) { if (opt3 == "raw") { Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromRawExe(aFile, false), Hardware.Processes.Scheduler.Priority.Normal); } else if (opt3 == "elf") { Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromELFExe(aFile, false).TheProcess, Hardware.Processes.Scheduler.Priority.Normal); } else { UnrecognisedOption(opt3); } } else { //Run as RAW for now Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromRawExe(aFile, false), Hardware.Processes.Scheduler.Priority.Normal); } } else if (opt2 == "um") { FOS_System.String opt3 = null; if (cmdParts.Count > 3) { opt3 = (FOS_System.String)cmdParts[3]; } if (opt3 != null) { if (opt3 == "raw") { Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromRawExe(aFile, true), Hardware.Processes.Scheduler.Priority.Normal); } else if (opt3 == "elf") { Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromELFExe(aFile, true).TheProcess, Hardware.Processes.Scheduler.Priority.Normal); } else { UnrecognisedOption(opt3); } } else { //Run as RAW for now Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromRawExe(aFile, true), Hardware.Processes.Scheduler.Priority.Normal); } } else { UnrecognisedOption(opt2); } } else { //Run as KM, ELF for now Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromELFExe(aFile, false).TheProcess, Hardware.Processes.Scheduler.Priority.Normal); } } else { console.WriteLine("File not found."); } } else { console.WriteLine("You must specify the file path."); } #endregion } else if (cmd == "ily") { #region ILY Hardware.Processes.ProcessManager.RegisterProcess( Processes.DynamicLinkerLoader.LoadProcess_FromRawExe( File.Open("a:/ily.bin"), false), Hardware.Processes.Scheduler.Priority.Normal); #endregion } else if (cmd == "show") { #region Show FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } ShowLicense(opt1); #endregion } else if (cmd == "help") { #region Help FOS_System.String opt1 = null; if (cmdParts.Count > 1) { opt1 = (FOS_System.String)cmdParts[1]; } ShowHelp(opt1); #endregion } else if (cmd == "clear") { #region Clear console.Clear(); #endregion } else if (cmd == "easter") { #region Easter Hardware.Processes.ProcessManager.CurrentProcess.CreateThread(Tasks.EasterTask.Main, "Easter"); #endregion } else if (cmd == "reboot") { #region Reboot Reboot(); #endregion } } } catch { OutputExceptionInfo(ExceptionMethods.CurrentException); } } } catch { OutputExceptionInfo(ExceptionMethods.CurrentException); //Pause to give us the chance to read the output. // We do not know what the code outside this shell may do. Processes.SystemCalls.SleepThread(1000); } console.WriteLine("Shell exited."); }
/// <summary> /// Initialises new partition information using the specified data. /// </summary> /// <param name="data">The data to read the partition info from.</param> /// <param name="offset">The offset in the data at which to start reading.</param> /// <param name="entrySize">The size of a partition entry.</param> public PartitionInfo(byte[] data, uint offset, uint entrySize) { //There is an underlying assumption here that the // supplied data is of sufficient length (including the // extra length required for any specified offset). //TODO: Check the entry size is valid //TODO: Throw an exception if data.length + offset < entrySize //Copy in Type ID data TypeID[0] = data[offset + 0]; TypeID[1] = data[offset + 1]; TypeID[2] = data[offset + 2]; TypeID[3] = data[offset + 3]; TypeID[4] = data[offset + 4]; TypeID[5] = data[offset + 5]; TypeID[6] = data[offset + 6]; TypeID[7] = data[offset + 7]; TypeID[8] = data[offset + 8]; TypeID[9] = data[offset + 9]; TypeID[10] = data[offset + 10]; TypeID[11] = data[offset + 11]; TypeID[12] = data[offset + 12]; TypeID[13] = data[offset + 13]; TypeID[14] = data[offset + 14]; TypeID[15] = data[offset + 15]; //Copy in the partition ID data ID[0] = data[offset + 16]; ID[1] = data[offset + 17]; ID[2] = data[offset + 18]; ID[3] = data[offset + 19]; ID[4] = data[offset + 20]; ID[5] = data[offset + 21]; ID[6] = data[offset + 22]; ID[7] = data[offset + 23]; ID[8] = data[offset + 24]; ID[9] = data[offset + 25]; ID[10] = data[offset + 26]; ID[11] = data[offset + 27]; ID[12] = data[offset + 28]; ID[13] = data[offset + 29]; ID[14] = data[offset + 30]; ID[15] = data[offset + 31]; //Parse the other partition data FirstLBA = ByteConverter.ToUInt32(data, offset + 32); LastLBA = ByteConverter.ToUInt32(data, offset + 40); Attributes = ByteConverter.ToUInt32(data, offset + 48); Name = ByteConverter.GetASCIIStringFromUTF16(data, offset + 56, 36).Trim(); #if GPT_TRACE BasicConsole.WriteLine(((FOS_System.String)"First LBA : ") + FirstLBA); BasicConsole.WriteLine(((FOS_System.String)"Last LBA : ") + LastLBA); BasicConsole.WriteLine(((FOS_System.String)"Attributes : ") + Attributes); BasicConsole.WriteLine(((FOS_System.String)"Name : ") + Name); #endif }
public BootRecord(Hardware.Devices.DiskDevice disk, uint startBlock, uint numBlocks, byte[] data) : base(disk, startBlock, numBlocks, data) { BootSystemIdentifier = ByteConverter.GetASCIIStringFromASCII(data, 7, 32); BootSystem = ByteConverter.GetASCIIStringFromASCII(data, 39, 32); }
/// <summary> /// Initializes a new file system mapping. /// </summary> /// <param name="aPrefix">The prefix to map.</param> /// <param name="aFileSystem">The file system to map.</param> public FileSystemMapping(FOS_System.String aPrefix, FileSystem aFileSystem) { prefix = aPrefix; theFileSystem = aFileSystem; }
/// <summary> /// Attempts to initialise the ATA drive. /// </summary> protected void InitDrive() { // At this point, DiscoverDrive has been called, but the additional identification data // has not been read // If it's a PATAPI drive, we need to send the IDENTIFY_PACKET command if (mDriveType == SpecLevel.PATAPI) { Reset(); SendCmd(Cmd.IdentifyPacket); } // Read Identification Space of the Device var deviceInfoBuffer = new UInt16[256]; IO.Data.Read_UInt16s(deviceInfoBuffer); mSerialNo = GetString(deviceInfoBuffer, 10, 20).Trim(); mFirmwareRev = GetString(deviceInfoBuffer, 23, 8).Trim(); mModelNo = GetString(deviceInfoBuffer, 27, 40).Trim(); // Hitachi hardrives found in real-world hardware failed in that: // They only work with one-sector writes at a time // This may be due to the fact that I'm working with old laptops and a sample size of one // Hitachi drive. Newer drives may work properly. All drives will work with a max size of // one though. // // Fujitsu drives suffer a similar fault. if (mModelNo.StartsWith("Hitachi") || mModelNo.StartsWith("FUJITSU")) { maxWritePioBlocks = 1; } //Words (61:60) shall contain the value one greater than the total number of user-addressable //sectors in 28-bit addressing and shall not exceed 0x0FFFFFFF. // We need 28 bit addressing - small drives on VMWare and possibly other cases are 28 bit blockCount = ((UInt32)deviceInfoBuffer[61] << 16 | deviceInfoBuffer[60]) - 1; //Words (103:100) shall contain the value one greater than the total number of user-addressable //sectors in 48-bit addressing and shall not exceed 0x0000FFFFFFFFFFFF. //The contents of words (61:60) and (103:100) shall not be used to determine if 48-bit addressing is //supported. IDENTIFY DEVICE bit 10 word 83 indicates support for 48-bit addressing. bool xLba48Capable = (deviceInfoBuffer[83] & 0x400) != 0; if (xLba48Capable) { blockCount = ((UInt64)deviceInfoBuffer[103] << 48 | (UInt64)deviceInfoBuffer[102] << 32 | (UInt64)deviceInfoBuffer[101] << 16 | (UInt64)deviceInfoBuffer[100]) - 1; mLBA48Mode = true; } }
public DirectoryRecord(byte[] data, uint offset, bool isRootDirectory = false) { IsRootDirectory = isRootDirectory; RecordLength = data[offset + 0]; ExtAttrRecordLength = data[offset + 1]; LBALocation = ByteConverter.ToUInt32(data, offset + 2); DataLength = ByteConverter.ToUInt32(data, offset + 10); RecordingDateTime = new DateTime(data, offset + 18); TheFileFlags = (FileFlags)data[offset + 25]; FileUnitSize = data[offset + 26]; FileInterleaveGapSize = data[offset + 27]; VolumeSequenceNumber = ByteConverter.ToUInt16(data, offset + 28); FileIdentifierLength = data[offset + 32]; FileIdentifier = IsRootDirectory ? "ROOT_DIRECTORY" : ByteConverter.GetASCIIStringFromASCII(data, offset + 33, FileIdentifierLength); }