/*DDK*************************************************************************/
/*                                                                           */
/* COPYRIGHT (C) Lexmark 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.                                */
/*                                                                           */
/*****************************************************************************/
/**************************************************************************
 *
 * SOURCE FILE NAME = PRDMFILE
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   prdm_CopyFile
 *             prdm_ReadFileContents
 *             prdm_CheckFileExists
 *             prdm_CheckFileOKForPrinter
 *             prdm_CopyFMFFiles
 *             prdm_StringsAreEqual
 *             prdm_ReadFontResource
 *
 * ENTRY POINTS:
 *
 * DEPENDENCIES:
 *
 * NOTES
 *
 *
 * STRUCTURES
 *
 * EXTERNAL REFERENCES
 *
 * EXTERNAL FUNCTIONS
 *
*/

#define INCL_32                         /* Convert to C/SET2    CON3201       */
#define INCL_DOSPROCESS                 /* Convert to C/SET2    CON3201       */
#define INCL_DOSRESOURCES
#define INCL_DOSSEMAPHORES
#define INCL_GPIERRORS
#define INCL_DOSERRORS
#define INCL_DOSMISC
#define INCL_GPIPRIMITIVES
#define INCL_WINHEAP
#define INCL_GPIBITMAPS
#define INCL_DOSMODULEMGR
#define INCL_WINFRAMEMGR
#define INCL_WINLISTBOXES
#define INCL_WINBUTTONS
#define INCL_WINERRORS
#define INCL_WINDIALOGS
#define INCL_WINSHELLDATA
#define INCL_WINENTRYFIELDS
#define INCL_WINMESSAGEMGR
#define INCL_WININPUT
#define INCL_WINMENUS
#define INCL_DOSPROCESS
#define INCL_WINWINDOWMGR
#define INCL_WINPOINTERS
#include <os2.h>
#undef INCL_DOSPROCESS                  /* Convert to C/SET2    CON3201       */
#undef INCL_DOSRESOURCES
#undef INCL_DOSSEMAPHORES
#undef INCL_GPIERRORS
#undef INCL_DOSERRORS
#undef INCL_DOSMISC
#undef INCL_GPIPRIMITIVES
#undef INCL_WINHEAP
#undef INCL_GPIBITMAPS
#undef INCL_DOSMODULEMGR
#undef INCL_WINFRAMEMGR
#undef INCL_WINLISTBOXES
#undef INCL_WINBUTTONS
#undef INCL_WINERRORS
#undef INCL_WINDIALOGS
#undef INCL_WINSHELLDATA
#undef INCL_WINENTRYFIELDS
#undef INCL_WINMESSAGEMGR
#undef INCL_WININPUT
#undef INCL_WINMENUS
#undef INCL_DOSPROCESS
#undef INCL_WINWINDOWMGR
#undef INCL_WINPOINTERS

#define INCL_DDIBUNDLES
#define INCL_DDIFONTSTRUCS
#define INCL_DDIDEFS
#include <pmddi.h>
#undef INCL_DDIBUNDLES
#undef INCL_DDIFONTSTRUCS
#undef INCL_DDIDEFS

#define INCL_WINP_SELSERVER
#define INCL_WINP_SELECTIVE
#define INCL_WINP_SEI
#include <pmwinx.h>
#undef INCL_WINP_SELSERVER
#undef INCL_WINP_SELECTIVE
#undef INCL_WINP_SEI

#define INCL_WINSHELLDATA
/* #include <pmshlp.h>                                              DLM01 */
#define INCL_WINSHELLDATA
#undef INCL_32                          /* Convert to C/SET2    CON3201       */

#include <prdconse.h>
#include <prddcone.h>
#include <prdecone.h>
#include <prdmcone.h>
#include <prdtcone.h>

#define NO_SYS
#define INCL_HELP
#define PRDMTYPE_INCL
#define NO_CONSTANT_INCL
#include <prdinclt.h>
#undef NO_CONSTANT_INCL
#undef NO_SYS
#undef INCL_HELP
#undef PRDMTYPE_INCL

#include <prdeextf.h>
#include <prdgextf.h>
#include <prdmextf.h>
#include <prduextf.h>

extern DModeDataType  DMData;
extern lpDMSettings   pDMSettings;

extern BYTE           SrcFileName[80];
extern BYTE           TrgFileName[80];
extern BYTE           SrcDirBuffer[80];
extern BYTE           TrgDirBuffer[80];
extern HMODULE        prdd_ModHandle;
extern USHORT         DRIVER_TYPE;

/******************************************************************************/
/*  PD00375: Externs for Nile/Tiber font lists.                               */
/******************************************************************************/
extern lpFontListType       DVTFontList9Wire [];
extern lpFontListType       DVTFontList9WireNLS [];
extern lpFontListType       DVTFontList24Wire [];
extern lpFontListType       DVTFontList24WireNLS [];





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_CopyFile                                          */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PSZ           SourcePath;                                        */
/*   PSZ           TargetPath;                                        */
/*   PSZ           Srcname;                                           */
/*   PSZ           Dstname;                                           */
/*   PSZ           Extension;                                         */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   Attempts to copy a file from the source directory to the         */
/*   target directory.  If the paths and filenames are the same,      */
/*   i.e. we are being asked to copy a file onto itself, we just      */
/*   return NO_ERROR without doing anything.                          */
/*                                                                    */
/*   Returns a Dos Result - either NO_ERROR (equivalent to the        */
/*   driver's DOS_OK) or a Dos Error number.                          */
/*                                                                    */
/*   All the parameters are null terminated strings. If               */
/*   Extension is null it is assumed that Filename already            */
/*   contains the extension; if Extension is not null it must         */
/*   include the initial point ('.').  The other parameters should    */
/*   not be null                                                      */
/*                                                                    */
/**********************************************************************/
#if 0
USHORT pascal prdm_CopyFile( SourcePath,
                             TargetPath,
                             Srcname,
                             Dstname,
                             Extension )

PSZ              SourcePath;
PSZ              TargetPath;
PSZ              Srcname;
PSZ              Dstname;
PSZ              Extension;
#endif

USHORT prdm_CopyFile( PSZ SourcePath,                      /* CON3201 */
                      PSZ TargetPath,                      /* CON3201 */
                      PSZ Srcname,                         /* CON3201 */
                      PSZ Dstname,                         /* CON3201 */
                      PSZ Extension )                      /* CON3201 */

{
#define TFUNC "prdm_CopyFile"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT      i;          /* Counting variables               */
    ULONG iExt;
    PBYTE       pWork;            /* Working pointer                  */
    SHORT       Result;           /* Function call return values      */
    USHORT      DosResult;        /* Dos Function call return values  */
//  USHORT      ActionTaken;      /* CON3201                          */
    ULONG       ActionTaken;      /* Parameter for DosOpen            */
    BYTE        FileInfoBuf[36];  /* Buffer for file                  */
    HFILE       SrcFileHandle;    /* Handle of file copied from       */
    HFILE       TrgFileHandle;    /* Handle of file copied to         */
    ULONG       FileSize;         /* Size of the down font file       */
    USHORT      BufferSize;       /* Size of the buffer               */
    PBYTE       Buffer;           /* Buffer to read data into         */
//  USHORT      BytesMoved;       /* CON3201                          */
    ULONG       BytesMoved;       /* Returned from DosRead/Write      */
    USHORT      RetVal;           /* Error code (OK or ERROR_ZERO)    */

    TRACE8(TFUNC, "Entry", FNULL, 0);


    /******************************************************************/
    /* Check for the case of copying a file onto itself; use a        */
    /* non case sensitive string compare function.                    */
    /******************************************************************/
    if ( prdm_StringsAreEqual( SourcePath,
                               TargetPath ) &&
         prdm_StringsAreEqual( Srcname,
                               Dstname ) )
    {
        return (NO_ERROR);
    }

    /******************************************************************/
    /* Build the full source filename.                                */
    /* Start by copying the path across. - add a backslash to         */
    /* the end if there isn't one already.                            */
    /******************************************************************/
    for ( i = 0, pWork = SourcePath; *pWork != (BYTE)'\0'; )
        SrcFileName[i++] = *pWork++;

    if ( *(pWork - 1) != '\\' )
        SrcFileName[i++] = (BYTE)'\\';

    /******************************************************************/
    /* Add on the filename and record the position of the extension   */
    /* if there is one.                                               */
    /******************************************************************/
    iExt = VALUE_NOT_SET;

    for ( pWork = Srcname; *pWork != (BYTE)'\0'; )
    {
        if ( *pWork == (BYTE)'.' )
            iExt = i;

        SrcFileName[i++] = *pWork++;
    }

    /******************************************************************/
    /* Add the extension if this not empty.  Start at the end of the  */
    /* filename if there is no extension already.                     */
    /******************************************************************/
    if ( Extension )
    {
        if ( iExt != VALUE_NOT_SET ) /* CON3203 */
            i = iExt;

        for ( pWork = Extension; *pWork != (BYTE)'\0'; )
            SrcFileName[i++] = *pWork++;
    }

    /******************************************************************/
    /* Finish off with a null terminator.                             */
    /******************************************************************/
    SrcFileName[i] = (BYTE)'\0';

    TRACE6(TFUNC, "Source Filename", SrcFileName, 10);


    /******************************************************************/
    /* Build the full target filename.                                */
    /* Start by copying the path across. - add a backslash to         */
    /* the end if there isn't one already.                            */
    /******************************************************************/
    for ( i = 0, pWork = TargetPath; *pWork != (BYTE)'\0'; )
        TrgFileName[i++] = *pWork++;

    if ( *(pWork - 1) != '\\' )
        TrgFileName[i++] = (BYTE)'\\';

    /******************************************************************/
    /* Add on the filename and record the position of the extension   */
    /* if there is one.                                               */
    /******************************************************************/
    iExt = VALUE_NOT_SET;

    for ( pWork = Dstname; *pWork != (BYTE)'\0'; )
    {
        if ( *pWork == (BYTE)'.' )
            iExt = i;

        TrgFileName[i++] = *pWork++;
    }

    /******************************************************************/
    /* Add the extension if this not empty.  Start at the end of the  */
    /* filename if there is no extension already.                     */
    /******************************************************************/
    if ( Extension )
    {
        if ( iExt != VALUE_NOT_SET ) /* CON3203 */
            i = iExt;

        for ( pWork = Extension; *pWork != (BYTE)'\0'; )
            TrgFileName[i++] = *pWork++;
    }

    /******************************************************************/
    /* Finish off with a null terminator.                             */
    /******************************************************************/
    TrgFileName[i] = (BYTE)'\0';

    TRACE6(TFUNC, "Target filename", TrgFileName, 10);

    /******************************************************************/
    /* Set up values used to handle tidy up on error.                 */
    /******************************************************************/
    RetVal = OK;
    Buffer = FNULL;

    /******************************************************************/
    /* Allow any hard error to be processed by the driver rather      */
    /* than a system pop-up.  This disables hard error pop-ups.       */
    /******************************************************************/
    (void)DosError( 0L );

    /******************************************************************/
    /* Open the source file.                                          */
    /******************************************************************/
    DosResult = DosOpen( (PSZ)SrcFileName,
                         (PHFILE)&SrcFileHandle,
                         (PULONG)&ActionTaken,
                         0L,
                         FILE_READONLY,
                         FILE_OPEN,
                         OPEN_ACCESS_READWRITE |
                           OPEN_SHARE_DENYNONE |
                           OPEN_FLAGS_FAIL_ON_ERROR,
                         0L );

    if (DosResult != NO_ERROR)
    {
        /* RetVal = ERROR_ZERO; */
        if ( DosResult == ERROR_PATH_NOT_FOUND ||
             DosResult == ERROR_NOT_READY      ||
             DosResult == ERROR_INVALID_DRIVE  ||
             DosResult == ERROR_INVALID_PATH   ||
             DosResult == ERROR_FILENAME_EXCED_RANGE)
        {
            RetVal = IDS_PATH_NOT_FOUND;
        }
        else
        {
            RetVal = IDS_FILE_NOT_FOUND;
        }

        goto ERROR_EXIT;
    }

    /******************************************************************/
    /* Get the file size.                                             */
    /******************************************************************/
    DosResult = DosQueryFileInfo( SrcFileHandle, 1, (PBYTE)FileInfoBuf, 36 );

    if (DosResult != NO_ERROR)
    {
       /* was ERROR_ZERO */
        RetVal = IDS_CANT_COPY;
        goto ERROR_EXIT;
    }

    FileSize = (ULONG)( *((PULONG)(FileInfoBuf + 12)) );

    TRACE6(TFUNC, "File info buffer", FileInfoBuf, 5);
    TRACE6(TFUNC, "File size", &FileSize, 1);

    /******************************************************************/
    /* Allocate memory to hold the file data.                         */
    /******************************************************************/
    BufferSize = (USHORT)min( FileSize, (ULONG)MAX_READ_LENGTH );

    TRACE6(TFUNC, "Buffer size", &BufferSize, 1);

 /* CON3201 *****************************************/
 /* DosResult = SSALLOCSEG ( BufferSize,            */
 /*                          &SELECTOROF(Buffer),   */
 /*                          0 );                   */
 /***************************************************/

    DosResult = SafeSSALLOCMEM ( &Buffer,
                             BufferSize,
                             0 );

    if (DosResult != NO_ERROR)
    {
       /* was ERROR_ZERO */
        RetVal = IDS_CANT_COPY;
        goto ERROR_EXIT;
    }

/*  OFFSETOF(Buffer) = 0;                                             CON3201 */

    /******************************************************************/
    /* Open the target file.                                          */
    /******************************************************************/
    DosResult = DosOpen( TrgFileName,
                         (PHFILE)&TrgFileHandle,
                         (PULONG)&ActionTaken,
                         0L,
                         FILE_NORMAL,
                         FILE_CREATE | FILE_TRUNCATE,
                         OPEN_ACCESS_WRITEONLY |
                           OPEN_SHARE_DENYNONE |
                           OPEN_FLAGS_WRITE_THROUGH |
                           OPEN_FLAGS_FAIL_ON_ERROR,
                         0L );

    if (DosResult != NO_ERROR)
    {
       /* was ERROR_ZERO */
        RetVal = IDS_CANT_COPY;
        goto ERROR_EXIT;
    }

    /******************************************************************/
    /* Read in a chunk of data from the source file and write it to   */
    /* the target file - repeat this until all the file has been      */
    /* copied.                                                        */
    /******************************************************************/
    while ( (LONG)FileSize > 0 )
    {
        DosResult = DosRead( SrcFileHandle,
                             (PVOID)Buffer,
                             BufferSize,
                             &BytesMoved );

        TRACE4(TFUNC, "Bytes moved", &BytesMoved, 1);

        if (DosResult != NO_ERROR)
        {
           /* was ERROR_ZERO */
            RetVal = IDS_CANT_COPY;
            goto ERROR_EXIT;
        }

        if (BufferSize != BytesMoved)
        {
            DosResult = ERROR_READ_FAULT;
           /* was ERROR_ZERO */
            RetVal = IDS_CANT_COPY;
            goto ERROR_EXIT;
        }

        /**************************************************************/
        /* Copy the data.                                             */
        /**************************************************************/
        DosResult = DosWrite( TrgFileHandle,
                              (PVOID)Buffer,
                              BufferSize,
                              &BytesMoved );

        if (DosResult != NO_ERROR)
        {
           /* was ERROR_ZERO */
            RetVal = IDS_CANT_COPY;
            goto ERROR_EXIT;
        }

        if (BufferSize != BytesMoved)
        {
            DosResult = ERROR_WRITE_FAULT;
           /* was ERROR_ZERO */
            RetVal = IDS_CANT_COPY;
            goto ERROR_EXIT;
        }

        FileSize -= (ULONG)MAX_READ_LENGTH;
        TRACE6(TFUNC, "File Size", &FileSize, 1);

        BufferSize = (USHORT)min(FileSize, (ULONG)MAX_READ_LENGTH);
        TRACE6(TFUNC, "Buffer size", &BufferSize, 1);
    }

ERROR_EXIT:
    /******************************************************************/
    /* Enable hard error pop-ups.  This clears the error condition.   */
    /* If this is not done then all subsequent disk accesses will     */
    /* fail.                                                          */
    /******************************************************************/
    (void)DosError( 1L );

    /******************************************************************/
    /* Close the source file.                                         */
    /******************************************************************/
    (void)DosClose ( SrcFileHandle );

    /******************************************************************/
    /* Close the target file.                                         */
    /******************************************************************/
    (void)DosClose ( TrgFileHandle );

    /******************************************************************/
    /* Free the buffer memory.                                        */
    /******************************************************************/
    if ( Buffer )
/*      SSFREESEG( SELECTOROF(Buffer) );                              CON3201 */
        SSFREEMEM( Buffer );

    /******************************************************************/
    /* Return either NO_ERROR or the Dos Error number.                */
    /******************************************************************/
    if (RetVal == OK)
        return (NO_ERROR);
    else
        return (RetVal);

}

#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_ReadFileContents                                  */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PSZ           Path;                                              */
/*   PSZ           Filename;                                          */
/*   PSZ           Extension;                                         */
/*   PUSHORT       pFileSize;                                         */
/*   PBYTE far *   pFileBufferAddr                                    */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   Path, Filename and Extension are null terminated strings.        */
/*   Path and Extension can be empty; Filename must not be empty.     */
/*   Any value in extension overides an extension already included in */
/*   Filename.  Extension must include the initial point ('.').       */
/*                                                                    */
/*   The argument pFileBufferAddr is a pointer to an address.  This   */
/*   address is set to point to a segment (with SSALLOCSEG) and the   */
/*   file contents are copied to this area.  The file size is         */
/*   returned in pFileSize.                                           */
/*                                                                    */
/*   Returns a Dos Result - either NO_ERROR (equivalent to the        */
/*   driver's DOS_OK) or a Dos Error number.                          */
/*                                                                    */
/**********************************************************************/
#if 0
USHORT pascal prdm_ReadFileContents( Path,
                                     Filename,
                                     Extension,
                                     pFileSize,
                                     pFileBufferAddr )

PSZ              Path;
PSZ              Filename;
PSZ              Extension;
PUSHORT          pFileSize;
PBYTE far *      pFileBufferAddr;
#endif

USHORT prdm_ReadFileContents( PSZ      Path,               /* CON3201 */
                              PSZ      Filename,           /* CON3201 */
                              PSZ      Extension,          /* CON3201 */
                              PUSHORT  pFileSize,          /* CON3201 */
                              PBYTE   *pFileBufferAddr )   /* CON3201 */

{
#define TFUNC "prdm_ReadFile"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT   DosResult;            /* Function call return values     */
    BYTE     FullPathName[80];
    PBYTE    pDest;
    PBYTE    pSource;
    PBYTE    pExt;
    HFILE    FileHandle;           /* File handle                     */
//  USHORT   ActionTaken;          /* CON3201                         */
    ULONG    ActionTaken;          /* Parameter for DosOpen           */
    BYTE     FileInfoBuf[36];      /* Buffer for file                 */
//  USHORT   BytesRead;            /* CON3201                         */
    ULONG    BytesRead;            /* returned from DosRead           */
    PBYTE    pFileBuffer = FNULL;
    USHORT   RetVal;



    /******************************************************************/
    /* Build the full pathname for the file.                          */
    /******************************************************************/
    pDest = FullPathName;

    /******************************************************************/
    /* Start with the path if this not empty - add a backslash to     */
    /* the end if there isn't one already.                            */
    /******************************************************************/
    if ( Path )
    {
        for ( pSource = Path; *pSource != (BYTE)'\0'; )
            *pDest++ = *pSource++;

        if ( *(pDest - 1) != '\\' )
            *pDest++ = (BYTE)'\\';
    }

    /******************************************************************/
    /* Add on the filename - this should never be empty.              */
    /* Record the position of the extension if there is one.          */
    /******************************************************************/
    pExt = FNULL;
    for ( pSource = Filename; *pSource != (BYTE)'\0'; )
    {
        if ( *pSource == (BYTE)'.' )
            pExt = pDest;
        *pDest++ = *pSource++;
    }

    /******************************************************************/
    /* Add the extension if this not empty.  Start at the end of the  */
    /* filename if there is no extension already.                     */
    /******************************************************************/
    if ( Extension )
    {
        if ( pExt != FNULL )
            pDest = pExt;

        for ( pSource = Extension; *pSource != (BYTE)'\0'; )
            *pDest++ = *pSource++;
    }

    /******************************************************************/
    /* Finish off with a null terminator.                             */
    /******************************************************************/
    *pDest = (BYTE)'\0';

    /******************************************************************/
    /* Set up values used to handle tidy up on error.                 */
    /******************************************************************/
    RetVal = NO_ERROR;

    /******************************************************************/
    /* Allow any hard error to be processed by the driver rather      */
    /* than a system pop-up.  This disables hard error pop-ups.       */
    /******************************************************************/
    (void)DosError( 0L );

    /******************************************************************/
    /* Open the source file.                                          */
    /******************************************************************/
    DosResult = DosOpen( FullPathName,
                         &FileHandle,
                         &ActionTaken,
                         0L,
                         FILE_READONLY,
                         FILE_OPEN,
                         OPEN_ACCESS_READWRITE |
                           OPEN_SHARE_DENYNONE |
                           OPEN_FLAGS_FAIL_ON_ERROR,
                         0L );

    if (DosResult != NO_ERROR)
    {
        if ( DosResult == ERROR_PATH_NOT_FOUND ||
             DosResult == ERROR_NOT_READY      ||
             DosResult == ERROR_INVALID_DRIVE  ||
             DosResult == ERROR_INVALID_PATH   ||
             DosResult == ERROR_FILENAME_EXCED_RANGE)
        {
            RetVal = IDS_PATH_NOT_FOUND;
        }
        else
        {
            RetVal = IDS_FILE_NOT_FOUND;
        }

        goto ERROR_EXIT;
    }

    /******************************************************************/
    /* Get the file size and store in the down font list.             */
    /******************************************************************/
/*  DosResult = DosQFileInfo( FileHandle,                             CON3201 */
    DosResult = DosQueryFileInfo( FileHandle,
                                  1,
                                  (PBYTE)FileInfoBuf,
                                  36 );

    if (DosResult != NO_ERROR)
    {
        RetVal = IDS_CANT_COPY;
        goto ERROR_EXIT;
    }

    *pFileSize = (USHORT)(*((PULONG)(FileInfoBuf + 12)));

    /******************************************************************/
    /* Allocate memory for the font metrics                           */
    /******************************************************************/
 /* CON3201 *****************************************************/
 /* DosResult = SSALLOCSEG ( (*pFileSize),                      */
 /*                           &SELECTOROF(pFileBuffer),         */
 /*                           0 );                              */
 /***************************************************************/
    DosResult = SafeSSALLOCMEM ( &pFileBuffer,
                             (*pFileSize),
                             0 );

    if (DosResult != NO_ERROR)
    {
        RetVal = IDS_CANT_COPY;
        goto ERROR_EXIT;
    }

/*  OFFSETOF(pFileBuffer) = 0;                                        CON3201 */

    /******************************************************************/
    /* Read in the file contents.                                     */
    /******************************************************************/
    DosResult = DosRead( FileHandle,
                         (PVOID)pFileBuffer,
                         (*pFileSize),
                         &BytesRead );

    if (DosResult != NO_ERROR)
    {
        RetVal = IDS_CANT_COPY;
        goto ERROR_EXIT;
    }

ERROR_EXIT:
    /******************************************************************/
    /* Close the file.                                                */
    /******************************************************************/
    (void)DosClose ( FileHandle );

    /******************************************************************/
    /* Enable hard error pop-ups.  This clears the error condition.   */
    /* If this is not done then all subsequent disk accesses will     */
    /* fail.                                                          */
    /******************************************************************/
    (void)DosError( 1L );

    /******************************************************************/
    /* Tidy up depending on success of above.                         */
    /******************************************************************/
    if ( RetVal == NO_ERROR )
    {
        *pFileBufferAddr = pFileBuffer;
        return (NO_ERROR);
    }
    else
    {
        if ( pFileBuffer )
/*          SSFREESEG( SELECTOROF(pFileBuffer) );                     CON3201 */
            SSFREEMEM( pFileBuffer);

        return (RetVal);
    }

}
#undef TFUNC







/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_CheckFileExists                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PSZ           Path;                                              */
/*   PSZ           Filename;                                          */
/*   PSZ           Extension;                                         */
/*   PHDIR         pSearchHandle;                                     */
/*   PFILEFINDBUF  pFileInfoBuffer;                                   */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   Checks existance of the given file; returns 1 if it exists,      */
/*   0 if not.                                                        */
/*                                                                    */
/*   Path, Filename and Extension are null terminated                 */
/*   strings; Path and Extension can be empty.  The calling routine   */
/*   must ensure that Filename is not empty and that pSearchHandle    */
/*   is set either to 0xFFFF or a previously returned value.  Any     */
/*   value in extension overides an extension already included in     */
/*   Filename.  Extension must include the initial point ('.').       */
/*                                                                    */
/**********************************************************************/
#if 0
USHORT pascal prdm_CheckFileExists( Path,
                                    Filename,
                                    Extension,
                                    pSearchHandle,
                                    pFileInfoBuffer )

PSZ              Path;
PSZ              Filename;
PSZ              Extension;
PHDIR            pSearchHandle;
PFILEFINDBUF     pFileInfoBuffer;
#endif
                                                            /* CON3201 */
USHORT prdm_CheckFileExists( PSZ           Path,             /* CON3201 */
                             PSZ           Filename,         /* CON3201 */
                             PSZ           Extension,        /* CON3201 */
                             PHDIR         pSearchHandle,    /* CON3201 */
                             PFILEFINDBUF3 pFileInfoBuffer ) /* CON3201 */

{
#define TFUNC "prdm_ChkFileExst"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    PBYTE    pDest;            /* Working pointers....                */
    PBYTE    pSource;          /*                     ....            */
    PBYTE    pExt;             /*                         ....        */
//  USHORT   SearchCount;      /* CON3201                             */
    ULONG    SearchCount;      /* Parameter for DosFindFirst          */
    SHORT    Result;           /* Function call return values         */
    USHORT   RetCode;          /* Value returned to calling fn.       */
    USHORT   Attributes;       /* type of files searched for          */

    TRACE8(TFUNC, "Entry", FNULL, 0);

    /******************************************************************/
    /* Build the search path for the file.                            */
    /******************************************************************/
    pDest = SrcFileName;

    /******************************************************************/
    /* Start with the path if this not empty - add a backslash to     */
    /* the end if there isn't one already.                            */
    /******************************************************************/
    if ( Path )
    {
        for ( pSource = Path; *pSource != (BYTE)'\0'; )
            *pDest++ = *pSource++;

        if ( *(pDest - 1) != '\\' )
            *pDest++ = (BYTE)'\\';
    }

    /******************************************************************/
    /* Add on the filename - this should never be empty.              */
    /* Record the position of the extension if there is one.          */
    /******************************************************************/
    pExt = FNULL;
    for ( pSource = Filename; *pSource != (BYTE)'\0'; )
    {
        if ( *pSource == (BYTE)'.' )
            pExt = pDest;
        *pDest++ = *pSource++;
    }

    /******************************************************************/
    /* Add the extension if this not empty.  Start at the end of the  */
    /* filename if there is no extension already.                     */
    /******************************************************************/
    if ( Extension )
    {
        if ( pExt )
            pDest = pExt;

        for ( pSource = Extension; *pSource != (BYTE)'\0'; )
            *pDest++ = *pSource++;
    }

    /******************************************************************/
    /* Finish off with a null terminator.                             */
    /******************************************************************/
    *pDest = (BYTE)'\0';

    TRACE4(TFUNC, "Search path", SrcFileName, 10);

    /******************************************************************/
    /* Set the search count to only one file requested.               */
    /* If we are checking just if the path exists then look for       */
    /* system and subdirectory files as well as normal files.         */
    /******************************************************************/
    SearchCount = 1;

    if ( !prdu_strcmp( (PBYTE)Filename, (PBYTE)ANY_FILENAME) )
        Attributes = 0x0014;            /* system + directory files   */
    else
        Attributes = 0;                 /* normal files only          */

    /******************************************************************/
    /* Allow any hard error to be processed by the driver rather      */
    /* than a system pop-up.  This disables hard error pop-ups.       */
    /******************************************************************/
    (void)DosError( 0x00L );

    /******************************************************************/
    /* Check to see if file exists.                                   */
    /******************************************************************/
    Result = DosFindFirst( SrcFileName,
                           pSearchHandle,
                           Attributes,
                           pFileInfoBuffer,
                           sizeof(FILEFINDBUF3),
                           &SearchCount,
                           1L );                 /* reserved value    */

    TRACE4(TFUNC, "DosFindFirst result", &Result, 1);
    TRACE4(TFUNC, "Search count", &SearchCount, 1);

    /******************************************************************/
    /* Enable hard error pop-ups.  This clears the error condition.   */
    /* If this is not done then all subsequent disk accesses will     */
    /* fail.                                                          */
    /******************************************************************/
    (void)DosError( 0x01L );

    /******************************************************************/
    /* Return found code.                                             */
    /******************************************************************/
    switch ( Result )
    {
        case NO_ERROR:
            if ( SearchCount != 0 )
                RetCode = FILE_FOUND;
            else
                RetCode = FILE_NOT_FOUND;
            break;

        case ERROR_PATH_NOT_FOUND:
        case ERROR_NOT_READY:
        case ERROR_INVALID_DRIVE:
        case ERROR_INVALID_PATH:
        case ERROR_FILENAME_EXCED_RANGE:
            RetCode = PATH_NOT_FOUND;
            break;

        case ERROR_FILE_NOT_FOUND:
        case ERROR_INVALID_HANDLE:
        default:
            RetCode = FILE_NOT_FOUND;
            break;
    }

    return (RetCode);
}
#undef TFUNC






/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_CheckFileOKForPrinter                             */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PSZ           Path;                                              */
/*   PSZ           Filename;                                          */
/*   PSZ           Extension;                                         */
/*   USHORT        CheckByteNo;                                       */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   Checks if this file is OK for this driver and the current        */
/*   printer; it returns 1 if OK, 0 if not.  CheckByteNo is counted   */
/*   from 0.                                                          */
/*                                                                    */
/*   Path, Filename and Extension are null terminated                 */
/*   strings; Path and Extension can be empty.                        */
/*                                                                    */
/*   This version can handle files for the following drivers:         */
/*                                                                    */
/*           IBM4019  ..  Carson/Pimlico                              */
/*           IBM42XX  ..  PRO  (ProPrinters and 4224s)                */
/*           IBM52XX  ..  Q    (Quick, Quiet III and 3816)            */
/*                                                                    */
/* New format: 4019 files can now be in the same format as Pro & Q    */
/* ones. Old format files will only be allowed on the 4019 Laser-     */
/* printers, not on the Heritage printers.                            */
/**********************************************************************/
#if 0
USHORT pascal prdm_CheckFileOKForPrinter( Path,
                                          Filename,
                                          Extension,
                                          CheckByteNo )

PSZ              Path;
PSZ              Filename;
PSZ              Extension;
USHORT           CheckByteNo;
#endif

USHORT prdm_CheckFileOKForPrinter( PSZ    Path,            /* CON3201 */
                                   PSZ    Filename,        /* CON3201 */
                                   PSZ    Extension,       /* CON3201 */
                                   USHORT CheckByteNo )    /* CON3201 */

{
#define TFUNC "prdm_ChckFileOK"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    PBYTE            pDest;            /* Working pointers...         */
    PBYTE            pSource;          /*                    ...      */
    PBYTE            pExt;             /*                       ...   */
    PBYTE            Buffer;           /* Buffer for file data        */
//  USHORT           ActionTaken;      /* CON3201                     */
    ULONG            ActionTaken;      /* Parameter for DosOpen       */
    HFILE            FileHandle;       /* Handle of file              */
//  USHORT           BytesRead;        /* CON3201                     */
    ULONG            BytesRead;        /* Returned from DosRead       */
    USHORT           BytesToRead;
    BYTE             CheckByte;        /* Byte checked for driver     */
                                       /* flag                        */
    USHORT           Result;           /* Function call return values */
    USHORT           RetVal;           /* Value returned              */
    BYTE             PrinterType;      /* Type of the current printer */
    BYTE             FileDriverType;   /* File valid for this driver  */
    BYTE             FilePrinterType;  /* File valid for this printer */

    TRACE8(TFUNC, "Entry", FNULL, 0);

    /******************************************************************/
    /* Build the search path for the file.                            */
    /******************************************************************/
    pDest = SrcFileName;

    /******************************************************************/
    /* Start with the path if this not empty - add a backslash to     */
    /* the end if there isn't one already.                            */
    /******************************************************************/
    if ( Path )
    {
        for ( pSource = Path; *pSource != (BYTE)'\0'; )
            *pDest++ = *pSource++;

        if ( *(pDest - 1) != '\\' )
            *pDest++ = (BYTE)'\\';
    }

    /******************************************************************/
    /* Add on the filename - this should never be empty.              */
    /* Record the position of the extension if there is one.          */
    /******************************************************************/
    pExt = FNULL;
    for ( pSource = Filename; *pSource != (BYTE)'\0'; )
    {
        if ( *pSource == (BYTE)'.' )
            pExt = pDest;
        *pDest++ = *pSource++;
    }

    /******************************************************************/
    /* Add the extension if this not empty.  Start at the end of the  */
    /* filename if there is no extension already.                     */
    /******************************************************************/
    if ( Extension )
    {
        if ( pExt )
            pDest = pExt;

        for ( pSource = Extension; *pSource != (BYTE)'\0'; )
            *pDest++ = *pSource++;
    }

    /******************************************************************/
    /* Finish off with a null terminator.                             */
    /******************************************************************/
    *pDest = (BYTE)'\0';

    TRACE4(TFUNC, "Search path", SrcFileName, 10);

    /******************************************************************/
    /*                                                                */
    /* If this is a CDF file then the next three bytes contain        */
    /* flags.  The format of these is:                                */
    /*                                                                */
    /*  byte  1..  MS Bit  : 0 for Pimlico (old-style carson)         */
    /*                       1 for other                              */
    /*             LS Bits : Number of fonts in card                  */
    /*                                                                */
    /*  byte  2..  0 for PRO driver (IBM42XX)                         */
    /*             1 for Q driver (IBM52XX)                           */
    /*             2 for new style IBM4019       (NEW)                */
    /*             ( 3 - 255 reserved )                               */
    /*                                                                */
    /*  byte  3..     PRO driver      Q driver   new 4019 driver      */
    /*             0    9-wire          5202      Laserprinter        */
    /*             1   24-wire          5204      Heritage            */
    /*             2    4224            3816                          */
    /*             ( 3 - 255 reserved )                               */
    /*                                                                */
    /* If this is a FMF file then the next four bytes contain         */
    /* flags.  The format of these is:                                */
    /*                                                                */
    /*  word  1..  MS Bit  : 0 for Pimlico (old-style carson)         */
    /*                       1 for other                              */
    /*             LS Bits : Font pitch definition -                  */
    /*                          0 .. Proportional Space               */
    /*                      not 0 .. Fixed Pitch (actual width)       */
    /*                                                                */
    /*  byte  2..  0 for PRO driver (IBM42XX)                         */
    /*             1 for Q driver(IBM52XX)                            */
    /*             2 for new style IBM4019       (NEW)                */
    /*             ( 3 - 255 reserved )                               */
    /*                                                                */
    /*  byte  3..     PRO driver      Q driver    new 4019 driver     */
    /*             0    9-wire          5202       Laserprinter       */
    /*             1   24-wire          5204       Heritage           */
    /*             2    4224            3816                          */
    /*             ( 3 - 255 reserved .. except see below )           */
    /*                                                                */
    /*    The top three bits can be set for the 5202 and the 5204     */
    /*    and refer to whether the FMF "supports" the following       */
    /*    font qualities:                                             */
    /*             7   Enhanced  (5202 only)                          */
    /*             6   Quality   (5202 and 5204)                      */
    /*             5   Draft     (5202 and 5204)                      */
    /*                                                                */
    /* If this is a Pimlico file then bytes 2 and 3 are not there.    */
    /* (Pimlico = old-style carson file).                             */
    /* Note that the the indices of the Q's in the DDT matches the    */
    /* values in byte 3.                                              */
    /*                                                                */
    /******************************************************************/

    /******************************************************************/
    /* Allocate memory for the file info up to the first byte flag    */
    /* (in the case of a fixed pitch Pimlico FMF file this could be   */
    /* the last byte in the file).                                    */
    /******************************************************************/
/*  Result = SSALLOCSEG ( CheckByteNo + 1, &SELECTOROF(Buffer), 0 ); CON3201 */
    Result = SafeSSALLOCMEM ( &Buffer, (CheckByteNo + 1), 0 );

    if ( Result != DOS_OK )
        return(ERROR_ZERO);

/*  OFFSETOF(Buffer) = 0;                                            CON3201 */

    /******************************************************************/
    /* Open the file.                                                 */
    /******************************************************************/
    Result = DosOpen( SrcFileName,
                      (PHFILE)&FileHandle,
                      (PULONG)&ActionTaken,
                      0L,
                      0x1,              /* File attribute - read only */
                      1,                /* open flag - open if exists */
                      0x42,             /* open mode                  */
                      0L );             /* reserved                   */

    if ( Result != DOS_OK )
    {
        TRACE4(TFUNC, "DosOpen failed", FNULL, 0);
/*      SSFREESEG( SELECTOROF(Buffer) );                             CON3201 */
        SSFREEMEM( Buffer );
        return(ERROR_ZERO);
    }

    /******************************************************************/
    /* Read the file into the buffer up to the byte we need to check  */
    /* and store this byte.                                           */
    /******************************************************************/
    BytesToRead = CheckByteNo + 1;

    Result = DosRead( FileHandle,
                      (PVOID)Buffer,
                      BytesToRead,
                      &BytesRead );

    if ( (Result != DOS_OK) || (BytesRead != BytesToRead) )
    {
        TRACE4(TFUNC, "DosRead failed", FNULL, 0);
        RetVal = ERROR_ZERO;
        goto Error_Return;
    }

    /******************************************************************/
    /* get the check byte and set up the printer type.                */
    /******************************************************************/
    CheckByte   = *(Buffer + CheckByteNo);
    PrinterType = (BYTE)pDMSettings->PrinterType;

    TRACE4(TFUNC, "Check byte", &CheckByte, 1);


    /******************************************************************/
    /* Check if we've got a standard style file or an old style carson*/
    /* (Pimlico) file.                                                */
    /******************************************************************/
    if ( CheckByte & FILE_NOT_OLD_STYLE_CARSON )
    {
        /**************************************************************/
        /* Read in the next two bytes of flags.                       */
        /**************************************************************/
        BytesToRead = 2;

        Result = DosRead( FileHandle,
                          (PVOID)Buffer,
                          BytesToRead,
                          &BytesRead );

        if ( (Result != DOS_OK) || (BytesRead != BytesToRead) )
        {
            TRACE4(TFUNC, "DosRead failed", FNULL, 0);
            RetVal = ERROR_ZERO;
            goto Error_Return;
        }

        FileDriverType  = Buffer[0] & DRIVER_TYPE_MASK;
        FilePrinterType = Buffer[1] & PRINTER_TYPE_MASK;

        /**************************************************************/
        /* Is the file for the current driver?                        */
        /**************************************************************/
        if ((DRIVER_TYPE == DDT_IBM42XX_DRV) &&
                                 (FileDriverType != FILE_FOR_PRO))
        {
            RetVal = FILE_NOT_FOR_PRINTER;
        }
        else
        {
            /**********************************************************/
            /* OK its the current driver - is it for the current      */
            /* printer?                                               */
            /**********************************************************/
            if ( FileDriverType == FILE_FOR_PRO )
            {
                if ( PrinterType <= IBM_PRO_PRINTER_III_XL )
                {
                    if ( FilePrinterType == FILE_FOR_9_WIRE )
                        RetVal = FILE_OK_FOR_PRINTER;
                    else
                        RetVal = FILE_NOT_FOR_PRINTER;
                }
                else if ( PrinterType <= IBM_PRO_PRINTER_XL24E )
                {
                    if ( FilePrinterType == FILE_FOR_24_WIRE )
                        RetVal = FILE_OK_FOR_PRINTER;
                    else
                        RetVal = FILE_NOT_FOR_PRINTER;
                }
                else if ( (PrinterType == IBM_4224_COLOR) ||
                          (PrinterType == IBM_4224_MONO) )
                {
                    if ( FilePrinterType == FILE_FOR_4224 )
                        RetVal = FILE_OK_FOR_PRINTER;
                    else
                        RetVal = FILE_NOT_FOR_PRINTER;
                }
                else
                {
                    /**********************************************************/
                    /*  INKJET : Font Card support                            */
                    /**********************************************************/
                    if ( FilePrinterType == FILE_FOR_4072 )
                        RetVal = FILE_OK_FOR_PRINTER;
                    else
                        RetVal = FILE_NOT_FOR_PRINTER;
                }
            }
            else if ( FileDriverType == FILE_FOR_Q )
            {
                /******************************************************/
                /* Method OK since no CDFs for 3816s.                 */
                /******************************************************/
                if ( FilePrinterType == PrinterType )
                    RetVal = FILE_OK_FOR_PRINTER;
                else
                    RetVal = FILE_NOT_FOR_PRINTER;
            }
            else                   /* FileDriverType == FILE_FOR_4019 */
            {
                if ( PrinterType <= IBM_4019_LASER_E )
                {
                    if ( FilePrinterType == FILE_FOR_LASER )
                        RetVal = FILE_OK_FOR_PRINTER;
                    else
                        RetVal = FILE_NOT_FOR_PRINTER;
                }
                else
                {
                    if ( FilePrinterType == FILE_FOR_HERITAGE )
                        RetVal = FILE_OK_FOR_PRINTER;
                    else
                        RetVal = FILE_NOT_FOR_PRINTER;
                }
            }
        }
    }
    else
    {
        RetVal = FILE_NOT_FOR_PRINTER;
    }

Error_Return:
    /******************************************************************/
    /* Close the file.                                                */
    /******************************************************************/
    Result = DosClose ( FileHandle );

    /******************************************************************/
    /* Free the buffer memory.                                        */
    /******************************************************************/
/*  SSFREESEG( SELECTOROF(Buffer) );                                  CON3201 */
    SSFREEMEM(Buffer);

    /******************************************************************/
    /* Return RetVal.                                                 */
    /******************************************************************/
    TRACE8(TFUNC, "Return value", &RetVal, 1);
    return (RetVal);

}
#undef TFUNC







/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_CopyFMFFiles                                      */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   Standard dialog box control procedure parameter block            */
/*                                                                    */
/*   HWND    hwnd;                                                    */
/*   PBYTE   TargetDirectory                                          */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function copies a CDF file and its associated FMF files.    */
/*   The source directory is contained in the external SrcDirBuffer.  */
/*                                                                    */
/**********************************************************************/
#if 0
USHORT pascal prdm_CopyFMFFiles( hwnd,
                                 TargetDirectory )

HWND   hwnd;
PBYTE  TargetDirectory;
#endif

USHORT prdm_CopyFMFFiles( HWND  hwnd,                      /* CON3201 */
                          PBYTE TargetDirectory )          /* CON3201 */

{
#define TFUNC "prdm_CopyFMFs"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    BYTE       NoOfFMFs;          /* Number of FMF files              */
    BYTE       FMFNameBuffer[13];
    USHORT     i, j;              /* Loop variables                   */
    USHORT     Result;            /* Function call return values      */
    USHORT     DosResult;
    PBYTE      pSource;           /* Working pointer                  */
    USHORT     FileSize;
    BOOL       OldCDFStruc;
    lpCDFFileStruc    pCDFData;


    /******************************************************************/
    /* Read in the CDF file data                                      */
    /******************************************************************/
    Result = prdm_ReadFileContents( SrcDirBuffer,
                                    DMData.CDFName,
                                    FNULL,
                                    &FileSize,
                                 /* (PBYTE far *)&pCDFData ); */
                                    (PBYTE *)&pCDFData );  /* CON3201 */

    if ( Result != NO_ERROR )
    {
        TRACE6(TFUNC, "Read file failed", &Result, 1);
        return (Result);
    }

    /******************************************************************/
    /* Get the number of FMFs - beware of the fact that the top bit   */
    /* is used as a flag.                                             */
    /******************************************************************/
    NoOfFMFs = pCDFData->FMFCount & CDF_NO_OF_FMFS_MASK;

    OldCDFStruc =
          !(pCDFData->FMFCount & FILE_NOT_OLD_STYLE_CARSON);

    /******************************************************************/
    /* Copy each of the FMF files in turn.                            */
    /******************************************************************/
    for ( i = 0; i < NoOfFMFs; i++ )
    {
        /**************************************************************/
        /* Null terminate the file name.                              */
        /**************************************************************/
        if ( OldCDFStruc )
            pSource = ((lpOldCDFFileStruc)pCDFData)->
                                           FMFEntryArray[i].FMFName;
        else
            pSource = pCDFData->FMFEntryArray[i].FMFName;

        for ( j = 0;
              (j < FILENAME_SIZE) && (*pSource != ' ');
              j++, pSource++ )
        {
             FMFNameBuffer[j] = *pSource;
        }

        FMFNameBuffer[j] = '\0';

        /**************************************************************/
        /* Copy the FMF file from the source directory to the target  */
        /* directory.                                                 */
        /**************************************************************/
        DosResult = prdm_CopyFile( SrcDirBuffer,
                                   TargetDirectory,
                                   FMFNameBuffer,
                                   FMFNameBuffer,
                                   FNULL );

        if ( DosResult != NO_ERROR )
        {
            TRACE6(TFUNC, "Copy FMF failed", &Result, 1);
            return (IDS_CANT_COPY);
        }
    }

    /******************************************************************/
    /* Free the memory containing the CDF data (allocated in          */
    /* prdm_ReadFileContents).                                        */
    /******************************************************************/
/*  SSFREESEG( SELECTOROF(pCDFData) );                                CON3201 */
    SSFREEMEM( pCDFData );

    /******************************************************************/
    /* Now copy the CDF file.from the source directory to the target  */
    /******************************************************************/
    DosResult = prdm_CopyFile( SrcDirBuffer,
                               TargetDirectory,
                               DMData.CDFName,
                               DMData.CDFName,
                               FNULL );

    if ( DosResult != NO_ERROR )
    {
        TRACE6(TFUNC, "Copy CDF failed", &Result, 1);
        return (IDS_CANT_COPY);
    }

    /******************************************************************/
    /* Let's go                                                       */
    /******************************************************************/
    TRACE6(TFUNC, "Exit OK", FNULL, 0);
    return (NO_ERROR);
}
#undef TFUNC





/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_StringsAreEqual                                   */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PSZ        pszSource;                                            */
/*   PSZ        pszTarget;                                            */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function compares two strings ignoring the case of the      */
/*   characters 'a' - 'z'.  It returns TRUE if the strings are the    */
/*   same; FALSE if not.                                              */
/*                                                                    */
/**********************************************************************/
#if 0
BOOL pascal far prdm_StringsAreEqual( pszSource,
                                      pszTarget )

PSZ      pszSource;
PSZ      pszTarget;
#endif

BOOL prdm_StringsAreEqual( PSZ pszSource,                  /* CON3201 */
                           PSZ pszTarget )                 /* CON3201 */

{
    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    BYTE     Source;
    BYTE     Target;

    if ( prdu_strlen((PBYTE)pszSource) !=
         prdu_strlen((PBYTE)pszTarget) )
    {
        return(FALSE);
    }

    for ( ; *pszSource; pszSource++, pszTarget++ )
    {
        Source = (BYTE)*pszSource;
        Target = (BYTE)*pszTarget;

        /**************************************************************/
        /* Force upper case letters before doing the compare.         */
        /**************************************************************/
        if ( Source >= (BYTE)'a' && Source <= (BYTE)'z' )
            Source -= (BYTE)('a' - 'A');

        if ( Target >= (BYTE)'a' && Target <= (BYTE)'z' )
            Target -= (BYTE)('a' - 'A');

        if ( Source != Target )
            return(FALSE);
    }

    return(TRUE);
}



/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_ReadFontResource                                  */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   lpFMFFileStruc far * ppFMFData;                                  */
/*   USHORT              ResourceId;                                  */
/*   PBOOL               pUseFlag;                                    */
/*   USHORT              NoDefinedFonts;     how many fonts in Res    */
/*                                           FontList to look through */
/*                                           to find the real FMF if  */
/*                                           this is a dummy FMF.     */
/*   lpFMFFontList       ResFontList;        list of fonts to look    */
/*                                           through.                 */
/*   lpDDTType           pDDT;                                        */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/* This routine grabs an FMF resource, gets a real FMF from a         */
/* dummy, and for the 4019 driver translates the FMF into the         */
/* Pro & Q FMF format.                                                */
/*                                                                    */
/* Note: currently we never free the FMF resources. It should be      */
/* done using DosFreeResource, unless the fonts are from 4019 in      */
/* which case use FreeGlobalHeapItem.                                 */
/**********************************************************************/
#if 0
USHORT pascal prdm_ReadFontResource( ppFMFData,
                                     ResourceId,
                                     pUseFlag,
                                     NoDefinedFonts,
                                     ResFontList,
                                     pDDT )
lpFMFFileStruc far *ppFMFData;
USHORT              ResourceId;
PBOOL               pUseFlag;
USHORT              NoDefinedFonts;
lpFMFFontList       ResFontList;
lpDDTType           pDDT;
#endif

USHORT prdm_ReadFontResource( lpFMFFileStruc *ppFMFData,      /*CON3201*/
                              USHORT          ResourceId,     /*CON3201*/
                              PBOOL           pUseFlag,       /*CON3201*/
                              USHORT          NoDefinedFonts, /*CON3201*/
                              lpFMFFontList   ResFontList,    /*CON3201*/
                              lpDDTType       pDDT )          /*CON3201*/

{
#define TFUNC "prdm_ReadFontResource"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    USHORT            Result;          /* Result of functions calls   */
    USHORT            j;               /* Loop variable               */
    PBYTE             pResourceFMF;
    PBYTE             pResourceFMFTemp;
    lpFMFFileStruc    pValidFMF;
    USHORT            FMFFileSize;
    USHORT            NoOfChangeBytes;
    USHORT            usByteOffset;
    BYTE              ByteValue;
    PBYTE             FilePtr;
    USHORT            PrinterType;

    /******************************************************************/
    /* Pick up the metrics from resources.                            */
    /*                                                                */
    /* Commented Out : ( MJB 10/11/90 )                               */
    /* Note on future versions we should use DosGetResource2, and     */
    /* we should free resources with DosFreeResource (see MS ref bk   */
    /* vol 4).                                                        */
    /******************************************************************/
#if 0
//  Result = DosGetResource2( (HMODULE)prdd_ModHandle,
//                            (USHORT)1000,
//                            ResourceId,
//                            (PVOID FAR *)&pResourceFMF );
#endif

    Result = DosGetResource( (HMODULE)prdd_ModHandle,
                             (USHORT)1000,
                             (USHORT)ResourceId,
                             (PPVOID)&pResourceFMF );
/*                           (PSEL)&SELECTOROF(pResourceFMF) );      CON3201 */

/*  OFFSETOF (pResourceFMF) = 0;                                     CON3201 */

    if ( Result != DOS_OK )
    {
        TRACE6(TFUNC, "DosGetRes failed", FNULL, 0);
        return (ERROR_ZERO);
    }

    /******************************************************************/
    /* DEBUG_SEGMENTS : AK - this flag now just indicates whether a   */
    /* segment is allocted.                                           */
    /******************************************************************/
    if (pUseFlag)
    {
        *pUseFlag = FALSE;
    }

    /******************************************************************/
    /* Check first byte of resource to see if this is a MultiCp FMF.  */
    /* If it is then set the return FMF pointer to skip first 3 bytes.*/
    /******************************************************************/
    if ( pResourceFMF[0] == MULTICP_FMF_VALUE )
    {
        *ppFMFData = (lpFMFFileStruc)(pResourceFMF + 3);
        return OK;
    }

    /******************************************************************/
    /* Save the address for the future                                */
    /******************************************************************/
    pResourceFMFTemp = pResourceFMF;


    /**************************************************************/
    /* If the FMF file is not a dummy and the metrics             */
    /* pointer has been set already then we do need to reset the  */
    /* pointer since the segment previously returned from         */
    /* DosGetResource could have become invalid.                  */
    /*                                                            */
    /* If the FMF file for this font is a dummy then if the       */
    /* metrics pointer has been set already we dont need to       */
    /* reset it; it has not been set already then we need to do   */
    /* some work.                                                 */
    /**************************************************************/
    if(( pResourceFMF[DUMMY_FMF_CHECK_BYTE] == DUMMY_FMF_CHECK_VALUE_FF ) ||
       ( pResourceFMF[DUMMY_FMF_CHECK_BYTE] == DUMMY_FMF_CHECK_VALUE_FE ) ||
       ( pResourceFMF[DUMMY_FMF_CHECK_BYTE] == DUMMY_FMF_CHECK_VALUE_FC ))
    {
        /**************************************************************/
        /* Dummy FMF.                                                 */
        /**************************************************************/

        /**********************************************************/
        /* Pick up the resource id for the valid FMF.             */
        /* The FMF indices start from 0; the resource ids         */
        /* start from 1 (since 0 is invalid) hence the            */
        /* factor of 1.                                           */
        /**********************************************************/
        if ( pResourceFMF[DUMMY_FMF_CHECK_BYTE] == DUMMY_FMF_CHECK_VALUE_FC )
            ResourceId = *(PUSHORT)(pResourceFMF + DUMMY_FMF_RES_INDEX) + 1;
        else
            ResourceId = *(pResourceFMF + DUMMY_FMF_RES_INDEX) + 1;
        TRACE6(TFUNC, "New resource id", &ResourceId, 1);

        PrinterType = pDMSettings->PrinterType;                   /*PD00375*/

        /**********************************************************/
        /* Search through previous entries in the font list       */
        /* to find the one whose metrics we will use as a         */
        /* base.                                                  */
        /**********************************************************/
        for ( j = 0; j < NoDefinedFonts; j++ )
        {
            /**************************************************************/
            /* PD00375: If its a nile/tiber the resident font list is not */
            /* set up in globlal DDTs, so use the ones in global data.    */
            /**************************************************************/
            if ( (DRIVER_TYPE == DDT_IBM42XX_DRV) &&
                 (pDDT->DDTFontFlags & DDT_NLS_FONTS_OPTIONAL) )
            {
                if ( (PrinterType == IBM_NILE_9) ||
                     (PrinterType == IBM_TIBER_9) )
                {
                    if (pDMSettings->MachineType == NLS_MACHINE)
                    {
                        if ( DVTFontList9WireNLS[j]->ResourceId == ResourceId )
                            break;
                    }
                    else
                    {
                        if ( DVTFontList9Wire[j]->ResourceId == ResourceId )
                            break;

                    }
                }

                if ( (PrinterType == IBM_NILE_24) ||
                     (PrinterType == IBM_TIBER_24) )
                {
                    if (pDMSettings->MachineType == NLS_MACHINE)
                    {
                        if ( DVTFontList24WireNLS[j]->ResourceId == ResourceId )
                            break;
                    }
                    else
                    {
                        if ( DVTFontList24Wire[j]->ResourceId == ResourceId )
                            break;
                    }
                }
            }
            else
            {
                if ( pDDT->DDTFontList[j]->ResourceId == ResourceId )
                    break;
            }
        }

        if ( j == NoDefinedFonts )
        {
            TRACE8(TFUNC, "Bad ResourceId", FNULL, 0);
            return (ERROR_ZERO);
        }

        TRACE6(TFUNC, "Index for base", &j, 1);

        pValidFMF = (lpFMFFileStruc)ResFontList[j].FMFAddress;

        /**********************************************************/
        /* Check the size of the valid FMF file and               */
        /* allocate space for it.                                 */
        /**********************************************************/
        if ( (pValidFMF->WidthFlag & FMF_WIDTH_MASK) == 0 )
            FMFFileSize = FMF_SIZE_PROP_SPACED;
        else
            FMFFileSize = FMF_SIZE_FIXED_PITCH;

        TRACE6(TFUNC, "FMF file size", &FMFFileSize, 1);

     /* CON3201 ************************************************/
     /* Result = SSALLOCSEG( FMFFileSize,                      */
     /*                      &SELECTOROF(*ppFMFData),          */
     /*                      0 );                              */
     /**********************************************************/

        Result = SafeSSALLOCMEM( &(*ppFMFData),
                                FMFFileSize,
                                0 );

        if ( Result != DOS_OK )
        {
            TRACE6(TFUNC, "SSALLOCSEG error", FNULL, 0);
            return ERROR_ZERO;
        }

/*      OFFSETOF(*ppFMFData) = 0;                                    CON3201 */

        /**************************************************************/
        /* DEBUG_SEGMENTS : AK - this flag now just indicates whether */
        /* a segment is allocted.                                     */
        /**************************************************************/
        if (pUseFlag)
        {
            *pUseFlag = TRUE;
        }


        /**********************************************************/
        /* Copy across the FMF data we use as a base.             */
        /**********************************************************/
        TRACE6(TFUNC, "Copy FMF across", FNULL, 0);

        prdu_memcpy( (PBYTE) *ppFMFData,
                     (PBYTE) pValidFMF,
                     FMFFileSize );

        /**********************************************************/
        /* Position pDummyFMFData to point to the start of        */
        /* the change info.                                       */
        /* Find out the number of bytes we need to change.        */
        /**********************************************************/
        if(pResourceFMFTemp[DUMMY_FMF_CHECK_BYTE] == DUMMY_FMF_CHECK_VALUE_FC)
            pResourceFMF += DUMMY_FMF_NO_OF_PAIRS_FC;
        else
            pResourceFMF += DUMMY_FMF_NO_OF_PAIRS;

        NoOfChangeBytes = *pResourceFMF++;

        TRACE6(TFUNC, "No of change bytes", &NoOfChangeBytes, 1);

        /**********************************************************/
        /* Change the Code Page metrics according to the           */
        /* data in the dummy FMF file.                            */
        /**********************************************************/

        if( (pResourceFMFTemp[DUMMY_FMF_CHECK_BYTE] ==
                                        DUMMY_FMF_CHECK_VALUE_FE) ||
          (pResourceFMFTemp[DUMMY_FMF_CHECK_BYTE] ==
                                        DUMMY_FMF_CHECK_VALUE_FC) )
        {
            for ( j = 0; j < NoOfChangeBytes; j++ )
            {
                usByteOffset = *pResourceFMF++;
                usByteOffset += ((*pResourceFMF) * 256) ;

                /**************************************************************/
                /* PD00595 : Add if stmt to check for Multi Codepage FMF      */
                /**************************************************************/
                if ( pValidFMF->Metrics.usCodePage == 0 )
                {
                    /**********************************************************/
                    /* This is a Multi codepage FMF type 0xFD that has been   */
                    /* compressed.  The index is 3 too large due to the 3     */
                    /* bytes at the beginning of a 0xFD FMF that are ignored, */
                    /* so subtract 3 from the index to get the memory offset  */
                    /* that needs to be updated.                              */
                    /**********************************************************/
                    usByteOffset -= 3;
                }

                pResourceFMF++;
                ByteValue  = *pResourceFMF++;

                ((PBYTE)*ppFMFData)[usByteOffset] = ByteValue;
            }
        }
        else     /* DUMMY_FMF_CHECK_VALUE_FF */
        {
            for ( j = 0; j < NoOfChangeBytes; j++ )
            {
                usByteOffset = *pResourceFMF++;
                ByteValue  = *pResourceFMF++;

                ((PBYTE)*ppFMFData)[usByteOffset] = ByteValue;
            }
        }

        /**********************************************************/
        /* Free the dummy FMF resource: only if it was got using  */
        /* DosGetResource2.                                       */
        /**********************************************************/
/*      DosFreeResource ( pResourceFMF ); */
    }
    else
    {
        /**************************************************************/
        /* Valid FMF.                                                 */
        /**************************************************************/
        *ppFMFData = (lpFMFFileStruc)pResourceFMF;

        /**************************************************************/
        /* We're done, unless this in an old style carson (Pimlico)   */
        /* FMF. See CheckFileOKForPrinter (above) for formats.        */
        /**************************************************************/
        if (pResourceFMF[ FMF_STYLE_CHECK_BYTE ]
                                            & FILE_NOT_OLD_STYLE_CARSON)
        {
            return OK;
        }

        /**************************************************************/
        /* The old style structure needs to be translated into the    */
        /* standard structure.                                        */
        /*                                                            */
        /* Get size needed.                                           */
        /**************************************************************/
        if ( (((lpFMFFileStruc)pResourceFMF)->WidthFlag
                                                & FMF_WIDTH_MASK) == 0 )
            FMFFileSize = FMF_SIZE_PROP_SPACED;
        else
            FMFFileSize = FMF_SIZE_FIXED_PITCH;

        /**************************************************************/
        /* Get mem to store translated FMF.                           */
        /**************************************************************/

     /* CON3201 *********************************************/
     /* Result = SSALLOCSEG( FMFFileSize,                   */
     /*                      &SELECTOROF(*ppFMFData),       */
     /*                      0 );                           */
     /*******************************************************/

        Result = SafeSSALLOCMEM( &(*ppFMFData),
                             FMFFileSize,
                             0 );

        if ( Result != DOS_OK )
        {
            TRACE6(TFUNC, "SSALLOCMEM error", FNULL, 0);
            return ERROR_ZERO;
        }

/*      OFFSETOF(*ppFMFData) = 0;                            CON3201 */

        /**************************************************************/
        /* DEBUG_SEGMENTS : AK - this flag now just indicates whether */
        /* a segment is allocted.                                     */
        /**************************************************************/
        if (pUseFlag)
        {
            *pUseFlag = TRUE;
        }

        /**************************************************************/
        /* Copy across the first 182 bytes.                           */
        /**************************************************************/
        prdu_memcpy( (PBYTE)*ppFMFData,
                     (PBYTE)pResourceFMF,
                     FMF_SIZE_4019_COMMON );

        FilePtr = (PBYTE)*ppFMFData + FMF_SIZE_4019_COMMON;

        /**************************************************************/
        /* Write the correct values into the next 2 bytes             */
        /* (PrinterType and DriverType) and reset the style flag.     */
        /*                                                            */
        /* The PrinterType value takes advantage of the fact that     */
        /* there are only 2 possible values of it in the new style    */
        /* 4019 files: 0 for the Laserprinters and 1 for the Heritage */
        /* printers.                                                  */
        /**************************************************************/
        *(FilePtr - 1) |= FILE_NOT_OLD_STYLE_CARSON;

        *FilePtr++ = FILE_FOR_4019;
        *FilePtr++ = (BYTE)(pDMSettings->PrinterType > IBM_4019_LASER_E);

        if ( FMFFileSize == FMF_SIZE_PROP_SPACED )
        {
            /**********************************************************/
            /* Write the rest of the FMF (width table for PS fonts).  */
            /**********************************************************/
            prdu_memcpy( (PBYTE)FilePtr,
                         (PBYTE)(pResourceFMF + FMF_SIZE_4019_COMMON),
                         FMF_SIZE_4019_RESIDUE );
        }
        /**************************************************************/
        /* Free the resource for the special 4019 case: only if the   */
        /* resource was got using DosGetResource2.                    */
        /**************************************************************/
/*      DosFreeResource ( pResourceFMF ); */
    }
    return OK;
}
#undef TFUNC


