亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? 網(wǎng)絡(luò)驅(qū)動(dòng)教程.txt

?? 驅(qū)動(dòng)開發(fā)過程中要注意的一些要點(diǎn)以及一些基本資料
?? TXT
?? 第 1 頁 / 共 3 頁
字號(hào):

對(duì)于這個(gè)設(shè)備,應(yīng)用程序可以打開、讀、寫、發(fā)出控制命令、關(guān)閉。

--------------示例3-----------------
// 打開
HANDLE Handle=CreateFile("\\.\MyNdisDevice",
GENERIC_WRITE|GENERIC_READ,
FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,NULL); 
if(Handle==INVALID_HANDLE_VALUE)
{}// 失敗了
else
{}// 成功了
// 寫
if(WriteFile(Handle,buf,len,&dlen,NULL))
{}// 成功了
else 
{}//失敗了

其他的函數(shù)調(diào)用涉及CloseHandle(),DeviceIoControl(),ReadFile(),使用參數(shù)請(qǐng)閱讀MSDN,與讀寫文件并無不同之處。主要要注意的是CreateFile的參數(shù),建議您直接用上邊的示例。我不太清楚每個(gè)參數(shù)的準(zhǔn)確含義,但是我用上邊的參數(shù)總是可以成功。

我不知道有沒有更好的辦法,我見過的驅(qū)動(dòng)主動(dòng)通知應(yīng)用程序的辦法是應(yīng)用程序用一個(gè)線程來讀驅(qū)動(dòng)。驅(qū)動(dòng)把要通知應(yīng)用程序的東西讓應(yīng)用程序讀出。這需要一個(gè)無盡循環(huán)的循環(huán)來讀這個(gè)驅(qū)動(dòng)。當(dāng)無數(shù)據(jù)可讀的時(shí)候可以阻塞。當(dāng)驅(qū)動(dòng)想通知應(yīng)用(如丟出一筆日志)的時(shí)候,寫一些東西讓應(yīng)用程序的ReadFile返回即可。

為了處理io請(qǐng)求我們現(xiàn)在來寫那個(gè)IoDispatch.這個(gè)函數(shù)在WDM驅(qū)動(dòng)中一般稱為分發(fā)例程。這個(gè)函數(shù)在Passive Level運(yùn)行,因此非常安全,幾乎可以調(diào)用絕大部分的系統(tǒng)內(nèi)核服務(wù)。

請(qǐng)結(jié)合下邊的例子,可以看到最簡(jiǎn)單的是IRP_MJ_CREATE和IRP_MJ_CLOSE調(diào)用。如果返回STATUS_SUCCESS則表示成功,STATUS_UNSUCCESSFULE則表示失敗。最簡(jiǎn)單的方法是只讓一個(gè)進(jìn)程打開自己,你可以設(shè)想一下應(yīng)該怎樣實(shí)現(xiàn),并作為一個(gè)小練習(xí)。

這里設(shè)備采用緩沖模式,這是最為簡(jiǎn)單的一種方式,其他方式我們不討論。為了設(shè)置為緩沖模式,我們回到示例代碼5.1,在注冊(cè)設(shè)備之后,加上這句:

m_pDeviceObject->Flags |= DO_BUFFERED_IO;

ReadFile的處理主要是輸出數(shù)據(jù)。用戶提供輸出緩沖及其長(zhǎng)度。你寫入數(shù)據(jù),并說明你寫入的長(zhǎng)度。在IrpStack->Parameters.Read.Length中得到輸出緩沖長(zhǎng)度。數(shù)據(jù)寫入Irp->AssociatedIrp.SystemBuffer中。實(shí)際輸出數(shù)據(jù)長(zhǎng)度請(qǐng)寫到Irp->IoStatus.Information中即可。

WriteFile的處理與ReadFile類似。不用的是Irp->AssociatedIrp.SystemBuffer成了輸入緩沖,而長(zhǎng)度在IrpStack->Parameters.Write.Length中。

DeviceIoControl的情況稍微復(fù)雜,一般先要得到一個(gè)功能碼,用戶程序一般要輸入數(shù)據(jù)(在輸入緩沖中),同時(shí)要獲得輸出(請(qǐng)你寫入輸出緩沖中),并指明了這些緩沖區(qū)的長(zhǎng)度。你還必須指明你輸出數(shù)據(jù)的真實(shí)長(zhǎng)度。

功能碼在IrpStack->Parameters.DeviceIoControl.IoControlCode;
緩沖模式,輸入緩沖長(zhǎng)度為IrpStack->Parameters.DeviceIoControl.InputBufferLength;
緩沖模式,輸出緩沖長(zhǎng)度為IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
共用緩沖區(qū)為Irp->AssociatedIrp.SystemBuffer;
實(shí)際輸出數(shù)據(jù)長(zhǎng)度請(qǐng)寫到Irp->IoStatus.Information中。

用下邊的方法返回失敗最為完整:注意指定了為參數(shù)錯(cuò)誤。你也可以指定其他錯(cuò)誤。請(qǐng)查閱ddk幫助。
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;

用下邊的方法返回成功:
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;

//------------示例4--------------
NTSTATUS IoDispatch(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp)
{
BOOLEAN ret = FALSE;
KIrp I(Irp);
PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);

switch(I.MajorFunction())
{
case IRP_MJ_CREATE:
// 如果有進(jìn)程調(diào)用了CreateFile
ret = TRUE;
break; 
case IRP_MJ_CLOSE:
// 如果有進(jìn)程調(diào)用了CloseFile
ret = TRUE;
break;
case IRP_MJ_CLEANUP:
ret = TRUE;
break;
case IRP_MJ_READ:
// 有進(jìn)程調(diào)用了ReadFile()
ret = FALSE;
break;
case IRP_MJ_WRITE:
// 如果調(diào)用了WriteFile()
ret = FALSE;
break;
case IRP_MJ_DEVICE_CONTROL:
ret = FALSE;
break;
default:
ret = FALSE;
};
if(ret)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
else
{
Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_INVALID_PARAMETER;
}
} 

好,希望我已經(jīng)說明白了驅(qū)動(dòng)與應(yīng)用之間如何交互。如果你還不是很理解,請(qǐng)留意下一章的實(shí)際例子。我們將做一個(gè)簡(jiǎn)單的中間層驅(qū)動(dòng),您可以通過應(yīng)用程序來配置這個(gè)驅(qū)動(dòng)的一些行為(如允許所有的包通過,或是禁止所有包通過)。


第六課 一個(gè)實(shí)際的中間層驅(qū)動(dòng)

第O課中我們已經(jīng)建立了一個(gè)框架,現(xiàn)在在瀏覽幾個(gè)重要的函數(shù)。最重要的是兩個(gè)OnReceive和一個(gè)OnSend.

先看框架生成的第一個(gè)OnRecevie.注意我的工程名為My.

//---------------示例6.1--------------------
NDIS_STATUS MyAdapter::OnReceive
(const KNdisPacket& Original, KNdisPacket& Repackaged)
{
TRACE("MyAdapter::OnReceive() %u bytesn", Original.QueryTotalLength());
HEADER* Content = (HEADER*) Original.QueryFirstBuffer();
Repackaged.CloneUp(Original);
return NDIS_STATUS_SUCCESS;
}

這個(gè)函數(shù)似乎比較好理解。當(dāng)計(jì)算機(jī)接受到網(wǎng)絡(luò)數(shù)據(jù)包的時(shí)候,我們的OnReceive被調(diào)用。Original是就是數(shù)據(jù)包。請(qǐng)結(jié)合第一課中的內(nèi)容。KNdisPacket是一個(gè)網(wǎng)絡(luò)數(shù)據(jù)包,但是其實(shí)際內(nèi)容放在KNdisBuffer中。一個(gè)KNdisPacket擁有一個(gè)KNdisBuffer鏈。

KNdisBuffer可以直接轉(zhuǎn)成任何地址來使用,也可以用KNdisBuffer::Address()來得到地址。

那么如上邊的示例,Original.QueryFirstBuffer()得到數(shù)據(jù)包頭。

注意,第一個(gè)緩沖區(qū)的長(zhǎng)度至少為14個(gè)字節(jié)(其實(shí)我并不這么肯定,但是我每次都恰好至少得到了14個(gè)字節(jié)),但是不要指望第一個(gè)KNdisBuffer就直接幫你搞定后邊的ip頭,tcp頭數(shù)據(jù)。一個(gè)鏈?zhǔn)降慕Y(jié)構(gòu)非常的不好處理,所以我建議費(fèi)點(diǎn)力氣把頭的部分復(fù)制到一個(gè)連續(xù)緩沖區(qū)中。一般都處理到tcp頭即可,也不過14+20+20才54個(gè)字節(jié)。拷貝起來是不費(fèi)多少資源的。

假設(shè)有一個(gè)KNdisPacket Packet,你可以用下邊的例子把前54個(gè)字節(jié)的數(shù)據(jù)拷貝到MyAheadBuf中。

//----------------示例6.2---------------------
UINT nBufCnt = Packet.QueryBufferCount();
KNdisBuffer Buf = Packet.QueryFirstBuffer();
if (!Buf.IsValid())
return;


unsigned char MyAheadBuf[14+20+20];
unsigned long MyAheadBufLen = 0,WantLen = 14+20+20;

// 拷貝足夠的長(zhǎng)度
while(WantLen > MyAheadBufLen)
{
if(WantLen - MyAheadBufLen > Buf.Length())
{
memcpy(&MyAheadBuf[MyAheadBufLen],Buf.Address(),Buf.Length());
MyAheadBufLen += Buf.Length();
Buf = Buf.GetNext();
if(!Buf.IsValid())
break;
}
else
{
memcpy(&MyAheadBuf[MyAheadBufLen],Buf.Address(),WantLen-MyAheadBufLen);
MyAheadBufLen = WantLen;
} 
} 


不幸的是并不是所有的計(jì)算機(jī)上都只調(diào)用上一個(gè)OnRecevie.另一個(gè)可能被調(diào)用的OnReceive函數(shù)如下。這可能和下層的微端口驅(qū)動(dòng)的特性有關(guān)。下邊這個(gè)函數(shù)HeaderBuffer是以太網(wǎng)包頭,長(zhǎng)度一般為14.LookAheadBuffer是以太網(wǎng)包頭之后的部分,如果這是個(gè)ip包,那就是ip頭了。我們能否驅(qū)動(dòng)到我們關(guān)心的ip頭和tcp頭?這需要LookAheadBufferLength至少為40.我認(rèn)為L(zhǎng)ookAheadBufferLength長(zhǎng)度至少為40.因?yàn)槲宜坪踹€沒有發(fā)現(xiàn)過少于40的情況。

如果不是,請(qǐng)發(fā)郵件給我MFC_Tan_Wen@163.com,非常感謝。

這導(dǎo)致我們可以直接用LookAheadBuffer來得到足夠的信息做大多數(shù)的工作。但是并不總是這樣的。比如我要對(duì)整個(gè)數(shù)據(jù)包加密,我有必要得到整個(gè)數(shù)據(jù)包。但是LookAheadBuffer可能小于PacketSize.這種情況,你必須調(diào)用TransferData()函數(shù),并在MyAdpater::OnTransferComplete()中處理這個(gè)數(shù)據(jù)包。但是OnTransferComplete()這種情況恰好和上一種OnReceive()的情況類似,所以這里不再詳述了。

//------------------示例6.3---------------------------
NDIS_STATUS MyAdapter::OnReceive(
IN OUT KNdisPartialPacket& PacketToAccept, 
IN PVOID HeaderBuffer, IN UINT HeaderBufferSize,
IN PVOID LookAheadBuffer, IN UINT LookaheadBufferSize,
IN UINT PacketSize)
{ 
TRACE("MyAdapter::OnReceive() Partial %u/%u%/%u bytesn",
HeaderBufferSize, LookaheadBufferSize, PacketSize);
UNREFERENCED_PARAMETER(PacketToAccept);
return NDIS_STATUS_SUCCESS;
}

OnSend()在有數(shù)據(jù)包發(fā)出的情況下被調(diào)用,處理方法應(yīng)該與第一種OnReceive的方法相同。

如果我想阻止數(shù)據(jù)包的接收或者發(fā)送,我直接return NNDIS_STATUS_NOT_ACCEPTED即可。并且我不向上或者向下復(fù)制數(shù)據(jù)包。

請(qǐng)定義一個(gè)全局的變量BOOLEAN Allow.并假定Allow如果為TRUE,我則不干涉所有數(shù)據(jù)包的發(fā)送接受。而如果為FALSE,我丟棄接收到的所有數(shù)據(jù)包,并阻止所有的發(fā)送包。

回到示例6.1,內(nèi)容應(yīng)該改為
TRACE("MyAdapter::OnReceive() %u bytesn", Original.QueryTotalLength());
if(Allow)
{ 
HEADER* Content = (HEADER*) Original.QueryFirstBuffer();
Repackaged.CloneUp(Original);
return NDIS_STATUS_SUCCESS;
}
else
return NDIS_STATUS_NOT_ACCEPTED;

其他的兩個(gè)函數(shù)請(qǐng)自己修改。

現(xiàn)在的問題是我必須用應(yīng)用程序來設(shè)置這個(gè)變量。以便控制我的網(wǎng)絡(luò)是否連通。這樣的一個(gè)防火墻只有兩個(gè)選項(xiàng),全開或者全關(guān),當(dāng)然這是一個(gè)無實(shí)際用處的防火墻。

回到上一章節(jié)的敘述,我們?cè)谶@個(gè)驅(qū)動(dòng)中加入注冊(cè)一個(gè)WDM設(shè)備。但是僅僅做了上邊的事情無法通過編譯。DriverNetworks的幫助指出,要注冊(cè)WDM設(shè)備必須在向?qū)е羞x中NDIS WDM選項(xiàng)。但是實(shí)際上只有微端口驅(qū)動(dòng)才有這個(gè)選項(xiàng)。因此必須用我下邊所說的方法:

首先包含頭文件<kndisvdw.h>。然后編譯預(yù)定義宏定義增加這幾個(gè):NTVERSION='WDM',NDIS_WDM=1.此時(shí)編譯ok,但是連接未必能搞定。

為此建議建立一個(gè)微端口驅(qū)動(dòng),選中wdm,編譯過程中會(huì)跳出來要你編譯很多l(xiāng)ib,這時(shí)全部編譯之即可。

回頭來,您的中間層驅(qū)動(dòng)已經(jīng)成功的加入了WDM設(shè)備。

現(xiàn)在考慮如何用WDM設(shè)備來控制開與斷。我設(shè)計(jì)一個(gè)DeviceIoCtrl來做這個(gè)事情:

定義:
#define IOCTL_SET_NET_OPEN_OR_CLOSE CTL_CODE(
FILE_DEVICE_UNKNOWN,
0x802,
METHOD_BUFFERED,
FILE_ANY_ACCESS)

這個(gè)指令帶一個(gè)字節(jié)的參數(shù)保存在輸入緩沖中。如果為0則全斷,反之全開。

然后修改IoDispatch函數(shù),加入以下的處理:

...
ULONG ControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;
ULONG InputLength = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
ULONG OutputLength = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(ControlCode)
{
case IOCTL_SET_NET_OPEN_OR_CLOSE:
{
// 主要的任務(wù)是首先檢查長(zhǎng)度是否足夠
if( 1 > OutputLength)
{
ret = FALSE;
break;;
}
// 得到輸入?yún)?shù)并設(shè)置自己全開全閉
UCHAR cAllow = *((UCHAR *)Irp->AssociatedIrp.SystemBuffer);
Allow = (cAllow==0)?FALSE:TRUE;
DWW_RULE_S *pDst = (DWW_RULE_S *)Buffer;
Irp->IoStatus.Information
ret = TRUE;
break;
}
...
} 

至于應(yīng)用程序如何調(diào)用DeviceIoControl,請(qǐng)參照上一課的例子。

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號(hào) Ctrl + =
減小字號(hào) Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91麻豆免费观看| 精品剧情在线观看| 日韩欧美高清dvd碟片| 中文字幕日韩一区| 久久疯狂做爰流白浆xx| 欧美视频在线观看一区二区| 久久夜色精品国产噜噜av| 亚洲一二三区视频在线观看| 国产成人精品免费视频网站| 日韩亚洲电影在线| 亚洲超碰精品一区二区| 99精品热视频| 国产亚洲精久久久久久| 麻豆91在线播放| 欧美丰满嫩嫩电影| 亚洲午夜激情av| 在线视频亚洲一区| 亚洲天堂精品视频| proumb性欧美在线观看| 久久精品日韩一区二区三区| 久久99久久精品欧美| 欧美情侣在线播放| 亚洲最快最全在线视频| 色综合咪咪久久| 亚洲女女做受ⅹxx高潮| 91网站最新地址| 中文字幕色av一区二区三区| 国产激情精品久久久第一区二区| 精品日韩一区二区三区免费视频| 蜜臀av在线播放一区二区三区| 91国偷自产一区二区开放时间 | 日韩欧美电影一区| 日本不卡一区二区三区| 制服丝袜在线91| 视频一区二区三区入口| 91精品综合久久久久久| 视频一区二区欧美| 欧美videos中文字幕| 美女视频一区二区| 久久综合九色综合欧美98| 国产精品资源在线| 国产精品久久久久影视| 日本高清成人免费播放| 一区二区视频在线| 在线观看网站黄不卡| 亚洲成av人片一区二区三区| 日韩视频在线一区二区| 国产麻豆视频一区二区| 国产精品久99| 欧美日韩视频一区二区| 美女视频黄频大全不卡视频在线播放| 欧美电影免费观看高清完整版 | 99久精品国产| 亚洲已满18点击进入久久| 国产一区二区三区免费看| 在线视频国内自拍亚洲视频| 一区二区三区日韩欧美| 在线观看一区二区精品视频| 天天操天天综合网| 2017欧美狠狠色| av午夜一区麻豆| 婷婷开心久久网| 久久久99久久| 91成人在线精品| 蜜臀国产一区二区三区在线播放| 国产亚洲污的网站| 久久综合久久久久88| 成人美女视频在线观看| 亚洲资源中文字幕| 久久综合网色—综合色88| 成人av集中营| 蜜桃91丨九色丨蝌蚪91桃色| 国产精品不卡在线| 欧美电影免费观看高清完整版在| 成人久久久精品乱码一区二区三区| 亚洲综合av网| 国产精品卡一卡二| 欧美电影免费观看高清完整版在线| av不卡一区二区三区| 麻豆一区二区99久久久久| 亚洲精品美国一| 欧美国产精品久久| 7777精品久久久大香线蕉| av在线这里只有精品| 久久成人免费网| 亚洲va欧美va国产va天堂影院| 亚洲国产激情av| 日韩精品一区二区三区蜜臀| 欧美三区免费完整视频在线观看| 国产高清在线精品| 极品少妇一区二区| 视频精品一区二区| 亚洲精品第1页| 国产精品福利影院| 国产婷婷一区二区| 日韩欧美一区二区视频| 欧美亚洲另类激情小说| 91在线播放网址| 大陆成人av片| 国产成人激情av| 国产麻豆午夜三级精品| 久久99精品久久久久婷婷| 亚洲.国产.中文慕字在线| 亚洲一区欧美一区| 一区二区三区不卡在线观看 | 欧美亚洲综合色| 99re成人在线| 成人激情av网| 粉嫩绯色av一区二区在线观看| 国产乱色国产精品免费视频| 男人的j进女人的j一区| 日韩国产精品大片| 欧美a级一区二区| 日韩av电影免费观看高清完整版| 亚洲va欧美va国产va天堂影院| 午夜视频在线观看一区| 五月综合激情网| 伦理电影国产精品| 国精产品一区一区三区mba桃花| 看电影不卡的网站| 国产伦精品一区二区三区免费| 久久丁香综合五月国产三级网站 | 成人免费视频一区| 成人免费看片app下载| 成人午夜伦理影院| 色狠狠色噜噜噜综合网| 欧美一a一片一级一片| 欧美一区二区在线视频| 日韩欧美在线1卡| 国产午夜精品一区二区| 亚洲欧美日韩成人高清在线一区| 亚洲免费观看在线观看| 亚洲午夜精品在线| 狠狠网亚洲精品| 99久久99精品久久久久久 | 成人v精品蜜桃久久一区| 99国产麻豆精品| 欧美日本不卡视频| 精品噜噜噜噜久久久久久久久试看 | 亚洲电影视频在线| 午夜精品国产更新| 韩国午夜理伦三级不卡影院| 波多野结衣中文一区| 欧美日韩小视频| 国产亚洲美州欧州综合国| 中文字幕制服丝袜一区二区三区 | 中文字幕亚洲一区二区av在线| 亚洲女女做受ⅹxx高潮| 日韩高清国产一区在线| 成人午夜激情在线| 欧美精品粉嫩高潮一区二区| 久久精品无码一区二区三区| 亚洲精品写真福利| 国产美女精品一区二区三区| 欧洲生活片亚洲生活在线观看| 欧美一区二区精品在线| 综合婷婷亚洲小说| 久久99久久精品| 在线一区二区三区四区| 精品国产凹凸成av人网站| 一区二区欧美在线观看| 国产裸体歌舞团一区二区| 欧美日韩精品三区| 国产精品理伦片| 久久精品国产亚洲a| 欧美综合久久久| 中文字幕日韩一区| 精品一区二区三区久久久| 欧美日韩你懂的| 亚洲天堂av老司机| 国产成人免费视频精品含羞草妖精 | 久久伊人中文字幕| 日日骚欧美日韩| 日本高清不卡在线观看| 国产精品天干天干在观线| 麻豆精品一区二区三区| 欧美日韩久久一区二区| 亚洲日本丝袜连裤袜办公室| 国产一区二区美女诱惑| 91精品国产综合久久香蕉麻豆| 亚洲精品少妇30p| aaa欧美大片| 国产精品久久久久久久浪潮网站 | 不卡的av电影在线观看| 久久精品国产免费看久久精品| 国产激情一区二区三区| 4438x亚洲最大成人网| 亚洲伦理在线免费看| 成人精品电影在线观看| 久久久蜜桃精品| 国产乱子轮精品视频| 日韩欧美一区二区视频| 日韩成人一级片| 欧美一区二区三区视频在线| 亚洲高清久久久| 欧美视频第二页| 日韩影院免费视频| 8v天堂国产在线一区二区| 亚州成人在线电影| 欧美一区二区三区免费在线看 |