VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextDevObj; int i; KLog(LInfo, "UnloadRoutine"); MonitorStop(NULL); pNextDevObj = pDriverObject->DeviceObject; for(i = 0; pNextDevObj != NULL; i++) { PMDEVICE_EXTENSION DevExt = (PMDEVICE_EXTENSION)pNextDevObj->DeviceExtension; PDEVICE_OBJECT DevObj = pNextDevObj; pNextDevObj = pNextDevObj->NextDevice; if (DevExt != NULL) { KLog(LInfo, "Deleted device ext %p device %p", DevExt, DevExt->DeviceObject); KLog(LInfo, "Deleted symlink = %wZ", &DevExt->SymLinkName); IoDeleteSymbolicLink(&DevExt->SymLinkName); } IoDeleteDevice(DevObj); } KLog(LInfo, "UnloadRoutine completed"); KLoggingRelease(); }
NTSTATUS EventLogWorkerRoutine(PEVENT_LOG EventLog) { KIRQL Irql; PLIST_ENTRY ListEntry = NULL; PSREQUEST request = NULL; if (EventLog->Stopping) return STATUS_TOO_LATE; KeAcquireSpinLock(&EventLog->EventListLock, &Irql); if (!IsListEmpty(&EventLog->EventListHead)) { ListEntry = RemoveHeadList(&EventLog->EventListHead); request = CONTAINING_RECORD(ListEntry, SREQUEST, ListEntry); } KeReleaseSpinLock(&EventLog->EventListLock, Irql); if (request != NULL) { PSREQUEST response = NULL; response = MonitorCallServer(request); if (response->status != SREQ_SUCCESS) KLog(LError, "request %d failed with err=%d", request->type, response->status); if (response != NULL) SRequestDelete(response); SRequestDelete(request); } return STATUS_SUCCESS; }
void InitProcesses (void) { struct CPU *cpu; int t; KLog("InitProcesses()"); max_cpu = 1; cpu_cnt = max_cpu; cpu = &cpu_table[0]; idle_task = CreateProcess (IdleTask, &idle_task_stack_top, SCHED_IDLE, 0, PROCF_DAEMON, &cpu_table[0]); vm_task = CreateProcess (VMTask, &vm_task_stack_top, SCHED_OTHER, 0, PROCF_DAEMON, &cpu_table[0]); root_process = CreateProcess (bootinfo->procman_entry_point, (void *)bootinfo->user_stack_ceiling, SCHED_OTHER, 100, PROCF_FILESYS, &cpu_table[0]); for (t=0; t < seg_cnt; t++) { if ((seg_table[t].flags & MEM_MASK) == MEM_ALLOC) { seg_table[t].owner = root_process; seg_table[t].segment_id = next_unique_segment_id ++; } } root_process->state = PROC_STATE_RUNNING; cpu->current_process = root_process; cpu->reschedule_request = 0; cpu->svc_stack = (vm_addr)&svc_stack_top; cpu->interrupt_stack = (vm_addr)&interrupt_stack_top; cpu->exception_stack = (vm_addr)&exception_stack_top; }
NTSTATUS DriverDeviceControlHandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp ) { NTSTATUS Status = STATUS_SUCCESS; PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode; ULONG method = ControlCode & 0x3; ULONG ResultLength = 0; ULONG InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength; ULONG OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength; PVOID Buffer = Irp->AssociatedIrp.SystemBuffer; KeEnterGuardedRegion(); KLOG(LInfo, "IoControl fdo %p, ioctl %x", fdo, ControlCode); if (OutputLength < InputLength) { KLog(LError, "invalid outputlen=%x vs inputlen=%x", OutputLength, InputLength); Status = STATUS_INVALID_PARAMETER; goto complete; } ResultLength = InputLength; switch( ControlCode) { case IOCTL_KMON_INIT: { PKMON_INIT initData = (PKMON_INIT)Buffer; if (InputLength < sizeof(KMON_INIT)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } KLog(LInfo, "IOCTL_KMON_INIT"); Status = MonitorStart(initData); break; } case IOCTL_KMON_RELEASE: { PKMON_RELEASE releaseData = (PKMON_RELEASE)Buffer; if (InputLength < sizeof(KMON_RELEASE)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } KLog(LInfo, "IOCTL_KMON_RELEASE"); Status = MonitorStop(releaseData); break; } case IOCTL_KMON_OPEN_WINSTA: { POPEN_WINSTA openWinsta = (POPEN_WINSTA)Buffer; if (InputLength < sizeof(OPEN_WINSTA)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } Status = MonitorOpenWinsta(openWinsta); break; } case IOCTL_KMON_OPEN_DESKTOP: { POPEN_DESKTOP openDeskop = (POPEN_DESKTOP)Buffer; if (InputLength < sizeof(OPEN_DESKTOP)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } Status = MonitorOpenDesktop(openDeskop); break; } case IOCTL_KMON_SCREENSHOT: { PKMON_SCREENSHOT screenShot = (PKMON_SCREENSHOT)Buffer; if (InputLength < sizeof(KMON_SCREENSHOT)) { Status = STATUS_BUFFER_TOO_SMALL; goto complete; } Status = MonitorScreenshot(screenShot); break; } default: Status = STATUS_INVALID_DEVICE_REQUEST; } complete: KeLeaveGuardedRegion(); KLog(LInfo, "dev=%p IoControl: %x bytes: %x, Status=%x", fdo, ControlCode, ResultLength, Status); return CompleteIrp(Irp, Status, ResultLength); }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS Status = STATUS_SUCCESS; PDEVICE_OBJECT DeviceObject = NULL; UNICODE_STRING DeviceName; DPRINT("KMON In DriverEntry\n"); DPRINT("KMON RegistryPath = %ws\n", RegistryPath->Buffer); #ifdef USE_DRIVER_UNLOAD DriverObject->DriverUnload = UnloadRoutine; #else DriverObject->DriverUnload = NULL; #endif DriverObject->MajorFunction[IRP_MJ_CREATE]= DriverIrpHandler; DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverIrpHandler; DriverObject->MajorFunction[IRP_MJ_READ] = DriverIrpHandler; DriverObject->MajorFunction[IRP_MJ_WRITE] = DriverIrpHandler; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DriverIrpHandler; DriverObject->MajorFunction[IRP_MJ_FLUSH_BUFFERS] = DriverIrpHandler; DriverObject->MajorFunction[IRP_MJ_CLEANUP] = DriverIrpHandler; DriverObject->MajorFunction[IRP_MJ_POWER] = DriverIrpHandler; RtlInitUnicodeString( &DeviceName, KMON_NT_DEVICE_NAME_W); Status = KLoggingInit(); if (!NT_SUCCESS(Status)) { DPRINT("KLoggingInit failure\n"); return Status; } KLog(LInfo, "DriverEntry drvObj=%p, regPath=%wZ", DriverObject, RegistryPath); Status = IoCreateDevice(DriverObject, sizeof(MDEVICE_EXTENSION), &DeviceName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeviceObject); if(!NT_SUCCESS(Status)) { KLoggingRelease(); return Status; } PMDEVICE_EXTENSION DevExt = (PMDEVICE_EXTENSION)DeviceObject->DeviceExtension; DevExt->DeviceObject = DeviceObject; // Сохраняем обратный указатель KLog(LInfo, "created Device %p, DevExt=%p", DeviceObject, DevExt); RtlInitUnicodeString(&DevExt->SymLinkName, KMON_DOS_DEVICE_NAME_W ); Status = IoCreateSymbolicLink( &DevExt->SymLinkName, &DeviceName ); if (!NT_SUCCESS(Status)) { IoDeleteDevice( DeviceObject ); KLoggingRelease(); return Status; } MonitorInit(DriverObject); KLog(LInfo, "DriverEntry successfully completed"); return Status; }
void Main (void) { void (*kernel_entry_point)(struct BootInfo *bi); void (*procman_entry_point)(void); size_t nbytes_read; size_t filesz; void *mod; void *addr; vm_addr heap_base, heap_ceiling; vm_addr user_stack_base, user_stack_ceiling; // Initialize bootloader dbg_init(); BlinkLEDs(10); sd_card_init(&bdev); fat_init(); init_mem(); // Load kernel at 1MB mark if (elf_load ("BOOT/KERNEL", (void *)&kernel_entry_point) != 0) KPanic ("Cannot load kernel"); kernel_phdr_cnt = phdr_cnt; bmemcpy (kernel_phdr_table, phdr_table, sizeof (Elf32_PHdr) * MAX_PHDR); user_base = 0x00800000; heap_base = segment_table[segment_cnt-1].base; heap_ceiling = segment_table[segment_cnt-1].ceiling; if (heap_ceiling > user_base) heap_ceiling = user_base; addr = SegmentCreate (heap_base, heap_ceiling - heap_base, SEG_TYPE_ALLOC, MAP_FIXED | PROT_READWRITE); if (addr == NULL) KPanic ("Could not allocate HEAP!"); KLog ("heap_base = %#010x, heap_ceiling = %#010x", heap_base, heap_ceiling); // Load root process (the Executive at 8MB mark if (elf_load ("BOOT/FILESYS", (void *)&procman_entry_point) != 0) KPanic ("Cannot load filesystem manager"); procman_phdr_cnt = phdr_cnt; bmemcpy (procman_phdr_table, phdr_table, sizeof (Elf32_PHdr) * MAX_PHDR); // Allocate memory for module table, read startup.txt // and load modules above 8MB module_table = SegmentCreate (user_base, sizeof (struct Module) * NMODULE, SEG_TYPE_ALLOC, PROT_READWRITE); KLog ("module_table = %#010x", module_table); if ((vm_addr)module_table < user_base) KPanic ("Bad module_table"); if (fat_open ("BOOT/STARTUP.TXT") != 0) KPanic ("Cannot open STARTUP.TXT"); module_cnt = 0; while (module_cnt < NMODULE) { if ((nbytes_read = fat_getline(module_table[module_cnt].name, 64)) == 0) break; if (module_table[module_cnt].name[0] == '\0' || module_table[module_cnt].name[0] == '\n' || module_table[module_cnt].name[0] == '\r' || module_table[module_cnt].name[0] == ' ') { KLOG ("Skipping blank lines"); continue; } if (fat_open (module_table[module_cnt].name) != 0) KPanic ("Cannot open module"); filesz = fat_get_filesize(); mod = SegmentCreate (user_base, filesz, SEG_TYPE_ALLOC, PROT_READWRITE); if (fat_read (mod, filesz) == filesz) { module_table[module_cnt].addr = mod; module_table[module_cnt].size = filesz; module_cnt++; } } // Allocate a stack for the Executive user_stack_base = SegmentCreate (user_base, 65536, SEG_TYPE_ALLOC, PROT_READWRITE); user_stack_ceiling = user_stack_base + 65536; // Pass the bootinfo, segment_table and module_table to kernel. bootinfo.procman_entry_point = procman_entry_point; bootinfo.user_stack_base = user_stack_base; bootinfo.user_stack_ceiling = user_stack_ceiling; bootinfo.user_base = user_base; bootinfo.heap_base = heap_base; bootinfo.heap_ceiling = heap_ceiling; bootinfo.screen_width = screen_width; bootinfo.screen_height = screen_height; bootinfo.screen_buf = screen_buf; bootinfo.screen_pitch = screen_pitch; bootinfo.module_table = module_table; bootinfo.module_cnt = module_cnt; bootinfo.segment_table = segment_table; bootinfo.segment_cnt = segment_cnt; KLOG ("Calling KERNEL entry point %#010x", (uint32) kernel_entry_point); kernel_entry_point(&bootinfo); while (1); }