xref: /reactos/dll/win32/ws2_32/src/dprovide.c (revision 682f85ad)
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