Cómo aplicaciones de Win32 pueden leer sectores de CD-ROM en Windows 95

IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.

137813
Este artículo se ha archivado. Se ofrece "tal cual" y no se volverá a actualizar.
Resumen
Algunas aplicaciones de Win32, como aplicaciones multimedia y juegos, necesitan leer sectores directamente desde los discos compactos para implementar el acceso personalizado o leer el almacenamiento en caché para optimizar el acceso a CD-ROM para propósitos específicos. En este artículo proporciona información y código de ejemplo que muestra cómo las aplicaciones de Win32 pueden leer sectores desde discos compactos en Windows 95.
Más información
El sistema de archivo de disco compacto (CDFS) de Windows 95 es un controlador de CD-ROM de modo protegido que implementa las funciones de 2Fh V86 modo MSCDEX interrupción como su único interfaz llamar la aplicación. Esta interfaz permite reemplazar los controladores de CD-ROM y Mscdex.exe de modo real y seguir siendo totalmente compatibles con aplicaciones existentes de MS-DOS y Windows 3.x. De hecho, las aplicaciones para MS-DOS y Windows 3.x no podrá indicar la diferencia entre CDFS y Mscdex.exe.

Windows 95 proporciona una interfaz para aplicaciones Win32 leer sectores de discos compactos. Esta interfaz difiera sustancialmente desde que proporcionó Windows. Mientras las aplicaciones Win32 en Windows NT utilizan CreateFile() y ReadFile() leer sectores de discos compactos, las aplicaciones de Win32 que se ejecutan en Windows 95 deben utilizar un método indirecto que implica thunk a una DLL de 16 bits llama a Int MSCDEX 2Fh funciones.

Dado que la interfaz MSCDEX es invocable sólo en modo de V86, aplicaciones deben thunk a una DLL de 16 bits y la DLL de 16 bits de Win32 debe utilizar la función de interfaz de modo protegido de DOS (DPMI) simular real modo de interrupción para llamar a sus funciones. La aplicación Win32 debe pasar un búfer a la DLL de 16 bits. Dentro de thunk, la DLL de 16 bits obtiene los datos del sector de MSCDEX, lo copia en búfer de la aplicación de Win32 y devuelve a la aplicación de Win32.



El código siguiente muestra cómo leer sectores de un disco compacto con el método descrito anteriormente. Dado que el código implementa un thunk plano, se divide en tres secciones:
  • Código que reside en un archivo DLL de Win32 (el lado de 32 bits de thunk).
  • Código que reside en la secuencia de comandos thunk.
  • Código que reside en la DLL de 16 bits que llama realmente a MSCDEX.
//--------------------------------------------------------------------// Code inside the Win32 DLL (the 32-bit side of the thunk)// ReadSectorsFromCD() is exported by the DLL so that it can be called// by Win32-based applications.#include <windows.h>#define CD_SECTOR_SIZE         2048__declspec(dllexport)BOOL WINAPI ReadSectorsFromCD (BYTE   bDrive,                               DWORD  dwStartSector,                               WORD   wSectors,                               LPBYTE lpBuff);// Prototype for thunk function in 16-bit DLL.BOOL FAR PASCAL ReadCDRomSectors (BYTE   bDrive,                                  DWORD  dwStartSector,                                  WORD   wSectors,                                  LPBYTE lpBuffer);/*-------------------------------------------------------------------  ReadSectorsFromCD()  Calls the thunked function, ReadCDRomSectors(). This function is  exported by the Win32 DLL and thus is callable from Win32-based  applications.  Parameters:     bDrive        Drive letter of CD-ROM drive to read from. Specified as        a character in the range 'A', 'B', 'C', ..., 'Z'.  May be        upper- or lower-case.     dwStartSector        First sector to read.     wSectors        Number of sectors to read.     lpBuffer        Buffer to contain sector data. Must be large enough to        accommodate all sectors being read. Because this buffer is        provided to the 16-bit DLL via a thunk, its maximum        length is limited to 64K.  Example use:     // Read 5 sectors from CD-ROM drive E: starting at sector 16.     fResult = ReadSectorsFromCD ('E', 16, 5, lpBuff);  Return Value     Returns TRUE if successful, or FALSE if an error occurred     in reading or if a parameter was invalid.-------------------------------------------------------------------*/ __declspec(dllexport)BOOL WINAPI ReadSectorsFromCD (BYTE   bDrive,                               DWORD  dwStartSector,                               WORD   wSectors,                               LPBYTE lpBuff){   // Call 16-bit DLL to read sectors via a 32->16 thunk   return ReadCDRomSectors (bDrive, dwStartSector, wSectors, lpBuff);}//--------------------------------------------------------------------// Contents of the thunk scriptenablemapdirect3216 = true;typedef unsigned short WORD;typedef unsigned long  DWORD;typedef unsigned char  BYTE, *LPBYTE;typedef bool           BOOL;BOOL ReadCDRomSectors (BYTE   bDrive,                       DWORD  dwStartSector,                       WORD   wSectors,                       LPBYTE lpBuffer){   lpBuffer = inout;}//--------------------------------------------------------------------// Code inside the 16-bit DLL. This code implements the 16-bit side of// the thunk, and is where the calls to MSCDEX are made to read// sectors from a compact disc.#include <windows.h>#include <string.h>#include <ctype.h>// Cooked-mode sector size in bytes#define CD_SECTOR_SIZE         2048// Maximum sector buffer size in bytes#define MAX_BUFFER_LENGTH      65536// Maximum number of sectors for each read request#define MAX_CD_SECTORS_TO_READ ((MAX_BUFFER_LENGTH) / \                                 (CD_SECTOR_SIZE))// Processor flags masks -- use for testing wFlags member of RMCS#define CARRY_FLAG  0x0001// Real-mode call structure for making DPMI Simulate Real Mode// Interrupt calls.typedef struct tagRMCS{   DWORD edi, esi, ebp, RESERVED, ebx, edx, ecx, eax;   WORD  wFlags, es, ds, fs, gs, ip, cs, sp, ss;} RMCS, FAR* LPRMCS;BOOL FAR PASCAL __export ReadCDRomSectors (BYTE   bDrive,                                           DWORD  dwStartSector,                                           WORD   wSectors,                                           LPBYTE lpBuffer);BOOL FAR PASCAL MSCDEX_ReadSector (BYTE   bDrive,                                   DWORD  dwStartSector,                                   LPBYTE RMlpBuffer);BOOL FAR PASCAL SimulateRM_Int (BYTE bIntNum, LPRMCS lpCallStruct);void FAR PASCAL BuildRMCS (LPRMCS lpCallStruct);/*-------------------------------------------------------------------  ReadCDRomSectors()  Reads a specified number of sectors from a CD-ROM.  Parameters:     bDrive        Drive letter of CD-ROM drive to read from. Specified as        a character in the range 'A', 'B', 'C', ..., 'Z'.  May be        upper- or lower-case.     dwStartSector        First sector to read.     wSectors        Number of sectors to read.     lpBuffer        Buffer to contain sector data. Must be large enough to        accommodate all sectors being read. Since this buffer is        provided by the calling Win32 application, no more than        the first 64K bytes will be used.  Return Value     Returns TRUE if successful, or FALSE if an error occurred     in reading or if a parameter was invalid.-------------------------------------------------------------------*/ BOOL FAR PASCAL __export ReadCDRomSectors (BYTE   bDrive,                                           DWORD  dwStartSector,                                           WORD   wSectors,                                           LPBYTE lpBuffer){   BOOL   fResult;   DWORD  cbOffset;   DWORD  i;   DWORD  gdaBuffer;     // Return value of GlobalDosAlloc().   LPBYTE RMlpBuffer;    // Real-mode buffer pointer   LPBYTE PMlpBuffer;    // Protected-mode buffer pointer   // Convert drive letter into drive number for MSCDEX call.   bDrive = toupper(bDrive) - 'A';   /*      Validate parameters:         bDrive must be between 0 and 25, inclusive.         lpBuffer must not be NULL.         wSectors must be between 1 and the maximum number of            sectors that can fit into a 64K buffer, inclusive.   */    if (bDrive > 25 || !lpBuffer)      return FALSE;   if (!wSectors || (wSectors > MAX_CD_SECTORS_TO_READ))      return FALSE;   /*      Allocate buffer for MSCDEX call. This buffer must be below 1MB      because the MSCDEX function will be called using DPMI. Like real-      mode MSCDEX.EXE, CDFS implements the MSCDEX API as V86-mode      Interrupt 2Fh functions.      Free memory below 1MB is relatively scarce, so allocating a      small sector buffer increases the chances that it can be      allocated no matter how many other applications and MS-DOS      device drivers are running. Also, a small sector buffer leaves      more memory for other applications to use.   */    gdaBuffer = GlobalDosAlloc (CD_SECTOR_SIZE);   if (!gdaBuffer)      return FALSE;   RMlpBuffer = (LPBYTE)MAKELONG(0, HIWORD(gdaBuffer));   PMlpBuffer = (LPBYTE)MAKELONG(0, LOWORD(gdaBuffer));   // Call MSCDEX to read each sector.   for (i = cbOffset = 0;        i < wSectors;        i++, cbOffset += CD_SECTOR_SIZE)      {      if (fResult = MSCDEX_ReadSector (bDrive,                                       dwStartSector + i,                                       RMlpBuffer))         _fmemcpy (lpBuffer + cbOffset, PMlpBuffer, CD_SECTOR_SIZE);      else         break;      }   GlobalDosFree (LOWORD(gdaBuffer));   return (fResult);}/*-------------------------------------------------------------------  MSCDEX_ReadSector()  Calls MSCDEX to read a single sector from a CD-ROM compact disc.  Parameters:     bDrive        Drive number of CD-ROM drive to read from. Expected to be        a number in the following series: 0 = A, 1 = B, 2 = C, etc.     dwStartSector        First sector of read.     RMlpBuffer        Real-mode segment:offset pointer to a buffer that will receive        sector data. Must be large enough to accommodate a single        sector in cooked mode.  Return Value     Returns TRUE if successful, or FALSE if an error occurred in     reading.-------------------------------------------------------------------*/ BOOL FAR PASCAL MSCDEX_ReadSector (BYTE   bDrive,                                   DWORD  dwStartSector,                                   LPBYTE RMlpBuffer){   RMCS   callStruct;   BOOL   fResult;   /*      Prepare DPMI Simulate Real Mode Interrupt call structure with      the register values used to make the MSCDEX Absolute read call.      Then, call MSCDEX using DPMI and check for errors in both the DPMI      call and the MSCDEX call.   */    BuildRMCS (&callStruct);   callStruct.eax = 0x1508;                 // MSCDEX Absolute read   callStruct.ebx = LOWORD(RMlpBuffer);     // Offset of sect buffer   callStruct.es  = HIWORD(RMlpBuffer);     // Segment of sect buffer   callStruct.ecx = bDrive;                 // 0=A, 1=B, 2=C, etc.   callStruct.edx = 1;                      // Read one sector   callStruct.esi = HIWORD(dwStartSector);   callStruct.edi = LOWORD(dwStartSector);   if (fResult = SimulateRM_Int (0x2F, &callStruct))      fResult = !(callStruct.wFlags & CARRY_FLAG);   return fResult;}/*-------------------------------------------------------------------  SimulateRM_Int()  Allows protected-mode software to execute real-mode interrupts  such as calls to MS-DOS, MS-DOS TSRs, MS-DOS device drivers.  This function implements the "Simulate Real Mode Interrupt"  function of the DPMI specification v0.9 and later.  Parameters:     bIntNum        Number of the interrupt to simulate.     lpCallStruct        Call structure that contains params (register values)        for bIntNum.  Return Value     SimulateRM_Int returns TRUE if it succeeded or FALSE if     it failed.  Comments     lpCallStruct is a protected-mode selector:offset address, not     a real-mode segment:offset address.-------------------------------------------------------------------*/ BOOL FAR PASCAL SimulateRM_Int (BYTE bIntNum, LPRMCS lpCallStruct){   BOOL fRetVal = FALSE;        // Assume failure   _asm {         push di         mov  ax, 0300h         ; DPMI Simulate Real Mode Interrupt         mov  bl, bIntNum       ; Number of the interrupt to simulate         mov  bh, 01h           ; Bit 0 = 1; all other bits must be 0         xor  cx, cx            ; No words to copy from PM to RM stack         les  di, lpCallStruct  ; Real mode call structure         int  31h               ; Call DPMI         jc   END1              ; CF set if error occurred         mov  fRetVal, TRUE     END1:         pop di        }   return (fRetVal);}/*-------------------------------------------------------------------   BuildRMCS()   Initializes a real-mode call structure by zeroing all its members.   Parameters:      lpCallStruct         Points to a real-mode call structure   Return Value         None.   Comments         lpCallStruct is a protected-mode selector:offset address,         not a real-mode segment:offset address.-------------------------------------------------------------------*/ void FAR PASCAL BuildRMCS (LPRMCS lpCallStruct)   {   _fmemset (lpCallStruct, 0, sizeof(RMCS));   }				
Referencias
DOS Protected Mode Interface Specification Version 0,9.
Guía del programador de Windows 95.
Documentación en pantalla del SDK de Win32.
Windows 95 4.00 cdrom CD-ROM absoluto

Advertencia: este artículo se ha traducido automáticamente

Propiedades

Id. de artículo: 137813 - Última revisión: 02/22/2014 04:23:53 - Revisión: 3.2

  • Microsoft Win32 Application Programming Interface
  • kbnosurvey kbarchive kbmt kbapi kbcode kbkernbase KB137813 KbMtes
Comentarios