IOCTL.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:8k
- /****************************************************************/
- /* */
- /* ioctl.c */
- /* */
- /* DOS/NT ioctl system call */
- /* */
- /* Copyright (c) 1995 */
- /* Pasquale J. Villani */
- /* All Rights Reserved */
- /* */
- /* This file is part of DOS-C. */
- /* */
- /* DOS-C is free software; you can redistribute it and/or */
- /* modify it under the terms of the GNU General Public License */
- /* as published by the Free Software Foundation; either version */
- /* 2, or (at your option) any later version. */
- /* */
- /* DOS-C is distributed in the hope that it will be useful, but */
- /* WITHOUT ANY WARRANTY; without even the implied warranty of */
- /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See */
- /* the GNU General Public License for more details. */
- /* */
- /* You should have received a copy of the GNU General Public */
- /* License along with DOS-C; see the file COPYING. If not, */
- /* write to the Free Software Foundation, 675 Mass Ave, */
- /* Cambridge, MA 02139, USA. */
- /****************************************************************/
- #include "../../hdr/portab.h"
- #include "globals.h"
- /* $Logfile: C:/dos-c/src/kernel/ioctl.c_v $ */
- #ifdef VERSION_STRINGS
- static BYTE *RcsId = "$Header: C:/dos-c/src/kernel/ioctl.c_v 1.6 11 Jan 1998 2:06:22 patv $";
- #endif
- /* $Log: C:/dos-c/src/kernel/ioctl.c_v $
- *
- * Rev 1.6 11 Jan 1998 2:06:22 patv
- * Added functionality to ioctl.
- *
- * Rev 1.5 04 Jan 1998 23:15:18 patv
- * Changed Log for strip utility
- *
- * Rev 1.4 16 Jan 1997 12:46:54 patv
- * pre-Release 0.92 feature additions
- *
- * Rev 1.3 29 May 1996 21:03:30 patv
- * bug fixes for v0.91a
- *
- * Rev 1.2 19 Feb 1996 3:21:34 patv
- * Added NLS, int2f and config.sys processing
- *
- * Rev 1.1 01 Sep 1995 17:54:16 patv
- * First GPL release.
- *
- * Rev 1.0 02 Jul 1995 8:32:04 patv
- * Initial revision.
- */
- /* $EndLog$ */
- #ifdef PROTO
- sft FAR *get_sft(COUNT);
- #else
- sft FAR *get_sft();
- #endif
- /*
- * WARNING: this code is non-portable (8086 specific).
- */
- COUNT
- DosDevIOctl (iregs FAR *r, COUNT FAR *err)
- {
- sft FAR *s;
- struct dpb FAR *dpbp;
- BYTE FAR *pBuffer = MK_FP(r -> DS, r -> DX);
- COUNT nMode;
- /* Test that the handle is valid */
- switch(r -> AL)
- {
- case 0x00:
- case 0x01:
- case 0x02:
- case 0x03:
- case 0x06:
- case 0x07:
- case 0x0a:
- case 0x0c:
-
- /* Get the SFT block that contains the SFT */
- if((s = get_sft(r -> BX)) == (sft FAR *)-1)
- {
- *err = DE_INVLDHNDL;
- return 0;
- }
- break;
- case 0x04:
- case 0x05:
- case 0x08:
- case 0x09:
- case 0x0d:
- case 0x0e:
- case 0x0f:
- case 0x10:
- case 0x11:
- if (r->BL > nblkdev)
- {
- *err = DE_INVLDDRV;
- return 0;
- }
- else
- dpbp = &blk_devices[r -> BL];
- break;
- case 0x0b:
- /* skip, it's a special case. */
- break;
- default:
- *err = DE_INVLDFUNC;
- return 0;
- }
- switch(r -> AL)
- {
- case 0x00:
- /* Get the flags from the SFT */
- r -> DX = r -> AX = s -> sft_flags;
- /* Test for file and network SFT. These return a 0 in */
- /* the AH register. */
- if( (s -> sft_flags & SFT_FSHARED)
- || !(s -> sft_flags & SFT_FDEVICE))
- {
- r -> AH = 0;
- }
- break;
- case 0x01:
- /* sft_flags is a file, return an error because you */
- /* can't set the status of a file. */
- if(!(s -> sft_flags & SFT_FDEVICE))
- {
- *err = DE_INVLDFUNC;
- return 0;
- }
- /* Set it to what we got in the DL register from the */
- /* user. */
- r -> AX = (s -> sft_flags |= (SFT_FDEVICE | r -> DL));
- break;
- case 0x0c:
- nMode = C_GENIOCTL;
- goto IoCharCommon;
- case 0x02:
- nMode = C_IOCTLIN;
- goto IoCharCommon;
- case 0x10:
- nMode = C_IOCTLQRY;
- goto IoCharCommon;
- case 0x03:
- nMode = C_IOCTLOUT;
- IoCharCommon:
- if(!(s -> sft_flags & SFT_FDEVICE)
- || ((r -> AL == 0x10) && !(s -> sft_dev-> dh_attr & ATTR_QRYIOCTL))
- || ((r -> AL == 0x0c) && !(s -> sft_dev-> dh_attr & ATTR_GENIOCTL)))
- {
- if(s -> sft_dev -> dh_attr & SFT_FIOCTL)
- {
- CharReqHdr.r_unit = 0;
- CharReqHdr.r_length = sizeof(request);
- CharReqHdr.r_command = nMode;
- CharReqHdr.r_count = r -> CX;
- CharReqHdr.r_trans = pBuffer;
- CharReqHdr.r_status = 0;
- execrh((request FAR *)&CharReqHdr,
- s -> sft_dev);
- if(CharReqHdr.r_status & S_ERROR)
- return char_error(&CharReqHdr,
- CharName(s -> sft_dev));
- if(r -> AL == 0x07)
- {
- r -> AL =
- CharReqHdr.r_status & S_BUSY ?
- 00 : 0xff;
- }
- break;
- }
- }
- *err = DE_INVLDFUNC;
- return 0;
- case 0x0d:
- nMode = C_GENIOCTL;
- goto IoBlockCommon;
- case 0x04:
- nMode = C_IOCTLIN;
- goto IoBlockCommon;
- case 0x11:
- nMode = C_IOCTLQRY;
- goto IoBlockCommon;
- case 0x05:
- nMode = C_IOCTLOUT;
- IoBlockCommon:
- if(!(dpbp -> dpb_device -> dh_attr & ATTR_IOCTL)
- || ((r -> AL == 0x11) && !(dpbp -> dpb_device-> dh_attr & ATTR_QRYIOCTL))
- || ((r -> AL == 0x0d) && !(dpbp -> dpb_device-> dh_attr & ATTR_GENIOCTL)))
- {
- *err = DE_INVLDFUNC;
- return 0;
- }
- CharReqHdr.r_unit = r -> BL;
- CharReqHdr.r_length = sizeof(request);
- CharReqHdr.r_command = nMode;
- CharReqHdr.r_count = r -> CX;
- CharReqHdr.r_trans = pBuffer;
- CharReqHdr.r_status = 0;
- execrh((request FAR *)&CharReqHdr,
- dpbp -> dpb_device);
- if(r -> AL == 0x08)
- {
- if(CharReqHdr.r_status & S_ERROR)
- {
- *err = DE_DEVICE;
- return 0;
- }
- r -> AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
- }
- else
- {
- if(CharReqHdr.r_status & S_ERROR)
- {
- *err = DE_DEVICE;
- return 0;
- }
- }
- break;
- case 0x06:
- if (s -> sft_flags & SFT_FDEVICE)
- {
- r -> AL = s -> sft_flags & SFT_FEOF ? 0 : 0xFF;
- }
- else
- r -> AL = s -> sft_posit >= s -> sft_size? 0xFF : 0;
- break;
- case 0x07:
- if (s -> sft_flags & SFT_FDEVICE)
- {
- goto IoCharCommon;
- }
- r -> AL = 0;
- break;
- case 0x08:
- if (dpbp -> dpb_device -> dh_attr & ATTR_EXCALLS)
- {
- nMode = C_REMMEDIA;
- goto IoBlockCommon;
- }
- *err = DE_INVLDFUNC;
- return 0;
- case 0x09:
- r -> DX = dpbp -> dpb_device -> dh_attr;
- break;
- case 0x0a:
- r -> DX = s -> sft_dcb -> dpb_device -> dh_attr;
- break;
- case 0x0e:
- nMode = C_GETLDEV;
- goto IoLogCommon;
- case 0x0f:
- nMode = C_SETLDEV;
- IoLogCommon:
- if(!(dpbp -> dpb_device -> dh_attr & ATTR_GENIOCTL))
- {
- if(r -> BL == 0)
- r -> BL = default_drive;
- CharReqHdr.r_unit = r -> BL;
- CharReqHdr.r_length = sizeof(request);
- CharReqHdr.r_command = nMode;
- CharReqHdr.r_count = r -> CX;
- CharReqHdr.r_trans = pBuffer;
- CharReqHdr.r_status = 0;
- execrh((request FAR *)&CharReqHdr,
- dpbp -> dpb_device);
- if(CharReqHdr.r_status & S_ERROR)
- *err = DE_ACCESS;
- else
- *err = SUCCESS;
- return 0;
- }
- *err = DE_INVLDFUNC;
- return 0;
- default:
- *err = DE_INVLDFUNC;
- return 0;
- }
- *err = SUCCESS;
- return 0;
- }