c31fcb31a71db256a26dd04dbdcee8740c2c0dc2
[mirror/winof/.git] / tools / wsdinstall / user / installsp.c
1 /*\r
2  * Copyright (c) 2005 SilverStorm Technologies.  All rights reserved.\r
3  *\r
4  * This software is available to you under the OpenIB.org BSD license\r
5  * below:\r
6  *\r
7  *     Redistribution and use in source and binary forms, with or\r
8  *     without modification, are permitted provided that the following\r
9  *     conditions are met:\r
10  *\r
11  *      - Redistributions of source code must retain the above\r
12  *        copyright notice, this list of conditions and the following\r
13  *        disclaimer.\r
14  *\r
15  *      - Redistributions in binary form must reproduce the above\r
16  *        copyright notice, this list of conditions and the following\r
17  *        disclaimer in the documentation and/or other materials\r
18  *        provided with the distribution.\r
19  *\r
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS\r
24  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN\r
25  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
26  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
27  * SOFTWARE.\r
28  *\r
29  * $Id$\r
30  */\r
31 \r
32 /*\r
33  *      Module Name: installsp.c\r
34  *      Description: This module installs/removes a winsock service provider for infiniband. \r
35  *      execute:\r
36  *      To install the service provider\r
37  *              installsp -i        \r
38  *      To remove the service provider\r
39  *              installsp -r\r
40  */\r
41 \r
42 #include <winsock2.h>\r
43 #include <ws2spi.h>\r
44 #include <stdio.h>\r
45 \r
46 /* Initialize the LSP's provider path for Infiband Service Provider dll */\r
47 static const WCHAR *provider_path = L"%SYSTEMROOT%\\system32\\ibwsd.dll";\r
48 static const WCHAR *provider_name = L"SilverStorm Winsock Direct for InfiniBand";\r
49 static const char *winsock_key_path = "System\\CurrentControlSet\\Services\\Winsock\\Parameters\\TCP on SAN";\r
50 static const char *silverstorm_key_name = "SilverStorm InfiniBand";\r
51 \r
52 /* Unique provider GUID generated with "uuidgen -s" */\r
53 static GUID provider_guid = {\r
54         /* c943654d-2c84-4db7-af3e-fdf1c5322458 */\r
55         0xc943654d, 0x2c84, 0x4db7,\r
56         { 0xaf, 0x3e, 0xfd, 0xf1, 0xc5, 0x32, 0x24,     0x58 }\r
57 };\r
58 \r
59 #ifdef _WIN64\r
60 #define WSCInstallProvider      WSCInstallProvider64_32\r
61 #endif  /* _WIN64 */\r
62 \r
63 /*\r
64  * Function: usage\r
65  *   Description: Prints usage information.\r
66  */\r
67 static void\r
68 usage (char *progname)\r
69 {\r
70         printf ("usage: %s [-i/-r]\n", progname);\r
71         printf ("       -i   Install the service provider\n"\r
72                         "       -r   Remove the service provider\n"\r
73                         "       -l   List service providers\n");\r
74 }\r
75 \r
76 \r
77 /* Function: print_providers\r
78  *   Description: \r
79  *     This function prints out each entry in the Winsock catalog.\r
80 */\r
81 static void print_providers(void)\r
82 {\r
83         WSAPROTOCOL_INFOW *protocol_info;\r
84         unsigned int protocol_count;\r
85         unsigned int i;\r
86         DWORD protocol_size;\r
87         INT errno;\r
88         int rc;\r
89 \r
90         /* Find the size of the buffer */\r
91         protocol_size = 0;\r
92         rc = WSCEnumProtocols (NULL, NULL, &protocol_size, &errno);\r
93         if (rc == SOCKET_ERROR && errno != WSAENOBUFS) {\r
94                 printf("WSCEnumProtocols() returned error (%d)\n", errno);\r
95                 return;\r
96         }\r
97 \r
98         /* Allocate the buffer */\r
99         protocol_info = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, protocol_size);\r
100         if (protocol_info == NULL) {\r
101                 printf("HeapAlloc() failed\n");\r
102                 return;\r
103         }\r
104 \r
105         /* Enumerate the catalog for real */\r
106         rc = WSCEnumProtocols (NULL, protocol_info, &protocol_size, &errno);\r
107         if (rc == SOCKET_ERROR) {\r
108                 printf("WSCEnumProtocols returned error for real enumeration (%d)\n",\r
109                          errno);\r
110                 HeapFree (GetProcessHeap (), 0, protocol_info);\r
111                 return;\r
112         }\r
113 \r
114         protocol_count = rc;\r
115 \r
116         for (i = 0; i < protocol_count; i++) {\r
117                 printf ("%010d - %S\n", protocol_info[i].dwCatalogEntryId,\r
118                                 protocol_info[i].szProtocol);\r
119         }\r
120 \r
121         HeapFree (GetProcessHeap (), 0, protocol_info);\r
122 \r
123         return;\r
124 }\r
125 \r
126 /*\r
127  * Function: install_provider\r
128  *   Description: installs the service provider\r
129  *\r
130  * Note: most of the information setup here comes from "MSDN Home >\r
131  * MSDN Library > Windows Development > Network Devices and\r
132  * Protocols > Design Guide > System Area Networks > Windows Sockets\r
133  * Direct > Windows Sockets Direct Component Operation > Installing\r
134  * Windows Sockets Direct Components".\r
135  * The direct link is http://msdn.microsoft.com/library/default.asp?url=/library/en-us/network/hh/network/wsdp_2xrb.asp\r
136  */\r
137 static void install_provider(void)\r
138 {\r
139         int rc;\r
140         INT errno;\r
141         LONG reg_error;\r
142         WSAPROTOCOL_INFOW provider;\r
143         HKEY hkey;\r
144 \r
145         /* Now setup the key. */\r
146         reg_error = RegCreateKeyEx( HKEY_LOCAL_MACHINE, winsock_key_path, 0, NULL,\r
147                 REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL, &hkey, NULL );\r
148         if( reg_error == ERROR_SUCCESS )\r
149         {\r
150                 reg_error = RegSetValueEx( hkey, silverstorm_key_name, 0, REG_BINARY,\r
151                         (PBYTE)&provider_guid, sizeof(GUID) );\r
152                 if( reg_error == ERROR_SUCCESS )\r
153                 {\r
154                         /* Force the system to write the new key now. */\r
155                         RegFlushKey(hkey);\r
156                 }\r
157                 else\r
158                 {\r
159                         fprintf(stderr, "RegSetValueEx failed with %d\n", GetLastError());\r
160                 }\r
161 \r
162                 RegCloseKey(hkey);\r
163         }\r
164         else\r
165         {\r
166                 fprintf(stderr, "Could not get a handle on Winsock registry (%d)\n", GetLastError());\r
167         }\r
168 \r
169         /* Setup the values in PROTOCOL_INFO */\r
170         provider.dwServiceFlags1 = \r
171                 XP1_GUARANTEED_DELIVERY | \r
172                 XP1_GUARANTEED_ORDER | \r
173                 XP1_MESSAGE_ORIENTED |\r
174                 XP1_GRACEFUL_CLOSE;\r
175         provider.dwServiceFlags2 = 0;   /* Reserved */\r
176         provider.dwServiceFlags3 = 0;   /* Reserved */\r
177         provider.dwServiceFlags4 = 0;   /* Reserved */\r
178         provider.dwProviderFlags = PFL_HIDDEN;\r
179         provider.ProviderId = provider_guid;    /* Service Provider ID provided by vendor. Need to be changed later */\r
180         provider.dwCatalogEntryId = 0;\r
181         provider.ProtocolChain.ChainLen = 1;    /* Base Protocol Service Provider */\r
182         provider.iVersion = 2;  /* don't know what it is */\r
183         provider.iAddressFamily = AF_INET;\r
184         provider.iMaxSockAddr = 16;\r
185         provider.iMinSockAddr = 16;\r
186         provider.iSocketType = SOCK_STREAM;\r
187         provider.iProtocol = IPPROTO_TCP;\r
188         provider.iProtocolMaxOffset = 0;\r
189         provider.iNetworkByteOrder = BIGENDIAN;\r
190         provider.iSecurityScheme = SECURITY_PROTOCOL_NONE;\r
191         provider.dwMessageSize = 0xFFFFFFFF; /* IB supports 32-bit lengths for data transfers on RC */\r
192         provider.dwProviderReserved = 0;\r
193         wcscpy( provider.szProtocol, provider_name );\r
194 \r
195         rc = WSCInstallProvider(\r
196                 &provider_guid, provider_path, &provider, 1, &errno );\r
197         if( rc == SOCKET_ERROR )\r
198         {\r
199                 if( errno == WSANO_RECOVERY )\r
200                         printf("The provider is already installed\n");\r
201                 else\r
202                         printf("install_provider: WSCInstallProvider failed: %d\n", errno);\r
203         }\r
204 }\r
205 \r
206 /*\r
207  * Function: remove_provider\r
208  *   Description: removes our provider.\r
209  */\r
210 static void remove_provider(void)\r
211 {\r
212         int rc;\r
213         int errno;\r
214         LONG reg_error;\r
215         HKEY hkey;\r
216 \r
217         /* Remove our key */\r
218         reg_error = RegOpenKeyEx(HKEY_LOCAL_MACHINE,\r
219                                                          winsock_key_path,\r
220                                                          0,\r
221                                                          (KEY_WRITE | KEY_READ),\r
222                                                          &hkey);\r
223         if (reg_error == ERROR_SUCCESS) {\r
224 \r
225                 reg_error = RegDeleteValue(hkey, silverstorm_key_name);\r
226                 if (reg_error == ERROR_SUCCESS) {\r
227                         /* Force the system to remove the key now. */\r
228                         RegFlushKey(hkey);\r
229                 } else {\r
230                         fprintf(stderr, "RegDeleteValue failed with %d\n", GetLastError());\r
231                 }\r
232 \r
233                 RegCloseKey(hkey);\r
234         }\r
235 \r
236         /* Remove from the catalog */\r
237         rc = WSCDeinstallProvider(&provider_guid, &errno);\r
238         if (rc == SOCKET_ERROR) {\r
239                 printf ("WSCDeinstallProvider failed: %d\n", errno);\r
240         }\r
241 \r
242 #ifdef _WIN64\r
243         /* Remove from the 32-bit catalog too! */\r
244         rc = WSCDeinstallProvider32(&provider_guid, &errno);\r
245         if (rc == SOCKET_ERROR) {\r
246                 printf ("WSCDeinstallProvider32 failed: %d\n", errno);\r
247         }\r
248 #endif  /* _WIN64 */\r
249 }\r
250 \r
251 /* Function: main\r
252  *\r
253  *  Description:\r
254  *    Parse the command line arguments and call either the install or remove\r
255  *    routine.\r
256  */\r
257 int __cdecl main (int argc, char *argv[])\r
258 {\r
259         WSADATA wsd;\r
260 \r
261         /* Load Winsock */\r
262         if (WSAStartup (MAKEWORD (2, 2), &wsd) != 0) {\r
263                 printf ("InstallSP: Unable to load Winsock: %d\n", GetLastError ());\r
264                 return -1;\r
265         }\r
266 \r
267         /* Confirm that the WinSock DLL supports 2.2. Note that if the\r
268          * DLL supports versions greater than 2.2 in addition to 2.2, it\r
269          * will still return 2.2 in wVersion since that is the version we\r
270          * requested. */\r
271         if (LOBYTE (wsd.wVersion) != 2 || HIBYTE (wsd.wVersion) != 2) {\r
272 \r
273                 /* Tell the user that we could not find a usable WinSock DLL. */\r
274                 WSACleanup ();\r
275                 printf\r
276                         ("InstallSP: Unable to find a usable version of Winsock DLL\n");\r
277                 return -1;\r
278         }\r
279         if (argc != 2) {\r
280                 usage (argv[0]);\r
281                 return -1;\r
282         }\r
283         if ((strlen (argv[1]) != 2) && (argv[1][0] != '-')\r
284                 && (argv[1][0] != '/')) {\r
285                 usage (argv[0]);\r
286                 return -1;\r
287         }\r
288         switch (tolower (argv[1][1])) {\r
289 \r
290         case 'i':\r
291                 /* Install the Infiniband Service Provider */\r
292                 install_provider ();\r
293                 break;\r
294 \r
295         case 'r':\r
296                 /* Remove the service provider */\r
297                 remove_provider ();\r
298                 break;\r
299 \r
300         case 'l':\r
301                 /* List existing providers */\r
302                 print_providers();\r
303                 break;\r
304 \r
305         default:\r
306                 usage (argv[0]);\r
307                 break;\r
308         }\r
309 \r
310         WSACleanup ();\r
311 \r
312         return 0;\r
313 }\r