1/* 2 * IODBCadm_DSNmanageController.m 3 * 4 * $Id$ 5 * 6 * The iODBC driver manager. 7 * 8 * Copyright (C) 1996-2021 OpenLink Software <iodbc@openlinksw.com> 9 * All Rights Reserved. 10 * 11 * This software is released under the terms of either of the following 12 * licenses: 13 * 14 * - GNU Library General Public License (see LICENSE.LGPL) 15 * - The BSD License (see LICENSE.BSD). 16 * 17 * Note that the only valid version of the LGPL license as far as this 18 * project is concerned is the original GNU Library General Public License 19 * Version 2, dated June 1991. 20 * 21 * While not mandated by the BSD license, any patches you make to the 22 * iODBC source code may be contributed back into the iODBC project 23 * at your discretion. Contributions will benefit the Open Source and 24 * Data Access community as a whole. Submissions may be made at: 25 * 26 * http://www.iodbc.org 27 * 28 * 29 * GNU Library Generic Public License Version 2 30 * ============================================ 31 * This library is free software; you can redistribute it and/or 32 * modify it under the terms of the GNU Library General Public 33 * License as published by the Free Software Foundation; only 34 * Version 2 of the License dated June 1991. 35 * 36 * This library is distributed in the hope that it will be useful, 37 * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 39 * Library General Public License for more details. 40 * 41 * You should have received a copy of the GNU Library General Public 42 * License along with this library; if not, write to the Free 43 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 44 * 45 * 46 * The BSD License 47 * =============== 48 * Redistribution and use in source and binary forms, with or without 49 * modification, are permitted provided that the following conditions 50 * are met: 51 * 52 * 1. Redistributions of source code must retain the above copyright 53 * notice, this list of conditions and the following disclaimer. 54 * 2. Redistributions in binary form must reproduce the above copyright 55 * notice, this list of conditions and the following disclaimer in 56 * the documentation and/or other materials provided with the 57 * distribution. 58 * 3. Neither the name of OpenLink Software Inc. nor the names of its 59 * contributors may be used to endorse or promote products derived 60 * from this software without specific prior written permission. 61 * 62 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 63 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 64 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 65 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL OPENLINK OR 66 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 67 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 68 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 69 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 70 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 71 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 72 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 */ 74 75 76#import "IODBCadm_DSNmanageController.h" 77#import "utils.h" 78#import "Helpers.h" 79#import "IODBCadm_DriverChooseDSNController.h" 80#import "IODBCadm_PoolConfigController.h" 81#import "IODBCadm_DrvRemoveController.h" 82#import "IODBCadm_DrvConfigController.h" 83 84 85 86void create_administrator (HWND hwnd) 87{ 88 @autoreleasepool { 89 90 NSApplication *app = [NSApplication sharedApplication]; 91 92 IODBCadm_DSNmanageController *dlg = [[IODBCadm_DSNmanageController alloc] init]; 93 94 [app runModalForWindow:dlg.window]; 95 96 [dlg.window orderOut:dlg.window]; 97 [dlg release]; 98 } 99} 100 101 102static LPWSTR create_driversetupw (LPCWSTR driver, LPCWSTR attrs, BOOL add, BOOL user) 103{ 104 wchar_t *connstr = NULL; 105 106 IODBCadm_DrvConfigController *dlg = [[IODBCadm_DrvConfigController alloc] initWithAttrs:attrs]; 107 dlg.drv_name = conv_wchar_to_NSString(driver); 108 dlg.add = add; 109 110 NSInteger rc = [NSApp runModalForWindow:dlg.window]; 111 if (rc == 1) { 112 int i = 0, size = 0; 113 wchar_t *cour, *prov; 114 int STRCONN_NB_TOKENS = 3; 115 116 size += (dlg.drv_name!=nil?dlg.drv_name.length:0) + 1; 117 size += (dlg.drv_file!=nil?dlg.drv_file.length:0) + wcslen(L"Driver=") +1; 118 size += (dlg.setup_file!=nil?dlg.setup_file.length:0) + wcslen(L"Setup=") +1; 119 120 size += wcslen(dlg.rb_sysuser.selectedColumn==0?L"USR" : L"SYS") + 1; 121 /* Malloc it */ 122 if ((connstr = (wchar_t *) malloc (++size * sizeof(wchar_t)))) 123 { 124 wcscpy(connstr, (dlg.rb_sysuser.selectedColumn==0? L"USR" : L"SYS")); 125 126 for (cour = connstr + 4; i < STRCONN_NB_TOKENS ; i++) 127 { 128 switch (i) 129 { 130 case 0: 131 prov = conv_NSString_to_wchar(dlg.drv_name); 132 if(prov) 133 { 134 wcscpy(cour, prov); 135 free(prov); 136 } 137 break; 138 case 1: 139 prov = conv_NSString_to_wchar(dlg.drv_file); 140 if(prov) 141 { 142 wcscpy(cour, L"Driver="); 143 wcscat(cour, prov); 144 free(prov); 145 } 146 break; 147 case 2: 148 prov = conv_NSString_to_wchar(dlg.setup_file); 149 if(prov) 150 { 151 wcscpy(cour, L"Setup="); 152 wcscat(cour, prov); 153 free(prov); 154 } 155 break; 156 }; 157 158 cour += (wcslen (cour) + 1); 159 } 160 161 for (i = 0; i < dlg.Attrs_list.count; i++) 162 { 163 wchar_t *val,*key; 164 NSDictionary *row = [dlg.Attrs_list objectAtIndex:i]; 165 NSString *nskey = (NSString*)[row valueForKey:@"key"]; 166 if ([nskey isEqualToString:@"..."] || nskey.length==0) 167 continue; 168 key = conv_NSString_to_wchar(nskey); 169 val = conv_NSString_to_wchar((NSString*)[row valueForKey:@"val"]); 170 cour = connstr; 171 connstr = (wchar_t*) malloc ((size + wcslen(key) + wcslen(val) + 2) * sizeof(wchar_t)); 172 if (connstr) 173 { 174 memcpy (connstr, cour, size*sizeof(wchar_t)); 175 if (key) { 176 wcscpy(connstr + size - 1, key); 177 wcscat(connstr + size - 1, L"="); 178 if (val) 179 wcscat(connstr + size - 1, val); 180 } 181 free (cour); 182 size += wcslen(key) + wcslen(val) + 2; 183 } 184 else 185 connstr = cour; 186 187 if (key!=NULL) free(key); 188 if (val!=NULL) free(val); 189 } 190 191 connstr[size - 1] = '\0'; 192 } 193 } 194 195 [dlg.window orderOut:dlg.window]; 196 [dlg release]; 197 198 return connstr; 199} 200 201 202 203@interface IODBCadm_DSNmanageController () 204 205@end 206 207@implementation IODBCadm_DSNmanageController 208@synthesize fld_CustomTrace = _fld_CustomTrace; 209@synthesize fld_LogFilePath = _fld_LogFilePath; 210@synthesize rb_WhenToTrace = _rb_WhenToTrace; 211@synthesize rb_TraceWide = _rb_TraceWide; 212@synthesize fld_RetryWaitTime = _fld_RetryWaitTime; 213@synthesize pool_tableView = _pool_tableView; 214@synthesize rb_PerfMon = _rb_PerfMon; 215@synthesize popup_dir_btn = _popup_dir_btn; 216@synthesize fdsn_tableView = _fdsn_tableView; 217@synthesize tab_view = _tab_view; 218@synthesize FileDSN_ArrController = _FileDSN_ArrController; 219@synthesize SysDSN_ArrController = _SysDSN_ArrController; 220@synthesize UserDSN_ArrController = _UserDSN_ArrController; 221@synthesize Drv_ArrController = _Drv_ArrController; 222@synthesize Pool_ArrController = _Pool_ArrController; 223@synthesize About_ArrController = _About_ArrController; 224@synthesize FileDSN_list=_FileDSN_list; 225@synthesize cur_dir=_cur_dir; 226 227- (id)init 228{ 229 char tmp[1024] = {""}; 230 231 self = [super initWithWindowNibName:@"IODBCadm_DSNmanageController"]; 232 if (self) { 233 self.FileDSN_list = [NSMutableArray arrayWithCapacity:16]; 234 235 SQLSetConfigMode (ODBC_BOTH_DSN); 236 if (!SQLGetPrivateProfileString("ODBC", "FileDSNPath", "", tmp, sizeof(tmp), "odbcinst.ini")) 237 self.cur_dir = get_user_documents_dir(); 238 else 239 self.cur_dir = conv_char_to_NSString(tmp); 240 } 241 _tracing_changed = FALSE; 242 _pool_changed = FALSE; 243 _drivers_loaded = FALSE; 244 return self; 245} 246 247- (void)dealloc 248{ 249 [_FileDSN_list release]; 250 [_cur_dir release]; 251 [super dealloc]; 252} 253 254 255- (id)initWithWindow:(NSWindow *)window 256{ 257 self = [super initWithWindow:window]; 258 if (self) { 259 // Initialization code here. 260 } 261 return self; 262} 263 264- (void)windowDidLoad 265{ 266 void *ptr; 267 [super windowDidLoad]; 268 _dialogCode = 0; 269 270 [[self window] center]; // Center the window. 271 self.window.title = 272#if defined (__x86_64__) 273 @"iODBC Data Source Administrator (Intel 64bit)"; 274#elif defined (__aarch64__) 275 @"iODBC Data Source Administrator (Apple Silicon)"; 276#elif defined (__i386__) 277 @"iODBC Data Source Administrator (Intel 32bit)"; 278#else 279 @"iODBC Data Source Administrator"; 280#endif 281 addDSNs_to_list(FALSE, _UserDSN_ArrController); 282 addDSNs_to_list(TRUE, _SysDSN_ArrController); 283 [_fdsn_tableView setDoubleAction:@selector(call_FDSN_DoubleClick)]; 284 addPools_to_list(_Pool_ArrController); 285 [_pool_tableView setDoubleAction:@selector(call_Pool_DoubleClick)]; 286 addComponents_to_list(_About_ArrController); 287} 288 289- (void)windowWillClose:(NSNotification*)notification 290{ 291 [NSApp stopModalWithCode:_dialogCode]; 292} 293 294- (void) call_FDSN_DoubleClick 295{ 296 NSInteger row = _fdsn_tableView.clickedRow; 297 NSDictionary *dict = [_FileDSN_list objectAtIndex:row]; 298 NSNumber *isdir = [dict valueForKey:@"isdir"]; 299 if (isdir.boolValue==TRUE){ 300 NSString *cliked_dir = [dict valueForKey:@"name"]; 301 NSString *new_path = [NSString stringWithFormat:@"%@/%@", _cur_dir, cliked_dir]; 302 self.cur_dir = new_path; 303 wchar_t *path = conv_NSString_to_wchar(_cur_dir); 304 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 305 fill_dir_menu(path, _popup_dir_btn); 306 if (path) free(path); 307 } else { 308 [self call_FileDSN_Config:self]; 309 } 310} 311 312 313- (void) call_Pool_DoubleClick 314{ 315 NSArray *sarr = [_Pool_ArrController selectedObjects]; 316 if (sarr.count>0) { 317 NSDictionary *dct = [sarr objectAtIndex:0]; 318 NSString *drv = [dct valueForKey:@"drv"]; 319 NSString *tm = [dct valueForKey:@"timeout"]; 320 NSString *qry = [dct valueForKey:@"query"]; 321 322 IODBCadm_PoolConfigController *dlg = [[IODBCadm_PoolConfigController alloc] initWithTitle:drv Timeout:tm Query:qry]; 323 324 NSInteger rc = [NSApp runModalForWindow:dlg.window]; 325 if (rc == 1) { 326 UWORD configMode; 327 tm = [NSString stringWithFormat:@"CPTimeout=%@", dlg.ptimeout ? dlg.ptimeout :@""]; 328 qry = [NSString stringWithFormat:@"CPProbe=%@", dlg.pquery ? dlg.pquery : @""]; 329 330 wchar_t *wtimeout = conv_NSString_to_wchar(tm); 331 wchar_t *wquery = conv_NSString_to_wchar(qry); 332 wchar_t *wdrv = conv_NSString_to_wchar(drv); 333 334 SQLGetConfigMode(&configMode); 335 SQLSetConfigMode(ODBC_SYSTEM_DSN); 336 if (wdrv) { 337 if (wtimeout) { 338 SQLSetConfigMode(ODBC_SYSTEM_DSN); 339 if (!SQLConfigDriverW ((void*)1L, ODBC_CONFIG_DRIVER, 340 wdrv, wtimeout, NULL, 0, NULL)) 341 _iodbcdm_errorboxw ((void*)1L, wdrv, 342 L"An error occurred when trying to set the connection pooling time-out "); 343 free(wtimeout); 344 } 345 if (wquery) { 346 SQLSetConfigMode(ODBC_SYSTEM_DSN); 347 if (!SQLConfigDriverW ((void*)1L, ODBC_CONFIG_DRIVER, 348 wdrv, wquery, NULL, 0, NULL)) 349 _iodbcdm_errorboxw ((void*)1L, wdrv, 350 L"An error occurred when trying to set the connection probe query "); 351 352 } 353 free(wdrv); 354 } 355 356 addPools_to_list(_Pool_ArrController); 357 } 358 359 [dlg.window orderOut:dlg.window]; 360 [dlg release]; 361 [self.window makeKeyAndOrderFront:self.window]; 362 } 363} 364 365 366/** NSTabViewDelegate **/ 367- (void)tabView:(NSTabView *)tabView didSelectTabViewItem:(NSTabViewItem *)tabViewItem 368{ 369 char tmp[4096]; 370 NSString *identifier = [tabViewItem identifier]; 371 372 if ([identifier isEqualToString:@"userdsn"]){ 373 addDSNs_to_list(FALSE, _UserDSN_ArrController); 374 } 375 else if ([identifier isEqualToString:@"sysdsn"]){ 376 addDSNs_to_list(TRUE, _SysDSN_ArrController); 377 } 378 else if ([identifier isEqualToString:@"filedsn"]){ 379 wchar_t *cur_path = conv_NSString_to_wchar(_cur_dir); 380 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 381 fill_dir_menu(cur_path, _popup_dir_btn); 382 if (cur_path) free(cur_path); 383 } 384 else if ([identifier isEqualToString:@"drivers"]){ 385 if (!_drivers_loaded) { 386 addDrivers_to_list(_Drv_ArrController); 387 _drivers_loaded = TRUE; 388 } 389 } 390 else if ([identifier isEqualToString:@"pool"]){ 391 if (!_pool_changed) 392 { 393 BOOL perfmon = FALSE; 394 /* Get the connection pooling options */ 395 SQLGetPrivateProfileString ("ODBC Connection Pooling", "Perfmon", 396 "", (char *)tmp, sizeof (tmp), "odbcinst.ini"); 397 if (!strcasecmp (tmp, "1") || !strcasecmp (tmp, "On")) 398 perfmon = TRUE; 399 SQLGetPrivateProfileString ("ODBC Connection Pooling", "Retry Wait", 400 "", tmp, sizeof (tmp), "odbcinst.ini"); 401 if (perfmon) 402 [_rb_PerfMon selectCellAtRow:0 column:0]; 403 else 404 [_rb_PerfMon selectCellAtRow:1 column:0]; 405 406 _fld_RetryWaitTime.stringValue = conv_char_to_NSString(tmp); 407 408 _pool_changed = TRUE; 409 } 410 addPools_to_list(_Pool_ArrController); 411 } 412 else if ([identifier isEqualToString:@"trace"]){ 413 wchar_t tokenstr[4096] = { L'\0' }, tokenstr1[4096] = { L'\0' }; 414 BOOL trace = FALSE; 415 BOOL traceauto = FALSE; 416 417 if (!_tracing_changed) 418 { 419 int mode = ODBC_SYSTEM_DSN; 420 421 /* Get the traces options */ 422 SQLSetConfigMode (mode); 423 SQLGetPrivateProfileStringW (L"ODBC", L"TraceFile", L"", tokenstr, 424 sizeof (tokenstr) / sizeof(wchar_t), NULL); 425 if (tokenstr[0] != L'\0') 426 { 427 /* All users wide */ 428 [_rb_TraceWide selectCellAtRow:1 column:0]; 429 } 430 else 431 { 432 /* Only for current user */ 433 mode = ODBC_USER_DSN; 434 SQLSetConfigMode (mode); 435 [_rb_TraceWide selectCellAtRow:0 column:0]; 436 } 437 438 SQLSetConfigMode (mode); 439 SQLGetPrivateProfileString ("ODBC", "Trace", "", tmp, sizeof (tmp), NULL); 440 if (!strcasecmp (tmp, "1") || !strcasecmp (tmp, "On")) 441 trace = TRUE; 442 443 SQLSetConfigMode (mode); 444 SQLGetPrivateProfileString ("ODBC", "TraceAutoStop", "", (char*)tokenstr, 445 sizeof (tokenstr), NULL); 446 if (!strcasecmp ((char*)tokenstr, "1") || !strcasecmp ((char*)tokenstr, "On")) 447 traceauto = TRUE; 448 449 SQLSetConfigMode (mode); 450 SQLGetPrivateProfileStringW (L"ODBC", L"TraceFile", L"", tokenstr, 451 sizeof (tokenstr) / sizeof(wchar_t), NULL); 452 453 SQLSetConfigMode (mode); 454 SQLGetPrivateProfileStringW (L"ODBC", L"TraceDLL", L"", tokenstr1, 455 sizeof (tokenstr1) / sizeof(wchar_t), NULL); 456 /* Set the widgets */ 457 if (trace) 458 { 459 if (!traceauto) 460 [_rb_WhenToTrace selectCellAtRow:1 column:0]; 461 else 462 [_rb_WhenToTrace selectCellAtRow:2 column:0]; 463 } 464 else 465 [_rb_WhenToTrace selectCellAtRow:0 column:0]; 466 467 _fld_LogFilePath.stringValue = tokenstr[0] == L'\0' 468 ? [NSString stringWithFormat:@"%@/sql.log", NSHomeDirectory()] 469 : conv_wchar_to_NSString(tokenstr); 470 471 _fld_CustomTrace.stringValue = conv_wchar_to_NSString(tokenstr1); 472 _tracing_changed = TRUE; 473 } 474 475 476 } 477 else if ([identifier isEqualToString:@"about"]){ 478 addComponents_to_list(_About_ArrController); 479 } 480} 481 482 483 484/** NSTableViewDelegate **/ 485- (NSView *)tableView:(NSTableView *)tableView viewForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row { 486 // Group our "model" object, which is a dictionary 487 if (tableView == _fdsn_tableView) { 488 NSDictionary *dict = [_FileDSN_list objectAtIndex:row]; 489 NSString *identifier = [tableColumn identifier]; 490 NSTableCellView *cellView = [tableView makeViewWithIdentifier:identifier owner:self]; 491 // Then setup properties on the cellView based on the column 492 cellView.textField.stringValue = [dict objectForKey:@"name"]; 493 cellView.imageView.objectValue = [dict objectForKey:@"icon"]; 494 return cellView; 495 } 496 return nil; 497} 498 499 500- (IBAction)call_Ok:(id)sender { 501 _dialogCode = 1; 502 if (_tracing_changed) 503 [self call_Trace_Apply:nil]; 504 if (_pool_changed) { 505 UWORD configMode; 506 char *tmp = NULL; 507 508 SQLGetConfigMode(&configMode); 509 /* Write keywords for tracing in the ini file */ 510 SQLSetConfigMode(ODBC_SYSTEM_DSN); 511 SQLWritePrivateProfileString ("ODBC Connection Pooling", "PerfMon", 512 _rb_PerfMon.selectedRow == 0 ? "1" : "0", "odbcinst.ini"); 513 514 tmp = conv_NSString_to_char(_fld_RetryWaitTime.stringValue); 515 if (tmp) { 516 SQLSetConfigMode(ODBC_SYSTEM_DSN); 517 SQLWritePrivateProfileString ("ODBC Connection Pooling", 518 "Retry Wait", tmp, "odbcinst.ini"); 519 free(tmp); 520 } 521 SQLSetConfigMode(configMode); 522 } 523 [self.window close]; 524} 525 526- (IBAction)call_Cancel:(id)sender { 527 _dialogCode = 0; 528 [self.window close]; 529} 530 531 532 533- (IBAction)call_UserDSN_Add:(id)sender { 534 wchar_t drv[1024] = { L'\0' }; 535 int sqlstat; 536 537 SQLSetConfigMode (ODBC_USER_DSN); 538 /* Try first to get the driver name */ 539 if (_iodbcdm_drvchoose_dialboxw ((void*)1L, drv, sizeof (drv) / sizeof(wchar_t), &sqlstat) == SQL_SUCCESS) 540 { 541 SQLSetConfigMode (ODBC_USER_DSN); 542 if (!SQLConfigDataSourceW ((void*)1L, ODBC_ADD_DSN, drv + WCSLEN (L"DRIVER="), L"\0\0")) 543 { 544 _iodbcdm_errorboxw ((void*)1L, NULL, L"An error occurred when trying to add the DSN : "); 545 goto done; 546 } 547 548 addDSNs_to_list(FALSE, _UserDSN_ArrController); 549 } 550done: 551 [self.window makeKeyAndOrderFront:self.window]; 552 return; 553} 554 555- (IBAction)call_UserDSN_Remove:(id)sender { 556 NSArray *item = [_UserDSN_ArrController selectedObjects]; 557 if (item!=nil && item.count>0){ 558 NSDictionary *dict = [item objectAtIndex:0]; 559 BOOL rc = remove_dsn(FALSE, [dict valueForKey:@"name"], [dict valueForKey:@"drv"]); 560 if (rc) 561 addDSNs_to_list(FALSE, _UserDSN_ArrController); 562 [self.window makeKeyAndOrderFront:self.window]; 563 } 564} 565 566- (IBAction)call_UserDSN_Config:(id)sender { 567 NSArray *item = [_UserDSN_ArrController selectedObjects]; 568 if (item!=nil && item.count>0){ 569 NSDictionary *dict = [item objectAtIndex:0]; 570 BOOL rc = configure_dsn(FALSE, [dict valueForKey:@"name"], [dict valueForKey:@"drv"]); 571 if (rc) 572 addDSNs_to_list(FALSE, _UserDSN_ArrController); 573 [self.window makeKeyAndOrderFront:self.window]; 574 } 575} 576 577 578- (IBAction)call_UserDSN_Test:(id)sender { 579 NSArray *item = [_UserDSN_ArrController selectedObjects]; 580 if (item!=nil && item.count>0){ 581 NSDictionary *dict = [item objectAtIndex:0]; 582 test_dsn(FALSE, [dict valueForKey:@"name"], [dict valueForKey:@"drv"]); 583 [self.window makeKeyAndOrderFront:self.window]; 584 } 585} 586 587 588- (IBAction)call_SysDSN_Add:(id)sender { 589 wchar_t drv[1024] = { L'\0' }; 590 int sqlstat; 591 592 SQLSetConfigMode (ODBC_USER_DSN); 593 /* Try first to get the driver name */ 594 if (_iodbcdm_drvchoose_dialboxw ((void*)1L, drv, sizeof (drv) / sizeof(wchar_t), &sqlstat) == SQL_SUCCESS) 595 { 596 SQLSetConfigMode (ODBC_USER_DSN); 597 if (!SQLConfigDataSourceW ((void*)1L, ODBC_ADD_SYS_DSN, drv + WCSLEN (L"DRIVER="), L"\0\0")) 598 { 599 _iodbcdm_errorboxw ((void*)1L, NULL, L"An error occurred when trying to add the DSN : "); 600 goto done; 601 } 602 603 addDSNs_to_list(TRUE, _SysDSN_ArrController); 604 } 605done: 606 [self.window makeKeyAndOrderFront:self.window]; 607 return; 608} 609 610- (IBAction)call_SysDSN_Remove:(id)sender { 611 NSArray *item = [_SysDSN_ArrController selectedObjects]; 612 if (item!=nil && item.count>0){ 613 NSDictionary *dict = [item objectAtIndex:0]; 614 BOOL rc = remove_dsn(TRUE, [dict valueForKey:@"name"], [dict valueForKey:@"drv"]); 615 if (rc) 616 addDSNs_to_list(TRUE, _SysDSN_ArrController); 617 [self.window makeKeyAndOrderFront:self.window]; 618 } 619} 620 621- (IBAction)call_SysDSN_Config:(id)sender { 622 NSArray *item = [_SysDSN_ArrController selectedObjects]; 623 if (item!=nil && item.count>0){ 624 NSDictionary *dict = [item objectAtIndex:0]; 625 BOOL rc = configure_dsn(TRUE, [dict valueForKey:@"name"], [dict valueForKey:@"drv"]); 626 if (rc) 627 addDSNs_to_list(TRUE, _SysDSN_ArrController); 628 [self.window makeKeyAndOrderFront:self.window]; 629 } 630} 631 632- (IBAction)call_SysDSN_Test:(id)sender { 633 NSArray *item = [_SysDSN_ArrController selectedObjects]; 634 if (item!=nil && item.count>0){ 635 NSDictionary *dict = [item objectAtIndex:0]; 636 test_dsn(TRUE, [dict valueForKey:@"name"], [dict valueForKey:@"drv"]); 637 [self.window makeKeyAndOrderFront:self.window]; 638 } 639} 640 641 642- (IBAction)call_FileDSN_Dir_Browse:(id)sender { 643 NSOpenPanel *panel = [NSOpenPanel openPanel]; 644 645 [panel setTitle:@"Choose your File DSN directory ..."]; 646 if (_cur_dir.length>0) 647 [panel setDirectoryURL:[NSURL fileURLWithPath:_cur_dir isDirectory:TRUE]]; 648 panel.allowsMultipleSelection = FALSE; 649 panel.canChooseDirectories = TRUE; 650 panel.canChooseFiles = FALSE; 651 panel.canCreateDirectories = TRUE; 652 653 NSInteger rc = [panel runModal]; 654 if (rc==NSFileHandlingPanelOKButton) { 655 self.cur_dir = ((NSURL*)[panel.URLs objectAtIndex:0]).path; 656 wchar_t *path = conv_NSString_to_wchar(_cur_dir); 657 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 658 fill_dir_menu(path, _popup_dir_btn); 659 if (path) free(path); 660 } 661 [self.window makeKeyAndOrderFront:self.window]; 662} 663 664 665- (IBAction)call_Dir_PopupBtn:(id)sender { 666 self.cur_dir = _popup_dir_btn.titleOfSelectedItem; 667 wchar_t *path = conv_NSString_to_wchar(_cur_dir); 668 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 669 fill_dir_menu(path, _popup_dir_btn); 670 if (path) free(path); 671} 672 673- (IBAction)call_FileDSN_Add:(id)sender { 674 BOOL rc = add_file_dsn(_cur_dir); 675 if (rc) { 676 wchar_t *cur_path = conv_NSString_to_wchar(_cur_dir); 677 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 678 fill_dir_menu(cur_path, _popup_dir_btn); 679 if (cur_path) free(cur_path); 680 } 681 [self.window makeKeyAndOrderFront:self.window]; 682} 683 684- (IBAction)call_FileDSN_Remove:(id)sender { 685 NSArray *item = [_FileDSN_ArrController selectedObjects]; 686 if (item!=nil && item.count>0){ 687 NSDictionary *dict = [item objectAtIndex:0]; 688 NSNumber *isdir = [dict valueForKey:@"isdir"]; 689 if (isdir.boolValue==FALSE){ 690 BOOL rc = remove_file_dsn(_cur_dir, [dict valueForKey:@"name"]); 691 if (rc){ 692 wchar_t *cur_path = conv_NSString_to_wchar(_cur_dir); 693 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 694 fill_dir_menu(cur_path, _popup_dir_btn); 695 if (cur_path) free(cur_path); 696 } 697 } 698 [self.window makeKeyAndOrderFront:self.window]; 699 } 700} 701 702- (IBAction)call_FileDSN_Config:(id)sender { 703 NSArray *item = [_FileDSN_ArrController selectedObjects]; 704 if (item!=nil && item.count>0){ 705 NSDictionary *dict = [item objectAtIndex:0]; 706 NSNumber *isdir = [dict valueForKey:@"isdir"]; 707 if (isdir.boolValue==FALSE){ 708 configure_file_dsn(_cur_dir, [dict valueForKey:@"name"]); 709 char *cur_path = conv_NSString_to_char(_cur_dir); 710 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 711 if (cur_path) free(cur_path); 712 713 } else { 714 715 self.cur_dir = [NSString stringWithFormat:@"%@/%@", _cur_dir, [dict valueForKey:@"name"]]; 716 wchar_t *path = conv_NSString_to_wchar(_cur_dir); 717 addFDSNs_to_list(_cur_dir, FALSE, _FileDSN_ArrController); 718 fill_dir_menu(path, _popup_dir_btn); 719 if (path) free(path); 720 } 721 [self.window makeKeyAndOrderFront:self.window]; 722 } 723} 724 725- (IBAction)call_FileDSN_Test:(id)sender { 726 NSArray *item = [_FileDSN_ArrController selectedObjects]; 727 if (item!=nil && item.count>0){ 728 NSDictionary *dict = [item objectAtIndex:0]; 729 NSNumber *isdir = [dict valueForKey:@"isdir"]; 730 if (isdir.boolValue==FALSE){ 731 test_file_dsn(_cur_dir, [dict valueForKey:@"name"]); 732 } 733 [self.window makeKeyAndOrderFront:self.window]; 734 } 735} 736 737- (IBAction)call_FileDSN_SetDir:(id)sender { 738 setdir_file_dsn(_cur_dir); 739 [self.window makeKeyAndOrderFront:self.window]; 740} 741 742 743- (IBAction)call_Drv_Add:(id)sender { 744 wchar_t connstr[4096] = { L'\0' }, tokenstr[4096] = { L'\0' }; 745 wchar_t *cstr; 746 747 cstr = (LPWSTR)create_driversetupw (NULL, (LPCWSTR)connstr, TRUE, TRUE); 748 if (cstr && cstr != connstr && cstr != (LPWSTR)- 1L) 749 { 750 SQLSetConfigMode (!wcscmp(cstr, L"USR") ? ODBC_USER_DSN : ODBC_SYSTEM_DSN); 751 if (!SQLInstallDriverExW (cstr + 4, NULL, tokenstr, 752 sizeof (tokenstr) / sizeof(wchar_t), NULL, ODBC_INSTALL_COMPLETE, NULL)) 753 { 754 _iodbcdm_errorboxw ((void*)1L, NULL, L"An error occurred when trying to add the driver"); 755 goto done; 756 } 757 758 free (cstr); 759 } 760 761 addDrivers_to_list(_Drv_ArrController); 762done: 763 [self.window makeKeyAndOrderFront:self.window]; 764 return; 765} 766 767 768- (IBAction)call_Drv_Remove:(id)sender { 769 wchar_t tokenstr[4096] = { L'\0' }; 770 771 NSArray *item = [_Drv_ArrController selectedObjects]; 772 if (item!=nil && item.count>0){ 773 int dsns = 0; 774 NSDictionary *dict = [item objectAtIndex:0]; 775 wchar_t *wdrv = conv_NSString_to_wchar([dict valueForKey:@"name"]); 776 777 if (wdrv) { 778 /* Initialize some values */ 779 SQLSetConfigMode (ODBC_USER_DSN); 780 if (SQLGetPrivateProfileStringW (wdrv, NULL, L"", tokenstr, sizeof (tokenstr)/sizeof(wchar_t), L"odbcinst.ini")) 781 dsns |= 1; 782 SQLSetConfigMode (ODBC_SYSTEM_DSN); 783 if (SQLGetPrivateProfileStringW (wdrv, NULL, L"", tokenstr, sizeof (tokenstr)/sizeof(wchar_t), L"odbcinst.ini")) 784 dsns |= 2; 785 786 IODBCadm_DrvRemoveController *dlg = [[IODBCadm_DrvRemoveController alloc] initWithDSNS:dsns]; 787 NSInteger rc = [NSApp runModalForWindow:dlg.window]; 788 if (rc == 1) { 789 790 if (create_confirmw ((void*)1L, wdrv, L"Are you sure you want to perform the removal of this driver ?")) 791 { 792 if ((dlg.dsns & 1) > 0) 793 { 794 SQLSetConfigMode (ODBC_USER_DSN); 795 if (!SQLRemoveDriverW (wdrv, dlg.deletedsn, NULL)) 796 { 797 _iodbcdm_errorboxw ((void*)1L, wdrv, 798 L"An error occurred when trying to remove the driver "); 799 goto done; 800 } 801 } 802 803 if ((dlg.dsns & 2) > 0) 804 { 805 SQLSetConfigMode (ODBC_SYSTEM_DSN); 806 if (!SQLRemoveDriverW (wdrv, dlg.deletedsn, NULL)) 807 { 808 _iodbcdm_errorboxw ((void*)1L, wdrv, 809 L"An error occurred when trying to remove the driver "); 810 goto done; 811 } 812 } 813 done: 814 addDrivers_to_list(_Drv_ArrController); 815 } 816 } 817 818 free(wdrv); 819 [dlg.window orderOut:dlg.window]; 820 [dlg release]; 821 } 822 [self.window makeKeyAndOrderFront:self.window]; 823 } 824} 825 826 827- (IBAction)call_Drv_Config:(id)sender { 828 wchar_t tokenstr[4096] = { L'\0' }; 829 UWORD conf = ODBC_USER_DSN; 830 831 NSArray *item = [_Drv_ArrController selectedObjects]; 832 if (item!=nil && item.count>0){ 833 NSDictionary *dict = [item objectAtIndex:0]; 834 wchar_t *wdrv = conv_NSString_to_wchar([dict valueForKey:@"name"]); 835 836 if (wdrv) { 837 wchar_t *curr, *cour, *cstr; 838 wchar_t connstr[4096] = { L'\0' }; 839 int size = sizeof (connstr) / sizeof(wchar_t); 840 841 SQLSetConfigMode (ODBC_USER_DSN); 842 if (!SQLGetPrivateProfileStringW (wdrv, NULL, L"", tokenstr, 843 sizeof (tokenstr) / sizeof(wchar_t), L"odbcinst.ini")) 844 { 845 SQLSetConfigMode (conf = ODBC_SYSTEM_DSN); 846 if (!SQLGetPrivateProfileStringW (wdrv, NULL, L"", tokenstr, 847 sizeof (tokenstr) / sizeof(wchar_t), L"odbcinst.ini")) 848 { 849 _iodbcdm_errorboxw ((void*)1L, wdrv, 850 L"An error occurred when trying to configure the driver "); 851 goto done; 852 } 853 } 854 855 for (curr = tokenstr, cour = connstr; *curr != L'\0' ; 856 curr += (wcslen (curr) + 1), cour += (wcslen(cour) + 1)) 857 { 858 wcscpy (cour, curr); 859 cour[wcslen (curr)] = L'='; 860 SQLSetConfigMode (conf); 861 SQLGetPrivateProfileStringW (wdrv, curr, L"", 862 cour + wcslen(curr) + 1, (int)(size - wcslen(curr) - 1), 863 L"odbcinst.ini"); 864 size -= (wcslen(cour) + 1); 865 } 866 867 *cour = L'\0'; 868 869 cstr = (LPWSTR)create_driversetupw (wdrv, (LPCWSTR)connstr, FALSE, (conf == ODBC_SYSTEM_DSN) ? FALSE : TRUE); 870 if (cstr && cstr != connstr && cstr != (LPWSTR) - 1L) 871 { 872 SQLSetConfigMode (conf); 873 if (!SQLInstallDriverExW (cstr + 4, NULL, tokenstr, 874 sizeof (tokenstr) / sizeof(wchar_t), NULL, 875 ODBC_INSTALL_COMPLETE, NULL)) 876 { 877 _iodbcdm_errorboxw ((void*)1L, NULL, 878 L"An error occurred when trying to configure the driver "); 879 goto done; 880 } 881 free (cstr); 882 } 883 884 done: 885 addDrivers_to_list(_Drv_ArrController); 886 free(wdrv); 887 } 888 [self.window makeKeyAndOrderFront:self.window]; 889 } 890} 891 892 893- (IBAction)call_Trace_Apply:(id)sender { 894 int mode; 895 wchar_t *tmp; 896 897 /* Clear previous setting */ 898 SQLSetConfigMode (ODBC_USER_DSN); 899 SQLWritePrivateProfileString ("ODBC", "Trace", NULL, NULL); 900 SQLSetConfigMode (ODBC_USER_DSN); 901 SQLWritePrivateProfileString ("ODBC", "TraceAutoStop", NULL, NULL); 902 SQLSetConfigMode (ODBC_USER_DSN); 903 SQLWritePrivateProfileString ("ODBC", "TraceFile", NULL, NULL); 904 SQLSetConfigMode (ODBC_USER_DSN); 905 SQLWritePrivateProfileString ("ODBC", "TraceDLL", NULL, NULL); 906 907 SQLSetConfigMode (ODBC_SYSTEM_DSN); 908 SQLWritePrivateProfileString ("ODBC", "Trace", NULL, NULL); 909 SQLSetConfigMode (ODBC_SYSTEM_DSN); 910 SQLWritePrivateProfileString ("ODBC", "TraceAutoStop", NULL, NULL); 911 SQLSetConfigMode (ODBC_SYSTEM_DSN); 912 SQLWritePrivateProfileString ("ODBC", "TraceFile", NULL, NULL); 913 SQLSetConfigMode (ODBC_SYSTEM_DSN); 914 SQLWritePrivateProfileString ("ODBC", "TraceDLL", NULL, NULL); 915 916 mode = _rb_TraceWide.selectedRow == 0 ? ODBC_USER_DSN : ODBC_SYSTEM_DSN; 917 918 /* Write keywords for tracing in the ini file */ 919 SQLSetConfigMode(mode); 920 if (_rb_WhenToTrace.selectedRow == 1 || _rb_WhenToTrace.selectedRow == 2) 921 SQLWritePrivateProfileString ("ODBC", "Trace", "1", NULL); 922 else 923 SQLWritePrivateProfileString ("ODBC", "Trace", "0", NULL); 924 925 SQLSetConfigMode(mode); 926 if (_rb_WhenToTrace.selectedRow == 2) 927 SQLWritePrivateProfileString ("ODBC", "TraceAutoStop", "1", NULL); 928 else 929 SQLWritePrivateProfileString ("ODBC", "TraceAutoStop", "0", NULL); 930 931 tmp = conv_NSString_to_wchar(_fld_LogFilePath.stringValue); 932 if (tmp) 933 { 934 SQLSetConfigMode(mode); 935 SQLWritePrivateProfileStringW (L"ODBC", L"TraceFile", tmp, NULL); 936 free(tmp); 937 } 938 939 tmp = conv_NSString_to_wchar(_fld_CustomTrace.stringValue); 940 if (tmp) 941 { 942 SQLSetConfigMode(mode); 943 SQLWritePrivateProfileStringW (L"ODBC", L"TraceDLL", tmp, NULL); 944 free(tmp); 945 } 946} 947 948- (IBAction)call_LogFilePath_Browse:(id)sender { 949 NSSavePanel *panel = [NSSavePanel savePanel]; 950 951 NSURL *file_url = [NSURL fileURLWithPath:_fld_LogFilePath.stringValue]; 952 NSString *fpath = file_url.path; 953 NSString *fname = file_url.lastPathComponent; 954 NSString *dir = [fpath substringToIndex:(fpath.length - fname.length)]; 955 956 [panel setTitle:@"Choose your trace file ..."]; 957 [panel setNameFieldStringValue:fname]; 958 [panel setDirectoryURL:[NSURL fileURLWithPath:dir isDirectory:TRUE]]; 959 NSInteger rc = [panel runModal]; 960 if (rc==NSFileHandlingPanelOKButton) 961 [_fld_LogFilePath setStringValue:[NSString stringWithFormat:@"%@/%@", panel.directoryURL.path, panel.nameFieldStringValue]]; 962 [self.window makeKeyAndOrderFront:self.window]; 963} 964 965- (IBAction)call_CustomTrace_Browse:(id)sender { 966 NSOpenPanel *panel = [NSOpenPanel openPanel]; 967 968 NSURL *file_url = [NSURL fileURLWithPath:_fld_CustomTrace.stringValue]; 969 NSString *fpath = file_url.path; 970 NSString *fname = file_url.lastPathComponent; 971 NSString *dir = [fpath substringToIndex:(fpath.length - fname.length)]; 972 973 974 [panel setTitle:@"Choose your trace library ..."]; 975 [panel setNameFieldStringValue:(fname.length>0)? fname: @"ODBC Trace Library"]; 976 if (dir.length>0) 977 [panel setDirectoryURL:[NSURL fileURLWithPath:dir isDirectory:TRUE]]; 978 panel.allowsMultipleSelection = FALSE; 979 panel.canChooseDirectories = FALSE; 980 981 NSInteger rc = [panel runModal]; 982 if (rc==NSFileHandlingPanelOKButton) 983 [_fld_CustomTrace setStringValue: ((NSURL*)[panel.URLs objectAtIndex:0]).path]; 984 [self.window makeKeyAndOrderFront:self.window]; 985} 986 987 988 989@end 990