00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "JackSystemDeps.h"
00022 #include "JackDriverLoader.h"
00023 #include "JackConstants.h"
00024 #include "JackError.h"
00025 #include <getopt.h>
00026 #include <stdio.h>
00027 #include <errno.h>
00028
00029 #ifndef WIN32
00030 #include <dirent.h>
00031 #endif
00032
00033 jack_driver_desc_t * jackctl_driver_get_desc(jackctl_driver_t * driver);
00034
00035 static void
00036 jack_print_driver_options (jack_driver_desc_t * desc, FILE *file)
00037 {
00038 unsigned long i;
00039 char arg_default[JACK_DRIVER_PARAM_STRING_MAX + 1];
00040
00041 for (i = 0; i < desc->nparams; i++) {
00042 switch (desc->params[i].type) {
00043 case JackDriverParamInt:
00044 sprintf (arg_default, "%" "i", desc->params[i].value.i);
00045 break;
00046 case JackDriverParamUInt:
00047 sprintf (arg_default, "%" "u", desc->params[i].value.ui);
00048 break;
00049 case JackDriverParamChar:
00050 sprintf (arg_default, "%c", desc->params[i].value.c);
00051 break;
00052 case JackDriverParamString:
00053 if (desc->params[i].value.str && strcmp (desc->params[i].value.str, "") != 0)
00054 sprintf (arg_default, "%s", desc->params[i].value.str);
00055 else
00056 sprintf (arg_default, "none");
00057 break;
00058 case JackDriverParamBool:
00059 sprintf (arg_default, "%s", desc->params[i].value.i ? "true" : "false");
00060 break;
00061 }
00062
00063 fprintf (file, "\t-%c, --%s \t%s (default: %s)\n",
00064 desc->params[i].character,
00065 desc->params[i].name,
00066 desc->params[i].short_desc,
00067 arg_default);
00068 }
00069 }
00070
00071 static void
00072 jack_print_driver_param_usage (jack_driver_desc_t * desc, unsigned long param, FILE *file)
00073 {
00074 fprintf (file, "Usage information for the '%s' parameter for driver '%s':\n",
00075 desc->params[param].name, desc->name);
00076 fprintf (file, "%s\n", desc->params[param].long_desc);
00077 }
00078
00079 SERVER_EXPORT void jack_free_driver_params(JSList * driver_params)
00080 {
00081 JSList *node_ptr = driver_params;
00082 JSList *next_node_ptr;
00083
00084 while (node_ptr) {
00085 next_node_ptr = node_ptr->next;
00086 free(node_ptr->data);
00087 free(node_ptr);
00088 node_ptr = next_node_ptr;
00089 }
00090 }
00091
00092 int
00093 jack_parse_driver_params (jack_driver_desc_t * desc, int argc, char* argv[], JSList ** param_ptr)
00094 {
00095 struct option * long_options;
00096 char * options, * options_ptr;
00097 unsigned long i;
00098 int opt;
00099 unsigned int param_index;
00100 JSList * params = NULL;
00101 jack_driver_param_t * driver_param;
00102
00103 if (argc <= 1) {
00104 *param_ptr = NULL;
00105 return 0;
00106 }
00107
00108
00109 if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) {
00110 if (argc > 2) {
00111 for (i = 0; i < desc->nparams; i++) {
00112 if (strcmp (desc->params[i].name, argv[2]) == 0) {
00113 jack_print_driver_param_usage (desc, i, stdout);
00114 return 1;
00115 }
00116 }
00117
00118 fprintf (stderr, "jackd: unknown option '%s' "
00119 "for driver '%s'\n", argv[2],
00120 desc->name);
00121 }
00122
00123 printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name);
00124 jack_print_driver_options (desc, stdout);
00125 return 1;
00126 }
00127
00128
00129 options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char));
00130 long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option));
00131
00132 options_ptr = options;
00133 for (i = 0; i < desc->nparams; i++) {
00134 sprintf (options_ptr, "%c::", desc->params[i].character);
00135 options_ptr += 3;
00136 long_options[i].name = desc->params[i].name;
00137 long_options[i].flag = NULL;
00138 long_options[i].val = desc->params[i].character;
00139 long_options[i].has_arg = optional_argument;
00140 }
00141
00142
00143 optind = 0;
00144 opterr = 0;
00145 while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) {
00146
00147 if (opt == ':' || opt == '?') {
00148 if (opt == ':') {
00149 fprintf (stderr, "Missing option to argument '%c'\n", optopt);
00150 } else {
00151 fprintf (stderr, "Unknownage with option '%c'\n", optopt);
00152 }
00153
00154 fprintf (stderr, "Options for driver '%s':\n", desc->name);
00155 jack_print_driver_options (desc, stderr);
00156 exit (1);
00157 }
00158
00159 for (param_index = 0; param_index < desc->nparams; param_index++) {
00160 if (opt == desc->params[param_index].character) {
00161 break;
00162 }
00163 }
00164
00165 driver_param = (jack_driver_param_t*)calloc (1, sizeof (jack_driver_param_t));
00166 driver_param->character = desc->params[param_index].character;
00167
00168 if (!optarg && optind < argc &&
00169 strlen(argv[optind]) &&
00170 argv[optind][0] != '-') {
00171 optarg = argv[optind];
00172 }
00173
00174 if (optarg) {
00175 switch (desc->params[param_index].type) {
00176 case JackDriverParamInt:
00177 driver_param->value.i = atoi (optarg);
00178 break;
00179 case JackDriverParamUInt:
00180 driver_param->value.ui = strtoul (optarg, NULL, 10);
00181 break;
00182 case JackDriverParamChar:
00183 driver_param->value.c = optarg[0];
00184 break;
00185 case JackDriverParamString:
00186 strncpy (driver_param->value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
00187 break;
00188 case JackDriverParamBool:
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 if (strcmp ("false", optarg) == 0 ||
00199 strcmp ("off", optarg) == 0 ||
00200 strcmp ("no", optarg) == 0 ||
00201 strcmp ("0", optarg) == 0 ||
00202 strcmp ("(null)", optarg) == 0 ) {
00203 driver_param->value.i = false;
00204
00205 } else {
00206
00207 driver_param->value.i = true;
00208
00209 }
00210 break;
00211 }
00212 } else {
00213 if (desc->params[param_index].type == JackDriverParamBool) {
00214 driver_param->value.i = true;
00215 } else {
00216 driver_param->value = desc->params[param_index].value;
00217 }
00218 }
00219
00220 params = jack_slist_append (params, driver_param);
00221 }
00222
00223 free (options);
00224 free (long_options);
00225
00226 if (param_ptr)
00227 *param_ptr = params;
00228
00229 return 0;
00230 }
00231
00232 SERVER_EXPORT int
00233 jackctl_parse_driver_params (jackctl_driver *driver_ptr, int argc, char* argv[])
00234 {
00235 struct option * long_options;
00236 char * options, * options_ptr;
00237 unsigned long i;
00238 int opt;
00239 JSList * node_ptr;
00240 jackctl_parameter_t * param = NULL;
00241 union jackctl_parameter_value value;
00242
00243 if (argc <= 1)
00244 return 0;
00245
00246 const JSList * driver_params = jackctl_driver_get_parameters(driver_ptr);
00247 if (driver_params == NULL)
00248 return 1;
00249
00250 jack_driver_desc_t * desc = jackctl_driver_get_desc(driver_ptr);
00251
00252
00253 if (strcmp (argv[1], "-h") == 0 || strcmp (argv[1], "--help") == 0) {
00254 if (argc > 2) {
00255 for (i = 0; i < desc->nparams; i++) {
00256 if (strcmp (desc->params[i].name, argv[2]) == 0) {
00257 jack_print_driver_param_usage (desc, i, stdout);
00258 return 1;
00259 }
00260 }
00261
00262 fprintf (stderr, "jackd: unknown option '%s' "
00263 "for driver '%s'\n", argv[2],
00264 desc->name);
00265 }
00266
00267 printf ("Parameters for driver '%s' (all parameters are optional):\n", desc->name);
00268 jack_print_driver_options (desc, stdout);
00269 return 1;
00270 }
00271
00272
00273 options = (char*)calloc (desc->nparams * 3 + 1, sizeof (char));
00274 long_options = (option*)calloc (desc->nparams + 1, sizeof (struct option));
00275
00276 options_ptr = options;
00277 for (i = 0; i < desc->nparams; i++) {
00278 sprintf (options_ptr, "%c::", desc->params[i].character);
00279 options_ptr += 3;
00280 long_options[i].name = desc->params[i].name;
00281 long_options[i].flag = NULL;
00282 long_options[i].val = desc->params[i].character;
00283 long_options[i].has_arg = optional_argument;
00284 }
00285
00286
00287 optind = 0;
00288 opterr = 0;
00289 while ((opt = getopt_long(argc, argv, options, long_options, NULL)) != -1) {
00290
00291 if (opt == ':' || opt == '?') {
00292 if (opt == ':') {
00293 fprintf (stderr, "Missing option to argument '%c'\n", optopt);
00294 } else {
00295 fprintf (stderr, "Unknownage with option '%c'\n", optopt);
00296 }
00297
00298 fprintf (stderr, "Options for driver '%s':\n", desc->name);
00299 jack_print_driver_options(desc, stderr);
00300 return 1;
00301 }
00302
00303 node_ptr = (JSList *)driver_params;
00304 while (node_ptr) {
00305 param = (jackctl_parameter_t*)node_ptr->data;
00306 if (opt == jackctl_parameter_get_id(param)) {
00307 break;
00308 }
00309 node_ptr = node_ptr->next;
00310 }
00311
00312 if (!optarg && optind < argc &&
00313 strlen(argv[optind]) &&
00314 argv[optind][0] != '-') {
00315 optarg = argv[optind];
00316 }
00317
00318 if (optarg) {
00319 switch (jackctl_parameter_get_type(param)) {
00320 case JackDriverParamInt:
00321 value.i = atoi (optarg);
00322 jackctl_parameter_set_value(param, &value);
00323 break;
00324 case JackDriverParamUInt:
00325 value.ui = strtoul (optarg, NULL, 10);
00326 jackctl_parameter_set_value(param, &value);
00327 break;
00328 case JackDriverParamChar:
00329 value.c = optarg[0];
00330 jackctl_parameter_set_value(param, &value);
00331 break;
00332 case JackDriverParamString:
00333 strncpy (value.str, optarg, JACK_DRIVER_PARAM_STRING_MAX);
00334 jackctl_parameter_set_value(param, &value);
00335 break;
00336 case JackDriverParamBool:
00337
00338
00339
00340
00341
00342
00343
00344
00345 if (strcmp ("false", optarg) == 0 ||
00346 strcmp ("off", optarg) == 0 ||
00347 strcmp ("no", optarg) == 0 ||
00348 strcmp ("0", optarg) == 0 ||
00349 strcmp ("(null)", optarg) == 0 ) {
00350 value.i = false;
00351 } else {
00352 value.i = true;
00353 }
00354 jackctl_parameter_set_value(param, &value);
00355 break;
00356 }
00357 } else {
00358 if (jackctl_parameter_get_type(param) == JackParamBool) {
00359 value.i = true;
00360 } else {
00361 value = jackctl_parameter_get_default_value(param);
00362 }
00363 jackctl_parameter_set_value(param, &value);
00364 }
00365 }
00366
00367 free(options);
00368 free(long_options);
00369 return 0;
00370 }
00371
00372 jack_driver_desc_t *
00373 jack_find_driver_descriptor (JSList * drivers, const char * name)
00374 {
00375 jack_driver_desc_t * desc = 0;
00376 JSList * node;
00377
00378 for (node = drivers; node; node = jack_slist_next (node)) {
00379 desc = (jack_driver_desc_t *) node->data;
00380
00381 if (strcmp (desc->name, name) != 0) {
00382 desc = NULL;
00383 } else {
00384 break;
00385 }
00386 }
00387
00388 return desc;
00389 }
00390
00391 static jack_driver_desc_t *
00392 jack_get_descriptor (JSList * drivers, const char * sofile, const char * symbol)
00393 {
00394 jack_driver_desc_t * descriptor, * other_descriptor;
00395 JackDriverDescFunction so_get_descriptor = NULL;
00396 JSList * node;
00397 void * dlhandle;
00398 char * filename;
00399 #ifdef WIN32
00400 int dlerr;
00401 #else
00402 const char * dlerr;
00403 #endif
00404
00405 int err;
00406 const char* driver_dir;
00407
00408 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00409
00410
00411 #ifdef WIN32
00412 char temp_driver_dir1[512];
00413 char temp_driver_dir2[512];
00414 GetCurrentDirectory(512, temp_driver_dir1);
00415 sprintf(temp_driver_dir2, "%s/%s", temp_driver_dir1, ADDON_DIR);
00416 driver_dir = temp_driver_dir2;
00417 #else
00418 driver_dir = ADDON_DIR;
00419 #endif
00420 }
00421
00422 filename = (char *)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1);
00423 sprintf (filename, "%s/%s", driver_dir, sofile);
00424
00425 if ((dlhandle = LoadDriverModule(filename)) == NULL) {
00426 #ifdef WIN32
00427 jack_error ("could not open driver .dll '%s': %ld", filename, GetLastError());
00428 #else
00429 jack_error ("could not open driver .so '%s': %s", filename, dlerror());
00430 #endif
00431
00432 free(filename);
00433 return NULL;
00434 }
00435
00436 so_get_descriptor = (JackDriverDescFunction)
00437 GetProc(dlhandle, symbol);
00438
00439 #ifdef WIN32
00440 if ((so_get_descriptor == NULL) && (dlerr = GetLastError()) != 0) {
00441 jack_log("jack_get_descriptor : dll is not a driver, err = %ld", dlerr);
00442 #else
00443 if ((so_get_descriptor == NULL) && (dlerr = dlerror ()) != NULL) {
00444 jack_log("jack_get_descriptor err = %s", dlerr);
00445 #endif
00446
00447 UnloadDriverModule(dlhandle);
00448 free(filename);
00449 return NULL;
00450 }
00451
00452 if ((descriptor = so_get_descriptor ()) == NULL) {
00453 jack_error("driver from '%s' returned NULL descriptor", filename);
00454 UnloadDriverModule(dlhandle);
00455 free(filename);
00456 return NULL;
00457 }
00458
00459 #ifdef WIN32
00460 if ((err = UnloadDriverModule(dlhandle)) == 0) {
00461 jack_error ("error closing driver .so '%s': %ld", filename, GetLastError ());
00462 }
00463 #else
00464 if ((err = UnloadDriverModule(dlhandle)) != 0) {
00465 jack_error ("error closing driver .so '%s': %s", filename, dlerror ());
00466 }
00467 #endif
00468
00469
00470 for (node = drivers; node; node = jack_slist_next (node)) {
00471 other_descriptor = (jack_driver_desc_t *) node->data;
00472
00473 if (strcmp(descriptor->name, other_descriptor->name) == 0) {
00474 jack_error("the drivers in '%s' and '%s' both have the name '%s'; using the first",
00475 other_descriptor->file, filename, other_descriptor->name);
00476
00477 free(filename);
00478 return NULL;
00479 }
00480 }
00481
00482 strncpy(descriptor->file, filename, JACK_PATH_MAX);
00483 free(filename);
00484 return descriptor;
00485 }
00486
00487 static bool check_symbol(const char* sofile, const char* symbol)
00488 {
00489 void * dlhandle;
00490 bool res = false;
00491 const char* driver_dir;
00492
00493 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00494
00495
00496 #ifdef WIN32
00497 char temp_driver_dir1[512];
00498 char temp_driver_dir2[512];
00499 GetCurrentDirectory(512, temp_driver_dir1);
00500 sprintf(temp_driver_dir2, "%s/%s", temp_driver_dir1, ADDON_DIR);
00501 driver_dir = temp_driver_dir2;
00502 #else
00503 driver_dir = ADDON_DIR;
00504 #endif
00505 }
00506
00507 char* filename = (char *)malloc(strlen (driver_dir) + 1 + strlen(sofile) + 1);
00508 sprintf (filename, "%s/%s", driver_dir, sofile);
00509
00510 if ((dlhandle = LoadDriverModule(filename)) == NULL) {
00511 #ifdef WIN32
00512 jack_error ("could not open component .dll '%s': %ld", filename, GetLastError());
00513 #else
00514 jack_error ("could not open component .so '%s': %s", filename, dlerror());
00515 #endif
00516 } else {
00517 res = (GetProc(dlhandle, symbol)) ? true : false;
00518 UnloadDriverModule(dlhandle);
00519 }
00520
00521 free(filename);
00522 return res;
00523 }
00524
00525 #ifdef WIN32
00526
00527 JSList *
00528 jack_drivers_load (JSList * drivers) {
00529 char * driver_dir;
00530 char driver_dir_storage[512];
00531 char dll_filename[512];
00532 WIN32_FIND_DATA filedata;
00533 HANDLE file;
00534 const char * ptr = NULL;
00535 JSList * driver_list = NULL;
00536 jack_driver_desc_t * desc;
00537
00538 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00539
00540 GetCurrentDirectory(512, driver_dir_storage);
00541 strcat(driver_dir_storage, "/");
00542 strcat(driver_dir_storage, ADDON_DIR);
00543 driver_dir = driver_dir_storage;
00544 }
00545
00546 sprintf(dll_filename, "%s/*.dll", driver_dir);
00547
00548 file = (HANDLE )FindFirstFile(dll_filename, &filedata);
00549
00550 if (file == INVALID_HANDLE_VALUE) {
00551 jack_error("error invalid handle");
00552 return NULL;
00553 }
00554
00555 do {
00556 ptr = strrchr (filedata.cFileName, '.');
00557 if (!ptr) {
00558 continue;
00559 }
00560 ptr++;
00561 if (strncmp ("dll", ptr, 3) != 0) {
00562 continue;
00563 }
00564
00565 desc = jack_get_descriptor (drivers, filedata.cFileName, "driver_get_descriptor");
00566 if (desc) {
00567 driver_list = jack_slist_append (driver_list, desc);
00568 }
00569
00570 } while (FindNextFile(file, &filedata));
00571
00572 if (!driver_list) {
00573 jack_error ("could not find any drivers in %s!", driver_dir);
00574 return NULL;
00575 }
00576
00577 return driver_list;
00578 }
00579
00580 #else
00581
00582 JSList *
00583 jack_drivers_load (JSList * drivers) {
00584 struct dirent * dir_entry;
00585 DIR * dir_stream;
00586 const char * ptr;
00587 int err;
00588 JSList * driver_list = NULL;
00589 jack_driver_desc_t * desc;
00590
00591 const char* driver_dir;
00592 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00593 driver_dir = ADDON_DIR;
00594 }
00595
00596
00597
00598 dir_stream = opendir (driver_dir);
00599 if (!dir_stream) {
00600 jack_error ("could not open driver directory %s: %s",
00601 driver_dir, strerror (errno));
00602 return NULL;
00603 }
00604
00605 while ((dir_entry = readdir(dir_stream))) {
00606
00607
00608 if (strncmp ("jack_", dir_entry->d_name, 5) != 0) {
00609 continue;
00610 }
00611
00612 ptr = strrchr (dir_entry->d_name, '.');
00613 if (!ptr) {
00614 continue;
00615 }
00616 ptr++;
00617 if (strncmp ("so", ptr, 2) != 0) {
00618 continue;
00619 }
00620
00621 desc = jack_get_descriptor (drivers, dir_entry->d_name, "driver_get_descriptor");
00622 if (desc) {
00623 driver_list = jack_slist_append (driver_list, desc);
00624 }
00625 }
00626
00627 err = closedir (dir_stream);
00628 if (err) {
00629 jack_error ("error closing driver directory %s: %s",
00630 driver_dir, strerror (errno));
00631 }
00632
00633 if (!driver_list) {
00634 jack_error ("could not find any drivers in %s!", driver_dir);
00635 return NULL;
00636 }
00637
00638 return driver_list;
00639 }
00640
00641 #endif
00642
00643 #ifdef WIN32
00644
00645 JSList *
00646 jack_internals_load (JSList * internals) {
00647 char * driver_dir;
00648 char driver_dir_storage[512];
00649 char dll_filename[512];
00650 WIN32_FIND_DATA filedata;
00651 HANDLE file;
00652 const char * ptr = NULL;
00653 JSList * driver_list = NULL;
00654 jack_driver_desc_t * desc;
00655
00656 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00657
00658 GetCurrentDirectory(512, driver_dir_storage);
00659 strcat(driver_dir_storage, "/");
00660 strcat(driver_dir_storage, ADDON_DIR);
00661 driver_dir = driver_dir_storage;
00662 }
00663
00664 sprintf(dll_filename, "%s/*.dll", driver_dir);
00665
00666 file = (HANDLE )FindFirstFile(dll_filename, &filedata);
00667
00668 if (file == INVALID_HANDLE_VALUE) {
00669 jack_error("error");
00670 return NULL;
00671 }
00672
00673 do {
00674
00675 ptr = strrchr (filedata.cFileName, '.');
00676 if (!ptr) {
00677 continue;
00678 }
00679 ptr++;
00680 if (strncmp ("dll", ptr, 3) != 0) {
00681 continue;
00682 }
00683
00684
00685 if (!check_symbol(filedata.cFileName, "jack_internal_initialize")) {
00686 continue;
00687 }
00688
00689 desc = jack_get_descriptor (internals, filedata.cFileName, "jack_get_descriptor");
00690 if (desc) {
00691 driver_list = jack_slist_append (driver_list, desc);
00692 }
00693
00694 } while (FindNextFile(file, &filedata));
00695
00696 if (!driver_list) {
00697 jack_error ("could not find any internals in %s!", driver_dir);
00698 return NULL;
00699 }
00700
00701 return driver_list;
00702 }
00703
00704 #else
00705
00706 JSList *
00707 jack_internals_load (JSList * internals) {
00708 struct dirent * dir_entry;
00709 DIR * dir_stream;
00710 const char * ptr;
00711 int err;
00712 JSList * driver_list = NULL;
00713 jack_driver_desc_t * desc;
00714
00715 const char* driver_dir;
00716 if ((driver_dir = getenv("JACK_DRIVER_DIR")) == 0) {
00717 driver_dir = ADDON_DIR;
00718 }
00719
00720
00721
00722 dir_stream = opendir (driver_dir);
00723 if (!dir_stream) {
00724 jack_error ("could not open driver directory %s: %s\n",
00725 driver_dir, strerror (errno));
00726 return NULL;
00727 }
00728
00729 while ((dir_entry = readdir(dir_stream))) {
00730
00731 ptr = strrchr (dir_entry->d_name, '.');
00732 if (!ptr) {
00733 continue;
00734 }
00735 ptr++;
00736 if (strncmp ("so", ptr, 2) != 0) {
00737 continue;
00738 }
00739
00740
00741 if (!check_symbol(dir_entry->d_name, "jack_internal_initialize")) {
00742 continue;
00743 }
00744
00745 desc = jack_get_descriptor (internals, dir_entry->d_name, "jack_get_descriptor");
00746 if (desc) {
00747 driver_list = jack_slist_append (driver_list, desc);
00748 }
00749 }
00750
00751 err = closedir (dir_stream);
00752 if (err) {
00753 jack_error ("error closing internal directory %s: %s\n",
00754 driver_dir, strerror (errno));
00755 }
00756
00757 if (!driver_list) {
00758 jack_error ("could not find any internals in %s!", driver_dir);
00759 return NULL;
00760 }
00761
00762 return driver_list;
00763 }
00764
00765 #endif
00766
00767 Jack::JackDriverClientInterface* JackDriverInfo::Open(jack_driver_desc_t* driver_desc,
00768 Jack::JackLockedEngine* engine,
00769 Jack::JackSynchro* synchro,
00770 const JSList* params)
00771 {
00772 #ifdef WIN32
00773 int errstr;
00774 #else
00775 const char * errstr;
00776 #endif
00777
00778 fHandle = LoadDriverModule (driver_desc->file);
00779
00780 if (fHandle == NULL) {
00781 #ifdef WIN32
00782 if ((errstr = GetLastError ()) != 0) {
00783 jack_error ("can't load \"%s\": %ld", driver_desc->file, errstr);
00784 #else
00785 if ((errstr = dlerror ()) != 0) {
00786 jack_error ("can't load \"%s\": %s", driver_desc->file, errstr);
00787 #endif
00788
00789 } else {
00790 jack_error ("bizarre error loading driver shared object %s", driver_desc->file);
00791 }
00792 return NULL;
00793 }
00794
00795 fInitialize = (driverInitialize)GetProc(fHandle, "driver_initialize");
00796
00797 #ifdef WIN32
00798 if ((fInitialize == NULL) && (errstr = GetLastError ()) != 0) {
00799 #else
00800 if ((fInitialize == NULL) && (errstr = dlerror ()) != 0) {
00801 #endif
00802 jack_error("no initialize function in shared object %s\n", driver_desc->file);
00803 return NULL;
00804 }
00805
00806 return fInitialize(engine, synchro, params);
00807 }
00808