createthread创建的IST用NDIS的workitem替换后对系统会有何影响?
各位高手:
我目前碰到一个问题,原来是用createthread创建的IST,有人想用NDIS的workitem替换,实现在WINDOWS下的可移植性。
不知在WINCE下用用NDIS的workitem替换CREATETHREAD有何影响,有没有人试过?
上楼我想请问一下,NDIS中直接用CreatThread开启线程好像行不通吧??看我在NDIS IM 的passthru.dll中在protocol.c中的ProtocolReceivePacket添加的代码,如下,模拟器debug版本编译后行不通!说CreatThread警告视为错误。
INT
ProtocolReceivePacket(
IN NDIS_HANDLE hProtocolBindingContext,
IN PNDIS_PACKET pPacket
)
/*++
Arguments:
ProtocolBindingContext - Pointer to our adapter structure.
Packet - Pointer to the packet
Return Value:
== 0 -> We are done with the packet
!= 0 -> We will keep the packet and call NdisReturnPackets() this
many times when done.
--*/
{
BINDING* pBinding = (BINDING*)hProtocolBindingContext;
INT iCode = 0;
NDIS_STATUS status;
PNDIS_PACKET pIMPacket;
INT rc;
NDIS_HANDLE hWriteThread;
//添加的
UINT PacketSize;
PVOID pPacketContent;
UCHAR* pBuf;
UINT BufLength;
NDIS_BUFFER * pNext;
UINT i;
//结束
#ifdef NDIS51
BOOLEAN bRemaining;
#endif
// Drop the packet silently if the upper miniport edge isn't initialized
DBGPRINT(("+++++++++++++++ get into ProtocolReceivePacket ----------\n"));
if (!pBinding->hMPBinding) goto cleanUp;
DBGPRINT(("+++++++++++++++ pBinding->hMPBinding is not NULL ----------\n"));
#ifdef NDIS51
//
// Check if we can reuse the same packet for indicating up.
// See also: ProtocolReceive().
//
(VOID)NdisIMGetCurrentPacketStack(pPacket, &bRemaining);
if (bRemaining) {
//
// We can reuse "Packet". Indicate it up and be done with it.
//
//begin
NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);
if (status == NDIS_STATUS_SUCCESS) {
PASSTHRU_PR_RECV* pProtocolRecv;
pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
pProtocolRecv->pOriginalPacket = pPacket;
pIMPacket->Private.Head = pPacket->Private.Head;
pIMPacket->Private.Tail = pPacket->Private.Tail;
NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));
NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));
status = NDIS_GET_PACKET_STATUS(pPacket);
NDIS_SET_PACKET_STATUS(pIMPacket, status);
NDIS_SET_PACKET_HEADER_SIZE(
pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
);
//创建线程实现传递copy的数据包pIMPacket做为参数传递,获取缓冲区数据。设置全局循环变量N(截取的包的个数)
//然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体hMyMutex(设置超时则线程返回)得到权限
//然后打开内存映射文件,把buffer data写入内存映射文件N次,
//释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,设置hReadEvent信号,
//利用事件对象等待App(App线程在调用等待中获得互斥体,得到对文件的读取和写入权限,读取数据,清空文件,
//释放互斥体,set hWriteEnent,reset hReadEvent,进入循环等待)代码如下:
hWriteThread=CreatThread(NULL,0,WriteThread,pIMPacket,0,&rc);//rc表示线程ID
if(hWriteThread)
CloseHandle(hWriteThread);
DBGPRINT(("++==>PASSTHRU::next we willshow the copied packet buffer context++++++++\n"));
//end
status = NDIS_GET_PACKET_STATUS(pPacket);
NdisMIndicateReceivePacket(pBinding->hMPBinding, &pPacket, 1);
iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;
goto cleanUp;
}
#endif // NDIS51
// actualy define NDIS51
// Get a packet off the pool and indicate that up
//
NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);
if (status == NDIS_STATUS_SUCCESS) {
PASSTHRU_PR_RECV* pProtocolRecv;
pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
pProtocolRecv->pOriginalPacket = pPacket;
pIMPacket->Private.Head = pPacket->Private.Head;
pIMPacket->Private.Tail = pPacket->Private.Tail;
//
// Get the original packet (it could be the same packet as the one
// received or a different one based on the number of layered miniports
// below) and set it on the indicated packet so the OOB data is visible
// correctly to protocols above us.
//
NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));
//
// Set Packet Flags
//
NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));
status = NDIS_GET_PACKET_STATUS(pPacket);
NDIS_SET_PACKET_STATUS(pIMPacket, status);
NDIS_SET_PACKET_HEADER_SIZE(
pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
);
NdisMIndicateReceivePacket(pBinding->hMPBinding, &pIMPacket, 1);
//++++
DBGPRINT(("++==>PASSTHRU::show the copied packet buffer context++++++++\n"));
//把数据包内容从Packet拷贝到pPacketContent
NdisQueryPacket( pIMPacket,NULL,NULL,NULL,&PacketSize);
NdisAllocateMemoryWithTag(&pPacketContent,2000,PASSTHRU_MEMORY_TAG);
if (pPacketContent!=NULL)
{
NdisZeroMemory (pPacketContent, 2000);
NdisQueryBufferSafe(pIMPacket->Private.Head, &pBuf, &BufLength, 32 );
NdisMoveMemory(pPacketContent, pBuf, BufLength);
i = BufLength;
pNext = pIMPacket->Private.Head;
for(;;)
{
if(pNext == pIMPacket->Private.Tail)
break;
pNext = pNext->Next; //指针后移
if(pNext == NULL)
break;
NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);
NdisMoveMemory((UCHAR*)pPacketContent+i,pBuf,BufLength);
i+=BufLength;
}
DBGPRINT(("+++++++++++++++now we should creat a thread to copy data and display ----------\n"));
}
//++然后创建线程对内存映射文件建立并且写入数据,
//当写完一个包后关闭文件。
//CreatThread(NULL,0,WriteMMFile, pPacketContent
//使用共享内存方式,因为减少了系统调用的开销,可以避免速度下降。
////添加的代码结束!
//
// Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
// NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
// it might have changed! Use the value saved in the local variable.
//
if (status == NDIS_STATUS_RESOURCES) {
//
// Our ReturnPackets handler will not be called for this packet.
// We should reclaim it right here.
//
NdisFreePacket(pIMPacket);
}
iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;
}
cleanUp:
DBGPRINT(("++++++++++++++ProtocolReceivePacket Over!!!!!!!!!! ----------\n"));
return iCode;
}
往下看,希望得到交流!
上楼我想请问一下,NDIS中直接用CreatThread开启线程好像行不通吧??看我在NDIS IM 的passthru.dll中在protocol.c中的ProtocolReceivePacket添加的代码,如下,模拟器debug版本编译后行不通!说CreatThread警告视为错误。
INT
ProtocolReceivePacket(
IN NDIS_HANDLE hProtocolBindingContext,
IN PNDIS_PACKET pPacket
)
/*++
Arguments:
ProtocolBindingContext - Pointer to our adapter structure.
Packet - Pointer to the packet
Return Value:
== 0 -> We are done with the packet
!= 0 -> We will keep the packet and call NdisReturnPackets() this
many times when done.
--*/
{
BINDING* pBinding = (BINDING*)hProtocolBindingContext;
INT iCode = 0;
NDIS_STATUS status;
PNDIS_PACKET pIMPacket;
INT rc;
NDIS_HANDLE hWriteThread;
//添加的
UINT PacketSize;
PVOID pPacketContent;
UCHAR* pBuf;
UINT BufLength;
NDIS_BUFFER * pNext;
UINT i;
//结束
#ifdef NDIS51
BOOLEAN bRemaining;
#endif
// Drop the packet silently if the upper miniport edge isn't initialized
DBGPRINT(("+++++++++++++++ get into ProtocolReceivePacket ----------\n"));
if (!pBinding->hMPBinding) goto cleanUp;
DBGPRINT(("+++++++++++++++ pBinding->hMPBinding is not NULL ----------\n"));
#ifdef NDIS51
//
// Check if we can reuse the same packet for indicating up.
// See also: ProtocolReceive().
//
(VOID)NdisIMGetCurrentPacketStack(pPacket, &bRemaining);
if (bRemaining) {
//
// We can reuse "Packet". Indicate it up and be done with it.
//
//begin
NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);
if (status == NDIS_STATUS_SUCCESS) {
PASSTHRU_PR_RECV* pProtocolRecv;
pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
pProtocolRecv->pOriginalPacket = pPacket;
pIMPacket->Private.Head = pPacket->Private.Head;
pIMPacket->Private.Tail = pPacket->Private.Tail;
NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));
NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));
status = NDIS_GET_PACKET_STATUS(pPacket);
NDIS_SET_PACKET_STATUS(pIMPacket, status);
NDIS_SET_PACKET_HEADER_SIZE(
pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
);
//创建线程实现传递copy的数据包pIMPacket做为参数传递,获取缓冲区数据。设置全局循环变量N(截取的包的个数)
//然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体hMyMutex(设置超时则线程返回)得到权限
//然后打开内存映射文件,把buffer data写入内存映射文件N次,
//释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,设置hReadEvent信号,
//利用事件对象等待App(App线程在调用等待中获得互斥体,得到对文件的读取和写入权限,读取数据,清空文件,
//释放互斥体,set hWriteEnent,reset hReadEvent,进入循环等待)代码如下:
hWriteThread=CreatThread(NULL,0,WriteThread,pIMPacket,0,&rc);//rc表示线程ID
if(hWriteThread)
CloseHandle(hWriteThread);
DBGPRINT(("++==>PASSTHRU::next we willshow the copied packet buffer context++++++++\n"));
//end
status = NDIS_GET_PACKET_STATUS(pPacket);
NdisMIndicateReceivePacket(pBinding->hMPBinding, &pPacket, 1);
iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;
goto cleanUp;
}
#endif // NDIS51
// actualy define NDIS51
// Get a packet off the pool and indicate that up
//
NdisAllocatePacket(&status, &pIMPacket, pBinding->hRecvPacketPool);
if (status == NDIS_STATUS_SUCCESS) {
PASSTHRU_PR_RECV* pProtocolRecv;
pProtocolRecv = (PASSTHRU_PR_RECV*)(pIMPacket->MiniportReserved);
pProtocolRecv->pOriginalPacket = pPacket;
pIMPacket->Private.Head = pPacket->Private.Head;
pIMPacket->Private.Tail = pPacket->Private.Tail;
//
// Get the original packet (it could be the same packet as the one
// received or a different one based on the number of layered miniports
// below) and set it on the indicated packet so the OOB data is visible
// correctly to protocols above us.
//
NDIS_SET_ORIGINAL_PACKET(pIMPacket, NDIS_GET_ORIGINAL_PACKET(pPacket));
//
// Set Packet Flags
//
NdisSetPacketFlags(pIMPacket, NdisGetPacketFlags(pPacket));
status = NDIS_GET_PACKET_STATUS(pPacket);
NDIS_SET_PACKET_STATUS(pIMPacket, status);
NDIS_SET_PACKET_HEADER_SIZE(
pIMPacket, NDIS_GET_PACKET_HEADER_SIZE(pPacket)
);
NdisMIndicateReceivePacket(pBinding->hMPBinding, &pIMPacket, 1);
//++++
DBGPRINT(("++==>PASSTHRU::show the copied packet buffer context++++++++\n"));
//把数据包内容从Packet拷贝到pPacketContent
NdisQueryPacket( pIMPacket,NULL,NULL,NULL,&PacketSize);
NdisAllocateMemoryWithTag(&pPacketContent,2000,PASSTHRU_MEMORY_TAG);
if (pPacketContent!=NULL)
{
NdisZeroMemory (pPacketContent, 2000);
NdisQueryBufferSafe(pIMPacket->Private.Head, &pBuf, &BufLength, 32 );
NdisMoveMemory(pPacketContent, pBuf, BufLength);
i = BufLength;
pNext = pIMPacket->Private.Head;
for(;;)
{
if(pNext == pIMPacket->Private.Tail)
break;
pNext = pNext->Next; //指针后移
if(pNext == NULL)
break;
NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);
NdisMoveMemory((UCHAR*)pPacketContent+i,pBuf,BufLength);
i+=BufLength;
}
DBGPRINT(("+++++++++++++++now we should creat a thread to copy data and display ----------\n"));
}
//++然后创建线程对内存映射文件建立并且写入数据,
//当写完一个包后关闭文件。
//CreatThread(NULL,0,WriteMMFile, pPacketContent
//使用共享内存方式,因为减少了系统调用的开销,可以避免速度下降。
////添加的代码结束!
//
// Check if we had indicated up the packet with NDIS_STATUS_RESOURCES
// NOTE -- do not use NDIS_GET_PACKET_STATUS(MyPacket) for this since
// it might have changed! Use the value saved in the local variable.
//
if (status == NDIS_STATUS_RESOURCES) {
//
// Our ReturnPackets handler will not be called for this packet.
// We should reclaim it right here.
//
NdisFreePacket(pIMPacket);
}
iCode = (status != NDIS_STATUS_RESOURCES) ? 1 : 0;
}
cleanUp:
DBGPRINT(("++++++++++++++ProtocolReceivePacket Over!!!!!!!!!! ----------\n"));
return iCode;
}
往下看,希望得到交流!
//the created thread
INT WINAPI WriteThread(PVIOD pArg)
{
//创建线程实现传递copy的数据包pIMPacket做为参数传递,获取缓冲区数据。设置全局循环变量N(截取的包的个数)
//然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体hMyMutex(设置超时则线程返回)得到权限
//然后打开内存映射文件,把buffer data写入内存映射文件N次,
//释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,set hReadEvent,reset hWriteEvent,线程返回)
//利用事件对象hReadEvent促发App等待线程,(App线程在调用等待中获得互斥体,得到对文件的读取权限,读取数据,
//释放互斥体,set hWriteEnent,reset hReadEvent,进入循环等待)代码如下
//------------------------------------------------------------------------------
//把数据包内容从Packet拷贝到pPacketContent
static UINT N=0;
static DWORD dwOffset=0;
PNDIS_PACKET pIMPacket;
UINT PacketSize;
PVOID pPacketContent;
LPBYTE pBuf;
UINT BufLength;
NDIS_BUFFER * pNext;
UINT i;
INT rc;
*PNDIS_HANDLE hMyMutex;
*PNDIS_HANDLE hMyFile,hMyFileMap;
PBYTE pMyFileMem;
LPTSTR szMyFileName="MyFile";
LPTSTR lpWriteEventName="MyWriteEvent";
LPTSTR lpReadEventName="MyReadEvent";
LPTSTR lpMutextName="MyMutex";
//INT rs;
pIMPacket=(PNDIS_PACKET)pArg;
NdisQueryPacket( pIMPacket,NULL,NULL,NULL,&PacketSize);
NdisAllocateMemoryWithTag(&pPacketContent,2000,PASSTHRU_MEMORY_TAG);
if (pPacketContent!=NULL)
{
NdisZeroMemory (pPacketContent, 2000);
NdisQueryBufferSafe(pIMPacket->Private.Head, &pBuf, &BufLength, 32 );
NdisMoveMemory(pPacketContent, pBuf, BufLength);
i = BufLength;
pNext = pIMPacket->Private.Head;
for(;;)
{
if(pNext == pIMPacket->Private.Tail)
break;
pNext = pNext->Next; //指针后移
if(pNext == NULL)
break;
NdisQueryBufferSafe(pNext,&pBuf,&BufLength,32);
NdisMoveMemory((UCHAR*)pPacketContent+i,pBuf,BufLength);
i+=BufLength;
}
}
//然后等待hWriteEvent(设置超时时间),如返回超时则线程返回,否则等待获得互斥体(设置超时则线程返回)得到权限
hWriteEvent=CreatEvent(NULL,TRUE,TURE,lpWriteEventName);
hReadEvent=CreatEvent(NULL,TRUE,TRUE,lpReadEnentName);
if(!hWriteEvent||!hReadEvent)
return -1;
rc=WaitForSingleObject(hWriteEvent,2000);
if(rc==WAit_OBJECT_0){
hMyMutex=CreatMutex(NULL,TURE, lpMutextName);
// rs=GetLastError();
//if(rs==ERROR_ALREADY_EXISTS)
rc=WaitForSingleObject(hMyMutex,2000);
if(rc!=WAit_OBJECT_0)
return 0;
//然后打开内存映射文件,把buffer data写入内存映射文件N次,
hMyFile = CreateFileForMapping (szMyFileName, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if (hMyFile== INVALID_HANDLE_VALUE) {
hMyFile = 0;
return GetLastError();
}
hMyFileMap=CreatFileMapping(hMyFile,NULL,PAGE_MAP_WRITE,0,0,0);
if(hMyFileMap==INVALID_HANDLE_VALUE)
{
CloseHandle(hMyFile);
return 0;
}
pMyFileMem=(LPBYTE) MapViewOfFile ( hMyFileMap, FILE_MAP_ALL_ACCESS , 0, dwOffset, 0 );
if(pMyFileMem){
//use the data in my file
NdisMoveMemory(pMyFileMem,pPacketContent,i);
N++;
UnmapViewOfFile(pMyFileMem);
}
CloseHandle(hMyFileMap);
CloseHandle(hMyFile);
//释放两次互斥体,线程返回(判断如果截取包次数到达N则设置释放两次互斥体,set hReadEvent,reset hWriteEvent,线程返回)
ReleaseMutex(hMyMutex);
ReleaseMutex(hMyMutex);
if(N>5)
{
SetEvent(hReadEvent);
ResetEvent(hWriteEvent);
}
return 1;
}
else
return -1;
}
//添加线程结束
好象和驱动程序的开发环境有关.
如果你用WIN2000/XP的DDK做开发环境,对某些只在用户态下才适用的API是不能在驱动程序代码里调用的,这里的CreateThread可能就是一个.