Programming 版 (精华区)
发信人: Sun (大灯泡), 信区: Programming
标 题: [转载] 讨论]关于数据采集卡驱动的内存分配问题 k
发信站: 紫 丁 香 (Thu Sep 9 10:41:47 1999), 转信
【 以下文字转载自 VisualProgram 讨论区 】
【 原文由 xiaojun 所发表 】
主题: [讨论]关于数据采集卡驱动的内存分配问题 kingchurch (转寄)
日期: 1998年9月19日 07:30:54
发件人: lyj.bbs@bbs.net.tsinghua.edu.cn
收件人: lyj@hs1.hit.edu.cn
发信人: gmouse (大大灰狼), 信区: Programming
各位VXD编程高手:
小弟这相有礼了!近日碰到难题,此番提出,还望多多指教!
我对自行开发的数据采集卡编一驱动.VXD,实现采集卡的buffer
满后,中断处理过程中将此buffer中的数据(32K)用memcpy()方式拷贝
到应用程序的全局堆块中(用GlobalAlloc(GPTR,0x8000)分配得到)。
如此即可由应用程序处理此数据块的内容。我在应用程序中分配好全局
堆之后,调用VXD的PM_API接口将此内存指针传给我的VXD,VXD接到之后,
将此指针值转换为VXD的FLAT地址,并启动采集过程。
我遇到的问题是,如何将全局内存指针--》VXD的可操作地址值?此方案
是否有漏洞?
1。我用到的结构:
typedef struct _PostMsgRequest
{
WORD ServiceID; // supplied by caller
WORD PostMsghWnd;
WORD PostMsgSeg;
WORD PostMsgOff;
WORD BufferSeg;
WORD BufferOff;
WORD BufferSize;
WORD Status;
} POSTMSGREQUEST, *PPOSTMSGREQUEST;
2。VXD中部分过程:
VOID PM_Api_Handler(VMHANDLE hVM, PCLIENT_STRUCT pRegs)
{
PPOSTMSGREQUEST pReq;
DWORD temp;
pReq = Map_Flat(CLIENT_ES, CLIENT_DI);
if (pReq == NULL) // validate
return;
// branch on requested service
switch (pReq->ServiceID)
{
case PMVXD_REGISTER:
pMemory = Map_Flat(PostMsgSeg,PostMsgOff);
if(pMemory == NULL)
return;
PostMsghWnd = pReq->PostMsghWnd;
if(PostMsghWnd==0)
return;
PostMsgSelector = pReq->PostMsgSeg;
PostMsgOffset = pReq->PostMsgOff;
if(PostMsgOffset==0)
return;
bClientRegistered = TRUE;
pReq->Status = STATUS_SUCCESS;
break;
case PMVXD_DEREGISTER:
pReq->Status = STATUS_FAULT;
bClientRegistered = FALSE;
break;
default:
pReq->Status = STATUS_FAULT;
}
}
3。应用程序的关键部分:
BOOL RegisterCallback(HWND hWnd)
{
POSTMSGREQUEST req;
hglb = GlobalAlloc(GPTR, 0x8000L);
Buffer = GlobalLock(hglb);
req.ServiceID = PMVXD_REGISTER;
req.PostMsghWnd = hWnd;
req.PostMsgSeg = FP_SEG((FARPROC)PostMessage);
req.PostMsgOff = FP_OFF((FARPROC)PostMessage);
req.BufferSeg = FP_SEG(Buffer); //Buffer为全局指针
req.BufferOff = FP_OFF(Buffer);
req.BufferSize = 0x8000L;
_asm lea di, [req]
_asm mov ax, ss
_asm mov es, ax
VxDAddr(); //为VXD的入口API;
return (req.Status);
}
发信人: suxm (笨笨), 信区: Programming
如果你用VXD的WIN32服务接口的话,问题就简单了。
你可以用DeviceIoControl函数。
应用程序可以利用这个函数中向VXD传递参数,如果你传递的参数是一地址
指针,VXD是可以直接用的。
还有一个建议,可以免去中断调用。
解决方案如下, 在VXD和应用程序之间建立一个同步信号灯。
然后开始VXD采集数据,当数据采集满了的时候,使信号灯亮。
这时应用程序去取VXD中的数据。
再补充一点,最好不要用中断调用,因为有很多需要注意的
地方,比如说有很多的VMM服务不能调用。
: VOID PM_Api_Handler(VMHANDLE hVM, PCLIENT_STRUCT pRegs)
: {
: PPOSTMSGREQUEST pReq;
: DWORD temp;
: pReq = Map_Flat(CLIENT_ES, CLIENT_DI);
: if (pReq == NULL) // validate
: return;
: // branch on requested service
: switch (pReq->ServiceID)
: {
: case PMVXD_REGISTER:
: pMemory = Map_Flat(PostMsgSeg,PostMsgOff);
: if(pMemory == NULL)
: : }
: }
: 3。应用程序的关键部分:
: BOOL RegisterCallback(HWND hWnd)
: {
: POSTMSGREQUEST req;
: hglb = GlobalAlloc(GPTR, 0x8000L);
: Buffer = GlobalLock(hglb);
: req.ServiceID = PMVXD_REGISTER;
: req.PostMsghWnd = hWnd;
: req.PostMsgSeg = FP_SEG((FARPROC)PostMessage);
: req.PostMsgOff = FP_OFF((FARPROC)PostMessage);
: req.BufferSeg = FP_SEG(Buffer); //Buffer为全局指针
: req.BufferOff = FP_OFF(Buffer);
: req.BufferSize = 0x8000L;
: _asm lea di, [req]
: _asm mov ax, ss
: _asm mov es, ax
: VxDAddr(); //为VXD的入口API;
: return (req.Status);
: }
发信人: gmouse (大大灰狼), 信区: Programming
我的VXD最终要为Win31服务,只是没有找到VtoolsD for win 3.1
只好用for win95的做实验,最终的应用程序也是16位的。所以
还望在这些条件内帮我解决,我将不胜感激!
对于win95的VXD设计,我也很感兴趣,希望进一步解释一下你的
设计思想,我的基础太差,刚刚起步,还望耐心指点!
在此先多谢了!
【 在 suxm (笨笨) 的大作中提到: 】
: 如果你用VXD的WIN32服务接口的话,问题就简单了。
: 你可以用DeviceIoControl函数。
: 应用程序可以利用这个函数中向VXD传递参数,如果你传递的参数是一地址
: 指针,VXD是可以直接用的。
: 还有一个建议,可以免去中断调用。
: 解决方案如下, 在VXD和应用程序之间建立一个同步信号灯。
: 然后开始VXD采集数据,当数据采集满了的时候,使信号灯亮。
: 这时应用程序去取VXD中的数据。
发信人: fingertip (自由自在), 信区: Programming
这种方法是将应用程序的数据传递给VXD,如果VXD在中断中使用这些地址,
是否会有问题?据说应使用PageLock或Thread Event?我不太明白。
换过来说,如果在VxD中申请内存,将其转换为Selector和Offset,是否就没有问题乐?
BTW,如果在VC++的App里获得了VxD传来的Selector和Offset,如何将它组装?
不好意思,这个问题有点不入门
发信人: xxhd (侠客), 信区: Programming
【 在 suxm (笨笨) 的大作中提到: 】
: 如果你用VXD的WIN32服务接口的话,问题就简单了。
: 你可以用DeviceIoControl函数。
: 应用程序可以利用这个函数中向VXD传递参数,如果你传递的参数是一地址
: 指针,VXD是可以直接用的。
: 还有一个建议,可以免去中断调用。
: 解决方案如下, 在VXD和应用程序之间建立一个同步信号灯。
: 然后开始VXD采集数据,当数据采集满了的时候,使信号灯亮。
: 这时应用程序去取VXD中的数据。
: 再补充一点,最好不要用中断调用,因为有很多需要注意的
: 地方,比如说有很多的VMM服务不能调用。
Suxm大侠:
从一些资料中看到,用GlobalAlloc 分配的内纯不是shared memory, 必须先使其共享,
另外传到Vxd以后,还要使这快内存pagelocked, Vxd才能在中断处理程序中使用。
但我不知如何先共享内纯, 请问如何做? 在Vxd中Linpagelock
以后,返回的是这片内纯的指针吗?
发信人: suxm (笨笨@迷茫中), 信区: Programming
看来你是想在WINDLL中分配内存了。
用GlobalAlloc,GloballLock,GlobalFix,GlobalPageLock得到
的buffer是全局堆中的,其指针是32位的,高位为16位段选
择器, 低位为Offset。 这样得到的内存不再需要你在VXD中PageLock
就可以用了 。
在前面的一篇文章里我给出了一个例子,关于如何使用这些API的组合。
查一下啦。
【 在 xxhd (侠客) 的大作中提到: 】
: Suxm大侠:
: 从一些资料中看到,用GlobalAlloc 分配的内纯不是shared memory, 必须先使其共享,
: 另外传到Vxd以后,还要使这快内存pagelocked, Vxd才能在中断处理程序中使用。
: 但我不知如何先共享内纯, 请问如何做? 在Vxd中Linpagelock
: 以后,返回的是这片内纯的指针吗?
发信人: xxhd (侠客), 信区: Programming
【 在 suxm (笨笨@迷茫中) 的大作中提到: 】
: 看来你是想在WINDLL中分配内存了。
: 用GlobalAlloc,GloballLock,GlobalFix,GlobalPageLock得到
: 的buffer是全局堆中的,其指针是32位的,高位为16位段选
: 择器, 低位为Offset。 这样得到的内存不再需要你在VXD中PageLock
: 就可以用了 。
: 在前面的一篇文章里我给出了一个例子,关于如何使用这些API的组合。
: 查一下啦。
您的这种方法是如何使Vxd共享Win16应用程序所分配的内纯。 那么怎样是Vxd
共享Win32程序分配的内纯呢?
发信人: suxm (笨笨@迷茫中), 信区: Programming
在WIN32APP中用MALLOC,然后在VXD中用PAGEMAPGLOBAL flag的
LinePageLock服务。
BTW:对于WIN16&VXD的内存共享问题,在WIN16中分配内存比较合
合适。因为如果在VXD中分配内存,那定在2GB以上,而WIN16
要想访问这块内存就不得不获得特殊的SELECTOR。
对于WIN32&VXD的内存共享问题,还是在VXD中分配内存的好。
【 在 xxhd (侠客) 的大作中提到: 】
: 您的这种方法是如何使Vxd共享Win16应用程序所分配的内纯。 那么怎样是Vxd
: 共享Win32程序分配的内纯呢?
发信人: xxhd (侠客), 信区: Programming
【 在 suxm (笨笨@迷茫中) 的大作中提到: 】
: 在WIN32APP中用MALLOC,然后在VXD中用PAGEMAPGLOBAL flag的
: LinePageLock服务。
: BTW:对于WIN16&VXD的内存共享问题,在WIN16中分配内存比较合
: 合适。因为如果在VXD中分配内存,那定在2GB以上,而WIN16
: 要想访问这块内存就不得不获得特殊的SELECTOR。
: 对于WIN32&VXD的内存共享问题,还是在VXD中分配内存的好。
关键问题是我想分配4M的内纯。malloc 能分配这么大的块吗?还有LinPageLock的参数
需要page number, 而其返回值就是pagelock的指针吗?
要获得page number是否可以这样做: LinPageLock(((DWORD)pointer)>>12,....) ?
另外要想Win16&Vxd 的mem共享,Vc5.0好象不支持Win16的函数,比如GlobalPageLock,
请问那个VC版本可以支持Win16的编程?
谢谢。
发信人: suxm (笨笨@迷茫中), 信区: Programming
【 在 xxhd (侠客) 的大作中提到: 】
: 关键问题是我想分配4M的内纯。malloc 能分配这么大的块吗?还有LinPageLock的参数
: 需要page number, 而其返回值就是pagelock的指针吗?
: 要获得page number是否可以这样做: LinPageLock(((DWORD)pointer)>>12,....) ?
记不得linpagelock的具体用法了。建议你在VXD中用pageallocate分配内存,4M
没有问题。另:MALLOC应该可以分配4M的内存。
: 另外要想Win16&Vxd 的mem共享,Vc5.0好象不支持Win16的函数,比如GlobalPageLock,
: 请问那个VC版本可以支持Win16的编程?
VC1。5 OR VC1。0
: 谢谢。
发信人: xxhd (侠客), 信区: Programming
【 在 suxm (笨笨@迷茫中) 的大作中提到: 】
: 记不得linpagelock的具体用法了。建议你在VXD中用pageallocate分配内存,4M
: 没有问题。另:MALLOC应该可以分配4M的内存。
: VC1。5 OR VC1。0
我也想试试Win16和vxd的通信,VC1.5可能不好找,哪儿有?
--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: hs5.hit.edu.cn]
--
※ 转载:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.118.239.237]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:208.152毫秒