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

📄 disk.c

📁 WinAoE is an open source GPLv3 driver for using AoE (ATA over Ethernet) on Microsoft Windows
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
  Copyright 2006-2008, V.
  For contact information, see http://winaoe.org/

  This file is part of WinAoE.

  WinAoE is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  WinAoE is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with WinAoE.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "portable.h"
#include <stdio.h>
#include <ntddk.h>
#include <srb.h>
#include <scsi.h>
#include <ntddscsi.h>
#include <ntddstor.h>
#include <ntdddisk.h>
#include <initguid.h>
#include "driver.h"
#include "aoe.h"

#ifndef _MSC_VER
long long __divdi3(long long u, long long v) {return u / v;}
#endif

#ifdef _MSC_VER
#if _WIN32_WINNT <= 0x0500
#ifdef _MSC_VER
#pragma pack(1)
#endif
typedef union _EIGHT_BYTE {
  struct {
    UCHAR Byte0;
    UCHAR Byte1;
    UCHAR Byte2;
    UCHAR Byte3;
    UCHAR Byte4;
    UCHAR Byte5;
    UCHAR Byte6;
    UCHAR Byte7;
  };
  ULONGLONG AsULongLong;
} __attribute__((__packed__)) EIGHT_BYTE, *PEIGHT_BYTE;
#ifdef _MSC_VER
#pragma pack()
#endif

#define REVERSE_BYTES_QUAD(Destination, Source) { \
  PEIGHT_BYTE d = (PEIGHT_BYTE)(Destination);     \
  PEIGHT_BYTE s = (PEIGHT_BYTE)(Source);          \
  d->Byte7 = s->Byte0;                            \
  d->Byte6 = s->Byte1;                            \
  d->Byte5 = s->Byte2;                            \
  d->Byte4 = s->Byte3;                            \
  d->Byte3 = s->Byte4;                            \
  d->Byte2 = s->Byte5;                            \
  d->Byte1 = s->Byte6;                            \
  d->Byte0 = s->Byte7;                            \
}
#endif
#endif

#if _WIN32_WINNT < 0x0502
#ifdef _MSC_VER
#pragma pack(1)
#endif
typedef struct _READ_CAPACITY_DATA_EX {
  LARGE_INTEGER LogicalBlockAddress;
  ULONG BytesPerBlock;
} __attribute__((__packed__)) READ_CAPACITY_DATA_EX, *PREAD_CAPACITY_DATA_EX;
#ifdef _MSC_VER
#pragma pack()
#endif
#endif

#ifdef _MSC_VER
#pragma pack(1)
#endif
typedef struct _PORTABLE_CDB16 {
  UCHAR OperationCode;
  UCHAR Reserved1:3;
  UCHAR ForceUnitAccess:1;
  UCHAR DisablePageOut:1;
  UCHAR Protection:3;
  UCHAR LogicalBlock[8];
  UCHAR TransferLength[4];
  UCHAR Reserved2;
  UCHAR Control;
} __attribute__((__packed__)) CDB16, *PCDB16;
#ifdef _MSC_VER
#pragma pack()
#endif

DEFINE_GUID(GUID_BUS_TYPE_INTERNAL, 0x2530ea73L, 0x086b, 0x11d1, 0xa0, 0x9f, 0x00, 0xc0, 0x4f, 0xc3, 0x40, 0xb1);

// in this file
NTSTATUS STDCALL BusGetDeviceCapabilities(IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_CAPABILITIES DeviceCapabilities);

NTSTATUS STDCALL DiskDispatchPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PIO_STACK_LOCATION Stack, IN PDEVICEEXTENSION DeviceExtension) {
  NTSTATUS Status;
  PDEVICE_RELATIONS DeviceRelations;
  PPNP_BUS_INFORMATION PnPBusInformation;
  PDEVICE_CAPABILITIES DeviceCapabilities;
  DEVICE_CAPABILITIES ParentDeviceCapabilities;
  PWCHAR String;
  ULONG StringLength;

  switch (Stack->MinorFunction) {
    case IRP_MN_QUERY_ID:
      if ((String = (PWCHAR)ExAllocatePool(NonPagedPool, (512 * sizeof(WCHAR)))) == NULL) {
        DbgPrint("DiskDispatchPnP ExAllocatePool IRP_MN_QUERY_ID\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        break;
      }
      RtlZeroMemory(String, (512 * sizeof(WCHAR)));
      switch (Stack->Parameters.QueryId.IdType) {
        case BusQueryDeviceID:
          StringLength = swprintf(String, L"AoE\\Disk%lu", DeviceExtension->Disk.DiskNumber) + 1;
          if ((Irp->IoStatus.Information = (ULONG_PTR)ExAllocatePool(PagedPool, StringLength * sizeof(WCHAR))) == 0) {
            DbgPrint("DiskDispatchPnP ExAllocatePool BusQueryDeviceID\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
          }
          RtlCopyMemory((PWCHAR)Irp->IoStatus.Information, String, StringLength * sizeof(WCHAR));
          Status = STATUS_SUCCESS;
          break;
        case BusQueryInstanceID:
          StringLength = swprintf(String, L"AOEDISK%lu", DeviceExtension->Disk.DiskNumber) + 1;
          if ((Irp->IoStatus.Information = (ULONG_PTR)ExAllocatePool(PagedPool, StringLength * sizeof(WCHAR))) == 0) {
            DbgPrint("DiskDispatchPnP ExAllocatePool BusQueryInstanceID\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
          }
          RtlCopyMemory((PWCHAR)Irp->IoStatus.Information, String, StringLength * sizeof(WCHAR));
          Status = STATUS_SUCCESS;
          break;
        case BusQueryHardwareIDs:
          StringLength = swprintf(String, L"AoE\\Disk%lu", DeviceExtension->Disk.DiskNumber) + 1;
          StringLength += swprintf(&String[StringLength], L"GenDisk") + 4;
          if ((Irp->IoStatus.Information = (ULONG_PTR)ExAllocatePool(PagedPool, StringLength * sizeof(WCHAR))) == 0) {
            DbgPrint("DiskDispatchPnP ExAllocatePool BusQueryHardwareIDs\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
          }
          RtlCopyMemory((PWCHAR)Irp->IoStatus.Information, String, StringLength * sizeof(WCHAR));
          Status = STATUS_SUCCESS;
          break;
        case BusQueryCompatibleIDs:
          StringLength = swprintf(String, L"GenDisk") + 4;
          if ((Irp->IoStatus.Information = (ULONG_PTR)ExAllocatePool(PagedPool, StringLength * sizeof(WCHAR))) == 0) {
            DbgPrint("DiskDispatchPnP ExAllocatePool BusQueryCompatibleIDs\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
          }
          RtlCopyMemory((PWCHAR)Irp->IoStatus.Information, String, StringLength * sizeof(WCHAR));
          Status = STATUS_SUCCESS;
          break;
        default:
          Irp->IoStatus.Information = 0;
          Status = STATUS_NOT_SUPPORTED;
      }
      ExFreePool(String);
      break;
    case IRP_MN_QUERY_DEVICE_TEXT:
      if ((String = (PWCHAR)ExAllocatePool(NonPagedPool, (512 * sizeof(WCHAR)))) == NULL) {
        DbgPrint("DiskDispatchPnP ExAllocatePool IRP_MN_QUERY_DEVICE_TEXT\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        break;
      }
      RtlZeroMemory(String, (512 * sizeof(WCHAR)));
      switch (Stack->Parameters.QueryDeviceText.DeviceTextType ) {
        case DeviceTextDescription:
          StringLength = swprintf(String, L"AoE Disk") + 1;
          if ((Irp->IoStatus.Information = (ULONG_PTR)ExAllocatePool(PagedPool, StringLength * sizeof(WCHAR))) == 0) {
            DbgPrint("DiskDispatchPnP ExAllocatePool DeviceTextDescription\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
          }
          RtlCopyMemory((PWCHAR)Irp->IoStatus.Information, String, StringLength * sizeof(WCHAR));
          Status = STATUS_SUCCESS;
          break;
        case DeviceTextLocationInformation:
          StringLength = swprintf(String, L"AoE e%d.%d", DeviceExtension->Disk.Major, DeviceExtension->Disk.Minor) + 1;
          if ((Irp->IoStatus.Information = (ULONG_PTR)ExAllocatePool(PagedPool, StringLength * sizeof(WCHAR))) == 0) {
            DbgPrint("DiskDispatchPnP ExAllocatePool DeviceTextLocationInformation\n");
            Status = STATUS_INSUFFICIENT_RESOURCES;
            break;
          }
          RtlCopyMemory((PWCHAR)Irp->IoStatus.Information, String, StringLength * sizeof(WCHAR));
          Status = STATUS_SUCCESS;
          break;
        default:
          Irp->IoStatus.Information = 0;
          Status = STATUS_NOT_SUPPORTED;
      }
      ExFreePool(String);
      break;
    case IRP_MN_QUERY_DEVICE_RELATIONS:
      if (Stack->Parameters.QueryDeviceRelations.Type != TargetDeviceRelation) {
        Status = Irp->IoStatus.Status;
        break;
      }
      if ((DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS) + sizeof (PDEVICE_OBJECT))) == NULL) {
        DbgPrint("DiskDispatchPnP ExAllocatePool IRP_MN_QUERY_DEVICE_RELATIONS\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        break;
      }
      DeviceRelations->Objects[0] = DeviceExtension->Self;
      DeviceRelations->Count = 1;
      ObReferenceObject(DeviceExtension->Self);
      Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations;
      Status = STATUS_SUCCESS;
      break;
    case IRP_MN_QUERY_BUS_INFORMATION:
      if ((PnPBusInformation = (PPNP_BUS_INFORMATION)ExAllocatePool(PagedPool, sizeof(PNP_BUS_INFORMATION))) == NULL) {
        DbgPrint("DiskDispatchPnP ExAllocatePool IRP_MN_QUERY_BUS_INFORMATION\n");
        Status = STATUS_INSUFFICIENT_RESOURCES;
        break;
      }
      PnPBusInformation->BusTypeGuid = GUID_BUS_TYPE_INTERNAL;
      PnPBusInformation->LegacyBusType = PNPBus;
      PnPBusInformation->BusNumber = 0;
      Irp->IoStatus.Information = (ULONG_PTR)PnPBusInformation;
      Status = STATUS_SUCCESS;
      break;
    case IRP_MN_QUERY_CAPABILITIES:
      DeviceCapabilities = Stack->Parameters.DeviceCapabilities.Capabilities;
      if (DeviceCapabilities->Version != 1 || DeviceCapabilities->Size < sizeof(DEVICE_CAPABILITIES)) {
        Status = STATUS_UNSUCCESSFUL;
        break;
      }
      if (!NT_SUCCESS(Status = BusGetDeviceCapabilities(((PDEVICEEXTENSION)DeviceExtension->Disk.Parent->DeviceExtension)->Bus.LowerDeviceObject, &ParentDeviceCapabilities))) break;
      RtlCopyMemory(DeviceCapabilities->DeviceState, ParentDeviceCapabilities.DeviceState, (PowerSystemShutdown + 1) * sizeof(DEVICE_POWER_STATE));
      DeviceCapabilities->DeviceState[PowerSystemWorking] = PowerDeviceD0;
      if (DeviceCapabilities->DeviceState[PowerSystemSleeping1] != PowerDeviceD0) DeviceCapabilities->DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
      if (DeviceCapabilities->DeviceState[PowerSystemSleeping2] != PowerDeviceD0) DeviceCapabilities->DeviceState[PowerSystemSleeping2] = PowerDeviceD3;
//      if (DeviceCapabilities->DeviceState[PowerSystemSleeping3] != PowerDeviceD0) DeviceCapabilities->DeviceState[PowerSystemSleeping3] = PowerDeviceD3;
      DeviceCapabilities->DeviceWake = PowerDeviceD1;
      DeviceCapabilities->DeviceD1 = TRUE;
      DeviceCapabilities->DeviceD2 = FALSE;
      DeviceCapabilities->WakeFromD0 = FALSE;
      DeviceCapabilities->WakeFromD1 = FALSE;
      DeviceCapabilities->WakeFromD2 = FALSE;
      DeviceCapabilities->WakeFromD3 = FALSE;
      DeviceCapabilities->D1Latency = 0;
      DeviceCapabilities->D2Latency = 0;
      DeviceCapabilities->D3Latency = 0;
      DeviceCapabilities->EjectSupported = FALSE;
      DeviceCapabilities->HardwareDisabled = FALSE;
      DeviceCapabilities->Removable = FALSE;
      DeviceCapabilities->SurpriseRemovalOK = FALSE;
      DeviceCapabilities->UniqueID = FALSE;
      DeviceCapabilities->SilentInstall = FALSE;
//      DeviceCapabilities->Address = DeviceObject->SerialNo;
//      DeviceCapabilities->UINumber = DeviceObject->SerialNo;
      Status = STATUS_SUCCESS;
      break;
    case IRP_MN_DEVICE_USAGE_NOTIFICATION:
      if (Stack->Parameters.UsageNotification.InPath) {
        DeviceExtension->Disk.SpecialFileCount++;
      } else {
        DeviceExtension->Disk.SpecialFileCount--;
      }
      Irp->IoStatus.Information = 0;
      Status = STATUS_SUCCESS;
      break;
    case IRP_MN_QUERY_PNP_DEVICE_STATE:
      Irp->IoStatus.Information = 0;
      Status = STATUS_SUCCESS;
      break;
    case IRP_MN_START_DEVICE:
      DeviceExtension->OldState = DeviceExtension->State;
      DeviceExtension->State = Started;
      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_REMOVE_DEVICE:
      DeviceExtension->OldState = DeviceExtension->State;
      DeviceExtension->State = NotStarted;
      if (DeviceExtension->Disk.Unmount) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -