Я работаю с платой PCI и испытываю трудности с доступом к устройству.
Поставляемый драйвер прекрасно работает на XP, но не работает на win7 / 10.Я создаю драйвер в режиме x64 и использую файл inf для установки драйвера .sys.И, кажется, в диспетчере устройств все в порядке.
Однако интерфейс не зарегистрирован в реестре.Нет экземпляра устройства под классом GUID.Также приложение тестирования не может найти интерфейс устройства.Мне удалось создать интерфейс устройства в приложении тестирования и получить путь к устройству.Но CreateFile, использующий путь, всегда завершится ошибкой с кодом ошибки 2 (не удается найти указанный файл).
Я провел некоторое исследование по этому вопросу.Я понимаю, что символическая ссылка на устройство отсутствует, что также можно проверить с помощью winobj.
Ниже приведена функция AddDevice в драйвере устройства:
NTSTATUS
AddDevice (
IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject
)
{
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_OBJECT deviceObject = NULL;
PDEVICE_EXTENSION deviceExtension;
DEVICE_DESCRIPTION deviceDescription;
PULONG mapRegisterCount = NULL;
UNICODE_STRING linkname;
PAGED_CODE ();
KdPrint (("s3_1000.sys: AddDevice\n"));
// Create our device object, which represents the Functional Device Object controlled by
// this device driver.
status = IoCreateDevice (
DriverObject,
sizeof (DEVICE_EXTENSION),
NULL,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&deviceObject);
// Exit AddDevice if we are unable to create the FDO.
if (!NT_SUCCESS (status))
{
KdPrint (("s3_1000.sys: IoCreateDevice exits with 0x%x\n", status));
return status;
}
// Initialize our device extension, where we keep all the required persistent
// information about this driver.
deviceExtension = (PDEVICE_EXTENSION) deviceObject->DeviceExtension;
deviceExtension->PhysicalDeviceObject = PhysicalDeviceObject;
deviceExtension->FunctionDeviceObject = deviceObject;
deviceExtension->InterruptObject = NULL;
deviceExtension->iotimeout = FALSE;
deviceExtension->timer = -1;
// Initialize the byte offset to memory within each BAR. BAR 0 is implemented as a
// set of memory-mapped registers for our DMA device. Hooks for BAR 1 are provided
// for future extension, but are unused in this driver.
deviceExtension->baseOffset[0] = 0x0;
deviceExtension->baseOffset[1] = 0x0;
// Place our driver on top of the current Device Stack for this hardware. In this
// simple case, we have only the PDO created by the bus driver, and our FDO that
// we are attaching.
deviceExtension->NextStackDeviceObject =
IoAttachDeviceToDeviceStack (deviceObject,PhysicalDeviceObject);
// Register the interface in the system registry and save the name assigned
// by the system in our device extension.
status = IoRegisterDeviceInterface (
PhysicalDeviceObject,
(LPGUID) &GuidDriver,
NULL,
&deviceExtension->InterfaceName);
// Exit if we are unsuccessful in registering our device. In this unlikely event,
// we will try to delete the device we've just added.
if (!NT_SUCCESS (status))
{
KdPrint (("s3_1000.sys: IoRegisterDeviceInterface exits with 0x%x\n", status));
IoDeleteDevice (deviceObject);
return status;
}
// Initialize our Driver state.
INITIALIZE_PNP_STATE (deviceExtension);
// Set up our driver to use Direct I/O for and to disable
// device initialization, since none is required.
// deviceObject->Flags |= DO_BUFFERED_IO; // Buffered I/O
deviceObject->Flags |= DO_DIRECT_IO; // Direct I/O (for DMA)
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
// Initialize the spin locks for the Read and Write request queues.
KeInitializeSpinLock(&deviceExtension->ReadQueueLock);
KeInitializeSpinLock(&deviceExtension->WriteQueueLock);
// Initialize the Irq Lists.
InitializeListHead(&deviceExtension->ReadQueue);
InitializeListHead(&deviceExtension->WriteQueue);
// Initialize the in-progress list (only 1 in-progress request of each type is allowed).
deviceExtension->ReadIrp = NULL;
deviceExtension->WriteIrp = NULL;
// Initialize the queue status parameters
deviceExtension->readstallcount = 1;
KeInitializeEvent(&deviceExtension->readevStop, NotificationEvent, FALSE);
deviceExtension->readabortstatus = (NTSTATUS) 0;
deviceExtension->writestallcount = 1;
KeInitializeEvent(&deviceExtension->writeevStop, NotificationEvent, FALSE);
deviceExtension->writeabortstatus = (NTSTATUS) 0;
IoInitializeRemoveLock(&deviceExtension->RemoveLock, 0, 0, 0);
// Initialize the Interrupt tracking variables.
deviceExtension->ReadDone = FALSE;
deviceExtension->WriteDone = FALSE;
// Initialize the device object so we can set a timeout for write operations
IoInitializeTimer(deviceObject, (PIO_TIMER_ROUTINE) OnTimer,
(PVOID) deviceExtension);
// Register a DpcForIsr to perform processing associated with an interrupt.
IoInitializeDpcRequest(deviceObject, DpcForIsr);
deviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
IoCreateSymbolicLink(&linkname,&deviceExtension->InterfaceName);
KdPrint (("s3_1000.sys: AddDevice complete\n"));
return status;
} // AddDevice
Я пытался открытьдругое устройство pci, которое имеет экземпляр устройства и символическую ссылку, используя путь устройства, и это работает.Но с этим не получилось.Мой вопрос: как я могу правильно зарегистрировать устройство под win7 / 10, чтобы я мог открыть устройство без ошибок?
МОЙ код открыть устройство:
hDevice = CreateFile (
path,//symlink,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL);
Работающее устройство PCI:
"\\\\?\\PCI#VEN_10EC&DEV_8168&SUBSYS_06221028&REV_0C#01000000684CE00000#{AD498944-762F-11D0-8DCB-00C04FC3358C}"
Неисправное устройство PCI:
\\\\?\\pci#ven_10ee&dev_6024&subsys_000710ee&rev_00#0000000101000a3500#{c671678c-82c1-43f3-d700-0049433e9a4b}
Реестр, как на картинке, и мы видим, что экземпляр устройства не отображается под классом GUID.Любая помощь очень ценится.