/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Microsoft Corporation, 1989                                 */
/* COPYRIGHT    Copyright (C) 1995 IBM Corporation                           */
/*                                                                           */
/*    The following IBM OS/2 WARP source code is provided to you solely for  */
/*    the purpose of assisting you in your development of OS/2 WARP device   */
/*    drivers. You may use this code in accordance with the IBM License      */
/*    Agreement provided in the IBM Device Driver Source Kit for OS/2. This  */
/*    Copyright statement may not be removed.                                */
/*                                                                           */
/*****************************************************************************/
/*static char *SCCSID = "@(#)vlptuser.c 6.10 92/03/20";*/
#pragma linesize(132)
#pragma pagesize(60)
#pragma title("VLPTUSER.C")
/****************************************************************************/
/*                                                                          */
/*                                                                          */
/*                                                                          */
/****************************************************************************/
/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  VLPTUSER.C                                            */
/*                                                                            */
/*   DESCRIPTIVE NAME:  Process VDM events that the VLPT has registered for   */
/*                      notification of when they occur                       */
/*                                                                            */
/*   FUNCTION: These routines process specific VDM events and return to       */
/*             the caller.                                                    */
/*                                                                            */
/*   NOTES:                                                                   */
/*      DEPENDENCIES: Spooler is running                                      */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:                                                            */
/*             VLPTCreate     -  VDM creation event handler                   */
/*             VLPTTerminate  -  VDM termination event handler                */
/*             VLPTPDBChange  -  VDM PDB change event handler                 */
/*             VLPTPDBDestroy -  VDM PDB destruction event handler            */
/*             VDHPrintClose  -  VKBD Ctrl-Alt-PrtSc handler                  */
/*             VLPTSetSpoolClose - PRINT_TIMEOUT DOS Setting change handler   */
/*             VLPTEventContext - Int 17h Print timeout handler               */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*             VDHAllocHook      - Allocate hook handle for VDHArmReturnHook  */
/*             VDHCloseVDD       - Close IDC with VDD                         */
/*             VDHInstallIntHook - Hook an interrupt                          */
/*             VDHInstallIOHook  - Hook the I/O port trap handler             */
/*             VDHRemoveIOHook   - Remove the hook for I/O port trap handler  */
/*             VDHCreateSem      - Create an event semaphore                  */
/*             VDHDestroySem     - Destroy an event semaphore                 */
/*             VDHOpenVDD        - Open IDC with VDD                          */
/*             VDHPostEventSem   - Post an event semaphore                    */
/*             VDHQuerySem       - Query state of event semaphore             */
/*             VDHQueryHookData  - Query Context Hook Data                    */
/*             VDHQueryProperty  - Query a DOS property                       */
/*             VDHRequestVDD     - Query a DOS property                       */
/*             VDHResetEventSem  - Reset an event semaphore                   */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

#include <mvdm.h>                       /* VDH services, etc.        */
#include "vlptp.h"                      /* VLPT data defines         */
#include "vlptdata.h"                   /* VLPT external data        */

#pragma BEGIN_SWAP_DATA
extern  SZ      szProplpt1timeout;
extern  SZ      szProplptseparate;
#pragma END_SWAP_DATA

#pragma BEGIN_SWAP_CODE

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VLPTCREATE                                       */
/*                                                                    */
/* DESCRIPTIVE NAME:  VLPT VDM Creation Event Handler                 */
/*                                                                    */
/* FUNCTION:  This routine is called from the VDM Manager when a VDM  */
/*            is created. Instance data is initialized. Interrupt 17h */
/*            hook routine is registered. IN and OUT parallel port    */
/*            hook routines are registered. Interrupt 05h hook        */
/*            routine is registered. Interrupt 05h return hook is     */
/*            allocated.                                              */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: VDM task time                                             */
/*                                                                    */
/* ENTRY POINT:  VLPTCreate                                           */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:  VDM Handle                                                 */
/*                                                                    */
/* EXIT-NORMAL:  returns !0                                           */
/*                                                                    */
/* EXIT-ERROR:   returns 0                                            */
/*                                                                    */
/* EFFECTS:  Per VDM data area is initialized.                        */
/*           VDM bios data area is created.                           */
/*                                                                    */
/* INTERNAL REFERENCES:  VLPTTerminate                                */
/*                                                                    */
/* EXTERNAL REFERENCES:  VDHAllocHook                                 */
/*                       VDHCloseVDD                                  */
/*                       VDHInstallIntHook                            */
/*                       VDHInstallIOHook                             */
/*                       VDHCreateSem                                 */
/*                       VDHOpenVDD                                   */
/*                       VDHQuerySem                                  */
/*                       VDHQueryHookData                             */
/*                       VDHQueryProperty                             */
/*                       VDHRequestVDD                                */
/*                       VDHResetEventSem                             */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
BOOL HOOKENTRY VLPTCreate(hvdm)
HVDM hvdm;
{
    INT i, j, k;                       /* counters                   */
    VDHSEMSTATE SemStateStruc;         /* set up semaphore state     */
                                       /*    structure               */
    PVOID posinbuffer;                 /* POS input buffer           */
    k = 0;                             /* initialize counter         */

#ifdef DEBUG
   vdhInt3();
#endif

    /*---------------------------------------------------------------*/
    /* If running on a PS2 then get the handle to VBIOS for making   */
    /* a request to get the address of the POS register data         */
    /* structure. After getting the VBIOS handle request the address */
    /* of the POS register data structure. Do this only once.        */
    /* All VDMs created after the first will not do this because     */
    /* the address is good for all VDMs.                             */
    /*---------------------------------------------------------------*/
    if (MachineType == MACHINE_TYPE_PS2)
    {
      if (pvddvbiospos==NULL)
      {
        if ((hvddvbios=VDHOpenVDD(VBIOS_NAME))==FALSE)
        {
          return FALSE;
        } else
        {
          if(VDHRequestVDD(hvddvbios,
                        hvdm,
                        0,
                        SSToDS(&posinbuffer),
                        &pvddvbiospos)==FALSE)
                        {
                          VDHCloseVDD(hvddvbios);
                          return FALSE;
                        }
        }
      }
    }

    /*---------------------------------------------------------------*/
    /*- Initialize non per port instance data                       -*/
    /*---------------------------------------------------------------*/
    this_VDM = hvdm;
    resp_val = 0;
    vlpt_sem_handle = (DWORD)0;
    pdbCurrent = INVALID_PDB;

    /*---------------------------------------------------------------*/
    /*- This loop initializes the per VDM bios data area parallel   -*/
    /*- port addresses and the per VDM data area.                   -*/
    /*---------------------------------------------------------------*/
    for(i=0; i<MAXPRTS; i++) {

    /*---------------------------------------------------------------*/
    /*- Copy the VLPT port address table base printer port address  -*/
    /*- into the current base printer port address location in the  -*/
    /*- current VDMs bios data area.                                -*/
    /*---------------------------------------------------------------*/
        VDMBase.rb_awLPT[i] = vpa_table[i].data;
        pvd_area[i].flags = FLAG_NOT_SET;
        pvd_area[i].data = FLAG_NOT_SET;
        pvd_area[i].status = (BYTE)POWER_ON_STATUS;
        pvd_area[i].lptportid = (UCHAR)i;
        pvd_area[i].fshandle = INVALID_HANDLE;
        pvd_area[i].bufcount = 0;
        pvd_area[i].reserve_word = 0;
        pvd_area[i].stream = NULL;
        pvd_area[i].pdb_spool = INVALID_PDB;
        pvd_area[i].pdb_direct = INVALID_PDB;

    /*---------------------------------------------------------------*/
    /*-  Allocate timer Hook for LPT spool Timeout                  -*/
    /*---------------------------------------------------------------*/

        if (!(pvd_area[i].hhookLptEventContext = VDHAllocHook(VDH_TIMER_HOOK,
                                                     (PFNARM)VLPTEventContext,
                                                     sizeof(PVLPTINST))))
            return FALSE;

    /*---------------------------------------------------------------*/
    /*- Initialize Timer Hook Data, see VLPTEventContext()          -*/
    /*---------------------------------------------------------------*/

        *(PULONG)VDHQueryHookData(pvd_area[i].hhookLptEventContext) =
                                  (ULONG)&pvd_area[i];

    } /* endfor */

    /*---------------------------------------------------------------*/
    /*- Set number of printers installed to 3 in VDM bios data area.-*/
    /*- DosDevConfig uses this area to find out how many physical   -*/
    /*- parallel ports are in the system. Therefore VLPT cannot     -*/
    /*- set it to match how many ports it is virtualizing.          -*/
    /*---------------------------------------------------------------*/
    //  VDMBase.rb_fsEquip |= BIOSEQUIP_PRINTERMASK;

    /*---------------------------------------------------------------*/
    /*- Register a semaphore for retry processing. If the call      -*/
    /*- fails return with failure.                                  -*/
    /*---------------------------------------------------------------*/
    if ((VDHCreateSem(&vlpt_sem_handle,VDH_EVENTSEM)) == 0) {

        return FALSE;                 /* return FALSE if call failed */

    } else {

    /*---------------------------------------------------------------*/
    /*- Call VDHQuerySem and check the state of the semaphore. If   -*/
    /*- it is posted/not owned then call VDHResetEventSem to own it.-*/
    /*---------------------------------------------------------------*/
        VDHQuerySem(vlpt_sem_handle,(PVDHSEMSTATE)SSToDS(&SemStateStruc));

        if (!(SemStateStruc.vss_fOwned)) {
            VDHResetEventSem(vlpt_sem_handle);
        } /* endif */

    } /* endif */

    /*---------------------------------------------------------------*/
    /*- Allocate hook handle for VDHArmReturnHook                   -*/
    /*---------------------------------------------------------------*/
    if((hhookVLPTIRet5 = VDHAllocHook(VDH_RETURN_HOOK, (PFNARM)VLPTIRet5,
      sizeof(UINT))) == NULL) {
        return FALSE;
    }

    /*---------------------------------------------------------------*/
    /*- Register a VDM interrupt hook handler for Int 17H.          -*/
    /*---------------------------------------------------------------*/
    VDHInstallIntHook(hvdm,
                      (ULONG)INT_17,
                      VLPTInt17,
                      !VDH_ASM_HOOK);


    /*---------------------------------------------------------------*/
    /*- Register a VDM interrupt hook handler for Int 05H.          -*/
    /*---------------------------------------------------------------*/
    VDHInstallIntHook(hvdm,
                      (ULONG)INT_05,
                      VLPTInt05,
                      !VDH_ASM_HOOK);

    /*---------------------------------------------------------------*/
    /*- This loop installs IO hooks for the data, status, control,  -*/
    /*- and reserve ports for each parallel printer port.           -*/
    /*---------------------------------------------------------------*/
    for(j=0; j<MAXPRTS; j++) {

    /*---------------------------------------------------------------*/
    /*- Only hook physical ports.                                   -*/
    /*---------------------------------------------------------------*/
       if (vpa_table[j].flags == PHYSICAL_PORT)
       {
    /*---------------------------------------------------------------*/
    /*- Register a VDM IO hook handler for parallel printer ports.  -*/
    /*- If the call ever fails then before returning VLPTTerminate  -*/
    /*- will be called to clean up IO and INT17 hooks.              -*/
    /*---------------------------------------------------------------*/
        if ((VDHInstallIOHook(hvdm,
                              vpa_table[j].data,
                              1,
                              &v_ioh[k].iohtable,
                              !VDH_ASM_HOOK)) == 0) {
            return FALSE;             /* return FALSE                */
        } /* endif */

        k++;                       /* increment IO handler table ptr */

        if ((VDHInstallIOHook(hvdm,
                              vpa_table[j].status,
                              1,
                              &v_ioh[k].iohtable,
                              !VDH_ASM_HOOK)) == 0) {
            return FALSE;             /* return FALSE                */
        } /* endif */

        k++;                       /* increment IO handler table ptr */

        if ((VDHInstallIOHook(hvdm,
                              vpa_table[j].control,
                              1,
                              &v_ioh[k].iohtable,
                              !VDH_ASM_HOOK)) == 0) {
            return FALSE;             /* return FALSE                */
        } /* endif */

        k++;                       /* increment IO handler table ptr */

    /*---------------------------------------------------------------*/
    /*- The 3BFh port is documented as a reserved parallel port in  -*/
    /*- the IBM Hardware Interface Technical Reference. The Hercules-*/
    /*- video adapter manufacturers broke compatibility by using    -*/
    /*- the reserved LPT1 port.  Now, other Super VGA adapter       -*/
    /*- manufacturers have also started using this port.  In the    -*/
    /*- interest of supporting SVGA, VLPT is discontinuing to hook  -*/
    /*- this IO port (VDHInstallIOHook) so that the video software  -*/
    /*- can use it.                                                 -*/
    /*---------------------------------------------------------------*/
        if (vpa_table[j].reserve != 0x03BF)
        {
          if ((VDHInstallIOHook(hvdm,
                                vpa_table[j].reserve,
                                1,
                                &v_ioh[k].iohtable,
                                !VDH_ASM_HOOK)) == 0) {
              return FALSE;             /* return FALSE                */
          } /* endif */

        }
        k++;                 /* increment IO handler table ptr */

       } else {
        k+=4;         /* if not physical increment for ports skipped */
       }

    } /* endfor */

    // Get the Current DOS Properties Setting

    nmsLptTimeout = VDHQueryProperty(szProplpt1timeout)*1000;
    if (VDHQueryProperty(szProplptseparate))
      VLPTFlags |= (FLAGS)LPTINT17SEP;
    else
      VLPTFlags &= ~(FLAGS)LPTINT17SEP;

    return TRUE;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VLPTTERMINATE                                    */
/*                                                                    */
/* DESCRIPTIVE NAME:  VLPT VDM Termination Event Handler              */
/*                                                                    */
/* FUNCTION:  This routine is called from the VDM Manager when a VDM  */
/*            is terminating. All printers are closed for the current */
/*            VDM handle using doClose. All IO hooks are removed.     */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: VDM task time                                             */
/*                                                                    */
/* ENTRY POINT:  VLPTTerminate                                        */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:  VDM Handle                                                 */
/*                                                                    */
/* EXIT-NORMAL:  !0                                                   */
/*                                                                    */
/* EXIT-ERROR:   0                                                    */
/*                                                                    */
/* EFFECTS:   Init-time flag in per VDM data area.                    */
/*                                                                    */
/* INTERNAL REFERENCES:  doCloseSpool                                 */
/*                       doCloseDirect                                */
/*                                                                    */
/* EXTERNAL REFERENCES:  VDHRemoveIOHook                              */
/*                       VDHDestroySem                                */
/*                       VDHPostEventSem                              */
/*                       VDHQuerySem                                  */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
BOOL HOOKENTRY VLPTTerminate(hvdm)
HVDM hvdm;
{
    INT i;                             /* counters                   */
    VDHSEMSTATE SemStateStruc;         /* set up semaphore state     */
                                       /*    structure               */

#ifdef DEBUG
   vdhInt3();
#endif

    /*---------------------------------------------------------------*/
    /*- This loop calls doCloseSpool and doCloseDirect to close all -*/
    /*- printers. It also clears the INIT flag in the per VDM data  -*/
    /*- area flags for each printer. It also removes all IO hooks   -*/
    /*- for the parallel printer ports.                             -*/
    /*---------------------------------------------------------------*/
    for(i=0; i<MAXPRTS; i++) {
        pvd_area[i].flags &= (~INIT_FLAG);
        doCloseSpool(&pvd_area[i]);
        doCloseDirect(&pvd_area[i]);

    /*---------------------------------------------------------------*/
    /*- If a Print-Screen is in progress the hold area of the per   -*/
    /*- VDM data area contains an open device and a data stream     -*/
    /*- that need to be cleaned up.                                 -*/
    /*---------------------------------------------------------------*/
        if (pvd_area[i].flags & PRT_SC_IN_PROG) {
            pvd_area[PORT_HOLD].flags &= (~INIT_FLAG);
            doCloseSpool(&pvd_area[PORT_HOLD]);
        } /* endif */

    } /* endfor */

    /*---------------------------------------------------------------*/
    /*- If the VDHCreateSem has returned a valid semaphore then     -*/
    /*- call VDHQuerySem and check the state of the semaphore to    -*/
    /*- make sure the semaphore is posted/not owned before          -*/
    /*- destroying it. If the semaphore is not posted/not owned     -*/
    /*- then call VDHPostEventSem to set it as posted/not owned.    -*/
    /*---------------------------------------------------------------*/
    if (vlpt_sem_handle) {

        VDHQuerySem(vlpt_sem_handle,(PVDHSEMSTATE)SSToDS(&SemStateStruc));

        if (SemStateStruc.vss_fOwned) {

            VDHPostEventSem(vlpt_sem_handle);

        } /* endif */

        VDHDestroySem(vlpt_sem_handle);

    } /* endif */

    return TRUE;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VLPTPDBCHANGE                                    */
/*                                                                    */
/* DESCRIPTIVE NAME:  VLPT VDM PDB Change Event Handler               */
/*                                                                    */
/* FUNCTION:  This routine is called from the VDM Manager when a VDM  */
/*            PDB change occurs.                                      */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: VDM task time                                             */
/*                                                                    */
/* ENTRY POINT:  VLPTPDBChange                                        */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:  hvdm   - VDM handle                                        */
/*         vPDB   - v86 segment of PDB                                */
/*                                                                    */
/* EXIT-NORMAL:  !0                                                   */
/*                                                                    */
/* EXIT-ERROR:   0                                                    */
/*                                                                    */
/* EFFECTS:                                                           */
/*                                                                    */
/* INTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
BOOL HOOKENTRY VLPTPDBChange(hvdm,vPDB)
HVDM hvdm;
VLPTPDB vPDB;
{

#ifdef DEBUG
   vdhInt3();
#endif

    /*---------------------------------------------------------------*/
    /*- Save current PDB                                            -*/
    /*---------------------------------------------------------------*/
    pdbCurrent = vPDB;

    return TRUE;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VLPTPDBDESTROY                                   */
/*                                                                    */
/* DESCRIPTIVE NAME:  VLPT VDM PDB Destruction Event Handler          */
/*                                                                    */
/* FUNCTION:  This routine is called from the VDM Manager when a VDM  */
/*            PDB is destroyed. Upon entry this routine will look     */
/*            for data streams that have a PDB that matches the one   */
/*            that was destroyed. Each data stream that has a PDB     */
/*            that matches will be closed.                            */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: VDM task time                                             */
/*                                                                    */
/* ENTRY POINT:  VLPTPDBDestroy                                       */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:  hvdm   - VDM handle                                        */
/*         vPDB   - v86 segment of PDB                                */
/*                                                                    */
/* EXIT-NORMAL:  !0                                                   */
/*                                                                    */
/* EXIT-ERROR:   0                                                    */
/*                                                                    */
/* EFFECTS:                                                           */
/*                                                                    */
/* INTERNAL REFERENCES:  doCloseSpool                                 */
/*                       doCloseDirect                                */
/*                                                                    */
/* EXTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
BOOL HOOKENTRY VLPTPDBDestroy(hvdm,vPDB)
HVDM hvdm;
VLPTPDB vPDB;
{
    INT i;                             /* counter                    */

#ifdef DEBUG
   vdhInt3();
#endif
    /*---------------------------------------------------------------*/
    /*- If separate print setting is ON then split on PDB destroy   -*/
    /*---------------------------------------------------------------*/
    if (VLPTFlags & LPTINT17SEP)
      {

      /*---------------------------------------------------------------*/
      /*- Make sure passed in PDB is valid                            -*/
      /*---------------------------------------------------------------*/
      if (vPDB != INVALID_PDB) {

      /*---------------------------------------------------------------*/
      /*- Look at each PDB in the per VDM data for ones that match    -*/
      /*- the PDB being destroyed. Call doClose for each device that  -*/
      /*- has a PDB match. If a Print-Screen is in progress for the   -*/
      /*- device in question then the device in the per VDM data area -*/
      /*- hold area should be closed if it's PDB is the same as the   -*/
      /*- current one. This will allow the Print-Screen to complete   -*/
      /*- normally.                                                   -*/
      /*---------------------------------------------------------------*/
          for(i=0; i<MAXPRTS; i++) {

              if (pvd_area[i].flags & PRT_SC_IN_PROG) {

                  if (vPDB == pvd_area[PORT_HOLD].pdb_spool) {
                      pvd_area[PORT_HOLD].flags &= (~INIT_FLAG);
                      doCloseSpool(&pvd_area[PORT_HOLD]);
                  } /* endif */

              } else {

                  if (vPDB == pvd_area[i].pdb_spool) {
                      pvd_area[i].flags &= (~INIT_FLAG);
                      doCloseSpool(&pvd_area[i]);
                  } /* endif */

              } /* endif */

              if (vPDB == pvd_area[i].pdb_direct) {
                  doCloseDirect(&pvd_area[i]);
              } /* endif */

          } /* endfor */

      } /* endif */
    } /* endif */
    return TRUE;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VDHPRINTCLOSE                                    */
/*                                                                    */
/* DESCRIPTIVE NAME:  Flush and close all open printers for a VDM     */
/*                                                                    */
/* FUNCTION:  This VDH service is called by other VDDs who wish to    */
/*            flush and close a VDM's open printers for any reason.   */
/*            A VDM may have more than one printer open. This service */
/*            will flush and close all of them.                       */
/*                                                                    */
/* NOTES:  This is an exported service.                               */
/*                                                                    */
/* CONTEXT: VDM task time                                             */
/*                                                                    */
/* ENTRY POINT:  VDHPrintClose                                        */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:  hvdm   VDM handle                                          */
/*                                                                    */
/* EXIT-NORMAL: NONE                                                  */
/*                                                                    */
/* EXIT-ERROR: NONE                                                   */
/*                                                                    */
/* EFFECTS:  Init flag in per VDM data area.                          */
/*                                                                    */
/* INTERNAL REFERENCES:  doCloseSpool                                 */
/*                       doCloseDirect                                */
/*                                                                    */
/* EXTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
VOID VDHENTRY VDHPrintClose(hvdm)
HVDM hvdm;
{
    INT i;                             /* counter                    */

#ifdef DEBUG
   vdhInt3();
#endif
    /*---------------------------------------------------------------*/
    /*- This loop calls doClose to close all printers. It also      -*/
    /*- clears the INIT flag in the per VDM data area flags for each-*/
    /*- printer.                                                    -*/
    /*---------------------------------------------------------------*/
    for(i=0; i<MAXPRTS; i++) {

    /*---------------------------------------------------------------*/
    /*- If a Print-Screen is in progress for the device in question -*/
    /*- then the device in the per VDM data area hold area should be-*/
    /*- closed. This will allow the Print-Screen to complete        -*/
    /*- normally.                                                   -*/
    /*---------------------------------------------------------------*/
        if (pvd_area[i].flags & PRT_SC_IN_PROG) {

            pvd_area[PORT_HOLD].flags &= (~INIT_FLAG);
            doCloseSpool(&pvd_area[PORT_HOLD]);

        } else {

            pvd_area[i].flags &= (~INIT_FLAG);
            doCloseSpool(&pvd_area[i]);

        } /* endif */

        doCloseDirect(&pvd_area[i]);

    } /* endfor */
    return;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VLPTSetSpoolClose                                */
/*                                                                    */
/* DESCRIPTIVE NAME:  Set/validate the DOS Setting PRINT_TIMEOUT.     */
/*                                                                    */
/* FUNCTION:  This routine is called when the state of                */
/*            PRINT_TIMEOUT DOS Setting changes.                      */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: VDM task context                                          */
/*                                                                    */
/* ENTRY POINT:  VLPTSetSpoolClose                                    */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:  op     operation to perform                                */
/*         hvdm   VDM handle                                          */
/*         cb     length of value                                     */
/*         psz    ptr to value                                        */
/*                                                                    */
/* EXIT-NORMAL: Returns zero, no error                                */
/*                                                                    */
/* EXIT-ERROR: NONE                                                   */
/*                                                                    */
/* EFFECTS:  nmsLptTimeout                                            */
/*                                                                    */
/* INTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
ULONG EXPENTRY VLPTSetSpoolClose(ULONG op, HVDM hvdm, ULONG cb, PSZ psz)
{
    REFHVDM(hvdm, ULONG, nmsLptTimeout ) = (ULONG)psz*1000;
    return 0;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VLPTEventContext                                 */
/*                                                                    */
/* DESCRIPTIVE NAME:  Close any int 17h generated spool files.        */
/*                                                                    */
/* FUNCTION:  This routine is called at task time when the            */
/*            VLPTEventTimer() has expired.  The event timer expires  */
/*            when an application stops issuing int 17h requests.     */
/*            This routine flushes any remaining characters that VLPT */
/*            has buffered to the spooler.                            */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: VDM task context                                          */
/*                                                                    */
/* ENTRY POINT:  VLPTEventContext                                     */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:  p      reference data (not used)                           */
/*         pcrf   pointer to client register frame (not used)         */
/*                                                                    */
/* EXIT-NORMAL: NONE                                                  */
/*                                                                    */
/* EXIT-ERROR: NONE                                                   */
/*                                                                    */
/* EFFECTS:  VLPTFlags                                                */
/*                                                                    */
/* INTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
VOID HOOKENTRY VLPTEventContext(PVOID p, PCRF pcrf)
{
    VLPTFlags |= (FLAGS)TIMEOUT_IN_PROG;
    doCloseSpool(*(PPVLPTINST)p);
    VLPTFlags &= ~(FLAGS)TIMEOUT_IN_PROG;

}

#pragma END_SWAP_CODE

