a13bf39c24ba9e9089ddf95af74f8da5755cbb61
[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"OpenIB Winsock Direct for InfiniBand";\r
49 static const char winsock_key_path[] =\r
50         "System\\CurrentControlSet\\Services\\Winsock\\Parameters\\TCP on SAN";\r
51 static const char openib_key_name[] = "OpenIB Alliance";\r
52 \r
53 /* Unique provider GUID generated with "uuidgen -s" */\r
54 static GUID provider_guid = {\r
55         /* c943654d-2c84-4db7-af3e-fdf1c5322458 */\r
56         0xc943654d, 0x2c84, 0x4db7,\r
57         { 0xaf, 0x3e, 0xfd, 0xf1, 0xc5, 0x32, 0x24,     0x58 }\r
58 };\r
59 \r
60 #ifdef _WIN64\r
61 #define WSCInstallProvider      WSCInstallProvider64_32\r
62 #endif  /* _WIN64 */\r
63 \r
64 #ifdef PERFMON_ENABLED\r
65 #include <Loadperf.h>\r
66 #include "wsd/ibsp_regpath.h"\r
67 \r
68 \r
69 typedef struct _pm_symbol_def\r
70 {\r
71         DWORD   name_def;\r
72         CHAR    name_str[40];\r
73         CHAR    name_desc[40];\r
74         CHAR    help_desc[256];\r
75 \r
76 } pm_symbol_def_t;\r
77 \r
78 static pm_symbol_def_t  _pm_symbols[]=\r
79 {\r
80         { IBSP_PM_OBJ,\r
81         "IBSP_PM_OBJ",\r
82         "IB Winsock Direct",\r
83         "InfiniBand Windows Sockets Direct Provider."\r
84         },\r
85         { IBSP_PM_COUNTER(BYTES_SEND),\r
86         "IBSP_PM_BYTES_TX_SEC",\r
87         "Send bytes/sec",\r
88         "Send bytes/second, excluding RDMA Write."\r
89         },\r
90         { IBSP_PM_COUNTER(BYTES_RECV),\r
91         "IBSP_PM_BYTES_RX_SEC",\r
92         "Recv bytes/sec",\r
93         "Receive bytes/second, excluding RDMA Read."\r
94         },\r
95         { IBSP_PM_COUNTER(BYTES_WRITE),\r
96         "IBSP_PM_RDMA_WR_SEC",\r
97         "RDMA Write bytes/sec",\r
98         "RDMA Write bytes/second."\r
99         },\r
100         { IBSP_PM_COUNTER(BYTES_READ),\r
101         "IBSP_PM_RDMA_RD_SEC",\r
102         "RDMA Read bytes/sec",\r
103         "RDMA Read bytes/second."\r
104         },\r
105         { IBSP_PM_COUNTER(BYTES_TOTAL),\r
106         "IBSP_PM_BYTES_SEC",\r
107         "Total bytes/sec",\r
108         "Total bytes transmitted per second, including send, "\r
109         "receive, RDMA Write, and RDMA Read."\r
110         },\r
111         { IBSP_PM_COUNTER(COMP_SEND),\r
112         "IBSP_PM_SEND_COMPLETIONS_SEC",\r
113         "Send Completions/sec",\r
114         "Send and RDMA Write Completions/sec."\r
115         },\r
116         { IBSP_PM_COUNTER(COMP_RECV),\r
117         "IBSP_PM_RECV_COMPLETIONS_SEC",\r
118         "Recv Completions/sec",\r
119         "Recv and RDMA Read Completions/sec."\r
120         },\r
121         { IBSP_PM_COUNTER(COMP_TOTAL),\r
122         "IBSP_PM_COMPLETIONS_SEC",\r
123         "Total Completions/sec",\r
124         "Total Completions processed per second."\r
125         },\r
126         { IBSP_PM_COUNTER(INTR_TOTAL),\r
127         "IBSP_PM_COMPLETIONS_INTR",\r
128         "Total Interrupts/sec",\r
129         "Completion Queue events per second."\r
130         }\r
131 };\r
132 \r
133 #define IBSP_PM_NUM_SYMBOLS  (sizeof(_pm_symbols)/sizeof(pm_symbol_def_t))\r
134 #define IBSP_PM_LANGUAGE "009" /* good for English */\r
135 \r
136 static CHAR *\r
137 _IBSPGenerateFileName(char *header,     char *file )\r
138 {\r
139         DWORD size1, size;\r
140         CHAR *full_file_name;\r
141         int header_len = header == NULL ? 0 : strlen(header);\r
142 \r
143         size = GetTempPath(0, NULL);\r
144         if (size == 0)\r
145         {\r
146                 fprintf( stderr, "GetTempPath  failed\n" );\r
147                 return NULL;\r
148         }\r
149         size1 = size + strlen(file) + header_len;\r
150         full_file_name = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, size1);\r
151         if ( full_file_name == NULL )\r
152         {\r
153                 fprintf( stderr, "GetTempPath  failed\n" );\r
154                 return NULL;\r
155         }\r
156         size1 = GetTempPath(size, full_file_name + header_len);\r
157         if (size != size1 + 1) \r
158         {\r
159                 fprintf( stderr, "Very strange, GetTempPath  returned something different\n" );\r
160                 HeapFree (GetProcessHeap (), 0, full_file_name);\r
161                 return NULL;\r
162         }\r
163         if (header_len != 0)\r
164         {\r
165                 memcpy(full_file_name, header, header_len);\r
166         }\r
167         strcat(full_file_name, file);\r
168         return full_file_name;\r
169 }\r
170 \r
171 \r
172 static DWORD\r
173 _IBSPPerfmonIniFilesGenerate( void )\r
174 {\r
175         FILE    *f_handle;\r
176         DWORD   num;\r
177         DWORD ret = ERROR_SUCCESS;\r
178         char *ibsp_pm_sym_file = NULL;\r
179         char *ibsp_pm_ini_file = NULL;\r
180 \r
181         /* create ".h" file first */\r
182         ibsp_pm_sym_file = _IBSPGenerateFileName(NULL, IBSP_PM_SYM_H_FILE);\r
183         if( !ibsp_pm_sym_file )\r
184         {\r
185                 fprintf( stderr, "_IBSPGenerateFileName  failed\n" );\r
186                 ret = ERROR_NOT_ENOUGH_MEMORY;\r
187                 goto Cleanup;\r
188         }\r
189 \r
190         f_handle = fopen( ibsp_pm_sym_file, "w+" );\r
191 \r
192         if( !f_handle )\r
193         {\r
194                 fprintf( stderr, "Create Header file %s failed\n", ibsp_pm_sym_file );\r
195                 ret = ERROR_FILE_INVALID;\r
196                 goto Cleanup;\r
197         }\r
198 \r
199         fprintf(\r
200                 f_handle, "/* %s Generated by program */ \r\n", ibsp_pm_sym_file );\r
201                 \r
202         \r
203         for( num = 0; num < IBSP_PM_NUM_SYMBOLS; num++ )\r
204         {\r
205                 fprintf( f_handle, "#define\t%s\t%d\r\n",\r
206                         _pm_symbols[num].name_str, _pm_symbols[num].name_def );\r
207         }\r
208 \r
209         fflush( f_handle );\r
210         fclose( f_handle );\r
211 \r
212         /* create 'ini' file next */\r
213         ibsp_pm_ini_file = _IBSPGenerateFileName(NULL, IBSP_PM_INI_FILE);\r
214         if( !ibsp_pm_sym_file )\r
215         {\r
216                 fprintf( stderr, "_IBSPGenerateFileName  failed\n" );\r
217                 ret = ERROR_NOT_ENOUGH_MEMORY;\r
218                 goto Cleanup;\r
219         }\r
220         f_handle = fopen( ibsp_pm_ini_file, "w+" );\r
221 \r
222         if( !f_handle )\r
223         {\r
224                 fprintf( stderr, "Create INI file %s  failed\n", ibsp_pm_ini_file );\r
225                 ret = ERROR_FILE_INVALID;\r
226                 goto Cleanup;\r
227         }\r
228         \r
229         fprintf( f_handle, "[info]\r\ndrivername=" IBSP_PM_SUBKEY_NAME\r
230                 "\r\nsymbolfile=%s\r\n\r\n", ibsp_pm_sym_file );\r
231         fprintf( f_handle,"[languages]\r\n" IBSP_PM_LANGUAGE\r
232                 "=language" IBSP_PM_LANGUAGE "\r\n\r\n" );\r
233 \r
234         fprintf( f_handle, \r
235                 "[objects]\r\n%s_" IBSP_PM_LANGUAGE "_NAME=%s\r\n\r\n[text]\r\n",\r
236                 _pm_symbols[0].name_str, _pm_symbols[0].name_desc );\r
237         \r
238         for( num = 0; num < IBSP_PM_NUM_SYMBOLS; num++ )\r
239         {\r
240                 fprintf( f_handle,"%s_" IBSP_PM_LANGUAGE "_NAME=%s\r\n",\r
241                         _pm_symbols[num].name_str, _pm_symbols[num].name_desc );\r
242                 fprintf( f_handle,"%s_" IBSP_PM_LANGUAGE "_HELP=%s\r\n",\r
243                         _pm_symbols[num].name_str, _pm_symbols[num].help_desc );\r
244         }\r
245 \r
246         fflush( f_handle );\r
247         fclose( f_handle );\r
248 \r
249 Cleanup:\r
250         if ( ibsp_pm_sym_file )\r
251         {\r
252                 HeapFree (GetProcessHeap (), 0, ibsp_pm_sym_file);\r
253         }\r
254         if ( ibsp_pm_ini_file )\r
255         {\r
256                 HeapFree (GetProcessHeap (), 0, ibsp_pm_ini_file);\r
257         }\r
258         return ret;\r
259 }\r
260 \r
261 \r
262 static void\r
263 _IBSPPerfmonIniFilesRemove( void )\r
264 {\r
265         char *ibsp_pm_sym_file = NULL;\r
266         char *ibsp_pm_ini_file = NULL;\r
267 \r
268         ibsp_pm_sym_file = _IBSPGenerateFileName(NULL, IBSP_PM_SYM_H_FILE);\r
269         if( !ibsp_pm_sym_file )\r
270         {\r
271                 fprintf( stderr, "_IBSPGenerateFileName  failed\n" );\r
272                 goto Cleanup;\r
273         }\r
274 \r
275         ibsp_pm_ini_file = _IBSPGenerateFileName(NULL, IBSP_PM_INI_FILE);\r
276         if( !ibsp_pm_sym_file )\r
277         {\r
278                 fprintf( stderr, "_IBSPGenerateFileName  failed\n" );\r
279                 goto Cleanup;\r
280         }\r
281 \r
282         if( !DeleteFile( ibsp_pm_ini_file ) )\r
283         {\r
284                 fprintf( stderr, "Delete file %s failed status %d\n",\r
285                         ibsp_pm_ini_file, GetLastError() );\r
286         }\r
287         if( !DeleteFile( ibsp_pm_sym_file ) )\r
288         {\r
289                 fprintf( stderr,"Delete file %s failed status %d\n",\r
290                         ibsp_pm_sym_file, GetLastError() );\r
291         }\r
292 \r
293 Cleanup:        \r
294         if ( ibsp_pm_sym_file )\r
295         {\r
296                 HeapFree (GetProcessHeap (), 0, ibsp_pm_sym_file);\r
297         }\r
298         if ( ibsp_pm_ini_file )\r
299         {\r
300                 HeapFree (GetProcessHeap (), 0, ibsp_pm_ini_file);\r
301         }\r
302         \r
303 }\r
304 \r
305 \r
306 /* Try to create IB WSD Performance Register Keys */\r
307 static LONG\r
308 _IBSPPerfmonRegisterKeys( void )\r
309 {\r
310         LONG    reg_status;\r
311         HKEY    pm_hkey;\r
312         DWORD   typesSupp = 7;\r
313 \r
314         reg_status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,\r
315                 IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF, 0, NULL,\r
316                 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &pm_hkey, NULL );\r
317 \r
318         if( reg_status != ERROR_SUCCESS )\r
319         {\r
320                 fprintf( stderr,\r
321                         "_IBSPPerfmonRegisterKeys Create Key %s failed with %d\n",\r
322                         IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF, reg_status );\r
323                 return reg_status;\r
324         }\r
325 \r
326         /* create/assign values to the key */\r
327         RegSetValueExW( pm_hkey, L"Library", 0, REG_EXPAND_SZ,\r
328                 (LPBYTE)provider_path, sizeof(provider_path) );\r
329 \r
330         RegSetValueEx( pm_hkey, TEXT("Open"), 0, REG_SZ,\r
331                 (LPBYTE)TEXT("IBSPPmOpen"), sizeof(TEXT("IBSPPmOpen")) );\r
332 \r
333         RegSetValueEx( pm_hkey, TEXT("Collect"), 0, REG_SZ,\r
334                 (LPBYTE)TEXT("IBSPPmCollectData"), sizeof(TEXT("IBSPPmCollectData")) );\r
335 \r
336         RegSetValueEx( pm_hkey, TEXT("Close"), 0, REG_SZ,\r
337                 (LPBYTE)TEXT("IBSPPmClose"), sizeof(TEXT("IBSPPmClose")) );\r
338 \r
339         RegFlushKey( pm_hkey );\r
340         RegCloseKey( pm_hkey );\r
341 \r
342         reg_status = RegCreateKeyEx( HKEY_LOCAL_MACHINE,\r
343                 IBSP_PM_EVENTLOG_PATH, 0, NULL,\r
344                 REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &pm_hkey, NULL );\r
345 \r
346         if( reg_status != ERROR_SUCCESS )\r
347         {\r
348                 fprintf(stderr, "Create EventLog Key failed with %d\n", reg_status );\r
349                 return reg_status;\r
350         }\r
351 \r
352         /* create/assign values to the key */\r
353         RegSetValueExW( pm_hkey, L"EventMessageFile", 0, REG_EXPAND_SZ,\\r
354                 (LPBYTE)provider_path, sizeof(provider_path) );\r
355 \r
356         RegSetValueEx( pm_hkey, TEXT("TypesSupported"), 0, REG_DWORD,\r
357                 (LPBYTE)&typesSupp, sizeof(typesSupp) );\r
358 \r
359         RegFlushKey( pm_hkey );\r
360         RegCloseKey( pm_hkey );\r
361 \r
362         return reg_status;\r
363 }\r
364 \r
365 \r
366 /* Try to destroy IB WSD Performance Register Keys */\r
367 static LONG\r
368 _IBSPPerfmonDeregisterKeys( void )\r
369 {\r
370         LONG    reg_status;\r
371 \r
372         reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
373                 IBSP_PM_REGISTRY_PATH IBSP_PM_SUBKEY_PERF,\r
374                 (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
375 \r
376         if( reg_status != ERROR_SUCCESS )\r
377         {\r
378                 fprintf( stderr,\r
379                         "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
380                         GetLastError() );\r
381         }\r
382 \r
383         reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
384                 IBSP_PM_REGISTRY_PATH, (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
385 \r
386         if( reg_status != ERROR_SUCCESS )\r
387         {\r
388                 fprintf( stderr,\r
389                         "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
390                         GetLastError() );\r
391         }\r
392 \r
393         reg_status = RegDeleteKeyEx( HKEY_LOCAL_MACHINE,\r
394                 IBSP_PM_EVENTLOG_PATH, (KEY_WOW64_32KEY | KEY_WOW64_64KEY), 0 );\r
395 \r
396         if( reg_status != ERROR_SUCCESS )\r
397         {\r
398                 fprintf( stderr,\r
399                         "_IBSPPerfmonRegisterKeys Remove SubKey failed with %d\n",\r
400                         GetLastError() );\r
401         }\r
402 \r
403         return reg_status;\r
404 }\r
405 \r
406 \r
407 /*\r
408  * functions will try to register performance counters\r
409  * definitions with PerfMon application.\r
410  * API externally called by lodctr.exe/unlodctr.exe utilities.\r
411  */\r
412 static DWORD\r
413 _IBSPPerfmonRegisterCounters( void )\r
414 {\r
415         DWORD status;\r
416         char *ibsp_pm_ini_file = NULL;\r
417 \r
418         ibsp_pm_ini_file = _IBSPGenerateFileName("unused ", IBSP_PM_INI_FILE);\r
419         if( !ibsp_pm_ini_file )\r
420         {\r
421                 fprintf( stderr, "_IBSPGenerateFileName  failed\n" );\r
422                 status = ERROR_NOT_ENOUGH_MEMORY;\r
423                 goto Cleanup;\r
424         }\r
425 \r
426         /*\r
427          * format commandline string, as per SDK :\r
428          *      Pointer to a null-terminated string that consists of one or more \r
429          *      arbitrary letters, a space, and then the name of the initialization\r
430          *      file.\r
431          */\r
432         status = LoadPerfCounterTextStrings( ibsp_pm_ini_file, TRUE );\r
433         if( status != ERROR_SUCCESS )\r
434         {\r
435                 status = GetLastError();\r
436                 fprintf( stderr,\r
437                         "IBSPPerfmonRegisterCounters install failed status %d\n", status );\r
438         }\r
439 Cleanup:        \r
440         if ( ibsp_pm_ini_file )\r
441         {\r
442                 HeapFree (GetProcessHeap (), 0, ibsp_pm_ini_file);\r
443         }\r
444 \r
445         return status;\r
446 }\r
447 \r
448 \r
449 /*\r
450  * functions will try to unregister performance counters\r
451  * definitions with PerfMon application.\r
452  * API externally called by lodctr.exe/unlodctr.exe utilities.\r
453  */\r
454 static DWORD\r
455 _IBSPPerfmonDeregisterCounters( void )\r
456 {\r
457         DWORD status;\r
458 \r
459         /*\r
460          * format commandline string, as per SDK :\r
461          *      Pointer to a null-terminated string that consists of one or more \r
462          *      arbitrary letters, a space, and then the name of the initialization\r
463          *      file.\r
464          */\r
465         status = UnloadPerfCounterTextStrings(\r
466                 TEXT("unused ") TEXT(IBSP_PM_SUBKEY_NAME), TRUE );\r
467         if( status != ERROR_SUCCESS )\r
468         {\r
469                 fprintf( stderr,\r
470                         "IBSPPerfmonDeregisterCounters remove failed status %d\n",\r
471                         status );\r
472         }\r
473         return status;\r
474 }\r
475 \r
476 #endif /* PERFMON_ENABLED */\r
477 \r
478 \r
479 /*\r
480  * Function: usage\r
481  *   Description: Prints usage information.\r
482  */\r
483 static void\r
484 usage (char *progname)\r
485 {\r
486         printf ("usage: %s [-i/-r [-p]]\n", progname);\r
487         printf ("    -i   Install the service provider\n"\r
488                         "    -r   Remove the OpenIB service provider\n"\r
489                         "    -r <name>   Remove the specified service provider\n"\r
490                         "    -l   List service providers\n");\r
491 }\r
492 \r
493 \r
494 /* Function: print_providers\r
495  *   Description: \r
496  *     This function prints out each entry in the Winsock catalog.\r
497 */\r
498 static void print_providers(void)\r
499 {\r
500         WSAPROTOCOL_INFOW *protocol_info;\r
501         unsigned int protocol_count;\r
502         unsigned int i;\r
503         DWORD protocol_size;\r
504         INT errno;\r
505         int rc;\r
506 \r
507         /* Find the size of the buffer */\r
508         protocol_size = 0;\r
509         rc = WSCEnumProtocols (NULL, NULL, &protocol_size, &errno);\r
510         if (rc == SOCKET_ERROR && errno != WSAENOBUFS) {\r
511                 printf("WSCEnumProtocols() returned error (%d)\n", errno);\r
512                 return;\r
513         }\r
514 \r
515         /* Allocate the buffer */\r
516         protocol_info = HeapAlloc (GetProcessHeap (), HEAP_ZERO_MEMORY, protocol_size);\r
517         if (protocol_info == NULL) {\r
518                 printf("HeapAlloc() failed\n");\r
519                 return;\r
520         }\r
521 \r
522         /* Enumerate the catalog for real */\r
523         rc = WSCEnumProtocols (NULL, protocol_info, &protocol_size, &errno);\r
524         if (rc == SOCKET_ERROR) {\r
525                 printf("WSCEnumProtocols returned error for real enumeration (%d)\n",\r
526                          errno);\r
527                 HeapFree (GetProcessHeap (), 0, protocol_info);\r
528                 return;\r
529         }\r
530 \r
531         protocol_count = rc;\r
532 \r
533         for (i = 0; i < protocol_count; i++) {\r
534                 printf ("%010d - %S\n", protocol_info[i].dwCatalogEntryId,\r
535                                 protocol_info[i].szProtocol);\r
536         }\r
537 \r
538         HeapFree (GetProcessHeap (), 0, protocol_info);\r
539 \r
540         return;\r
541 }\r
542 \r
543 /*\r
544  * Function: install_provider\r
545  *   Description: installs the service provider\r
546  *\r
547  * Note: most of the information setup here comes from "MSDN Home >\r
548  * MSDN Library > Windows Development > Network Devices and\r
549  * Protocols > Design Guide > System Area Networks > Windows Sockets\r
550  * Direct > Windows Sockets Direct Component Operation > Installing\r
551  * Windows Sockets Direct Components".\r
552  * The direct link is http://msdn.microsoft.com/library/default.asp?url=/library/en-us/network/hh/network/wsdp_2xrb.asp\r
553  */\r
554 static void install_provider(void)\r
555 {\r
556         int rc;\r
557         INT errno;\r
558         LONG reg_error;\r
559         WSAPROTOCOL_INFOW provider;\r
560         HKEY hkey;\r
561 \r
562         /* Now setup the key. */\r
563         reg_error = RegCreateKeyExA( HKEY_LOCAL_MACHINE, winsock_key_path,\r
564                 0, NULL, REG_OPTION_NON_VOLATILE, (KEY_WRITE | KEY_READ), NULL,\r
565                 &hkey, NULL );\r
566         if( reg_error == ERROR_SUCCESS )\r
567         {\r
568                 reg_error = RegSetValueExA( hkey, openib_key_name, 0, REG_BINARY,\r
569                         (PBYTE)&provider_guid, sizeof(GUID) );\r
570                 if( reg_error == ERROR_SUCCESS )\r
571                 {\r
572                         /* Force the system to write the new key now. */\r
573                         RegFlushKey(hkey);\r
574                 }\r
575                 else\r
576                 {\r
577                         fprintf(stderr, "RegSetValueEx failed with %d\n", GetLastError());\r
578                 }\r
579 \r
580                 RegCloseKey(hkey);\r
581         }\r
582         else\r
583         {\r
584                 fprintf(stderr, "Could not get a handle on Winsock registry (%d)\n", GetLastError());\r
585         }\r
586 \r
587         /* Setup the values in PROTOCOL_INFO */\r
588         provider.dwServiceFlags1 = \r
589                 XP1_GUARANTEED_DELIVERY | \r
590                 XP1_GUARANTEED_ORDER | \r
591                 XP1_MESSAGE_ORIENTED |\r
592                 XP1_GRACEFUL_CLOSE;\r
593         provider.dwServiceFlags2 = 0;   /* Reserved */\r
594         provider.dwServiceFlags3 = 0;   /* Reserved */\r
595         provider.dwServiceFlags4 = 0;   /* Reserved */\r
596         provider.dwProviderFlags = PFL_HIDDEN;\r
597         provider.ProviderId = provider_guid;    /* Service Provider ID provided by vendor. Need to be changed later */\r
598         provider.dwCatalogEntryId = 0;\r
599         provider.ProtocolChain.ChainLen = 1;    /* Base Protocol Service Provider */\r
600         provider.iVersion = 2;  /* don't know what it is */\r
601         provider.iAddressFamily = AF_INET;\r
602         provider.iMaxSockAddr = 16;\r
603         provider.iMinSockAddr = 16;\r
604         provider.iSocketType = SOCK_STREAM;\r
605         provider.iProtocol = IPPROTO_TCP;\r
606         provider.iProtocolMaxOffset = 0;\r
607         provider.iNetworkByteOrder = BIGENDIAN;\r
608         provider.iSecurityScheme = SECURITY_PROTOCOL_NONE;\r
609         provider.dwMessageSize = 0xFFFFFFFF; /* IB supports 32-bit lengths for data transfers on RC */\r
610         provider.dwProviderReserved = 0;\r
611         wcscpy( provider.szProtocol, provider_name );\r
612 \r
613         rc = WSCInstallProvider(\r
614                 &provider_guid, provider_path, &provider, 1, &errno );\r
615         if( rc == SOCKET_ERROR )\r
616         {\r
617                 if( errno == WSANO_RECOVERY )\r
618                         printf("The provider is already installed\n");\r
619                 else\r
620                         printf("install_provider: WSCInstallProvider failed: %d\n", errno);\r
621         }\r
622 }\r
623 \r
624 /*\r
625  * Function: remove_provider\r
626  *   Description: removes our provider.\r
627  */\r
628 static void remove_provider( const char* const provider_name )\r
629 {\r
630         int rc;\r
631         int errno;\r
632         LONG reg_error;\r
633         HKEY hkey;\r
634 \r
635         /* Remove our key */\r
636         reg_error = RegOpenKeyExA(HKEY_LOCAL_MACHINE,\r
637                                                          winsock_key_path,\r
638                                                          0,\r
639                                                          (KEY_WRITE | KEY_READ),\r
640                                                          &hkey);\r
641         if (reg_error == ERROR_SUCCESS) {\r
642 \r
643                 reg_error = RegDeleteValueA(hkey, provider_name);\r
644                 if (reg_error == ERROR_SUCCESS) {\r
645                         /* Force the system to remove the key now. */\r
646                         RegFlushKey(hkey);\r
647                 } else {\r
648                         fprintf(stderr, "RegDeleteValue failed with %d\n", GetLastError());\r
649                 }\r
650 \r
651                 RegCloseKey(hkey);\r
652         }\r
653 \r
654         /* Remove from the catalog */\r
655         rc = WSCDeinstallProvider(&provider_guid, &errno);\r
656         if (rc == SOCKET_ERROR) {\r
657                 printf ("WSCDeinstallProvider failed: %d\n", errno);\r
658         }\r
659 \r
660 #ifdef _WIN64\r
661         /* Remove from the 32-bit catalog too! */\r
662         rc = WSCDeinstallProvider32(&provider_guid, &errno);\r
663         if (rc == SOCKET_ERROR) {\r
664                 printf ("WSCDeinstallProvider32 failed: %d\n", errno);\r
665         }\r
666 #endif  /* _WIN64 */\r
667 }\r
668 \r
669 /* Function: main\r
670  *\r
671  *  Description:\r
672  *    Parse the command line arguments and call either the install or remove\r
673  *    routine.\r
674  */\r
675 int __cdecl main (int argc, char *argv[])\r
676 {\r
677         WSADATA wsd;\r
678 \r
679         /* Load Winsock */\r
680         if (WSAStartup (MAKEWORD (2, 2), &wsd) != 0) {\r
681                 printf ("InstallSP: Unable to load Winsock: %d\n", GetLastError ());\r
682                 return -1;\r
683         }\r
684 \r
685         /* Confirm that the WinSock DLL supports 2.2. Note that if the\r
686          * DLL supports versions greater than 2.2 in addition to 2.2, it\r
687          * will still return 2.2 in wVersion since that is the version we\r
688          * requested. */\r
689         if (LOBYTE (wsd.wVersion) != 2 || HIBYTE (wsd.wVersion) != 2) {\r
690 \r
691                 /* Tell the user that we could not find a usable WinSock DLL. */\r
692                 WSACleanup ();\r
693                 printf\r
694                         ("InstallSP: Unable to find a usable version of Winsock DLL\n");\r
695                 return -1;\r
696         }\r
697         if (argc < 2) {\r
698                 usage (argv[0]);\r
699                 return -1;\r
700         }\r
701         if ((strlen (argv[1]) != 2) && (argv[1][0] != '-')\r
702                 && (argv[1][0] != '/')) {\r
703                 usage (argv[0]);\r
704                 return -1;\r
705         }\r
706         switch (tolower (argv[1][1])) {\r
707 \r
708         case 'i':\r
709                 /* Install the Infiniband Service Provider */\r
710                 install_provider ();\r
711 #ifdef PERFMON_ENABLED\r
712                 _IBSPPerfmonIniFilesGenerate();\r
713                 if ( _IBSPPerfmonRegisterKeys() == ERROR_SUCCESS )\r
714                                 _IBSPPerfmonRegisterCounters();\r
715 #endif\r
716                 break;\r
717 \r
718         case 'r':\r
719                 /* Remove the service provider */\r
720                 if( argc == 2 )\r
721                         remove_provider( openib_key_name );\r
722                 else\r
723                         remove_provider( argv[2] );\r
724 #ifdef PERFMON_ENABLED\r
725                 _IBSPPerfmonIniFilesRemove();\r
726                 if ( _IBSPPerfmonDeregisterCounters() == ERROR_SUCCESS )\r
727                         _IBSPPerfmonDeregisterKeys();\r
728 #endif\r
729                 break;\r
730 \r
731         case 'l':\r
732                 /* List existing providers */\r
733                 print_providers();\r
734                 break;\r
735         \r
736         default:\r
737                 usage (argv[0]);\r
738                 break;\r
739         }\r
740 \r
741         WSACleanup ();\r
742 \r
743         return 0;\r
744 }\r