tuiui
Участник
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
|
|
« Ответ #1 : 21-04-2010 13:44 » |
|
так. 1. то что вы нагенерили только что - стирайте с винта нафиг)))) 2. затем сгенерите то же самое, но в визарде нумеги(в самом начале) выбирайте пункт "не использовать классы нумеги" (или как-то так) - получится код на чистом Си.
3. и попробуйте еще раз) после этого - велкам)
PS объяснять почему "1" и "2" - уже сто раз писал) не стану повторятся)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #2 : 22-04-2010 05:15 » |
|
))) Я знал, что Ochkarik посоветует мне именно это. Ну что ж. Попробуем. Отпишусь попозже
|
|
|
Записан
|
|
|
|
tuiui
Участник
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
Участник
Offline
|
|
« Ответ #4 : 22-04-2010 07:53 » |
|
И еще одна странная вещь. Когда из приложения
Открываю драйвер => получаю handle => WriteFile(handle, ... ) => Закрываю приложение
Комп перезагружается молча
Если перед закрытием приложения освободить хэндл - все ок. И это при том, что функции записи в драйвере еще нет.
Буду очень признателен за пример кода метода записи в память устройства
|
|
|
Записан
|
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #5 : 22-04-2010 08:09 » |
|
MultiplierWriteDispatch - что-то какой-то левый код получился. Может стоит без студии взять и руками написать?
|
|
|
Записан
|
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #6 : 22-04-2010 08:37 » |
|
дело в том, что опыта нет. Если я правильно понимаю, студия генерит каркас, где все "обслуживающие" функции создаются в правильном хорошем виде, и мне лезть туда не надо. А надо только в методы, отвечающий за запись и чтение, вписать несколько строк своего кода (собственно, запись и чтение). Поправьте меня, если я не прав. Код, сгенерированный с использованием С++ я обрабатывал именно так и все работало. Правда BSOD вылетал. По совету Ochkarik'a сделал все на чистом С. Теперь не знаю, куда и какой код писать.
|
|
|
Записан
|
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #7 : 22-04-2010 08:54 » |
|
Ну раз уж вы решили действовать через студию, то я вряд ли смогу сказать что и как. Это Ochkarik'а надо ждать. Но студия, вообще говоря, не компенсирует недостаток опыта. Лучше учиться, разбираться, чтобы понимать что делаешь.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #8 : 22-04-2010 10:14 » |
|
resource, студия - это не страшно) студия в режиме чистого Си - просто рыбу генерит. там нет ничего кроме функций DDK. это в режиме классов она свои обертки использует.(почему я против них и выступал)))
tuiui, угу. все почти так) 1. когда вы генерили рыбу - там был пункт, который позволял задать требуемые ресурсы для устройства. (в том числе память, прерывания, и т.д.) вы это сделали? 2. писать по адресу - что имеется в виду? там стоит отображаемая память или DMA ресурс? если первое то см. пункт 1. в настройках визарда надо вставить Dispatch процедуры(это фактически пользовательский интерфейс драйвера) и связать их с зарезервированным ранее ресурсом отображаемой памяти.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #9 : 22-04-2010 10:23 » |
|
Спасибо. Давайте по порядку.
При создании проекта в DS я задал ресурс DataMemory типа Memory (не DMA).
Сгенерировал код на чистом Си.
Теперь, видимо надо сделать с этим кодом что-то такое, чтобы при обращении из приложения командой WriteFile(DriberHandle, Buffer, Count, Overlapped) - (примерно) В эту самую память DataMemory писался буфер Buffer, в количестве Count начиная со смещения, заданного в Overlapped.
Мне почему-то кажется, что это вещь очень стандартная.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #10 : 22-04-2010 10:29 » |
|
скомпилите еще раз. но помимо ресурсов - задайте создание тестового приложения. задайте создание Dispatch процедур (IO control или Read/Write) там же в настройках визарда можно связать заданную функцию интерфейса драйвера ( Dispatch процедур (IO control или Read/Write) и соответствующий ресурс.
поиграйтесь настройками несколько раз - то что вам надо, делается там исключительно визардом, даже дописывать кода не надо)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
Ochkarik
|
|
« Ответ #11 : 22-04-2010 10:31 » |
|
жаль у меня DS не стоит... и студия несовместимая. даже скриншотов не могу сделать)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
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
|
|
« Ответ #13 : 22-04-2010 13:46 » |
|
нет, по моему что то вы недоделали... можно вас попросить скриншоты визарда по шагам выложить?
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #14 : 23-04-2010 05:24 » |
|
Вот скрины Визарда
|
|
|
Записан
|
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #15 : 23-04-2010 05:25 » |
|
продолжение
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
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
|
|
« Ответ #18 : 23-04-2010 11:56 » |
|
файл тот. там должны быть обработчики и READ/WRITE и IOCTL в конце.
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
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
|
|
« Ответ #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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #21 : 23-04-2010 12:15 » |
|
Файла этого нет ( И такого типа ресурсов нет А размер и базовый адрес имеющейся памяти инициализируется вроде нормально. В структуре DeviceExtension он присутствует. Я пробовал делать заглушку. Из приложения выполнял WriteFile, а в драйвере сделал, чтобы он возвращал размер памяти. Все ок. То есть в драйвере, кажется, все имеется для записи. И указатель на буфер и базовый адрес памяти, и размер записываемого буфера. Не хватает только собственно записи - передачи запроса ниже к аппаратуре Может у нас разные версии Driver Studio? Может, в новой версии что-то поменялось.
|
|
« Последнее редактирование: 23-04-2010 12:20 от tuiui »
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #22 : 23-04-2010 12:41 » |
|
нет, сейчаспроинсталировал, действительно... не дописывает... абыдно) ну тогда остается только: memcpy() вписать)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
resource
Молодой специалист
Offline
Пол:
|
|
« Ответ #23 : 23-04-2010 12:43 » |
|
студию фтопку
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #24 : 23-04-2010 12:47 » |
|
resource, ша в топку то?) я пол года гемороился пока в ручную это делал)
|
|
|
Записан
|
RTFM уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #25 : 23-04-2010 17:12 » |
|
)) Ochkarik, я рад, что мы пришли к общему результату. Но можно ли поподробнее насчет того, что именно вписать и куда ))
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #27 : 26-04-2010 04:59 » |
|
CmResourceTypeMemory - я считал, что вы имеете в виду тип ресурса в визарде студии )) Типа Memory, Port, DMA и еще CmResourceTypeMemory )) Видимо, я неправильно понял. Будем вставлять memcpy().
|
|
|
Записан
|
|
|
|
tuiui
Участник
Offline
|
|
« Ответ #28 : 26-04-2010 09:20 » |
|
Блин... Не могу никак присобачить туда этот memcpy(). Помогите кто-нибудь )) У memcpy() в качестве параметров: - адрес источника. Это понятно. Его мне выдала студия. writeBuffer = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); - количество данных. Тоже понятно. writeLength = irpStack->Parameters.Write.Length; - адрес назначения... Как его получить?! Как узнать адрес, в который отображена моя память? Вот бы мне пример кода ) Буду счастлив беспредельно.
|
|
|
Записан
|
|
|
|
Ochkarik
|
|
« Ответ #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 уже хоть раз наконец! :[ ну или хотя бы STFW...
|
|
|
|