//------------------------------------------------------------------------ // LSPAlreadyInstalled() // // Check to see if the restricted network LSP is alreay installed. //------------------------------------------------------------------------ DWORD LSPAlreadyInstalled( BOOL *pfIsInstalled ) { int i; int iEnumResult; int iError; DWORD dwStatus = NO_ERROR; int aiProtocols[2]; WSAPROTOCOL_INFOW *pProtocolInfoBuff = NULL; DWORD dwProtocolInfoBuffSize = 0; // Enumerate TCP/IP providers and chains *pfIsInstalled = FALSE; aiProtocols[0] = IPPROTO_TCP; aiProtocols[1] = 0; // Call WSCEnumProtocols with a zero length buffer so we know what // size to send in to get all the installed PROTOCOL_INFO structs. iEnumResult = WSCEnumProtocols( aiProtocols, pProtocolInfoBuff, &dwProtocolInfoBuffSize, &iError ); if ((iEnumResult == SOCKET_ERROR) && (iError == WSAENOBUFS)) { pProtocolInfoBuff = (WSAPROTOCOL_INFOW*)new char [dwProtocolInfoBuffSize]; if (!pProtocolInfoBuff) { // Out of memory... return ERROR_NOT_ENOUGH_MEMORY; } iEnumResult = WSCEnumProtocols( aiProtocols, pProtocolInfoBuff, &dwProtocolInfoBuffSize, &iError ); if (iEnumResult != SOCKET_ERROR) { // Look through the list and see if the Restricted Network LSP // is already there. for (i=0; i<iEnumResult; i++) { if (!memcmp(&pProtocolInfoBuff[i].ProviderId, &LayeredProviderGuid, sizeof(GUID))) { *pfIsInstalled = TRUE; break; } } } } delete pProtocolInfoBuff; return dwStatus; }
SOCKET open_ifs_socket(int af, int type, int protocol) { dTHX; char *s; unsigned long proto_buffers_len = 0; int error_code; SOCKET out = INVALID_SOCKET; if ((s = PerlEnv_getenv("PERL_ALLOW_NON_IFS_LSP")) && atoi(s)) return WSASocket(af, type, protocol, NULL, 0, 0); if (WSCEnumProtocols(NULL, NULL, &proto_buffers_len, &error_code) == SOCKET_ERROR && error_code == WSAENOBUFS) { WSAPROTOCOL_INFOW *proto_buffers; int protocols_available = 0; Newx(proto_buffers, proto_buffers_len / sizeof(WSAPROTOCOL_INFOW), WSAPROTOCOL_INFOW); if ((protocols_available = WSCEnumProtocols(NULL, proto_buffers, &proto_buffers_len, &error_code)) != SOCKET_ERROR) { int i; for (i = 0; i < protocols_available; i++) { WSAPROTOCOL_INFOA proto_info; if ((af != AF_UNSPEC && af != proto_buffers[i].iAddressFamily) || (type != proto_buffers[i].iSocketType) || (protocol != 0 && proto_buffers[i].iProtocol != 0 && protocol != proto_buffers[i].iProtocol)) continue; if ((proto_buffers[i].dwServiceFlags1 & XP1_IFS_HANDLES) == 0) continue; convert_proto_info_w2a(&(proto_buffers[i]), &proto_info); out = WSASocket(af, type, protocol, &proto_info, 0, 0); break; } } Safefree(proto_buffers); } return out; }
// // Function: EnumerateProvidersExisting // // Description: // This function enumerates the catalog into a preallocated buffer. // int EnumerateProvidersExisting( WINSOCK_CATALOG Catalog, WSAPROTOCOL_INFOW *ProtocolInfo, LPDWORD ProtocolInfoSize ) { INT ErrorCode = NO_ERROR, rc = NO_ERROR; #ifdef _WIN64 if ( LspCatalog64Only == Catalog ) { rc = WSCEnumProtocols( NULL, ProtocolInfo, ProtocolInfoSize, &ErrorCode ); } else if ( LspCatalog32Only == Catalog ) { rc = WSCEnumProtocols32( NULL, ProtocolInfo, ProtocolInfoSize, &ErrorCode ); } #else if ( LspCatalog32Only == Catalog ) { rc = WSCEnumProtocols( NULL, ProtocolInfo, ProtocolInfoSize, &ErrorCode ); } else if ( LspCatalog64Only == Catalog ) { dbgprint( "Unable to enumerate 64-bit Winsock catalog from 32-bit process!" ); } #endif if ( SOCKET_ERROR == rc ) { dbgprint( "EnumerateProvidersExisting: WSCEnumProviders failed: %d", GetLastError() ); } return rc; }
void main() { int nProtocols; int nError; DWORD dwSize = 0; LPWSAPROTOCOL_INFOW pProtoInfo = NULL; // 首次调用,pProtoInfo传入NULL,取得需要的缓冲区长度 if(WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR) { if(nError != WSAENOBUFS) { return ; } } // 申请足够缓冲区内存。 pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize); if (pProtoInfo == NULL) { return ; } //再次调用WSCEnumProtocols函数 nProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError); wchar_t szWPath[MAX_PATH] = {0}; int iLen = MAX_PATH; //使控制台支持中文编码//////////////////////////////////////////////////////////////////// setlocale(LC_ALL, "chs"); wprintf(L"%-10s%-25s%s\n\n", L"提供者ID", L"协议类型", L"DLL路径"); wchar_t *szWType[3] = {L"分层协议", L"基础协议", L"协议链"}; int iIndex = 0; for(int i=0; i<nProtocols; i++) { //打印传输服务提供者ID wprintf(L"%-13d", pProtoInfo[i].dwCatalogEntryId); //打印传输服务提供者协议类型 iIndex = (pProtoInfo[i].ProtocolChain.ChainLen>1?2:pProtoInfo[i].ProtocolChain.ChainLen); wprintf(L"%-15s", szWType[iIndex]); //打印传输服务提供者所对应DLL的路径 WSCGetProviderPath(&pProtoInfo[i].ProviderId, szWPath, &iLen, NULL); wprintf(L"%-15s\n", szWPath); } wprintf(L"共计 %d 个传输服务提供者\n", nProtocols); //释放内存 GlobalFree(pProtoInfo); //恢复控制台编码////////////////////////////////////////////////////////////////////////// setlocale(LC_ALL, NULL); }
bool HasIPv6Enabled() { #ifndef WIN32 // We only need to check this for Windows XP (so far). return true; #else if (IsWindowsVistaOrLater()) { return true; } if (!IsWindowsXpOrLater()) { return false; } DWORD protbuff_size = 4096; scoped_array<char> protocols; LPWSAPROTOCOL_INFOW protocol_infos = NULL; int requested_protocols[2] = {AF_INET6, 0}; int err = 0; int ret = 0; // Check for protocols in a do-while loop until we provide a buffer large // enough. (WSCEnumProtocols sets protbuff_size to its desired value). // It is extremely unlikely that this will loop more than once. do { protocols.reset(new char[protbuff_size]); protocol_infos = reinterpret_cast<LPWSAPROTOCOL_INFOW>(protocols.get()); ret = WSCEnumProtocols(requested_protocols, protocol_infos, &protbuff_size, &err); } while (ret == SOCKET_ERROR && err == WSAENOBUFS); if (ret == SOCKET_ERROR) { return false; } // Even if ret is positive, check specifically for IPv6. // Non-IPv6 enabled WinXP will still return a RAW protocol. for (int i = 0; i < ret; ++i) { if (protocol_infos[i].iAddressFamily == AF_INET6) { return true; } } return false; #endif }
void zmq::pgm_socket_t::open_transport () { SOCKADDR_IN salocal; SOCKADDR_IN sasession; zmq_log (1, "Opening PGM: network %s, port %i, %s(%i)\n", network, port_number, __FILE__, __LINE__); // Check if the machine supports PGM. int protocol_list[] = { IPPROTO_RM, 0 }; WSAPROTOCOL_INFOW* lpProtocolBuf = NULL; DWORD dwBufLen = 0; int err; int protocols = WSCEnumProtocols (protocol_list, lpProtocolBuf, &dwBufLen, &err); if (protocols != SOCKET_ERROR) assert (false); else if (err != WSAENOBUFS) assert (false); // Allocate needed space for lpProtocolBuf. lpProtocolBuf = (WSAPROTOCOL_INFOW*)malloc (dwBufLen); if (lpProtocolBuf == NULL) assert (false); // Get information about available protocols, the information will be // placed to lpProtocolBuf. protocols = WSCEnumProtocols (protocol_list, lpProtocolBuf, &dwBufLen, &err); if (SOCKET_ERROR == protocols) { free (lpProtocolBuf); assert (false); } bool found = FALSE; for (int i = 0; i < protocols; i++) { if (AF_INET == lpProtocolBuf[i].iAddressFamily && IPPROTO_RM == lpProtocolBuf[i].iProtocol && SOCK_RDM == lpProtocolBuf[i].iSocketType) { found = TRUE; break; } } if (!found) { fprintf (stderr, "PGM support is not installed on this machine."); free (lpProtocolBuf); assert (false); } free (lpProtocolBuf); // Receiver transport. if (receiver) { receiver_listener_socket = socket (AF_INET, SOCK_RDM, IPPROTO_RM); wsa_assert (receiver_listener_socket != INVALID_SOCKET); // The bind port (port_number) specified should match that // which the sender specified in the connect call. salocal.sin_family = AF_INET; salocal.sin_port = htons (port_number); salocal.sin_addr.s_addr = inet_addr (multicast); int rc = bind (receiver_listener_socket, (SOCKADDR *) &salocal, sizeof(salocal)); wsa_assert (rc != SOCKET_ERROR); rc = listen (receiver_listener_socket, 10); wsa_assert (rc != SOCKET_ERROR); // Set the socket to non-blocking mode. u_long flag = 1; rc = ioctlsocket (receiver_listener_socket, FIONBIO, &flag); wsa_assert (rc != SOCKET_ERROR); // Sender transport. } else { sender_socket = socket (AF_INET, SOCK_RDM, IPPROTO_RM); wsa_assert (sender_socket != INVALID_SOCKET); salocal.sin_family = AF_INET; salocal.sin_port = htons (0); // Port is ignored here salocal.sin_addr.s_addr = htonl (INADDR_ANY); int rc = bind (sender_socket, (SOCKADDR *)&salocal, sizeof(salocal)); wsa_assert (rc != SOCKET_ERROR); int to_preallocate = 0; // Set socket options. ULONG val = 1; setsockopt (sender_socket, IPPROTO_RM, RM_HIGH_SPEED_INTRANET_OPT, (char*)&val, sizeof(val)); // Set the socket to non-blocking mode. u_long flag = 1; rc = ioctlsocket (sender_socket, FIONBIO, &flag); wsa_assert (rc != SOCKET_ERROR); // Set the outgoing interface. ULONG send_iface; send_iface = inet_addr (network); rc = setsockopt (sender_socket, IPPROTO_RM, RM_SET_SEND_IF, (char *)&send_iface, sizeof(send_iface)); wsa_assert (rc != SOCKET_ERROR); // Set window size. // Parameter WindowSizeInBytes is calculated automaticaly as // send_window.WindowSizeInBytes = // send_window.RateKbitsPerSec * send_window.WindowSizeInMSecs / 8. assert (pgm_max_rte >= 1000); assert (pgm_secs != 0); RM_SEND_WINDOW send_window; send_window.RateKbitsPerSec = (pgm_max_rte / 1024) * 8; send_window.WindowSizeInMSecs = pgm_secs * 1000; // Parameter WindowSizeInBytes is calculated automaticaly as: send_window.WindowSizeInBytes = send_window.RateKbitsPerSec * send_window.WindowSizeInMSecs / 8; // Set multicast address and port number. sasession.sin_family = AF_INET; sasession.sin_port = htons (port_number); sasession.sin_addr.s_addr = inet_addr (multicast); rc = setsockopt (sender_socket, IPPROTO_RM, RM_RATE_WINDOW_SIZE, (char *) &send_window, sizeof (send_window)); wsa_assert (rc != SOCKET_ERROR); rc = connect (sender_socket, (SOCKADDR *)&sasession, sizeof(sasession)); wsa_assert (rc != SOCKET_ERROR); } }
// // Function: GetProviders // // Description: // This enumerates the Winsock catalog via the global variable ProtocolInfo. // LPWSAPROTOCOL_INFOW EnumerateProviders( WINSOCK_CATALOG Catalog, LPINT TotalProtocols ) { LPWSAPROTOCOL_INFOW ProtocolInfo = NULL; DWORD ProtocolInfoSize = 0; INT ErrorCode = NO_ERROR, rc; if ( NULL == TotalProtocols ) goto cleanup; *TotalProtocols = 0; #ifdef _WIN64 // Find out how many entries we need to enumerate if ( LspCatalog64Only == Catalog ) { // Find the size of the buffer rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if (ProtocolInfo == NULL) goto cleanup; // Enumerate the catalog for real rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; } else if ( LspCatalog32Only == Catalog ) { HMODULE hModule; LPWSCENUMPROTOCOLS fnWscEnumProtocols32 = NULL; // Load ws2_32.dll hModule = LoadLibrary( TEXT( "ws2_32.dll" ) ); if ( NULL == hModule ) goto cleanup; // Find the 32-bit catalog enumerator fnWscEnumProtocols32 = (LPWSCENUMPROTOCOLS) GetProcAddress( hModule, TEXT( "WSCEnumProtocols32" ) ); if ( NULL == fnWscEnumProtocols32 ) goto cleanup; // Find the required buffer size rc = fnWscEnumProtocols32(NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if ( NULL == ProtocolInfo ) goto cleanup; // Enumrate the catalog for real this time rc = fnWscEnumProtocols32( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; FreeLibrary( hModule ); } #else if ( LspCatalog32Only == Catalog ) { // Find the size of the buffer rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if ( NULL == ProtocolInfo ) goto cleanup; // Enumerate the catalog for real rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; } else if ( LspCatalog64Only == Catalog ) { dbgprint( "Unable to enumerate 64-bit Winsock catalog from 32-bit process!"); } #endif else { // Find the size of the buffer rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if ( NULL == ProtocolInfo ) goto cleanup; // Enumerate the catalog for real rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; } cleanup: if ( ( NO_ERROR != ErrorCode ) && ( NULL != ProtocolInfo ) ) { LspFree( ProtocolInfo ); ProtocolInfo = NULL; } return ProtocolInfo; }
//------------------------------------------------------------------------ // InstallLSP() // // Install the msrlsp into the Winsock2 WSP chains. // //------------------------------------------------------------------------ void InstallLSP() { int i; int EnumResult; int iError; LONG lStatus; DWORD CatalogEntryId; LPWSAPROTOCOL_INFOW ProtocolInfoBuff = NULL; DWORD ProtocolInfoBuffSize = 0; BOOL EntryIdFound; // Install the WSAPROTOCOL_INFOW for the layered provider. lStatus = InstallRestrictedLSP( &CatalogEntryId ); if (NO_ERROR == lStatus) { // // Enumerate the installed providers and chains // // Call WSCEnumProtocols with a zero length buffer so we know what // size to send in to get all the installed PROTOCOL_INFO // structs. WSCEnumProtocols( NULL, ProtocolInfoBuff, & ProtocolInfoBuffSize, &iError); ProtocolInfoBuff = (LPWSAPROTOCOL_INFOW)new char [ProtocolInfoBuffSize]; if (ProtocolInfoBuff) { EnumResult = WSCEnumProtocols( NULL, // lpiProtocols ProtocolInfoBuff, // lpProtocolBuffer & ProtocolInfoBuffSize, // lpdwBufferLength &iError ); if (SOCKET_ERROR != EnumResult) { // Find our provider entry to get our catalog entry ID EntryIdFound = FALSE; for (i=0; i<EnumResult; i++) { if (!memcmp(&ProtocolInfoBuff[i].ProviderId, &LayeredProviderGuid, sizeof(GUID))) { CatalogEntryId = ProtocolInfoBuff[i].dwCatalogEntryId; EntryIdFound = TRUE; break; } } if (EntryIdFound) { for (i=0; i<EnumResult; i++) { if ( (ProtocolInfoBuff[i].iAddressFamily == AF_INET) && (ProtocolInfoBuff[i].iProtocol == IPPROTO_TCP) ) { InstallNewChain( &ProtocolInfoBuff[i], CatalogEntryId ); break; } } } } } } }
NS_IMETHODIMP LSPAnnotationGatherer::Run() { PR_SetCurrentThreadName("LSP Annotator"); mThread = NS_GetCurrentThread(); DWORD size = 0; int err; // Get the size of the buffer we need if (SOCKET_ERROR != WSCEnumProtocols(nullptr, nullptr, &size, &err) || err != WSAENOBUFS) { // Er, what? NS_NOTREACHED("WSCEnumProtocols suceeded when it should have failed ..."); return NS_ERROR_FAILURE; } auto byteArray = MakeUnique<char[]>(size); WSAPROTOCOL_INFOW* providers = reinterpret_cast<WSAPROTOCOL_INFOW*>(byteArray.get()); int n = WSCEnumProtocols(nullptr, providers, &size, &err); if (n == SOCKET_ERROR) { // Lame. We provided the right size buffer; we'll just give up now. NS_WARNING("Could not get LSP list"); return NS_ERROR_FAILURE; } nsCString str; for (int i = 0; i < n; i++) { AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str); str.AppendLiteral(" : "); str.AppendInt(providers[i].iVersion); str.AppendLiteral(" : "); str.AppendInt(providers[i].iAddressFamily); str.AppendLiteral(" : "); str.AppendInt(providers[i].iSocketType); str.AppendLiteral(" : "); str.AppendInt(providers[i].iProtocol); str.AppendLiteral(" : "); str.AppendPrintf("0x%x", providers[i].dwServiceFlags1); str.AppendLiteral(" : "); str.AppendPrintf("0x%x", providers[i].dwProviderFlags); str.AppendLiteral(" : "); wchar_t path[MAX_PATH]; int pathLen = MAX_PATH; if (!WSCGetProviderPath(&providers[i].ProviderId, path, &pathLen, &err)) { AppendUTF16toUTF8(nsDependentString(path), str); } str.AppendLiteral(" : "); // If WSCGetProviderInfo is available, we should call it to obtain the // category flags for this provider. When present, these flags inform // Windows as to which order to chain the providers. nsModuleHandle ws2_32(LoadLibraryW(L"ws2_32.dll")); if (ws2_32) { decltype(WSCGetProviderInfo)* pWSCGetProviderInfo = reinterpret_cast<decltype(WSCGetProviderInfo)*>( GetProcAddress(ws2_32, "WSCGetProviderInfo")); if (pWSCGetProviderInfo) { DWORD categoryInfo; size_t categoryInfoSize = sizeof(categoryInfo); if (!pWSCGetProviderInfo(&providers[i].ProviderId, ProviderInfoLspCategories, (PBYTE)&categoryInfo, &categoryInfoSize, 0, &err)) { str.AppendPrintf("0x%x", categoryInfo); } } } str.AppendLiteral(" : "); if (providers[i].ProtocolChain.ChainLen <= BASE_PROTOCOL) { // If we're dealing with a catalog entry that identifies an individual // base or layer provider, log its provider GUID. RPC_CSTR provIdStr = nullptr; if (UuidToStringA(&providers[i].ProviderId, &provIdStr) == RPC_S_OK) { str.Append(reinterpret_cast<char*>(provIdStr)); RpcStringFreeA(&provIdStr); } } if (i + 1 != n) { str.AppendLiteral(" \n "); } } mString = str; NS_DispatchToMainThread(NewRunnableMethod(this, &LSPAnnotationGatherer::Annotate)); return NS_OK; }