zyhflorida
驱动牛犊
驱动牛犊
  • 注册日期2002-08-09
  • 最后登录2003-11-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1363回复:6

再次请教各位,关于读取PACKET时丢失数据的问题。(20 分)

楼主#
更多 发布于:2002-08-23 23:02
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题?

谢谢各位!
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2002-08-23 23:13
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题?

谢谢各位!


可以两面入手:

1。应用层开多线程。

2。驱动层内建一环形的缓冲区。

当然可能还有其他更好的方法!?



 :)
[color=red]大头鬼! :P[/color]
zyhflorida
驱动牛犊
驱动牛犊
  • 注册日期2002-08-09
  • 最后登录2003-11-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-08-23 23:25
谢谢MAGICX,不知我能否将IRP->ASSOCIATEDIRP->SYSTEMBUFFER做成CIRCULAR BUFFER呀?如果问题太愚蠢,请别见笑, 我是新手:-)
zyhflorida
驱动牛犊
驱动牛犊
  • 注册日期2002-08-09
  • 最后登录2003-11-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-08-24 06:18
再将我的问题仔细描述一下:

NDIS_STATUS IOControlHandler (
DWORD ControlCode,
PUCHAR pInBuffer,
DWORD InputBufferLength,
PUCHAR pOutBuffer,
DWORD OutputBufferLength,
PDWORD pReturnedSize
)
{
switch ( ControlCode )
{
case IOCTL_PIM_GET_VERSION:
{
*((PDWORD) pOutBuffer) = NDISHK_ETHERNET_BRIDGE;
*pReturnedSize = sizeof (DWORD);
return NDIS_STATUS_SUCCESS;
}
case IOCTL_PIM_SET_BRIDGING:
{
PrF_SetBridgingStatus (*((PDWORD)(pInBuffer)));
*pReturnedSize = 0;
return NDIS_STATUS_SUCCESS;
}
case IOCTL_PIM_GET_PACKET:
{
RtlMoveMemory(pOutBuffer, data1, MAX_ETHER_SIZE*sizeof(unsigned char));
DbgPrint(\"IoControlHandler is :  %X%X%X%X%X%X%X%X%X%X%X\\n\", pOutBuffer[0], pOutBuffer[1],pOutBuffer[2],pOutBuffer[3],pOutBuffer[4],pOutBuffer[5],pOutBuffer[6],pOutBuffer[7],pOutBuffer[8],pOutBuffer[9],pOutBuffer[10]);
*pReturnedSize = MAX_ETHER_SIZE*sizeof(unsigned char);
return NDIS_STATUS_SUCCESS;
}
}

return NDIS_STATUS_NOT_RECOGNIZED;
}

DISPATCH ROUTINE 里:

case IRP_MJ_DEVICE_CONTROL:
{
pBuffer = ( PUCHAR ) Irp -> AssociatedIrp.SystemBuffer;
InputBufferLength = irpStack -> Parameters.DeviceIoControl.InputBufferLength;
OutputBufferLength = irpStack -> Parameters.DeviceIoControl.OutputBufferLength;
ControlCode = irpStack -> Parameters.DeviceIoControl.IoControlCode;
Status = STATUS_SUCCESS;

if   (
IOControlHandler (
ControlCode,
pBuffer,
InputBufferLength,
pBuffer,
OutputBufferLength,
&ReturnedSize ) != NDIS_STATUS_SUCCESS
)
{
Status = STATUS_INVALID_PARAMETER;
ReturnedSize = 0;
}

WIN32程序如下:
#include \"stdafx.h\"

// Sample class for driver connectivity

class CPIMApi {
public:
// Data members
bool m_IsLoadSuccessfully;
int m_SizeRet;

// Functions
bool DrvIoControl ( DWORD dwService, void *BuffIn, int SizeIn, void *BuffOut, int SizeOut, int *SizeRet, LPOVERLAPPED povlp);
int GetVersion();
void SetBridgingState (ULONG state);
void GetPacket();
void SetUserEvent();

// Construction/destruction
CPIMApi(const char * pszFileName = \"NDISHK\" );
~CPIMApi();

private:
// Protected data members
OVERLAPPED m_ovlp;
HANDLE m_hDrv;
public:
HANDLE m_hEvent;
int k;

};

// Constructor besides initialization opens driver
CPIMApi::CPIMApi(const char * pszFileName )
{
char FullName [ 300 ];
     strcpy ( FullName, \"\\\\\\\\.\\\\\" );
     strcat ( FullName, pszFileName );
     m_IsLoadSuccessfully = FALSE;
k = 0;

m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    
m_hDrv   = CreateFile( FullName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_DELETE_ON_CLOSE, 0 );
    
if   ( m_hDrv == INVALID_HANDLE_VALUE )
     {
 m_hDrv   = CreateFile ( FullName, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0 );
     }
     if   ( m_hDrv == INVALID_HANDLE_VALUE )
     {
          m_ovlp.hEvent = 0;
     }
     else
     {
          m_ovlp.hEvent = 0;
          m_ovlp.hEvent = CreateEvent ( 0, TRUE, FALSE, NULL );

          if   ( m_ovlp.hEvent )
          {
               m_IsLoadSuccessfully = TRUE;
          }
     }
}

// Destructor closes handle to device
CPIMApi::~CPIMApi()
{
if   ( m_hDrv != INVALID_HANDLE_VALUE )
{
  CloseHandle ( m_hDrv );
}
    if   ( m_ovlp.hEvent )
{
  CloseHandle ( m_ovlp.hEvent );
}
}

// Wrapper around DeviceIoControl API
bool CPIMApi::DrvIoControl(DWORD dwService, void *BuffIn, int SizeIn, void *BuffOut, int SizeOut, int *SizeRet, LPOVERLAPPED povlp)
{
     ULONG Ret = 0;
     if   ( m_hDrv != INVALID_HANDLE_VALUE )
     {
if(povlp == NULL)
Ret = DeviceIoControl ( m_hDrv, dwService, BuffIn, SizeIn, BuffOut, SizeOut, (unsigned long*)SizeRet, &m_ovlp);
else
Ret = DeviceIoControl ( m_hDrv, dwService, BuffIn, SizeIn, BuffOut, SizeOut, (unsigned long*)SizeRet, povlp);
     }

     return Ret?true:false;
}

// Getting version info function
int CPIMApi::GetVersion()
{
ULONG nDriverAPIVersion = 0xFFFFFFFF;
int cbBytesRet =0;
bool bIOResult = DrvIoControl(
 IOCTL_PIM_GET_VERSION,
 &nDriverAPIVersion,
 sizeof(ULONG),
 &nDriverAPIVersion,
 sizeof(ULONG),
                      &cbBytesRet,   // Bytes Returned
                      NULL
 );
return nDriverAPIVersion;
}

// Starts bridging interfaces
void CPIMApi::SetBridgingState (ULONG state)
{
int cbBytesRet =0;

if (GetVersion() == NDISHK_ETHERNET_BRIDGE)
{
printf (\"\\nThis version support bridging.\\nStarting....\\n\");

bool bIOResult = DrvIoControl(
 IOCTL_PIM_SET_BRIDGING,
 &state,
 sizeof(ULONG),
 NULL,
 0,
 &cbBytesRet,   // Bytes Returned
 NULL
 );
}
else
{
printf (\"\\nThis version of driver does not support ethernet bridging.\\n\");
}
}

void CPIMApi::GetPacket()
{
unsigned char v[1515];
unsigned char t[1515];
ULONG cbBytesRet =0;
OVERLAPPED      overlapped;

memset(v, 0, 1515*sizeof(unsigned char));
memset(t, 0, 1515*sizeof(unsigned char));

memset(&overlapped, 0, sizeof(OVERLAPPED));
overlapped.hEvent = CreateEvent(
NULL, // pointer to security attributes
FALSE, // automatic reset
FALSE, // initialize to not signaled
NULL
); // pointer to the event-object name

// ReadFile( m_hDrv, t, 1515*sizeof(unsigned char), &cbBytesRet, &overlapped);
bool bIOResult = DrvIoControl(
 IOCTL_PIM_GET_PACKET,
 &v,
 1515 * sizeof(unsigned char),
 &t,
 1515 * sizeof(unsigned char),
                      reinterpret_cast<int *>(&cbBytesRet),   // Bytes Returned
                      &overlapped
 );

printf(\"Test value %d is %x%x%x%x%x%x%x%x%x%x%x \\n\", k, t[0], t[1],t[2],t[3],t[4],t[5],t[6],t[7],t[8],t[9]);
k++;
}

void CPIMApi::SetUserEvent()
{
int bytesRet;

DrvIoControl(
IOCTL_PIM_SET_EVENT,
&m_hEvent,
sizeof(HANDLE),
NULL,
0,
&bytesRet,
NULL);
}


int main(int argc, char* argv[])
{
CPIMApi api;
DWORD status;

if (api.m_IsLoadSuccessfully)
{
if (argc == 2)
{
if (!strcmp(argv[1], \"ON\"))
{
api.SetBridgingState(1);
api.SetUserEvent();

while(1)
{
status = WaitForSingleObject(api.m_hEvent, INFINITE);
if (status == WAIT_ABANDONED || status == WAIT_OBJECT_0 || status == WAIT_TIMEOUT)
{
printf(\"got event %d   %d\\n\", api.k, status);
// api.GetPacket();
// api.GetPacket();
api.k++;
}
}

return 0;
}

if (!strcmp(argv[1], \"OFF\"))
{
api.SetBridgingState (0);
return 0;
}
}
}

printf (\"Usage: client OFF|ON\\n OFF - stop bridging \\n ON  - start bridging\");
return 0;
}

如果在DRIVER里用一CIRCULAR BUFFER,该如何实现?因为我在DRIVER理实际就是将数据拷到SYSTEMBUFFER 里。

谢谢各位。
HuYuguang
论坛版主
论坛版主
  • 注册日期2001-04-25
  • 最后登录2013-04-29
  • 粉丝3
  • 关注1
  • 积分92分
  • 威望11点
  • 贡献值0点
  • 好评度9点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2002-08-24 12:54
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题?

谢谢各位!


我郁闷,因为很显然你对我的代码误用了,
我写那篇文章是要解释如何用扳手拧一个螺丝,
当然,你用这把扳手订钉子也能钉进去,但是
感觉不会太好吧?
不再回忆从前,我已经生活在幸福当中。
oxEar
驱动牛犊
驱动牛犊
  • 注册日期2002-03-28
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-08-24 18:52
感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题?

谢谢各位!


我对这个问题也想弄明白, 为什么你用DEVICEIOCONTROL来读数据呢?
能不能用MajorFunction[IRP_MJ_READ],然后在应用层用
ReadFile来读数据,另外,如果加密数据,有没有必要将数据
传到应用层,在那里加密,再写到核心层呢?
magicx
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2014-08-18
  • 粉丝1
  • 关注0
  • 积分-14分
  • 威望13点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-08-24 19:03
[quote]感谢老MO的提示和老胡的文章,现在收到PACKET后给WIN32发送NOFITYEVENT, WIN32 可以读到PACKET了。但是现在的问题是当流量大的时候会丢失数据。我现在用的是BUFFERED_IO,PACKET拷到IRP->ASSOCIATEDIRP->SYSTEMBUFFER,应用程序通过DEVICEIOCONTROL到这里读取数据。请问我如何才能解决这个问题?

谢谢各位!


我对这个问题也想弄明白, 为什么你用DEVICEIOCONTROL来读数据呢?
能不能用MajorFunction[IRP_MJ_READ],然后在应用层用
ReadFile来读数据,另外,如果加密数据,有没有必要将数据
传到应用层,在那里加密,再写到核心层呢? [/quote]

应该只是个例子吧!

不必如此的细哦。。。。。。

 :)
[color=red]大头鬼! :P[/color]
游客

返回顶部