Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1] 2  Все   Вниз
  Печать  
Автор Тема: Синий экран при обращении к драйверу PCI устройства  (Прочитано 37851 раз)
0 Пользователей и 1 Гость смотрят эту тему.
tuiui
Участник

ru
Offline Offline

« : 21-04-2010 08:00 » 

Здравствуйте, товарищи!

Использовал    Driver Studio 3.2 + VC6 + DDK 2600     для написания драйвера платы PCI. Необходимо было, чтобы драйвер писал в память PCI-платы заданное количество данных по заданному адресу.

Driver Studio создал рыбу драйвера, в код функции записи я написал:
Код:
NTSTATUS MultiplierDevice::Write(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

//получаем буфер пользователя. Он передается через Irp.
KMemory Mem(I.Mdl());
PUCHAR pBuffer = (PUCHAR) Mem.MapToSystemSpace();

            //получаем число 4-байтных слов, которое должно быть записано.
ULONG dwTotalSize = I.WriteSize(CURRENT);
ULONG dwBytesWrite = dwTotalSize;

//получаем смещение слова в памяти
ULONG dwWordOffset = IoGetCurrentIrpStackLocation(I)->Parameters.Write.ByteOffset.LowPart;

//пишем заданное число двойных слов    
DataMemory.outd(dwWordOffset,(ULONG*)pBuffer,dwTotalSize);

//возвращаем количество прочитанных слов
I.Information() = DataMemory.Count();
I.Status() = status;

//Обработать следующий IRP-пакет.
            PnpNextIrp(I);

return status;
}

Понимаю, что код очень не красивый. Прошу не ругаться  Краснею

При обращении к драйверу командой WriteFile из приложения вылетает синий экран. Причем только тогда, когда количество записываемых данных больше какого-то определенного значения.

Пробовал вместо драйвера писать данные в txt-файл.  Все Ок. Поэтому пришел к выводу, что ошибка в коде драйвере.

Быть может, надо проверять какое-то условие перед записью.
(такое впечатление, что при записи драйвер выходит за какой-то диапазон адресов)

Драйверы раньше никогда не писал. Код написан по примерам из статей.

Заранее благодарен за помощь
« Последнее редактирование: 21-04-2010 08:13 от Алексей1153++ » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 21-04-2010 13:44 » 

так.
1. то что вы нагенерили только что - стирайте с винта нафиг))))
 
2. затем сгенерите то же самое, но в визарде нумеги(в самом начале) выбирайте пункт "не использовать классы нумеги" (или как-то так) - получится код на чистом Си.

3. и попробуйте еще раз) после этого - велкам)

PS объяснять почему "1" и "2" - уже сто раз писал) не стану повторятся)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #2 : 22-04-2010 05:15 » 

))) Я знал, что Ochkarik посоветует мне именно это. Ну что ж. Попробуем. Отпишусь попозже
Записан
tuiui
Участник

ru
Offline Offline

« Ответ #3 : 22-04-2010 06:21 » 

Сделал все, как вы сказали: сгенерировал новый код на чистом С. Если я правильно понял, свой код для записи в устройство надо добавлять в метод MultiplierReadDispatch (multiplier - название устройства) ?

Код:
NTSTATUS MultiplierWriteDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    PMULTIPLIER_DEVICE_EXTENSION    deviceExtension;
    NTSTATUS                        status;
    PIO_STACK_LOCATION              irpStack;
    PVOID                           writeBuffer;
    ULONG                           writeLength;

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    deviceExtension = (PMULTIPLIER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    status = MultiplierCheckIoLock(&deviceExtension->IoLock, Irp);
    if (!NT_SUCCESS(status) || (status == STATUS_PENDING))
    {
        MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;
    }

    // Get our IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Get the write buffer length
    writeLength = irpStack->Parameters.Write.Length;
    if (writeLength == 0)
    {
        // just complete 0 length request
        status = STATUS_SUCCESS;

        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        MultiplierDecrementIoCount(&deviceExtension->IoLock);

        MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);

        return status;
    }

    writeBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

    return status;

}

Пока что свой код не добавлял. Кстати, компилировать эту "рыбу" надо с помощью DDK Built.exe utulity? Просто получается и просто по F7. Сделал и так, и так. В обоих случаях приложение НЕ находит драйвер по символической ссылке "Multiplier0", но находит "Multiplier".

И скажите, код из моего первого примера подойдет для этого случая? Просто примеров для чистого С не нашел


Записан
tuiui
Участник

ru
Offline Offline

« Ответ #4 : 22-04-2010 07:53 » 

И еще одна странная вещь. Когда из приложения

Открываю драйвер => получаю handle => WriteFile(handle, ... ) => Закрываю приложение

Комп перезагружается молча

Если перед закрытием приложения освободить хэндл - все ок. И это при том, что функции записи в драйвере еще нет.

Буду очень признателен за пример кода метода записи в память устройства
Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 22-04-2010 08:09 » 

MultiplierWriteDispatch - что-то какой-то левый код получился. Может стоит без студии взять и руками написать?
Записан
tuiui
Участник

ru
Offline Offline

« Ответ #6 : 22-04-2010 08:37 » 

дело в том, что опыта нет. Если я правильно понимаю, студия генерит каркас, где все "обслуживающие" функции создаются в правильном хорошем виде, и мне лезть туда не надо.  А надо только в методы, отвечающий за запись и чтение, вписать несколько строк своего кода (собственно, запись и чтение). Поправьте меня, если я не прав. Код, сгенерированный с использованием С++ я обрабатывал именно так и все работало. Правда BSOD вылетал. По совету Ochkarik'a сделал все на чистом С. Теперь не знаю, куда и какой код писать.
Записан
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 22-04-2010 08:54 » 

Ну раз уж вы решили действовать через студию, то я вряд ли смогу сказать что и как. Это Ochkarik'а надо ждать. Но студия, вообще говоря, не компенсирует недостаток опыта. Лучше учиться, разбираться, чтобы понимать что делаешь.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #8 : 22-04-2010 10:14 » 

resource, студия - это не страшно) студия в режиме чистого Си - просто рыбу генерит. там нет ничего кроме функций DDK.
это в режиме классов она свои обертки использует.(почему я против них и выступал)))

tuiui, угу. все почти так)
1. когда вы генерили рыбу - там был пункт, который позволял задать требуемые ресурсы для устройства. (в том числе память, прерывания, и т.д.) вы это сделали?
2. писать по адресу - что имеется в виду? там стоит отображаемая память или DMA ресурс? если первое то см. пункт 1. в настройках визарда надо вставить Dispatch процедуры(это фактически пользовательский интерфейс драйвера) и связать их с зарезервированным ранее ресурсом отображаемой памяти.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #9 : 22-04-2010 10:23 » 

Спасибо.
Давайте по порядку.

При создании проекта в DS я задал ресурс DataMemory типа Memory (не DMA).

Сгенерировал код на чистом Си.

Теперь, видимо надо сделать с этим кодом что-то такое, чтобы при обращении из приложения командой
WriteFile(DriberHandle, Buffer, Count, Overlapped) -  (примерно)
В эту самую память DataMemory писался буфер Buffer, в количестве Count начиная со смещения, заданного в Overlapped.

Мне почему-то кажется, что это вещь очень стандартная.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 22-04-2010 10:29 » 

скомпилите еще раз. но помимо ресурсов - задайте создание тестового приложения.
задайте создание Dispatch процедур (IO control или Read/Write)
там же в настройках визарда можно связать заданную функцию интерфейса драйвера ( Dispatch процедур (IO control или Read/Write) и соответствующий ресурс.

поиграйтесь настройками несколько раз - то что вам надо, делается там исключительно визардом, даже дописывать кода не надо)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 22-04-2010 10:31 » 

жаль у меня DS не стоит... и студия несовместимая. даже скриншотов не могу сделать)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #12 : 22-04-2010 10:35 » 

)) Жаль. Так вот я увязал IRP_MJ_READ и IRP_MJ_WRITE с этой самой памятью DataMemory, которую задал в ресурсах. Я правильно понимаю, что обработчики этих IRP называются
MultiplierReadDispatch и MultiplierWriteDispatch? Если да, то вот код, который я получил (каким мне выдала его студия)

Код:
NTSTATUS MultiplierWriteDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    PMULTIPLIER_DEVICE_EXTENSION    deviceExtension;
    NTSTATUS                        status;
    PIO_STACK_LOCATION              irpStack;
    PVOID                           writeBuffer;
    ULONG                           writeLength;

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    deviceExtension = (PMULTIPLIER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    status = MultiplierCheckIoLock(&deviceExtension->IoLock, Irp);
    if (!NT_SUCCESS(status) || (status == STATUS_PENDING))
    {
        MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;
    }

    // Get our IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Get the write buffer length
    writeLength = irpStack->Parameters.Write.Length;
    if (writeLength == 0)
    {
        // just complete 0 length request
        status = STATUS_SUCCESS;

        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        MultiplierDecrementIoCount(&deviceExtension->IoLock);

        MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);

        return status;
    }

    writeBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
    
return status;
}

Для чтения - аналогично.

Просто я тут не вижу самого "акта" записи. Какие-то проверки, какие-то обработки ошибок. А где же запись?  Здесь была моя ладья...

Может DS "забыла" вставить строчки с командами записи?
« Последнее редактирование: 22-04-2010 11:50 от tuiui » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 22-04-2010 13:46 » 

нет, по моему что то вы недоделали...
можно вас попросить скриншоты визарда по шагам  выложить?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #14 : 23-04-2010 05:24 » 

Вот скрины Визарда

* Шаг 1 - Шаг 5.rar (226.77 Кб - загружено 939 раз.)
Записан
tuiui
Участник

ru
Offline Offline

« Ответ #15 : 23-04-2010 05:25 » 

продолжение

* Шаг 6 - Шаг 13.rar (386.8 Кб - загружено 970 раз.)
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #16 : 23-04-2010 09:54 » 

блин. третий раз ответ пишу третий раз случайно окно закрываю)))

экран 4 - попробуйте вместо ручного задания ID, сразу выбрать установленную карту PCI. вроде бы студия сама ресурсы умела находить.

экран 5 - какие ресурсы еще выбрать можно? i/o порты, прерывания, DMA, отображаемая память?

экран 7 - для READ/WRITE вместо direct выбрать ,буферизированный ввод. формирование очереди - отключить.
добавить два IOCTL один на чтение второй на запись того же региона. тоже с буферизацией и без очереди (будет проще разбираться).

PS видимо, из за включения очереди MultiplierWriteDispatch не завершается IoCompleteRequest-ом... я собственно для PCI не пробовал генерить (или уже не помню, давно было), но делал это для USB и 1394. в обоих случаях мне в IOCTL давали доступ с тестового приложения на запись/чтение  указанных ресурсов железа...
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #17 : 23-04-2010 10:47 » 

Экран 5 - можно выбрать только Память, Порты и DMA

Экран 7 - выбирается только Direct. В остальных случаях ругается и сама устанавливает Direct. Создал еще 2 IOCTL. Тоже не разрешает беферизацию выбирать. Пишет, что для этого типа ресурса только direct in и direct out

сгенерировал...

вид тот же. Может, я не тот файл смотрю - "iorw.c" ведь надо смотреть?

Вы рекомендуете использовать только IOCTL? Без MJ_READ/MJ_WRITE?
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #18 : 23-04-2010 11:56 » 

файл тот. там должны быть обработчики и READ/WRITE и IOCTL в конце.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #19 : 23-04-2010 12:08 » 

Да. Вот они

Код:
///////////////////////////////////////////////////////////////////////////////////////////////////
//  MultiplierWriteDispatch
//      Handled incoming write requests
//
//  Arguments:
//      IN  DeviceObject
//              Device object for our device
//
//      IN  Irp
//              The write IRP to handle
//
//  Return Value:
//      NT status code
//
NTSTATUS MultiplierWriteDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    PMULTIPLIER_DEVICE_EXTENSION    deviceExtension;
    NTSTATUS                        status;
    PIO_STACK_LOCATION              irpStack;
    PVOID                           writeBuffer;
    ULONG                           writeLength;

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    deviceExtension = (PMULTIPLIER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    status = MultiplierCheckIoLock(&deviceExtension->IoLock, Irp);
    if (!NT_SUCCESS(status) || (status == STATUS_PENDING))
    {
        MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

        return status;
    }

    // Get our IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Get the write buffer length
    writeLength = irpStack->Parameters.Write.Length;
    if (writeLength == 0)
    {
        // just complete 0 length request
        status = STATUS_SUCCESS;

        Irp->IoStatus.Information = 0;
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);

        MultiplierDecrementIoCount(&deviceExtension->IoLock);

        MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status);

        return status;
    }

    writeBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

    return status;
}

 MultiplierReadDispatch - аналогичный

А это MultiplierDeviceIoControlDispatch
Код:
///////////////////////////////////////////////////////////////////////////////////////////////////
//  MultiplierDeviceIoControlDispatch
//      Handled incoming IOCTL requests
//
//  Arguments:
//      IN  DeviceObject
//              Device object for our device
//
//      IN  Irp
//              The IOCTL IRP to handle
//
//  Return Value:
//      NT status code
//
NTSTATUS MultiplierDeviceIoControlDispatch(
    IN  PDEVICE_OBJECT  DeviceObject,
    IN  PIRP            Irp
    )
{
    PIO_STACK_LOCATION              irpStack;
    NTSTATUS                        status;
    PMULTIPLIER_DEVICE_EXTENSION    deviceExtension;
    PVOID                           inputBuffer;
    ULONG                           inputLength;
    PVOID                           outputBuffer;
    ULONG                           outputLength;

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);

    deviceExtension = (PMULTIPLIER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;

    // Get our IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);

    // Get the buffer lengths
    inputLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
    outputLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;

    switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
    {

    case IOCTL_800:
        MultiplierDebugPrint(DBG_IO, DBG_INFO, __FUNCTION__": IOCTL_800");

        status = MultiplierCheckIoLock(&deviceExtension->IoLock, Irp);
        if (!NT_SUCCESS(status) || (status == STATUS_PENDING))
        {
            MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

            return status;
        }

        // direct ioctl
        inputBuffer = Irp->AssociatedIrp.SystemBuffer;
        if (Irp->MdlAddress != NULL)
        {
            outputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
        }
        else
        {
            outputBuffer = NULL;
        }
        break;

    case IOCTL_801:
        MultiplierDebugPrint(DBG_IO, DBG_INFO, __FUNCTION__": IOCTL_801");

        status = MultiplierCheckIoLock(&deviceExtension->IoLock, Irp);
        if (!NT_SUCCESS(status) || (status == STATUS_PENDING))
        {
            MultiplierDebugPrint(DBG_IO, DBG_WARN, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

            return status;
        }

        // direct ioctl
        inputBuffer = Irp->AssociatedIrp.SystemBuffer;
        if (Irp->MdlAddress != NULL)
        {
            outputBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
        }
        else
        {
            outputBuffer = NULL;
        }
        break;

    default:
        status = STATUS_INVALID_DEVICE_REQUEST;
        Irp->IoStatus.Status = status;
        IoCompleteRequest (Irp, IO_NO_INCREMENT);
        break;
    }

    MultiplierDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);

    return status;
}

Может, вручную дописать туда что надо. Знать бы еще, что надо... Или переустановить DS. Или версию взять другую...
« Последнее редактирование: 23-04-2010 12:10 от tuiui » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #20 : 23-04-2010 12:10 » 

нашел тут у себя фрагменты DS....
судя по ним...
у вас должен быть код:
файл WDMDriver.c
процедура $$ProjectName$$StartDevice()
в ней
    // Get our current IRP stack location
    irpStack = IoGetCurrentIrpStackLocation(Irp);
$$INCLUDE PowerPnp\startres.inc

из "startres.inc" копируется код инициализации ресурсов PCI.
Код:
$$COMMENT Resource allocation code

    // Do whatever initialization needed when starting the device:
    // gather information about it,  update the registry, etc.
    // At this point, the lower level drivers completed the IRP
    if ((irpStack->Parameters.StartDevice.AllocatedResources != NULL) &&
        (irpStack->Parameters.StartDevice.AllocatedResourcesTranslated != NULL))
    {
        // Parameters.StartDevice.AllocatedResources points to a
        // CM_RESOURCE_LIST describing the hardware resources that
        // the PnP Manager assigned to the device. This list contains
        // the resources in raw form. Use the raw resources to program
        // the device.

        partialResourceList =
            &irpStack->Parameters.StartDevice.AllocatedResources->List[0].PartialResourceList;

        resource = &partialResourceList->PartialDescriptors[0];

        // Parameters.StartDevice.AllocatedResourcesTranslated points
        // to a CM_RESOURCE_LIST describing the hardware resources that
        // the PnP Manager assigned to the device. This list contains
        // the resources in translated form. Use the translated resources
        // to connect the interrupt vector, map I/O space, and map memory.

        partialResourceListTranslated =
            &irpStack->Parameters.StartDevice.AllocatedResourcesTranslated->List[0].PartialResourceList;

        resourceTrans = &partialResourceListTranslated->PartialDescriptors[0];
$$IFDEF PORT_COUNT

        // reset the total port count
        portCount = 0;
$$ENDIF
$$IFDEF MEMORY_COUNT

        // reset the total memory range count
        memCount = 0;
$$ENDIF

        // search the resources
        for (ii = 0;
             ii < partialResourceList->Count;
             ++ii, ++resource, ++resourceTrans)
        {

            switch (resource->Type)
            {
            case CmResourceTypePort:
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_INFO,  "Resource Type Port");
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_INFO, "Port.Start %I64x", resource->u.Port.Start.QuadPart);
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_INFO, "Port.Length %x", resource->u.Port.Length);
$$IFDEF PORT_COUNT

                switch (portCount)
                {
$$DEFINE INDEX = 0
$$WHILE ($$INDEX$$ < $$PORT_COUNT$$)
$$DEFINE PORT_NAME = @(PORT$$INDEX$$)
                case $$INDEX$$:
                    if (resourceTrans->Type == CmResourceTypePort)
                    {
                        DeviceExtension->b$$PORT_NAME$$IsIo = TRUE;

                        DeviceExtension->$$PORT_NAME$$Length = resourceTrans->u.Port.Length;
                        DeviceExtension->b$$PORT_NAME$$Mapped = (resourceTrans->Flags & CM_RESOURCE_PORT_IO) == 0;
                        if (DeviceExtension->b$$PORT_NAME$$Mapped)
                        {
                            DeviceExtension->$$PORT_NAME$$Base = (PUCHAR)MmMapIoSpace(
                                                                    resourceTrans->u.Port.Start,
                                                                    resourceTrans->u.Port.Length,
                                                                    MmNonCached
                                                                    );
                        }
                        else
                        {
                            DeviceExtension->$$PORT_NAME$$Base = (PUCHAR)resourceTrans->u.Port.Start.QuadPart;
                        }
                    }
                    else
                    {
                        ASSERT(resourceTrans->Type == CmResourceTypeMemory);

                        DeviceExtension->b$$PORT_NAME$$IsIo = FALSE;
                        DeviceExtension->b$$PORT_NAME$$Mapped = TRUE;

                        DeviceExtension->$$PORT_NAME$$Length = resourceTrans->u.Memory.Length;
                        DeviceExtension->$$PORT_NAME$$Base = (PUCHAR)MmMapIoSpace(
                                                            resourceTrans->u.Memory.Start,
                                                            resourceTrans->u.Memory.Length,
                                                            MmNonCached
                                                            );
                    }
                    break;
$$UNDEF PORT_NAME
$$ASSIGN INDEX = $$INDEX$$ + 1
$$ENDWHILE
$$UNDEF INDEX
                default:
                    $$ProjectName$$DebugPrint(DBG_PNP, DBG_INFO,  "Extra Port");
                    break;
                }

                ++portCount;
$$ENDIF // PORT_COUNT
                break;
            case CmResourceTypeMemory:
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Memory");
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Memory.Start %I64x", resource->u.Memory.Start.QuadPart);
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Memory.Length %x", resource->u.Memory.Length);
$$IFDEF MEMORY_COUNT

                switch (memCount)
                {
$$DEFINE INDEX = 0
$$WHILE ($$INDEX$$ < $$MEMORY_COUNT$$)
$$DEFINE MEMORY_NAME = @(MEMORY$$INDEX$$)
                case $$INDEX$$:
                    if (resourceTrans->Type == CmResourceTypeMemory)
                    {
                        DeviceExtension->b$$MEMORY_NAME$$IsIo = FALSE;
                        DeviceExtension->b$$MEMORY_NAME$$Mapped = TRUE;

                        DeviceExtension->$$MEMORY_NAME$$Length = resourceTrans->u.Memory.Length;
                        DeviceExtension->$$MEMORY_NAME$$Base = (PUCHAR)MmMapIoSpace(
                                                            resourceTrans->u.Memory.Start,
                                                            resourceTrans->u.Memory.Length,
                                                            MmNonCached
                                                            );
                    }
                    else
                    {
                        ASSERT(resourceTrans->Type == CmResourceTypePort);

                        DeviceExtension->b$$MEMORY_NAME$$IsIo = TRUE;

                        DeviceExtension->$$MEMORY_NAME$$Length = resourceTrans->u.Port.Length;
                        DeviceExtension->b$$MEMORY_NAME$$Mapped = (resourceTrans->Flags & CM_RESOURCE_PORT_IO) == 0;
                        if (DeviceExtension->b$$MEMORY_NAME$$Mapped)
                        {
                            DeviceExtension->$$MEMORY_NAME$$Base = (PUCHAR)MmMapIoSpace(
                                                                    resourceTrans->u.Port.Start,
                                                                    resourceTrans->u.Port.Length,
                                                                    MmNonCached
                                                                    );
                        }
                        else
                        {
                            DeviceExtension->$$MEMORY_NAME$$Base = (PUCHAR)resourceTrans->u.Port.Start.QuadPart;
                        }
                    }
                    break;
$$UNDEF MEMORY_NAME
$$ASSIGN INDEX = $$INDEX$$ + 1
$$ENDWHILE
$$UNDEF INDEX
                default:
                    $$ProjectName$$DebugPrint(DBG_PNP, DBG_INFO,  "Extra Memory Range");
                    break;
                }

                ++memCount;
$$ENDIF // MEMORY_COUNT
                break;
            case CmResourceTypeInterrupt:
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Resource Type Interrupt");
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Level %x", resourceTrans->u.Interrupt.Level);
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Vector %x", resourceTrans->u.Interrupt.Vector);
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Interrupt.Affinity %x\n", resourceTrans->u.Interrupt.Affinity);
$$IFDEF INTERRUPT

                DeviceExtension->$$ProjectName$$InterruptVector = resourceTrans->u.Interrupt.Vector;
                DeviceExtension->$$ProjectName$$InterruptLevel = (KIRQL)resourceTrans->u.Interrupt.Level;
                DeviceExtension->$$ProjectName$$InterruptAffinity = resourceTrans->u.Interrupt.Affinity;
                DeviceExtension->b$$ProjectName$$InterruptShared = resourceTrans->ShareDisposition == CmResourceShareShared;
                DeviceExtension->$$ProjectName$$InterruptMode =
                    (resourceTrans->Flags == CM_RESOURCE_INTERRUPT_LATCHED) ? Latched : LevelSensitive;
$$ENDIF // INTERRUPT
                break;
            default:
                $$ProjectName$$DebugPrint(DBG_PNP, DBG_TRACE, "Unknown Resource Type %x", resourceTrans->Type);
                break;
            }
        }
    }

    //*****************************************************************
    //*****************************************************************
    // TODO: check that all required resources have been allocated
    //*****************************************************************
    //*****************************************************************
$$IFDEF PORT_COUNT

    if (portCount < $$PORT_COUNT$$)
    {
        return STATUS_DEVICE_CONFIGURATION_ERROR;
    }
$$DEFINE INDEX = 0
$$WHILE ($$INDEX$$ < $$PORT_COUNT$$)
$$DEFINE PORT_NAME = @(PORT$$INDEX$$)
   
    if (DeviceExtension->$$PORT_NAME$$Base == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
$$UNDEF PORT_NAME
$$ASSIGN INDEX = $$INDEX$$ + 1
$$ENDWHILE
$$UNDEF INDEX
$$ENDIF // PORT_COUNT
$$IFDEF MEMORY_COUNT

    if (memCount < $$MEMORY_COUNT$$)
    {
        return STATUS_DEVICE_CONFIGURATION_ERROR;
    }
$$DEFINE INDEX = 0
$$WHILE ($$INDEX$$ < $$MEMORY_COUNT$$)
$$DEFINE MEMORY_NAME = @(MEMORY$$INDEX$$)
   
    if (DeviceExtension->$$MEMORY_NAME$$Base == NULL)
    {
        return STATUS_INSUFFICIENT_RESOURCES;
    }
$$UNDEF MEMORY_NAME
$$ASSIGN INDEX = $$INDEX$$ + 1
$$ENDWHILE
$$UNDEF INDEX
$$ENDIF // MEMORY_COUNT
$$IFDEF INTERRUPT

    if (DeviceExtension->$$ProjectName$$InterruptVector == 0)
    {
        return STATUS_DEVICE_CONFIGURATION_ERROR;
    }
$$ENDIF // INTERRUPT

вам нужен ресурс CmResourceTypeMemory. после инициализации адреса и длинна
DeviceExtension->$$MEMORY_NAME$$Base
DeviceExtension->$$MEMORY_NAME$$Length
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #21 : 23-04-2010 12:15 » 

Файла этого нет (
И такого типа ресурсов нет
А размер и базовый адрес имеющейся памяти инициализируется вроде нормально.
В структуре DeviceExtension он присутствует. Я пробовал делать заглушку. Из приложения выполнял WriteFile, а в драйвере сделал, чтобы он возвращал размер памяти. Все ок.

То есть в драйвере, кажется, все имеется для записи. И указатель на буфер и базовый адрес памяти, и размер записываемого буфера. Не хватает только собственно записи - передачи запроса ниже к аппаратуре  Здесь была моя ладья...

Может у нас разные версии Driver Studio? Может, в новой версии что-то поменялось.
« Последнее редактирование: 23-04-2010 12:20 от tuiui » Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #22 : 23-04-2010 12:41 » 

нет, сейчаспроинсталировал, действительно... не дописывает... абыдно)
ну тогда остается только:
memcpy() вписать)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
resource
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 23-04-2010 12:43 » 

студию фтопку   Улыбаюсь
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #24 : 23-04-2010 12:47 » 

resource, ша в топку то?) я пол года гемороился пока в ручную это делал)
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #25 : 23-04-2010 17:12 » 

)) Ochkarik, я рад, что мы пришли к общему результату. Но можно ли поподробнее насчет того, что именно вписать и куда ))
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #26 : 23-04-2010 18:07 » 

по общей идее, если у вас ресурс отображаемой памяти. то вам надо просто скопировать память. а вот откуда и куда - надо вспоминать...
флаги METHOD_IN_DIRECT, METHOD_OUT_DIRECT не помню какой в какую сторону.
http://msdn.microsoft.com/en-us/library/ff558709(VS.85).aspx
или в read/write выставить соответствующие....
вам надо сделать memcpy() из буфера получаемого от приложения в отображаемую память (DeviceExtension->$$MEMORY_NAME$$Base и DeviceExtension->$$MEMORY_NAME$$Length)
например в MultiplierWriteDispatch - вроде где пользовательский буфер - понятно?)


ЗЫ насчет того что CmResourceTypeMemory- "И такого типа ресурсов нет", это очень подозрительно. а какой естЬ?)
вам точно отображаемая память нужна?) драйвер вообще подошел к железке? вы его проинсталировали?
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
tuiui
Участник

ru
Offline Offline

« Ответ #27 : 26-04-2010 04:59 » 

CmResourceTypeMemory - я считал, что вы имеете в виду тип ресурса в визарде студии )) Типа Memory, Port, DMA и еще CmResourceTypeMemory )) Видимо, я неправильно понял. Будем вставлять memcpy(). 
Записан
tuiui
Участник

ru
Offline Offline

« Ответ #28 : 26-04-2010 09:20 » 

Блин... Не могу никак присобачить туда этот memcpy(). Помогите кто-нибудь ))
 
У memcpy() в качестве параметров:

- адрес источника. Это понятно. Его мне выдала студия.
Код:
writeBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

- количество данных. Тоже понятно.
Код:
writeLength = irpStack->Parameters.Write.Length;

- адрес назначения... Как его получить?! Как узнать адрес, в который отображена моя память?

Вот бы мне пример кода ) Буду счастлив беспредельно.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #29 : 26-04-2010 14:39 » 

адрес-длинна:
deviceExtension->_____Base
deviceExtension->_____Length
у вас где то в коде примерно так должно быть.
ищите процедуру StartDevice() (она вызывается по IRP_MJ_PNP+IRP_MN_START_DEVICE)
в ней должен быть код похожий на https://forum.shelek.ru/index.php/topic,24191.msg233624.html#msg233624
этот код как раз и инициализирует отображаемую память.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1] 2  Все   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines