Moving Grave6:(MG#_6.X01):16/10/1996 << Back To Moving Grave6


Unas palabras antes... (La venganza...) ─────────────────────────────────────── Como hace ya algunos meses atras, cuando habiamos tocado el tema de devices drivers, el cual quedo inconcluso por una pequenia contrariedad (las cuales si son inteligente, se daran cuenta) pero a la cual no pienso nombrar...asi es que como vimos la respuesta de la gente...decidimos a sa- carlo nuevamente pero esta vez mas completo y con un virus de DEVICES DRIVER que REALMENTE FUNCIONE, pero antes de ver al virus, terminemos de ver el tema de los driver. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= INSTALLABLE DEVICE DRIVERS (PART II) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= CONTENIDO DE ESTA EDICION ------------------------- Esctructura de un Device Driver Instalando Device Drivers Instalando Character Devices Instalando Block Devices Request Header Unit Code Field Command Code Field Status Field Funciones de los Device Driver INIT MEDIA CHECK Media Descriptor Byte CREANDO BPB (BIOS Parameter Block) INPUT OR OUTPUT NONDESTRUCTIVE INPUT NO WAIT STATUS FLUSH OPEN or CLOSE (DOS 3.0+) REMOVEABLE MEDIA (DOS 3.0+) ESCTRUCTURA DE UN DEVICE DRIVER├─────────────────────────────────────────────── Un device driver consiste de tres grandes partes: UN DEVICE HEADER UNA RUTINA DE ESTRATEGIA UNA RUTINA DE INTERRUPCION DEVICE HEADER El driver tiene un header especial para identificarse como un DEVICE y para definir los puntos de entrada de la rutina de estrategia e interrupcion y posee varios atributos. Este header esta localizado en el comienzo del archivo. Este contien un puntero a el proximo device driver en la cadena, el atributo de el device, desplazamiento (offset) dentro de la rutina de estrategia y la de interrupcion, y el ID (Independence Day, no!, sino identificador) del device. Este es el formato de un header de un device driver: ┌──────────────────────────────────────────────────────────────────────────────┐ │ D E V I C E H E A D E R │ ├───────┬────────┬─────────────────────────────────────────────────────────────┤ │Offset │ Length │ Descripcion │ ├───────┼────────┼─────────────────────────────────────────────────────────────┤ │ 00h │ word │ Puntero al proximo campo DEVICE HEADER (OFFSET) │ ├───────┼────────┼─────────────────────────────────────────────────────────────┤ │ 02h │ word │ Puntero al proximo campo DEVICE HEADER (SEGMENT) │ ├───────┼────────┼─────────────────────────────────────────────────────────────┤ │ 04h │ word │ Atributo │ ├───────┼────────┼─────────────────────────────────────────────────────────────┤ │ 06h │ word │ Puntero a la rutina de ESTRATEGIA (offset solamente) │ ├───────┼────────┼─────────────────────────────────────────────────────────────┤ │ 08h │ word │ Puntero a la rutina de INTERRUPCION (offset solamente) │ ├───────┼────────┼─────────────────────────────────────────────────────────────┤ │ 0Ah │8 bytes │ Nombre/Unidad │ └───────┴────────┴─────────────────────────────────────────────────────────────┘ PUNTERO AL PROXIMO CAMPO DEVICE HEADER El CAMPO DEVICE HEADER es un puntero a un de un header hasta el otro header de un device driver. Este campo es un DOBLE WORD que esta seteado por el DOS en el momento que el device driver es leido. El primer word es el offset y el segundo word es el segmento. Si estas leyendo solamente un device driver, setea el CAMPO DEVICE HEADER en -1 despues de leer el device. Si esta leyendo mas de un device driver, setea el primer word de el header del device driver hacia el offset del proximo hea- der del device driver. Setea el Header del device driver del ultimo device driver a -1. ATRIBUTO El atributo es un campo de un word usado para identificar el tipo de device por el cual el driver es responsable. Este campo distingue entre un bloque y un caracter device y determina si el device es selecciona este le da un tra- tamiento especial. Los atributos son los siguientes: ┌──────────────────────────────────────────────────────────────────────────────┐ │ A T T R I B U T E F I E L D │ ├──────────┬───────┬───────────────────────────────────────────────────────────┤ │ word │ attr. │ │ ├──────────┼───────┤ description │ │ bits │ set │ │ ├──────────┼───────┼───────────────────────────────────────────────────────────┤ │ 0 │ 0 │ not current standard input device │ │ │ 1 │ current standard input device │ ├──────────┼───────┼───────────────────────────────────────────────────────────┤ │ 1 │ 0 │ not current standard output device │ │ │ 1 │ current standard output device │ ├──────────┼───────┼───────────────────────────────────────────────────────────┤ │ 2 │ 0 │ not current NUL device │ │ │ 1 │ current NUL device │ ├──────────┼───────┼───────────────────────────────────────────────────────────┤ │ 3 │ 0 │ not current CLOCK device │ │ │ 1 │ current CLOCK device │ ├──────────┼───────┼───────────────────────────────────────────────────────────┤ │ 4 │ 0 │ standard CON I/O routines should be used │ │ │ 1 │ fast screen I/O (int 29h) should be used │ ├──────────┼───────┴───────────────────────────────────────────────────────────┤ │ 5 - 10 │ "reserved for DOS" - unknown - should be set to 0 │ ├──────────┼───────┬───────────────────────────────────────────────────────────┤ │ 11 │ 0 │ doesn't support removeable media (default for DOS 2.x) │ │ │ 1 │ supports removeable media (DOS 3.0+ only) │ ├──────────┼───────┴───────────────────────────────────────────────────────────┤ │ 12 │ "reserved for DOS" - unknown - should be set to 0 │ ├──────────┼───────┬───────────────────────────────────────────────────────────┤ │ 13 │ 0 │ IBM format (block devices) │ │ │ 1 │ non-IBM format (block devices) │ │ │ 1 │ output till busy (character devices) │ ├──────────┼───────┼───────────────────────────────────────────────────────────┤ │ 14 │ 0 │ doesn't support IOCTL │ │ │ 1 │ supports IOCTL │ ├──────────┼───────┼───────────────────────────────────────────────────────────┤ │ 15 │ 0 │ block device │ │ │ 1 │ character device │ └──────────┴───────┴───────────────────────────────────────────────────────────┘ nota 1) Si un bit es definido en el word de atributo solamente para un solo tipo de device, un driver para los otros tipos de devices debera se- tear este bit a 0 2) Para DOS 2.0 los bits 4-12 deben estar apagados BIT 1 es el bit de entrada y salida estandar. Este es usado por los caracter device solamente. Use este bit para decirle a DOS si su caracter device driver es la nuevo entrada device o la salida device estandar. BIT 2 es el bit de atributo NULo. Este es usado por los caracters devices so- lamente. Usar este para decirle a dos si su caracter devices driver es un DEVICE NULo.Aunque este sea un bit de DEVICE NULo, se puede reasig- nar el DEVICE NUL o reemplazar este con su propia rutina. Este atribu- to existe para DOS y solamente DOS puede decir si el DEVICE NULo esta siendo usado. BIT 3 es el bit de CLOCK DEVICE. Este es usado por los caracter device sola- mente. Por defecto es 0. Se puede usar para indicar a DOS si su carac- ter device driver es un nuevo CLOCK device. BIT 4 Es el bit de "salida de video rapita". Por defecto es 0, el cual usa el BIOS para escribir en la pantalla. Cuando es seteado este bit usa la int 29h para renovar mucho mas rapido la pantalla. BITS 5-10 Reservados para DOS, desconocidos. Debe estar seteado en 0. BIT 11 Es el bit de open/close removeable media. Usar este para indicarle a DOS si el device driver puede manejar el removeable media.Este bit es valido para DOS mayores a la version 3.0 solamente. Este bit esta re- servado en la version 2.x. Puesto que DOS 2.x no puede ver a este bit. BIT 12 reservado para DPS, desconocido. Debe estar seteado en 0 BIT 13 Es el bit de formato non-IBM.Cuando es usado por los block devices este afecta la operacion de llamado al creador de BPB (BIOS parameter block) DEVICE.Para los caracter device este indica que el device im- plementa el llamado a OUTPUT UNTIL BUSY device. BIT 14 Es el bit de IOCTL. Este es usado tanto para caracter como para block devices. Usar este para indicar a DOS cuales de los device driver puede manejar la cadena de control a travez de la funcion 44h del IOCTL Si un device driver no puede procesar la cadena de control, el bit 14 deberia ser seteado a 0. De este modo DOS puede retornar un error si un intento es producido a travez de la llamada de funcion IOCTL para enviar o recivir la cadena de control hacia el device.Si el device puede procesar la cadena de control, el bit 14 debera ser seteado a 1. De este modo, DOS creara llamados a la funcion de entrada/salida IOCTL del device para enviar/recivir cadenas IOCTL. La funcion IOCTL el envio de datos y desde el device sin actualizar permite una lectura/escritura normal. En este caso, el device driver puede usar datos para su propio uso, (p/ejemplo, seteando un BAUD RATE o STOP BITS, cambio de longitudes, etc.) Este es principal para el device para interpretar la informacion que es pasada por este, pero la informacion quizas no sea tratada como una solicitud normal del I/O. BIT 15 Es el bit de TIPO. Usar este para indicar al sistema de que el driver es un block o un caracter device. PUNTERO A LA RUTINA DE ESTRATEGIA Este campo contiene un puntero hacia la funcion "estrategia del device" en el driver. Esta funcion es llamada siempre que un requerimiento sea creado por el driver, y debe colocar la localizacion de el REQUEST HEADER desde DOS. Este puntero es un valor del tipo word, y debe estar de todas formas como el device header. PUNTERO A LA RUTINA DE INTERRUPCION Este campo contiene un puntero a la funcion que activa la rutina del driver para ejecutar el comando en el request header actual. Este es llamado por DOS despues del llamado de la funcion de estrategia, y debera resetar a la direc- cion del request header recuperado por la "estrategia", para dejar desde la posibilidad de interrupciones entre los dos llamados. Este puntero es un valor de tipo word, y entonces deber estar en el mismo segmento como el devi- ce header. CAMPO DE NOMBRE/UNIDAD Este es un campo de 8-byte, este contiene el nombre de un caracter device o el numero de unidades en un block device. Para el nombre caracter, el nombre es justificado a la izquierda y el espacio es llenado para completar 8 bytes. Para los block devices, el numero de unidades puede ser ubicado en el primer byte. Esto es opcional porque DOS completa en esta ubicacion con el valor de- vuelto con el codigo de INIT del driver. Los restantes 7 bytes del ID block device son reservados y no son usados. INSTALANDO UN DEVICE DRIVER├────────────────────────────────────────────────── DOS instala un nuevo device driver dinamicamente en el momento del booteo pa- ra leer y procesar los comandos DEVICE en el archivo config.sys. Por ejemplo, si tu tienes escrito un device driver llamado RAMDISK, para instalarlo deberas colocar este comando dentro del archivo config.sys DEVICE=[drive][path] RAMDISK [parameters] DOS crea una llamada lejana al device driver en su primer punto de entrada de la estrategia, usando el request header para pasar informacion describiendo que DOS posee el device driver para usar. Esta rutina de estrategia no ejecuta el request pero mejor dicho enfila el request o salva el puntero a el request header. El segundo punto de entrada es la rutina de interrupcion y es llamada por el DOS inmediatamente despues de que la rutina de estrategia retorna. La rutina de interrupcion es llamada sin parametros. Esta funcion es para ejecutar la operacion basada sobre la hilera de request y es setea cualquier informacion retornada. DOS pasa el puntero a el request header en ES:BX. Esta estructura consiste de un tamanio de header fijo (Request Header) seguido por la informacion per- tinente a la operacion a ejecutar. NOTA: Este es respondable del device driver para preservar el estado de la maquina. Por ejemplo, salava todos los registros en la entrada y recu- pera estos a la salida. El stack usado por DOS tiene bastante lugar en este para salvar todos los registros. Si es necesario mas espacio del stack, este es el responsable de alocar al device driver y mantener otro stack. Todos los llamados a ejecutar el device driver son llamados lejanos (FAR). Una llamada lejana es ejecutada para retornar al DOS. INSTALANDO UN CARACTER DEVICE Una de las funciones definidas por cada device es INIT. Esta rutina es lla- mada solamente cuando el device es instalado y nunca mas. La rutina INIT re- torna lo siguiente: A) Una localizacion hacia el primer byte libre de la memoria despues del devi- ce driver. Como un TSR que esta colocado en la direccion final del campo. De este modo, el codigo inicializacion puede ser usado una vez y de este modo ahorra espacio. B) Despues de setear el campo de direccion, un caracter device driver puede setear el word de estado y retornar. INSTALANDO BLOCK DEVICES Los block devices son instalados en la misma forma que el caracter device. La diferencia es que el block device retorna informacion adicional. Lo block de- vice puede retornar lo siguiente: A) El numero de unidades dentro del block device. Este numero determina los nombres logicos que puede tener el device. Por ejemplo, si la actual actual letra logica del device es F en el momento del llamado de instalacion, y el y la rutina INIT del block device driver retorna tres unidades logicas, las letras G, H e I son asignadas a las unidades. Este mapeo esta determinado por la posicion del driver en la lista de device y el numero de unidades en el device. El numero de unidades retornados por el INIT sobrepasa el valor el campo de nombre/unidad del device header. B) Un puntero al array de puntero BPB (BIOS parameter block). Esto es un pun- tero a un array de "N" punteros word, esta "N" es el numero de unidades de- finidas. Estos punteros word apuntan a los BPBs. De esta manera, si la to- talidad de las unidades son la misma, el array de entrada puede apuntar a el mismo BPB para guardar espacio. El BPB contiene informacion pertinente del device tal como al tamaño del sector, numero de sectores por unidad localizada, etc. El tamaño del sector del BPB no puede ser mas grande que el maximo tamaño localizado seteado en el DOS en el momento de su inicializacion. Este array puede estar protegi- do por tres punteros seteador por el retorno. C) El byte de media descriptor. Este byte es pasado por el device asi que este conoce que parametros DOS usa actualmente una unidad driver en particular. Los block device pueden tomar accesos severos. Este puede ser "dumb" o "smart". Un dumb device define una unidad (y por lo tanto un BPB) para cada posible convinacion de media driver. Unidad 0=driver 0; simple cara, unidad 1=driver 0;doble cara, etc. Para este método, los bytes de media descriptor significan nada (?). Un device listo permite multiples media por unidad. En este caso, el BPB table retorna a INIT deben tener un largo espacio libre a para acomodar el largo posible de las medias soportadas (tamaño del sector en BPB debe estar como largo como maximo tamaño del sector DOS que esta siendo usado actualmente). Los Smart drivers usan el byte de media descriptor para pasar informacion acerca de que media es uctual en la unidad. REQUEST HEADER├──────────────────────────────────────────────────────────────── El request header pasa la informacion describiendo que DOS necesita el device driver para funcionar. (?) Cuando un coigo de comando de un device driver es valido o una funcion es lla- mado por su programa de aplicacion, DOS desarrollar una estructura de datos llamada el "Request Header" en ES:BX y pasando esto al punto de entrada de la estrategia. Esta estructura consiste de un 13 byte definido el cual puede ser seguido por otros bytes de datos dependiendo de la funcion requerida. Este es la responsabilidad del device driver para preservar el estado de la maquina, por ejemplo, salvando todos los registros incluyendo flags en la en- trada y recuperando estos en la salida. Estos es bastante lugar en la stack cuándo la estrategia y la interrupcion son llamadas luego de unos 20 pushes. Si es necesario mas stack, el driver setea al lado estos propio espacios de stack. La parte fija ("static") de el request header es la siguiente: ┌────────────────────────────────────────────────────────────────────────────┐ │ R E Q U E S T H E A D E R │ ├───────┬───────┬────────────────────────────────────────────────────────────┤ │Offset │Length │ F i e l d │ ├───────┼───────┼────────────────────────────────────────────────────────────┤ │ 00h │ byte │ Length in bytes of the request header plus any data at end │ ├───────┼───────┼────────────────────────────────────────────────────────────┤ │ 01h │ byte │ Unit code. Determines subunit to use in block devices │ │ │ │ (minor device) Has no meaning for character devices │ ├───────┼───────┼────────────────────────────────────────────────────────────┤ │ 02h │ byte │ Command code │ ├───────┼───────┼────────────────────────────────────────────────────────────┤ │ 03h │ word │ Status │ ├───────┼───────┼────────────────────────────────────────────────────────────┤ │ 05h │8 bytes│ Reserved for DOS │ ├───────┼───────┼────────────────────────────────────────────────────────────┤ │ 0Ch │varies │ Data appropriate for the operation │ └───────┴───────┴────────────────────────────────────────────────────────────┘ REQUEST HEADER LENGTH FIELD La longitud en bytes del total del request header (0-255) más algun dato en el final del header. UNIT CODE FIELD El campo de unidad de codigo identifica cual unidad en un block device driver posee el request. Por ejemplo, si un block device driver posee tres unidades definidas, entonces los posibles valores del campo de codigo de unidad varia entre 0, 1, y 2. Este campo no es valido para los caracteres devices. COMMAND CODE FIELD El codigo de comando invoca a funciones especificas del device driver. Las funciones de la 0 a la 12 estan soportadas en todos los devices driver. Las funciones 13-15 estan disponibles solamente en DOS 3.0 o mayores. Algunas funciones son relevantes por cualquiera de los dos devices, caracteres o bloques, pero no ambos; nonetheless(?) todas las funciones deben tener una rutina ejecutable presente aun si esta no hace nada pero seteado el flag de terminacion en el word de retorno de estatus en el request header. El campo de codigo de comando en el request header puede tener los siguientes valores: ┌──────┬──────────────────┬────────────────────────────────────────────────────┐ │ code │ name │ function │ ├──────┼──────────────────┼────────────────────────────────────────────────────┤ │ 0 │ INIT │ initialize driver for later use (used once only) │ │ 1 │ MEDIA CHECK │ block devices only, NOP for character devices │ │ 2 │ BUILD BPB │ block devices only, NOP for character devices │ │ 3 │ IOCTL input │ called only if device has IOCTL bit set │ │ 4 │ INPUT │ read data │ │ 5 │ NONDESTRUCTIVE INPUT NO WAIT character devices only │ │ 6 │ INPUT STATUS │ character devices only │ │ 7 │ INPUT FLUSH │ character devices only │ │ 8 │ OUTPUT │ write data │ │ 9 │ OUTPUT │ write data with verify │ │ 10 │ OUTPUT STATUS │ character devices only │ │ 11 │ OUTPUT FLUSH │ character devices only │ │ 12 │ IOCTL OUTPUT │ called only if device has IOCTL bit is set │ │ 13 │ DEVICE OPEN │ called only if OPEN/CLOSE/RM bit is set │ │ 14 │ DEVICE CLOSE │ called only if OPEN/CLOSE/RM bit is set │ │ 15 │ REMOVEABLE MEDIA │ only if OPEN/CLOSE/RM bit set & device is block │ │ 16 │ OUTPUT UNTIL BUSY│ only called if bit 13 is set & device is character │ └──────┴──────────────────┴────────────────────────────────────────────────────┘ Los codigos de comando individuales seran descritos luego en este capitulo. STATUS FIELD El campo word status es cero sobre entrada y es seteado por la rutina de in- terrupcion sobre la salida del driver. El campo del status en el request header contiene: ┌─────────────────────────────────────────────────────────────────────────────┐ │ D E V I C E D R I V E R S T A T U S F I E L D │ ├───────┬───┬─────────────────────────────────────────────────────────────────┤ │ size │bit│ definition │ ├───────┼───┼─────────────────────────────────────────────────────────────────┤ │ byte │ 0 │ │ │ │ 1 │ │ │ │ 2 │ │ │ │ 3 │ Error message return code │ │ │ 4 │ (with bit 15=1) │ │ │ 5 │ │ │ │ 6 │ │ │ │ 7 │ │ ├───────┼───┼─────────────────────────────────────────────────────────────────┤ │ byte │ 8 │ DONE │ │ ├───┼─────────────────────────────────────────────────────────────────┤ │ │ 9 │ BUSY │ │ ├───┼─────────────────────────────────────────────────────────────────┤ │ │ A │ Reserved by DOS, unknown │ │ │ B │ │ │ │ C │ │ │ │ D │ │ │ │ E │ │ │ ├───┼─────────────────────────────────────────────────────────────────┤ │ │ F │ Error │ └───────┴───┴─────────────────────────────────────────────────────────────────┘ Los 8 bits bajos del word status define un mensaje de error si el bit 15 esta definido. Estos errores son los siguientes: 00h write protect violation 01h unknown unit 02h device not ready 03h unknown command 04h CRC error 05h bad drive request structure length 06h seek error 07h unknown media 08h sector not found 09h printer out of paper 0Ah write fault 0Bh read fault 0Ch general failure 0Dh reserved 0Eh reserved 0Fh invalid disk change BIT 8 es el bit de terminado. Si este esta seteado, el medio de operacion esta completo. El driver setea el bit en 1 cuando este existe. BIT 9 es el bit de BUSY. Este esta solamente seteado por el llamado del sta- tus y el llamado media removible. BITS 10-14 son reservados. BIT 15 es el bit de error. Si este bit es seteado, los 8 bits bajos del word status (7-0) indican el codigo de error. RESERVED FOR DOS Los fuentes oficiales rotulan esta area como "reservada para DOS". Otros fuen- tes indican que este consiste en dos punteros doble-word (4-bytes) usados para mantener un lista enlazada de los request headers de este device y una lista de todos los devices request actuales naturalmente procesados por DOS. Este es aparentemente usado por la indeliverada version multitasking de DOS. DEVICE DRIVER FUNCTIONS├─────────────────────────────────────────────────────── Todas las rutinas de estrategia son llamadas con ES:BX apuntando al request header. La rutina de interrupcion toma los punteros del request header desde la fila donde se guardan las rutina de estrategia. El codigo de comando en el request header dice al driver que funcion ejecutar. NOTA: Todos los punteros DWORD son guardado primero el offset, y luego el seg- mento ############################ INIT Command code = 0 (all devices) Ejecuta todas las inicializaciones requeridas por DOS en el momento del booteo para instalar el driver y setear las variables locales del driver. Esta funcion es llamada solamente una vez, cuando el driver es leido. ES:BX Puntero al byte-26 del request header y estructura de dato Formato de la estructura: offset length field 00h 13 bytes request header 0Dh byte number of units (not set by character devices) 11h dword ending address of the driver's resident code 15h dword pointer to BPB array (not set by character devices) /pointer to remainder of arguments 19h byte drive number (DOS 3.0+ only) Cuando el INIT es llamado, el driver realiza lo siguiente: A) Setea el numero de unidades (solamente block devices) B) Setea el puntero al array del BPB (solamente block devices) C) Ejecuta alguno codigo de inicializacion (para modems, impresoras, etc) D) Setea la direccion final del codigo residente del programa. E) Setea el word de status en el request header. Para obtener la informacion obtenidad desde el CONFIG.SYS hacia un device driver en el momento del INIT, el puntero al campo del BPB apunta a un buffer conteniendo la informacion pasada desde el CONFIG.SYS siguiendo el =.El buffer que DOS pasa a el driver en el INIT despues el file especificado contiene una cadena de ASCII de el file abierto. La cadena ASCII (terminada en 0h=NULL) es terminada por un retorno de carro (0Dh) y retorno de linea (0Ah). Si ahi no estan los parametros de informacion despues de la especificacion del archivo, el archivo especificado es inmediatamente seguido de un retorno de linea (0Ah) NOTA: Esta informacion es de solo lectura y solamente el sistema llama 01h-0Ch y 30h puede estar emitido por el codigo del INIT del driver El ultimo byte de parametro contiene la letra del driver desde la primera unidad de un block device. Por ejemplo, 0=A, 1=B, etc. Si una rutina INI determina que este no puede setear el device y buscar la salida sin usar nada de memoria, siguiendo este procedimiento: A) Setear el numero de unidades a 0 B) Setear el offset de la direccion del final a 0 C) Setear el desplazamineto del segmento de la direccion del final a el codigo del segmento (CS) NOTA: Si hay multiples device drivers en una solo archivo de imagen de memoria, la direccion final retornada por el ultimo llamado INIT es el primero usado por DOS. Este recomienda que todo device driver en un solo archivo de imagen de memoria retorna la mismo direccion del final. ############################ MEDIA CHECK command code = 1 (block devices only) Chequea para ver si el disco fue cambiado desde el ultimo acceso. ES:BX Puntero al byte-19 del request header y estructura de datos Formato de la structure: offset length field 00h 13 bytes request header 0Dh byte media descriptor from BPB 0Eh byte returned 0Fh dword returns a pointer to the previous volume ID (if bit 11=1 and disk change is returned) (DOS 3.0+) Cuando el campo del codigo de comando es 1, DOS llama al MEDIA CHECK para una unidad driver y pasa este byte de media descriptor. MEDIA CHECK retorna lo siguiente: A) media not changed C) not sure B) media changed D) error code El driver ejecuta lo siguiente: A) Setea el word de status en el request header. B) Setea el byte de retorno 00h No reconoce si el MEDIA ha sido cambiado 01h El MEDIA no fue cambiado -1 El MEDIA fue cambiado DOS 3.0+: Si el driver seteo el bit 11 de media removible del device header, el word de atributo a 1 y el driver retorna -1 (media changed), el driver debe setear el puntero DWORD al campo de identificacion del volume previo. Si DOS determina que el media cambiado es un error, DOS generea un error 0Fh (cambio de disco invalido) sobre a favor de el device. Si el driver no posee implemen- tado el soporte del volumen de identificacion, pero teniendo el bit 11 seteado en 1, el driver setea el puntero a la cadena "NO NAME", 0. MEDIA DESCRIPTOR Actualmente el byte de media descriptor esta definido para unos pocos tipos de medias. Este byte es indentico al media byte si el device tiene el bit de for- mato non-IBM apagado (off). Estos valores predeterminados son: byte de media descriptor => 1 1 1 1 1 0 0 0 (numeric order) 7 6 5 4 3 2 1 0 BIT MEANING 0 0 not double sided 1 double sided 1 0 not 8 sector 1 8 sector 2 0 nonremoveable 1 removeable 3-7 must be set to 1 ############################ BUILD BPB (BIOS Parameter Block) command code = 2 (solamente block devices) ES:BX puntero al byte 22 del request header y estructura de datos Formato de la estructura: offset length field 00h 13 bytes request header 0Dh byte media descriptor from DOS 0Eh dword transfer address (buffer address) 12h dword pointer to BPB table DOS llama al CREADOR DE BPB (BUILD BPB) bajo las siguientes dos condiciones: A) Si el "media changed" es retornado. B) Si "not sure" es retornado. Si es asi,este no usa buffers. Usando buffers en buffers con datos cambiados que todavía no fue escrito en el disco. El driver debe tener lo siguiente: A) Seteado el puntero al BPB. B) Seteado el word de stauts en el request header. El driver debe determinar el tipo correcto de medio correcto en la unidad a retornar el puntero a la tabla del BPB. El modo en que el buffer es usado (puntero pasado por el DOS) esta determinado por el bit de formato non-IBM en el campo de atributo de el device header. Si el bit 13=0 (el device es un IBM compatible), el buffer contiene el primer sector de la FAT (el byte FAT ID que es el mas importante). El driver no debe alterara este buffer en este caso. Si el bit 13=1 el buffer es un primer sector del area "scratch" qué puede ser usada por cualquiera. Para drivers este soporta la identificacion de volume y el cambio de disco, el llamado puede causar un nuevo identificador de volume para dejar de leer el disco. Este llamado indica que el disco ha sido cambiado correctamente. Si el device es compatible con IBM, debe ser cierto que el primer sector de la primera copia de la FAT esta localizada en algun sector por todos los me- dios posibles. Este es porque el sector de la FAT es leido antes que el medio (media) sea realmente determinado. La informacion llevada al BPB por un medio particular es colocado en el boot sector por el medio (media). En particular, el formato del boot sector es: ┌──────────────────────────────────────────────────────────────────────────────┐ │ For DOS 2.x, 3 byte near jump (0E9h) For DOS 3.x+, 2 byte near jump (0EBh) │ │ followed by a NOP (90h) │ ├──────────┬───────────────────────────────────────────────────────────────────┤ │ 8 bytes │ OEM name and version │ ├──────────┼─────┬─────────────────────────────────────────────────────────────┤ │ BYTE │ │ sectors per allocation unit (must be a power of 2) │ ├──────────┤ ├─────────────────────────────────────────────────────────────┤ │ WORD │ B │ reserved sectors (strarting at logical sector 0) │ ├──────────┤ ├─────────────────────────────────────────────────────────────┤ │ BYTE │ │ number of FATs │ ├──────────┤ ├─────────────────────────────────────────────────────────────┤ │ WORD │ P │ max number of root directory entries │ ├──────────┤ ├─────────────────────────────────────────────────────────────┤ │ WORD │ │ number of sectors in logical image (total number of │ │ │ │ sectors in media, including boot sector directories, etc.) │ ├──────────┤ B ├─────────────────────────────────────────────────────────────┤ │ BYTE │ │ media descriptor │ ├──────────┤ ├─────────────────────────────────────────────────────────────┤ │ WORD │ │ number of sectors occupied by a single FAT │ ├──────────┼─────┴─────────────────────────────────────────────────────────────┤ │ WORD │ sectors per track │ ├──────────┼───────────────────────────────────────────────────────────────────┤ │ WORD │ number of heads │ ├──────────┼───────────────────────────────────────────────────────────────────┤ │ WORD │ number of hidden sectors │ └──────────┴───────────────────────────────────────────────────────────────────┘ Los tres ultimos words retornan informacion acerca del medio (media). El nu- mero de cabezas es util para soportar diferentes drivers de multiples cabezas que tengan la misma capacidad de almacenamiento pero un diferentes numeros de supercicies. El numero de sectores ocultos es util para el esquema de la par- ticion del driver. ############################ INPUT / OUTPUT (IOCTL) command code = 3 IOCTL Read 4 Read (block or character devices) 8 Write (block or character devices) 9 Write With Verify 12 IOCTL Write 16 Output Until Busy (character devices only) ES:BX Puntero al byte 24 del request header y la estructura de datos Formato de la estructura: offset length field 00h 13 bytes request header 0Dh byte media descriptor byte from BPB 0Eh dword transfer address (buffer address) 12h word byte/sector count 14h word starting sector number (block devices) [no meaning on character devices] 16h dword (DOS 3.0+) pointer to the volume ID if error code 0Fh is returned El driver debe ejecutar lo siguiente: A) Setear el world del status en el request header B) ejecutar la funcion de peticion C) setear el actual numero de sectores o bytes transferidos El chequeo de error no es ejecutado en un llamado I/O de IOCTL. Sin embargo el drive debe retornar el sector o el byte contador al actual numero de bytes transferidos. Bajo ciertas circunstancias un block device driver puede preguntar para una operacion de escritura de 64k bytes que parecen un redondeo de la direccion de tranferencia en el paquete de I/O del BIOS. Este surge debido a una optimiza- ción sumada al escribir codigo en DOS. Este solo sucede en escrituras que estan dentro de un tamaño de sector de 64k sobre archivos que estan extendidos pasan- do el actual EOF (End Of File). Esto esta permitido por el device driver para ignorar el balance de la escritura que redondea, si este asi lo escoge. Por ejemplo, una escritura con un valor de 10000h byte de sectores con una direccion de transferencia de XXX:1 ignora los dos ultimos bytes. Un usuario de programa nunca puede requerir un I/O de mas te 0FFFFh bytes y tampoco redondear (igual a 0) en el segmento de tranferencia, también en este los dos ultimos bytes son ignorados. Un programa que usa llamadas a funciones de DOS nunca pide una funcion de entrada o salida de mas de 0FFFFh bytes, por lo tanto, un redondeo en el seg- mento de transferencia (buffer) nunca puede ocurrir. Por este motivo nunca podra ignorar bytes que pretenda redondear en el segmento de transferencia. Si el driver retorna un codigo de error 0Fh (Cambio de disco invalido) este debe colocar un puntero DWORD a un string ASCIIZ el cual es el correcto volu- me ID a pedir al usuario a reinsertar el disco (?). DOS 3.0+: El contador de referencia al abrir archivos sobre el campo (mantenido por los llamados de OPEN y CLOSE) permite al driver determinar cuando para retornar un error 0Fh. Si no hay abiertos archivos (contador de referencia=0) y el dis- co ha sido cambiado, el I/O esta bien, y no es retornado el error 0Fh. Si no hay abiertos archivos (contador de referencia >0) y el disco ha sigo cambiado, un error de condicion 0Fh puede que exista. ############################ NONDESTRUCTIVE INPUT NO WAIT command code = 5 (character devices only) Lee caracteres desde la entrada pero no remueve esta desde el buffer ES:BX puntero al byte 14 del request header y la estructura de datos Formato de la estructura: offset length field 00h 13 bytes request header 0Dh byte read from device El driver debe hacer los siguiente: A) Retornar un byte desde el device B) Setear el word del status en el request header. Si el caracter device retorna busy (ocupado - bit=0) (caracteres en el buffer), entonces el proximo caracter que se lea es retornado. Este caracter no es removido del buffer (por lo tanto se llama entrada no destructible). Esta llamada permite al DOS mirar delante un caracter. ############################ STATUS command codes = 6 Input Status (character devices only) 10 Output Status (character devices only) Chequea el caracter que esta esperando en el buffer de entrada ES:BX puntero al byte 13 del request header Este driver debe hacer lo siguiente: A) ejecutar la funcion requerida B) setear el bit de BUSY C) setear el word de status en el request header. El bit de busy es seteado de la siguiente manera: Para entradas sobre caracter devices sin buffer: Si el bit de busy (bit 9) es 1 en el retorno, una peticion de escritura pretende esperar por la terminacion de la peticion actual. Si el bit de busy es 0, no hay peticiones actuales. Por lo tanto, una peticion de escritura pretende comenzar inmediatamente. Para entradas sobre caracter devices con buffer: Si el bit de busy es 1 en la salida, una peticion de escritura hace el device físico. Si el bit busy es 0, hay caracteres en el buffer del device y una lectura retorna rapidamente. Este también indica que un usuario puede tipear algo. DOS asume que todos los carac- teres devices tiene tipo de entrada de buffer adelante. Devices que no posean este buffer siempre retornan busy=0 así que DOS no "corta" esperando por la informacion a ser colocada en el buffer que no existe. ############################ FLUSH INPUT BUFFERS command code = 7 (character devices only) Fuerza todas los datos en el buffer a un device especial. ES:BX puntero al byte 13 del request header. Este llamado dice el driver para limpiar (terminar) todas las peticiones pen- dientes que este conoce. Este uso primario es para limpiar la coloa de entrada de un caracter device. El driver debe setear el word de status en el request header sobre el retorno. ############################ FLUSH OUTPUT BUFFERS command code 11 (character devices only) Fuerza todas los datos en el buffer a un device especial. ES:BX puntero al byte 13 del request header Este llamado dice el driver para limpiar todas salidas del buffer y descartar las peticiones pendientes. Este uso primario es para limpiar la coloa de sali- da de un caracter device. El driver debe setear el word de status en el request header sobre el retorno. ############################ OPEN or CLOSE (DOS 3.0+) command code = 13 Open (block or character devices) 14 Close (block or character devices) ES:BX puntero al byte 13 del static del request header Estos llamados estan designados para dar al device informacion sobre el actual archivo activo sobre el device si el bit 11 de el word de atributo se encuentra seteado. Sobre block devices, estos llamados pueden ser usados para manejar el "buffereo" local. El device puede mantener un contador referencia. Todos las aperturas causan al device un incremento en el contador de referencia. Todos los cierres causan en el device un decremento en el contador de referencia. Cuando el contador de referencia es 0, si no hay archivos abiertos en el devi- ce. Por lo tanto, el device driver limpiara los buffers dentro del devices ello tiene escrito porque no puede cambiar el medio sobre un driver de medio remo- vible. Si el medio es cambiado, este aconsejable resetear el contador de re- ferencia a 0 sin limpiar los buffers. Esto puede pensar de como "el ultimo cerrado produce la limpieza". Estos llamados son mas utiles sobre un caracter device. El llamado de ABRIR puede ser usado para enviar la cadena de iniciali- zacion al device. En una impresora, esto puede causar un string para enviar para setear el font, el tamaño del papel, etc. Así que la impresora pretende siempre estar un un estado concido en el flujo de entrada I/O. De forma similar un llamada a CERRAR puede ser usado para enviar un string puesto en el final del flujo de I/O. Usando el IOCTL para setear este PRE y POST string provee al device una flexibilidad mecanica del control del I/O serial. Desde entonces todos los procesos tienen acceso a STDIN, STDOUT, STDERR, STDAUX, y STDPRN (handles 0, 1, 2, 3, y 4) al CON, AUX, y PRN devices estan siempre abiertos. ############################ REMOVABLE MEDIA (DOS 3.0+) command code = 15 (block devices only) Este llamado identifica el tipo de medio como removible o no. ES:BX puntero al byte 13 del static del request header Para usar este llamado, se debe setear el bit 11 del campo de atributo a 1 ( medio removible). Los block devices pueden solamente llamar a través de una subfuncion de la funcion de llamada al IOCTL (int 21 funcion 44h). Esta llamada es util porque esta permitir una utilidad para conocer si este es tratado como un driver de medio no removible o como un driver de medio re- movible. Por ejemplo, el utilitario FORMAT necesita conocer si un driver es removible o no porque este imprime diferentes versiones de algunos prompts (?) Nota: No se ejecutan chequeos de errores. Estos son asumidos que estos llamados siempre suceden. =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= END OF TEXT ----> INSTALLABLE DEVICE DRIVERS (PART II) =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= Espero que cualquier duda que tengan sobre el tema no duden en llamar a los boards respectivos!, y dejar mensajes. ---/ Moving Grave 6 [MG#6] /--- ---/ COEAC Group. /--- -= Written by DΣ$ΓτΘ¥Στ From the HALLS OF THE DAMNED =-