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
WsTpAllocate(VOID)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
WsTpInitialize(IN PTPROVIDER Provider,IN LPSTR DllName,IN LPWSAPROTOCOL_INFOW ProtocolInfo)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
WsTpWSPCleanup(IN PTPROVIDER Provider,IN LPINT lpErrNo)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
WsTpDelete(IN PTPROVIDER Provider)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
WsTpDereference(IN PTPROVIDER Provider)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