feat(kernel,gui): NT I/O Manager (IRP-based drivers) + Registry Editor

Kernel (NT I/O subsystem):
- kernel/nt/io.c + include/kernel/nt/io.h (new): DRIVER_OBJECTs with a
  MajorFunction dispatch table, DEVICE_OBJECTs that can be stacked (attached),
  and IRPs pushed down the stack via io_call_driver / completed with
  io_complete_request. Ships three demo drivers: \Driver\Null (write sink,
  EOF reads), \Driver\Zero (zero-filled reads), and \Driver\Monitor -- a filter
  attached above \Device\Null that counts and forwards each IRP down the stack.
  Wired into the [12/14] boot step.
- LazyBox `iodev` lists drivers/devices with the stack and IRP counters, then
  runs a live demo: a WRITE IRP through the filtered Null stack and a READ from
  the Zero device.

GUI:
- gui/gui_apps.c: "Registry Editor" -- navigate the NT \Registry hive tree,
  click subkeys to descend and ".." to go up, with a values pane showing each
  value's name/type/data. Registered in the app table (start menu).

Verified live in the GUI terminal (screenshotted): 3 drivers / 3 devices, the
NullMonitor->Null device stack, a 16-byte WRITE sunk through the filter
(status 0x0), and an 8-byte zeroed READ from \Device\Zero. Clean build on
x86_64/aarch64/armv8i; 0 panics / 0 OOM.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
Claude-Session: https://claude.ai/code/session_01Fh5z6V7nGPbHvqVG5p4CXX
This commit is contained in:
subhobhai943andClaude Opus 4.8 committed 2026-08-25 20:51:14 +05:30
1 parent 526ad8c741
commit ea937a699c
8 files changed
+513 -3

No files matched your search

+1 -1
View File
@@ -125,7 +125,7 @@ CORE_SRCS = kernel/main.c kernel/task.c kernel/sync.c kernel/timer.c kernel/prin
kernel/panic.c kernel/trace.c kernel/sched.c kernel/cron.c kernel/syscall.c \
kernel/syslog.c kernel/module.c kernel/kobject.c kernel/metrics.c kernel/namespace.c \
kernel/signal.c kernel/workqueue.c kernel/tsc.c kernel/vt_art.c \
kernel/sub/sub_runtime.c kernel/sub/sub_vm.c kernel/nt/ob.c kernel/nt/reg.c \
kernel/sub/sub_runtime.c kernel/sub/sub_vm.c kernel/nt/ob.c kernel/nt/reg.c kernel/nt/io.c \
kernel/wait.c kernel/futex.c kernel/rcu.c kernel/ktest.c \
kernel/elf.c kernel/exec.c \
lib/string.c lib/vsprintf.c lib/bitmap.c lib/rbtree.c lib/kfifo.c lib/hashtable.c lib/font8x8.c \
+120
View File
@@ -10,6 +10,7 @@
#include <kernel/printk.h>
#include <kernel/rust.h>
#include <kernel/nt/ob.h>
#include <kernel/nt/reg.h>
#include <lib/string.h>
#include <lib/printf.h>
@@ -768,3 +769,122 @@ void gui_app_objbrowse_launch(int x, int y, int w, int h) {
win->handle_event = objbrowse_event;
}
}
// =================================================================
// 10. Registry Editor -- navigate the NT \Registry hive tree
// =================================================================
typedef struct {
reg_key_t* current;
int row_h;
int list_top_rel; // list start, relative to window content top
int sub_count; // subkeys shown this frame (for click mapping)
bool has_up; // a ".." row is present
} regedit_data_t;
static void regedit_build_path(reg_key_t* key, char* out, size_t len) {
// Walk parents into a reversed segment stack, then join with backslashes.
const char* segs[16];
int n = 0;
reg_key_t* k = key;
while (k && n < 16) { segs[n++] = k->name; k = k->parent; }
size_t pos = 0;
out[0] = '\0';
for (int i = n - 1; i >= 0; i--) {
int wrote = snprintf(out + pos, (pos < len) ? len - pos : 0, "\\%s", segs[i]);
if (wrote > 0) pos += (size_t)wrote;
if (pos >= len) break;
}
}
static void regedit_paint(gui_window_t* win) {
regedit_data_t* rd = (regedit_data_t*)win->user_data;
if (!rd) return;
if (!rd->current) rd->current = reg_root();
int cx = win->x + 12;
int top = win->y + GUI_TITLEBAR_HEIGHT;
char path[192];
regedit_build_path(rd->current, path, sizeof(path));
gui_gfx_draw_string_16_shadow(cx, top + 8, "Registry Editor", GUI_THEME_PRIMARY, GUI_COLOR_BLACK);
gui_gfx_draw_string(cx, top + 28, path, GUI_THEME_TEXT_MUTED);
rd->row_h = 13;
rd->list_top_rel = GUI_TITLEBAR_HEIGHT + 46;
int y = top + 46;
rd->has_up = (rd->current->parent != NULL);
if (rd->has_up) {
gui_gfx_draw_string(cx, y, "..", GUI_THEME_ACCENT);
y += rd->row_h;
}
// Subkeys (navigable)
int kc = reg_enum_key_count(rd->current);
rd->sub_count = kc;
for (int i = 0; i < kc; i++) {
reg_key_t* sub = reg_enum_key(rd->current, i);
char line[64];
snprintf(line, sizeof(line), "[%s]", sub->name);
gui_gfx_draw_string(cx, y, line, GUI_THEME_SUCCESS);
y += rd->row_h;
}
// Values pane
y += 4;
gui_gfx_draw_line(cx, y, win->x + win->width - 12, y, GUI_THEME_BORDER);
y += 6;
int vc = reg_enum_value_count(rd->current);
if (vc == 0) {
gui_gfx_draw_string(cx, y, "(no values)", GUI_THEME_TEXT_DIM);
}
for (int i = 0; i < vc; i++) {
reg_value_t* v = reg_enum_value(rd->current, i);
char rendered[REG_STR_MAX + 8];
reg_value_to_string(v, rendered, sizeof(rendered));
char line[160];
snprintf(line, sizeof(line), "%-18s %-10s %s", v->name, reg_type_name(v->type), rendered);
gui_gfx_draw_string(cx, y, line, GUI_THEME_TEXT_MAIN);
y += rd->row_h;
if (y > win->y + win->height - 12) break;
}
}
static void regedit_event(gui_window_t* win, const gui_event_t* ev) {
regedit_data_t* rd = (regedit_data_t*)win->user_data;
if (!rd) return;
if (ev->type == GUI_EVENT_CLOSE) {
if (win->user_data) { kfree(win->user_data); win->user_data = NULL; }
return;
}
if (ev->type != GUI_EVENT_MOUSE_DOWN) return;
if (!rd->current) return;
int rel = ev->rel_y - rd->list_top_rel;
if (rel < 0) return;
int row = rel / (rd->row_h > 0 ? rd->row_h : 13);
int idx = 0;
if (rd->has_up) {
if (row == 0) { rd->current = rd->current->parent; return; }
idx = row - 1;
} else {
idx = row;
}
if (idx >= 0 && idx < rd->sub_count) {
reg_key_t* sub = reg_enum_key(rd->current, idx);
if (sub) rd->current = sub;
}
}
void gui_app_regedit_launch(int x, int y, int w, int h) {
gui_window_t* win = gui_wm_create_window("Registry Editor", x, y, (w > 0) ? w : 480, (h > 0) ? h : 360);
if (win) {
regedit_data_t* rd = (regedit_data_t*)kzalloc(sizeof(regedit_data_t));
if (rd) rd->current = reg_root();
win->user_data = rd;
win->paint = regedit_paint;
win->handle_event = regedit_event;
}
}
+3 -2
View File
@@ -59,6 +59,7 @@ static const desktop_app_t g_apps[] = {
{ "Life", GUI_ICON_FLASK, gui_app_life_launch, 240, 70, 480, 380 },
{ "Rust Lab", GUI_ICON_INFO, gui_app_rustlab_launch, 300, 80, 420, 300 },
{ "Objects", GUI_ICON_TASKS, gui_app_objbrowse_launch,280, 70, 460, 340 },
{ "RegEdit", GUI_ICON_SETTINGS, gui_app_regedit_launch, 300, 90, 480, 360 },
{ "Clock", GUI_ICON_CLOCK, gui_app_clock_launch, 460, 120, 280, 260 },
{ "Settings", GUI_ICON_SETTINGS, gui_app_settings_launch, 160, 60, 400, 320 },
{ "About", GUI_ICON_INFO, gui_app_about_launch, 240, 140, 330, 170 },
@@ -67,8 +68,8 @@ static const desktop_app_t g_apps[] = {
// Which of the above appear on the desktop itself.
// Indices into g_apps[]: Terminal, Files, Monitor, Kernel Log, KTest, Life,
// Rust Lab, Settings. (Objects lives in the start menu.)
static const int g_desktop_icons[] = { 0, 1, 2, 4, 5, 9, 10, 13 };
// Rust Lab, Settings. (Objects/RegEdit live in the start menu.)
static const int g_desktop_icons[] = { 0, 1, 2, 4, 5, 9, 10, 14 };
#define DESKTOP_ICON_COUNT ((int)(sizeof(g_desktop_icons) / sizeof(g_desktop_icons[0])))
static bool g_start_menu_open = false;
+1
View File
@@ -12,5 +12,6 @@ void gui_app_about_launch(int x, int y, int w, int h);
void gui_app_life_launch(int x, int y, int w, int h);
void gui_app_rustlab_launch(int x, int y, int w, int h);
void gui_app_objbrowse_launch(int x, int y, int w, int h);
void gui_app_regedit_launch(int x, int y, int w, int h);
#endif // _GUI_APPS_H
+87
View File
@@ -0,0 +1,87 @@
#ifndef _KERNEL_NT_IO_H
#define _KERNEL_NT_IO_H
// -----------------------------------------------------------------------------
// SUB-OS NT-Inspired I/O Manager
//
// Models the Windows NT I/O subsystem: DRIVER_OBJECTs export a MajorFunction
// dispatch table, DEVICE_OBJECTs are created by drivers and can be stacked
// (attached) into a device stack, and I/O flows as IRPs (I/O Request Packets)
// pushed down the stack with IoCallDriver / completed with IoCompleteRequest.
// -----------------------------------------------------------------------------
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include <kernel/nt/ob.h> // NTSTATUS, STATUS_* codes
typedef enum {
IRP_MJ_CREATE = 0,
IRP_MJ_CLOSE,
IRP_MJ_READ,
IRP_MJ_WRITE,
IRP_MJ_DEVICE_CONTROL,
IRP_MJ_MAXIMUM
} irp_major_t;
#define IO_NAME_MAX 48
#define IO_MAX_DRIVERS 16
#define IO_MAX_DEVICES 32
typedef struct _DEVICE_OBJECT DEVICE_OBJECT;
typedef struct _DRIVER_OBJECT DRIVER_OBJECT;
typedef struct _IRP IRP;
typedef NTSTATUS (*driver_dispatch_t)(DEVICE_OBJECT* dev, IRP* irp);
typedef NTSTATUS (*driver_entry_t)(DRIVER_OBJECT* drv);
struct _DRIVER_OBJECT {
char name[IO_NAME_MAX]; // e.g. "\Driver\Null"
driver_dispatch_t major_function[IRP_MJ_MAXIMUM];
DEVICE_OBJECT* device_list; // devices this driver owns
uint64_t irp_count;
};
struct _DEVICE_OBJECT {
char name[IO_NAME_MAX]; // e.g. "\Device\Null"
DRIVER_OBJECT* driver;
DEVICE_OBJECT* next_on_driver; // next in the driver's device_list
DEVICE_OBJECT* attached_to; // lower device in the stack (or NULL)
void* device_extension;
uint64_t read_count;
uint64_t write_count;
uint64_t ioctl_count;
};
struct _IRP {
irp_major_t major_function;
void* buffer;
uint32_t length;
uint32_t io_control_code;
NTSTATUS status;
uint32_t information; // bytes transferred on completion
DEVICE_OBJECT* current_device;
};
void io_init(void);
const char* io_major_name(irp_major_t mj);
DRIVER_OBJECT* io_create_driver(const char* name, driver_entry_t entry);
NTSTATUS io_create_device(DRIVER_OBJECT* drv, const char* name,
size_t ext_size, DEVICE_OBJECT** out);
DEVICE_OBJECT* io_attach_device(DEVICE_OBJECT* source, DEVICE_OBJECT* target);
DEVICE_OBJECT* io_lookup_device(const char* name);
IRP* io_build_irp(irp_major_t mj, void* buffer, uint32_t length);
NTSTATUS io_call_driver(DEVICE_OBJECT* dev, IRP* irp);
void io_complete_request(IRP* irp, NTSTATUS status);
void io_free_irp(IRP* irp);
// Enumeration / stats.
int io_driver_count(void);
DRIVER_OBJECT* io_driver_at(int index);
int io_device_count(void);
DEVICE_OBJECT* io_device_at(int index);
void io_get_stats(uint32_t* out_drivers, uint32_t* out_devices, uint64_t* out_irps);
#endif // _KERNEL_NT_IO_H
+2
View File
@@ -9,6 +9,7 @@
#include <kernel/module.h>
#include <kernel/nt/ob.h>
#include <kernel/nt/reg.h>
#include <kernel/nt/io.h>
#include <kernel/trace.h>
#include <kernel/namespace.h>
#include <kernel/syslog.h>
@@ -243,6 +244,7 @@ static void subos_modular_core_boot(void) {
cron_init();
ob_init();
reg_init();
io_init();
service_manager_init();
printk(ANSI_BRIGHT_GREEN "OK\n" ANSI_RESET);
+242
View File
@@ -0,0 +1,242 @@
// -----------------------------------------------------------------------------
// SUB-OS NT-Inspired I/O Manager (Io)
//
// Drivers register a MajorFunction dispatch table and create named device
// objects. Devices can be stacked (a filter attached on top of a lower device);
// io_call_driver invokes the top device's dispatch, which may forward the IRP
// down to dev->attached_to. Ships three demo drivers: Null, Zero, and a Monitor
// filter stacked above Null that counts and forwards every IRP.
// -----------------------------------------------------------------------------
#include <kernel/nt/io.h>
#include <mm/kmalloc.h>
#include <lib/string.h>
#include <kernel/printk.h>
#include <kernel/sync.h>
static DRIVER_OBJECT* g_drivers[IO_MAX_DRIVERS];
static int g_driver_count = 0;
static DEVICE_OBJECT* g_devices[IO_MAX_DEVICES];
static int g_device_count = 0;
static uint64_t g_total_irps = 0;
static spinlock_t g_io_lock = SPINLOCK_INIT;
const char* io_major_name(irp_major_t mj) {
switch (mj) {
case IRP_MJ_CREATE: return "CREATE";
case IRP_MJ_CLOSE: return "CLOSE";
case IRP_MJ_READ: return "READ";
case IRP_MJ_WRITE: return "WRITE";
case IRP_MJ_DEVICE_CONTROL: return "DEVICE_CONTROL";
default: return "UNKNOWN";
}
}
DRIVER_OBJECT* io_create_driver(const char* name, driver_entry_t entry) {
spin_lock(&g_io_lock);
if (g_driver_count >= IO_MAX_DRIVERS) {
spin_unlock(&g_io_lock);
return NULL;
}
DRIVER_OBJECT* drv = (DRIVER_OBJECT*)kzalloc(sizeof(DRIVER_OBJECT));
if (!drv) {
spin_unlock(&g_io_lock);
return NULL;
}
strncpy(drv->name, name ? name : "", IO_NAME_MAX - 1);
g_drivers[g_driver_count++] = drv;
spin_unlock(&g_io_lock);
if (entry) {
entry(drv); // DriverEntry fills the MajorFunction table and creates devices
}
return drv;
}
NTSTATUS io_create_device(DRIVER_OBJECT* drv, const char* name,
size_t ext_size, DEVICE_OBJECT** out) {
if (!drv) return STATUS_UNSUCCESSFUL;
spin_lock(&g_io_lock);
if (g_device_count >= IO_MAX_DEVICES) {
spin_unlock(&g_io_lock);
return STATUS_INSUFFICIENT_RES;
}
DEVICE_OBJECT* dev = (DEVICE_OBJECT*)kzalloc(sizeof(DEVICE_OBJECT));
if (!dev) {
spin_unlock(&g_io_lock);
return STATUS_INSUFFICIENT_RES;
}
strncpy(dev->name, name ? name : "", IO_NAME_MAX - 1);
dev->driver = drv;
if (ext_size > 0) {
dev->device_extension = kzalloc(ext_size);
}
// Link into the driver's device list and the global table.
dev->next_on_driver = drv->device_list;
drv->device_list = dev;
g_devices[g_device_count++] = dev;
spin_unlock(&g_io_lock);
if (out) *out = dev;
return STATUS_SUCCESS;
}
DEVICE_OBJECT* io_attach_device(DEVICE_OBJECT* source, DEVICE_OBJECT* target) {
if (!source || !target) return NULL;
spin_lock(&g_io_lock);
source->attached_to = target; // source now sits above target in the stack
spin_unlock(&g_io_lock);
return target;
}
DEVICE_OBJECT* io_lookup_device(const char* name) {
if (!name) return NULL;
spin_lock(&g_io_lock);
DEVICE_OBJECT* found = NULL;
for (int i = 0; i < g_device_count; i++) {
if (strcmp(g_devices[i]->name, name) == 0) { found = g_devices[i]; break; }
}
spin_unlock(&g_io_lock);
return found;
}
IRP* io_build_irp(irp_major_t mj, void* buffer, uint32_t length) {
IRP* irp = (IRP*)kzalloc(sizeof(IRP));
if (!irp) return NULL;
irp->major_function = mj;
irp->buffer = buffer;
irp->length = length;
irp->status = STATUS_UNSUCCESSFUL;
irp->information = 0;
return irp;
}
NTSTATUS io_call_driver(DEVICE_OBJECT* dev, IRP* irp) {
if (!dev || !irp) return STATUS_UNSUCCESSFUL;
irp->current_device = dev;
spin_lock(&g_io_lock);
g_total_irps++;
if (dev->driver) dev->driver->irp_count++;
switch (irp->major_function) {
case IRP_MJ_READ: dev->read_count++; break;
case IRP_MJ_WRITE: dev->write_count++; break;
case IRP_MJ_DEVICE_CONTROL: dev->ioctl_count++; break;
default: break;
}
driver_dispatch_t fn = NULL;
if (dev->driver && irp->major_function < IRP_MJ_MAXIMUM) {
fn = dev->driver->major_function[irp->major_function];
}
spin_unlock(&g_io_lock);
if (!fn) {
irp->status = STATUS_UNSUCCESSFUL;
return irp->status;
}
return fn(dev, irp);
}
void io_complete_request(IRP* irp, NTSTATUS status) {
if (!irp) return;
irp->status = status;
}
void io_free_irp(IRP* irp) {
if (irp) kfree(irp);
}
int io_driver_count(void) { return g_driver_count; }
DRIVER_OBJECT* io_driver_at(int index) {
return (index >= 0 && index < g_driver_count) ? g_drivers[index] : NULL;
}
int io_device_count(void) { return g_device_count; }
DEVICE_OBJECT* io_device_at(int index) {
return (index >= 0 && index < g_device_count) ? g_devices[index] : NULL;
}
void io_get_stats(uint32_t* out_drivers, uint32_t* out_devices, uint64_t* out_irps) {
if (out_drivers) *out_drivers = (uint32_t)g_driver_count;
if (out_devices) *out_devices = (uint32_t)g_device_count;
if (out_irps) *out_irps = g_total_irps;
}
// ---------------------------------------------------------------------------
// Demo drivers
// ---------------------------------------------------------------------------
// \Driver\Null : sink writes, return EOF on reads (like NT's \Device\Null).
static NTSTATUS null_read(DEVICE_OBJECT* dev, IRP* irp) {
(void)dev;
irp->information = 0; // 0 bytes == end of file
io_complete_request(irp, STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS null_write(DEVICE_OBJECT* dev, IRP* irp) {
(void)dev;
irp->information = irp->length; // swallow everything
io_complete_request(irp, STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS null_entry(DRIVER_OBJECT* drv) {
drv->major_function[IRP_MJ_READ] = null_read;
drv->major_function[IRP_MJ_WRITE] = null_write;
io_create_device(drv, "\\Device\\Null", 0, NULL);
return STATUS_SUCCESS;
}
// \Driver\Zero : reads yield a buffer full of zero bytes.
static NTSTATUS zero_read(DEVICE_OBJECT* dev, IRP* irp) {
(void)dev;
if (irp->buffer && irp->length) {
memset(irp->buffer, 0, irp->length);
}
irp->information = irp->length;
io_complete_request(irp, STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS zero_entry(DRIVER_OBJECT* drv) {
drv->major_function[IRP_MJ_READ] = zero_read;
io_create_device(drv, "\\Device\\Zero", 0, NULL);
return STATUS_SUCCESS;
}
// \Driver\Monitor : a filter stacked above \Device\Null. It counts each IRP in
// its device extension and forwards to the lower device, demonstrating a stack.
typedef struct { uint64_t forwarded; } monitor_ext_t;
static NTSTATUS monitor_passthrough(DEVICE_OBJECT* dev, IRP* irp) {
monitor_ext_t* ext = (monitor_ext_t*)dev->device_extension;
if (ext) ext->forwarded++;
if (dev->attached_to) {
return io_call_driver(dev->attached_to, irp); // pass down the stack
}
io_complete_request(irp, STATUS_SUCCESS);
return STATUS_SUCCESS;
}
static NTSTATUS monitor_entry(DRIVER_OBJECT* drv) {
drv->major_function[IRP_MJ_READ] = monitor_passthrough;
drv->major_function[IRP_MJ_WRITE] = monitor_passthrough;
drv->major_function[IRP_MJ_DEVICE_CONTROL] = monitor_passthrough;
DEVICE_OBJECT* filter = NULL;
io_create_device(drv, "\\Device\\NullMonitor", sizeof(monitor_ext_t), &filter);
DEVICE_OBJECT* lower = io_lookup_device("\\Device\\Null");
if (filter && lower) {
io_attach_device(filter, lower);
}
return STATUS_SUCCESS;
}
void io_init(void) {
g_driver_count = 0;
g_device_count = 0;
g_total_irps = 0;
io_create_driver("\\Driver\\Null", null_entry);
io_create_driver("\\Driver\\Zero", zero_entry);
io_create_driver("\\Driver\\Monitor", monitor_entry);
printk(ANSI_BRIGHT_GREEN "IO: " ANSI_RESET
"NT I/O Manager online (%d drivers, %d devices, IRP-based dispatch)\n",
g_driver_count, g_device_count);
}
+57
View File
@@ -31,6 +31,7 @@
#include <kernel/rust.h>
#include <kernel/nt/ob.h>
#include <kernel/nt/reg.h>
#include <kernel/nt/io.h>
#include <kernel/sub_lang.h>
#include <kernel/cpp_kernel.h>
#include <userland/snake.h>
@@ -659,6 +660,61 @@ static int applet_reg(int argc, char** argv) {
return 1;
}
static int applet_iodev(int argc, char** argv) {
(void)argc; (void)argv;
uint32_t drivers = 0, devices = 0;
uint64_t irps = 0;
io_get_stats(&drivers, &devices, &irps);
printk(ANSI_BRIGHT_CYAN "NT I/O Manager:\n" ANSI_RESET);
printk(" Drivers: %u Devices: %u IRPs dispatched: %llu\n",
drivers, devices, (unsigned long long)irps);
int dc = io_device_count();
for (int i = 0; i < dc; i++) {
DEVICE_OBJECT* dev = io_device_at(i);
if (!dev) continue;
printk(" " ANSI_YELLOW "%-22s" ANSI_RESET " drv=%-16s r=%llu w=%llu ioctl=%llu",
dev->name, dev->driver ? dev->driver->name : "?",
(unsigned long long)dev->read_count,
(unsigned long long)dev->write_count,
(unsigned long long)dev->ioctl_count);
if (dev->attached_to) {
printk(" -> %s", dev->attached_to->name);
}
printk("\n");
}
// Live demo: push a WRITE IRP through the filtered Null stack and a READ to
// the Zero device, then report what came back.
printk(ANSI_BRIGHT_CYAN "IRP demo:\n" ANSI_RESET);
DEVICE_OBJECT* mon = io_lookup_device("\\Device\\NullMonitor");
if (mon) {
char payload[16];
memset(payload, 'X', sizeof(payload));
IRP* irp = io_build_irp(IRP_MJ_WRITE, payload, sizeof(payload));
if (irp) {
NTSTATUS st = io_call_driver(mon, irp);
printk(" WRITE %u bytes to %s -> status=0x%X, %u bytes sunk (via filter)\n",
(unsigned)sizeof(payload), mon->name, st, irp->information);
io_free_irp(irp);
}
}
DEVICE_OBJECT* zero = io_lookup_device("\\Device\\Zero");
if (zero) {
uint8_t buf[8];
memset(buf, 0xEE, sizeof(buf));
IRP* irp = io_build_irp(IRP_MJ_READ, buf, sizeof(buf));
if (irp) {
io_call_driver(zero, irp);
printk(" READ %u bytes from %s -> first bytes %02X %02X %02X (zeroed)\n",
irp->information, zero->name, buf[0], buf[1], buf[2]);
io_free_irp(irp);
}
}
return 0;
}
static int applet_rand(int argc, char** argv) {
int count = (argc >= 2) ? atoi(argv[1]) : 4;
printk("Random Integers: ");
@@ -2371,6 +2427,7 @@ static const lazybox_applet_t applets[] = {
{"objdir", applet_objdir, "objdir [\\path]", "List the NT object namespace","Kernel"},
{"ntobj", applet_ntobj, "ntobj", "NT Object Manager stats/demo","Kernel"},
{"reg", applet_reg, "reg query|add|set|stats", "NT configuration registry", "Kernel"},
{"iodev", applet_iodev, "iodev", "NT I/O Manager devices & IRP","Kernel"},
{"rand", applet_rand, "rand [count]", "Generate random numbers", "Crypto"},
{"certcheck", applet_certcheck, "certcheck", "View X.509 kernel keyring", "Security"},
{"capsh", applet_capsh, "capsh", "View process capabilities", "Security"},