⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mirrordrive95_kernel.cpp

📁 DVD工具dvdsynth的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***********************************************************************
 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 <http://www.gnu.org/copyleft/gpl.html>.
***********************************************************************/


#include "../include/dvdsynth-device.h"
#include "kernel-io.h"


//#define IOS_SPY


DvsDockingBayKernelGlobal* g_callbacks;


template<class T>
static inline T min(T a, T b) { return a<b?a:b; }


/*******************************************************************\
\*******************************************************************/


#define VXD_CALL(device_id,service_id) \
   __asm int 0x20                 \
   __asm _emit ((service_id)&255) \
   __asm _emit ((service_id)>>8)  \
   __asm _emit ((device_id)&255)  \
   __asm _emit ((device_id)>>8)


#define VXD_JUMP(device_id,service_id) VXD_CALL(device_id,32768+(service_id))


#define VXD_STACKCALL_SERVICE(device_id,service_id,prototype) \
   __declspec(naked) prototype { VXD_JUMP(device_id,service_id) }


VXD_STACKCALL_SERVICE( 16,   7, void __cdecl IOS_Register(DRP* drp) );

extern "C"
VXD_STACKCALL_SERVICE( 51,   3, CONFIGRET __cdecl CONFIGMG_Get_Parent(DEVNODE* pdn, DEVNODE dn, ULONG flags) );

VXD_STACKCALL_SERVICE(  1,  97, int __cdecl _CopyPageTable(unsigned lin_page_num, unsigned npages, unsigned* buf, unsigned flags) );

#define PAGEMAPGLOBAL  0x40000000

VXD_STACKCALL_SERVICE(  1,  99, int __cdecl _LinPageLock(unsigned page, unsigned npages, unsigned flags) );
VXD_STACKCALL_SERVICE(  1,  99, int __cdecl _LinPageUnLock(unsigned page, unsigned npages, unsigned flags) );


__declspec(naked)
void __stdcall IOS_SendCommand(IOR* ior, DCB_BLOCKDEV* bdd) {
   __asm {
      pushad
      mov   esi,[esp+36]
      mov   edi,[esp+40]
//      mov   ebx,[esp+44]
      VXD_CALL(16,4)
      popad
      retn  8  // 12
   }
}


__declspec(naked)
unsigned __stdcall Create_Semaphore(unsigned token_count) {
   __asm {
      mov   ecx,[esp+4]
      VXD_CALL(1,37)
      jnc   noerror
      xor   eax,eax
noerror:
      retn  4
   }
}


__declspec(naked)
unsigned __stdcall Get_VMM_Reenter_Count() {
   __asm {
      VXD_CALL(1,6)
      mov eax,ecx
      retn
   }
}


// Wait_Semaphore flags
#define BLOCK_SVC_INTS			1
#define BLOCK_SVC_IF_INTS_LOCKED	2
#define BLOCK_ENABLE_INTS		4
#define BLOCK_POLL			8
#define BLOCK_THREAD_IDLE		16
#define BLOCK_FORCE_SVC_INTS		32

__declspec(naked)
void __stdcall Wait_Semaphore(unsigned handle, unsigned flags) {
   __asm {
      mov   eax,[esp+4]
      mov   ecx,[esp+8]
      VXD_CALL(1,39)
      retn  8
   }
}


__declspec(naked)
void __stdcall Signal_Semaphore_No_Switch(unsigned handle) {
   __asm {
      mov   eax,[esp+4]
      VXD_CALL(1,305)
      retn  4
   }
}


/*******************************************************************\
\*******************************************************************/


struct SRB {
   USHORT Length;          // 00
   UCHAR Function;
   UCHAR SrbStatus;
   UCHAR ScsiStatus;       // 04
   UCHAR PathId;
   UCHAR TargetId;
   UCHAR Lun;
   UCHAR QueueTag;         // 08
   UCHAR QueueAction;
   UCHAR CdbLength;
   UCHAR SenseInfoBufferLength;
   ULONG SrbFlags;         // 0C
   ULONG DataTransferLength;  // 10
   ULONG TimeOutValue;     // 14
   PVOID DataBuffer;       // 18
   PVOID SenseInfoBuffer;  // 1C
   SRB*  NextSrb;          // 20
   PVOID OriginalRequest;  // 24
   PVOID SrbExtension;     // 28
   ULONG QueueSortKey;     // 2C
   UCHAR Cdb[16];          // 30

   // The following are Win9x-only fields!
   PVOID SrbIopPointer;
   SRB*  SrbNextSrb;
   SRB*  SrbNextActiveSrb;
   UCHAR SrbRetryCount;
   UCHAR Filler[3];
};

#define SRB_FUNCTION_EXECUTE_SCSI   0x00


/*******************************************************************\
\*******************************************************************/


#ifdef IOS_SPY    // I used this code to reverse-engineer ASPI

unsigned old_IOS_SendCommand;

void PrintHex(unsigned char* p, int n) {
   if (signed(p) >= 0) return;
   for (int i=0; i<n; i+=16) {
      const char* fmt = " %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n";
      if (n-i < 16) {
         fmt += 5*(16-(n-i));
      }
      g_callbacks->DebugPrintf(fmt, p[i+0], p[i+1], p[i+2], p[i+3], p[i+4], p[i+5], p[i+6], p[i+7], 
         p[i+8], p[i+9], p[i+10], p[i+11], p[i+12], p[i+13], p[i+14], p[i+15]);
   }
}

void __stdcall IOSHookFunc(IOR* ior, DCB_BLOCKDEV* bdd, void* something) {
   if (ior->IOR_func != 15) return;

   g_callbacks->DebugPrintf("IOS_SendCommand(%08X,%08X,%08X), func=%02X\n", ior, bdd, something, ior->IOR_func);
   g_callbacks->DebugPrintf("VMM reenter count = %d\n", Get_VMM_Reenter_Count());

   const int offset = int(&((DCB*)0)->DCB_bdd);

   DCB* dcb = (DCB*)((unsigned char*)bdd - offset);

   unsigned char* iop = (unsigned char*)ior-100;
   g_callbacks->DebugPrintf("IOP (%08X):\n", iop);
   PrintHex(iop, 100);
//   g_callbacks->MemSet(ior->urequestor_usage+1, 0xEE, 16);
   g_callbacks->DebugPrintf("IOR (%08X):\n", iop+100);
   PrintHex(iop+100, sizeof(IOR));
   unsigned char* srb = (unsigned char*)((IOP*)iop)->IOP_srb;
   g_callbacks->DebugPrintf("SRB (%08X):\n", srb);
   PrintHex(srb, sizeof(SRB));
   if (ior->IOR_flags & IORF_PHYS_SGDS) {
      SGD* sgds = (SGD*)ior->IOR_sgd_lin_phys;
      for (int i=0; i<ior->IOR_num_sgds; ++i) {
         g_callbacks->DebugPrintf("SGD #%d: %08X %08X\n", i, sgds[i].SG_buff_ptr, sgds[i].SG_buff_size);
      }
   }
   unsigned char* srb_extension = srb + sizeof(SRB);
   g_callbacks->DebugPrintf("SRB extension (%08X):\n", srb_extension);
   PrintHex(srb_extension, dcb->DCB_srb_ext_size);
}

__declspec(naked)
void HookIOS() {
   __asm {
      push  esi
      mov   eax,0x00100004 // IOS_SendCommand
      mov   esi,offset hookproc
      VXD_CALL(1,144)      // Hook_Device_Service
      pop   esi
      retn

      jmp   short hookproc
      jmp   [old_IOS_SendCommand]
hookproc:
      pushad
      pushfd
      push  ebx
      push  edi
      push  esi
      call  IOSHookFunc
      popfd
      popad
      jmp   [old_IOS_SendCommand]
   }
}

#endif


/*******************************************************************\
\*******************************************************************/


ILB ilb;


void __cdecl AsyncEventProc(AEP* paep) {
//   paep->AEP_result = (paep->AEP_func == AEP_BOOT_COMPLETE) ? AEP_SUCCESS : AEP_FAILURE;
   paep->AEP_result = AEP_SUCCESS;
}


void SPTInit() {
   if (ilb.ILB_service_rtn)
      return;

   static DRP drp = {
      {'X','X','X','X','X','X','X','X'},
      DRP_SCSI_LAYER,
      AsyncEventProc,
      &ilb,
      {'D','V','D','S','y','n','t','h',' ','d','e','v','i','c','e',' '},
   };
   IOS_Register(&drp);
   g_callbacks->DebugPrintf("after IOS_Register: DRP_reg_result=%x ILB_service_rtn=%x\n", drp.DRP_reg_result, ilb.ILB_service_rtn);

#ifdef IOS_SPY
   HookIOS();
#endif
}

inline void ILBServiceRtn(ISP* pisp) {
   ilb.ILB_service_rtn(pisp);
}

inline bool ILBIOCriteriaRtn(IOR* pior) {
   return ilb.ILB_io_criteria_rtn(pior) == 0;
}

inline bool ILBIntIOCriteriaRtn(IOP* piop) {
   return ilb.ILB_int_io_criteria_rtn(piop) == 0;
}

__declspec(naked)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -