📄 pcidp.asm
字号:
TITLE C:\Kernel2000\pcidp.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
$$SYMBOLS SEGMENT BYTE USE32 'DEBSYM'
$$SYMBOLS ENDS
$$TYPES SEGMENT BYTE USE32 'DEBTYP'
$$TYPES ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
; COMDAT _RtlConvertLongToLargeInteger@4
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _DriverEntry@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPAddDevice@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPDispatchPower@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPDispatchPnp@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPDeviceControl@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPCreateClose@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPCleanup@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPUnload@4
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPCancelInterrupt@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPForDpcIsr@16
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPISR@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PCIDPCancelMapDMARoutine@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _GUID_PCIDP_INTERFACE
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC _GUID_PCIDP_INTERFACE
; COMDAT _GUID_PCIDP_INTERFACE
CONST SEGMENT
_GUID_PCIDP_INTERFACE DD 0b93c517H
DW 0dadaH
DW 04be9H
DB 09fH
DB 0beH
DB 089H
DB 018H
DB 08bH
DB 039H
DB 08eH
DB 05H
CONST ENDS
PUBLIC _DriverEntry@8
PUBLIC _PCIDPAddDevice@8
PUBLIC _PCIDPDispatchPower@8
PUBLIC _PCIDPDispatchPnp@8
PUBLIC _PCIDPDeviceControl@8
PUBLIC _PCIDPCreateClose@8
PUBLIC _PCIDPCleanup@8
PUBLIC _PCIDPUnload@4
EXTRN _DbgBreakPoint@0:NEAR
EXTRN _DbgPrint:NEAR
; COMDAT _DriverEntry@8
; File c:\kernel2000\pcidp.c
_TEXT SEGMENT
$SG8423 DB '[PCIDP]->Entering DriverEntry...', 0aH, 00H
_DriverObject$ = 8
_DriverEntry@8 PROC NEAR ; COMDAT
; 37 :
; 38 : // Debug entry point
; 39 : DbgPrint("[PCIDP]->Entering DriverEntry...\n"); //debug
push OFFSET FLAT:$SG8423
call _DbgPrint
pop ecx
; 40 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
; 41 :
; 42 : // Initialize the driver object with this driver's entry points.
; 43 : DriverObject->MajorFunction[IRP_MJ_CREATE] = PCIDPCreateClose;
mov eax, DWORD PTR _DriverObject$[esp-4]
mov ecx, OFFSET FLAT:_PCIDPCreateClose@8
mov DWORD PTR [eax+56], ecx
; 44 : DriverObject->MajorFunction[IRP_MJ_CLOSE] = PCIDPCreateClose;
mov DWORD PTR [eax+64], ecx
; 45 : DriverObject->DriverExtension->AddDevice = PCIDPAddDevice;
mov ecx, DWORD PTR [eax+24]
mov DWORD PTR [ecx+4], OFFSET FLAT:_PCIDPAddDevice@8
; 46 : DriverObject->MajorFunction[IRP_MJ_PNP] = PCIDPDispatchPnp;
mov DWORD PTR [eax+164], OFFSET FLAT:_PCIDPDispatchPnp@8
; 47 : DriverObject->MajorFunction[IRP_MJ_POWER] = PCIDPDispatchPower;
mov DWORD PTR [eax+144], OFFSET FLAT:_PCIDPDispatchPower@8
; 48 : DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = PCIDPDeviceControl;
mov DWORD PTR [eax+112], OFFSET FLAT:_PCIDPDeviceControl@8
; 49 : DriverObject->MajorFunction[IRP_MJ_CLEANUP] = PCIDPCleanup;
mov DWORD PTR [eax+128], OFFSET FLAT:_PCIDPCleanup@8
; 50 : DriverObject->DriverUnload = (PDRIVER_UNLOAD)PCIDPUnload;
mov DWORD PTR [eax+52], OFFSET FLAT:_PCIDPUnload@4
; 51 : //DriverObject->DriverStartIo = (PDRIVER_STARTIO)PCIDPStartIo; //to have OS manage queued IRPs
; 52 :
; 53 : // Initialize any other driver global data.
; 54 :
; 55 : // Save a copy of the registry path pointed to by RegistryPath.
; 56 :
; 57 : // Register for driver reinitialization.
; 58 : // IoRegisterDriverReinitialization();
; 59 :
; 60 : return STATUS_SUCCESS;
xor eax, eax
; 61 : }
ret 8
_DriverEntry@8 ENDP
_TEXT ENDS
EXTRN __imp__MmProbeAndLockPages@12:NEAR
EXTRN __imp__MmBuildMdlForNonPagedPool@4:NEAR
EXTRN __imp__MmGetPhysicalAddress@4:NEAR
EXTRN __imp__MmAllocateContiguousMemory@12:NEAR
EXTRN __imp__IoRegisterDeviceInterface@16:NEAR
EXTRN __imp__KeInitializeEvent@12:NEAR
EXTRN __imp__IoAllocateMdl@20:NEAR
EXTRN __imp__IoAttachDeviceToDeviceStack@8:NEAR
EXTRN __imp__IoCreateDevice@28:NEAR
EXTRN __imp__IoDeleteDevice@4:NEAR
; COMDAT _PCIDPAddDevice@8
; File c:\kernel2000\pcidp.c
_TEXT SEGMENT
$SG8436 DB '[PCIDP]->Entering AddDevice...', 0aH, 00H
$SG8458 DB '[PCIDP]->Leaving AddDevice, status=%ld...', 0aH, 00H
_DriverObject$ = 8
_PhysicalDeviceObject$ = 12
_NTStatus$ = 8
_DeviceObject$ = -4
_PhysicalAddress$ = -12
_PCIDPAddDevice@8 PROC NEAR ; COMDAT
; 72 : ){
push ebp
mov ebp, esp
sub esp, 12 ; 0000000cH
push ebx
push esi
push edi
; 73 : NTSTATUS NTStatus;
; 74 : PDEVICE_OBJECT DeviceObject;
; 75 : PPCIDP_EXTENSION ObjExt;
; 76 : PHYSICAL_ADDRESS MaxAddress;
; 77 : PHYSICAL_ADDRESS PhysicalAddress;
; 78 :
; 79 : // Debug entry point
; 80 : DbgPrint("[PCIDP]->Entering AddDevice...\n"); //debug
push OFFSET FLAT:$SG8436
call _DbgPrint
pop ecx
; 81 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
; 82 :
; 83 : // Create the device space that will be associated with this driver.
; 84 : //todo: how to set up security attributes so the app. can call this driver
; 85 : // (because of the FILE_DEVICE_SECURE_OPEN parameter).
; 86 : NTStatus = IoCreateDevice(
; 87 : IN DriverObject, // The driver object
; 88 : IN sizeof(PCIDP_EXTENSION), // Size (bytes) of the device ext.
; 89 : IN NULL, // The device name; let the OS name it
; 90 : IN FILE_DEVICE_PCIDP00, // The device type
; 91 : IN FILE_DEVICE_SECURE_OPEN, // Device characteristics
; 92 : IN FALSE, // Exclusive Device flag
; 93 : OUT &DeviceObject // New created device object
; 94 : );
lea eax, DWORD PTR _DeviceObject$[ebp]
xor ebx, ebx
push eax
push ebx
push 256 ; 00000100H
push 49920 ; 0000c300H
push ebx
push 160 ; 000000a0H
push DWORD PTR _DriverObject$[ebp]
call DWORD PTR __imp__IoCreateDevice@28
; 95 : if(NTStatus != STATUS_SUCCESS)
cmp eax, ebx
mov DWORD PTR _NTStatus$[ebp], eax
jne $Exit$8441
; 96 : goto Exit;
; 97 :
; 98 : // Initialize the driver's extended object.
; 99 : ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
mov eax, DWORD PTR _DeviceObject$[ebp]
; 100 : RtlZeroMemory(ObjExt, sizeof(PCIDP_EXTENSION));
push 40 ; 00000028H
pop ecx
mov esi, DWORD PTR [eax+40]
xor eax, eax
mov edi, esi
rep stosd
; 101 :
; 102 : //ObjExt->BusNumber = BusNumber; - not needed
; 103 : //ObjExt->SlotNumber = SlotNumber; - not needed
; 104 : //ObjExt->BoardNumber = BoardNumber; - not needed
; 105 : //ObjExt->BaseAddresses[0] = CardInfo.u.type0.BaseAddresses[0]; - not needed
; 106 : //ObjExt->BaseAddresses[1] = CardInfo.u.type0.BaseAddresses[1]; - not needed
; 107 : //ObjExt->BaseAddresses[2] = CardInfo.u.type0.BaseAddresses[2]; - not needed
; 108 : //ObjExt->BaseAddresses[3] = CardInfo.u.type0.BaseAddresses[3]; - not needed
; 109 : //ObjExt->BaseAddresses[4] = CardInfo.u.type0.BaseAddresses[4]; - not needed
; 110 : //ObjExt->BaseAddresses[5] = CardInfo.u.type0.BaseAddresses[5]; - not needed
; 111 : //ObjExt->MemoryAccess - enum resources (Start)
; 112 : //ObjExt->IOAccess - enum resources (Start)
; 113 : //ObjExt->MemoryAccessLength - enum resources (Start)
; 114 : //ObjExt->IOAccessLength - enum resources (Start)
; 115 : //ObjExt->MemoryBase - initialized by MmMapIoSpace call (Start)
; 116 : //ObjExt->IOBase - not needed
; 117 : //ObjExt->InterruptObject - initialized by IoConnectInterrupt call (Start)
; 118 : //ObjExt->InterruptData - used in DpcISR and ISR
; 119 :
; 120 : ObjExt->LLData.IsEmpty = TRUE;
; 121 : ObjExt->LLData.CurrentLink = NULL;
; 122 : ObjExt->LLData.InsertedCount = 0;
; 123 : ObjExt->LLData.FreeMax = 0;
; 124 :
; 125 : //ObjExt->LListSpin - initialized by KeInitializeSpinLock call (AddDevice)
; 126 : //ObjExt->VirtualDMAAddress - initialized by MmAllocateContiguousMemory (AddDevice)
; 127 : //ObjExt->PhysicalDMAAddress - initialized by MmGetPhysicalAddress (AddDevice)
; 128 : //ObjExt->MDL - initialized by IoAllocateMdl (AddDevice)
; 129 : //ObjExt->SymbolicLinkName - initialized by IoRegisterDeviceInterface (AddDevice)
; 130 : //ObjExt->PhysicalDeviceObject - not needed
; 131 : //ObjExt->NextLowerDeviceObject - initialized by IoAttachDeviceToDeviceStack (AddDevice)
; 132 : //ObjExt->WaitEvent - initialized by KeInitializeEvent (AddDevice)
; 133 :
; 134 :
; 135 : // Now create a symbolic link an application can use to gain access to the
; 136 : // driver's services for this device.
; 137 : NTStatus = IoRegisterDeviceInterface(
; 138 : IN PhysicalDeviceObject, //The PDO
; 139 : IN &GUID_PCIDP_INTERFACE, //GUID for the interface class
; 140 : IN NULL, //Reference string (not used)
; 141 : OUT &ObjExt->SymbolicLinkName //returned symbolic link name
; 142 : );
lea eax, DWORD PTR [esi+132]
mov BYTE PTR [esi+104], 1
push eax
push ebx
push OFFSET FLAT:_GUID_PCIDP_INTERFACE
mov DWORD PTR [esi+112], ebx
push DWORD PTR _PhysicalDeviceObject$[ebp]
mov WORD PTR [esi+106], bx
mov WORD PTR [esi+108], bx
call DWORD PTR __imp__IoRegisterDeviceInterface@16
; 143 : if(NTStatus != STATUS_SUCCESS)
cmp eax, ebx
mov DWORD PTR _NTStatus$[ebp], eax
jne SHORT $ExitA$8448
; 144 : goto ExitA;
; 145 :
; 146 : // Attach the device object to its device stack.
; 147 : ObjExt->NextLowerDeviceObject = IoAttachDeviceToDeviceStack(
; 148 : DeviceObject,
; 149 : PhysicalDeviceObject
; 150 : );
push DWORD PTR _PhysicalDeviceObject$[ebp]
push DWORD PTR _DeviceObject$[ebp]
call DWORD PTR __imp__IoAttachDeviceToDeviceStack@8
; 151 : if(ObjExt->NextLowerDeviceObject == NULL){
cmp eax, ebx
mov DWORD PTR [esi+140], eax
jne SHORT $L8450
; 152 : NTStatus = STATUS_UNSUCCESSFUL; //todo: more meaningful error code
mov DWORD PTR _NTStatus$[ebp], -1073741823 ; c0000001H
$ExitA$8448:
; 198 : goto Exit;
; 199 :
; 200 : ExitA:
; 201 : IoDeleteDevice (DeviceObject);
push DWORD PTR _DeviceObject$[ebp]
call DWORD PTR __imp__IoDeleteDevice@4
jmp SHORT $Exit$8441
$L8450:
; 153 : goto ExitA;
; 154 : }
; 155 :
; 156 : // Set up an synchro event for the start device IRP.
; 157 : KeInitializeEvent(&ObjExt->WaitEvent, SynchronizationEvent, FALSE);
push ebx
lea eax, DWORD PTR [esi+144]
push 1
push eax
call DWORD PTR __imp__KeInitializeEvent@12
; 158 :
; 159 : // Allocate a contiguous span of memory for DMA usage.
; 160 : MaxAddress.LowPart = 0xFFFFFFFF;
; 161 : MaxAddress.HighPart = 0;
xor ecx, ecx
or eax, -1
; 162 : ObjExt->VirtualDMAAddress = MmAllocateContiguousMemory(
; 163 : IN (ULONG)DMASize, //16K
; 164 : IN MaxAddress //Full 32 bit address range
; 165 : );
push ecx
mov edi, 16384 ; 00004000H
push eax
push edi
call DWORD PTR __imp__MmAllocateContiguousMemory@12
; 166 :
; 167 : if(ObjExt->VirtualDMAAddress != NULL){
cmp eax, ebx
mov DWORD PTR [esi+120], eax
je SHORT $L8454
; 168 : PhysicalAddress = MmGetPhysicalAddress(
; 169 : ObjExt->VirtualDMAAddress
; 170 : );
push eax
call DWORD PTR __imp__MmGetPhysicalAddress@4
; 171 : ObjExt->PhysicalDMAAddress = PhysicalAddress.LowPart;
; 172 :
; 173 : ObjExt->MDL = IoAllocateMdl(
; 174 : ObjExt->VirtualDMAAddress,
; 175 : DMASize,
; 176 : FALSE,
; 177 : FALSE,
; 178 : NULL
; 179 : );
push ebx
push ebx
push ebx
push edi
push DWORD PTR [esi+120]
mov DWORD PTR _PhysicalAddress$[ebp+4], edx
mov DWORD PTR [esi+124], eax
call DWORD PTR __imp__IoAllocateMdl@20
add esi, 128 ; 00000080H
; 180 :
; 181 : if(ObjExt->MDL){
cmp eax, ebx
mov DWORD PTR [esi], eax
je SHORT $L8457
; 182 : MmBuildMdlForNonPagedPool(ObjExt->MDL);
push eax
call DWORD PTR __imp__MmBuildMdlForNonPagedPool@4
; 183 : MmProbeAndLockPages(
; 184 : ObjExt->MDL,
; 185 : KernelMode,
; 186 : IoModifyAccess
; 187 : );
push 2
push ebx
push DWORD PTR [esi]
call DWORD PTR __imp__MmProbeAndLockPages@12
; 188 : }
; 189 : }
; 190 :
; 191 : // Could not allocate memory for DMA but that is not
; 192 : // a show-stopper.
; 193 : else
jmp SHORT $L8457
$L8454:
; 194 : ObjExt->PhysicalDMAAddress = 0;
mov DWORD PTR [esi+124], ebx
$L8457:
; 195 :
; 196 : // To get here means we were successful.
; 197 : DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
mov eax, DWORD PTR _DeviceObject$[ebp]
and BYTE PTR [eax+28], 127 ; 0000007fH
$Exit$8441:
; 202 :
; 203 : Exit:
; 204 :
; 205 : // Debug exit point
; 206 : DbgPrint("[PCIDP]->Leaving AddDevice, status=%ld...\n", NTStatus); //debug
push DWORD PTR _NTStatus$[ebp]
push OFFSET FLAT:$SG8458
call _DbgPrint
pop ecx
pop ecx
; 207 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
; 208 :
; 209 : return NTStatus;
mov eax, DWORD PTR _NTStatus$[ebp]
pop edi
pop esi
pop ebx
; 210 : }
leave
ret 8
_PCIDPAddDevice@8 ENDP
_TEXT ENDS
EXTRN __imp__PoCallDriver@8:NEAR
EXTRN __imp__PoStartNextPowerIrp@4:NEAR
; COMDAT _PCIDPDispatchPower@8
; File c:\kernel2000\pcidp.c
_TEXT SEGMENT
$SG8466 DB '[PCIDP]->Entering DispatchPower...', 0aH, 00H
$SG8468 DB '[PCIDP]->Leaving DispatchPower, status=%ld...', 0aH, 00H
_DeviceObject$ = 8
_Irp$ = 12
_PCIDPDispatchPower@8 PROC NEAR ; COMDAT
; 221 : ){
push esi
push edi
; 222 : PPCIDP_EXTENSION ObjExt;
; 223 : NTSTATUS NTStatus;
; 224 :
; 225 : // Debug entry point
; 226 : DbgPrint("[PCIDP]->Entering DispatchPower...\n"); //debug
push OFFSET FLAT:$SG8466
call _DbgPrint
pop ecx
; 227 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
; 228 :
; 229 : ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
mov eax, DWORD PTR _DeviceObject$[esp+4]
; 230 :
; 231 : PoStartNextPowerIrp(Irp);
mov esi, DWORD PTR _Irp$[esp+4]
push esi
mov edi, DWORD PTR [eax+40]
call DWORD PTR __imp__PoStartNextPowerIrp@4
; 232 : IoSkipCurrentIrpStackLocation(Irp);
inc BYTE PTR [esi+35]
add DWORD PTR [esi+96], 36 ; 00000024H
; 233 : NTStatus = PoCallDriver(ObjExt->NextLowerDeviceObject, Irp);
push esi
push DWORD PTR [edi+140]
call DWORD PTR __imp__PoCallDriver@8
; 234 :
; 235 : // Debug exit point
; 236 : DbgPrint("[PCIDP]->Leaving DispatchPower, status=%ld...\n", NTStatus); //debug
push eax
push OFFSET FLAT:$SG8468
call _DbgPrint
pop ecx
pop ecx
; 237 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
pop edi
; 238 :
; 239 : return STATUS_SUCCESS;
xor eax, eax
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -