public int Read_2352(byte[] buffer, int offset)
        {
            //user data
            int read = Blob.BaseBlob.Read(Offset, buffer, offset + 16, 2048);

            //if we read the 2048 physical bytes OK, then return the complete sector
            if (read == 2048 && has_extra_data)
            {
                Buffer.BlockCopy(extra_data, 0, buffer, offset, 16);
                Buffer.BlockCopy(extra_data, 16, buffer, offset + 2064, 4 + 8 + 172 + 104);
                return(2352);
            }

            //sync
            buffer[offset + 0] = 0x00; buffer[offset + 1] = 0xFF; buffer[offset + 2] = 0xFF; buffer[offset + 3] = 0xFF;
            buffer[offset + 4] = 0xFF; buffer[offset + 5] = 0xFF; buffer[offset + 6] = 0xFF; buffer[offset + 7] = 0xFF;
            buffer[offset + 8] = 0xFF; buffer[offset + 9] = 0xFF; buffer[offset + 10] = 0xFF; buffer[offset + 11] = 0x00;
            //sector address
            buffer[offset + 12] = bcd_aba_min;
            buffer[offset + 13] = bcd_aba_sec;
            buffer[offset + 14] = bcd_aba_frac;
            //mode 1
            buffer[offset + 15] = 1;

            //calculate EDC and poke into the sector
            uint edc = ECM.EDC_Calc(buffer, offset, 2064);

            ECM.PokeUint(buffer, 2064, edc);

            //intermediate
            for (int i = 0; i < 8; i++)
            {
                buffer[offset + 2068 + i] = 0;
            }
            //ECC
            ECM.ECC_Populate(buffer, offset, buffer, offset, false);

            //VALIDATION - check our homemade algorithms against code derived from ECM
            ////EDC
            //GPL_ECM.edc_validateblock(buffer, 2064, buffer, offset + 2064);
            ////ECC
            //GPL_ECM.ecc_validate(buffer, offset, false);

            //if we read the 2048 physical bytes OK, then return the complete sector
            if (read == 2048)
            {
                extra_data = new byte[16 + 4 + 8 + 172 + 104];
                Buffer.BlockCopy(buffer, 0, extra_data, 0, 16);
                Buffer.BlockCopy(buffer, 2064, extra_data, 16, 4 + 8 + 172 + 104);
                has_extra_data = true;
                return(2352);
            }
            //otherwise, return a smaller value to indicate an error
            else
            {
                return(read);
            }
        }
Exemple #2
0
            void Reconstruct(byte[] secbuf, int type)
            {
                //sync
                secbuf[0] = 0;
                for (int i = 1; i <= 10; i++)
                {
                    secbuf[i] = 0xFF;
                }
                secbuf[11] = 0x00;

                //misc stuff
                switch (type)
                {
                case 1:
                    //mode 1
                    secbuf[15] = 0x01;
                    //reserved
                    for (int i = 0x814; i <= 0x81B; i++)
                    {
                        secbuf[i] = 0x00;
                    }
                    break;

                case 2:
                case 3:
                    //mode 2
                    secbuf[15] = 0x02;
                    //flags - apparently CD XA specifies two copies of these 4bytes of flags. ECM didnt store the first copy; so we clone the second copy which was stored down to the spot for the first copy.
                    secbuf[0x10] = secbuf[0x14];
                    secbuf[0x11] = secbuf[0x15];
                    secbuf[0x12] = secbuf[0x16];
                    secbuf[0x13] = secbuf[0x17];
                    break;
                }

                //edc
                switch (type)
                {
                case 1: ECM.PokeUint(secbuf, 0x810, ECM.EDC_Calc(secbuf, 0, 0x810)); break;

                case 2: ECM.PokeUint(secbuf, 0x818, ECM.EDC_Calc(secbuf, 16, 0x808)); break;

                case 3: ECM.PokeUint(secbuf, 0x92C, ECM.EDC_Calc(secbuf, 16, 0x91C)); break;
                }

                //ecc
                switch (type)
                {
                case 1: ECM.ECC_Populate(secbuf, 0, secbuf, 0, false); break;

                case 2: ECM.ECC_Populate(secbuf, 0, secbuf, 0, true); break;
                }
            }
        /// <summary>
        /// Synthesizes the complete ECM data (EDC + ECC) for a Mode 1 data sector (and puts it in place)
        /// Make sure everything else in the sector userdata is done before calling this
        /// </summary>
        public static void ECM_Mode1(byte[] buf2352, int offset, int LBA)
        {
            //EDC
            uint edc = ECM.EDC_Calc(buf2352, offset, 2064);

            ECM.PokeUint(buf2352, offset + 2064, edc);

            //reserved, zero
            for (int i = 0; i < 8; i++)
            {
                buf2352[offset + 2068 + i] = 0;
            }

            //ECC
            ECM.ECC_Populate(buf2352, offset, buf2352, offset, false);
        }
        /// <summary>
        /// Synthesizes the EDC checksum for a Mode 2 Form 2 data sector (and puts it in place)
        /// </summary>
        public static void EDC_Mode2_Form2(byte[] buf2352, int offset)
        {
            uint edc = ECM.EDC_Calc(buf2352, offset + 16, 2324 + 8);

            ECM.PokeUint(buf2352, offset + 2348, edc);
        }
        /// <summary>
        /// Synthesizes the EDC checksum for a Mode 2 Form 1 data sector (and puts it in place)
        /// </summary>
        public static void EDC_Mode2_Form1(byte[] buf2352, int offset)
        {
            uint edc = ECM.EDC_Calc(buf2352, offset + 16, 2048 + 8);

            ECM.PokeUint(buf2352, offset + 2072, edc);
        }