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