📄 pcidpprivate.cod
字号:
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 __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
_TEXT SEGMENT
_DeviceObject$ = 8
_Irp$ = 12
_LIdx$ = -8
_DIdx$ = -4
_InterruptMode$ = -16
_Shareable$ = -12
_InterruptLevel$ = 12
_StartDevice@8 PROC NEAR ; COMDAT
; 24 : ){
00000 55 push ebp
00001 8b ec mov ebp, esp
00003 83 ec 10 sub esp, 16 ; 00000010H
; 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 : BOOLEAN Shareable;
; 33 : KIRQL InterruptLevel;
; 34 : PIO_STACK_LOCATION IrpStack;
; 35 : PPCIDP_EXTENSION ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
00006 8b 45 08 mov eax, DWORD PTR _DeviceObject$[ebp]
00009 53 push ebx
0000a 56 push esi
0000b 57 push edi
0000c 8b 58 28 mov ebx, DWORD PTR [eax+40]
; 36 :
; 37 : // Debug entry point
; 38 : //DbgPrint("[PCIDP]->Entering StartDevice...\n"); //debug
; 39 : //DbgBreakPoint(); //debug
; 40 :
; 41 : IoSetDeviceInterfaceState(&ObjExt->SymbolicLinkName, TRUE);
0000f 6a 01 push 1
00011 8d 83 84 00 00
00 lea eax, DWORD PTR [ebx+132]
00017 50 push eax
00018 ff 15 00 00 00
00 call DWORD PTR __imp__IoSetDeviceInterfaceState@8
; 42 :
; 43 : // Let the lower level drivers handle the IRP first.
; 44 : IoCopyCurrentIrpStackLocationToNext(IN Irp);
0001e 8b 55 0c mov edx, DWORD PTR _Irp$[ebp]
00021 6a 07 push 7
00023 59 pop ecx
00024 8b 72 60 mov esi, DWORD PTR [edx+96]
00027 8d 46 dc lea eax, DWORD PTR [esi-36]
0002a 8b f8 mov edi, eax
0002c f3 a5 rep movsd
0002e 80 60 03 00 and BYTE PTR [eax+3], 0
; 45 :
; 46 : IoSetCompletionRoutine(
; 47 : IN Irp,
; 48 : IN DeviceCompletionRoutine,
; 49 : IN NULL, //Context
; 50 : IN TRUE, //InvokeOnSuccess
; 51 : IN TRUE, //InvokeOnError
; 52 : IN TRUE //InvokeOnCancel
; 53 : );
00032 8b 42 60 mov eax, DWORD PTR [edx+96]
00035 83 e8 24 sub eax, 36 ; 00000024H
00038 33 f6 xor esi, esi
0003a c7 40 1c 00 00
00 00 mov DWORD PTR [eax+28], OFFSET FLAT:_DeviceCompletionRoutine@12
00041 89 70 20 mov DWORD PTR [eax+32], esi
00044 c6 40 03 e0 mov BYTE PTR [eax+3], 224 ; 000000e0H
; 54 :
; 55 : NTStatus = IoCallDriver(ObjExt->NextLowerDeviceObject, Irp);
00048 8b 8b 8c 00 00
00 mov ecx, DWORD PTR [ebx+140]
0004e ff 15 00 00 00
00 call DWORD PTR __imp_@IofCallDriver@8
00054 8b f8 mov edi, eax
; 56 : if(NTStatus == STATUS_PENDING){
00056 81 ff 03 01 00
00 cmp edi, 259 ; 00000103H
0005c 75 17 jne SHORT $L8440
; 57 : KeWaitForSingleObject(
; 58 : IN &ObjExt->WaitEvent,
; 59 : IN Executive, //WaitReason
; 60 : IN KernelMode, //WaitMode
; 61 : IN FALSE, //Alertable
; 62 : IN NULL //Timeout
; 63 : );
0005e 56 push esi
0005f 56 push esi
00060 56 push esi
00061 8d 83 90 00 00
00 lea eax, DWORD PTR [ebx+144]
00067 56 push esi
00068 50 push eax
00069 ff 15 00 00 00
00 call DWORD PTR __imp__KeWaitForSingleObject@20
; 64 : NTStatus = Irp->IoStatus.Status;
0006f 8b 45 0c mov eax, DWORD PTR _Irp$[ebp]
00072 8b 78 18 mov edi, DWORD PTR [eax+24]
$L8440:
; 65 : }
; 66 :
; 67 : // Processed after the lower level drivers have successfully finished with the IRP.
; 68 : if(NT_SUCCESS(NTStatus)){
00075 3b fe cmp edi, esi
00077 0f 8c 3e 01 00
00 jl $L8458
; 69 : IrpStack = IoGetCurrentIrpStackLocation(IN Irp);
; 70 : Resources = IrpStack->Parameters.StartDevice.AllocatedResourcesTranslated;
0007d 8b 45 0c mov eax, DWORD PTR _Irp$[ebp]
00080 8b 40 60 mov eax, DWORD PTR [eax+96]
00083 8b 70 08 mov esi, DWORD PTR [eax+8]
; 71 :
; 72 : // Get the I/O port attributes.
; 73 : Status = GetResources(Resources, CmResourceTypePort, &LIdx, &DIdx);
00086 8d 45 fc lea eax, DWORD PTR _DIdx$[ebp]
00089 50 push eax
0008a 8d 45 f8 lea eax, DWORD PTR _LIdx$[ebp]
0008d 50 push eax
0008e 6a 01 push 1
00090 56 push esi
00091 e8 00 00 00 00 call _GetResources@16
; 74 : if(Status == TRUE){
00096 3c 01 cmp al, 1
00098 0f 85 45 01 00
00 jne $L8444
; 75 : ObjExt->IOAccess = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Port.Start;
0009e 8b 45 fc mov eax, DWORD PTR _DIdx$[ebp]
000a1 8b 4d f8 mov ecx, DWORD PTR _LIdx$[ebp]
000a4 8d 04 48 lea eax, DWORD PTR [eax+ecx*2]
000a7 c1 e0 04 shl eax, 4
000aa 8b 4c 30 18 mov ecx, DWORD PTR [eax+esi+24]
000ae 89 4b 08 mov DWORD PTR [ebx+8], ecx
000b1 8b 44 30 1c mov eax, DWORD PTR [eax+esi+28]
000b5 89 43 0c mov DWORD PTR [ebx+12], eax
; 76 : ObjExt->IOAccessLength = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Port.Length;
000b8 8b 45 fc mov eax, DWORD PTR _DIdx$[ebp]
000bb 8b 4d f8 mov ecx, DWORD PTR _LIdx$[ebp]
000be 8d 44 48 02 lea eax, DWORD PTR [eax+ecx*2+2]
000c2 c1 e0 04 shl eax, 4
000c5 8b 04 30 mov eax, DWORD PTR [eax+esi]
000c8 89 43 14 mov DWORD PTR [ebx+20], eax
; 81 : NTStatus = STATUS_INSUFFICIENT_RESOURCES;
; 82 : //Irp->IoStatus.Status = NTStatus;
; 83 : return NTStatus;
; 84 : }
; 85 :
; 86 : // Map to the memory base space in order to support driver services.
; 87 : Status = GetResources(Resources, CmResourceTypeMemory, &LIdx, &DIdx);
000cb 8d 45 fc lea eax, DWORD PTR _DIdx$[ebp]
000ce 50 push eax
000cf 8d 45 f8 lea eax, DWORD PTR _LIdx$[ebp]
000d2 50 push eax
000d3 6a 03 push 3
000d5 56 push esi
000d6 e8 00 00 00 00 call _GetResources@16
; 88 : if(Status == TRUE){
000db 3c 01 cmp al, 1
000dd 0f 85 04 01 00
00 jne $L8447
; 89 : if(
; 90 : Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 91 : CM_RESOURCE_MEMORY_COMBINEDWRITE
; 92 : )
000e3 8b 45 fc mov eax, DWORD PTR _DIdx$[ebp]
000e6 8b 4d f8 mov ecx, DWORD PTR _LIdx$[ebp]
000e9 8d 04 48 lea eax, DWORD PTR [eax+ecx*2]
000ec c1 e0 04 shl eax, 4
000ef 03 c6 add eax, esi
000f1 66 8b 48 16 mov cx, WORD PTR [eax+22]
000f5 f6 c1 08 test cl, 8
000f8 74 05 je SHORT $L8448
; 93 : CacheType = MmWriteCombined;
000fa 6a 02 push 2
000fc 59 pop ecx
; 94 : else if(
000fd eb 09 jmp SHORT $L8450
$L8448:
; 95 : Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags &
; 96 : CM_RESOURCE_MEMORY_CACHEABLE
; 97 : )
000ff 0f b6 c9 movzx ecx, cl
00102 c1 e9 05 shr ecx, 5
00105 83 e1 01 and ecx, 1
$L8450:
; 98 : CacheType = MmCached;
; 99 : else
; 100 : CacheType = MmNonCached;
; 101 :
; 102 : ObjExt->MemoryAccess = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Memory.Start;
00108 8b 50 18 mov edx, DWORD PTR [eax+24]
; 103 : ObjExt->MemoryAccessLength = Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Memory.Length;
; 104 :
; 105 : ObjExt->MemoryBase = (ULONG*)MmMapIoSpace(
; 106 : IN ObjExt->MemoryAccess,
; 107 : IN ObjExt->MemoryAccessLength,
; 108 : IN CacheType
; 109 : );
0010b 51 push ecx
0010c 89 13 mov DWORD PTR [ebx], edx
0010e 8b 40 1c mov eax, DWORD PTR [eax+28]
00111 89 43 04 mov DWORD PTR [ebx+4], eax
00114 8b 45 fc mov eax, DWORD PTR _DIdx$[ebp]
00117 8b 55 f8 mov edx, DWORD PTR _LIdx$[ebp]
0011a 8d 44 50 02 lea eax, DWORD PTR [eax+edx*2+2]
0011e c1 e0 04 shl eax, 4
00121 8b 04 30 mov eax, DWORD PTR [eax+esi]
00124 50 push eax
00125 89 43 10 mov DWORD PTR [ebx+16], eax
00128 ff 73 04 push DWORD PTR [ebx+4]
0012b ff 33 push DWORD PTR [ebx]
0012d ff 15 00 00 00
00 call DWORD PTR __imp__MmMapIoSpace@16
; 110 : if(ObjExt->MemoryBase == NULL){
00133 85 c0 test eax, eax
00135 89 43 18 mov DWORD PTR [ebx+24], eax
00138 75 07 jne SHORT $L8454
; 111 : NTStatus = STATUS_SOME_NOT_MAPPED;
; 112 : //Irp->IoStatus.Status = NTStatus;
; 113 : return NTStatus;
0013a b8 07 01 00 00 mov eax, 263 ; 00000107H
0013f eb 7c jmp SHORT $L8416
$L8454:
; 120 : }
; 121 :
; 122 : // Map the PCI board's IRQ to a system vector.
; 123 : // todo: resolve the interrupt pin source
; 124 : ObjExt->InterruptObject = 0;
00141 83 63 20 00 and DWORD PTR [ebx+32], 0
; 125 : //if((ULONG)CardInfo.u.type0.InterruptPin != 0){ //use IRP_MN_READ_CONFIG
; 126 :
; 127 : // Connect the driver to the IRQ.
; 128 : Status = GetResources(Resources, CmResourceTypeInterrupt, &LIdx, &DIdx);
00145 8d 45 fc lea eax, DWORD PTR _DIdx$[ebp]
00148 50 push eax
00149 8d 45 f8 lea eax, DWORD PTR _LIdx$[ebp]
0014c 50 push eax
0014d 6a 02 push 2
0014f 56 push esi
00150 e8 00 00 00 00 call _GetResources@16
; 129 : if(Status == TRUE){
00155 3c 01 cmp al, 1
00157 75 62 jne SHORT $L8458
; 130 : if(
; 131 : Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].Flags ==
; 132 : CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE
; 133 : )
00159 8b 7d fc mov edi, DWORD PTR _DIdx$[ebp]
0015c 8b 4d f8 mov ecx, DWORD PTR _LIdx$[ebp]
0015f 33 d2 xor edx, edx
; 134 : InterruptMode = LevelSensitive;
; 135 : else
; 136 : InterruptMode = Latched;
; 137 :
; 138 : if(
; 139 : Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].ShareDisposition ==
; 140 : CmResourceShareShared
; 141 : )
; 142 : Shareable = TRUE;
; 143 : else
; 144 : Shareable = FALSE;
; 145 :
; 146 : InterruptLevel = (KIRQL)Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Level;
; 147 : NTStatus = IoConnectInterrupt(
; 148 : OUT &ObjExt->InterruptObject,
; 149 : IN PCIDPISR, //pointer to ISR
; 150 : IN DeviceObject, //context to send to ISR
; 151 : IN NULL, //optional spinlock
; 152 : IN Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Vector, //mapped interrupt vector
; 153 : IN InterruptLevel, //DIRQL u.Interrupt.Level
; 154 : IN InterruptLevel, //DIRQL u.Interrupt.Level
; 155 : IN InterruptMode, //latched/level interrupt
; 156 : IN Shareable, //shareable interrupt
; 157 : IN Resources->List[LIdx].PartialResourceList.PartialDescriptors[DIdx].u.Interrupt.Affinity, //processor enable mask
; 158 : IN FALSE //floating save (false for X86)
; 159 : );
00161 6a 00 push 0
00163 8d 04 4f lea eax, DWORD PTR [edi+ecx*2]
00166 8d 4c 4f 02 lea ecx, DWORD PTR [edi+ecx*2+2]
0016a c1 e0 04 shl eax, 4
0016d 03 c6 add eax, esi
0016f 66 39 50 16 cmp WORD PTR [eax+22], dx
00173 0f 95 c2 setne dl
00176 80 78 15 03 cmp BYTE PTR [eax+21], 3
0017a 89 55 f0 mov DWORD PTR _InterruptMode$[ebp], edx
0017d 0f 94 c2 sete dl
00180 c1 e1 04 shl ecx, 4
00183 88 55 f4 mov BYTE PTR _Shareable$[ebp], dl
00186 8a 50 18 mov dl, BYTE PTR [eax+24]
00189 ff 34 31 push DWORD PTR [ecx+esi]
0018c 88 55 0c mov BYTE PTR _InterruptLevel$[ebp], dl
0018f 8d 73 20 lea esi, DWORD PTR [ebx+32]
00192 ff 75 f4 push DWORD PTR _Shareable$[ebp]
00195 ff 75 f0 push DWORD PTR _InterruptMode$[ebp]
00198 ff 75 0c push DWORD PTR _InterruptLevel$[ebp]
0019b ff 75 0c push DWORD PTR _InterruptLevel$[ebp]
0019e ff 70 1c push DWORD PTR [eax+28]
001a1 6a 00 push 0
001a3 ff 75 08 push DWORD PTR _DeviceObject$[ebp]
001a6 68 00 00 00 00 push OFFSET FLAT:_PCIDPISR@8
001ab 56 push esi
001ac ff 15 00 00 00
00 call DWORD PTR __imp__IoConnectInterrupt@44
001b2 8b f8 mov edi, eax
; 160 : if(NTStatus != STATUS_SUCCESS){
001b4 85 ff test edi, edi
001b6 74 0c je SHORT $L8466
; 161 : ObjExt->InterruptObject = 0;
001b8 83 26 00 and DWORD PTR [esi], 0
$L8458:
; 175 : }
; 176 : //}
; 177 : }
; 178 :
; 179 : // Debug exit point
; 180 : //DbgPrint("[PCIDP]->Leaving StartDevice, status=0x%x...\n", NTStatus); //debug
; 181 : //DbgBreakPoint(); //debug
; 182 :
; 183 : return NTStatus;
001bb 8b c7 mov eax, edi
$L8416:
001bd 5f pop edi
001be 5e pop esi
001bf 5b pop ebx
; 184 : }
001c0 c9 leave
001c1 c2 08 00 ret 8
$L8466:
; 162 : //Irp->IoStatus.Status = NTStatus;
; 163 : return NTStatus;
; 164 : }
; 165 :
; 166 : // Register the PCIDPForDpcIsr routine with this device
; 167 : // driver.
; 168 : IoInitializeDpcRequest(
; 169 : IN DeviceObject,
; 170 : IN PCIDPForDpcIsr
; 171 : );
001c4 8b 45 08 mov eax, DWORD PTR _DeviceObject$[ebp]
001c7 50 push eax
001c8 83 c0 74 add eax, 116 ; 00000074H
001cb 68 00 00 00 00 push OFFSET FLAT:_PCIDPForDpcIsr@16
001d0 50 push eax
001d1 ff 15 00 00 00
00 call DWORD PTR __imp__KeInitializeDpc@12
; 172 :
; 173 : // Set up the spin lock for the linked list holding pending IRPs.
; 174 : KeInitializeSpinLock(&ObjExt->LListSpin);
001d7 83 c3 74 add ebx, 116 ; 00000074H
001da 53 push ebx
001db ff 15 00 00 00
00 call DWORD PTR __imp__KeInitializeSpinLock@4
001e1 eb d8 jmp SHORT $L8458
$L8444:
; 77 : }
; 78 : else{
; 79 : //ObjExt->IOAccess = 0;
; 80 : ObjExt->IOAccessLength = 0;
001e3 83 63 14 00 and DWORD PTR [ebx+20], 0
$L8447:
; 114 : }
; 115 : }
; 116 : else{
; 117 : NTStatus = STATUS_INSUFFICIENT_RESOURCES;
; 118 : //Irp->IoStatus.Status = NTStatus;
; 119 : return NTStatus;
001e7 b8 9a 00 00 c0 mov eax, -1073741670 ; c000009aH
001ec eb cf jmp SHORT $L8416
_StartDevice@8 ENDP
_TEXT ENDS
PUBLIC _StopDevice@4
PUBLIC _DeleteAllEntries@4
EXTRN __imp__MmUnmapIoSpace@8:NEAR
EXTRN __imp__IoDisconnectInterrupt@4:NEAR
; COMDAT _StopDevice@4
_TEXT SEGMENT
_DeviceObject$ = 8
_StopDevice@4 PROC NEAR ; COMDAT
; 188 :
; 189 : PPCIDP_EXTENSION ObjExt = (PPCIDP_EXTENSION)DeviceObject->DeviceExtension;
00000 8b 44 24 04 mov eax, DWORD PTR _DeviceObject$[esp-4]
00004 56 push esi
00005 8b 70 28 mov esi, DWORD PTR [eax+40]
; 190 :
; 191 : // Debug entry point
; 192 : //DbgPrint("[PCIDP]->Entering StopDevice...\n"); //debug
; 193 : //DbgBreakPoint(); //debug
; 194 :
; 195 : // Disconnect the driver from the interrupt if enabled.
; 196 : if(ObjExt->InterruptObject)
00008 8b 46 20 mov eax, DWORD PTR [esi+32]
0000b 85 c0 test eax, eax
0000d 74 07 je SHORT $L8473
; 197 : IoDisconnectInterrupt(ObjExt->InterruptObject);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -