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