xref: /reactos/dll/win32/ws2_32/src/nsprovid.c (revision 53221834)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS WinSock 2 API
4  * FILE:        dll/win32/ws2_32/src/nsprovid.c
5  * PURPOSE:     Namespace Provider Object
6  * PROGRAMMER:  Alex Ionescu (alex@relsoft.net)
7  */
8 
9 /* INCLUDES ******************************************************************/
10 
11 #include <ws2_32.h>
12 
13 /* FUNCTIONS *****************************************************************/
14 
15 PNSQUERY_PROVIDER
16 WSAAPI
17 WsNqProvAllocate(VOID)
18 {
19     PNSQUERY_PROVIDER Provider;
20 
21     /* Allocate the object */
22     Provider = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Provider));
23 
24     /* Return it */
25     return Provider;
26 }
27 
28 DWORD
29 WSAAPI
30 WsNqProvInitialize(IN PNSQUERY_PROVIDER QueryProvider,
31                    IN PNS_PROVIDER Provider)
32 {
33     /* Reference the provider */
34     InterlockedIncrement(&Provider->RefCount);
35 
36     /* Set it as our own */
37     QueryProvider->Provider = Provider;
38 
39     /* Return success */
40     return ERROR_SUCCESS;
41 }
42 
43 VOID
44 WSAAPI
45 WsNqProvDelete(IN PNSQUERY_PROVIDER QueryProvider)
46 {
47     /* Check if we have a provider */
48     if (QueryProvider->Provider)
49     {
50         /* Dereference it */
51         WsNpDereference(QueryProvider->Provider);
52 
53         /* Clear it */
54         QueryProvider->Provider = NULL;
55     }
56 
57     /* Delete us */
58     HeapFree(WsSockHeap, 0, QueryProvider);
59 }
60 
61 PNS_PROVIDER
62 WSAAPI
63 WsNpAllocate(VOID)
64 {
65     PNS_PROVIDER Provider;
66 
67     /* Allocate the object */
68     Provider = HeapAlloc(WsSockHeap, HEAP_ZERO_MEMORY, sizeof(*Provider));
69     if (Provider)
70     {
71         /* Set non-null data */
72         Provider->RefCount = 1;
73         Provider->Service.cbSize = sizeof(NSP_ROUTINE);
74     }
75 
76     /* Return it */
77     return Provider;
78 }
79 
80 DWORD
81 WSAAPI
82 WsNpInitialize(IN PNS_PROVIDER Provider,
83                IN LPWSTR DllName,
84                IN LPGUID ProviderId)
85 {
86     INT ErrorCode = ERROR_SUCCESS;
87     LPNSPSTARTUP NSPStartupProc;
88     CHAR AnsiPath[MAX_PATH], ExpandedDllPath[MAX_PATH];
89 
90     /* Convert the path to ANSI */
91     WideCharToMultiByte(CP_ACP,
92                         0,
93                         DllName,
94                         -1,
95                         AnsiPath,
96                         MAX_PATH,
97                         NULL,
98                         NULL);
99 
100     /* Expand the DLL Path */
101     ExpandEnvironmentStringsA(AnsiPath,
102                               ExpandedDllPath,
103                               MAX_PATH);
104 
105     /* Load the DLL */
106     Provider->DllHandle = LoadLibraryA(ExpandedDllPath);
107     if (!Provider->DllHandle)
108     {
109         /* Fail */
110         ErrorCode = WSAEPROVIDERFAILEDINIT;
111         goto Fail;
112     }
113 
114     /* Get the pointer to NSPStartup */
115     NSPStartupProc = (LPNSPSTARTUP)GetProcAddress(Provider->DllHandle,
116                                                   "NSPStartup");
117     if (!NSPStartupProc)
118     {
119         /* Fail */
120         ErrorCode = WSAEPROVIDERFAILEDINIT;
121         goto Fail;
122     }
123 
124     /* Call it */
125     (*NSPStartupProc)(ProviderId, &Provider->Service);
126 
127     /* Save the provider ID */
128     Provider->ProviderId = *ProviderId;
129     return ErrorCode;
130 
131 Fail:
132     /* Bail out */
133     if (Provider->DllHandle) FreeLibrary(Provider->DllHandle);
134     Provider->DllHandle = NULL;
135     return ErrorCode;
136 }
137 
138 DWORD
139 WSAAPI
140 WsNpNSPCleanup(IN PNS_PROVIDER Provider)
141 {
142     INT ErrorCode = ERROR_SUCCESS;
143     LPNSPCLEANUP lpNSPCleanup = NULL;
144 
145     /* Make sure we have a loaded handle */
146     if (Provider->DllHandle)
147     {
148         /* Get the pointer and clear it */
149         lpNSPCleanup = InterlockedExchangePointer((PVOID*)&Provider->Service.NSPCleanup,
150                                                   NULL);
151         /* If it's not NULL, call it */
152         if (lpNSPCleanup) ErrorCode = lpNSPCleanup(&Provider->ProviderId);
153     }
154 
155     /* Return */
156     return ErrorCode;
157 }
158 
159 VOID
160 WSAAPI
161 WsNpDelete(IN PNS_PROVIDER Provider)
162 {
163     /* Make sure we have a loaded handle */
164     if (Provider->DllHandle)
165     {
166         /* Clean us up */
167         WsNpNSPCleanup(Provider);
168 
169         /* Unload the library */
170         FreeLibrary(Provider->DllHandle);
171         Provider->DllHandle = NULL;
172     }
173 
174     /* Delete us */
175     HeapFree(WsSockHeap, 0, Provider);
176 }
177 
178 VOID
179 WSAAPI
180 WsNpDereference(IN PNS_PROVIDER Provider)
181 {
182     /* Decrease the reference count and check if it's zero */
183     if (!InterlockedDecrement(&Provider->RefCount))
184     {
185         /* Delete us*/
186         WsNpDelete(Provider);
187     }
188 }
189 
190 DWORD
191 WSAAPI
192 WsNqProvLookupServiceEnd(IN PNSQUERY_PROVIDER QueryProvider)
193 {
194     /* Simply call the provider */
195     return WsNpLookupServiceEnd(QueryProvider->Provider,
196                                 QueryProvider->LookupHandle);
197 }
198 
199 DWORD
200 WSAAPI
201 WsNqProvLookupServiceNext(IN PNSQUERY_PROVIDER QueryProvider,
202                           IN DWORD ControlFlags,
203                           IN PDWORD BufferLength,
204                           LPWSAQUERYSETW Results)
205 {
206     /* Simply call the provider */
207     return WsNpLookupServiceNext(QueryProvider->Provider,
208                                  QueryProvider->LookupHandle,
209                                  ControlFlags,
210                                  BufferLength,
211                                  Results);
212 }
213 
214 DWORD
215 WSAAPI
216 WsNqProvLookupServiceBegin(IN PNSQUERY_PROVIDER QueryProvider,
217                            IN LPWSAQUERYSETW Restrictions,
218                            IN LPWSASERVICECLASSINFOW ServiceClassInfo,
219                            IN DWORD ControlFlags)
220 {
221     /* Simply call the provider */
222     return WsNpLookupServiceBegin(QueryProvider->Provider,
223                                   Restrictions,
224                                   ServiceClassInfo,
225                                   ControlFlags,
226                                   &QueryProvider->LookupHandle);
227 }
228 
229 DWORD
230 WSAAPI
231 WsNpLookupServiceEnd(IN PNS_PROVIDER Provider,
232                      IN HANDLE LookupHandle)
233 {
234     /* Call the NSP */
235     return Provider->Service.NSPLookupServiceEnd(LookupHandle);
236 }
237 
238 DWORD
239 WSAAPI
240 WsNpLookupServiceNext(IN PNS_PROVIDER Provider,
241                       IN HANDLE LookupHandle,
242                       IN DWORD ControlFlags,
243                       OUT PDWORD BufferLength,
244                       OUT LPWSAQUERYSETW Results)
245 {
246     /* Call the NSP */
247     return Provider->Service.NSPLookupServiceNext(LookupHandle,
248                                                   ControlFlags,
249                                                   BufferLength,
250                                                   Results);
251 }
252 
253 DWORD
254 WSAAPI
255 WsNpLookupServiceBegin(IN PNS_PROVIDER Provider,
256                        IN LPWSAQUERYSETW Restrictions,
257                        IN LPWSASERVICECLASSINFOW ServiceClassInfo,
258                        IN DWORD ControlFlags,
259                        OUT PHANDLE LookupHandle)
260 {
261     /* Call the NSP */
262     return Provider->Service.NSPLookupServiceBegin(&Provider->ProviderId,
263                                                    Restrictions,
264                                                    ServiceClassInfo,
265                                                    ControlFlags,
266                                                    LookupHandle);
267 }
268 
269