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:
maksw committed 2026-05-03 19:35:48 +02:00
1 parent 7f4052f41c
commit 9fa2a7e0db
61 files changed
+1311 -456

No files matched your search

+112
View File
@@ -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;
}