⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bus.c

📁 WinAoE is an open source GPLv3 driver for using AoE (ATA over Ethernet) on Microsoft Windows
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -