:pserver:cvsanon@mok.lvcm.com:/CVS/ReactOS reactos
[reactos.git] / lib / msafd / misc / helpers.c
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS Ancillary Function Driver DLL
4  * FILE:        misc/helpers.c
5  * PURPOSE:     Helper DLL management
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * REVISIONS:
8  *   CSH 01/09-2000 Created
9  */
10 #include <msafd.h>
11 #include <helpers.h>
12
13 CRITICAL_SECTION HelperDLLDatabaseLock;
14 LIST_ENTRY HelperDLLDatabaseListHead;
15
16 PWSHELPER_DLL CreateHelperDLL(
17     LPWSTR LibraryName)
18 {
19     PWSHELPER_DLL HelperDLL;
20
21     HelperDLL = HeapAlloc(GlobalHeap, 0, sizeof(WSHELPER_DLL));
22     if (!HelperDLL)
23         return NULL;
24
25     InitializeCriticalSection(&HelperDLL->Lock);
26     HelperDLL->hModule = NULL;
27     lstrcpyW(HelperDLL->LibraryName, LibraryName);
28     HelperDLL->Mapping = NULL;
29
30     EnterCriticalSection(&HelperDLLDatabaseLock);
31     InsertTailList(&HelperDLLDatabaseListHead, &HelperDLL->ListEntry);
32     LeaveCriticalSection(&HelperDLLDatabaseLock);
33
34     AFD_DbgPrint(MAX_TRACE, ("Returning helper at (0x%X).\n", HelperDLL));
35
36     return HelperDLL;
37 }
38
39
40 INT DestroyHelperDLL(
41     PWSHELPER_DLL HelperDLL)
42 {
43     INT Status;
44
45     AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X).\n", HelperDLL));
46
47     EnterCriticalSection(&HelperDLLDatabaseLock);
48     RemoveEntryList(&HelperDLL->ListEntry);
49     LeaveCriticalSection(&HelperDLLDatabaseLock);
50
51     if (HelperDLL->hModule) {
52         Status = UnloadHelperDLL(HelperDLL);
53     } else {
54         Status = NO_ERROR;
55     }
56
57     if (HelperDLL->Mapping)
58         HeapFree(GlobalHeap, 0, HelperDLL->Mapping);
59
60     DeleteCriticalSection(&HelperDLL->Lock);
61
62     HeapFree(GlobalHeap, 0, HelperDLL);
63
64     return Status;
65 }
66
67
68 PWSHELPER_DLL LocateHelperDLL(
69     LPWSAPROTOCOL_INFOW lpProtocolInfo)
70 {
71     PLIST_ENTRY CurrentEntry;
72     PWSHELPER_DLL HelperDLL;
73     UINT i;
74
75     EnterCriticalSection(&HelperDLLDatabaseLock);
76     CurrentEntry = HelperDLLDatabaseListHead.Flink;
77     while (CurrentEntry != &HelperDLLDatabaseListHead) {
78             HelperDLL = CONTAINING_RECORD(CurrentEntry,
79                                       WSHELPER_DLL,
80                                       ListEntry);
81
82         for (i = 0; i < HelperDLL->Mapping->Rows; i++) {
83             if ((lpProtocolInfo->iAddressFamily == HelperDLL->Mapping->Mapping[i].AddressFamily) &&
84                 (lpProtocolInfo->iSocketType    == HelperDLL->Mapping->Mapping[i].SocketType) &&
85                 ((lpProtocolInfo->iProtocol     == HelperDLL->Mapping->Mapping[i].Protocol) ||
86                 (lpProtocolInfo->iSocketType    == SOCK_RAW))) {
87                 LeaveCriticalSection(&HelperDLLDatabaseLock);
88                 AFD_DbgPrint(MAX_TRACE, ("Returning helper DLL at (0x%X).\n", HelperDLL));
89                 return HelperDLL;
90             }
91         }
92
93         CurrentEntry = CurrentEntry->Flink;
94     }
95     LeaveCriticalSection(&HelperDLLDatabaseLock);
96
97     AFD_DbgPrint(MAX_TRACE, ("Could not locate helper DLL.\n"));
98
99     return NULL;
100 }
101
102
103 #define GET_ENTRY_POINT(helper, exportname, identifier) { \
104     PVOID entry;                        \
105                                         \
106     entry = GetProcAddress(helper->hModule, exportname); \
107     if (!entry)                         \
108         return ERROR_BAD_PROVIDER;      \
109     ((PVOID)helper->EntryTable.##identifier) = entry; \
110 }
111
112
113 INT GetHelperDLLEntries(
114     PWSHELPER_DLL HelperDLL)
115 {
116     GET_ENTRY_POINT(HelperDLL, "WSHAddressToString", lpWSHAddressToString);
117     GET_ENTRY_POINT(HelperDLL, "WSHEnumProtocols", lpWSHEnumProtocols);
118     GET_ENTRY_POINT(HelperDLL, "WSHGetBroadcastSockaddr", lpWSHGetBroadcastSockaddr);
119     GET_ENTRY_POINT(HelperDLL, "WSHGetProviderGuid", lpWSHGetProviderGuid);
120     GET_ENTRY_POINT(HelperDLL, "WSHGetSockaddrType", lpWSHGetSockaddrType);
121     GET_ENTRY_POINT(HelperDLL, "WSHGetSocketInformation", lpWSHGetSocketInformation);
122     GET_ENTRY_POINT(HelperDLL, "WSHGetWildcardSockaddr", lpWSHGetWildcardSockaddr);
123     GET_ENTRY_POINT(HelperDLL, "WSHGetWinsockMapping", lpWSHGetWinsockMapping);
124     GET_ENTRY_POINT(HelperDLL, "WSHGetWSAProtocolInfo", lpWSHGetWSAProtocolInfo);
125     GET_ENTRY_POINT(HelperDLL, "WSHIoctl", lpWSHIoctl);
126     GET_ENTRY_POINT(HelperDLL, "WSHJoinLeaf", lpWSHJoinLeaf);
127     GET_ENTRY_POINT(HelperDLL, "WSHNotify", lpWSHNotify);
128     GET_ENTRY_POINT(HelperDLL, "WSHOpenSocket", lpWSHOpenSocket);
129     GET_ENTRY_POINT(HelperDLL, "WSHOpenSocket2", lpWSHOpenSocket2);
130     GET_ENTRY_POINT(HelperDLL, "WSHSetSocketInformation", lpWSHSetSocketInformation);
131     GET_ENTRY_POINT(HelperDLL, "WSHStringToAddress", lpWSHStringToAddress);
132
133     return NO_ERROR;
134 }
135
136
137 INT LoadHelperDLL(
138     PWSHELPER_DLL HelperDLL)
139 {
140     INT Status = NO_ERROR;
141
142     AFD_DbgPrint(MAX_TRACE, ("Loading helper dll at (0x%X).\n", HelperDLL));
143
144     if (!HelperDLL->hModule) {
145         /* DLL is not loaded so load it now */
146         HelperDLL->hModule = LoadLibrary(HelperDLL->LibraryName);
147
148         AFD_DbgPrint(MAX_TRACE, ("hModule is (0x%X).\n", HelperDLL->hModule));
149
150         if (HelperDLL->hModule) {
151             Status = GetHelperDLLEntries(HelperDLL);
152         } else
153             Status = ERROR_DLL_NOT_FOUND;
154     } else
155         Status = NO_ERROR;
156
157     AFD_DbgPrint(MAX_TRACE, ("Status (%d).\n", Status));
158
159     return Status;
160 }
161
162
163 INT UnloadHelperDLL(
164     PWSHELPER_DLL HelperDLL)
165 {
166     INT Status = NO_ERROR;
167
168     AFD_DbgPrint(MAX_TRACE, ("HelperDLL (0x%X) hModule (0x%X).\n", HelperDLL, HelperDLL->hModule));
169
170     if (HelperDLL->hModule) {
171         if (!FreeLibrary(HelperDLL->hModule)) {
172             Status = GetLastError();
173         }
174         HelperDLL->hModule = NULL;
175     }
176
177     return Status;
178 }
179
180
181 VOID CreateHelperDLLDatabase(VOID)
182 {
183     PWSHELPER_DLL HelperDLL;
184
185     InitializeCriticalSection(&HelperDLLDatabaseLock);
186
187     InitializeListHead(&HelperDLLDatabaseListHead);
188
189     /* FIXME: Read helper DLL configuration from registry */
190     HelperDLL = CreateHelperDLL(L"wshtcpip.dll");
191     if (!HelperDLL)
192         return;
193
194     HelperDLL->Mapping = HeapAlloc(
195       GlobalHeap,
196       0,
197       3 * sizeof(WINSOCK_MAPPING) + 3 * sizeof(DWORD));
198     if (!HelperDLL->Mapping)
199         return;
200
201     HelperDLL->Mapping->Rows    = 3;
202     HelperDLL->Mapping->Columns = 3;
203
204     HelperDLL->Mapping->Mapping[0].AddressFamily = AF_INET;
205     HelperDLL->Mapping->Mapping[0].SocketType    = SOCK_STREAM;
206     HelperDLL->Mapping->Mapping[0].Protocol      = IPPROTO_TCP;
207
208     HelperDLL->Mapping->Mapping[1].AddressFamily = AF_INET;
209     HelperDLL->Mapping->Mapping[1].SocketType    = SOCK_DGRAM;
210     HelperDLL->Mapping->Mapping[1].Protocol      = IPPROTO_UDP;
211
212     HelperDLL->Mapping->Mapping[2].AddressFamily = AF_INET;
213     HelperDLL->Mapping->Mapping[2].SocketType    = SOCK_RAW;
214     HelperDLL->Mapping->Mapping[2].Protocol      = 0;
215
216     LoadHelperDLL(HelperDLL);
217 }
218
219
220 VOID DestroyHelperDLLDatabase(VOID)
221 {
222     PLIST_ENTRY CurrentEntry;
223     PLIST_ENTRY NextEntry;
224     PWSHELPER_DLL HelperDLL;
225
226     CurrentEntry = HelperDLLDatabaseListHead.Flink;
227     while (CurrentEntry != &HelperDLLDatabaseListHead) {
228         NextEntry = CurrentEntry->Flink;
229
230               HelperDLL = CONTAINING_RECORD(CurrentEntry,
231                                       WSHELPER_DLL,
232                                       ListEntry);
233
234         DestroyHelperDLL(HelperDLL);
235
236         CurrentEntry = NextEntry;
237     }
238
239     DeleteCriticalSection(&HelperDLLDatabaseLock);
240 }
241
242 /* EOF */