void main() { int nTotalProtocols; LPWSAPROTOCOL_INFO pProtoInfo = GetProvider(&nTotalProtocols); if(pProtoInfo != NULL) { // 打印出各个提供者的协议信息 for(int i=0; i<nTotalProtocols; i++) { printf(" Protocol: %s \n", pProtoInfo[i].szProtocol); printf(" CatalogEntryId: %d ChainLen: %d \n\n", pProtoInfo[i].dwCatalogEntryId, pProtoInfo[i].ProtocolChain.ChainLen); } FreeProvider(pProtoInfo); } }
int WSPAPI WSPStartup( WORD wVersionRequested, LPWSPDATA lpWSPData, LPWSAPROTOCOL_INFO lpProtocolInfo, WSPUPCALLTABLE UpcallTable, LPWSPPROC_TABLE lpProcTable ) { int i; ODS1(L"WSPStartup... %s \n", g_szCurrentApp); if(lpProtocolInfo->ProtocolChain.ChainLen <= 1) { return WSAEPROVIDERFAILEDINIT; } g_pUpCallTable = UpcallTable; WSAPROTOCOL_INFOW NextProtocolInfo; int nTotalProtos; LPWSAPROTOCOL_INFOW pProtoInfo = GetProvider(&nTotalProtos); DWORD dwBaseEntryId = lpProtocolInfo->ProtocolChain.ChainEntries[1]; for(i=0; i<nTotalProtos; i++) { if(pProtoInfo[i].dwCatalogEntryId == dwBaseEntryId) { memcpy(&NextProtocolInfo, &pProtoInfo[i], sizeof(NextProtocolInfo)); break; } } if(i >= nTotalProtos) { ODS(L" WSPStartup: Can not find underlying protocol \n"); return WSAEPROVIDERFAILEDINIT; } int nError; TCHAR szBaseProviderDll[MAX_PATH]; int nLen = MAX_PATH; if(::WSCGetProviderPath(&NextProtocolInfo.ProviderId, szBaseProviderDll, &nLen, &nError) == SOCKET_ERROR) { ODS1(L" WSPStartup: WSCGetProviderPath() failed %d \n", nError); return WSAEPROVIDERFAILEDINIT; } if(!::ExpandEnvironmentStrings(szBaseProviderDll, szBaseProviderDll, MAX_PATH)) { ODS1(L" WSPStartup: ExpandEnvironmentStrings() failed %d \n", ::GetLastError()); return WSAEPROVIDERFAILEDINIT; } HMODULE hModule = ::LoadLibrary(szBaseProviderDll); if(hModule == NULL) { ODS1(L" WSPStartup: LoadLibrary() failed %d \n", ::GetLastError()); return WSAEPROVIDERFAILEDINIT; } LPWSPSTARTUP pfnWSPStartup = NULL; pfnWSPStartup = (LPWSPSTARTUP)::GetProcAddress(hModule, "WSPStartup"); if(pfnWSPStartup == NULL) { ODS1(L" WSPStartup: GetProcAddress() failed %d \n", ::GetLastError()); return WSAEPROVIDERFAILEDINIT; } LPWSAPROTOCOL_INFOW pInfo = lpProtocolInfo; if(NextProtocolInfo.ProtocolChain.ChainLen == BASE_PROTOCOL) pInfo = &NextProtocolInfo; int nRet = pfnWSPStartup(wVersionRequested, lpWSPData, pInfo, UpcallTable, lpProcTable); if(nRet != ERROR_SUCCESS) { ODS1(L" WSPStartup: underlying provider's WSPStartup() failed %d \n", nRet); return nRet; } g_NextProcTable = *lpProcTable; lpProcTable->lpWSPSocket = WSPSocket; lpProcTable->lpWSPCloseSocket = WSPCloseSocket; lpProcTable->lpWSPConnect = WSPConnect; lpProcTable->lpWSPAccept = WSPAccept; lpProcTable->lpWSPSend = WSPSend; lpProcTable->lpWSPSendTo = WSPSendTo; lpProcTable->lpWSPRecv = WSPRecv; lpProcTable->lpWSPRecvFrom = WSPRecvFrom; lpProcTable->lpWSPAddressToString = WSPAddressToString; lpProcTable->lpWSPAsyncSelect = WSPAsyncSelect; lpProcTable->lpWSPBind = WSPBind; lpProcTable->lpWSPCancelBlockingCall = WSPCancelBlockingCall; lpProcTable->lpWSPCleanup = WSPCleanup; lpProcTable->lpWSPDuplicateSocket = WSPDuplicateSocket; lpProcTable->lpWSPEnumNetworkEvents = WSPEnumNetworkEvents; lpProcTable->lpWSPEventSelect = WSPEventSelect; lpProcTable->lpWSPGetOverlappedResult = WSPGetOverlappedResult; lpProcTable->lpWSPGetPeerName = WSPGetPeerName; lpProcTable->lpWSPGetQOSByName = WSPGetQOSByName; lpProcTable->lpWSPGetSockName = WSPGetSockName; lpProcTable->lpWSPGetSockOpt = WSPGetSockOpt; lpProcTable->lpWSPIoctl = WSPIoctl; lpProcTable->lpWSPJoinLeaf = WSPJoinLeaf; lpProcTable->lpWSPListen = WSPListen; lpProcTable->lpWSPRecvDisconnect = WSPRecvDisconnect; lpProcTable->lpWSPSelect = WSPSelect; lpProcTable->lpWSPSendDisconnect = WSPSendDisconnect; lpProcTable->lpWSPSetSockOpt = WSPSetSockOpt; lpProcTable->lpWSPShutdown = WSPShutdown; lpProcTable->lpWSPStringToAddress = WSPStringToAddress; FreeProvider(pProtoInfo); return nRet; }
BOOL InstallProvider(WCHAR *pwszPathName) { WCHAR wszLSPName[] = L"PhoenixLSP"; LPWSAPROTOCOL_INFOW pProtoInfo; int nProtocols; WSAPROTOCOL_INFOW OriginalProtocolInfo[3]; DWORD dwOrigCatalogId[3]; int nArrayCount = 0; DWORD dwLayeredCatalogId; // 我们分层协议的目录ID号 int nError; // 找到我们的下层协议,将信息放入数组中 // 枚举所有服务程序提供者 pProtoInfo = GetProvider(&nProtocols); BOOL bFindUdp = FALSE; BOOL bFindTcp = FALSE; BOOL bFindRaw = FALSE; int i=0; for(i; i<nProtocols; i++) { if(pProtoInfo[i].iAddressFamily == AF_INET) { if(!bFindUdp && pProtoInfo[i].iProtocol == IPPROTO_UDP) { memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW)); OriginalProtocolInfo[nArrayCount].dwServiceFlags1 = OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId; bFindUdp = TRUE; } if(!bFindTcp && pProtoInfo[i].iProtocol == IPPROTO_TCP) { memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW)); OriginalProtocolInfo[nArrayCount].dwServiceFlags1 = OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId; bFindTcp = TRUE; } if(!bFindRaw && pProtoInfo[i].iProtocol == IPPROTO_IP) { memcpy(&OriginalProtocolInfo[nArrayCount], &pProtoInfo[i], sizeof(WSAPROTOCOL_INFOW)); OriginalProtocolInfo[nArrayCount].dwServiceFlags1 = OriginalProtocolInfo[nArrayCount].dwServiceFlags1 & (~XP1_IFS_HANDLES); dwOrigCatalogId[nArrayCount++] = pProtoInfo[i].dwCatalogEntryId; bFindRaw = TRUE; } } } // 安装我们的分层协议,获取一个dwLayeredCatalogId // 随便找一个下层协议的结构复制过来即可 WSAPROTOCOL_INFOW LayeredProtocolInfo; memcpy(&LayeredProtocolInfo, &OriginalProtocolInfo[0], sizeof(WSAPROTOCOL_INFOW)); // 修改协议名称,类型,设置PFL_HIDDEN标志 wcscpy(LayeredProtocolInfo.szProtocol, wszLSPName); LayeredProtocolInfo.ProtocolChain.ChainLen = LAYERED_PROTOCOL; // 0; LayeredProtocolInfo.dwProviderFlags |= PFL_HIDDEN; // 安装 if(::WSCInstallProvider(&ProviderGuid, pwszPathName, &LayeredProtocolInfo, 1, &nError) == SOCKET_ERROR) { return FALSE; } // 重新枚举协议,获取分层协议的目录ID号 FreeProvider(pProtoInfo); pProtoInfo = GetProvider(&nProtocols); for(i=0; i<nProtocols; i++) { if(memcmp(&pProtoInfo[i].ProviderId, &ProviderGuid, sizeof(ProviderGuid)) == 0) { dwLayeredCatalogId = pProtoInfo[i].dwCatalogEntryId; break; } } // 安装协议链 // 修改协议名称,类型 WCHAR wszChainName[WSAPROTOCOL_LEN + 1]; for(i=0; i<nArrayCount; i++) { swprintf(wszChainName, L"%ws over %ws", wszLSPName, OriginalProtocolInfo[i].szProtocol); wcscpy(OriginalProtocolInfo[i].szProtocol, wszChainName); if(OriginalProtocolInfo[i].ProtocolChain.ChainLen == 1) { OriginalProtocolInfo[i].ProtocolChain.ChainEntries[1] = dwOrigCatalogId[i]; } else { for(int j = OriginalProtocolInfo[i].ProtocolChain.ChainLen; j>0; j--) { OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j] = OriginalProtocolInfo[i].ProtocolChain.ChainEntries[j-1]; } } OriginalProtocolInfo[i].ProtocolChain.ChainLen ++; OriginalProtocolInfo[i].ProtocolChain.ChainEntries[0] = dwLayeredCatalogId; } // 获取一个Guid,安装之 GUID ProviderChainGuid; if(::UuidCreate(&ProviderChainGuid) == RPC_S_OK) { if(::WSCInstallProvider(&ProviderChainGuid, pwszPathName, OriginalProtocolInfo, nArrayCount, &nError) == SOCKET_ERROR) { return FALSE; } } else return FALSE; // 重新排序Winsock目录,将我们的协议链提前 // 重新枚举安装的协议 FreeProvider(pProtoInfo); pProtoInfo = GetProvider(&nProtocols); DWORD dwIds[20]; int nIndex = 0; // 添加我们的协议链 for(i=0; i<nProtocols; i++) { if((pProtoInfo[i].ProtocolChain.ChainLen > 1) && (pProtoInfo[i].ProtocolChain.ChainEntries[0] == dwLayeredCatalogId)) dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId; } // 添加其它协议 for(i=0; i<nProtocols; i++) { if((pProtoInfo[i].ProtocolChain.ChainLen <= 1) || (pProtoInfo[i].ProtocolChain.ChainEntries[0] != dwLayeredCatalogId)) dwIds[nIndex++] = pProtoInfo[i].dwCatalogEntryId; } // 重新排序Winsock目录 if((nError = ::WSCWriteProviderOrder(dwIds, nIndex)) != ERROR_SUCCESS) { return FALSE; } FreeProvider(pProtoInfo); return TRUE; }