LSP(分層服務提供者)

2021-09-06 06:33:30 字數 4674 閱讀 4818

lsp本身是dll,可以將它安裝到winsock目錄,以便建立套接字的應用程式不必知道此lsp的任何資訊就能呼叫它。

執行原理:

套接字建立函式會在winsock目錄中尋找合適的協議

呼叫此協議,的提供者匯出的函式 完成各種功能。

編寫目的:

讓使用者呼叫自定義的服務提供者,有自定義的服務提供者呼叫下層提供者。這樣便截獲所有的winsock呼叫了。

服務提供者本身是dll,匯出一些與winsock api相對應的spi函式。winsock庫載入服務提供者時,便依靠這些函式來實現winsockapi。

lsp也是如此,它向上匯出所有的spi函式供 ws2_32.dll呼叫,在內部通過呼叫基礎提供者實現這些spi。

安裝lsp:

協議鏈:

協議鏈描述了 分層提供者 加入winsock的目錄的順序。

typedef struct

_wsaprotocolchainwsaprotocolchain,*lpwsaprotocolchain;

chainlen為0:分層協議  為1 基礎協議   大於1 協議鏈

當chainlen為0或者1時,chainentries陣列無意義

大於1時,各個服務提供者的目錄id就包含在陣列中。

實現lsp的dll要麼被另乙個lsp載入,要麼直接被ws2_32.dll載入。取決於它的位置。

如果lsp沒有在協議鏈的頂端,就會被鏈中位於它上層的lsp載入,否則的話,將被ws2_32.dll載入。

安裝lsp時,必須在winsock目錄中安裝兩種協議:乙個分層協議,乙個協議鏈

安裝分層協議視為了獲取winsock庫分配的目錄id號,一邊在協議鏈中標識自己的位置。

協議鏈才是winsock目錄中lsp的真正入口,連中包含了自己分層協議的目錄id號和下層提供者的目錄id號。

在安裝時,要先安裝乙個分層協議,用系統分配給此分層協議的目錄id和下層提供者的目錄id構建乙個chainentries陣列,進而構建乙個wsaprotocol_infow結構,然後再安裝這個協議鏈。

安裝函式:

提供lsp guid dll wsaprotocol_infow結構便可。

int

wscinstallprovider(

const

lpguid lpproviderid,

const

lpwstr lpszproviderdllpath,

const

lpwsaprotocol_infow lpprotocolinfolist,

dword dwnumberofentries,

lpint lperrno

);

每乙個安裝提供者需要乙個guid來標識它的入口,guid可以通過命令列工具uuidgen或者在程式設計使用uuidcreate函式來生成。

lsp的wsaprotocol_infow結構通常從它要分層的下層提供者拷貝

1 szprotocol域要修改,以包含新提供者的名稱

2 如果包含xp1_ifs_handles標識,要從dwserviceflags1域移除。

重新目錄排序  wscwriteproviderorder

新安裝的lsp會預設安裝到winsock目錄的結尾,這樣系統呼叫的時候,還是會呼叫原先呼叫的lsp,因此只有進行重新的排序才能讓系統呼叫到新安裝的lsp。

總結:

1 安裝分層協議入口,以便獲取系統分配的目錄id號。

2 安裝乙個或者多個協議鏈,安裝的數量取決於要分層的下層協議的數量。

3 在結尾進行目錄排序。

示例**:

//

////

instdemo.cpp

#include

#include

//定義了wscwriteproviderorder函式

#include

#include

#pragma comment(lib, "ws2_32.lib")

#pragma comment(lib, "rpcrt4.lib") //

實現了uuidcreate函式

//要安裝的lsp的硬編碼,在移除的時候還要使用它

guid providerguid = };

lpwsaprotocol_infow getprovider(lpint lpntotalprotocols)

pprotoinfo =(lpwsaprotocol_infow)::globalalloc(gptr, dwsize);

*lpntotalprotocols = ::wscenumprotocols(null, pprotoinfo, &dwsize, &nerror);

return

pprotoinfo;

}void

freeprovider(lpwsaprotocol_infow pprotoinfo)

//將lsp安裝到udp協議提供者之上

int installprovider(wchar *wszdllpath)

} //首先安裝分層協議,獲取乙個winsock庫安排的目錄id號,即dwlayeredcatalogid

//直接使用下層協議的wsaprotocol_infow結構即可

memcpy(&udplayeredinfo, &udpchaininfo, sizeof

(udplayeredinfo));

//修改協議名稱,型別,設定pfl_hidden標誌

wcscpy(udplayeredinfo.szprotocol, wszlspname);

udplayeredinfo.protocolchain.chainlen = layered_protocol; //

layered_protocol即0

udplayeredinfo.dwproviderflags |=pfl_hidden;

//安裝

if(::wscinstallprovider(&providerguid,

wszdllpath, &udplayeredinfo, 1, &nerror) ==socket_error)

return

nerror;

//重新列舉協議,獲取分層協議的目錄id號

freeprovider(pprotoinfo);

pprotoinfo = getprovider(&nprotocols);

for(i=0; i)

}//安裝協議鏈

//修改協議名稱,型別

wchar wszchainname[wsaprotocol_len + 1

]; swprintf(wszchainname, l

"%ws over %ws

", wszlspname, udpchaininfo.szprotocol);

wcscpy(udpchaininfo.szprotocol, wszchainname);

if(udpchaininfo.protocolchain.chainlen == 1

)

else

}udpchaininfo.protocolchain.chainlen ++;

//將我們的分層協議置於此協議鏈的頂層

udpchaininfo.protocolchain.chainentries[0] =dwlayeredcatalogid;

//獲取乙個guid,安裝之

guid providerchainguid;

if(::uuidcreate(&providerchainguid) ==rpc_s_ok)

else

return

getlasterror();

//重新排序winsock目錄,將我們的協議鏈提前

//重新列舉安裝的協議

freeprovider(pprotoinfo);

pprotoinfo = getprovider(&nprotocols);

dword dwids[

20];

int nindex = 0

;

//新增我們的協議鏈

for(i=0; i)

//新增其它協議

for(i=0; i)

//重新排序winsock目錄

nerror =::wscwriteproviderorder(dwids, nindex);

freeprovider(pprotoinfo);

return

nerror;

}void

removeprovider()

}if(i }

//移除分層協議

::wscdeinstallprovider(&providerguid, &nerror);

}}///

/int binstall = 0

;void

main()

else

}else

removeprovider();

}

LSP(分層服務提供程式)

一 簡介 二 lsp操作 netsh winsockoption 顯示命令列表。audit 顯示已經安裝和刪除的 winsock lsp 列表。dump 顯示乙個配置指令碼。help 顯示命令列表。remove 從系統中刪除 winsock lsp。reset 重置 winsock 目錄為清除狀態。...

服務提供者 order

本節課我們來實現服務提供者 orde,order 為系統提供訂單相關服務,包括新增訂單 查詢訂單 刪除訂單 處理訂單,具體實現如下所示。1.在父工程下建立乙個 module,命名為 order,pom.xml 新增相關依賴,order 需要訪問資料庫,所以整合 mybatis 相關依賴,配置檔案從 ...

建立服務提供者

當 client 向 server 註冊時,它會提供一些元資料,例如主機和埠,url,主頁等。eureka server 從每個 client 例項接收心跳訊息。如果心跳超時,則通常將該例項從註冊 server 中刪除。通過註解 enableeurekaclient表明自己是乙個 eureka cl...