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