DeviceVerify.cs :  » Game » WBFSSync » DevConsole » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Game » WBFSSync 
WBFSSync » DevConsole » DeviceVerify.cs
//-------------------------------------
// WBFSSync - WBFSSync.exe
//
// Copyright 2009 Caian (mga Frst) <frost.omega@hotmail.com> :
//
// WBFSSync is Licensed under the terms of the Microsoft Reciprocal License (Ms-RL)
//
// DeviceVerify.cs:
//
// Classe que engloba ferramentas de verificao de disco wbfs
//
//-------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using WBFSSync;
using System.IO;
using System.Net;

namespace DevConsole{
    static class DeviceVerify
    {
        const int wbfsMagic = (('W' << 24) | ('B' << 16) | ('F' << 8) | ('S'));
        const uint wiidiscMagic = 0x5D1C9EA3;

        const ushort discHeaderCopySize = 256;

        const byte wiiSectorSize_s = 15;
        const uint wiiSectorSize = 32768;
        const uint wiiSectorsPerDisc = 143432 * 2; //Suporte a Double Layer

        const int wbfsHeadMagicPos = 0; // Posio do "Magic" dentro do cabealho do sistema de arquivos
        const int wbfsHeadHdSecsPos = 4; // Posio do "Nmero de setores" dentro do cabealho do sistema de arquivos
        const int wbfsHeadHdSecSz = 8; // Posio do "Tamanho do setor" dentro do cabealho do sistema de arquivos
        const int wbfsHeadWbfsSecSz = 9; // Posio do "Tamanho do setor WBFS" dentro do cabealho do sistema de arquivos
        const int wbfsHeadDiscTable = 12; // Posio da "Tabela de disco" dentro do cabealho do sistema de arquivos

        public const int wiidiscMagicPos = 24;
        public const uint wbfsHeaderSize = 12;

        //-------------------------------
        static long step = 0;
        static long steps = 1;

        static List<String> log = new List<string>();
        static string file = "";

        //-------------------------------
        static void LogLine(String format, params Object[] args)
        {
            log.Add(String.Format(format, args));
            Draw();
        }

        //-------------------------------
        static void Log(String format, params Object[] args)
        {
            log[log.Count - 1] = log[log.Count - 1] + String.Format(format, args);
            Draw();
        }

        //-------------------------------
        public static void VerifyCommand(String[] args)
        {
            if (args.Length != 2)
            {
                Console.WriteLine("verify DRIVE-LETTER");
                return;
            }

            Verify(args[1][0]);
        }

        //-------------------------------
        static void Verify(Char drive)
        {
            step = 0;
            steps = 1;

            string devfile = @"\\.\" + drive + ':';
            LogLine("Opening Drive '{0}'...", devfile);

            IIOContext device = IOManager.CreateIOContext("DEVVERIFY", devfile, System.IO.FileAccess.ReadWrite, 
                FileShare.None, 0, FileMode.Open, EFileAttributes.NoBuffering);

            if (device.Result != 0)
            {
                LogLine("Failed to open device! Error {0}", device.Result);
                goto END;
            }

            if (device.Lock() != IORet.RET_IO_OK)
            {
                LogLine("Failed to open device! Error {0}", device.Result);
                goto END;
            }

            //

            DISK_GEOMETRY dg = device.GetDiskGeometry();
            PARTITION_INFORMATION pi = device.GetPartitionInformation();

            if (dg.BytesPerSector == 0)
            {
                LogLine("Device is empty!");
                goto END;
            }

            //

            LogLine("Loading partition Head...");

            uint PartitionOffsetLBA = 0;

            uint hdSectorSize = dg.BytesPerSector;
            uint hdTotalSectors = (uint)(pi.PartitionLength / hdSectorSize);

            byte hdSectorSize_s = bitshift((uint)hdSectorSize);
            byte hdTotalSectors_s = bitshift((uint)hdTotalSectors);

            uint wiiTotalSectors = (uint)((long)hdTotalSectors * hdSectorSize / wiiSectorSize);

            //Cabealho

            Byte[] Head = new Byte[hdSectorSize];

            //L o cabealho do disco
            if (device.Read(Head, PartitionOffsetLBA * hdSectorSize, (int)hdSectorSize) != IORet.RET_IO_OK)
            {
                LogLine("Failed to read device! Error {0}", device.Result);
                goto END;
            }
            else
            {
                Log("Ok");
            }

            uint discWbfsMagic = BitConverter.ToUInt32(Head, wbfsHeadMagicPos);
            uint discTotalSectors = ntohi(BitConverter.ToUInt32(Head, wbfsHeadHdSecsPos));
            byte discSectorSize_s = Head[wbfsHeadHdSecSz];

            if (discWbfsMagic != htoni(wbfsMagic))
            {
                LogLine("Incorrect partition magic, fixing...");
                Byte[] newmagic = BitConverter.GetBytes(htoni(wbfsMagic));
                newmagic.CopyTo(Head, wbfsHeadMagicPos);
                Log("Ok");
            }

            if (discTotalSectors != hdTotalSectors)
            {
                LogLine("Incorrect partition total sectors, fixing...");
                Byte[] newmagic = BitConverter.GetBytes(htoni(hdTotalSectors));
                newmagic.CopyTo(Head, wbfsHeadHdSecsPos);
                Log("Ok");
            }

            if (discSectorSize_s != hdSectorSize_s)
            {
                LogLine("Incorrect partition sector size, fixing...");
                Head[wbfsHeadHdSecSz] = hdSectorSize_s;
                Log("Ok");
            }

            //

            Byte size_s;
            for (size_s = 6; size_s < 11; size_s++)
            {
                if (wiiTotalSectors < ((1U << 16) * (1 << size_s)))
                {
                    break;
                }
            }

            byte wbfsSectorSize_s = (byte)(size_s + wiiSectorSize_s);
            Head[wbfsHeadWbfsSecSz] = wbfsSectorSize_s;

            //

            uint wbfsSectorSize = (uint)(1 << wbfsSectorSize_s);
            ushort wbfsTotalSectors = (ushort)((int)wiiTotalSectors >> (int)(wbfsSectorSize_s - wiiSectorSize_s));
            ushort wbfsSectorsPerDisc = (ushort)((int)wiiSectorsPerDisc >> (int)(wbfsSectorSize_s - wiiSectorSize_s));

            uint wiiSectorsPerWBFSSector = (uint)(1 << (int)(wbfsSectorSize_s - wiiSectorSize_s));

            ushort discInfoSize = (ushort)Align_LBA((int)(discHeaderCopySize + wbfsSectorsPerDisc * 2), hdSectorSize);
            uint discInfoSizeInSecs = (uint)(discInfoSize >> hdSectorSize_s);

            uint WLBAPositionLBA = (uint)(((int)wbfsSectorSize - (int)wbfsTotalSectors / 8) >> (int)hdSectorSize_s);
            int WLBASize = Align_LBA(wbfsTotalSectors / 8, hdSectorSize);

            ushort maxDiscs = Math.Min((ushort)((WLBAPositionLBA - 1) / (discInfoSize >> hdSectorSize_s)),
                (ushort)(hdSectorSize - wbfsHeaderSize));

            //

            LogLine("Writing sector...");

            if (device.Write(Head, PartitionOffsetLBA * hdSectorSize, (int)hdSectorSize) != IORet.RET_IO_OK)
            {
                LogLine("Failed to write to device! Error {0}", device.Result);
                goto END;
            }
            else
            {
                Log("Ok");
            }

            Head = null;

            //

            LogLine("Loading WBFS Sector 0...");

            Byte[] WBFSHead = new Byte[wbfsSectorSize];

            if (device.Read(WBFSHead, PartitionOffsetLBA * hdSectorSize, (int)wbfsSectorSize) != IORet.RET_IO_OK)
            {
                LogLine("Failed to read device! Error {0}", device.Result);
                goto END;
            }
            else
            {
                Log("Ok");
            }

            //

            LogLine("Verifying filesystem integrity...");
            steps = maxDiscs;
            List<ushort> SectorCrossingList = new List<ushort>();

            uint validated = 0;

            for (int i = 0; i < maxDiscs; i++)
            {
                step++;
                file = String.Format("{0}\\DISCTABLE[{1}]", devfile, i);
                Draw();

                //

                Byte[] info = new byte[discInfoSize];

                if (device.Read(info, (PartitionOffsetLBA + 1 /*setor 0*/ + i * discInfoSizeInSecs) * hdSectorSize,
                    discInfoSize) != IORet.RET_IO_OK)
                {
                    LogLine("Failed to read device! Error {0}", device.Result);
                    goto END;
                }

                //

                uint magic = _be32(info, 24);
                if (magic != 0x5D1C9EA3)
                {
                    //LogLine("Disc {0} is not a wii disc!", i);
                    continue;
                }

                //

                String code = Encoding.Default.GetString(info, 0, 6);
                String name = Encoding.Default.GetString(info, 32, 32).TrimEnd('\0');

                LogLine("Found disc '{0} - {1}', verifying sectors...", code, name);

                uint usedsectors = 0;
                bool invalid = false;

                for (int j = 0; j < wbfsSectorsPerDisc; j++)
                {
                    int p = discHeaderCopySize + (2 * j);
                    ushort s = ntohs(BitConverter.ToUInt16(info, p));
                    if (s != 0)
                    {
                        if (IsSectorUsed(WBFSHead, (int)(WLBAPositionLBA * hdSectorSize), s))
                        {
                            usedsectors++;
                            if (SectorCrossingList.Contains(s))
                            {
                                LogLine("Crossed sector found, disc is invalid!");
                                invalid = true;
                                break;
                            }

                            SectorCrossingList.Add(s);
                        }
                        else
                        {
                            LogLine("Inconsistent sector found at {0}, disc is invalid!", j);
                            invalid = true;
                            break;
                        }
                    }
                }

                if (invalid)
                {
                    continue;
                }

                LogLine("Disc validated: {0} - {1}, {2} Bytes", code, name, ((long)usedsectors * wbfsSectorSize));
                WBFSHead[wbfsHeadDiscTable + i] = 1;
                validated++;
            }

            //

            LogLine("Writing WBFS sector...");

            if (device.Write(WBFSHead, PartitionOffsetLBA * hdSectorSize, (int)hdSectorSize) != IORet.RET_IO_OK)
            {
                LogLine("Failed to write to device! Error {0}", device.Result);
                goto END;
            }
            else
            {
                Log("Ok");
            }

            //

            LogLine("Scanned {0} discs, validated {1}", maxDiscs, validated);
            LogLine("Done.");

        END:

            Head = null;
            WBFSHead = null;

            device.Unlock();
            device.Close();

            Console.Write("Press Any Key");
            Console.ReadKey(true);
            Program.LoadMainScreen();
        }

        //-------------------------------
        static void Draw()
        {
            int i = 0;
            StringBuilder screen = new StringBuilder();

            //-------------------------------
            screen.Append('');
            for (i = 0; i < Console.WindowWidth - 2; i++) screen.Append('');
            screen.Append('');

            screen.Append(" Disk verify utility");
            for (i = 0; i < Console.WindowWidth - 22; i++) screen.Append(' ');
            screen.Append('');

            screen.Append('');
            for (i = 0; i < Console.WindowWidth - 2; i++) screen.Append('');
            screen.Append('');

            //-------------------------------
            int maxlog = Console.WindowHeight - 11;
            int logstart = log.Count - maxlog;

            for (i = Math.Max(logstart, 0); i < log.Count; i++)
            {
                screen.Append('');

                string logline = log[i];
                if (logline.Length > Console.WindowWidth - 2) logline = logline.Substring(0, Console.WindowWidth - 2);
                screen.Append(logline);

                for (int j = 0; j < Console.WindowWidth - logline.Length - 2; j++) screen.Append(' ');
                screen.Append('');
            }

            //-------------------------------
            while (i++ < maxlog)
            {
                screen.Append('');
                for (int j = 0; j < Console.WindowWidth - 2; j++) screen.Append(' ');
                screen.Append('');
            }

            //-------------------------------
            screen.Append('');
            for (i = 0; i < Console.WindowWidth - 2; i++) screen.Append('');
            screen.Append('');

            screen.Append('');
            for (int j = 0; j < Console.WindowWidth - 2; j++) screen.Append(' ');
            screen.Append('');

            //-------------------------------
            screen.Append(" ");

            string fileline = file;
            if (fileline.Length > Console.WindowWidth - 4) fileline = fileline.Substring(0, Console.WindowWidth - 4);
            screen.Append(fileline);

            for (int j = 0; j < Console.WindowWidth - fileline.Length - 4; j++) screen.Append(' ');
            screen.Append(" ");

            //-------------------------------
            screen.Append(" ");
            float progress = (float)(Console.WindowWidth - 4) * step / (float)steps;
            for (i = 0; i < (int)progress; i++) screen.Append('');
            while (i++ < Console.WindowWidth - 4) screen.Append('');
            screen.Append(" ");

            screen.Append('');
            for (int j = 0; j < Console.WindowWidth - 2; j++) screen.Append(' ');
            screen.Append('');

            screen.Append('');
            for (int j = 0; j < Console.WindowWidth - 2; j++) screen.Append('');
            screen.Append('');

            //-------------------------------
            Console.Clear();
            Console.ResetColor();
            Console.Write(screen.ToString());
        }

        //-------------------------------
        static byte bitshift(uint size)
        {
            byte r = 0;

            do
            {
                size >>= 1;
                r++;

            } while (size > 1);

            return r;
        }

        static int Align_LBA(int x, uint hdSectorSize)
        {
            return ((x) + (int)hdSectorSize - 1) & (~((int)hdSectorSize - 1));
        }

        static uint _be32(byte[] p, uint i)
        {
            return ((uint)(p[i]) << 24) | ((uint)(p[i + 1]) << 16) | ((uint)(p[i + 2]) << 8) | (uint)(p[i + 3]);
        }

        static bool IsSectorUsed(Byte[] wbfssector0, int pos, ushort sector)
        {
            int abssector = (sector - 1) / 32;
            uint v = ntohi(BitConverter.ToUInt32(wbfssector0, pos + 4 * abssector));
            return (v & (1 << ((sector - 1) % 32))) == 0;
        }

        //----------------- Network to Host
        static uint ntohi(uint i) { return (uint)IPAddress.NetworkToHostOrder((int)i); }
        static ushort ntohs(ushort i) { return (ushort)IPAddress.NetworkToHostOrder((short)i); }
        static ulong ntohl(ulong i) { return (ulong)IPAddress.NetworkToHostOrder((long)i); }

        //----------------- Host to Network
        static uint htoni(uint i) { return (uint)IPAddress.HostToNetworkOrder((int)i); }
        static ushort htons(ushort i) { return (ushort)IPAddress.HostToNetworkOrder((short)i); }
        static ulong htonl(ulong i) { return (ulong)IPAddress.HostToNetworkOrder((long)i); }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.