home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / cdrom.zip / DDK / BASE / SRC / VDEV / VCDROM / vcdrom.c < prev    next >
C/C++ Source or Header  |  1996-06-18  |  19KB  |  568 lines

  1. /***************************************************************************
  2.  *
  3.  * SOURCE FILE NAME = VCDROM.C
  4.  *
  5.  * DESCRIPTIVE NAME = VCDROM Initializations
  6.  *
  7.  * DESCRIPTION This module contains all the VCDROM's initialization
  8.  *             procedures, event handler procedures, and global
  9.  *             as well as VDM instance data declarations.
  10.  *
  11.  * Copyright : COPYRIGHT IBM CORPORATION, 1991, 1992
  12.  *             Copyright Microsoft Corporation, 1990
  13.  *             LICENSED MATERIAL - PROGRAM PROPERTY OF IBM
  14.  *             REFER TO COPYRIGHT INSTRUCTION FORM#G120-2083
  15.  *             RESTRICTED MATERIALS OF IBM
  16.  *             IBM CONFIDENTIAL
  17.  *
  18.  * ENTRY POINTS:
  19.  *             VDDInit
  20.  *             VCDROMCreateVDM
  21.  *               InstallStub
  22.  *             VCDROMTerminateVDM
  23.  *             VCDROMPDBDestroy
  24.  *               CloseHandles
  25.  *
  26.  * EXTERNAL REFERENCES:
  27.  *
  28.  * CHANGE ACTIVITY =
  29.  *  DATE      FLAG        APAR   CHANGE DESCRIPTION
  30.  *  --------  ----------  -----  --------------------------------------
  31.  *  mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
  32.  *  08/16/91  @V2.0DTF           Created.
  33.  *
  34.  *  09/25/92  @V2.0FJS00         Changed installstub to installinthook on int
  35.  *                               0x2f instead of int 0x66.  Also patch dos stub
  36.  *                               device driver with VCDROMDosLink address for
  37.  *                               ARPL. Define and initialize current HVDM
  38.  *                               instance storage.
  39.  *
  40.  *  10/21/92  @V2.0FJS01         Changed VCDROMCreateVDM to obtain VPIC slave
  41.  *                               routine address and to query the INT_DURING_IO
  42.  *                               DOS property.  MSCDEX absolute sector read
  43.  *                               (used by Sherlock Holmes) blocks in the device
  44.  *                               driver preventing simulated hardware interrupts
  45.  *                               (like sound) in a DOS session.
  46.  *
  47.  *  12/05/92  @V2.0FJS02         Changed installstub to copy the number of
  48.  *                               units to the stub DOS device driver header.
  49.  *                               Some DOS applications look for the number of
  50.  *                               units there.
  51.  *
  52.  *  03/24/93  @V2.0FJS03         Added VCDROMPDBDestroy routine to close drive
  53.  *                               handles when the application terminates. This
  54.  *                               usually indicates the CD-ROM disc is being
  55.  *                               changed.
  56.  *
  57.  ****************************************************************************/
  58.  
  59.  
  60. #include <mvdm.h>
  61. #include <propname.h>
  62. #include "vcdromp.h"
  63. #include "reqhdr.h"
  64. #include "ctrlblk.h"
  65. #include "cdstub.h"
  66.  
  67.  
  68.  
  69. #ifdef  VDDSTRICT
  70. MODNAME = __FILE__;
  71. #endif
  72.  
  73. /*
  74. **  VCDROM Global Data
  75. */
  76.  
  77. #pragma BEGIN_GLOBAL_DATA
  78.  
  79. #ifdef  VDDSTRICT
  80. CHAR    szAssertMsg[] = "VCDROM assertion failure in %s, line %d\n";
  81. #endif
  82.  
  83. #ifdef  VDDDEBUG
  84. CHAR    szModule[] = "VCDROM: ";
  85. #endif
  86.  
  87. BOOL    flSLAVE;
  88. SZ      szRealTime = PROP_NAME_INT_DURING_IO;
  89. SZ      szVPICName = "VPIC";
  90. HVDD    hvddVPIC=NULL;
  91. PFN     pfnSlaveRequest=NULL;
  92.  
  93. #pragma END_GLOBAL_DATA
  94.  
  95. #pragma BEGIN_SWAP_DATA
  96.  
  97. #pragma END_SWAP_DATA
  98.  
  99. /*
  100. **  VCDROM Instance Data
  101. */
  102.  
  103. #pragma BEGIN_SWAP_INSTANCE
  104.  
  105. HVDM hvdmCurrent=0;                /* instance copy of HVDM                  */
  106.  
  107. ULONG  slaveparms [10];            /* VDHFSCtl parms to pass to slave thread */
  108.  
  109. struct                             /* OS/2 generic ioctl code and category   */
  110. CategoryCode
  111. IoctlOutputCodes [] = {
  112.                         0x44, 0x80,         /* eject disk                    */
  113.                         0x46, 0x80,         /* lock/unlock                   */
  114.                         0x40, 0x80,         /* reset                         */
  115.                         0x40, 0x81,         /* audio channel control         */
  116.                         0x4F, 0x80,         /* write drive bytes             */
  117.                         0x45, 0x80          /* close tray                    */
  118. };
  119.  
  120. struct                             /* OS/2 generic ioctl code and category   */
  121. CategoryCode
  122. IoctlInputCodes [] = {
  123.                         0xFF, 0x80,         /* undefined                     */
  124.                         0x70, 0x80,         /* location of head              */
  125.                         0xFF, 0x80,         /* undefined                     */
  126.                         0xFF, 0x80,         /* undefined                     */
  127.                         0x60, 0x81,         /* audio channel info            */
  128.                         0x6F, 0x80,         /* read drive bytes              */
  129.                         0x60, 0x80,         /* device status                 */
  130.                         0x63, 0x80,         /* return sector size            */
  131.                         0x78, 0x80,         /* return volume size            */
  132.                         0x00, 0x80,         /* ** MEDIA CHANGED exception ** */
  133.                         0x61, 0x81,         /* audio disk info               */
  134.                         0x62, 0x81,         /* audio track info              */
  135.                         0x63, 0x81,         /* q channel info                */
  136.                         0x64, 0x81,         /* sub channel info              */
  137.                         0x79, 0x80,         /* UPC code                      */
  138.                         0x65, 0x81          /* audio status info             */
  139. };
  140.  
  141. USHORT  NumberOfDrives = 0;
  142. USHORT  FirstDriveNumber = 0;
  143.  
  144. VPDOSDDTYPE DosDDHeader;                    /* V86FAR address of dos driver  */
  145.  
  146. HFILE
  147. DriveHandle [MAX_NUMBER_OF_DRIVES];         /* DASD open drive handles       */
  148.  
  149. UCHAR
  150. CdromCharDriverName[] = CDROM_CHAR_DRIVER_NAME;
  151.  
  152. UCHAR
  153. DriveString [] = "A:\0B:\0C:\0D:\0E:\0F:\0G:\0H:\0I:\0J:\0K:\0L:\0M:\0"
  154.                  "N:\0O:\0P:\0Q:\0R:\0S:\0T:\0U:\0V:\0W:\0X:\0Y:\0Z:\0";
  155.  
  156. ULONG       DataArea[4];                    /* for the VDHDevIOCtl call      */
  157. ULONG       ParmList[20];                   /* for VDHDevIOCtl/VDHFSCtl calls*/
  158.  
  159. ULONG       DataLengthInOut;                /* these are just dummies for    */
  160. ULONG       ParmLengthInOut;                /*  the VDHDevIOCtl call         */
  161.  
  162. ULONG       ActionTaken;                    /* for VDHOpen                   */
  163. HFILE       FileHandle;                     /* for VDHOpen                   */
  164.  
  165. #pragma END_SWAP_INSTANCE
  166.  
  167. /*
  168. **  VCDROM Initialization Data
  169. */
  170.  
  171. #pragma BEGIN_INIT_DATA
  172.  
  173. #pragma END_INIT_DATA
  174.  
  175.  
  176. #pragma BEGIN_GLOBAL_CODE
  177.  
  178. #pragma END_GLOBAL_CODE
  179.  
  180. /*
  181. **  VCDROM Initialization Code
  182. */
  183.  
  184. #pragma BEGIN_INIT_CODE
  185.  
  186.  
  187. /****************************************************************************
  188.  *
  189.  * FUNCTION NAME = VDDInit
  190.  *
  191.  * DESCRIPTION   = Virtual CDROM Initialization Entry Point
  192.  *
  193.  *                 VCDROM initialization routine
  194.  *                 See VDD Manager for complete semantics.
  195.  *
  196.  *                 This dynamically exported subroutine is called during
  197.  *                 system initialization.
  198.  *
  199.  *                 CONTEXT:
  200.  *                 Init-time
  201.  *
  202.  *                 PSEUDOCODE:
  203.  *                 define user event hook (VCDROMCreateVDM)
  204.  *                 define user event hook (VCDROMTerminateVDM)
  205.  *                 define user event hook (VCDROMPDBDestroy)
  206.  *
  207.  * INPUT         = psz - pointer to configuration strings (not used)                                                                 NONE
  208.  *
  209.  * OUTPUT        =
  210.  *
  211.  * RETURN-NORMAL = return TRUE
  212.  *
  213.  * RETURN-ERROR  = return FALSE
  214.  *
  215.  ****************************************************************************/
  216.  
  217. BOOL EXPENTRY VDDInit ( PSZ  psz )
  218. {
  219.     /*---------------------------------------------------------------*/
  220.     /*- Register a VDM Creation handler entry point.                -*/
  221.     /*---------------------------------------------------------------*/
  222.     if ((VDHInstallUserHook((ULONG)VDM_CREATE,
  223.                             (PUSERHOOK)VCDROMCreateVDM)) == 0)
  224.         return FALSE;                     /* return FALSE if VDH call failed */
  225.  
  226.     /*---------------------------------------------------------------*/
  227.     /*- Register a VDM Termination handler entry point.             -*/
  228.     /*---------------------------------------------------------------*/
  229.     if ((VDHInstallUserHook((ULONG)VDM_TERMINATE,
  230.                             (PUSERHOOK)VCDROMTerminateVDM)) == 0)
  231.         return FALSE;                     /* return FALSE if VDH call failed */
  232.  
  233.     /*---------------------------------------------------------------*/
  234.     /*- Register a VDM PDB destruction handler entry point.         -*/
  235.     /*---------------------------------------------------------------*/
  236.     if ((VDHInstallUserHook((ULONG)VDM_PDB_DESTROY,
  237.                             (PUSERHOOK)VCDROMPDBDestroy)) == 0)
  238.         return FALSE;                     /* return FALSE if VDH call failed */
  239.  
  240.     return TRUE;                            /* successful installation       */
  241.  
  242. }
  243.  
  244.  
  245. #pragma END_INIT_CODE
  246.  
  247. #pragma BEGIN_SWAP_CODE
  248.  
  249.  
  250. /****************************************************************************
  251.  *
  252.  * FUNCTION NAME = VCDROMCreateVDM
  253.  *
  254.  * DESCRIPTION   = VDM creation notification
  255.  *                 See VDHInstallUserHook for complete semantics.
  256.  *
  257.  *                 This registered subroutine is called each time a new VDM
  258.  *                 is created.  Note that not a lot of initialization should be
  259.  *                 needed (ie, static initialization for most of the instance
  260.  *                 data suffices).
  261.  *
  262.  *                 CONTEXT:
  263.  *                 VDM Task-time
  264.  *
  265.  *                 PSEUDOCODE:
  266.  *                 Get the drive letter information from the physical driver.
  267.  *                 Install the DOS stub driver.
  268.  *                 request VPIC slave thread routine for MSCDEX absolute disc
  269.  *                 reads.  Set flSLAVE flag if INT_DURING_IO property set.
  270.  *
  271.  * INPUT         = hvdm - handle of VDM
  272.  *
  273.  * OUTPUT        =
  274.  *
  275.  * RETURN-NORMAL = return TRUE
  276.  *
  277.  * RETURN-ERROR  = return FALSE
  278.  *
  279.  ****************************************************************************/
  280.  
  281. BOOL HOOKENTRY VCDROMCreateVDM (HVDM hvdm)
  282. {
  283.     register
  284.     ULONG   rc;
  285.  
  286.     hvdmCurrent = hvdm;
  287.  
  288. /*  INT_3;  */
  289.  
  290.     rc = VDHOpen ( CdromCharDriverName,
  291.                    &FileHandle,
  292.                    &ActionTaken,
  293.                    FILESIZE,
  294.                    FILEATTRIBUTE,
  295.                    OPENFLAG,
  296.                    CHAROPENMODE,
  297.                    EABUF );
  298.  
  299.  
  300.     if ( rc == VDH_FAILURE )
  301.     {
  302.         rc = VDHGetError ();               /* For debugging and to clear it. */
  303.         return TRUE;                       /* Do not fail install because    */
  304.     }                                      /*  the VDM will crash, but do    */
  305.                                            /*  not register anything.        */
  306.  
  307.     ParmLengthInOut = PARM_LENGTH_MAX;     /* these are just dummies for     */
  308.     DataLengthInOut = DATA_LENGTH_MAX;     /*  the VDHDevIOCtl call          */
  309.  
  310.     rc = VDHDevIOCtl ( FileHandle,
  311.                        0x0082,
  312.                        0x0060,             /* return drive letter information*/
  313.                        ParmList,
  314.                        PARM_LENGTH_MAX,
  315.                        &ParmLengthInOut,
  316.                        DataArea,
  317.                        DATA_LENGTH_MAX,
  318.                        &DataLengthInOut );
  319.  
  320.     if ( rc == VDH_FAILURE )
  321.     {
  322.         rc = VDHGetError ();
  323.     }
  324.     else
  325.     {
  326.         rc = FALSE;
  327.     }
  328.     if ( rc )
  329.     {
  330.         VDHClose ( FileHandle );
  331.         return FALSE;                      /* do not install                 */
  332.     }
  333.  
  334.     VDHClose ( FileHandle );
  335.  
  336.     NumberOfDrives = (USHORT) *DataArea;
  337.     FirstDriveNumber = * ( (PUSHORT) DataArea + 1 );
  338.  
  339.     if ( ! InstallStub () )
  340.         return FALSE;
  341.  
  342.     /*
  343.     ** if INT_DURING_IO DOS property set, and have VPIC slave routine
  344.     ** then set the flSLAVE flag for dual thread operations.
  345.     */
  346.     if(VDHQueryProperty(szRealTime))
  347.     {
  348.        if(hvddVPIC==NULL)
  349.           hvddVPIC = VDHOpenVDD(szVPICName);
  350.        if((hvddVPIC!=NULL)&&(pfnSlaveRequest==NULL))
  351.            VDHRequestVDD(hvddVPIC,
  352.                          0,
  353.                          VPIC_SLAVE_ADDRESS,
  354.                          NULL,
  355.                          (PVOID)&pfnSlaveRequest);
  356.        if(pfnSlaveRequest!=NULL)
  357.           flSLAVE = TRUE;
  358.     }
  359.  
  360.     return TRUE;
  361.  
  362. }
  363.  
  364.  
  365. /****************************************************************************
  366.  *
  367.  * FUNCTION NAME = InstallStub
  368.  *
  369.  * DESCRIPTION   = install our DOS Device Driver
  370.  *
  371.  *                 The DOS Device Driver stub serves three purposes:
  372.  *
  373.  *                   To let DOS applications know that CDROM and MSCDEX are
  374.  *                   installed. Most apps call int 2f to determine this, some
  375.  *                   will search for the device driver name.
  376.  *
  377.  *                   To trap int 2fh (ah=15h) calls and relay them to this
  378.  *                   driver.
  379.  *
  380.  *                   To route cdrom device driver requests to this code.
  381.  *
  382.  *                 GLOBAL EFFECTS:
  383.  *                 Memory is allocated from DOS to hold our device driver
  384.  *
  385.  *                 PSEUDOCODE:
  386.  *                 Get some VDM memory for our device driver.
  387.  *                 Copy the driver into VDM space.
  388.  *                 Copy the number of units into the device driver header.
  389.  *                 Install the driver as a DOS device driver.
  390.  *                 Save the DOS drivers address.
  391.  *                 If the installation failed, erase the driver name
  392.  *                     (so that applications that try to identify the
  393.  *                     existence of the CDROM driver by hunting through
  394.  *                     the device driver list will not find a
  395.  *                     half-installed CDROM driver).
  396.  *
  397.  * INPUT         = NONE
  398.  *
  399.  * OUTPUT        =
  400.  *
  401.  * RETURN-NORMAL = returns TRUE
  402.  *
  403.  * RETURN-ERROR  = returns FALSE
  404.  *
  405.  ****************************************************************************/
  406.  
  407. BOOL PRIVENTRY InstallStub (VOID)
  408. {
  409.     register
  410.     PBYTE  dosDDstart;                /* where the Dos Device Driver will go  */
  411.     VPVOID vpBP;                      /* breakpoint address for ARPL          */
  412.     HHOOK  hBPHook;                   /* hook handle                          */
  413.  
  414.     if ( ! ( dosDDstart = VDHAllocDosMem (CDROMStubLength) ) )
  415.         return FALSE;
  416.  
  417.     memcpy ( dosDDstart, CDROMStubStart, CDROMStubLength );
  418.  
  419.     *(dosDDstart + CDROMNumUnits) = (UCHAR) NumberOfDrives; /* patch dd header*/
  420.  
  421.                                                  /* set arpl to VCDROMDosLink */
  422.     hBPHook = VDHAllocHook (VDH_BP_HOOK,(PFNARM) VCDROMDosLink, 0);
  423.     if (hBPHook == NULL)
  424.       return FALSE;
  425.  
  426.     vpBP = VDHArmBPHook (hBPHook);                       /* get arpl address  */
  427.  
  428.     *(PDWORD)(dosDDstart + CDROMPatch0) = (DWORD) vpBP; /* patch device driver*/
  429.  
  430.     DosDDHeader = (VPDOSDDTYPE) VPFROMP(dosDDstart);
  431.  
  432.     if ( ! VDHSetDosDevice ( (VPDOSDDTYPE) VPFROMP(dosDDstart) ))
  433.     {
  434.         *(PDWORD) (dosDDstart + CDROMDevName) = 0;    /* kill the device name */
  435.         return FALSE;
  436.     }
  437.  
  438.     return TRUE;
  439. }
  440.  
  441.  
  442. /****************************************************************************
  443.  *
  444.  * FUNCTION NAME = VCDROMTerminateVDM
  445.  *
  446.  * DESCRIPTION   = VDM Destruction
  447.  *
  448.  *                 VDM destruction notification
  449.  *                 See VDHInstallUserHook for complete semantics.
  450.  *
  451.  *                 This registered subroutine is called each time a VDM
  452.  *                 is destroyed.  This handler deallocates the per VDM
  453.  *                 resources used by the VDM being destroyed.
  454.  *
  455.  *                 CONTEXT:
  456.  *                 VDM Task-time
  457.  *
  458.  *                 PSEUDOCODE:
  459.  *                 Close any open drive handles
  460.  *
  461.  * INPUT         = hvdm - handle of VDM
  462.  *
  463.  * OUTPUT        = return TRUE
  464.  *
  465.  * RETURN-NORMAL =
  466.  * RETURN-ERROR  =
  467.  *
  468.  ****************************************************************************/
  469.  
  470. BOOL HOOKENTRY VCDROMTerminateVDM (HVDM hvdm)
  471. {
  472.     CloseHandles();
  473.     return TRUE;
  474. }
  475.  
  476.  
  477. /****************************************************************************
  478.  *
  479.  * FUNCTION NAME = VCDROMPDBDestroy
  480.  *
  481.  * DESCRIPTION   = VDM PDB destruction notification
  482.  *                 See VDHInstallUserHook for complete semantics.
  483.  *
  484.  *                 This registered subroutine is called each time a VDM PDB
  485.  *                 is destroyed.  This handler causes the per VDM drive handles
  486.  *                 to be closed.
  487.  *
  488.  *                 When an application terminates, the PDB is destroyed.  This
  489.  *                 also means (probably) that the CD-ROM disc is being changed.
  490.  *                 The open drive handles need to be closed.  When a new drive
  491.  *                 request occurs, vcdrom will open the drive and mount the new
  492.  *                 disc (or remount the old disc if no disc change occurred).
  493.  *
  494.  *                 CONTEXT:
  495.  *                 VDM Task-time
  496.  *
  497.  *                 PSEUDOCODE:
  498.  *                 Close any open drive handles
  499.  *
  500.  * INPUT         = hvdm - handle of VDM
  501.  *                 vpdb - V86 segment of terminating DOS Program Data Block
  502.  *
  503.  * OUTPUT        = TRUE
  504.  *
  505.  * RETURN-NORMAL =
  506.  * RETURN-ERROR  =
  507.  *
  508.  ****************************************************************************/
  509.  
  510. BOOL HOOKENTRY VCDROMPDBDestroy(HVDM hvdm, USHORT vPDB)
  511. {
  512.     CloseHandles();
  513.     return TRUE;
  514. }
  515.  
  516.  
  517. /****************************************************************************
  518.  *
  519.  * FUNCTION NAME = CloseHandles
  520.  *
  521.  * DESCRIPTION   = Close any open per-VDM drive handles
  522.  *
  523.  *                 This routine is called to close any open per-VDM drive
  524.  *                 handles. This routine searches through the DriveHandle array
  525.  *                 for any non NULL drive handles.  If one is found, VDHClose
  526.  *                 is called to close the handle and NULL is stored in the
  527.  *                 DriveHandle array.
  528.  *
  529.  *                 CONTEXT:
  530.  *                 VDM Task-time
  531.  *
  532.  *                 PSEUDOCODE:
  533.  *                 Close any open drive handles
  534.  *
  535.  * INPUT         = None
  536.  *
  537.  * OUTPUT        = None
  538.  *
  539.  * RETURN-NORMAL =
  540.  * RETURN-ERROR  =
  541.  *
  542.  ****************************************************************************/
  543.  
  544. VOID PRIVENTRY CloseHandles (VOID)
  545. {
  546.     register
  547.     ULONG   n;
  548.     register
  549.     ULONG   last_drive;
  550.     register
  551.     HFILE   handle;
  552.  
  553.     last_drive = FirstDriveNumber + NumberOfDrives;
  554.  
  555.     for ( n = FirstDriveNumber; n < last_drive; ++n ) {
  556.         handle = DriveHandle [n];
  557.         if ( handle != NULL ) {
  558.             VDHClose ( handle );
  559.             DriveHandle [n] = NULL;
  560.         }
  561.     }
  562.  
  563.     return;
  564. }
  565.  
  566.  
  567. #pragma END_SWAP_CODE
  568.