/// <summary>
        /// Refreshes the logical device.
        /// </summary>
        public void Refresh()
        {
            bootSector = null;
            data       = new UInt16[0];

            // Jump to FAT partition
            DeviceStream.Seek(partition.RelativeSector * PhysicalDevice.SectorSize, SeekOrigin.Begin);
            if (!partition.IsFAT)
            {
                return;
            }

            // Boot sector
            bootSector = (BootSector)StreamActivator.CreateInstance(typeof(BootSector), DeviceStream);
            DeviceStream.Seek(448, SeekOrigin.Current);

            // Failsafe .. be sure FAT partition table is valid
            if ((DeviceStream.ReadByte() != 0x55) || (DeviceStream.ReadByte() != 0xAA))
            {
                bootSector = null;
                return;
            }

            // Get FAT sector
            BinaryReader br = new BinaryReader(DeviceStream);

            data = new UInt16[bootSector.NumberOfFATs * ((bootSector.SectorsPerFAT * PhysicalDevice.SectorSize) / 2)];
            for (int i = 0; i < data.Length; i++)
            {
                data[i] = br.ReadUInt16();
            }
        }
Beispiel #2
0
        protected override Stream GetStreamInternal(Uri uri, FileMode mode, FileAccess access)
        {
            string path = GetPath(uri);

            long offset;

            if (!String.IsNullOrEmpty(uri.Fragment) && Int64.TryParse(HttpUtility.UrlDecode(uri.Fragment.Substring(1)), out offset))
            {
                DeviceStream stream;
                switch (mode)
                {
                case FileMode.Create:
                    stream = new DeviceStream(path, FileMode.OpenOrCreate, access);
                    stream.SetLength(offset);
                    break;

                case FileMode.Truncate:
                    stream = new DeviceStream(path, FileMode.Open, access);
                    stream.SetLength(offset);
                    break;

                default:
                    stream = new DeviceStream(path, mode, access);
                    break;
                }
                stream.Seek(offset, SeekOrigin.Begin);
                return(stream);
            }
            else
            {
                return(new DeviceStream(path, mode, access));
            }
        }
Beispiel #3
0
        /// <summary>
        /// Reads the specified file entry.
        /// </summary>
        public byte[] ReadFile(FileEntry file)
        {
            ushort nextCluster = file.FirstCluster;
            uint   sizeLeft    = file.FileSize;
            uint   clusterSize = (uint)(PhysicalDevice.SectorSize * device.BootSector.SectorsPerCluster);
            uint   sector;

            int offset = 0;

            byte[] data = new Byte[file.FileSize];
            while (true)
            {
                // Calculate next sector
                sector = (uint)(device.RootDirectorySector + ((((nextCluster == 0) ? (0) : (nextCluster + 2))) * device.BootSector.SectorsPerCluster));
                // Jump to data sector
                DeviceStream.Seek((device.Partition.RelativeSector + sector) * device.BootSector.BytesPerSector, SeekOrigin.Begin);
                // Read correct size
                if (sizeLeft < clusterSize)
                {
                    DeviceStream.Read(data, offset, (int)sizeLeft);
                    break;
                }
                else
                {
                    DeviceStream.Read(data, offset, (int)clusterSize);
                    offset   += (int)clusterSize;
                    sizeLeft -= clusterSize;
                }
                // Get next cluster
                nextCluster = device.Data[nextCluster];
                if ((nextCluster == 0x0000) || (nextCluster == 0xFFF7))
                {
                    break;    // Bad cluster pointer
                }
                if ((nextCluster >= 0xFFF8) && (nextCluster <= 0xFFFF))
                {
                    break;    // End of cluster of file
                }
            }
            return(data);
        }
Beispiel #4
0
        public static void WriteBootLoaderToDisk(string DiskId, IDeviceProfile deviceProfile)
        {
            var          chunkSize = 131072;
            DeviceStream ds        = new DeviceStream(DiskId, FileAccess.ReadWrite);

            ds.Seek(0, SeekOrigin.Begin);
            byte[] bootloader = File.ReadAllBytes(deviceProfile.Bootloader());

            var sectors = bootloader.Count() / chunkSize;

            DateTime startTime = DateTime.Now;

            using (BinaryReader br = new BinaryReader(new MemoryStream(bootloader)))
                for (int i = 0; i < sectors; i++)
                {
                    var buff = br.ReadBytes(chunkSize);
                    ds.Write(buff, 0, chunkSize);
                    Logging.ShowProgress((UInt64)bootloader.Count(), startTime, (UInt64)((i + 1) * chunkSize), (UInt64)((i + 1) * chunkSize), false);
                }
            Logging.Log("");

            ds.Dispose();
        }
Beispiel #5
0
        /// <summary>
        /// Enumerates the file entries contained in the current directory.
        /// </summary>
        private FileEntry[] EnumerateFileEntries(uint clusterNumber, bool includeFiles, bool includeDirectories, bool deleted, bool currentOnly, bool parentOnly)
        {
            ArrayList files  = new ArrayList();
            uint      sector = (uint)(device.RootDirectorySector + ((((clusterNumber == 0) ? (0) : (clusterNumber + 2))) * device.BootSector.SectorsPerCluster));

            // Jump to next directory sector
            DeviceStream.Seek((device.Partition.RelativeSector + sector) * device.BootSector.BytesPerSector, SeekOrigin.Begin);
            while (true)
            {
                FileEntry file = (FileEntry)StreamActivator.CreateInstance(typeof(FileEntry), DeviceStream);
                if (file.FileAttributes == FileAttributes.LongFileName)
                {
                    continue;
                }
                if (file.Name[0] == 0x00)
                {
                    break;  // No more entries
                }
                if (currentOnly)
                {
                    if ((clusterNumber == 0) && ((file.FileAttributes & FileAttributes.VolumeId) != 0))
                    {
                        files.Add(file);
                    }
                    else if (file.Name == ".          ")
                    {
                        files.Add(file);
                    }
                    continue;
                }
                if (parentOnly)
                {
                    if (file.Name == "..         ")
                    {
                        files.Add(file);
                    }
                    continue;
                }
                // Skip the volume id
                if ((file.FileAttributes & FileAttributes.VolumeId) != 0)
                {
                    continue;
                }

                // Skip deleted/non-deleted entries
                if ((file.Name[0] == '?') != deleted)
                {
                    continue;
                }

                // Show info
                bool isDirectory = ((file.FileAttributes & FileAttributes.Directory) != 0);
                if ((isDirectory) && (!includeDirectories))
                {
                    continue;
                }
                if ((!isDirectory) && (!includeFiles))
                {
                    continue;
                }
                files.Add(file);
            }
            return((FileEntry[])files.ToArray(typeof(FileEntry)));
        }
 protected override void When()
 {
     NewPosition = DeviceStream.Seek(123, SeekOrigin.Begin);
 }
Beispiel #7
0
        public Lumia.PhoneInfo GetPhoneInfo(uint diskNumber)
        {
            var time = DateTime.Now;

            Log.Debug("Initializing Device Stream...");

            var deviceName = @"\\.\PhysicalDrive" + diskNumber;

            var diskSectorSize = (int)GetDiskSize.GetDiskSectorSize(deviceName);

            byte[]            platconfig;
            byte[]            dppconfig;
            QualcommPartition part;

            using (var devicestream = new DeviceStream(deviceName))
            {
                ulong platStart = 0;
                ulong platEnd   = 0;
                ulong dppStart  = 0;
                ulong dppEnd    = 0;

                ulong sbl1Start = 0;
                ulong sbl1End   = 0;

                Log.Debug("Reading device GPT...");

                // Code to find the PLAT and DPP FAT partition offsets
                devicestream.Seek(0, SeekOrigin.Begin);
                var buffer = new byte[diskSectorSize];

                while (Encoding.ASCII.GetString(buffer, 0, 8) != "EFI PART")
                {
                    devicestream.Read(buffer, 0, diskSectorSize);
                }

                var partentrycount = BitConverter.ToUInt32(buffer, 0x50);
                var partentrysize  = BitConverter.ToUInt32(buffer, 0x54);
                var bytestoread    = (int)Math.Round(partentrycount * partentrysize / (double)diskSectorSize,
                                                     MidpointRounding.AwayFromZero) * diskSectorSize;
                var partarray = new byte[bytestoread];
                devicestream.Read(partarray, 0, bytestoread);
                devicestream.Seek(0, SeekOrigin.Begin);

                using (var br = new BinaryReader(new MemoryStream(partarray)))
                {
                    var name = new byte[72]; // fixed name size
                    while (true)
                    {
                        var type = new Guid(br.ReadBytes(16));
                        if (type == Guid.Empty)
                        {
                            break;
                        }

                        br.BaseStream.Seek(16, SeekOrigin.Current);
                        var firstLba = br.ReadUInt64();
                        var lastLba  = br.ReadUInt64();
                        br.BaseStream.Seek(0x8, SeekOrigin.Current);
                        name = br.ReadBytes(name.Length);

                        var convname        = Encoding.Unicode.GetString(name).TrimEnd('\0');
                        var diskstartoffset = firstLba * (uint)diskSectorSize;
                        var diskendoffset   = lastLba * (uint)diskSectorSize;

                        if (convname == "PLAT")
                        {
                            Log.Debug("Found PLAT");

                            platStart = diskstartoffset;
                            platEnd   = diskendoffset;
                        }

                        if (convname == "DPP")
                        {
                            Log.Debug("Found DPP");

                            dppStart = diskstartoffset;
                            dppEnd   = diskendoffset;
                        }

                        if (convname == "SBL1")
                        {
                            Log.Debug("Found SBL1");

                            sbl1Start = diskstartoffset;
                            sbl1End   = diskendoffset;
                        }
                    }
                }

                var sbl1Partition = new byte[platEnd - platStart];

                Log.Debug("Reading SBL1 Partition");
                ChunkReader(devicestream, sbl1Partition, sbl1Start, sbl1End,
                            (int)sbl1End - (int)sbl1Start); // We can just read the whole thing in a single run from testing

                part = new QualcommPartition(sbl1Partition);

                // Initialize DiscUtils
                SetupHelper.SetupComplete();

                Log.Debug("Reading pconf.bin from file system...");

                using (var platFileSystem =
                           new FatFileSystem(new PartialStream(devicestream, (long)platStart, (long)platEnd))
                       ) //new MemoryStream(PLATPartition)))
                {
                    using (Stream platConf = platFileSystem.OpenFile(@"pconf.bin", FileMode.Open, FileAccess.Read))
                        using (var platConfigStream = new MemoryStream())
                        {
                            platConf.CopyTo(platConfigStream);
                            platconfig = platConfigStream.ToArray();
                        }
                }

                Log.Debug("Reading product.dat from file system...");

                using (var dppFileSystem =
                           new FatFileSystem(new PartialStream(devicestream, (long)dppStart, (long)dppEnd))
                       ) //new MemoryStream(DPPPartition)))
                {
                    var isMmo = dppFileSystem.DirectoryExists("MMO");
                    Log.Debug("Is the device a MMO device: " + isMmo);

                    // Properly handle earlier 950s/RX130s with Nokia folders.
                    using (Stream dppConf = dppFileSystem.OpenFile(isMmo ? @"MMO\product.dat" : @"Nokia\product.dat",
                                                                   FileMode.Open, FileAccess.Read))
                        using (var dppConfigStream = new MemoryStream())
                        {
                            dppConf.CopyTo(dppConfigStream);
                            dppconfig = dppConfigStream.ToArray();
                        }
                }
            }

            var ndate = DateTime.Now - time;

            Log.Debug("Finished in: " + ndate.TotalSeconds + " seconds.");

            Log.Debug("Drumroll...");
            Log.Debug("//////////////////");
            Log.Debug("product.dat");
            Log.Debug("//////////////////");

            // We now did read both product.dat and pconf.bin, you want to detect a device with pconf and check for the ID, if needed you can also read product.dat
            // Below are samples of pconf, you want to read NAME property. This is the device platform identifier.
            //
            // pconf.bin
            //
            // NAME=P6148
            // PKEY = 3
            // SWVERSION = 03030.00000.14256.02000

            var ddp  = ParseDpp(Encoding.ASCII.GetString(dppconfig));
            var plat = ParsePlat(Encoding.ASCII.GetString(platconfig));

            Log.Debug(BitConverter.ToString(part.RootKeyHash));

            return(new Lumia.PhoneInfo(ddp, plat, part.RootKeyHash));
        }
Beispiel #8
0
 protected override void When()
 {
     NewPosition = DeviceStream.Seek(345, SeekOrigin.Current);
 }
Beispiel #9
0
 protected override void When()
 {
     NewPosition = DeviceStream.Seek(234, SeekOrigin.End);
 }