hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:1759回复:11

帮忙看一下内存操作的问题

楼主#
更多 发布于:2003-09-30 10:30
我按照以下的办法实现应用程序与驱动之间的共享内存:
首先如下分配内存:
SystemVirtualAddress = MmAllocateContiguousMemory(NumberOfBytes,
HighestAcceptableAddress); 或
SystemVirtualAddress = ExAllocatePool(PoolType, NumberOfBytes);
如下分配一个 MDL:
Mdl = IoAllocateMdl(SystemVirtualAddress, NumberOfBytes, FALSE,
FALSE, NULL);
建立 MDL 以描述内存页。
MmBuildMdlForNonPagedPool(Mdl);
如下将锁定的页面映射至进程的用户地址空间中:
UserVirtualAddress = MmMapLockedPages(Mdl, UserMode);
然后用IOCTL将UserVirtualAddress传递给应用程序如下pSystemBuffer = Irp->AssociatedIrp.SystemBuffer;
*(PVOID*)pSystemBuffer=deviceExt->VirtualAddress;
在应用程序中接收该虚拟地址如下:
PCHAR Buffer;
DeviceIoControl(app->hDevice, (DWORD)hEventPass,
NULL, 0, (PCHAR)&Buffer,sizeof(PVOID),
&count, NULL)
之后我在驱动中对pSystemVirtualAddress的读写都没有问题,可是在应用程序中对接收了虚拟地址的Buffer读写都出错,请问错在哪里?

最新喜欢:

ljmmaryljmmar...
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-09-30 11:10
*(PVOID*)pSystemBuffer=deviceExt->VirtualAddress;
修改为:
*(ULONG*)pSystemBuffer=(ULONG)(UserVirtualAddress);
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-09-30 11:45
在应用程序的IOCTL里该怎么做,我弄来弄去来是死机阿
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2003-09-30 11:58

#include \"ntddk.h\"
#include \"..\\common\\ShareMemory.h\"

static NTSTATUS MydrvDispatch (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
static NTSTATUS MydrvDispatchIoctl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
VOID DriverUnload (IN PDRIVER_OBJECT pDriverObject);

PVOID SystemVirtualAddress, UserVirtualAddress;
PMDL Mdl;

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING nameString, linkString;
PDEVICE_OBJECT deviceObject;
NTSTATUS status;
WCHAR wBuffer[200];

nameString.Buffer = wBuffer;
nameString.MaximumLength = 200;

DriverObject->DriverUnload = DriverUnload;

RtlInitUnicodeString(&nameString, L\"\\\\Device\\\\My_ShareMemory\" );

status = IoCreateDevice(DriverObject,
0,
&nameString,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&deviceObject
);


if (!NT_SUCCESS(status))
return status;

deviceObject->Flags |= DO_BUFFERED_IO;

RtlInitUnicodeString(&linkString, L\"\\\\??\\\\My_ShareMemory\");

status = IoCreateSymbolicLink (&linkString, &nameString);

if (!NT_SUCCESS(status))
{
IoDeleteDevice (DriverObject->DeviceObject);
return status;
}

DriverObject->MajorFunction[IRP_MJ_CREATE] = MydrvDispatch;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = MydrvDispatch;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MydrvDispatchIoctl;

SystemVirtualAddress = ExAllocatePool(NonPagedPool, 1024);
Mdl = IoAllocateMdl(SystemVirtualAddress, 1024, FALSE, FALSE, NULL);
MmBuildMdlForNonPagedPool(Mdl);

strcpy(SystemVirtualAddress, \"In Driver\");
DbgPrint((char *)SystemVirtualAddress );
DbgPrint(\"\\n\");

return STATUS_SUCCESS;
}
 
static NTSTATUS MydrvDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status;
PIO_STACK_LOCATION irpSp;

// UNREFERENCED_PARAMETER(DeviceObject);

//得到当前IRP (I/O请求包)
irpSp = IoGetCurrentIrpStackLocation(Irp);

switch (irpSp->MajorFunction)
{
case IRP_MJ_CREATE:
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;
break;

case IRP_MJ_CLOSE:
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;
break;

case IRP_MJ_CLEANUP:
MmUnmapLockedPages(UserVirtualAddress, Mdl);
break;

default:
break;
}

IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;

}

static NTSTATUS MydrvDispatchIoctl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
PIO_STACK_LOCATION IrpStack;
NTSTATUS status;
ULONG ControlCode;
ULONG InputLength, OutputLength;
TCHAR wInputBuffer[200];
TCHAR OutMsg[] = \"Hello, Application!\";

//得到当前IRP (IO请求包)
IrpStack = IoGetCurrentIrpStackLocation( Irp );

//得到DeviceIoControl传来的控制码
ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
//得到DeviceIoControl传来的输入缓冲区长度
InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
//得到DeviceIoControl的输出缓冲区长度
OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;

switch (ControlCode)
{
case IOCTL_SHAREMEMORY_GETVADDR:
try
{
UserVirtualAddress = MmMapLockedPages(Mdl, UserMode);
*((PVOID *)(Irp->AssociatedIrp.SystemBuffer)) = UserVirtualAddress;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = sizeof(PVOID);
}
except(EXCEPTION_EXECUTE_HANDLER){}
break;

case IOCTL_SHAREMEMORY_SHOWCONTENT:
DbgPrint(\"Now the shared memory is : \");
DbgPrint((char *)SystemVirtualAddress );
DbgPrint(\"\\n\");
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0L;

default:
break;
}
status = Irp->IoStatus.Status;
//完成IRP请求
IoCompleteRequest(Irp, 0);
return status;
}


VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
UNICODE_STRING nameString;
RtlInitUnicodeString(&nameString, L\"\\\\??\\\\My_ShareMemory\");
IoDeleteSymbolicLink(&nameString);
IoDeleteDevice(pDriverObject->DeviceObject);

ExFreePool(SystemVirtualAddress);
IoFreeMdl(Mdl);
return;
}
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-09-30 13:30
现在的问题是我已经可以在驱动中把UserVirtualAddress正确的传递给应用程序,当时应用程序却不能对这个地址读写,一操作就出错!
所以问题可能在两个方面:1。可能在驱动中没有正确地映射到用户地址空间2。是不是win2000不允许Win32程序访问不在一个任务的地址空间中的内存?
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-09-30 13:37
另外对于内存的申请和用户进程地址的映射我都是在DriverEntry中实现的,会不会有问题?
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2003-09-30 14:14
问题已经解决了,原来映射用户地址空间那一步是不能在DriverEntry里头实现得,要在调度进程的上下文中映射
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
7楼#
发布于:2003-09-30 15:46
当然,不然是运行在ARBITRARY  CONTEST中,所以对用户地址的访问需要加入SEH.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
kucy_zhou@163.c
驱动牛犊
驱动牛犊
  • 注册日期2003-11-26
  • 最后登录2005-11-04
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-21 10:35
hoosyman:
  我也遇到了这样的问题,我在驱动中分配的内存也是对的,我是在driverentry下分配的内存,在ioctl下映射得内存。可是我在应用程序却不能到正确的。我觉得我程序没有问题。不知道怎么回事,请帮帮忙。
应用程序:
DWORD DataBuf[1024];
if(!DeviceIoControl(hAMCC5920, IOCTL_AMCC5920_MAP_MEMORY, NULL, 0,(PDWORD)&DataBuf, sizeof(1024), &dwReturnedLength, NULL))
    {
        printf(\"Ioctl mapmemory failed x%\\n \",GetLastError());
    }

驱动程序:
SystemVirtualAddress = ExAllocatePool(NonPagedPool,1024*9);   //allocate memory in driver
Mdl = IoAllocateMdl(SystemVirtualAddress, 1024*9, FALSE, FALSE, NULL);
if(!Mdl)
{
       ExFreePool(SystemVirtualAddress);
       return(NULL);
 }

 MmBuildMdlForNonPagedPool(Mdl);

case IOCTL_AMCC5920_MAP_MEMORY:
  try
  {
    UserVirtualAddress = MmMapLockedPagesSpecifyCache(Mdl,
                  UserMode,NULL,NULL,FALSE,NULL); // Priority
   DbgPrint(\"IO_GETADD:pUserVirAdd=%d\\n\",UserVirtualAddress);//
*((PVOID *)(pIrp->UserBuffer)) = UserVirtualAddress;
if(UserVirtualAddress==0)
 {
    DbgPrint(\"UserVirtualAddress==0\\n\");//
    Status=(!STATUS_SUCCESS);
    break;
  }

  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = sizeof(PVOID);
kucy_zhou@163.c
驱动牛犊
驱动牛犊
  • 注册日期2003-11-26
  • 最后登录2005-11-04
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-27 08:54
/////////////////////////////////////////////////////////
现在的问题是我已经可以在驱动中把UserVirtualAddress正确的传递给应用程序,当时应用程序却不能对这个地址读写,一操作就出错!
所以问题可能在两个方面:1。可能在驱动中没有正确地映射到用户地址空间2。是不是win2000不允许Win32程序访问不在一个任务的地址空间中的内存?
//////////////////////////////////////////////////////
我现在遇到的问题和你上面的一模一样,我在应用程序中得了正确的地址,可是就是不能访问,请问你最后是怎么解决的亚?我的程序
已经贴出来了,请帮帮忙忙好么?


 
hoosyman
驱动小牛
驱动小牛
  • 注册日期2002-10-31
  • 最后登录2006-07-14
  • 粉丝0
  • 关注0
  • 积分20分
  • 威望2点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-04-27 11:01
////////////////////////////////////////////////////
DWORD DataBuf[1024];
if(!DeviceIoControl(hAMCC5920, IOCTL_AMCC5920_MAP_MEMORY, NULL, 0,(PDWORD)&DataBuf, sizeof(1024), &dwReturnedLength, NULL))
{
printf(\"Ioctl mapmemory failed x%\\n \",GetLastError());
}
/////////////////////////////////////////////////////
改为:
DWORD DataBuf[1024];
if(!DeviceIoControl(hAMCC5920, IOCTL_AMCC5920_MAP_MEMORY, NULL, 0,(PULONG)&DataBuf, sizeof(ULONG), &dwReturnedLength, NULL))
{
printf(\"Ioctl mapmemory failed x%\\n \",GetLastError());
}


kucy_zhou@163.c
驱动牛犊
驱动牛犊
  • 注册日期2003-11-26
  • 最后登录2005-11-04
  • 粉丝0
  • 关注0
  • 积分17分
  • 威望3点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-04-29 09:19
谢谢,好了!可是又有新问题了。
游客

返回顶部