Chinaunix首页 | 论坛 | 博客
  • 博客访问: 399702
  • 博文数量: 73
  • 博客积分: 3120
  • 博客等级: 中校
  • 技术积分: 785
  • 用 户 组: 普通用户
  • 注册时间: 2010-10-20 12:26
文章分类

全部博文(73)

文章存档

2013年(4)

2012年(10)

2011年(32)

2010年(27)

分类: WINDOWS

2011-12-21 11:45:59

//定义结构体
typedef struct _RING_MGR
{
 unsigned int max_len;
 unsigned int rp;
 unsigned int wp;
 int over_flag;
 unsigned char *data;
}RING_MGR,*PRING_MGR;
 
typedef struct _DEVICE_EXTENSION  {
        .
        .
        .
  PRING_MGR          pSendDataRing;  
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;
 
 
//初始化RingBuffer
void SKYRingBufferInit(PRING_MGR *pr,unsigned int size){
 PRING_MGR pring;
 pring=(PRING_MGR)ExAllocatePoolWithTag(NonPagedPool,size+sizeof(RING_MGR),'SKY');
 pring->max_len=size;
 pring->rp=0;
 pring->wp=0;
 pring->over_flag=0;
 pring->data=(unsigned char *)pring+sizeof(RING_MGR);
 *pr=pring;
 SKYDbgPrint(SKY_CHECK,("Baseaddr=%x headsize=%d dataaddr=%x maxlen=%d",(unsigned char *)pring,sizeof(RING_MGR),pring->data,pring->max_len));
}
//复位RingBuffer
void SKYRingBufferReset(PRING_MGR pr){
 pr->rp=0;
 pr->wp=0;
 pr->over_flag=0;
}
//释放RingBuffer
void SKYRingBufferFree(PRING_MGR pr){
 if(pr)
  ExFreePool(pr);
}
//获取RingBuffer中数据长度
ULONG SKYGetRingDataLen(PRING_MGR pr)
{
 unsigned int data_len;
 if(pr->rp == pr->wp)
  data_len=0;
 else if(pr->rp > pr->wp)
 {
  data_len=pr->max_len-pr->rp+pr->wp;
 }
 else
 {
  data_len=pr->wp-pr->rp;
 }
 return data_len;
}
//获取RingBuffer的剩余长度
ULONG SKYGetRingFreeLen(PRING_MGR pr)
{
 unsigned int free_len;
 if(pr->rp == pr->wp)
  free_len=pr->max_len;
 else if(pr->rp > pr->wp)
 {
  free_len=pr->rp-pr->wp;
 }
 else
 {
  free_len=pr->max_len-pr->wp+pr->rp;
 }
 return free_len;
}
//读取数据
NTSTATUS SKYReadBuffer(PRING_MGR pr, unsigned char *data, unsigned int len)
{
 unsigned int data_len;
 
 data_len=SKYGetRingDataLen(pr);
 if(data_len  return STATUS_UNSUCCESSFUL;
 if(pr->rp > pr->wp)
 {
  unsigned int first_len;
  first_len=pr->max_len-pr->rp;
  if(first_len>=len)
  {
   RtlCopyMemory(data,pr->data+pr->rp,len);
   pr->rp=(pr->rp+len)%pr->max_len;
  }
  else
  {
   RtlCopyMemory(data,pr->data+pr->rp,first_len);
   pr->rp=0;
   RtlCopyMemory(data+first_len,pr->data+pr->rp,len-first_len);
   pr->rp=(pr->rp+len-first_len)%pr->max_len;
  }
 }
 else
 {
  RtlCopyMemory(data,pr->data+pr->rp,len);
  pr->rp=(pr->rp+len)%pr->max_len;
 }
 return STATUS_SUCCESS;
}
//存放数据
NTSTATUS SKYStoreBuffer(PRING_MGR pr, unsigned char *data, unsigned int len)
{
 unsigned int free_len;
 free_len=SKYGetRingFreeLen(pr);
 if(free_len < len||len==0)
 {
  return STATUS_UNSUCCESSFUL;
 }
 if(pr->rp > pr->wp)
 {
  RtlCopyMemory(pr->data+pr->wp,data,len);
  pr->wp=(len+pr->wp)%pr->max_len;
 }
 else
 {
  unsigned int first_free_len;
  first_free_len=pr->max_len-pr->wp;
  if(first_free_len>=len)
  {
   RtlCopyMemory(pr->data+pr->wp,data,len);
   pr->wp=(len+pr->wp)%pr->max_len;
  }
  else
  {
   RtlCopyMemory(pr->data+pr->wp,data,first_free_len);
   pr->wp=0;
   RtlCopyMemory(pr->data+pr->wp,data+first_free_len,len-first_free_len);
   pr->wp=(len-first_free_len+pr->wp)%pr->max_len;
  }
 }
 return STATUS_SUCCESS;
}
 
示例:
#define RING_BUFFER_SIZE 1024*1024
SKYRingBufferInit(&deviceExtension->pSendDataRing,RING_BUFFER_SIZE);
SKYStoreBuffer(deviceExtension->pSendDataRing,(unsigned char *)InBuffer, InputBufferLength)
SKYReadBuffer(deviceExtension->pReceiveDataRing, (unsigned char *)OutBuffer, outputBufferLength);
SKYRingBufferFree(deviceExtension->pSendDataRing);
 
阅读(2999) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~