1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS WinSock 2 API 4 * FILE: dll/win32/ws2_32/src/dprovide.c 5 * PURPOSE: Transport Provider Object 6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net) 7 */ 8 9 /* INCLUDES ******************************************************************/ 10 11 #include <ws2_32.h> 12 13 #define NDEBUG 14 #include <debug.h> 15 16 /* FUNCTIONS *****************************************************************/ 17 18 PTPROVIDER 19 WSAAPI 20 WsTpAllocate(VOID) 21 { 22 PTPROVIDER Provider; 23 24 /* Allocate the object */ 25 Provider = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Provider)); 26 if (Provider) 27 { 28 /* Setup non-zero data */ 29 Provider->RefCount = 1; 30 } 31 32 /* Return it */ 33 return Provider; 34 } 35 36 DWORD 37 WSAAPI 38 WsTpInitialize(IN PTPROVIDER Provider, 39 IN LPSTR DllName, 40 IN LPWSAPROTOCOL_INFOW ProtocolInfo) 41 { 42 WORD VersionRequested = MAKEWORD(2,2); 43 LPWSPSTARTUP WSPStartupProc; 44 WSPDATA WspData; 45 CHAR ExpandedDllPath[MAX_PATH]; 46 DWORD ErrorCode; 47 DPRINT("WsTpInitialize: %p, %p, %p\n", Provider, DllName, ProtocolInfo); 48 49 /* Clear the tables */ 50 RtlZeroMemory(&Provider->UpcallTable, sizeof(Provider->UpcallTable)); 51 RtlZeroMemory(&Provider->Service, sizeof(Provider->Service)); 52 53 /* Set up the Upcall Table */ 54 Provider->UpcallTable.lpWPUCloseEvent = WPUCloseEvent; 55 Provider->UpcallTable.lpWPUCloseSocketHandle = WPUCloseSocketHandle; 56 Provider->UpcallTable.lpWPUCreateEvent = WPUCreateEvent; 57 Provider->UpcallTable.lpWPUCreateSocketHandle = WPUCreateSocketHandle; 58 Provider->UpcallTable.lpWPUFDIsSet = WPUFDIsSet; 59 Provider->UpcallTable.lpWPUGetProviderPath = WPUGetProviderPath; 60 Provider->UpcallTable.lpWPUModifyIFSHandle = WPUModifyIFSHandle; 61 Provider->UpcallTable.lpWPUPostMessage = WPUPostMessage; 62 Provider->UpcallTable.lpWPUQueryBlockingCallback = WPUQueryBlockingCallback; 63 Provider->UpcallTable.lpWPUQuerySocketHandleContext = WPUQuerySocketHandleContext; 64 Provider->UpcallTable.lpWPUQueueApc = WPUQueueApc; 65 Provider->UpcallTable.lpWPUResetEvent = WPUResetEvent; 66 Provider->UpcallTable.lpWPUSetEvent = WPUSetEvent; 67 Provider->UpcallTable.lpWPUOpenCurrentThread = WPUOpenCurrentThread; 68 Provider->UpcallTable.lpWPUCloseThread = WPUCloseThread; 69 70 /* Expand the DLL Path */ 71 ExpandEnvironmentStrings(DllName, ExpandedDllPath, MAX_PATH); 72 73 /* Load the DLL */ 74 Provider->DllHandle = LoadLibrary(ExpandedDllPath); 75 76 if (!Provider->DllHandle) 77 { 78 return SOCKET_ERROR; 79 } 80 /* Get the pointer to WSPStartup */ 81 WSPStartupProc = (LPWSPSTARTUP)GetProcAddress(Provider->DllHandle, "WSPStartup"); 82 83 if (!WSPStartupProc) 84 { 85 return SOCKET_ERROR; 86 } 87 /* Call it */ 88 ErrorCode = (*WSPStartupProc)(VersionRequested, 89 &WspData, 90 ProtocolInfo, 91 Provider->UpcallTable, 92 &Provider->Service); 93 94 /* Return */ 95 return ErrorCode; 96 } 97 98 DWORD 99 WSAAPI 100 WsTpWSPCleanup(IN PTPROVIDER Provider, 101 IN LPINT lpErrNo) 102 { 103 LPWSPCLEANUP WSPCleanup = NULL; 104 INT ErrorCode = ERROR_SUCCESS; 105 106 /* Make sure we have a loaded handle */ 107 if (Provider->DllHandle) 108 { 109 /* Get the pointer and clear it */ 110 WSPCleanup = InterlockedExchangePointer((PVOID*)&Provider->Service.lpWSPCleanup, 111 NULL); 112 /* If it's not NULL, call it */ 113 if (WSPCleanup) ErrorCode = WSPCleanup(lpErrNo); 114 } 115 116 /* Return */ 117 return ErrorCode; 118 } 119 120 VOID 121 WSAAPI 122 WsTpDelete(IN PTPROVIDER Provider) 123 { 124 INT ErrorCode; 125 126 /* Make sure we have a loaded handle */ 127 if (Provider->DllHandle) 128 { 129 /* Clean us up */ 130 WsTpWSPCleanup(Provider, &ErrorCode); 131 132 /* Unload the library */ 133 FreeLibrary(Provider->DllHandle); 134 Provider->DllHandle = NULL; 135 } 136 137 /* Delete us */ 138 HeapFree(WsSockHeap, 0, Provider); 139 } 140 141 VOID 142 WSAAPI 143 WsTpDereference(IN PTPROVIDER Provider) 144 { 145 /* Decrease the reference count and check if it's zero */ 146 if (!InterlockedDecrement(&Provider->RefCount)) 147 { 148 /* Delete us*/ 149 WsTpDelete(Provider); 150 } 151 } 152