colonel.exe 🤑, refactor all include directives, AHCI is now interrupt driven, upgrades to IDE, implemented I/O Request Packets, fix numerous keyboard issues, change all for (;;) and while (1) to while (true), DbgPrint guarded by spinlock, fix KeSignalEvent, major KernelMain refactor, added SystemInitThread because of new blocking I/O, replace memcpy manouvers with strncpy and strncat, add: run for ide, runa for ahci, rund for debug and ide, runad for debug and ahci.
This commit is contained in:
1 parent
7f4052f41c
commit
9fa2a7e0db
61 files changed
+1311
-456
No files matched your search
@@ -0,0 +1,112 @@
|
||||
// ke_irp.c - I/O Request Packet dispatch and queue helpers
|
||||
//
|
||||
// This file lives in the kernel layer and is the ONLY place that bridges the
|
||||
// IRP abstraction to kernel sync objects. All calls to KeEventCreate,
|
||||
// KeSignalEvent, KeWaitForEvent, KeSignalSemaphore, and ObDereferenceObject
|
||||
// are confined here; hal_disk.c and io_driver.h remain free of those symbols.
|
||||
//
|
||||
// Dependency graph (→ = includes / calls):
|
||||
// ke_irp.c → ke_irp.h (IRP type, IRP_QUEUE, forward decls)
|
||||
// → ke_event.h (KeEventCreate, KeSignalEvent, KeWaitForEvent)
|
||||
// → ke_semaphore.h (KeSignalSemaphore)
|
||||
// → ob_object.h (ObDereferenceObject)
|
||||
// → io_driver.h (HalDiskDispatch)
|
||||
// hal_disk.c → io_driver.h only (no ke_event.h, no ke_semaphore.h)
|
||||
|
||||
#include <ke_irp.h>
|
||||
#include <ke_event.h>
|
||||
#include <ke_semaphore.h>
|
||||
#include <ob_object.h>
|
||||
#include <io_driver.h>
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// IRP_QUEUE operations
|
||||
// -------------------------------------------------------------------------
|
||||
// These are defined here (not as static inlines in ke_irp.h) so that
|
||||
// ke_irp.h can avoid including ke_semaphore.h, keeping the header safe
|
||||
// for inclusion from the HAL layer.
|
||||
|
||||
void IrpQueueInit(IRP_QUEUE *q, struct SEMAPHORE *sem) {
|
||||
q->Lock = (SPINLOCK)SPINLOCK_INIT;
|
||||
q->Semaphore = sem;
|
||||
LIST_INIT(&q->Head);
|
||||
}
|
||||
|
||||
void IrpQueueEnqueue(IRP_QUEUE *q, IRP *irp) {
|
||||
uintptr_t flags = KeAcquireSpinlock(&q->Lock);
|
||||
if (irp->Flags & IRP_FLAG_PRIORITY)
|
||||
ListInsertHead(&q->Head, &irp->Link);
|
||||
else
|
||||
ListInsertTail(&q->Head, &irp->Link);
|
||||
KeReleaseSpinlock(&q->Lock, flags);
|
||||
// Signal outside the spinlock — safe, and avoids priority-inversion risk.
|
||||
KeSignalSemaphore((SEMAPHORE *)q->Semaphore);
|
||||
}
|
||||
|
||||
IRP *IrpQueueDequeue(IRP_QUEUE *q) {
|
||||
uintptr_t flags = KeAcquireSpinlock(&q->Lock);
|
||||
LIST_ENTRY *node = ListPopHead(&q->Head);
|
||||
KeReleaseSpinlock(&q->Lock, flags);
|
||||
if (!node) return (IRP *)0;
|
||||
return CONTAINING_RECORD(node, IRP, Link);
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// IoSubmitIrp
|
||||
// -------------------------------------------------------------------------
|
||||
// Calls HalDiskDispatch() which is HAL-layer safe (no event references).
|
||||
// If the dispatch ran inline (sync fallback), we fire the completion hooks
|
||||
// here in the kernel layer where we can legally call KeSignalEvent.
|
||||
|
||||
KSTATUS IoSubmitIrp(IRP *irp) {
|
||||
if (!irp) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
KSTATUS st = HalDiskDispatch(irp->DriveIndex, irp);
|
||||
|
||||
if (st == STATUS_NOT_FOUND)
|
||||
return STATUS_NOT_FOUND;
|
||||
|
||||
if (st == STATUS_SUCCESS) {
|
||||
// Sync fallback ran; irp->Status is already written.
|
||||
// Fire completion hooks now — we are in kernel context so this is safe.
|
||||
if (irp->CompletionEvent)
|
||||
KeSignalEvent((EVENT *)irp->CompletionEvent);
|
||||
if (irp->CompletionFn)
|
||||
irp->CompletionFn(irp, irp->CompletionCtx);
|
||||
}
|
||||
|
||||
// Return STATUS_PENDING in both cases so callers have a uniform contract:
|
||||
// "completion is signalled via the event/callback, not this return value."
|
||||
return STATUS_PENDING;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// IoSubmitIrpSync
|
||||
// -------------------------------------------------------------------------
|
||||
// Creates a stack-allocated auto-reset event, attaches it to the IRP,
|
||||
// submits, and blocks. Callers that already provided a CompletionEvent
|
||||
// should use IoSubmitIrp() directly and wait on their own event instead.
|
||||
|
||||
KSTATUS IoSubmitIrpSync(IRP *irp) {
|
||||
if (!irp) return STATUS_INVALID_PARAMETER;
|
||||
|
||||
EVENT *ev = (EVENT *)0;
|
||||
KSTATUS st = KeEventCreate(EventAutoReset, 0, &ev);
|
||||
if (!KSUCCESS(st)) return st;
|
||||
|
||||
// Attach our event; preserve any callback the caller may have set.
|
||||
irp->CompletionEvent = ev;
|
||||
|
||||
st = IoSubmitIrp(irp);
|
||||
// IoSubmitIrp always returns STATUS_PENDING on the non-error paths.
|
||||
// The event is signalled either by the driver worker (async) or by
|
||||
// IoSubmitIrp itself (sync fallback), so KeWaitForEvent will always
|
||||
// return promptly in the sync-fallback case.
|
||||
if (st == STATUS_PENDING)
|
||||
KeWaitForEvent(ev);
|
||||
|
||||
// Release our reference to the temporary event object.
|
||||
ObDereferenceObject(&ev->Header);
|
||||
|
||||
return irp->Status;
|
||||
}
|
||||
Reference in new issue
Block a user