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

📄 isapnp.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 3 页
字号:
  ULONG Size,
  ULONG Priority,
  ULONG Option)
{
  PISAPNP_DESCRIPTOR Descriptor;
	UCHAR tmp[3];
  ULONG irq, i, last = 0;
  BOOLEAN found;
  NTSTATUS Status;

	Peek(tmp, Size);

	irq = UCHAR2USHORT(tmp[0], tmp[0]);

  DPRINT("IRQ bitmask: 0x%X\n", irq);

  found = FALSE;
  for (i = 0; i < 16; i++) {
    if (!found && (irq & (1 << i))) {
      last = i;
      found = TRUE;
    }

    if ((found && !(irq & (1 << i))) || (irq & (1 << i) && (i == 15))) {
      Status = AddResourceDescriptor(LogicalDevice,
        Priority, Option, &Descriptor);
      if (!NT_SUCCESS(Status))
        return Status;
      Descriptor->Descriptor.Type = CmResourceTypeInterrupt;
      Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
      Descriptor->Descriptor.u.Interrupt.MinimumVector = last;

      if ((irq & (1 << i)) && (i == 15))
        Descriptor->Descriptor.u.Interrupt.MaximumVector = i;
      else
        Descriptor->Descriptor.u.Interrupt.MaximumVector = i - 1;

      DPRINT("Found IRQ range %d - %d for logical device %d on card %d\n",
        Descriptor->Descriptor.u.Interrupt.MinimumVector,
        Descriptor->Descriptor.u.Interrupt.MaximumVector,
        LogicalDevice->Number,
        LogicalDevice->Card->CardId);

      found = FALSE;
    }
  }

  return STATUS_SUCCESS;
}

/*
 * Add DMA resource to resources list
 */
static NTSTATUS AddDmaResource(
  PISAPNP_LOGICAL_DEVICE LogicalDevice,
  ULONG Size,
  ULONG Priority,
  ULONG Option)
{
  PISAPNP_DESCRIPTOR Descriptor;
	UCHAR tmp[2];
  ULONG dma, flags, i, last = 0;
  BOOLEAN found;
  NTSTATUS Status;

	Peek(tmp, Size);

	dma = tmp[0];
  flags = tmp[1];

  DPRINT("DMA bitmask: 0x%X\n", dma);

  found = FALSE;
  for (i = 0; i < 8; i++) {
    if (!found && (dma & (1 << i))) {
      last = i;
      found = TRUE;
    }

    if ((found && !(dma & (1 << i))) || (dma & (1 << i) && (i == 15))) {
      Status = AddResourceDescriptor(LogicalDevice,
        Priority, Option, &Descriptor);
      if (!NT_SUCCESS(Status))
        return Status;
      Descriptor->Descriptor.Type = CmResourceTypeDma;
      Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
      Descriptor->Descriptor.u.Dma.MinimumChannel = last;

      if ((dma & (1 << i)) && (i == 15))
        Descriptor->Descriptor.u.Dma.MaximumChannel = i;
      else
        Descriptor->Descriptor.u.Dma.MaximumChannel = i - 1;

      /* FIXME: Parse flags */

      DPRINT("Found DMA range %d - %d for logical device %d on card %d\n",
        Descriptor->Descriptor.u.Dma.MinimumChannel,
        Descriptor->Descriptor.u.Dma.MaximumChannel,
        LogicalDevice->Number,
        LogicalDevice->Card->CardId);

      found = FALSE;
    }
  }

  return STATUS_SUCCESS;
}

/*
 * Add port resource to resources list
 */
static NTSTATUS AddIOPortResource(
  PISAPNP_LOGICAL_DEVICE LogicalDevice,
  ULONG Size,
  ULONG Priority,
  ULONG Option)
{
#if 0
  DPRINT("I/O port: size 0x%X\n", Size);
  Skip(Size);
#else
  PISAPNP_DESCRIPTOR Descriptor;
	UCHAR tmp[7];
  NTSTATUS Status;

	Peek(tmp, Size);

  Status = AddResourceDescriptor(LogicalDevice,
    Priority, Option, &Descriptor);
  if (!NT_SUCCESS(Status))
    return Status;
  Descriptor->Descriptor.Type = CmResourceTypePort;
  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
  Descriptor->Descriptor.u.Port.Length = tmp[6];
  /* FIXME: Parse flags */
  Descriptor->Descriptor.u.Port.Alignment = 0;
  Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]);
  Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[4], tmp[4]);

  DPRINT("Found I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
    Descriptor->Descriptor.u.Port.MinimumAddress,
    Descriptor->Descriptor.u.Port.MaximumAddress,
    LogicalDevice->Number,
    LogicalDevice->Card->CardId);
#endif
  return STATUS_SUCCESS;
}

/*
 * Add fixed port resource to resources list
 */
static NTSTATUS AddFixedIOPortResource(
  PISAPNP_LOGICAL_DEVICE LogicalDevice,
  ULONG Size,
  ULONG Priority,
  ULONG Option)
{
#if 0
  DPRINT("Fixed I/O port: size 0x%X\n", Size);
  Skip(Size);
#else
  PISAPNP_DESCRIPTOR Descriptor;
	UCHAR tmp[3];
  NTSTATUS Status;

	Peek(tmp, Size);

  Status = AddResourceDescriptor(LogicalDevice,
    Priority, Option, &Descriptor);
  if (!NT_SUCCESS(Status))
    return Status;
  Descriptor->Descriptor.Type = CmResourceTypePort;
  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
  Descriptor->Descriptor.u.Port.Length = tmp[2];
  Descriptor->Descriptor.u.Port.Alignment = 0;
  Descriptor->Descriptor.u.Port.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]);
  Descriptor->Descriptor.u.Port.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[0], tmp[1]);

  DPRINT("Found fixed I/O port range 0x%X - 0x%X for logical device %d on card %d\n",
    Descriptor->Descriptor.u.Port.MinimumAddress,
    Descriptor->Descriptor.u.Port.MaximumAddress,
    LogicalDevice->Number,
    LogicalDevice->Card->CardId);
#endif
  return STATUS_SUCCESS;
}

/*
 * Add memory resource to resources list
 */
static NTSTATUS AddMemoryResource(
  PISAPNP_LOGICAL_DEVICE LogicalDevice,
  ULONG Size,
  ULONG Priority,
  ULONG Option)
{
#if 0
  DPRINT("Memory range: size 0x%X\n", Size);
  Skip(Size);
#else
  PISAPNP_DESCRIPTOR Descriptor;
	UCHAR tmp[9];
  NTSTATUS Status;

	Peek(tmp, Size);

  Status = AddResourceDescriptor(LogicalDevice,
    Priority, Option, &Descriptor);
  if (!NT_SUCCESS(Status))
    return Status;
  Descriptor->Descriptor.Type = CmResourceTypeMemory;
  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
  Descriptor->Descriptor.u.Memory.Length = UCHAR2USHORT(tmp[7], tmp[8]) << 8;
  Descriptor->Descriptor.u.Memory.Alignment = UCHAR2USHORT(tmp[5], tmp[6]);
  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart = UCHAR2USHORT(tmp[1], tmp[2]) << 8;
  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart = UCHAR2USHORT(tmp[3], tmp[4]) << 8;

  DPRINT("Found memory range 0x%X - 0x%X for logical device %d on card %d\n",
    Descriptor->Descriptor.u.Memory.MinimumAddress,
    Descriptor->Descriptor.u.Memory.MaximumAddress,
    LogicalDevice->Number,
    LogicalDevice->Card->CardId);
#endif
  return STATUS_SUCCESS;
}

/*
 * Add 32-bit memory resource to resources list
 */
static NTSTATUS AddMemory32Resource(
  PISAPNP_LOGICAL_DEVICE LogicalDevice,
  ULONG Size,
  ULONG Priority,
  ULONG Option)
{
#if 0
  DPRINT("Memory32 range: size 0x%X\n", Size);
  Skip(Size);
#else
  PISAPNP_DESCRIPTOR Descriptor;
	UCHAR tmp[17];
  NTSTATUS Status;

	Peek(tmp, Size);

  Status = AddResourceDescriptor(LogicalDevice,
    Priority, Option, &Descriptor);
  if (!NT_SUCCESS(Status))
    return Status;
  Descriptor->Descriptor.Type = CmResourceTypeMemory;
  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
  Descriptor->Descriptor.u.Memory.Length =
    UCHAR2ULONG(tmp[13], tmp[14], tmp[15], tmp[16]);
  Descriptor->Descriptor.u.Memory.Alignment =
    UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]);
  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart =
    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart =
    UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]);

  DPRINT("Found memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
    Descriptor->Descriptor.u.Memory.MinimumAddress,
    Descriptor->Descriptor.u.Memory.MaximumAddress,
    LogicalDevice->Number,
    LogicalDevice->Card->CardId);
#endif
  return STATUS_SUCCESS;
}

/*
 * Add 32-bit fixed memory resource to resources list
 */
static NTSTATUS AddFixedMemory32Resource(
  PISAPNP_LOGICAL_DEVICE LogicalDevice,
  ULONG Size,
  ULONG Priority,
  ULONG Option)
{
#if 0
  DPRINT("Memory32 range: size 0x%X\n", Size);
  Skip(Size);
#else
  PISAPNP_DESCRIPTOR Descriptor;
	UCHAR tmp[17];
  NTSTATUS Status;

	Peek(tmp, Size);

  Status = AddResourceDescriptor(LogicalDevice,
    Priority, Option, &Descriptor);
  if (!NT_SUCCESS(Status))
    return Status;
  Descriptor->Descriptor.Type = CmResourceTypeMemory;
  Descriptor->Descriptor.ShareDisposition = CmResourceShareDeviceExclusive;
  Descriptor->Descriptor.u.Memory.Length =
    UCHAR2ULONG(tmp[9], tmp[10], tmp[11], tmp[12]);
  Descriptor->Descriptor.u.Memory.Alignment =
    UCHAR2ULONG(tmp[5], tmp[6], tmp[7], tmp[8]);
  Descriptor->Descriptor.u.Memory.MinimumAddress.QuadPart =
    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);
  Descriptor->Descriptor.u.Memory.MaximumAddress.QuadPart =
    UCHAR2ULONG(tmp[1], tmp[2], tmp[3], tmp[4]);

  DPRINT("Found fixed memory32 range 0x%X - 0x%X for logical device %d on card %d\n",
    Descriptor->Descriptor.u.Memory.MinimumAddress,
    Descriptor->Descriptor.u.Memory.MaximumAddress,
    LogicalDevice->Number,
    LogicalDevice->Card->CardId);
#endif
  return STATUS_SUCCESS;
}


/*
 * Parse logical device tag
 */
static PISAPNP_LOGICAL_DEVICE ParseLogicalDevice(
  PISAPNP_DEVICE_EXTENSION DeviceExtension,
  PISAPNP_CARD Card,
  ULONG Size,
  USHORT Number)
{
	UCHAR tmp[6];
	PISAPNP_LOGICAL_DEVICE LogicalDevice;

  DPRINT("Card %d  Number %d\n", Card->CardId, Number);

  Peek(tmp, Size);

  LogicalDevice = (PISAPNP_LOGICAL_DEVICE)ExAllocatePoolWithTag(
    PagedPool, sizeof(ISAPNP_LOGICAL_DEVICE), TAG_ISAPNP);
	if (!LogicalDevice)
		return NULL;

  RtlZeroMemory(LogicalDevice, sizeof(ISAPNP_LOGICAL_DEVICE));

  LogicalDevice->Number = Number;
	LogicalDevice->VendorId = UCHAR2USHORT(tmp[0], tmp[1]);
	LogicalDevice->DeviceId = UCHAR2USHORT(tmp[2], tmp[3]);
	LogicalDevice->Regs = tmp[4];
	LogicalDevice->Card = Card;
	if (Size > 5)
		LogicalDevice->Regs |= tmp[5] << 8;

  InitializeListHead(&LogicalDevice->Configuration);

  ExInterlockedInsertTailList(&Card->LogicalDevices,
    &LogicalDevice->CardListEntry,
    &Card->LogicalDevicesLock);

  ExInterlockedInsertTailList(&DeviceExtension->DeviceListHead,
    &LogicalDevice->DeviceListEntry,
    &DeviceExtension->GlobalListLock);

  DeviceExtension->DeviceListCount++;

	return LogicalDevice;
}


/*
 * Parse resource map for logical device
 */
static BOOLEAN CreateLogicalDevice(PISAPNP_DEVICE_EXTENSION DeviceExtension,
  PISAPNP_CARD Card, USHORT Size)
{
	ULONG number = 0, skip = 0, compat = 0;
	UCHAR type, tmp[17];
  PISAPNP_LOGICAL_DEVICE LogicalDevice;
  BOOLEAN Small;
  ULONG Priority = 0;
  ULONG Option = IO_RESOURCE_REQUIRED;

  DPRINT("Card %d  Size %d\n", Card->CardId, Size);

  LogicalDevice = ParseLogicalDevice(DeviceExtension, Card, Size, (USHORT) number++);
	if (!LogicalDevice)
		return FALSE;

  while (TRUE) {
		if (!ReadTag(&type, &Size, &Small))
			return FALSE;

                if (skip && !(Small && ((type == ISAPNP_SRIN_LDEVICE_ID)
      || (type == ISAPNP_SRIN_END_TAG))))
			goto skip;

    if (Small) {
  		switch (type) {
	  	case ISAPNP_SRIN_LDEVICE_ID:
        if ((Size >= 5) && (Size <= 6)) {
          LogicalDevice = ParseLogicalDevice(
            DeviceExtension, Card, Size, (USHORT)number++);
	        if (!LogicalDevice)
  	        return FALSE;
  				Size = 0;
	  			skip = 0;
		  	} else {
			  	skip = 1;
			  }
        Priority = 0;
        Option = IO_RESOURCE_REQUIRED;
			  compat = 0;
			  break;

		  case ISAPNP_SRIN_CDEVICE_ID:
			  if ((Size == 4) && (compat < MAX_COMPATIBLE_ID)) {
				  Peek(tmp, 4);
				  LogicalDevice->CVendorId[compat] = UCHAR2USHORT(tmp[0], tmp[1]);
				  LogicalDevice->CDeviceId[compat] = UCHAR2USHORT(tmp[2], tmp[3]);
				  compat++;
				  Size = 0;
			  }
			  break;

		  case ISAPNP_SRIN_IRQ_FORMAT:
  			if ((Size < 2) || (Size > 3))
				  goto skip;
			  AddIrqResource(LogicalDevice, Size, Priority, Option);
			  Size = 0;
			  break;

		  case ISAPNP_SRIN_DMA_FORMAT:
  			if (Size != 2)
				  goto skip;
        AddDmaResource(LogicalDevice, Size, Priority, Option);
			  Size = 0;
			  break;

		  case ISAPNP_SRIN_START_DFUNCTION:
  			if (Size > 1)
				  goto skip;

        if (Size > 0) {
  				Peek(tmp, Size);
          Priority = tmp[0];
				  Size = 0;
          /* FIXME: Maybe use IO_RESOURCE_PREFERRED for some */
          Option = IO_RESOURCE_ALTERNATIVE;
        } else {
          Priority = 0;
          Option = IO_RESOURCE_ALTERNATIVE;
        }

        DPRINT("   Start priority %d   \n", Priority);

        LogicalDevice->CurrentDescriptorCount = 0;

			  break;

  		case ISAPNP_SRIN_END_DFUNCTION:

        DPRINT("   End priority %d   \n", Priority);

	  		if (Size != 0)
		  		goto skip;
        Priority = 0;
        Option = IO_RESOURCE_REQUIRED;
        LogicalDevice->CurrentDescriptorCount = 0;
			  break;

  		case ISAPNP_SRIN_IO_DESCRIPTOR:
	  		if (Size != 7)
		  		goto skip;
			  AddIOPortResource(LogicalDevice, Size, Priority, Option);
			  Size = 0;
			  break;

		  case ISAPNP_SRIN_FL_IO_DESCRIPOTOR:
			  if (Size != 3)
  				goto skip;
			  AddFixedIOPortResource(LogicalDevice, Size, Priority, Option);
			  Size = 0;
			  break;

		  case ISAPNP_SRIN_VENDOR_DEFINED:
  			break;

		  case ISAPNP_SRIN_END_TAG:
			  if (Size > 0)
  				Skip(Size);
        return FALSE;

		  default:
  			DPRINT("Ignoring small tag of type 0x%X for logical device %d on card %d\n",
          type, LogicalDevice->Number, Card->CardId);
      }
    } else {
      switch (type) {
		  case ISAPNP_LRIN_MEMORY_RANGE:
			  if (Size != 9)
  				goto skip;
			  AddMemoryResource(LogicalDevice, Size, Priority, Option);
			  Size = 0;
			  break;

		  case ISAPNP_LRIN_ID_STRING_ANSI:
        ParseAnsiName(&LogicalDevice->Name, &Size);
			  break;

		  case ISAPNP_LRIN_ID_STRING_UNICODE:
  			break;

	  	case ISAPNP_LRIN_VENDOR_DEFINED:
			  break;

		  case ISAPNP_LRIN_MEMORY_RANGE32:
  			if (Size != 17)
				  goto skip;
			  AddMemory32Resource(LogicalDevice, Size, Priority, Option);
			  Size = 0;
			  break;

		  case ISAPNP_LRIN_FL_MEMORY_RANGE32:
  			if (Size != 17)
				  goto skip;
			  AddFixedMemory32Resource(LogicalDevice, Size, Priority, Option);
			  Size = 0;
			  break;

		  default:
  			DPRINT("Ignoring large tag of type 0x%X for logical device %d on card %d\n",
          type, LogicalDevice->Number, Card->CardId);
		  }
    }
skip:
  if (Size > 0)
	  Skip(Size);
	}

	return TRUE;
}


/*
 * Parse resource map for ISA PnP card
 */
static BOOLEAN ParseResourceMap(PISAPNP_DEVICE_EXTENSION DeviceExtension,
  PISAPNP_CARD Card)
{
	UCHAR type, tmp[17];
	USHORT size;
  BOOLEAN Small;

  DPRINT("Card %d\n", Card->CardId);

	while (TRUE) {
		if (!ReadTag(&type, &size, &Small))
			return FALSE;

    if (Small) {
		  switch (type) {
		  case ISAPNP_SRIN_VERSION:
  			if (size != 2)
	  			goto skip;
		  	Peek(tmp, 2);
			  Card->PNPVersion = tmp[0];
			  Card->ProductVersion = tmp[1];
			  size = 0;
			  break;

      case ISAPNP_SRIN_LDEVICE_ID:
  			if ((size >= 5) && (size <= 6)) {
				  if (!CreateLogicalDevice(DeviceExtension, Card, size))
  					return FALSE;
				  size = 0;
			  }
			  break;

      case ISAPNP_SRIN_CDEVICE_ID:
        /* FIXME: Parse compatible IDs */
        break;

		  case ISAPNP_SRIN_END_TAG:
			  if (size > 0)
  				Skip(size);
			  return TRUE;

		  default:
  			DPRINT("Ignoring small tag Type 0x%X for Card %d\n", type, Card->CardId);
		  }

⌨️ 快捷键说明

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