史萊姆論壇

返回   史萊姆論壇 > 教學文件資料庫 > 程式 & 網頁設計技術文件
忘記密碼?
論壇說明

歡迎您來到『史萊姆論壇』 ^___^

您目前正以訪客的身份瀏覽本論壇,訪客所擁有的權限將受到限制,您可以瀏覽本論壇大部份的版區與文章,但您將無法參與任何討論或是使用私人訊息與其他會員交流。若您希望擁有完整的使用權限,請註冊成為我們的一份子,註冊的程序十分簡單、快速,而且最重要的是--註冊是完全免費的!

請點擊這裡:『註冊成為我們的一份子!』

Google 提供的廣告


 
 
主題工具 顯示模式
舊 2003-12-14, 08:26 PM   #1 (permalink)
榮譽會員
 
psac 的頭像
榮譽勳章
UID - 3662
在線等級: 級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時級別:30 | 在線時長:1048小時 | 升級還需:37小時
註冊日期: 2002-12-07
住址: 木柵市立動物園
文章: 17381
現金: 5253 金幣
資產: 33853 金幣
預設 UDP和socket函數

關鍵字 socket udp
原作者姓名 Fang

正文

以下討論關於Winsock2我的文件。

UDP是一個無連接的傳輸協定,因此socket函數connect似乎對UDP是沒有意義的,
然而事實不是這樣。

一個插口有幾個內容,其中包括傳輸協定,近端網址/連接埠,目的位址/連接埠。

對於UDP來說,socket函數建立一個插口;bind函數指明了近端網址/連接埠
(包括ADDR_ANY,通配所有本機網路接頭);connect可以用來指明目的地
址/連接埠;

一般來說,UDP客戶端在建立了插口後會直接用sendto函數傳送資料,需要
在sendto函數的參數里指明目的位址/連接埠。如果一個UDP客戶端在建立了插
口後首先用connect函數指明了目的位址/連接埠,然後也可以用send函數接受
資料,因為此時send函數已經知道對方位址/連接埠,用getsockname也可以得
到這個信息。

UDP客戶端在建立了插口後會直接用sendto函數傳送資料,還隱含了一個操作,
那就是在傳送資料之前,UDP會首先為該插口選項一個獨立的UDP連接埠(在1024
-5000之間),將該插口置為已綁定狀態。如果一個UDP客戶端在建立了插口後
首先用bind函數指明了近端網址/連接埠,也是可以的,這樣可以強迫UDP使用指
定的連接埠傳送資料。(事實上,UDP無所謂伺服器和客戶端,這裡的界限已經模
糊了。)

UDP伺服器也可以使用connect,如上面所述,connect可以用來指明目的位址
/連接埠;這將導致伺服器只接受特定一個主機的請求。




驅動程式和應用程式之間通信(For Win2000 or later version)  作者 Fang

關鍵字 驅動 套用 通信


文章原始出處 根據網上一些資料整理。

正文
Q:
請問有什麼方法實現驅動程式主動和應用程式進行既時通訊,而不用應用程式採用定時查詢的方法?
比如驅動有一事件發生需要立即通知應用程式,或驅動程式需要像應用程式讀取一些內容.

A:
有一個很容易的方式,在驅動程式和應用程式之間用一個事件。
在應用程式CreateFile的時候,驅動程式IoCreateSynchronizationEvent一個有名的事件,然後應用程式CreateEvent/OpenEvent此有名事件即可。
注意點:
1,不要在驅動啟始化的時候新增事件,此時大多不能成功新增;
2,讓驅動先新增,那麼此後應用程式開啟時,只能讀(Waitxxxx),不能寫(SetEvent/ResetEvent)。反之,如果應用程式先新增,則應用程式和驅動程式都有讀寫權限;
3,用名字比較理想,注意驅動中名字在\BaseNamedObjects\下,例如應用程式用「xxxEvent」,那麼驅動中就是「\BaseNamedObjects\xxxEvent」;
4,用HANDLE的方式也可以,但是在WIN98下是否可行,未知。
5,此後,驅動對讀請求應立即返回,否則就返回失敗。不然將失去用事件通知的意義(不再等待讀完成,而是有需要(通知事件)時才會讀);
6,應用程式發現有事件,應該在一個循環中讀取,直到讀取失敗,表明沒有資料可讀;否則會漏掉後續資料,而沒有及時讀取;

Sample Code:


// Describe the share memory.
typedef struct _PKT_BUFFER
{
PMDL BufferMdl;
PVOID UserBaseAddress;
PVOID KernelBaseAddress;
}PKT_BUFFER, *PPKT_BUFFER;

typedef struct _SHARE_EVENT_CONTEXT
{
WCHAR EventName[128]; // Event name, the only connection btw ring0/ring3
HANDLE Win32EventHandle; // Ring3 copy of the event handle
HANDLE DriverEventHandle; // Ring0 copy of the event handle
PVOID DriverEventObject; // The event object
}SHARE_EVENT_CONTEXT, *PSHARE_EVENT_CONTEXT;


BOOLEAN CreateShareMemory(PPKT_BUFFER PktBuffer, ULONG Size)
{
PktBuffer->KernelBaseAddress = ExAllocatePoolWithTag(NonPagedPool,
Size,
'MpaM');

if(!PktBuffer->KernelBaseAddress)
return FALSE;

//
// Allocate and initalize an MDL that describes the buffer
//
PktBuffer->BufferMdl = IoAllocateMdl(PktBuffer->KernelBaseAddress,
Size,
FALSE,
FALSE,
NULL);

if(!PktBuffer->BufferMdl)
{
ExFreePool(PktBuffer->KernelBaseAddress);
PktBuffer->KernelBaseAddress =NULL;
return FALSE;
}

MmBuildMdlForNonPagedPool(PktBuffer->BufferMdl);

DEBUGP(DL_INFO, ("CreateShareMemory: KernelBaseAddress = 0x%p\n", PktBuffer->KernelBaseAddress));

return TRUE;
}

VOID DestroyShareMemory(PPKT_BUFFER PktBuffer)
{
if(PktBuffer->BufferMdl)
{
IoFreeMdl(PktBuffer->BufferMdl);
PktBuffer->BufferMdl = NULL;
}

if(PktBuffer->KernelBaseAddress)
{
ExFreePool(PktBuffer->KernelBaseAddress);
PktBuffer->KernelBaseAddress = NULL;
}
}

//This function works in user dispatch code.
BOOLEAN MapSharedMemory(PPKT_BUFFER PktBuffer)
{
if(!PktBuffer->BufferMdl)
return FALSE;

//
// The preferred V5 way to map the buffer into user space
//
PktBuffer->UserBaseAddress =
MmMapLockedPagesSpecify快取(PktBuffer->BufferMdl, // MDL
UserMode, // Mode
Mm快取d, // Caching
NULL, // Address
FALSE, // Bugcheck?
NormalPagePriority); // Priority

if(!PktBuffer->UserBaseAddress)
return FALSE;

DEBUGP(DL_INFO, ("MapSharedMemory SUCCESS, UserBaseAddress %p\n", PktBuffer->UserBaseAddress));
return TRUE;
}

VOID UnmapSharedMemory(PPKT_BUFFER PktBuffer)
{
if(PktBuffer->UserBaseAddress)
{
MmUnmapLockedPages(PktBuffer->UserBaseAddress, PktBuffer->BufferMdl);
PktBuffer->UserBaseAddress = NULL;
}
}

BOOLEAN CreateShareEvent(PSHARE_EVENT_CONTEXT ShareEvent)
{
UNICODE_STRING UnicodeName;
WCHAR UnicodeBuffer[128] = L"\\BaseNamedObjects\\";

RtlInitUnicodeString(&UnicodeName, UnicodeBuffer);
UnicodeName.MaximumLength = 128;
RtlAppendUnicodeToString(&UnicodeName, ShareEvent->EventName);

ShareEvent->DriverEventObject = IoCreateSynchronizationEvent(&UnicodeName,
&ShareEvent->DriverEventHandle);

if(ShareEvent->DriverEventObject == NULL)
{
ShareEvent->DriverEventHandle = NULL;
DEBUGP(DL_INFO, ("CreateSynchronizationEvent FAILED Name=%ws\n", UnicodeBuffer));
return FALSE;
}
else
{
KeClearEvent(ShareEvent->DriverEventObject);

DEBUGP(DL_INFO, ("CreateSynchronizationEvent SUCCESS Name=%ws DriverEventObject=%p, DriverEventHandle=%u\n",
UnicodeBuffer,
ShareEvent->DriverEventObject,
ShareEvent->DriverEventHandle));

return TRUE;
}
}

VOID DestroyShareEvents(PSHARE_EVENT_CONTEXT ShareEvent)
{
if(ShareEvent->DriverEventHandle)
{
ZwClose(ShareEvent->DriverEventHandle);
ShareEvent->DriverEventObject = NULL;
ShareEvent->DriverEventHandle = NULL;
}
}
psac 目前離線  
送花文章: 3, 收花文章: 1631 篇, 收花: 3205 次
 



發表規則
不可以發文
不可以回覆主題
不可以上傳附加檔案
不可以編輯您的文章

論壇啟用 BB 語法
論壇啟用 表情符號
論壇啟用 [IMG] 語法
論壇禁用 HTML 語法
Trackbacks are 禁用
Pingbacks are 禁用
Refbacks are 禁用


所有時間均為台北時間。現在的時間是 10:33 AM


Powered by vBulletin® 版本 3.6.8
版權所有 ©2000 - 2024, Jelsoft Enterprises Ltd.


SEO by vBSEO 3.6.1