/*static char *SCCSID = "@(#)vlptinit.c 6.5 91/08/23";*/
#pragma linesize(132)
#pragma pagesize(60)
#pragma title("VLPTINIT.C")
/****************************************************************************/
/*                                                                          */
/*                       IBM/Microsoft Confidential                         */
/*                                                                          */
/*                 Copyright (c) IBM Corporation  1987, 1990                */
/*                 Copyright (c) Microsoft Corp.  1987, 1990                */
/*                           All Rights Reserved                            */
/*                                                                          */
/****************************************************************************/
/************************** START OF SPECIFICATIONS ***************************/
/*                                                                            */
/*   SOURCE FILE NAME:  VLPTINIT.C                                            */
/*                                                                            */
/*   DESCRIPTIVE NAME:  Initialize virtual LPT device driver(VLPT)            */
/*                                                                            */
/*   STATUS:  Cruiser                                                         */
/*                                                                            */
/*   FUNCTION: This routine registers the VDM Creation and Termination entry  */
/*             points for VLPT. It also initializes the VLPT port address     */
/*             table.                                                         */
/*                                                                            */
/*   NOTES: This routine is used by Sys Init.                                 */
/*      DEPENDENCIES: Spooler is running                                      */
/*      RESTRICTIONS: None                                                    */
/*                                                                            */
/*   ENTRY POINTS:                                                            */
/*             VLPTInit - Initialize virtual LPT device driver                */
/*             VLPTPDDProc - VLPT entry point for PLPT                        */
/*                                                                            */
/*   EXTERNAL REFERENCES:                                                     */
/*             VDHInstallUserHook - Install VDM event hook                    */
/*             VDHAllocPages      - Allocate memory object                    */
/*             VDHFreePages       - Free the memory object                    */
/*             VDHQuerySysValue   - Get system values                         */
/*             VDHOpenPDD         - Get PDD entry point                       */
/*             VDHQuerySel        - Convert 0:32 to 16:16                     */
/*                                                                            */
/**************************** END OF SPECIFICATIONS ***************************/

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

#pragma BEGIN_INIT_DATA

struct def_bios_data_area def_bd_area[MAXPRTS]={    /* Default bios data   */
                           (USHORT)DEFLPT1,0,       /* area allocation and */
                           (USHORT)DEFLPT2,0,       /* initialization      */
                           (USHORT)DEFLPT3,0};      /*                     */

#pragma END_INIT_DATA

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

#pragma BEGIN_INIT_CODE

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VDDInit                                          */
/*                                                                    */
/* DESCRIPTIVE NAME:  Virtual LPT Initialization entry point          */
/*                                                                    */
/* FUNCTION:  The function of this routine is to register the VDM     */
/*            Creation, Termination, PDB Change, and PDB Destroy      */
/*            handlers. This routine also sets up the VLPT Port       */
/*            Address table in the global data area.                  */
/*                                                                    */
/* NOTES:                                                             */
/*                                                                    */
/* CONTEXT: System Initialization                                     */
/*                                                                    */
/* ENTRY POINT:  VDDInit                                              */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT: psz - pointer to configuration strings                      */
/*                                                                    */
/* EXIT-NORMAL: returns !0                                            */
/*                                                                    */
/* EXIT-ERROR: returns 0                                              */
/*                                                                    */
/* EFFECTS: VLPT Port Address table in the global data area.          */
/*                                                                    */
/* INTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  VDHInstallUserHook - Install VDM event hook  */
/*                       VDHAllocPages      - Allocate memory object  */
/*                       VDHFreePages       - Free the memory object  */
/*                       VDHQuerySysValue   - Get system values       */
/*                       VDHOpenPDD         - Get PDD entry point     */
/*                       VDHQuerySel        - Convert 0:32 to 16:16   */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
BOOL EXPENTRY VDDInit(psz)         /* VLPT VDDInit      */
PSZ psz;                           /* pointer to configuration string */
{
    INT i, j, k;                   /* counter                        */
    PWORD p;                       /* bios data area pointer         */
    PVOID pLowMemAlias;            /* physical low memory pointer    */
    VPBOUND vpbLprTimeout = {VLPT_SPOOL_MIN, VLPT_SPOOL_MAX, VLPT_SPOOL_STEP};

#ifdef DEBUG
   vdhInt3();
#endif

    /*---------------------------------------------------------------*/
    /*- Register a VDM termination handler entry point.             -*/
    /*---------------------------------------------------------------*/
    if ((VDHInstallUserHook((ULONG)VDM_TERMINATE,
                            (PUSERHOOK)VLPTTerminate)) == 0)
        return FALSE;             /* return FALSE if VDH call failed */

    /*---------------------------------------------------------------*/
    /*- Register a VDM creation handler entry point.                -*/
    /*---------------------------------------------------------------*/
    if ((VDHInstallUserHook((ULONG)VDM_CREATE,
                            (PUSERHOOK)VLPTCreate)) == 0)
        return FALSE;             /* return FALSE if VDH call failed */

    /*---------------------------------------------------------------*/
    /*- Register a VDM PDB change handler entry point.              -*/
    /*---------------------------------------------------------------*/
    if ((VDHInstallUserHook((ULONG)VDM_PDB_CHANGE,
                            (PUSERHOOK)VLPTPDBChange)) == 0)
        return FALSE;             /* return FALSE if VDH call failed */

    /*---------------------------------------------------------------*/
    /*- Register a VDM PDB destruction handler entry point.         -*/
    /*---------------------------------------------------------------*/
    if ((VDHInstallUserHook((ULONG)VDM_PDB_DESTROY,
                            (PUSERHOOK)VLPTPDBDestroy)) == 0)
        return FALSE;             /* return FALSE if VDH call failed */

    /*---------------------------------------------------------------*/
    /*- Find out what type of machine the system was booted on.     -*/
    /*---------------------------------------------------------------*/
    if ((MachineType =
          VDHQuerySysValue(CURRENT_VDM, VDHGSV_MACHINETYPE)) == 0)
        return FALSE;             /* return FALSE if VDH call failed */

    /*---------------------------------------------------------------*/
    /*- Get the entry point to the PLPT.                            -*/
    /*---------------------------------------------------------------*/
    PLPTPDDProc = VDHOpenPDD(LPT_NAME, VLPTPDDProc);

    /*---------------------------------------------------------------*/
    /*- Get the printer buffer size from PLPT.                      -*/
    /*---------------------------------------------------------------*/
    if (PLPTPDDProc)
    {
      for(i=0; i<MAXPRTS; i++)
      {

    /*---------------------------------------------------------------*/
    /*- The buffer value is returned in an element of an array      -*/
    /*- that VLPT passed a pointer to in the call to the PLPT. This -*/
    /*- pointer has to be 16:16, F16PFROMP does a VDHQuerySel to    -*/
    /*- convert the 0:32 pointer to 16:16.                          -*/
    /*---------------------------------------------------------------*/
          if (PLPTPDDProc((ULONG)PLPT_GET_BUFFER_SIZE,
                           (F16PVOID)i,
                           F16PFROMP(&ulbuffersize[i])) != 0)
          {
             ulbuffersize[i] = BUFSIZ;
          } /* endif */

      } /* endfor */

    } /* endif */

    /*---------------------------------------------------------------*/
    /* Get access to low memory                                      */
    /*---------------------------------------------------------------*/
    pLowMemAlias = VDHAllocPages(LOWMEM_START,
                                 LOWMEM_PAGES,
                                 VDHAP_SYSTEM | VDHAP_PHYSICAL);

    /*---------------------------------------------------------------*/
    /* If page allocation failed then return FALSE                   */
    /*---------------------------------------------------------------*/
    if (!pLowMemAlias) {
        return FALSE;
    }

    /*---------------------------------------------------------------*/
    /*- Set a pointer to the first base printer port address in the -*/
    /*- system bios data area.                                      -*/
    /*---------------------------------------------------------------*/
    p = pVDMBase(pLowMemAlias)->rb_awLPT;

    /*---------------------------------------------------------------*/
    /*- This loop is responsible for setting up the VLPT port       -*/
    /*- address table. This loop will use the parallel port         -*/
    /*- address in the system bios data area as the                 -*/
    /*- base(data) address if it is not zero, and mark that address -*/
    /*- as USED in the default bios data area structure, and fill   -*/
    /*- in the status, control, and reserve port addresses.         -*/
    /*-                                                             -*/
    /*---------------------------------------------------------------*/
    for(i=0; i<MAXPRTS; i++) {  /* set up to loop for each port      */

    /*---------------------------------------------------------------*/
    /*- Does the parallel port address area in the system bios data -*/
    /*- that p is currently pointing to contain an address of 0 ?   -*/
    /*---------------------------------------------------------------*/
        if (p[i]==0) {

    /*---------------------------------------------------------------*/
    /*- The address for parallel port i is zero so loop through the -*/
    /*- default bios data area looking for an un-used parallel port.-*/
    /*- When an un-used port is found set the current data port     -*/
    /*- equal to the corresponding available default address. Then  -*/
    /*- set the status, control, and reserve ports equal to the     -*/
    /*- respective offset from the data port address. Then mark the -*/
    /*- current parallel port as USED in the default bios data area.-*/
    /*---------------------------------------------------------------*/
            for(j=0; ((j<MAXPRTS) && (def_bd_area[j].flags & USED)); j++);

    /*---------------------------------------------------------------*/
    /*- If somehow the parallel port area pointed to contains a     -*/
    /*- zero address and an UNUSED port in the default bios data    -*/
    /*- area is not found then return FALSE to indicate             -*/
    /*- that VLPT initialization failed.                            -*/
    /*---------------------------------------------------------------*/
            if (j==MAXPRTS) {
                return FALSE;
            } /* endif */

            vpa_table[i].data = def_bd_area[j].lptbase;
            vpa_table[i].status = vpa_table[i].data + (WORD)1;
            vpa_table[i].control = vpa_table[i].data + (WORD)2;
            vpa_table[i].reserve = vpa_table[i].data + (WORD)3;
            vpa_table[i].flags = FLAG_NOT_SET;
            def_bd_area[j].flags |= USED;

    /*---------------------------------------------------------------*/
    /*- The address for parallel port i is not zero so set the      -*/
    /*- current data port equal to the address currently pointed    -*/
    /*- to in the system bios data area. Then set the status,       -*/
    /*- control, and reserve ports equal to the respective offset   -*/
    /*- from the data port address.                                 -*/
    /*---------------------------------------------------------------*/
        } else {
            vpa_table[i].data = p[i];
            vpa_table[i].status = vpa_table[i].data + (WORD)1;
            vpa_table[i].control = vpa_table[i].data + (WORD)2;
            vpa_table[i].reserve = vpa_table[i].data + (WORD)3;
            vpa_table[i].flags = PHYSICAL_PORT;

    /*---------------------------------------------------------------*/
    /*- Search for the address in the default bios data area table  -*/
    /*- that matches the one currently pointed to in the system     -*/
    /*- bios data area.                                             -*/
    /*---------------------------------------------------------------*/
            for(k=0; ((k<MAXPRTS) && (def_bd_area[k].lptbase!=p[i])); k++);

    /*---------------------------------------------------------------*/
    /*- If a match has been found then mark that address as used in -*/
    /*- the default bios data area table. If for some reason an     -*/
    /*- address in the system bios data area is not one that is     -*/
    /*- accounted for in the default bios data this routine will    -*/
    /*- not be able to mark it as used. But no harm is done because -*/
    /*- the default bios data area is really just keeping track of  -*/
    /*- available parallel port addresses to be used as place       -*/
    /*- holders when the system bios data area address is a zero.   -*/
    /*---------------------------------------------------------------*/
            if (k!=MAXPRTS) {
                def_bd_area[k].flags |= USED;
            } /* endif */


        } /* endif */

    } /* endfor */

    VDHFreePages(pLowMemAlias); /* Free pages from VDHAllocPages req.*/


    /*---------------------------------------------------------------*/
    /*-  Register DOS Setting for LPT Timeout (secs)                -*/
    /*---------------------------------------------------------------*/
    if (!VDHRegisterProperty(
        szProplpt1timeout,              // property name
        NULL,                           // no help file
        0,                              // no help id
        VDMP_INT,                       // type
        VDMP_ORD_OTHER,                 // no ordinal
        0,                              // modifiable after creation
        (VOID*)(VLPT_SPOOL_CLOSE),      // default
        SSToDS(&vpbLprTimeout),         // validation info
        VLPTSetSpoolClose               // function
         )
        )
        return FALSE;

    /*---------------------------------------------------------------*/
    /*-  Register DOS Setting for splitting or not on PDB changes   -*/
    /*---------------------------------------------------------------*/
    if (!VDHRegisterProperty(
        szProplptseparate,              // property name
        NULL,                           // no help file
        0,                              // no help id
        VDMP_BOOL,                      // type
        VDMP_ORD_OTHER,                 // no ordinal
        VDMP_CREATE,                    // not modifiable after creation
        (VOID*)1,                       // default
        NULL,                           // validation info
        NULL                            // no function, create time only
         )
        )
        return FALSE;

    return TRUE;
}

/********************** START OF SPECIFICATIONS ***********************/
/*                                                                    */
/* SUBROUTINE NAME:  VLPTPDDProc                                      */
/*                                                                    */
/* DESCRIPTIVE NAME:  VLPT entry point for PLPT                       */
/*                                                                    */
/* FUNCTION:  This subroutine is registered by the VDD during VDD     */
/*            Initialization via VDHOpenPDD and is called by the PDD  */
/*            to provide notification of various events. At this time */
/*            this routine is just a place holder. The PLPT does not  */
/*            need to notify the VLPT of anything yet...              */
/*                                                                    */
/* NOTES:  This is a private PDD->VDD entry point.                    */
/*                                                                    */
/* CONTEXT: PDD task time                                             */
/*                                                                    */
/* ENTRY POINT:  VLPTPDDProc                                          */
/*    LINKAGE:  CALL NEAR 32                                          */
/*                                                                    */
/* INPUT:                                                             */
/*          ulFunc - request function                                 */
/*          f16p1  - parameter 1                                      */
/*          f16p2  - parameter 2                                      */
/*                                                                    */
/* EXIT-NORMAL: return TRUE                                           */
/*                                                                    */
/* EXIT-ERROR: return FALSE - invalid request function                */
/*                                                                    */
/* EFFECTS:  NONE                                                     */
/*                                                                    */
/* INTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/* EXTERNAL REFERENCES:  NONE                                         */
/*                                                                    */
/************************ END OF SPECIFICATIONS ***********************/
SBOOL VDDENTRY VLPTPDDProc(ulFunc,f16p1,f16p2)
ULONG ulFunc;
F16PVOID f16p1;
F16PVOID f16p2;
{
    return TRUE;
}

#pragma END_INIT_CODE
