IOCTL.C
上传用户:dcs7469208
上传日期:2010-01-02
资源大小:443k
文件大小:8k
源码类别:

操作系统开发

开发平台:

DOS

  1. /****************************************************************/
  2. /*                                                              */
  3. /*                          ioctl.c                             */
  4. /*                                                              */
  5. /*                    DOS/NT ioctl system call                  */
  6. /*                                                              */
  7. /*                      Copyright (c) 1995                      */
  8. /*                      Pasquale J. Villani                     */
  9. /*                      All Rights Reserved                     */
  10. /*                                                              */
  11. /* This file is part of DOS-C.                                  */
  12. /*                                                              */
  13. /* DOS-C is free software; you can redistribute it and/or       */
  14. /* modify it under the terms of the GNU General Public License  */
  15. /* as published by the Free Software Foundation; either version */
  16. /* 2, or (at your option) any later version.                    */
  17. /*                                                              */
  18. /* DOS-C is distributed in the hope that it will be useful, but */
  19. /* WITHOUT ANY WARRANTY; without even the implied warranty of   */
  20. /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See    */
  21. /* the GNU General Public License for more details.             */
  22. /*                                                              */
  23. /* You should have received a copy of the GNU General Public    */
  24. /* License along with DOS-C; see the file COPYING.  If not,     */
  25. /* write to the Free Software Foundation, 675 Mass Ave,         */
  26. /* Cambridge, MA 02139, USA.                                    */
  27. /****************************************************************/
  28. #include "../../hdr/portab.h"
  29. #include "globals.h"
  30. /* $Logfile:   C:/dos-c/src/kernel/ioctl.c_v  $ */
  31. #ifdef VERSION_STRINGS
  32. static BYTE *RcsId = "$Header:   C:/dos-c/src/kernel/ioctl.c_v   1.6   11 Jan 1998  2:06:22   patv  $";
  33. #endif
  34. /* $Log:   C:/dos-c/src/kernel/ioctl.c_v  $
  35.  * 
  36.  *    Rev 1.6   11 Jan 1998  2:06:22   patv
  37.  * Added functionality to ioctl.
  38.  * 
  39.  *    Rev 1.5   04 Jan 1998 23:15:18   patv
  40.  * Changed Log for strip utility
  41.  * 
  42.  *    Rev 1.4   16 Jan 1997 12:46:54   patv
  43.  * pre-Release 0.92 feature additions
  44.  * 
  45.  *    Rev 1.3   29 May 1996 21:03:30   patv
  46.  * bug fixes for v0.91a
  47.  * 
  48.  *    Rev 1.2   19 Feb 1996  3:21:34   patv
  49.  * Added NLS, int2f and config.sys processing
  50.  * 
  51.  *    Rev 1.1   01 Sep 1995 17:54:16   patv
  52.  * First GPL release.
  53.  * 
  54.  *    Rev 1.0   02 Jul 1995  8:32:04   patv
  55.  * Initial revision.
  56.  */
  57. /* $EndLog$ */
  58. #ifdef PROTO
  59. sft FAR *get_sft(COUNT);
  60. #else
  61. sft FAR *get_sft();
  62. #endif
  63. /*
  64.  * WARNING:  this code is non-portable (8086 specific).
  65.  */
  66. COUNT 
  67. DosDevIOctl (iregs FAR *r, COUNT FAR *err)
  68. {
  69. sft FAR *s;
  70. struct dpb FAR *dpbp;
  71. BYTE FAR *pBuffer = MK_FP(r -> DS, r -> DX);
  72. COUNT nMode;
  73. /* Test that the handle is valid */
  74. switch(r -> AL)
  75. {
  76. case 0x00:
  77. case 0x01:
  78. case 0x02:
  79. case 0x03:
  80. case 0x06:
  81. case 0x07:
  82. case 0x0a:
  83. case 0x0c:
  84. /* Get the SFT block that contains the SFT */
  85. if((s = get_sft(r -> BX)) == (sft FAR *)-1)
  86. {
  87. *err = DE_INVLDHNDL;
  88. return 0;
  89. }
  90. break;
  91. case 0x04:
  92. case 0x05:
  93. case 0x08:
  94. case 0x09:
  95. case 0x0d:
  96. case 0x0e:
  97. case 0x0f:
  98. case 0x10:
  99. case 0x11:
  100. if (r->BL > nblkdev)
  101. {    
  102. *err = DE_INVLDDRV;
  103. return 0;
  104. }
  105. else
  106. dpbp = &blk_devices[r -> BL];
  107. break;
  108. case 0x0b:
  109. /* skip, it's a special case. */
  110. break;
  111. default:
  112. *err = DE_INVLDFUNC;
  113. return 0;
  114. }
  115. switch(r -> AL)
  116. {
  117. case 0x00:
  118. /* Get the flags from the SFT */
  119. r -> DX = r -> AX = s -> sft_flags;
  120. /* Test for file and network SFT.  These return a 0 in */
  121. /* the AH register. */
  122. if( (s -> sft_flags & SFT_FSHARED)
  123. || !(s -> sft_flags & SFT_FDEVICE))
  124. {
  125.  r -> AH = 0;
  126. }
  127. break;
  128. case 0x01:
  129. /* sft_flags is a file, return an error because you */
  130. /* can't set the status of a file. */
  131. if(!(s -> sft_flags & SFT_FDEVICE))
  132. {
  133. *err = DE_INVLDFUNC;
  134. return 0;
  135. }
  136. /* Set it to what we got in the DL register from the */
  137. /* user. */
  138. r -> AX = (s -> sft_flags |= (SFT_FDEVICE | r -> DL));
  139. break;
  140. case 0x0c:
  141. nMode = C_GENIOCTL;
  142. goto  IoCharCommon;
  143. case 0x02:
  144. nMode = C_IOCTLIN;
  145. goto  IoCharCommon;
  146. case 0x10:
  147. nMode = C_IOCTLQRY;
  148. goto IoCharCommon;
  149. case 0x03:
  150. nMode = C_IOCTLOUT;
  151. IoCharCommon:
  152. if(!(s -> sft_flags & SFT_FDEVICE)
  153. || ((r -> AL == 0x10) && !(s -> sft_dev-> dh_attr & ATTR_QRYIOCTL))
  154. || ((r -> AL == 0x0c) && !(s -> sft_dev-> dh_attr & ATTR_GENIOCTL)))
  155. {
  156. if(s -> sft_dev -> dh_attr & SFT_FIOCTL)
  157.   {
  158. CharReqHdr.r_unit = 0;
  159. CharReqHdr.r_length = sizeof(request);
  160. CharReqHdr.r_command = nMode;
  161. CharReqHdr.r_count = r -> CX;
  162. CharReqHdr.r_trans = pBuffer;
  163. CharReqHdr.r_status = 0;
  164. execrh((request FAR *)&CharReqHdr,
  165.  s -> sft_dev);
  166. if(CharReqHdr.r_status & S_ERROR)
  167. return char_error(&CharReqHdr, 
  168. CharName(s -> sft_dev));
  169. if(r -> AL == 0x07)
  170. {
  171. r -> AL = 
  172.   CharReqHdr.r_status & S_BUSY ?
  173. 00 : 0xff;
  174. }
  175.      break;
  176. }
  177. }
  178. *err = DE_INVLDFUNC;
  179. return 0;
  180. case 0x0d:
  181. nMode = C_GENIOCTL;
  182. goto  IoBlockCommon;
  183. case 0x04:
  184. nMode = C_IOCTLIN;
  185. goto  IoBlockCommon;
  186. case 0x11:
  187. nMode = C_IOCTLQRY;
  188. goto IoBlockCommon;
  189. case 0x05:
  190. nMode = C_IOCTLOUT;
  191. IoBlockCommon:
  192. if(!(dpbp -> dpb_device -> dh_attr & ATTR_IOCTL)
  193. || ((r -> AL == 0x11) && !(dpbp -> dpb_device-> dh_attr & ATTR_QRYIOCTL))
  194. || ((r -> AL == 0x0d) && !(dpbp -> dpb_device-> dh_attr & ATTR_GENIOCTL)))
  195. {
  196. *err = DE_INVLDFUNC;
  197. return 0;
  198. }
  199. CharReqHdr.r_unit = r -> BL;
  200. CharReqHdr.r_length = sizeof(request);
  201. CharReqHdr.r_command = nMode;
  202. CharReqHdr.r_count = r -> CX;
  203. CharReqHdr.r_trans = pBuffer;
  204. CharReqHdr.r_status = 0;
  205. execrh((request FAR *)&CharReqHdr,
  206.  dpbp -> dpb_device);
  207. if(r -> AL == 0x08)
  208. {
  209. if(CharReqHdr.r_status & S_ERROR)
  210. {
  211. *err = DE_DEVICE;
  212. return 0;
  213. }
  214. r -> AX = (CharReqHdr.r_status & S_BUSY) ? 1 : 0;
  215. }
  216. else
  217. {
  218. if(CharReqHdr.r_status & S_ERROR)
  219. {
  220. *err = DE_DEVICE;
  221. return 0;
  222. }
  223. }
  224.      break;
  225. case 0x06:
  226. if (s -> sft_flags & SFT_FDEVICE)
  227. {
  228.     r -> AL = s -> sft_flags & SFT_FEOF ? 0 : 0xFF;
  229. }
  230. else 
  231.     r -> AL = s -> sft_posit >= s -> sft_size? 0xFF : 0;
  232. break;
  233. case 0x07:
  234. if (s -> sft_flags & SFT_FDEVICE)
  235. {
  236. goto IoCharCommon;
  237. }
  238. r -> AL = 0;
  239. break;
  240. case 0x08:
  241. if (dpbp -> dpb_device -> dh_attr & ATTR_EXCALLS)
  242. {
  243. nMode = C_REMMEDIA;
  244. goto IoBlockCommon;
  245. }
  246. *err = DE_INVLDFUNC;
  247. return 0;
  248. case 0x09:
  249. r -> DX = dpbp -> dpb_device -> dh_attr;
  250. break;
  251. case 0x0a:
  252. r -> DX = s -> sft_dcb -> dpb_device -> dh_attr;
  253. break;
  254. case 0x0e:
  255. nMode = C_GETLDEV;
  256. goto IoLogCommon;
  257. case 0x0f:
  258. nMode = C_SETLDEV;
  259. IoLogCommon:
  260. if(!(dpbp -> dpb_device -> dh_attr & ATTR_GENIOCTL))
  261. {
  262. if(r -> BL == 0)
  263. r -> BL = default_drive;
  264. CharReqHdr.r_unit = r -> BL;
  265. CharReqHdr.r_length = sizeof(request);
  266. CharReqHdr.r_command = nMode;
  267. CharReqHdr.r_count = r -> CX;
  268. CharReqHdr.r_trans = pBuffer;
  269. CharReqHdr.r_status = 0;
  270. execrh((request FAR *)&CharReqHdr,
  271.  dpbp -> dpb_device);
  272. if(CharReqHdr.r_status & S_ERROR)
  273. *err = DE_ACCESS;
  274. else
  275. *err = SUCCESS;
  276. return 0;
  277. }
  278. *err = DE_INVLDFUNC;
  279. return 0;
  280. default:
  281. *err = DE_INVLDFUNC;
  282. return 0;
  283. }
  284. *err = SUCCESS;
  285. return 0;
  286. }