📄 mirrordrive95_kernel.cpp
字号:
/***********************************************************************
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 + -