| |
| |
| |
| |
| |
| |
| #include <psxtypes/psxtypes.h> |
| #include <ntapi/ntapi.h> |
| #include <ntapi/nt_termios.h> |
| #include <ptycon/ptycon.h> |
| #include "ptycon_driver_impl.h" |
| #include "ptycon_ioctl_impl.h" |
| #include "ptycon_status_impl.h" |
| |
| static int32_t ptyc_pty_open(nt_pty * hptm, nt_guid * pty_guid, nt_pty ** hpty) |
| { |
| nt_vfd_dev_name pty_name; |
| nt_oa oa = {sizeof(oa),0,0,0,0,0}; |
| |
| ntapi->vfd_dev_name_init( |
| &pty_name,pty_guid); |
| |
| oa.obj_name = &pty_name.name; |
| oa.root_dir = hptm; |
| |
| return ntapi->pty_open( |
| 0,hpty, |
| NT_FILE_ALL_ACCESS, |
| &oa,0,0,0); |
| } |
| |
| static int32_t ptyc_ptm_open(struct ptyc_common_ctx * cctx) |
| { |
| nt_guid pty_guid = TTY_PTM_GUID; |
| |
| return ptyc_pty_open( |
| 0,&pty_guid, |
| &cctx->hptm); |
| } |
| |
| static int32_t ptyc_pts_open(struct ptyc_common_ctx * cctx) |
| { |
| int32_t status; |
| nt_guid pty_guid = TTY_PTS_GUID; |
| |
| if ((status = ptyc_grant(cctx->hptm))) |
| return status; |
| |
| return ptyc_pty_open( |
| cctx->hptm,&pty_guid, |
| &cctx->hpts); |
| } |
| |
| static int32_t ptyc_make_raw(nt_pty * hpty) |
| { |
| int32_t status; |
| nt_iosb iosb; |
| nt_tty_sigctl_info ctlinfo; |
| struct tty_termios termios; |
| |
| ntapi->tt_aligned_block_memset( |
| &ctlinfo,0,sizeof(ctlinfo)); |
| |
| if ((status = ntapi->pty_ioctl( |
| hpty, |
| 0,0,0, |
| &iosb, |
| TTY_TCGETS, |
| &ctlinfo,sizeof(ctlinfo), |
| &ctlinfo,sizeof(ctlinfo)))) |
| return status; |
| |
| ntapi->tt_generic_memcpy( |
| &termios, |
| &ctlinfo.terminfo, |
| sizeof(termios)); |
| |
| termios.c_oflag &= ~TTY_OPOST; |
| |
| termios.c_cflag &= ~(TTY_CSIZE | TTY_PARENB); |
| termios.c_cflag |= TTY_CS8; |
| |
| termios.c_lflag &= ~(TTY_ECHO |
| | TTY_ECHONL |
| | TTY_ICANON |
| | TTY_ISIG |
| | TTY_IEXTEN); |
| |
| termios.c_iflag &= ~(TTY_IGNBRK |
| | TTY_BRKINT |
| | TTY_PARMRK |
| | TTY_ISTRIP |
| | TTY_INLCR |
| | TTY_IGNCR |
| | TTY_ICRNL |
| | TTY_IXON); |
| |
| ntapi->tt_aligned_block_memset( |
| &ctlinfo,0,sizeof(ctlinfo)); |
| |
| ntapi->tt_generic_memcpy( |
| &ctlinfo.terminfo, |
| &termios, |
| sizeof(termios)); |
| |
| return ntapi->pty_ioctl( |
| hpty, |
| 0,0,0, |
| &iosb, |
| TTY_TCSETS, |
| &ctlinfo,sizeof(ctlinfo), |
| &ctlinfo,sizeof(ctlinfo)); |
| } |
| |
| static int32_t ptyc_make_oven(nt_pty * hpty) |
| { |
| int32_t status; |
| nt_iosb iosb; |
| nt_tty_sigctl_info ctlinfo; |
| struct tty_termios termios; |
| |
| ntapi->tt_aligned_block_memset( |
| &ctlinfo,0,sizeof(ctlinfo)); |
| |
| if ((status = ntapi->pty_ioctl( |
| hpty, |
| 0,0,0, |
| &iosb, |
| TTY_TCGETS, |
| &ctlinfo,sizeof(ctlinfo), |
| &ctlinfo,sizeof(ctlinfo)))) |
| return status; |
| |
| ntapi->tt_generic_memcpy( |
| &termios, |
| &ctlinfo.terminfo, |
| sizeof(termios)); |
| |
| termios.c_cflag = TTY_CBAUD | TTY_CREAD | TTY_CS8 | TTY_HUPCL; |
| termios.c_iflag = TTY_ICRNL | TTY_BRKINT | TTY_IXON; |
| termios.c_lflag = TTY_ECHO |
| | TTY_ECHOCTL |
| | TTY_ECHOE |
| | TTY_ECHOK |
| | TTY_ECHOKE |
| | TTY_ICANON |
| | TTY_ISIG |
| | TTY_IEXTEN; |
| |
| termios.c_oflag = TTY_OPOST |
| | TTY_ONLCR |
| | TTY_TAB0 |
| | TTY_VT0 |
| | TTY_BS0 |
| | TTY_CR0 |
| | TTY_FF0 |
| | TTY_NL0; |
| |
| ntapi->tt_aligned_block_memset( |
| &ctlinfo,0,sizeof(ctlinfo)); |
| |
| ntapi->tt_generic_memcpy( |
| &ctlinfo.terminfo, |
| &termios, |
| sizeof(termios)); |
| |
| return ntapi->pty_ioctl( |
| hpty, |
| 0,0,0, |
| &iosb, |
| TTY_TCSETS, |
| &ctlinfo,sizeof(ctlinfo), |
| &ctlinfo,sizeof(ctlinfo)); |
| } |
| |
| int ptyc_alloc_pty(struct ptyc_driver_ctx * dctx) |
| { |
| int32_t status; |
| struct ptyc_driver_ctx_impl * ictx; |
| struct ptyc_common_ctx * cctx; |
| |
| if (!(ictx = ptyc_get_driver_ictx(dctx))) |
| return NT_STATUS_INVALID_HANDLE; |
| |
| cctx = &ictx->cctx; |
| |
| if (cctx->hpts || cctx->hptm) |
| return ptyc_set_status( |
| dctx,NT_STATUS_DEVICE_ALREADY_ATTACHED); |
| |
| if ((status = ptyc_ptm_open(cctx))) |
| return ptyc_set_status( |
| dctx,status); |
| |
| if ((status = ptyc_make_raw(cctx->hptm))) |
| return ptyc_set_status( |
| dctx,status); |
| |
| if ((status = ptyc_pts_open(cctx))) |
| return ptyc_set_status( |
| dctx,status); |
| |
| if ((status = ptyc_set_client_info(cctx->hpts,&ictx->clctx.clinfo))) |
| return ptyc_set_status( |
| dctx,status); |
| |
| if (cctx->drvflags & PTYC_DRIVER_DBG_RAW) |
| if ((status = ptyc_make_raw(cctx->hpts))) |
| return ptyc_set_status( |
| dctx,status); |
| |
| if (cctx->drvflags & PTYC_DRIVER_DBG_OVEN) |
| if ((status = ptyc_make_oven(cctx->hpts))) |
| return ptyc_set_status( |
| dctx,status); |
| |
| if (cctx->drvflags & (PTYC_DRIVER_DBG_RAW|PTYC_DRIVER_DBG_OVEN)) |
| if ((status = ptyc_pty_own(cctx->hpts,ictx->rtdata))) |
| return ptyc_set_status( |
| dctx,status); |
| |
| return ptyc_set_status( |
| dctx,NT_STATUS_SUCCESS); |
| } |
| |
| void ptyc_free_pty(struct ptyc_driver_ctx * dctx) |
| { |
| struct ptyc_driver_ctx_impl * ictx; |
| |
| if (!(ictx = ptyc_get_driver_ictx(dctx))) |
| return; |
| |
| if (ictx->cctx.hpts) { |
| ntapi->pty_close(ictx->cctx.hpts); |
| ictx->cctx.hpts = 0; |
| } |
| |
| if (ictx->cctx.hptm) { |
| ntapi->pty_close(ictx->cctx.hptm); |
| ictx->cctx.hptm = 0; |
| } |
| } |