📄 pcidpprivateold.asm
字号:
TITLE C:\Kernel2000\pcidpprivate.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 _StartDevice@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _StopDevice@4
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _CancelStopDevice@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _RemoveDevice@4
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _DeviceCompletionRoutine@12
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _GetResources@16
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _GetNextEntry@16
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _PutBackEntry@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _FreeEntry@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _GetFreeEntry@4
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _InsertEntry@8
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
; COMDAT _DeleteAllEntries@4
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC _StartDevice@8
PUBLIC _DeviceCompletionRoutine@12
PUBLIC _GetResources@16
EXTRN __imp__MmMapIoSpace@16:NEAR
EXTRN __imp__IoSetDeviceInterfaceState@8:NEAR
EXTRN __imp__KeInitializeDpc@12:NEAR
EXTRN _DbgBreakPoint@0:NEAR
EXTRN _DbgPrint:NEAR
EXTRN __imp__KeWaitForSingleObject@20:NEAR
EXTRN __imp__KeInitializeSpinLock@4:NEAR
EXTRN __imp_@IofCallDriver@8:NEAR
EXTRN __imp__IoConnectInterrupt@44:NEAR
EXTRN _PCIDPForDpcIsr@16:NEAR
EXTRN _PCIDPISR@8:NEAR
; COMDAT _StartDevice@8
; File c:\kernel2000\pcidpprivate.c
_TEXT SEGMENT
$SG8430 DB '[PCIDP]->Entering StartDevice...', 0aH, 00H
ORG $+2
$SG8468 DB '[PCIDP]->Leaving StartDevice, status=%ld...', 0aH, 00H
_DeviceObject$ = 8
_Irp$ = 12
_NTStatus$ = -12
_LIdx$ = -8
_DIdx$ = -4
_StartDevice@8 PROC NEAR ; COMDAT
; 24 : ){
push ebp
mov ebp, esp
sub esp, 12 ; 0000000cH
; 25 : NTSTATUS NTStatus;
; 26 : BOOLEAN Status;
; 27 : ULONG LIdx;
; 28 : ULONG DIdx;
; 29 : CM_RESOURCE_LIST* Resources;
; 30 : MEMORY_CACHING_TYPE CacheType;
; 31 : KINTERRUPT_MODE InterruptMode;
; 32 : PIO_STACK_LOCATION IrpStack;
; 33 : PPCIDP_EXTENSION ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
mov eax, DWORD PTR _DeviceObject$[ebp]
push ebx
push esi
push edi
mov ebx, DWORD PTR [eax+40]
; 34 :
; 35 : // Debug entry point
; 36 : DbgPrint("[PCIDP]->Entering StartDevice...\n"); //debug
push OFFSET FLAT:$SG8430
call _DbgPrint
pop ecx
; 37 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
; 38 :
; 39 : IoSetDeviceInterfaceState(&ObjExt->SymbolicLinkName, TRUE);
lea eax, DWORD PTR [ebx+132]
push 1
push eax
call DWORD PTR __imp__IoSetDeviceInterfaceState@8
; 40 :
; 41 : // Let the lower level drivers handle the IRP first.
; 42 : IoCopyCurrentIrpStackLocationToNext(IN Irp);
mov edx, DWORD PTR _Irp$[ebp]
push 7
pop ecx
mov esi, DWORD PTR [edx+96]
lea eax, DWORD PTR [esi-36]
mov edi, eax
rep movsd
and BYTE PTR [eax+3], 0
; 43 :
; 44 : IoSetCompletionRoutine(
; 45 : IN Irp,
; 46 : IN DeviceCompletionRoutine,
; 47 : IN NULL, //Context
; 48 : IN TRUE, //InvokeOnSuccess
; 49 : IN TRUE, //InvokeOnError
; 50 : IN TRUE //InvokeOnCancel
; 51 : );
mov eax, DWORD PTR [edx+96]
sub eax, 36 ; 00000024H
xor edi, edi
mov DWORD PTR [eax+28], OFFSET FLAT:_DeviceCompletionRoutine@12
mov DWORD PTR [eax+32], edi
mov BYTE PTR [eax+3], 224 ; 000000e0H
; 52 :
; 53 : NTStatus = IoCallDriver(ObjExt->NextLowerDeviceObject, Irp);
mov ecx, DWORD PTR [ebx+140]
call DWORD PTR __imp_@IofCallDriver@8
; 54 : if(NTStatus == STATUS_PENDING){
cmp eax, 259 ; 00000103H
mov DWORD PTR _NTStatus$[ebp], eax
jne SHORT $L8442
; 55 : KeWaitForSingleObject(
; 56 : IN &ObjExt->WaitEvent,
; 57 : IN Executive, //WaitReason
; 58 : IN KernelMode, //WaitMode
; 59 : IN FALSE, //Alertable
; 60 : IN NULL //Timeout
; 61 : );
push edi
push edi
push edi
lea eax, DWORD PTR [ebx+144]
push edi
push eax
call DWORD PTR __imp__KeWaitForSingleObject@20
; 62 : NTStatus = Irp->IoStatus.Status;
mov eax, DWORD PTR _Irp$[ebp]
mov eax, DWORD PTR [eax+24]
mov DWORD PTR _NTStatus$[ebp], eax
$L8442:
; 63 : }
; 64 :
; 65 : // Processed after the lower level drivers have successfully finished with the IRP.
; 66 : if(NT_SUCCESS(NTStatus)){
cmp DWORD PTR _NTStatus$[ebp], edi
jl $L8459
; 67 : IrpStack = IoGetCurrentIrpStackLocation(IN Irp);
; 68 : Resources = IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
mov eax, DWORD PTR _Irp$[ebp]
mov eax, DWORD PTR [eax+96]
mov esi, DWORD PTR [eax+8]
; 69 :
; 70 : // Get the I/O port attributes.
; 71 : Status = GetResources(Resources, CmResourceTypePort, &LIdx, &DIdx);
lea eax, DWORD PTR _DIdx$[ebp]
push eax
lea eax, DWORD PTR _LIdx$[ebp]
push eax
push 1
push esi
call _GetResources@16
; 72 : if(Status == TRUE){
cmp al, 1
jne SHORT $L8446
; 73 : ObjExt->IOAccess = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Port.Start;
mov eax, DWORD PTR _LIdx$[ebp]
mov ecx, DWORD PTR _DIdx$[ebp]
lea eax, DWORD PTR [ecx+eax*2]
shl eax, 4
mov ecx, DWORD PTR [eax+esi+24]
mov DWORD PTR [ebx+8], ecx
mov eax, DWORD PTR [eax+esi+28]
mov DWORD PTR [ebx+12], eax
; 74 : ObjExt->IOAccessLength = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Port.Length;
mov eax, DWORD PTR _DIdx$[ebp]
mov ecx, DWORD PTR _LIdx$[ebp]
lea eax, DWORD PTR [eax+ecx*2+2]
shl eax, 4
mov eax, DWORD PTR [eax+esi]
mov DWORD PTR [ebx+20], eax
; 75 : }
; 76 : else{
jmp SHORT $L8447
$L8446:
; 77 : //ObjExt->IOAccess = 0;
; 78 : ObjExt->IOAccessLength = 0;
mov DWORD PTR [ebx+20], edi
$L8447:
; 79 : //NTStatus = STATUS_INSUFFICIENT_RESOURCES;
; 80 : //Irp->IoStatus.Status = NTStatus;
; 81 : //return NTStatus;
; 82 : }
; 83 :
; 84 : // Map to the memory base space in order to support driver services.
; 85 : Status = GetResources(Resources, CmResourceTypeMemory, &LIdx, &DIdx);
lea eax, DWORD PTR _DIdx$[ebp]
push eax
lea eax, DWORD PTR _LIdx$[ebp]
push eax
push 3
push esi
call _GetResources@16
; 86 : if(Status == TRUE){
cmp al, 1
jne $L8448
; 87 : if(
; 88 : Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 89 : CM_RESOURCE_MEMORY_COMBINEDWRITE
; 90 : )
mov eax, DWORD PTR _DIdx$[ebp]
mov ecx, DWORD PTR _LIdx$[ebp]
lea eax, DWORD PTR [eax+ecx*2]
shl eax, 4
add eax, esi
mov cx, WORD PTR [eax+22]
test cl, 8
je SHORT $L8449
; 91 : CacheType = MmWriteCombined;
push 2
pop ecx
; 92 : else if(
jmp SHORT $L8451
$L8449:
; 93 : Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 94 : CM_RESOURCE_MEMORY_CACHEABLE
; 95 : )
movzx ecx, cl
shr ecx, 5
and ecx, 1
$L8451:
; 96 : CacheType = MmCached;
; 97 : else
; 98 : CacheType = MmNonCached;
; 99 :
; 100 : ObjExt->MemoryAccess = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Memory.Start;
mov edx, DWORD PTR [eax+24]
; 101 : ObjExt->MemoryAccessLength = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Memory.Length;
; 102 :
; 103 : ObjExt->MemoryBase = (ULONG*)MmMapIoSpace(
; 104 : IN ObjExt->MemoryAccess,
; 105 : IN ObjExt->MemoryAccessLength,
; 106 : IN CacheType
; 107 : );
push ecx
mov DWORD PTR [ebx], edx
mov eax, DWORD PTR [eax+28]
mov DWORD PTR [ebx+4], eax
mov eax, DWORD PTR _DIdx$[ebp]
mov edx, DWORD PTR _LIdx$[ebp]
lea eax, DWORD PTR [eax+edx*2+2]
shl eax, 4
mov eax, DWORD PTR [eax+esi]
push eax
mov DWORD PTR [ebx+16], eax
push DWORD PTR [ebx+4]
push DWORD PTR [ebx]
call DWORD PTR __imp__MmMapIoSpace@16
; 108 : if(ObjExt->MemoryBase == NULL){
cmp eax, edi
mov DWORD PTR [ebx+24], eax
jne SHORT $L8455
; 109 : NTStatus = STATUS_SOME_NOT_MAPPED;
; 110 : //Irp->IoStatus.Status = NTStatus;
; 111 : return NTStatus;
mov eax, 263 ; 00000107H
jmp $L8419
$L8455:
; 118 : }
; 119 :
; 120 : // Map the PCI board's IRQ to a system vector.
; 121 : // todo: resolve the interrupt pin source
; 122 : ObjExt->InterruptObject = 0;
; 123 : //if((ULONG)CardInfo.u.type0.InterruptPin != 0){ //use IRP_MN_READ_CONFIG
; 124 :
; 125 : // Connect the driver to the IRQ.
; 126 : Status = GetResources(Resources, CmResourceTypeInterrupt, &LIdx, &DIdx);
lea eax, DWORD PTR _DIdx$[ebp]
mov DWORD PTR [ebx+32], edi
push eax
lea eax, DWORD PTR _LIdx$[ebp]
push eax
push 2
push esi
call _GetResources@16
; 127 : if(Status == TRUE){
cmp al, 1
jne SHORT $L8459
; 128 : if(
; 129 : Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 130 : CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
; 131 : )
; 132 : InterruptMode = LevelSensitive;
; 133 : else
; 134 : InterruptMode = Latched;
; 135 :
; 136 : NTStatus = IoConnectInterrupt(
; 137 : OUT &ObjExt->InterruptObject,
; 138 : IN PCIDPISR, //pointer to ISR
; 139 : IN DeviceObject, //context to send to ISR
; 140 : IN NULL, //optional spinlock
; 141 : IN Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Vector, //mapped interrupt vector u.Interrupt.Vector
; 142 : IN (KIRQL)Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Level, //DIRQL u.Interrupt.Level
; 143 : IN (KIRQL)Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Level, //DIRQL u.Interrupt.Level
; 144 : IN InterruptMode, //latched/level interrupt
; 145 : IN TRUE, //shareable interrupt
; 146 : IN Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Affinity, //processor enable mask u.Interrupt.Affinity
; 147 : IN FALSE //floating save (false for X86)
; 148 : );
mov edi, DWORD PTR _DIdx$[ebp]
mov ecx, DWORD PTR _LIdx$[ebp]
push 0
lea eax, DWORD PTR [edi+ecx*2]
lea ecx, DWORD PTR [edi+ecx*2+2]
shl ecx, 4
shl eax, 4
push DWORD PTR [ecx+esi]
add eax, esi
mov edi, DWORD PTR _DeviceObject$[ebp]
lea esi, DWORD PTR [ebx+32]
mov dl, BYTE PTR [eax+24]
push 1
push 1
push edx
push edx
push DWORD PTR [eax+28]
push 0
push edi
push OFFSET FLAT:_PCIDPISR@8
push esi
call DWORD PTR __imp__IoConnectInterrupt@44
; 149 : if(NTStatus != STATUS_SUCCESS){
test eax, eax
mov DWORD PTR _NTStatus$[ebp], eax
je SHORT $L8466
; 150 : ObjExt->InterruptObject = 0;
and DWORD PTR [esi], 0
; 151 : //Irp->IoStatus.Status = NTStatus;
; 152 : return NTStatus;
jmp SHORT $L8419
$L8466:
; 153 : }
; 154 :
; 155 : // Register the PCIDPForDpcIsr routine with this device
; 156 : // driver.
; 157 : IoInitializeDpcRequest(
; 158 : IN DeviceObject,
; 159 : IN PCIDPForDpcIsr
; 160 : );
push edi
add edi, 116 ; 00000074H
push OFFSET FLAT:_PCIDPForDpcIsr@16
push edi
call DWORD PTR __imp__KeInitializeDpc@12
; 161 :
; 162 : // Set up the spin lock for the linked list holding pending IRPs.
; 163 : KeInitializeSpinLock(&ObjExt->LListSpin);
add ebx, 116 ; 00000074H
push ebx
call DWORD PTR __imp__KeInitializeSpinLock@4
$L8459:
; 164 : }
; 165 : //}
; 166 : }
; 167 :
; 168 : // Debug exit point
; 169 : DbgPrint("[PCIDP]->Leaving StartDevice, status=%ld...\n", NTStatus); //debug
push DWORD PTR _NTStatus$[ebp]
push OFFSET FLAT:$SG8468
call _DbgPrint
pop ecx
pop ecx
; 170 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
; 171 :
; 172 : return NTStatus;
mov eax, DWORD PTR _NTStatus$[ebp]
$L8419:
pop edi
pop esi
pop ebx
; 173 : }
leave
ret 8
$L8448:
; 112 : }
; 113 : }
; 114 : else{
; 115 : NTStatus = STATUS_INSUFFICIENT_RESOURCES;
; 116 : //Irp->IoStatus.Status = NTStatus;
; 117 : return NTStatus;
mov eax, -1073741670 ; c000009aH
jmp SHORT $L8419
_StartDevice@8 ENDP
_TEXT ENDS
PUBLIC _StopDevice@4
PUBLIC _DeleteAllEntries@4
EXTRN __imp__MmUnmapIoSpace@8:NEAR
EXTRN __imp__IoDisconnectInterrupt@4:NEAR
; COMDAT _StopDevice@4
; File c:\kernel2000\pcidpprivate.c
_TEXT SEGMENT
$SG8474 DB '[PCIDP]->Entering StopDevice...', 0aH, 00H
_DeviceObject$ = 8
_StopDevice@4 PROC NEAR ; COMDAT
; 177 :
; 178 : PPCIDP_EXTENSION ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
mov eax, DWORD PTR _DeviceObject$[esp-4]
push esi
; 179 :
; 180 : // Debug entry point
; 181 : DbgPrint("[PCIDP]->Entering StopDevice...\n"); //debug
push OFFSET FLAT:$SG8474
mov esi, DWORD PTR [eax+40]
call _DbgPrint
pop ecx
; 182 : DbgBreakPoint(); //debug
call _DbgBreakPoint@0
; 183 :
; 184 : // Disconnect the driver from the interrupt if enabled.
; 185 : if(ObjExt->InterruptObject)
mov eax, DWORD PTR [esi+32]
test eax, eax
je SHORT $L8475
; 186 : IoDisconnectInterrupt(ObjExt->InterruptObject);
push eax
call DWORD PTR __imp__IoDisconnectInterrupt@4
$L8475:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -