📄 bus.c
字号:
Walker = BusDeviceExtension->Bus.ChildList;
while (Walker->Disk.Next != NULL) Walker = Walker->Disk.Next;
Walker->Disk.Next = DeviceExtension;
}
BusDeviceExtension->Bus.Children++;
return TRUE;
}
NTSTATUS STDCALL BusDispatchPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION Stack, IN PDEVICEEXTENSION DeviceExtension) {
NTSTATUS Status;
KEVENT Event;
PDEVICE_RELATIONS DeviceRelations;
PDEVICEEXTENSION Walker, Next;
ULONG Count;
switch (Stack->MinorFunction) {
case IRP_MN_START_DEVICE:
KeInitializeEvent(&Event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, (PIO_COMPLETION_ROUTINE)IoCompletionRoutine, (PVOID)&Event, TRUE, TRUE, TRUE);
Status = IoCallDriver(DeviceExtension->Bus.LowerDeviceObject, Irp);
if (Status == STATUS_PENDING) {
DbgPrint("Locked\n");
KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
}
if (NT_SUCCESS(Status = Irp->IoStatus.Status)) {
DeviceExtension->OldState = DeviceExtension->State;
DeviceExtension->State = Started;
}
Status = STATUS_SUCCESS;
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
case IRP_MN_REMOVE_DEVICE:
DeviceExtension->OldState = DeviceExtension->State;
DeviceExtension->State = Deleted;
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(DeviceExtension->Bus.LowerDeviceObject, Irp);
Walker = DeviceExtension->Bus.ChildList;
while (Walker != NULL) {
Next = Walker->Disk.Next;
IoDeleteDevice(Walker->Self);
Walker = Next;
}
DeviceExtension->Bus.Children = 0;
DeviceExtension->Bus.ChildList = NULL;
IoDetachDevice(DeviceExtension->Bus.LowerDeviceObject);
IoDeleteDevice(DeviceExtension->Self);
return Status;
case IRP_MN_QUERY_DEVICE_RELATIONS:
if (Stack->Parameters.QueryDeviceRelations.Type != BusRelations || Irp->IoStatus.Information) {
Status = Irp->IoStatus.Status;
break;
}
Count = 0;
Walker = DeviceExtension->Bus.ChildList;
while (Walker != NULL) {
Count++;
Walker = Walker->Disk.Next;
}
if ((DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(NonPagedPool, sizeof(DEVICE_RELATIONS) + (sizeof(PDEVICE_OBJECT) * Count))) == NULL) {
Irp->IoStatus.Information = 0;
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
DeviceRelations->Count = Count;
Count = 0;
Walker = DeviceExtension->Bus.ChildList;
while (Walker != NULL) {
DeviceRelations->Objects[Count] = Walker->Self;
Count++;
Walker = Walker->Disk.Next;
}
Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
Status = STATUS_SUCCESS;
break;
case IRP_MN_QUERY_PNP_DEVICE_STATE:
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
break;
case IRP_MN_QUERY_STOP_DEVICE:
DeviceExtension->OldState = DeviceExtension->State;
DeviceExtension->State = StopPending;
Status = STATUS_SUCCESS;
break;
case IRP_MN_CANCEL_STOP_DEVICE:
DeviceExtension->State = DeviceExtension->OldState;
Status = STATUS_SUCCESS;
break;
case IRP_MN_STOP_DEVICE:
DeviceExtension->OldState = DeviceExtension->State;
DeviceExtension->State = Stopped;
Status = STATUS_SUCCESS;
break;
case IRP_MN_QUERY_REMOVE_DEVICE:
DeviceExtension->OldState = DeviceExtension->State;
DeviceExtension->State = RemovePending;
Status = STATUS_SUCCESS;
break;
case IRP_MN_CANCEL_REMOVE_DEVICE:
DeviceExtension->State = DeviceExtension->OldState;
Status = STATUS_SUCCESS;
break;
case IRP_MN_SURPRISE_REMOVAL:
DeviceExtension->OldState = DeviceExtension->State;
DeviceExtension->State = SurpriseRemovePending;
Status = STATUS_SUCCESS;
break;
default:
Status = Irp->IoStatus.Status;
}
Irp->IoStatus.Status = Status;
IoSkipCurrentIrpStackLocation(Irp);
Status = IoCallDriver(DeviceExtension->Bus.LowerDeviceObject, Irp);
return Status;
}
NTSTATUS STDCALL BusDispatchDeviceControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION Stack, IN PDEVICEEXTENSION DeviceExtension) {
NTSTATUS Status;
PUCHAR Buffer;
ULONG Count;
PTARGETLIST TargetWalker;
PDEVICEEXTENSION DiskWalker, DiskWalkerPrevious;
PTARGETS Targets;
PDISKS Disks;
KIRQL Irql;
switch (Stack->Parameters.DeviceIoControl.IoControlCode) {
case IOCTL_AOE_SCAN:
DbgPrint("Got IOCTL_AOE_SCAN...\n");
KeAcquireSpinLock(&TargetListSpinLock, &Irql);
Count = 0;
TargetWalker = TargetList;
while (TargetWalker != NULL) {
Count++;
TargetWalker = TargetWalker->Next;
}
if ((Targets = (PTARGETS)ExAllocatePool(NonPagedPool, sizeof(TARGETS) + (Count * sizeof(TARGET)))) == NULL) {
DbgPrint("BusDispatchDeviceControl ExAllocatePool Targets\n");
Irp->IoStatus.Information = 0;
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
Irp->IoStatus.Information = sizeof(TARGETS) + (Count * sizeof(TARGET));
Targets->Count = Count;
Count = 0;
TargetWalker = TargetList;
while (TargetWalker != NULL) {
RtlCopyMemory(&Targets->Target[Count], &TargetWalker->Target, sizeof(TARGET));
Count++;
TargetWalker = TargetWalker->Next;
}
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Targets, (Stack->Parameters.DeviceIoControl.OutputBufferLength < (sizeof(TARGETS) + (Count * sizeof(TARGET)))?Stack->Parameters.DeviceIoControl.OutputBufferLength:(sizeof(TARGETS) + (Count * sizeof(TARGET)))));
ExFreePool(Targets);
KeReleaseSpinLock(&TargetListSpinLock, Irql);
Status = STATUS_SUCCESS;
break;
case IOCTL_AOE_SHOW:
DbgPrint("Got IOCTL_AOE_SHOW...\n");
Count = 0;
DiskWalker = DeviceExtension->Bus.ChildList;
while (DiskWalker != NULL) {
Count++;
DiskWalker = DiskWalker->Disk.Next;
}
if ((Disks = (PDISKS)ExAllocatePool(NonPagedPool, sizeof(DISKS) + (Count * sizeof(DISK)))) == NULL) {
DbgPrint("BusDispatchDeviceControl ExAllocatePool Disks\n");
Irp->IoStatus.Information = 0;
Status = STATUS_INSUFFICIENT_RESOURCES;
break;
}
Irp->IoStatus.Information = sizeof(DISKS) + (Count * sizeof(DISK));
Disks->Count = Count;
Count = 0;
DiskWalker = DeviceExtension->Bus.ChildList;
while (DiskWalker != NULL) {
Disks->Disk[Count].Disk = DiskWalker->Disk.DiskNumber;
RtlCopyMemory(&Disks->Disk[Count].ClientMac, &DiskWalker->Disk.ClientMac, 6);
RtlCopyMemory(&Disks->Disk[Count].ServerMac, &DiskWalker->Disk.ServerMac, 6);
Disks->Disk[Count].Major = DiskWalker->Disk.Major;
Disks->Disk[Count].Minor = DiskWalker->Disk.Minor;
Disks->Disk[Count].LBASize = DiskWalker->Disk.LBADiskSize;
Count++;
DiskWalker = DiskWalker->Disk.Next;
}
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Disks, (Stack->Parameters.DeviceIoControl.OutputBufferLength < (sizeof(DISKS) + (Count * sizeof(DISK)))?Stack->Parameters.DeviceIoControl.OutputBufferLength:(sizeof(DISKS) + (Count * sizeof(DISK)))));
ExFreePool(Disks);
Status = STATUS_SUCCESS;
break;
case IOCTL_AOE_MOUNT:
Buffer = Irp->AssociatedIrp.SystemBuffer;
DbgPrint("Got IOCTL_AOE_MOUNT for client: %02x:%02x:%02x:%02x:%02x:%02x Major:%d Minor:%d\n", Buffer[0], Buffer[1], Buffer[2], Buffer[3], Buffer[4], Buffer[5], *(PUSHORT)(&Buffer[6]), (UCHAR)Buffer[8]);
if (!BusAddChild(DeviceObject, Buffer, *(PUSHORT)(&Buffer[6]), (UCHAR)Buffer[8], FALSE)) {
DbgPrint("BusAddChild failed\n");
} else {
if (DeviceExtension->Bus.PhysicalDeviceObject != NULL) IoInvalidateDeviceRelations(DeviceExtension->Bus.PhysicalDeviceObject, BusRelations);
}
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
break;
case IOCTL_AOE_UMOUNT:
Buffer = Irp->AssociatedIrp.SystemBuffer;
DbgPrint("Got IOCTL_AOE_UMOUNT for disk: %d\n", *(PULONG)Buffer);
DiskWalker = DeviceExtension->Bus.ChildList;
DiskWalkerPrevious = DiskWalker;
while ((DiskWalker != NULL) && (!DiskWalker->Disk.BootDrive) && (DiskWalker->Disk.DiskNumber != *(PULONG)Buffer)) {
DiskWalkerPrevious = DiskWalker;
DiskWalker = DiskWalker->Disk.Next;
}
if (DiskWalker != NULL) {
DbgPrint("Deleting disk %d\n", DiskWalker->Disk.DiskNumber);
if (DiskWalker == DeviceExtension->Bus.ChildList) {
DeviceExtension->Bus.ChildList = DiskWalker->Disk.Next;
} else {
DiskWalkerPrevious->Disk.Next = DiskWalker->Disk.Next;
}
DiskWalker->Disk.Unmount = TRUE;
DiskWalker->Disk.Next = NULL;
if (DeviceExtension->Bus.PhysicalDeviceObject != NULL) IoInvalidateDeviceRelations(DeviceExtension->Bus.PhysicalDeviceObject, BusRelations);
}
DeviceExtension->Bus.Children--;
Irp->IoStatus.Information = 0;
Status = STATUS_SUCCESS;
break;
default:
Irp->IoStatus.Information = 0;
Status = STATUS_INVALID_DEVICE_REQUEST;
}
Irp->IoStatus.Status = Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return Status;
}
NTSTATUS STDCALL BusDispatchSystemControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION Stack, IN PDEVICEEXTENSION DeviceExtension) {
DbgPrint("...\n");
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(DeviceExtension->Bus.LowerDeviceObject, Irp);
}
NTSTATUS STDCALL IoCompletionRoutine(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKEVENT Event) {
KeSetEvent(Event, 0, FALSE);
return STATUS_MORE_PROCESSING_REQUIRED;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -