I would like to add a new software interrupt to the Interrupt Descriptor Table (IDT) while executing a E-series device driver in kernel mode.
My problem is that I get a 0xC0000005: STATUS_ACCESS_VIOLATION error when I access an entry in the IDT. I access the IDT as part of an AddInterrupt() routine I call in HandleStartDevice(). I am baffled.
Thank you.
HandleStartDevice() {
...
AddInterrupt()
}
/* Interrupt to be added */
#define ADDINT 0x22
/* sidt instruction stores the base and limit of IDTR in this format */
typedef struct idtr {
short Limit; // 16 bits
unsigned int Base; // 32 bits
} Idtr_t, *PIdtr_t;
/* Decriptor Entry corresponding to interrupt gate */
typedef struct idtentry { // is 8 bytes bytes : should be 8 bytes
unsigned short OffsetLow; // 2 bytes : 2 bytes ok
unsigned short Selector; // 2 bytes : 2 bytes ok
unsigned char Reserved; // 8 bits
unsigned char Always1:3; // 3 bits
unsigned char Type:1; // 1 bits
unsigned char Always0:1; // 1 bits
unsigned char Dpl:2; // 2 bits
unsigned char Present:1; // 1 bits
unsigned short OffsetHigh; // 2 bytes
} IdtEntry_t, *PIdtEntry_t;
/* Old Idt Entry */
IdtEntry_t OldIdtEntry;
/* Buffer to store result of sidt instruction */
char buffer[6]; // 48 bits: 16 bits LIMIT, 32 bits BASE
/* Pointer to structure to identify the limit and base of IDTR*/
PIdtr_t Idtr= (PIdtr_t) buffer;
NTSTATUS AddInterrupt() {
PIdtEntry_t IdtEntry;
/* Get the Base and Limit of IDT table */
_asm sidt buffer
IdtEntry=(PIdtEntry_t)Idtr->Base;
if ((IdtEntry[ADDINT].OffsetLow!=0) || (IdtEntry[ADDINT].OffsetHigh!=0))
return STATUS_UNSUCCESSFUL;
--> // 0xC0000005: STATUS_ACCESS_VIOLATION
...
}