|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1988 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that the above copyright notice and this paragraph are ! 7: * duplicated in all such forms and that any documentation, ! 8: * advertising materials, and other materials related to such ! 9: * distribution and use acknowledge that the software was developed ! 10: * by the University of California, Berkeley. The name of the ! 11: * University may not be used to endorse or promote products derived ! 12: * from this software without specific prior written permission. ! 13: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR ! 14: * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED ! 15: * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 16: */ ! 17: ! 18: #ifndef lint ! 19: static char sccsid[] = "@(#)api.c 4.4 (Berkeley) 10/31/89"; ! 20: #endif /* not lint */ ! 21: ! 22: /* ! 23: * This file implements the API used in the PC version. ! 24: */ ! 25: ! 26: #include <stdio.h> ! 27: ! 28: #include "api.h" ! 29: #include "../general/general.h" ! 30: ! 31: #include "../api/disp_asc.h" ! 32: ! 33: #include "screen.h" ! 34: #include "hostctlr.h" ! 35: #include "oia.h" ! 36: ! 37: #include "../general/globals.h" ! 38: ! 39: int apitrace = 0; ! 40: ! 41: /* ! 42: * Some defines for things we use internally. ! 43: */ ! 44: ! 45: #define PS_SESSION_ID 23 ! 46: #define BUF_SESSION_ID 0 ! 47: ! 48: /* ! 49: * General utility routines. ! 50: */ ! 51: ! 52: #if defined(MSDOS) ! 53: ! 54: #if defined(LINT_ARGS) ! 55: static void movetous(char *, int, int, int); ! 56: static void movetothem(int, int, char *, int); ! 57: #endif /* defined(LINT_ARGS) */ ! 58: ! 59: #define access_api(foo,length,copyin) (foo) ! 60: #define unaccess_api(foo,goo,length,copyout) ! 61: ! 62: static void ! 63: movetous(parms, es, di, length) ! 64: char *parms; ! 65: int es, di; ! 66: int length; ! 67: { ! 68: char far *farparms = parms; ! 69: ! 70: movedata(es, di, FP_SEG(farparms), FP_OFF(farparms), length); ! 71: if (apitrace) { ! 72: Dump('(', parms, length); ! 73: } ! 74: } ! 75: ! 76: static void ! 77: movetothem(es, di, parms, length) ! 78: int es, di; ! 79: char *parms; ! 80: int length; ! 81: { ! 82: char far *farparms = parms; ! 83: ! 84: movedata(FP_SEG(farparms), FP_OFF(farparms), es, di, length); ! 85: if (apitrace) { ! 86: Dump(')', parms, length); ! 87: } ! 88: } ! 89: #endif /* defined(MSDOS) */ ! 90: ! 91: #if defined(unix) ! 92: extern char *access_api(); ! 93: extern void movetous(), movetothem(), unaccess_api(); ! 94: #endif /* defined(unix) */ ! 95: ! 96: ! 97: /* ! 98: * Supervisor Services. ! 99: */ ! 100: ! 101: static void ! 102: name_resolution(regs, sregs) ! 103: union REGS *regs; ! 104: struct SREGS *sregs; ! 105: { ! 106: NameResolveParms parms; ! 107: ! 108: movetous((char *) &parms, sregs->es, regs->x.di, sizeof parms); ! 109: ! 110: regs->h.cl = 0; ! 111: if (memcmp((char *)&parms, NAME_SESSMGR, sizeof parms.gate_name) == 0) { ! 112: regs->x.dx = GATE_SESSMGR; ! 113: } else if (memcmp((char *)&parms, NAME_KEYBOARD, ! 114: sizeof parms.gate_name) == 0) { ! 115: regs->x.dx = GATE_KEYBOARD; ! 116: } else if (memcmp((char *)&parms, NAME_COPY, sizeof parms.gate_name) == 0) { ! 117: regs->x.dx = GATE_COPY; ! 118: } else if (memcmp((char *)&parms, NAME_OIAM, sizeof parms.gate_name) == 0) { ! 119: regs->x.dx = GATE_OIAM; ! 120: } else { ! 121: regs->h.cl = 0x2e; /* Name not found */ ! 122: } ! 123: regs->h.ch = 0x12; ! 124: regs->h.bh = 7; ! 125: } ! 126: ! 127: /* ! 128: * Session Information Services. ! 129: */ ! 130: ! 131: static void ! 132: query_session_id(regs, sregs) ! 133: union REGS *regs; ! 134: struct SREGS *sregs; ! 135: { ! 136: QuerySessionIdParms parms; ! 137: ! 138: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 139: ! 140: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 141: parms.rc = 0x0c; ! 142: } else if (parms.option_code != 0x01) { ! 143: parms.rc = 0x0d; /* Invalid option code */ ! 144: #ifdef NOTOBS ! 145: } else if ((parms.data_code != 0x45) && (parms.data_code != 0x00/*OBS*/)) { ! 146: parms.rc = 0x0b; ! 147: #endif /* NOTOBS */ ! 148: } else { ! 149: NameArray list; ! 150: ! 151: movetous((char *)&list, FP_SEG(parms.name_array), ! 152: FP_OFF(parms.name_array), sizeof list); ! 153: if ((list.length < 14) || (list.length > 170)) { ! 154: parms.rc = 0x12; ! 155: } else { ! 156: list.number_matching_session = 1; ! 157: list.name_array_element.short_name = parms.data_code; ! 158: list.name_array_element.type = TYPE_DFT; ! 159: list.name_array_element.session_id = PS_SESSION_ID; ! 160: memcpy(list.name_array_element.long_name, "ONLYSESS", ! 161: sizeof list.name_array_element.long_name); ! 162: movetothem(FP_SEG(parms.name_array), ! 163: FP_OFF(parms.name_array), (char *)&list, sizeof list); ! 164: parms.rc = 0; ! 165: } ! 166: } ! 167: parms.function_id = 0x6b; ! 168: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 169: } ! 170: ! 171: static void ! 172: query_session_parameters(regs, sregs) ! 173: union REGS *regs; ! 174: struct SREGS *sregs; ! 175: { ! 176: QuerySessionParametersParms parms; ! 177: ! 178: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 179: ! 180: if ((parms.rc !=0) || (parms.function_id != 0)) { ! 181: parms.rc = 0x0c; ! 182: } else if (parms.session_id != PS_SESSION_ID) { ! 183: parms.rc = 0x02; ! 184: } else { ! 185: parms.rc = 0; ! 186: parms.session_type = TYPE_DFT; ! 187: parms.session_characteristics = 0; /* Neither EAB nor PSS */ ! 188: parms.rows = MaxNumberLines; ! 189: parms.columns = MaxNumberColumns; ! 190: parms.presentation_space = 0; ! 191: } ! 192: parms.function_id = 0x6b; ! 193: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 194: } ! 195: ! 196: static void ! 197: query_session_cursor(regs, sregs) ! 198: union REGS *regs; ! 199: struct SREGS *sregs; ! 200: { ! 201: QuerySessionCursorParms parms; ! 202: ! 203: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 204: ! 205: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 206: parms.rc = 0x0c; ! 207: } else if (parms.session_id != PS_SESSION_ID) { ! 208: parms.rc = 0x02; ! 209: } else { ! 210: parms.rc = 0; ! 211: parms.cursor_type = CURSOR_BLINKING; /* XXX what is inhibited? */ ! 212: parms.row_address = ScreenLine(CursorAddress); ! 213: parms.column_address = ScreenLineOffset(CursorAddress); ! 214: } ! 215: ! 216: parms.function_id = 0x6b; ! 217: movetothem(sregs->es, regs->x.di, (char *) &parms, sizeof parms); ! 218: } ! 219: ! 220: /* ! 221: * Keyboard Services. ! 222: */ ! 223: ! 224: ! 225: static void ! 226: connect_to_keyboard(regs, sregs) ! 227: union REGS *regs; ! 228: struct SREGS *sregs; ! 229: { ! 230: ConnectToKeyboardParms parms; ! 231: ! 232: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 233: ! 234: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 235: parms.rc = 0x0c; ! 236: } else if (parms.session_id != PS_SESSION_ID) { ! 237: parms.rc = 0x02; ! 238: } else if (parms.intercept_options != 0) { ! 239: parms.rc = 0x01; ! 240: } else { ! 241: parms.rc = 0; ! 242: parms.first_connection_identifier = 0; ! 243: } ! 244: parms.function_id = 0x62; ! 245: ! 246: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 247: } ! 248: ! 249: static void ! 250: disconnect_from_keyboard(regs, sregs) ! 251: union REGS *regs; ! 252: struct SREGS *sregs; ! 253: { ! 254: DisconnectFromKeyboardParms parms; ! 255: ! 256: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 257: ! 258: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 259: parms.rc = 0x0c; ! 260: } else if (parms.session_id != PS_SESSION_ID) { ! 261: parms.rc = 0x02; ! 262: } else if (parms.connectors_task_id != 0) { ! 263: parms.rc = 04; /* XXX */ ! 264: } else { ! 265: parms.rc = 0; ! 266: } ! 267: parms.function_id = 0x62; ! 268: ! 269: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 270: } ! 271: ! 272: static void ! 273: write_keystroke(regs, sregs) ! 274: union REGS *regs; ! 275: struct SREGS *sregs; ! 276: { ! 277: WriteKeystrokeParms parms; ! 278: ! 279: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 280: ! 281: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 282: parms.rc = 0x0c; ! 283: } else if (parms.session_id != PS_SESSION_ID) { ! 284: parms.rc = 0x02; ! 285: } else if (parms.connectors_task_id != 0) { ! 286: parms.rc = 0x04; ! 287: } else { ! 288: parms.number_of_keys_sent = 0; ! 289: parms.rc = 0; ! 290: if (parms.options == OPTION_SINGLE_KEYSTROKE) { ! 291: KeystrokeEntry *entry = &parms.keystroke_specifier.keystroke_entry; ! 292: ! 293: if (AcceptKeystroke(entry->scancode, entry->shift_state) == 0) { ! 294: parms.rc = 0x10; /* XXX needs 0x12 too! */ ! 295: } ! 296: parms.number_of_keys_sent++; ! 297: } else if (parms.options == OPTION_MULTIPLE_KEYSTROKES) { ! 298: KeystrokeList ! 299: list, ! 300: far *atlist = parms.keystroke_specifier.keystroke_list; ! 301: KeystrokeEntry ! 302: entry[10], /* 10 at a time */ ! 303: *ourentry, ! 304: far *theirentry; ! 305: int ! 306: todo; ! 307: ! 308: movetous((char *)&list, FP_SEG(atlist), ! 309: FP_OFF(atlist), sizeof *atlist); ! 310: todo = list.length/2; ! 311: ourentry = entry+(highestof(entry)+1); ! 312: theirentry = &atlist->keystrokes; ! 313: ! 314: while (todo) { ! 315: if (ourentry > &entry[highestof(entry)]) { ! 316: int thistime; ! 317: ! 318: thistime = todo; ! 319: if (thistime > numberof(entry)) { ! 320: thistime = numberof(entry); ! 321: } ! 322: movetous((char *)entry, FP_SEG(theirentry), ! 323: FP_OFF(theirentry), thistime*sizeof *theirentry); ! 324: theirentry += thistime; ! 325: ourentry = entry; ! 326: } ! 327: if (AcceptKeystroke(ourentry->scancode, ! 328: ourentry->shift_state) == 0) { ! 329: parms.rc = 0x10; /* XXX needs 0x12 too! */ ! 330: break; ! 331: } ! 332: parms.number_of_keys_sent++; ! 333: ourentry++; ! 334: todo--; ! 335: } ! 336: } else { ! 337: parms.rc = 0x01; ! 338: } ! 339: } ! 340: parms.function_id = 0x62; ! 341: ! 342: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 343: /* XXX */ ! 344: } ! 345: ! 346: ! 347: static void ! 348: disable_input(regs, sregs) ! 349: union REGS *regs; ! 350: struct SREGS *sregs; ! 351: { ! 352: DisableInputParms parms; ! 353: ! 354: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 355: ! 356: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 357: parms.rc = 0x0c; ! 358: } else if (parms.session_id != PS_SESSION_ID) { ! 359: parms.rc = 0x02; ! 360: } else if (parms.connectors_task_id != 0) { ! 361: parms.rc = 0x04; ! 362: } else { ! 363: SetOiaApiInhibit(&OperatorInformationArea); ! 364: parms.rc = 0; ! 365: } ! 366: parms.function_id = 0x62; ! 367: ! 368: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 369: } ! 370: ! 371: static void ! 372: enable_input(regs, sregs) ! 373: union REGS *regs; ! 374: struct SREGS *sregs; ! 375: { ! 376: EnableInputParms parms; ! 377: ! 378: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 379: ! 380: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 381: parms.rc = 0x0c; ! 382: } else if (parms.session_id != PS_SESSION_ID) { ! 383: parms.rc = 0x02; ! 384: } else if (parms.connectors_task_id != 0) { ! 385: parms.rc = 0x04; ! 386: } else { ! 387: ResetOiaApiInhibit(&OperatorInformationArea); ! 388: parms.rc = 0; ! 389: } ! 390: parms.function_id = 0x62; ! 391: ! 392: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 393: } ! 394: ! 395: /* ! 396: * Copy Services. ! 397: */ ! 398: ! 399: static ! 400: copy_subroutine(target, source, parms, what_is_user, length) ! 401: BufferDescriptor *target, *source; ! 402: CopyStringParms *parms; ! 403: int what_is_user; ! 404: #define USER_IS_TARGET 0 ! 405: #define USER_IS_SOURCE 1 ! 406: { ! 407: #define TARGET_NO_EAB 1 ! 408: #define SOURCE_NO_EAB 2 ! 409: #define TARGET_PC 4 ! 410: #define SOURCE_PC 8 ! 411: #define NO_FIELD_ATTRIBUTES 16 ! 412: int needtodo = 0; ! 413: int access_length; ! 414: char far *input; ! 415: char far *output; ! 416: char far *access_pointer; ! 417: ! 418: if ((target->characteristics^source->characteristics) ! 419: &CHARACTERISTIC_EAB) { ! 420: if (target->characteristics&CHARACTERISTIC_EAB) { ! 421: needtodo |= TARGET_NO_EAB; /* Need to bump for EAB in target */ ! 422: } else { ! 423: needtodo |= SOURCE_NO_EAB; /* Need to bump for EAB in source */ ! 424: } ! 425: } ! 426: if (target->session_type != source->session_type) { ! 427: if (target->session_type == TYPE_PC) { ! 428: needtodo |= TARGET_PC; /* scan codes to PC */ ! 429: } else { ! 430: needtodo |= SOURCE_PC; /* PC to scan codes */ ! 431: } ! 432: } ! 433: if ((parms->copy_mode©_MODE_FIELD_ATTRIBUTES) == 0) { ! 434: needtodo |= NO_FIELD_ATTRIBUTES; ! 435: } ! 436: access_length = length; ! 437: if (what_is_user == USER_IS_TARGET) { ! 438: if (target->characteristics&CHARACTERISTIC_EAB) { ! 439: access_length *= 2; ! 440: } ! 441: input = (char far *) &Host[source->begin]; ! 442: access_pointer = target->buffer; ! 443: output = access_api(target->buffer, access_length, 0); ! 444: } else { ! 445: if (source->characteristics&CHARACTERISTIC_EAB) { ! 446: access_length *= 2; ! 447: } ! 448: access_pointer = source->buffer; ! 449: input = access_api(source->buffer, access_length, 1); ! 450: output = (char far *) &Host[target->begin]; ! 451: } ! 452: while (length--) { ! 453: if (needtodo&TARGET_PC) { ! 454: *output++ = disp_asc[*input++]; ! 455: } else if (needtodo&SOURCE_PC) { ! 456: *output++ = asc_disp[*input++]; ! 457: } else { ! 458: *output++ = *input++; ! 459: } ! 460: if (needtodo&TARGET_NO_EAB) { ! 461: input++; ! 462: } else if (needtodo&SOURCE_NO_EAB) { ! 463: *output++ = 0; /* Should figure out good EAB? */ ! 464: } ! 465: } ! 466: if (what_is_user == USER_IS_TARGET) { ! 467: unaccess_api(target->buffer, access_pointer, access_length, 1); ! 468: } else { ! 469: unaccess_api(source->buffer, access_pointer, access_length, 0); ! 470: } ! 471: } ! 472: ! 473: ! 474: static void ! 475: copy_string(regs, sregs) ! 476: union REGS *regs; ! 477: struct SREGS *sregs; ! 478: { ! 479: CopyStringParms parms; ! 480: BufferDescriptor *target = &parms.target, *source = &parms.source; ! 481: int length; ! 482: ! 483: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 484: ! 485: length = 1+parms.source_end-source->begin; ! 486: if ((parms.rc != 0) || (parms.function_id !=0)) { ! 487: parms.rc = 0x0c; ! 488: } else if (target->session_id == BUF_SESSION_ID) { /* Target is buffer */ ! 489: if (source->session_id != PS_SESSION_ID) { /* A no-no */ ! 490: parms.rc = 0x2; ! 491: } else { ! 492: if ((source->begin < 0) || (source->begin > highestof(Host))) { ! 493: parms.rc = 0x06; /* invalid source definition */ ! 494: } else { ! 495: if ((source->begin+length) > highestof(Host)) { ! 496: length = highestof(Host)-source->begin; ! 497: parms.rc = 0x0f; /* Truncate */ ! 498: } ! 499: if ((source->characteristics == target->characteristics) && ! 500: (source->session_type == target->session_type)) { ! 501: if (source->characteristics&CHARACTERISTIC_EAB) { ! 502: length *= 2; ! 503: } ! 504: movetothem(FP_SEG(target->buffer), ! 505: FP_OFF(target->buffer), ! 506: (char *)&Host[source->begin], length); ! 507: } else { ! 508: copy_subroutine(target, source, &parms, ! 509: USER_IS_TARGET, length); ! 510: } ! 511: } ! 512: } ! 513: } else if (source->session_id != BUF_SESSION_ID) { ! 514: parms.rc = 0xd; ! 515: } else { ! 516: /* Send to presentation space (3270 buffer) */ ! 517: if ((target->begin < 0) || (target->begin > highestof(Host))) { ! 518: parms.rc = 0x07; /* invalid target definition */ ! 519: } if (!UnLocked) { ! 520: parms.rc = 0x03; /* Keyboard locked */ ! 521: } else if (parms.copy_mode != 0) { ! 522: parms.rc = 0x0f; /* Copy of field attr's not allowed */ ! 523: } else if (IsProtected(target->begin) || /* Make sure no protected */ ! 524: (WhereAttrByte(target->begin) != /* in range */ ! 525: WhereAttrByte(target->begin+length-1))) { ! 526: parms.rc = 0x0e; /* Attempt to write in protected */ ! 527: } else { ! 528: if ((target->begin+length) > highestof(Host)) { ! 529: length = highestof(Host)-target->begin; ! 530: parms.rc = 0x0f; /* Truncate */ ! 531: } ! 532: TurnOnMdt(target->begin); /* Things have changed */ ! 533: if ((source->characteristics == target->characteristics) && ! 534: (source->session_type == target->session_type)) { ! 535: if (source->characteristics&CHARACTERISTIC_EAB) { ! 536: length *= 2; ! 537: } ! 538: movetous((char *)&Host[target->begin], ! 539: FP_SEG(source->buffer), ! 540: FP_OFF(source->buffer), length); ! 541: } else { ! 542: copy_subroutine(target, source, &parms, USER_IS_SOURCE, length); ! 543: } ! 544: } ! 545: } ! 546: parms.function_id = 0x64; ! 547: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 548: } ! 549: ! 550: ! 551: /* ! 552: * Operator Information Area Services. ! 553: */ ! 554: ! 555: static void ! 556: read_oia_group(regs, sregs) ! 557: union REGS *regs; ! 558: struct SREGS *sregs; ! 559: { ! 560: ReadOiaGroupParms parms; ! 561: ! 562: movetous((char *)&parms, sregs->es, regs->x.di, sizeof parms); ! 563: ! 564: if ((parms.rc != 0) || (parms.function_id != 0)) { ! 565: parms.rc = 0x0c; ! 566: } else if (parms.session_id != PS_SESSION_ID) { ! 567: parms.rc = 0x02; ! 568: } else { ! 569: int group = parms.oia_group_number; ! 570: char *from; ! 571: int size; ! 572: ! 573: if ((group != API_OIA_ALL_GROUPS) && ! 574: ((group > API_OIA_LAST_LEGAL_GROUP) || (group < 0))) { ! 575: } else { ! 576: if (group == API_OIA_ALL_GROUPS) { ! 577: size = API_OIA_BYTES_ALL_GROUPS; ! 578: from = (char *)&OperatorInformationArea; ! 579: } else if (group == API_OIA_INPUT_INHIBITED) { ! 580: size = sizeof OperatorInformationArea.input_inhibited; ! 581: from = (char *)&OperatorInformationArea.input_inhibited[0]; ! 582: } else { ! 583: size = 1; ! 584: from = ((char *)&OperatorInformationArea)+group; ! 585: } ! 586: movetothem(FP_SEG(parms.oia_buffer), FP_OFF(parms.oia_buffer), ! 587: from, size); ! 588: } ! 589: } ! 590: parms.function_id = 0x6d; ! 591: movetothem(sregs->es, regs->x.di, (char *)&parms, sizeof parms); ! 592: } ! 593: ! 594: /*ARGSUSED*/ ! 595: static void ! 596: unknown_op(regs, sregs) ! 597: union REGS *regs; ! 598: struct SREGS *sregs; ! 599: { ! 600: regs->h.ch = 0x12; ! 601: regs->h.cl = 0x05; ! 602: } ! 603: ! 604: ! 605: handle_api(regs, sregs) ! 606: union REGS *regs; ! 607: struct SREGS *sregs; ! 608: { ! 609: /* ! 610: * Do we need to log this transaction? ! 611: */ ! 612: if (apitrace) { ! 613: Dump('<', (char *)regs, sizeof *regs); ! 614: Dump('<', (char *)sregs, sizeof *sregs); ! 615: } ! 616: if (regs->h.ah == NAME_RESOLUTION) { ! 617: name_resolution(regs, sregs); ! 618: #if defined(unix) ! 619: } else if (regs->h.ah == PS_OR_OIA_MODIFIED) { ! 620: while ((oia_modified == 0) && (ps_modified == 0)) { ! 621: (void) Scheduler(1); ! 622: } ! 623: oia_modified = ps_modified = 0; ! 624: #endif /* defined(unix) */ ! 625: } else if (regs->h.ah != 0x09) { ! 626: regs->h.ch = 0x12; ! 627: regs->h.cl = 0x0f; /* XXX Invalid environmental access */ ! 628: } else if (regs->x.bx != 0x8020) { ! 629: regs->h.ch = 0x12; ! 630: regs->h.cl = 0x08; /* XXX Invalid wait specified */ ! 631: } else if (regs->h.ch != 0) { ! 632: regs->x.cx = 0x1206; /* XXX Invalid priority */ ! 633: } else { ! 634: switch (regs->x.dx) { ! 635: case GATE_SESSMGR: ! 636: switch (regs->h.al) { ! 637: case QUERY_SESSION_ID: ! 638: if (regs->h.cl != 0) { ! 639: regs->x.cx = 0x1206; ! 640: } else { ! 641: regs->x.cx = 0x1200; ! 642: query_session_id(regs, sregs); ! 643: } ! 644: break; ! 645: case QUERY_SESSION_PARAMETERS: ! 646: if (regs->h.cl != 0) { ! 647: regs->x.cx = 0x1206; ! 648: } else { ! 649: regs->x.cx = 0x1200; ! 650: query_session_parameters(regs, sregs); ! 651: } ! 652: break; ! 653: case QUERY_SESSION_CURSOR: ! 654: if ((regs->h.cl != 0xff) && (regs->h.cl != 0x00/*OBS*/)) { ! 655: regs->x.cx = 0x1206; ! 656: } else { ! 657: regs->x.cx = 0x1200; ! 658: query_session_cursor(regs, sregs); ! 659: } ! 660: break; ! 661: default: ! 662: unknown_op(regs, sregs); ! 663: break; ! 664: } ! 665: break; ! 666: case GATE_KEYBOARD: ! 667: if (regs->h.cl != 00) { ! 668: regs->x.cx = 0x1206; ! 669: } else { ! 670: regs->x.cx = 0x1200; ! 671: switch (regs->h.al) { ! 672: case CONNECT_TO_KEYBOARD: ! 673: connect_to_keyboard(regs, sregs); ! 674: break; ! 675: case DISABLE_INPUT: ! 676: disable_input(regs, sregs); ! 677: break; ! 678: case WRITE_KEYSTROKE: ! 679: write_keystroke(regs, sregs); ! 680: break; ! 681: case ENABLE_INPUT: ! 682: enable_input(regs, sregs); ! 683: break; ! 684: case DISCONNECT_FROM_KEYBOARD: ! 685: disconnect_from_keyboard(regs, sregs); ! 686: break; ! 687: default: ! 688: unknown_op(regs, sregs); ! 689: break; ! 690: } ! 691: } ! 692: break; ! 693: case GATE_COPY: ! 694: if (regs->h.cl != 0xff) { ! 695: regs->x.cx = 0x1206; ! 696: } else { ! 697: regs->x.cx = 0x1200; ! 698: switch (regs->h.al) { ! 699: case COPY_STRING: ! 700: copy_string(regs, sregs); ! 701: break; ! 702: default: ! 703: unknown_op(regs, sregs); ! 704: break; ! 705: } ! 706: } ! 707: break; ! 708: case GATE_OIAM: ! 709: if (regs->h.cl != 0xff) { ! 710: regs->x.cx = 0x1206; ! 711: } else { ! 712: regs->x.cx = 0x1200; ! 713: switch (regs->h.al) { ! 714: case READ_OIA_GROUP: ! 715: read_oia_group(regs, sregs); ! 716: break; ! 717: default: ! 718: unknown_op(regs, sregs); ! 719: break; ! 720: } ! 721: } ! 722: break; ! 723: default: ! 724: regs->h.ch = 0x12; ! 725: regs->h.cl = 0x34; /* Invalid GATE entry */ ! 726: break; ! 727: } ! 728: } ! 729: /* ! 730: * Do we need to log this transaction? ! 731: */ ! 732: if (apitrace) { ! 733: Dump('>', (char *)regs, sizeof *regs); ! 734: Dump('>', (char *)sregs, sizeof *sregs); ! 735: #ifdef MSDOS ! 736: { char buf[10]; gets(buf); } ! 737: #endif /* MSDOS */ ! 738: } ! 739: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.