/*********************************************************************** Copyright 2002 Ben Rudiak-Gould. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA, or visit . ***********************************************************************/ #include "../include/dvdsynth-device.h" #include "DVDUnrestrict.h" struct DvsDockingBayKernelGlobal* g_callbacks; unsigned get4(const unsigned char* p) { return p[0]*16777216 + p[1]*65536 + p[2]*256 + p[3]; } unsigned get4rba(unsigned base, const unsigned char* p) { unsigned x = get4(p); return x ? base+x : (unsigned)-1; } void HandleSector(struct DVDUnrestrictKernel* self, unsigned lba, unsigned char* data, int len) { unsigned word0 = get4(&data[0]); if (word0 == 0x000001BA && get4(&data[38]) == 0x000001BF && get4(&data[42]) == 0x03D40000) { /* PCI/DSI pack */ data[49] = 0; /* turn off macrovision */ g_callbacks->MemSet(data+53, 0, 4); /* enable all user ops */ } else { if (word0 == 0x44564456 && get4(&data[4]) == 0x4944454F) { unsigned word8 = get4(&data[8]); if (word8 == 0x2D564D47) { /* VMG ifo */ unsigned ifo_sector = lba; unsigned pgc_uops_offset = get4(data+0x84) + 8; if (pgc_uops_offset+4 <= len) { g_callbacks->MemSet(data+pgc_uops_offset, 0, 4); } self->tt_srpt_sector = get4rba(ifo_sector, data+0xC4); self->pgci_sector = (unsigned)-1; self->pgci_ut_sector = get4rba(ifo_sector, data+0xC8); data[35] = 0; /* enable all regions */ } else if (word8 == 0x2D565453) { /* VTS ifo */ unsigned ifo_sector = lba; self->tt_srpt_sector = (unsigned)-1; self->pgci_sector = get4rba(ifo_sector, data+0xCC); self->pgci_ut_sector = get4rba(ifo_sector, data+0xD0); } } if (lba == self->tt_srpt_sector) { int num_titles = data[0]*256 + data[1]; int i; for (i=0; ipgci_ut_sector) { int num_lang_units = data[0]*256 + data[1]; int lang_unit; for (lang_unit = 0; lang_unit < num_lang_units; ++lang_unit) { unsigned lu_offset; int num_pgcs, pgc; if (lang_unit*8 + 12 + 4 > len) break; lu_offset = get4(&data[lang_unit*8 + 12]); if (lu_offset+2 > len) break; num_pgcs = data[lu_offset]*256 + data[lu_offset+1]; for (pgc = 0; pgc < num_pgcs; ++pgc) { unsigned pgc_uops_offset; if (lu_offset + pgc*8 + 12 + 4 > len) break; pgc_uops_offset = lu_offset + get4(&data[lu_offset + pgc*8 + 12]) + 8; if (pgc_uops_offset + 4 <= len) { g_callbacks->MemSet(data+pgc_uops_offset, 0, 4); } } } } if (lba == self->pgci_sector) { int num_pgcs = data[0]*256 + data[1]; int pgc; for (pgc = 0; pgc < num_pgcs; ++pgc) { unsigned pgc_uops_offset; if (pgc*8 + 12 + 4 > len) break; pgc_uops_offset = get4(&data[pgc*8 + 12]) + 8; if (pgc_uops_offset + 4 <= len) { g_callbacks->MemSet(data+pgc_uops_offset, 0, 4); } } } } } scsi_result_t ScsiCommand(struct DvsDeviceKernel* _self, const unsigned char* cdb, int cdblen, unsigned char* buffer, unsigned long* pbuflen, int inout, SenseData* sense) { struct DVDUnrestrictKernel* self = (struct DVDUnrestrictKernel*)_self; scsi_result_t result = self->child->ScsiCommand(self->child, cdb, cdblen, buffer, pbuflen, inout, sense); if (cdb[0] == SCSIOP_READ && result == SCSIRESULT_SUCCESS) { unsigned first_sector = get4(&cdb[2]); unsigned num_sectors = cdb[7]*256+cdb[8]; int i; for (i=0; i 5) buffer[5] = 0; /* enable all regions */ } return result; } void* __cdecl GetDispatchFunc() { return &ScsiCommand; } void __cdecl DvdsynthDriverInit(struct DvsDockingBayKernelGlobal* callbacks) { g_callbacks = callbacks; } unsigned __stdcall DLLEntry(void* hinst, unsigned reason, void* reserved) { return 1; }