/*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 = PRDMCONV
 *
 * DESCRIPTIVE NAME =
 *
 *
 * VERSION
 *
 * DATE
 *
 * DESCRIPTION
 *
 * FUNCTIONS   DrvInstall
 *             prdm_ConvertOldIniToNew
 *             prdm_ReadTerminatedWordFromText
 *
 * 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_DOSSEMAPHORES
#define INCL_WINWINDOWMGR
#define INCL_GPIERRORS
#define INCL_SHLERRORS
#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_WINPOINTERS
#define INCL_DEV
#define INCL_DOSMISC
#include <os2.h>
#undef INCL_DOSPROCESS                  /* Convert to C/SET2    CON3201       */
#undef INCL_DOSSEMAPHORES
#undef INCL_WINWINDOWMGR
#undef INCL_GPIERRORS
#undef INCL_SHLERRORS
#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_WINPOINTERS
#undef INCL_DEV
#undef INCL_DOSMISC

#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 */
#undef  INCL_WINSHELLDATA                                          /* CON3201 */

#include <prddcone.h>
#include <prdmcone.h>
#include <prdconse.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 <prdmextf.h>
#include <prdeextf.h>                            /* PD00208          */
#include <prdyextf.h>
#include <prduextf.h>
#include <prdmtrcf.h>
#define INCL_SPLDOSPRINT                /* Convert to C/SET2    CON3201       */
#include <pmspl.h>                                /* PD00280          */
#undef  INCL_SPLDOSPRINT                /* Convert to C/SET2    CON3201       */
#undef INCL_32                          /* Convert to C/SET2    CON3201       */


/**********************************************************************/
/* Declarations of global data structures.                            */
/**********************************************************************/


/**********************************************************************/
/* Set up external accesses                                           */
/**********************************************************************/
extern USHORT                 DEFAULT_PRINTER;
extern USHORT                 NO_OF_PRINTERS;
extern PCHAR                  OS2_INI_VERSION;
extern PCHAR                  DriverNameString;
extern HMODULE                prdd_ModHandle;
extern USHORT                 DRIVER_TYPE;

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: DrvInstall                                             */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function is an entry point into the device driver.  It is   */
/*   accessed from the OS/2 Printer Install or CSD Install. It calls  */
/*   prdm_ConvertOldIniToNew which converts the old OS2.INI format    */
/*   to new format.                                                   */
/*                                                                    */
/**********************************************************************/
#if 0
VOID pascal far _loadds DrvInstall( )
#endif

VOID DrvInstall( )                                         /* CON3201 */

{
#define TFUNC "DrvInstall"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
USHORT     Result;
BOOL       DeleteOldDriver;

    DeleteOldDriver = TRUE;
    Result = prdm_ConvertOldIniToNew(DeleteOldDriver);
    return;
}
#undef TFUNC

/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_ConvertOldIniToNew                                */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/*   This function will split the PM_SPOOLER_DD entry into seperate   */
/*   ones.                                                            */
/*   For each printer type in the PM_SPOOLER_DD entry there will be   */
/*   a new PM_SPOOLER_DD entry. The new entry will contain all the    */
/*   printer names for that type. A keyname (drivername.printer_type) */
/*   will be associated to this entry. The version number will be     */
/*   updated and the printer data will be expanded to a new format.   */
/*   If we find our driver name in the PM_SPOOLER_PRINTER entry       */
/*   associated with the logical printer name defined in the          */
/*   PM_SPOOLER_DD. If we find  our driver_name then we will replace  */
/*   it with "driver_name.selected_printer_type".                     */
/*                                                                    */
/*   Example of old PM_SPOOLER_PRINTER entry:                         */
/*                  LPT1;LASERJET.Laserjet II,IBM42XX;LPT1Q;;         */
/*                                                                    */
/*   Example of new PM_SPOOLER_PRINTER entry:                         */
/*               LPT1;LASERJET.Laserjet II,IBM42XX.PRO III XL;LPT1Q;; */
/*                                                                    */
/*  For each logical printer name read PM_SPOOLER_PRINTER. If there   */
/*  is a entry with our driver name (not "drivername.printer_type")   */
/*  then replace it with "drivername.default_printer".                */
/*  Change the PM_SPOOLER_QUEUE_DD entry.                             */
/*  First pass: Read the first queue name in the PM_SPOOLER_PRINTER   */
/*  (entry. Using the queue name read the PM_SPOOLER_QUEUE_DD.        */
/*  If our driver name is in there then                               */
/*  replace it with the one in the PM_SPOOLER_PRINTER.                */
/*  Second pass: for each queue name read the PM_SPOOLER_QUEUE_DD     */
/*  entry. If there is a entry with our driver name                   */
/*  not "drivername.printer_type")                                    */
/*  then replace it with "drivername.default_printer".                */
/*                                                                    */
/**********************************************************************/
#if 0
USHORT pascal prdm_ConvertOldIniToNew( DeleteOldDriver )

BOOL          DeleteOldDriver;
#endif

USHORT prdm_ConvertOldIniToNew( BOOL DeleteOldDriver )     /* CON3201 */

{
#define TFUNC "prdm_ConvertOldIniToNew"

    /******************************************************************/
    /* Local Variables                                                */
    /******************************************************************/
    ULONG     IniSize;         /* The size of the entry in OS2.INI    */
                               /* for the printer driver              */
    ULONG     QSize;           /* The size of the entry in PM_Q_DDDATA*/
                               /* PD00280                             */
    USHORT    DriverDataSize;  /* The size of driver data  PD00301    */
    USHORT    IniSize1;        /* The size of the entry in OS2.INI    */
    USHORT    BufferSize;      /* The size of the entry required in   */
                               /* OS2.INI after any changes           */
    USHORT    QDDSize;         /* The size of the entry required in   */
                               /* OS2.INI after any changes           */
    USHORT    Result;          /* Function call return values         */
    PBYTE     IniData;         /* Pointer into the OS2.INI file for   */
                               /* reading its contents                */
    PBYTE     PrevStartPtr;    /* Pointers used to copy information   */
    PBYTE     StartPtr;        /* Pointers used to copy information   */
    PBYTE     pDest;           /* Pointers used to copy information   */
    PBYTE     pDestSave;       /* Pointers used to copy information   */
    PBYTE     pSource;         /* back into OS2.INI                   */
    PBYTE     VersionStart;    /* Start of the printer name in OS2.INI*/
    PBYTE     NameStart;       /* Start of the printer name in OS2.INI*/
    PBYTE     NewDriverData;   /* pointer to start of new driver data */
    PBYTE     pTarget;         /* pointer to start of new driver data */
    PDRIVDATA DriverData;      /* New driver data PD00301             */
    SHORT     i, j, k;         /* Loop control variables              */
    USHORT    SearchState;     /* The current state of the search for */
                               /* the printer name                    */
    PBYTE     OldIniBuffer;    /* Copy of OS2.INI entry , old format  */
    PBYTE     OldIniBuffer1;   /* Copy of OS2.INI entry , old format  */
    PBYTE     IniBufferQDD;    /* Copy of OS2.INI entry , old format  */
    PBYTE     IniQDDData;      /* Copy of OS2.INI entry , old format  */
    PBYTE     OldQDDData;      /* Copy of OS2.INI entry , old format  */
    PBYTE     NewQDDData;      /* Copy of OS2.INI entry , old format  */
    PPRQINFO3 QDDData_Old;     /* Copy of OS2.INI entry , old format  */
    PPRQINFO3 QDDData_New;     /* Copy of OS2.INI entry , old format  */
    PBYTE     NewIniBuffer;    /* Copy of OS2.INI entry , new format  */
    PBYTE     KeyNameBuffer;   /* to store all key names              */
    PBYTE     TempBuffer;      /*                                     */
    PBYTE     KeyName;         /*                                     */
    USHORT    RetVal;          /* The value to return at the end of   */
                               /* tis routine.                        */
    USHORT    LPNameCnt;       /* Logical printer name counter        */
    USHORT    SelectedPrinter; /* Currently selected printer          */
    USHORT    PrinterType;     /* Printer type being handled          */
    USHORT    PrinterModel;    /* Printer type being handled          */
    USHORT    TypeEntryLen;    /* The length of the INI entry for a   */
                               /* particular printer type.            */
    PCHAR     pszIniVersion;
    ULONG     ulIniVersion;
    USHORT    DosResult;
/*  CON3201
**  PFN       pPrfQueryProfSz;
**  PFN       pPrfQueryProfData;
**  PFN       pPrfWriteProfString;
**  PFN       pPrfWriteProfData;
**  PFN       pDosPrintQSetInfo;
*/  PFN       pDosPrintQGetInfo;
    HMODULE   ModuleHandle;
    BOOL      ModuleOK;
    CHAR      Prntr_Name_Buf[MAX_PRNTR_NAME];
    CHAR      Prntr_Name_Dflt[MAX_PRNTR_NAME];
    CHAR      DeviceName_KeyWord[MAX_PRNTR_NAME+DRIVER_NAME_LEN+1];
    SHORT     IniVersionType;
    BOOL      PM_SP_DD_ByPass;
    BOOL      PM_SP_DD_Write;
    BOOL      WriteQueueDD;
    LPNInfoType LPNInfo[100];
    BYTE      Terminator;
    BYTE      pszWord[100];
    BYTE      VersionBuf[5];
    BOOL      OS2Level;                /* True >= OS2 1.3, False = OS2 1.2 */
    ERRORID   Error;
    BOOL      OldDriverExist;
/* CON3201 - This variable is not used anywhere                            */
/*  USHORT    Version;                    OS2 Version Number  PD00591      */

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

    WriteQueueDD = FALSE;

    for ( i = 0; i < 100; i++ )
    {
        LPNInfo[i].PrinterInfoFlag = 0;
    }

    /******************************************************************/
    /* Set up the return value.  Set the pointers to any memory which */
    /* may be allocated to Null to allow controlled exit on an error  */
    /* (through Error_Return label).                                  */
    /******************************************************************/
    RetVal = (USHORT)IDS_CONVERSION_COMP;

    OldIniBuffer    = FNULL;
    OldIniBuffer1   = FNULL;
    IniBufferQDD    = FNULL;
    NewIniBuffer    = FNULL;
    KeyNameBuffer   = FNULL;
    IniQDDData      = FNULL;                /* PD00607                */

    /******************************************************************/
    /* Set up the buffer for PM_SPOOLER_DD. PD00208                   */
    /******************************************************************/
    prdu_strcpy(pszWord,DriverNameString);
    pszWord[DRIVER_NAME_LEN]   = '.';
    pszWord[DRIVER_NAME_LEN+1] = 'D';
    pszWord[DRIVER_NAME_LEN+2] = 'R';
    pszWord[DRIVER_NAME_LEN+3] = 'V';
    pszWord[DRIVER_NAME_LEN+4] = ';';
    pszWord[DRIVER_NAME_LEN+5] = ';';
    pszWord[DRIVER_NAME_LEN+6] = ';';
    pszWord[DRIVER_NAME_LEN+7] = '\0';


    /******************************************************/
    /* Get the OS version. PD00591                        */
    /******************************************************/
 /* CON3201 Version is not used anywhere in this routine */
 /* DosGetVersion(&Version);                             */

    /******************************************************************/
    /* Set up the Version.                             PD00208        */
    /******************************************************************/
    prdu_strcpy( VersionBuf, OS2_INI_VERSION );
    *(VersionBuf + 3) = ';';
    *(VersionBuf + 4) = '\0';

    /******************************************************************/
    /* Set up the prefix part of the device name.                     */
    /******************************************************************/
    prdu_strcpy(DeviceName_KeyWord,DriverNameString);
    DeviceName_KeyWord[DRIVER_NAME_LEN] = '.';

    /******************************************************************/
    /* description string from the RC  file.                          */
    /******************************************************************/
    WinLoadString( hab,
                   prdd_ModHandle,
                   IDS_FIRST_PRINTER + DEFAULT_PRINTER,
                   MAX_PRNTR_NAME,
                   (PSZ)Prntr_Name_Dflt );

    /******************************************************************/
    /* Calcuate the hex value of the IniVersion from the              */
    /* OS2_INI_VERSION string.                                        */
    /******************************************************************/
    pszIniVersion = OS2_INI_VERSION;
    ulIniVersion = 0;
    while (*pszIniVersion)
    {
        ulIniVersion = (ulIniVersion << 4) + (*pszIniVersion++ - '0');
    }

    /******************************************************************/
    /* Get hold of a segment to store our copy of the driver data     */
    /* from the OS2.INI file.                                         */
    /******************************************************************/

    BufferSize = 65535;                     /* 64K                    */

 /* Result = SSALLOCSEG( BufferSize, &SELECTOROF(OldIniBuffer1), 0 ); */
    Result = SafeSSALLOCMEM( &OldIniBuffer1, BufferSize, 0 );  /* CON3201 */

    if ( Result != DOS_OK )
    {
         RetVal = (USHORT)IDS_CONVERSION_NO_BUFFER;
         goto Error_Return;
    }

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

    /******************************************************************/
    /* Get hold of a segment to store the new copy of the driver data.*/
    /******************************************************************/

    BufferSize = 65535;                     /* 64K                    */

 /* Result = SSALLOCSEG( BufferSize, &SELECTOROF(NewIniBuffer), 0 ); */
    Result = SafeSSALLOCMEM( &NewIniBuffer, BufferSize, 0 );   /* CON3201 */

    if ( Result != DOS_OK )
    {
         RetVal = (USHORT)IDS_CONVERSION_NO_BUFFER;
         goto Error_Return;
    }

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


    /******************************************************************/
    /* Get hold of a segment to store all the PM_SPOOLER_PRINTER key  */
    /* names.                                                         */
    /******************************************************************/

    BufferSize = 65535;                     /* 64K                    */

 /* Result = SSALLOCSEG( BufferSize, &SELECTOROF(KeyNameBuffer), 0 ); */
    Result = SafeSSALLOCMEM( &KeyNameBuffer, BufferSize, 0 );  /* CON3201 */

    if ( Result != DOS_OK )
    {
         RetVal = (USHORT)IDS_CONVERSION_NO_BUFFER;
         goto Error_Return;
    }

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

    /******************************************************************/
    /* Get hold of a segment to store our copy of the                 */
    /* PM_SPOOLER_QUEUE_DDData from the OS2.INI file.                 */
    /******************************************************************/

    BufferSize = 5000;                      /* 5000 bytes             */

 /* Result = SSALLOCSEG( BufferSize, &SELECTOROF(IniQDDData), 0 ); */
    Result = SafeSSALLOCMEM( &IniQDDData, BufferSize, 0 );     /* CON3201 */

    if ( Result != DOS_OK )
    {
         RetVal = (USHORT)IDS_CONVERSION_NO_BUFFER;
         goto Error_Return;
    }

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

    /******************************************************************/
    /* Get hold of a segment to store our copy of the                 */
    /* PM_SPOOLER_QUEUE_DD from the OS2.INI file.                     */
    /******************************************************************/

    QDDSize = 100;                          /* 100 bytes              */

 /* Result = SSALLOCSEG( QDDSize, &SELECTOROF(IniBufferQDD), 0 ); */
    Result = SafeSSALLOCMEM( &IniBufferQDD, QDDSize, 0 );      /* CON3201 */

    if ( Result != DOS_OK )
    {
         RetVal = (USHORT)IDS_CONVERSION_NO_BUFFER;
         goto Error_Return;
    }

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

/* CON3201 - we are going to static link so will not need to do DosLoadModule */
#if 0
    ModuleOK = DosLoadModule( FNULL, 0, "PMSHAPI", &ModuleHandle);

    if (ModuleOK == DOS_OK)
    {
        DosResult = DosGetProcAddr( ModuleHandle,
                                   "PRFQUERYPROFILEDATA",
                                   &pPrfQueryProfData);

        if ( DosResult != DOS_OK )
        {
            RetVal = (USHORT)IDS_CONVERSION_ERR;
            goto Error_Return;
        }

        DosResult = DosGetProcAddr( ModuleHandle,
                                    "PRFQUERYPROFILESIZE",
                                    &pPrfQueryProfSz);

        if ( DosResult != DOS_OK )
        {
            RetVal = (USHORT)IDS_CONVERSION_ERR;
            goto Error_Return;
        }

        DosResult = DosGetProcAddr( ModuleHandle,
                                    "PRFWRITEPROFILESTRING",
                                    &pPrfWriteProfString);

        if ( DosResult != DOS_OK )
        {
            RetVal = (USHORT)IDS_CONVERSION_ERR;
            goto Error_Return;
        }

        DosResult = DosGetProcAddr( ModuleHandle,
                                    "PRFWRITEPROFILEDATA",
                                    &pPrfWriteProfData);

        if ( DosResult != DOS_OK )
        {
            RetVal = (USHORT)IDS_CONVERSION_ERR;
            goto Error_Return;
        }
    }

    ModuleOK = DosLoadModule( FNULL, 0, "PMSPL", &ModuleHandle);

    if (ModuleOK == DOS_OK)
    {
        DosResult = DosGetProcAddr( ModuleHandle,
                                    "DOSPRINTQSETINFO",
                                    &pDosPrintQSetInfo);
        if ( DosResult != DOS_OK )
        {
            OS2Level = FALSE;          /* OS2 level is 1.2                  */
        }
        else
        {
            OS2Level = TRUE;           /* OS2 level is greater or equal 1.3 */
        }
        DosResult = DosGetProcAddr( ModuleHandle,
                                    "DOSPRINTQGETINFO",
                                    &pDosPrintQGetInfo);
        if ( DosResult != DOS_OK )
        {
            OS2Level = FALSE;          /* OS2 level is 1.2                  */
        }
        else
        {
            OS2Level = TRUE;           /* OS2 level is greater or equal 1.3 */
        }

    }
/* CON3201 - End of if'd out code */
#endif
    /* CON3201 ********************************************************/
    /* Set OS2Level to TRUE since this will only run on 2.0+          */
    /******************************************************************/
    OS2Level = TRUE;

    /******************************************************************/
    /* For 4019 driver migrate all. For 42XX and 52XX drivers Migrate */
    /* only version 45 to 190. PD00436                                */
    /******************************************************************/
    PrinterModel = NO_OF_PRINTERS;
    for (; PrinterModel < NO_OF_PRINTERS+1; PrinterModel++)
    {
        if ( OldIniBuffer )
        {
         /* SSFREESEG(SELECTOROF(OldIniBuffer)); */
            SSFREEMEM( OldIniBuffer );                     /* CON3201 */
            OldIniBuffer = FNULL;
        }
        LPNameCnt = 0;
        OldDriverExist = FALSE;
        if ( PrinterModel < NO_OF_PRINTERS )
        {
            /**********************************************************/
            /* Read description string from the RC file.              */
            /**********************************************************/
            WinLoadString( hab,
                           prdd_ModHandle,
                           IDS_FIRST_PRINTER + PrinterModel,
                           MAX_PRNTR_NAME,
                           (PSZ)Prntr_Name_Buf );

            /******************************************************/
            /* Setup the key word.                                */
            /******************************************************/
            prdu_strcpy (DeviceName_KeyWord + DRIVER_NAME_LEN + 1,
                         Prntr_Name_Buf);

            /**************************************************************/
            /* Find out the size of the entry in OS2.INI for the printer  */
            /* driver - returned in IniSize.                              */
            /**************************************************************/
/*          if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE ,               CON3201 */
            if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE ,
                                     (PSZ)"PM_SPOOLER_DD" ,
                                     (PSZ)DeviceName_KeyWord,
                                     (PULONG)&IniSize) )
            {
                continue;
            }
            /**************************************************************/
            /* Get hold of a segment to store our copy of the driver data */
            /* from the OS2.INI file.  PD00436                            */
            /**************************************************************/

         /* Result = SSALLOCSEG( IniSize, &SELECTOROF(OldIniBuffer), 0 ); */
            Result = SafeSSALLOCMEM( &OldIniBuffer, IniSize, 0 );  /* CON3201 */

            if ( Result != DOS_OK )
            {
                RetVal = (USHORT)IDS_CONVERSION_NO_BUFFER;
                goto Error_Return;
            }

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

            /**************************************************************/
            /* Read data from OS2.INI and store in the buffer.            */
            /**************************************************************/
/*          if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,              CON3201 */
            if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                     (PSZ)"PM_SPOOLER_DD",
                                     (PSZ)DeviceName_KeyWord,
                                     (PVOID)OldIniBuffer,
                                     (PULONG)&IniSize ) )
            {
                continue;
            }
        }
        else
        {
            /***************************************************************/
            /* Find out the size of the entry in OS2.INI for the printer   */
            /* driver - returned in IniSize.                               */
            /***************************************************************/

/*          if ( !pPrfQueryProfileSz( HINI_SYSTEMPROFILE ,           CON3201 */
            if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE ,
                                     (PSZ)"PM_SPOOLER_DD" ,
                                     (PSZ)DriverNameString,
                                     (PULONG)&IniSize) )
            {
                continue;
            }

            /**************************************************************/
            /* Get hold of a segment to store our copy of the driver data */
            /* from the OS2.INI file.  PD00436                            */
            /**************************************************************/

         /* Result = SSALLOCSEG( IniSize, &SELECTOROF(OldIniBuffer), 0 ); */
            Result = SafeSSALLOCMEM( &OldIniBuffer, IniSize, 0 );  /* CON3201 */

            if ( Result != DOS_OK )
            {
                RetVal = (USHORT)IDS_CONVERSION_NO_BUFFER;
                goto Error_Return;
            }

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

            /**************************************************************/
            /* Read data from OS2.INI and store in the buffer.            */
            /**************************************************************/
/*          if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,              CON3201 */
            if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                     (PSZ)"PM_SPOOLER_DD",
                                     (PSZ)DriverNameString,
                                     (PVOID)OldIniBuffer,
                                     (PULONG)&IniSize ) )
            {
                continue;
            }
            OldDriverExist = TRUE;
        }
        /******************************************************************/
        /* Initialise.                                                    */
        /******************************************************************/
        PM_SP_DD_ByPass = FALSE;
        PM_SP_DD_Write  = TRUE;
        /******************************************************************/
        /* Scan the driver data (ignoring the path and                    */
        /* global data) until we find the first printer name.             */
        /******************************************************************/
        SearchState = S_PATH;
        /******************************************************************/
        /* Scan the OldIniBuffer until either the end (*IniData == 0).    */
        /******************************************************************/
        for ( IniData = OldIniBuffer; (*IniData && SearchState != S_NAME);
              IniData++ )
        {
             /*************************************************************/
             /* Depending on what we are currently looking for            */
             /*************************************************************/
             switch (SearchState)
             {
                 case S_PATH:
                     /*****************************************************/
                     /* Skip past the path.                               */
                     /*****************************************************/
                     if (*IniData == ';')
                     {
                         /*************************************************/
                         /* Found the end of the path so start skipping   */
                         /* through the global options.                   */
                         /*************************************************/
                         SearchState = S_GLOBAL;
                     }
                     break;

                 case S_GLOBAL:
                     /*****************************************************/
                     /* Global options contain nothing or an OS2.INI      */
                     /* entry version number. If nothing or an            */
                     /* incompatible version then delete the entry.       */
                     /* and create a new entry. Set the flag to           */
                     /* convert PM_SPOOLER_PRINTER, PM_SPOOLER_QUEUE_DD.  */
                     /*****************************************************/
                     SearchState = S_NAME;
                     if (*IniData == ';' || *(IniData+3) != ';')
                     {
                         *IniData++ = ';';
                         *IniData++ = ';';
                         *IniData = '\0';

                         *IniData--;              /* PD00436 it will trap  */
                                                  /* if we do not decrement*/
                         PM_SP_DD_ByPass = TRUE;
                     }
                     else
                     {
                         /*************************************************/
                         /* Get the version number.                       */
                         /*************************************************/
                         for ( VersionStart = IniData;
                               *IniData != ';';
                               IniData++ );

                         *IniData = '\0';

                         /*************************************************/
                         /* Work out whether the .ini entry is current,   */
                         /* and whether we can use it.                    */
                         /*************************************************/
                         IniVersionType =
                                       prde_GetIniVersionType(VersionStart);

                         *IniData = ';';

                         switch (IniVersionType)
                         {
                             case INI_VERSION_PREVIOUS:
                                 /*****************************************/
                                 /* The ini entry is in an old format     */
                                 /* that we can read.  Call               */
                                 /* TranslateOldIniEntry which grabs a    */
                                 /* new buffer, writes data in the new    */
                                 /* format into the new buffer, and       */
                                 /* throws away the current IniBuffer.    */
                                 /* It returns a pointer to the new one.  */
                                 /*****************************************/
                                 TempBuffer = prdm_TranslateOldIniEntry (
                                                        OldIniBuffer,
                                                        (PUSHORT)&IniSize );

                                 if (!TempBuffer)
                                 {
                                     /*************************************/
                                     /* Couldn't alloc new segments in    */
                                     /* subroutine Drop to the case       */
                                     /* INI_VERSION_DONT_USE.             */
                                     /*************************************/
                                     IniVersionType = INI_VERSION_DONT_USE;
                                 }
                                 else
                                 {
                                     /*************************************/
                                     /* Subroutine call successful.       */
                                     /* Reset OldIniBuffer and all        */
                                     /* pointers into it.                 */
                                     /*************************************/
                                     OldIniBuffer = TempBuffer;
                                     NameStart = OldIniBuffer;
                                     while ( *NameStart++ != ';');
                                     NameStart += 4;
                                     IniData = NameStart;
                                     break;
                                 }
                             case INI_VERSION_DONT_USE:
                                 /*****************************************/
                                 /*       version.                        */
                                 /*****************************************/
                                 IniData -= 3;
                                 *IniData++ = ';';
                                 *IniData++ = ';';
                                 *IniData = '\0';
                                 PM_SP_DD_ByPass = TRUE;
                                 break;

                             case INI_VERSION_CURRENT:
                                 /*****************************************/
                                 /*       version.  Don't convert data    */
                                 /*****************************************/
                                 RetVal = (USHORT)IDS_CONVERSION_ERR;
                                 goto Error_Return;
                                 break;
                         }
                     }

             }
             /*.. switch (SearchState) ............................       */

        } /* for (IniData = IniBuffer; *IniData; IniData++)               */

        if ( PM_SP_DD_ByPass )
        {
            if ( PrinterModel == NO_OF_PRINTERS )
            {
                /**************************************************************/
                /* Setup the default device name.                             */
                /**************************************************************/
                prdu_strcpy (DeviceName_KeyWord+DRIVER_NAME_LEN+1,
                             Prntr_Name_Dflt);

                /**************************************************************/
                /* Create a new entry using default device name keyword.      */
                /**************************************************************/
/*              Result = pPrfWriteProfString( HINI_SYSTEMPROFILE,    CON3201 */
                Result = PrfWriteProfileString( HINI_SYSTEMPROFILE,
                                             (PSZ)"PM_SPOOLER_DD",
                                             (PSZ)DeviceName_KeyWord,
                                             (PVOID)pszWord);
            }
        } /* if ( PM_SP_DD_ByPass )                                       */
        else
        {
            /**************************************************************/
            /* Read PM_SPOOLER_DD entry and setup the logical printer     */
            /* name information.                                          */
            /**************************************************************/
            for ( IniData = NameStart; *IniData; IniData++ )
            {
                if ( *IniData == '=' )          /* skip over printer name */
                {
                    *IniData = '\0';            /* for coping purpose only*/

                    prdu_strcpy( LPNInfo[LPNameCnt].LPName,
                                  NameStart);

                    *IniData++ = '=';    /* put it back the way it was    */

                    /******************************************************/
                    /* Read selected printer field.                       */
                    /******************************************************/
                    prdm_ReadWordFromText(
                                       LPNInfo[LPNameCnt].SelectedPrinter,
                                       PRINTER_TYPE_LENGTH,
                                       IniData );

                    TRACE6 (TFUNC, "Selected printer", &SelectedPrinter, 1);

                    LPNInfo[LPNameCnt].pLPNInfo = IniData;

                    /******************************************************/
                    /*  Read all printer types for this logical printer.  */
                    /******************************************************/
                    while ( *IniData != ';' && *IniData !=',')
                    {
                        prdm_ReadWordFromText( PrinterType,
                                               PRINTER_TYPE_LENGTH,
                                               IniData);

                        /**************************************************/
                        /*  Set flag for this printer type.               */
                        /**************************************************/
                        LPNInfo[LPNameCnt].PrinterInfoFlag |=
                                            (1 << PrinterType );

                        /**************************************************/
                        /*  Get entry length for this printer.            */
                        /**************************************************/
                        prdm_ReadWordFromText( TypeEntryLen,
                                               NO_DATA_SIZE_DIGITS,
                                               IniData);

                        TRACE6 (TFUNC, "Entry Length", &TypeEntryLen, 1);

                        IniData += (TypeEntryLen - PRINTER_TYPE_LENGTH -
                                    NO_DATA_SIZE_DIGITS);
                    }

                    LPNameCnt++;
                }
                if ( *IniData == ',')
                {
                    /******************************************************/
                    /* Get next logical printer name                      */
                    /******************************************************/
                    NameStart = IniData + 1;
                }
                if ( *IniData == ';')
                {
                    /******************************************************/
                    /* end of data.                                       */
                    /******************************************************/
                    break;
                } /* if ( *IniData++ == ';')                              */
            } /* for ( LPNameCnt=0; *IniData; IniData++ )                 */

            /**************************************************************/
            /* Point to new buffer.                                       */
            /**************************************************************/
            pDest   = NewIniBuffer;

            /**************************************************************/
            /* For each printer model create a new entry.                 */
            /**************************************************************/
            for ( i=0; i < NO_OF_PRINTERS; i++ )
            {
                /**********************************************************/
                /* Set flag to flase so we don't create a new entry for   */
                /* this printer type. This falg get set if this printer   */
                /* type is in the data for any logical printer.           */
                /**********************************************************/
                PM_SP_DD_Write = FALSE;

                for ( j=0; j<LPNameCnt; j++)
                {
                    /******************************************************/
                    /* Check PrinterInfoFlag for this logical printer if  */
                    /* it is set then write data into the new buffer.     */
                    /******************************************************/
                    if ( LPNInfo[j].PrinterInfoFlag & (1 << i) )
                    {
                        PM_SP_DD_Write = TRUE;
                        /******************************************************/
                        /* description string from the RC  file.              */
                        /******************************************************/
                        WinLoadString( hab,
                                       prdd_ModHandle,
                                       IDS_FIRST_PRINTER + i,
                                       MAX_PRNTR_NAME,
                                       (PSZ)Prntr_Name_Buf );

                        /******************************************************/
                        /* Setup the key word.                                */
                        /******************************************************/
                        prdu_strcpy (DeviceName_KeyWord + DRIVER_NAME_LEN + 1,
                                     Prntr_Name_Buf);

                        pSource = LPNInfo[j].pLPNInfo;
                        /**************************************************/
                        /* Read data until we find matching printer type. */
                        /**************************************************/
                        while ( *pSource != ';' && *pSource != ',' )
                        {
                            /**********************************************/
                            /*  Read printer type                         */
                            /**********************************************/
                            prdm_ReadWordFromText( PrinterType,
                                                   PRINTER_TYPE_LENGTH,
                                                   pSource);
                            /**********************************************/
                            /* Read length of this entry for this printer.*/
                            /**********************************************/
                            prdm_ReadWordFromText( TypeEntryLen,
                                                   NO_DATA_SIZE_DIGITS,
                                                   pSource);

                            if ( PrinterType == i )
                            {
                                /******************************************/
                                /* Copy the data into the new buffer      */
                                /******************************************/
                                pSource -= (PRINTER_TYPE_LENGTH +
                                            NO_DATA_SIZE_DIGITS);

                                for ( k=0; k < TypeEntryLen; k++ )
                                {
                                    *pDest++ = *pSource++;
                                }
                                *pDest++ = ';';
                                *pDest++ = '\0';
                                 BufferSize = (USHORT)((ULONG)pDest -
                                                       (ULONG)NewIniBuffer);

PM_DD_WRITE:
                                /*******************************************/
                                /* Find out if  this entry already exist.  */
                                /* If exist then do not replaced it.       */
                                /*******************************************/
                                if ( !prde_PM_DD_Exist( LPNInfo[j].LPName,
                                                        DeviceName_KeyWord ))
                                {
                                    prdm_PM_DD_Write(LPNInfo[j].LPName,
                                                     DeviceName_KeyWord,
                                                     "DRIVERDATA",
                                                     NewIniBuffer,
                                                     BufferSize);

                                    prdm_PM_DD_Write(LPNInfo[j].LPName,
                                                     DeviceName_KeyWord,
                                                     "VERSION",
                                                     VersionBuf,
                                                     (USHORT)5);
                                }

                                /***********************************/
                                /* Point to new buffer.            */
                                /***********************************/
                                pDest   = NewIniBuffer;

                                break;
                            } /* if ( PrinterType == i )                  */
                            else                /* point to next entry    */
                            {
                                pSource += (TypeEntryLen -
                                   PRINTER_TYPE_LENGTH - NO_DATA_SIZE_DIGITS);
                            }

                        } /*  while ( *pSource != ';' && *pSource != ',' )*/

                    } /* if ( LPNInfo[j].PrinterInfoFlag & (1 << i) )     */

                } /* for ( j=0; j<LPNameCnt; j++)                         */

                /**********************************************************/
                /* Create a new entry if this flag is set                 */
                /**********************************************************/
                if ( PM_SP_DD_Write )
                {
                    /******************************************************/
                    /* description string from the RC  file.              */
                    /******************************************************/
                    WinLoadString( hab,
                                   prdd_ModHandle,
                                   IDS_FIRST_PRINTER + i,
                                   MAX_PRNTR_NAME,
                                   (PSZ)Prntr_Name_Buf );

                    /******************************************************/
                    /* Setup the key word.                                */
                    /******************************************************/
                    prdu_strcpy (DeviceName_KeyWord + DRIVER_NAME_LEN + 1,
                                 Prntr_Name_Buf);

                    /******************************************************/
                    /* Create a new entry using device name keyword.      */
                    /******************************************************/
/* CON3201          Result = pPrfWriteProfString( HINI_SYSTEMPROFILE,         */
                    Result = PrfWriteProfileString( HINI_SYSTEMPROFILE,
                                                   (PSZ)"PM_SPOOLER_DD",
                                                   (PSZ)DeviceName_KeyWord,
                                                   (PVOID)pszWord);

                } /* if ( PM_SP_DD_Write )                                    */

PM_SP_DD_END:

                PM_SP_DD_Write = FALSE;


            } /*  for ( i=0; i < NO_OF_PRINTERS; i++ )                    */

        } /*  else                                                        */

    } /*  for ( PrinterModel=0; PrinterModel < NO_OF_PRINTERS+1; ... )                    */
    /******************************************************************/
    /* If DeleteOldDriver is TRUE update the PM_SPOOLER_PRINTER and   */
    /* delete the old driver                                          */
    /******************************************************************/
    if ( !DeleteOldDriver )
    {
        goto Error_Return;
    }

PM_SPOOLER_PRINTER:
    /******************************************************************/
    /* Update PM_SPOOLER_PRINTER entry.                               */
    /******************************************************************/

    /******************************************************************/
    /* Find out the size of the PM_SPOOLER_PRINTER entry returned in  */
    /* IniSize.                                                       */
    /******************************************************************/

/*  if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE,                        CON3201 */
    if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE,
                           (PSZ)"PM_SPOOLER_PRINTER",
                           (PSZ)FNULL,
                           (PULONG)&IniSize) )
    {
        goto PM_SPOOLER_QUEUE_DD;
    }
    TRACE6(TFUNC, "IniSize", &IniSize, 1);

    /******************************************************************/
    /* Read PM_SPOOLER_PRINTER entry with a null key name. this       */
    /* returns a list of all listed logical printer name seperated    */
    /* from each other by one null. The list is terminated by two     */
    /* nulls.                                                         */
    /******************************************************************/
/*  if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,                      CON3201 */
    if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                             (PSZ)"PM_SPOOLER_PRINTER",
                             (PSZ)FNULL,
                             (PVOID)KeyNameBuffer,
                             (PULONG)&IniSize ) )
    {
        goto PM_SPOOLER_QUEUE_DD;
    }
    KeyName =  KeyNameBuffer;
    while ( *KeyName )
    {
        WriteQueueDD = FALSE;
        /**************************************************************/
        /* Find out the size of the PM_SPOOLER_PRINTER entry.         */
        /**************************************************************/

/*     if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE,                     CON3201 */
        if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE,
                                 (PSZ)"PM_SPOOLER_PRINTER",
                                 (PSZ)KeyName,
                                 (PULONG)&IniSize) )
        {
            goto PM_SPOOLER_PRINTER_NEXT;
        }
        TRACE6(TFUNC, "IniSize", &IniSize, 1);
        /**************************************************************/
        /* Read PM_SPOOLER_PRINTER entry with this KeyName            */
        /**************************************************************/
/*      if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,                  CON3201 */
        if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                 (PSZ)"PM_SPOOLER_PRINTER",
                                 (PSZ)KeyName,
                                 (PVOID)OldIniBuffer1,
                                 (PULONG)&IniSize ) )
        {
            goto PM_SPOOLER_PRINTER_NEXT;
        }

        StartPtr = OldIniBuffer1;

        /**************************************************************/
        /* first ';' is for logical printer address                   */
        /**************************************************************/

        while ( *StartPtr++ != ';');

     /* (BYTE)Terminator = ','; */
        Terminator = ',';                                  /* CON3201 */

        while ( Terminator != ';' )
        {
            PrevStartPtr = StartPtr;        /* previous start pointer */

            if (!prdm_ReadTerminatedWordFromText(pszWord,
                                             &Terminator,
                                             (PBYTE)",;",
                                             &StartPtr))
            {
                goto PM_SPOOLER_PRINTER_NEXT;
            }

           if ( !prdu_strcmpN( (PBYTE)pszWord,DriverNameString,
                               DRIVER_NAME_LEN ) &&
                ( pszWord[ DRIVER_NAME_LEN ] != '.') )
           {
               /***************************************************/
               /* Copy the data into NewIniBuffer up to our       */
               /* driver name.                                    */
               /***************************************************/
               for ( pDest = NewIniBuffer, pSource = OldIniBuffer1;
                     pSource < PrevStartPtr;  )
               {
                   *pDest++ = *pSource++;
               }
               /***************************************************/
               /* This is an old entry and it needs to be         */
               /* converted to new format.                        */
               /***************************************************/
               for ( i = 0; i < LPNameCnt; i++)
               {
                   if (!prdu_strcmp((PBYTE)LPNInfo[i].LPName,KeyName ))
                   {
                       /*******************************************/
                       /* description string from the RC file.    */
                       /*******************************************/
                       WinLoadString( hab,
                              prdd_ModHandle,
                              IDS_FIRST_PRINTER +
                                         LPNInfo[i].SelectedPrinter,
                              MAX_PRNTR_NAME,
                              (PSZ)Prntr_Name_Buf );

                       /*******************************************/
                       /* Setup the key word.                     */
                       /*******************************************/
                       prdu_strcpy ( DeviceName_KeyWord +
                                                DRIVER_NAME_LEN + 1,
                                     Prntr_Name_Buf);

                       /*******************************************/
                       /* Put driverName.DeviceName into the      */
                       /* NewIniBuffer                            */
                       /*******************************************/
                       for ( pSource = DeviceName_KeyWord;
                             *pSource; )
                       {
                           *pDest++ = *pSource++;
                       }
                       /*******************************************/
                       /* Copy the data after our driver name.    */
                       /*******************************************/
                       for ( pSource = StartPtr-1; *pSource; )
                       {
                           *pDest++ = *pSource++;
                       }
                       *pDest = '\0';       /* null terminator    */
                       /***************************************************/
                       /* Write PM_SPOOLER_PRINTER entry.                 */
                       /***************************************************/
/* CON3201             Result = pPrfWriteProfString( HINI_SYSTEMPROFILE,      */
                       Result = PrfWriteProfileString( HINI_SYSTEMPROFILE,
                                           (PSZ)"PM_SPOOLER_PRINTER",
                                           (PSZ)KeyName,
                                           (PVOID)NewIniBuffer);

                       /*******************************************/
                       /* Read the first queue name from          */
                       /* OldIniBuffer1.                          */
                       /*******************************************/
                       StartPtr = OldIniBuffer1;

                       /*******************************************/
                       /* first ';' is for logical printer        */
                       /* address.                                */
                       /*******************************************/
                       while ( *StartPtr++ != ';');

                       /*******************************************/
                       /* 2nd ';' is for DeviceName.              */
                       /*******************************************/
                       while ( *StartPtr++ != ';');

                       /*******************************************/
                       /* Read the queue name.                    */
                       /*******************************************/
                       if (!prdm_ReadTerminatedWordFromText(pszWord,
                                                       &Terminator,
                                                       (PBYTE)",;",
                                                       &StartPtr))
                       {
                           *pszWord = ';';
                       }

                       while ( (*pszWord != ';') && (*pszWord) )
                       {
                           /**********************************************/
                           /* Read PM_SPOOLER_QUEUE_DD entry with this   */
                           /* queue name. Find out the size of the       */
                           /* PM_SPOOLER_QUEUE_DD entry first.           */
                           /**********************************************/
/* CON3201                 if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE,         */
                           if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE,
                                          (PSZ)"PM_SPOOLER_QUEUE_DD",
                                          (PSZ)pszWord,
                                          (PULONG)&IniSize) )
                           {
                               break;
                           }

                           /**********************************************/
                           /* if buffer required is more than what we got*/
                           /**********************************************/
                           if ( IniSize > QDDSize )
                           {
                               break;
                           }

                           /**********************************************/
                           /* Read PM_SPOOLER_QUEUE_DD entry.            */
                           /**********************************************/
/* CON3201                 if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,       */
                           if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                               (PSZ)"PM_SPOOLER_QUEUE_DD",
                                               (PSZ)pszWord,
                                               (PVOID)IniBufferQDD,
                                               (PULONG)&IniSize ) )
                           {
                               break;
                           }

                           /**********************************************/
                           /* Read PM_SPOOLER_QUEUE_DDDATA entry with    */
                           /* this queue name. Find out the size of the  */
                           /* PM_SPOOLER_QUEUE_DDDATA entry first.       */
                           /**********************************************/
/* CON3201                 if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE,         */
                           if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE,
                                          (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                          (PSZ)pszWord,
                                          (PULONG)&IniSize) )
                           {
                               break;
                           }
                           /**********************************************/
                           /* Read PM_SPOOLER_QUEUE_DDDATA entry.        */
                           /**********************************************/
/* CON3201                 if ( !pPrfQueryProfData(                           */
                           if ( !PrfQueryProfileData(
                                       HINI_SYSTEMPROFILE,
                                       (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                       (PSZ)pszWord,
                                       (PVOID)IniQDDData,
                                       (PULONG)&IniSize ) )
                           {
                               break;
                           }

                           if ((*IniBufferQDD != ';') &&
                                !prdu_strcmpN((PBYTE)IniBufferQDD,
                                              DriverNameString,
                                              DRIVER_NAME_LEN) &&
                                (*(IniBufferQDD+DRIVER_NAME_LEN)!='.'))
                           {
                               /**********************************/
                               /* Put driverName.DeviceName into */
                               /* the IniBufferQDD.              */
                               /**********************************/

                               for (pSource = DeviceName_KeyWord,
                                    pDest=IniBufferQDD,
                                    j=1; *pSource; j++)
                               {
                                   *pDest++ = *pSource++;
                               }

                               *pDest = '\0';    /* null terminat*/
                               /****************************************/
                               /* Put devicename in DriverData. PD00280*/
                               /****************************************/
                               if ( IniSize > 40 )
                               {
                                   prdu_strcpyN((PBYTE)IniQDDData+8,
                                            (PBYTE)(IniBufferQDD+8), 32);
                               }
                               *pDest++ = ';';
                               *pDest = '\0';    /* null terminate       */
                                pDest--;
                               /******************************************/
                               /* PD00301: Allocate a new buffer and put */
                               /* old driver data in it. Call prdm_dialog*/
                               /* to migrate driver data with uflags=2.  */
                               /* put this new buffer back in PM_SP_Q_   */
                               /* DDData.                                */
                               /******************************************/
                                DriverDataSize = sizeof(DRIVDATA) +
                                                 sizeof(DMDriverStruc) - 1;

                             /* Result = SSALLOCSEG( DriverDataSize,      */
                             /*          &SELECTOROF(NewDriverData), 0 ); */
                                Result = SafeSSALLOCMEM( &NewDriverData, /*CON3201*/
                                                     DriverDataSize, /*CON3201*/
                                                     0 );            /*CON3201*/

                                if ( Result != DOS_OK )
                                {
                                    RetVal=(USHORT)IDS_CONVERSION_NO_BUFFER;
                                    goto Error_Return;
                                }

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

                                pSource = IniQDDData;
                                pTarget = NewDriverData;

                                for ( i = 0; (i < DriverDataSize) &&
                                             (i < IniSize);
                                             i++ )
                                {
                                    *pTarget++ = *pSource++;
                                }

                                DriverData = (PDRIVDATA)NewDriverData;

                                DriverData->cb = sizeof(DRIVDATA) +
                                                sizeof(DMDriverStruc) -1;

                                Result = prdm_Dialog( (PDRIVDATA)DriverData,
                                                      DriverNameString,
                                                      DeviceName_KeyWord+8,
                                                      KeyName,
                                                      (ULONG)2 );

                               /******************************************/
                               /* Write PM_SPOOLER_QUEUE_DD entry for    */
                               /* OS2 1.3 and above. To do that we first */
                               /* read PPRQINFO3 structure and then we   */
                               /* change the DeviceName and DriverData   */
                               /* DeviceName. Then we write the PPRQINFO3*/
                               /* structure back out. PD00280            */
                               /******************************************/
                               if ( OS2Level )
                               {
/* CON3201                         Result =  pDosPrintQGetInfo(               */
                                   Result =  SplQueryQueue(
                                                      (PSZ)FNULL,
                                                      (PSZ)pszWord,
                                                      3,
                                                      (PSZ)FNULL,
                                                      0,
                                                      (PULONG)&QSize);
                                   /*************************************************/
                                   /* Get hold of a segment to store our copy of the*/
                                   /* PPRQINFO3 structure. Add DeviceName length.   */
                                   /*************************************************/
                                /* Result = SSALLOCSEG(                    */
                                /*           QSize,                        */
                                /*           &SELECTOROF(OldQDDData), 0 ); */
                                   Result = SafeSSALLOCMEM(        /* CON3201 */
                                             &OldQDDData,          /* CON3201 */
                                             QSize, 0 );           /* CON3201 */

                                   if ( Result != DOS_OK )
                                   {
                                       if ( NewDriverData )     /* PD00607    */
                                        /* SSFREESEG(SELECTOROF(NewDriverData));*/
                                           SSFREEMEM(NewDriverData);/*CON3201*/

                                        RetVal=(USHORT)IDS_CONVERSION_NO_BUFFER;
                                        goto Error_Return;
                                   }

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

                                   /******************************************/
                                   /* Get hold of a segment to store our     */
                                   /* new copy of the PPRQINFO3 structure.   */
                                   /******************************************/
                                /* Result = SSALLOCSEG(                    */
                                /*           QSize + DriverDataSize,       */
                                /*           &SELECTOROF(NewQDDData), 0 ); */
                                   Result = SafeSSALLOCMEM(          /*CON3201*/
                                           &NewQDDData,              /*CON3201*/
                                           (QSize + DriverDataSize), /*CON3201*/
                                            0 );                     /*CON3201*/

                                   if ( Result != DOS_OK )
                                   {
                                       if ( NewDriverData )     /* PD00607    */
                                        /* SSFREESEG(SELECTOROF(NewDriverData));*/
                                           SSFREEMEM(NewDriverData);/*CON3201*/


                                       if ( OldQDDData )        /* PD00607    */
                                        /* SSFREESEG(SELECTOROF(OldQDDData));*/
                                           SSFREEMEM(OldQDDData);/*CON3201*/

                                        RetVal=(USHORT)IDS_CONVERSION_NO_BUFFER;
                                        goto Error_Return;
                                   }

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

/* CON3201                         Result =  pDosPrintQGetInfo(               */
                                   Result =  SplQueryQueue(
                                                      (PSZ)FNULL,
                                                      (PSZ)pszWord,
                                                      3,
                                                      (PBYTE)OldQDDData,
                                                      QSize,
                                                      (PULONG)&QSize);

                                   QDDData_Old = (PPRQINFO3) OldQDDData;

                                   QDDData_New = (PPRQINFO3) NewQDDData;

                                   QDDData_New->pszName =
                                             QDDData_Old->pszName;

                                   QDDData_New->uPriority =
                                             QDDData_Old->uPriority;

                                   QDDData_New->uStartTime =
                                             QDDData_Old->uStartTime;

                                   QDDData_New->uUntilTime =
                                             QDDData_Old->uUntilTime;

                                /* QDDData_New->pad1 =          */
                                /*           QDDData_Old->pad1; */
                                   QDDData_New->fsType =           /* CON3201 */
                                             QDDData_Old->fsType;  /* CON3201 */

                                   QDDData_New->pszSepFile =
                                             QDDData_Old->pszSepFile;

                                   QDDData_New->pszPrProc =
                                             QDDData_Old->pszPrProc;

                                   QDDData_New->pszParms =
                                             QDDData_Old->pszParms;

                                   QDDData_New->pszComment =
                                             QDDData_Old->pszComment;

                                   QDDData_New->fsStatus =
                                             QDDData_Old->fsStatus;

                                   QDDData_New->cJobs =
                                             QDDData_Old->cJobs;

                                   QDDData_New->pszPrinters =
                                             QDDData_Old->pszPrinters;

                                   QDDData_New->pszDriverName =
                                             DeviceName_KeyWord;

                                   QDDData_New->pDriverData = DriverData;

/* CON3201                         Result =  pDosPrintQSetInfo(               */
                                   Result =  SplSetQueue(
                                                      (PSZ)FNULL,
                                                      (PSZ)pszWord,
                                                      3,
                                                      (PPRQINFO3)QDDData_New,
                                                      QSize+
                                                      DriverDataSize,
                                                      0);
                                   if ( OldQDDData )
                                    /* SSFREESEG(SELECTOROF(OldQDDData)); */
                                       SSFREEMEM(OldQDDData);/*CON3201*/

                                   if ( NewQDDData )
                                    /* SSFREESEG(SELECTOROF(NewQDDData)); */
                                       SSFREEMEM(NewQDDData);/*CON3201*/
                               }
                               else
                               {
                                   /**********************************/
                                   /* Write NULL into                */
                                   /* PM_SPOOLER_QUEUE_DDDATA entry. */
                                   /**********************************/
/*  CON3201                        Result = pPrfWriteProfData(                */
                                   Result = PrfWriteProfileData(
                                            HINI_SYSTEMPROFILE,
                                            (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                            (PSZ)pszWord,
                                            (PVOID)pDest,
                                            (ULONG)(2));
                                   /****************************************/
                                   /* Write the new buffer back into       */
                                   /* PM_SPOOLER_QUEUE_DDDATA entry.       */
                                   /****************************************/
                                   *(NewDriverData+DriverDataSize-2) =';';
                                   *(NewDriverData+DriverDataSize-1) ='\0';

/* CON3201                         Result = pPrfWriteProfData(               */
                                   Result = PrfWriteProfileData(
                                         HINI_SYSTEMPROFILE,
                                         (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                         (PSZ)pszWord,
                                         (PVOID)NewDriverData,
                                         (ULONG)DriverDataSize);

                                   Error = WinGetLastError(hab);

                                   /**********************************/
                                   /* Write the buffer into          */
                                   /* PM_SPOOLER_QUEUE_DD entry.     */
                                   /**********************************/
/* CON3201                         Result = pPrfWriteProfString(              */
                                   Result = PrfWriteProfileString(
                                         HINI_SYSTEMPROFILE,
                                         (PSZ)"PM_SPOOLER_QUEUE_DD",
                                         (PSZ)pszWord,
                                         (PVOID)IniBufferQDD);

                                   Error = WinGetLastError(hab);
                               }

                               if ( NewDriverData )
                                /* SSFREESEG(SELECTOROF(NewDriverData)); */
                                   SSFREEMEM(NewDriverData);  /* CON3201 */

                           } /* if ( !prdu_strcmpN((PBYTE)IniBufferQDD   */

                           /**********************************************/
                           /* Read the queue name.                       */
                           /**********************************************/
                           if (!prdm_ReadTerminatedWordFromText(pszWord,
                                                           &Terminator,
                                                           (PBYTE)",;",
                                                           &StartPtr))
                           {
                               *pszWord = ';';
                           }

                       } /* while( *pszWord!=';'                         */


                       break;
                   }

               } /* for ( i = 0; i < LPNameCnt; i++ )   */

               /**********************************************************/
               /* If this logical printer name was not in PM_SP_DD entry.*/
               /**********************************************************/
               if ( i == LPNameCnt )
               {
                   /******************************************************/
                   /* Setup the default device name.                     */
                   /******************************************************/
                   prdu_strcpy (DeviceName_KeyWord + DRIVER_NAME_LEN + 1,
                                Prntr_Name_Dflt);

                   /******************************************************/
                   /* Put driverName.default device name into buffer.    */
                   /******************************************************/
                   for ( pSource = DeviceName_KeyWord; *pSource; )
                   {
                       *pDest++ = *pSource++;
                   }
                   /*****************************************************/
                   /* Copy the data after our driver name.              */
                   /*****************************************************/
                   for ( pSource = StartPtr-1; *pSource; )
                   {
                       *pDest++ = *pSource++;
                   }
//   PD00440       *pDest++ = ';';      /* terminator                   */
                   *pDest = '\0';       /* null terminator              */

                   /*****************************************************/
                   /* Write PM_SPOOLER_PRINTER entry.                   */
                   /*****************************************************/
/* CON3201         Result = pPrfWriteProfString( HINI_SYSTEMPROFILE,          */
                   Result = PrfWriteProfileString( HINI_SYSTEMPROFILE,
                                          (PSZ)"PM_SPOOLER_PRINTER",
                                          (PSZ)KeyName,
                                          (PVOID)NewIniBuffer);


                   /**************************************************/
                   /* Read the first queue name from OldIniBuffer1.  */
                   /**************************************************/
                   StartPtr = OldIniBuffer1;

                   /**************************************************/
                   /* first ';' is for logical printer address.      */
                   /**************************************************/
                   while ( *StartPtr++ != ';');

                   /**************************************************/
                   /* 2nd ';' is for DeviceName.                     */
                   /**************************************************/
                   while ( *StartPtr++ != ';');

                   /**************************************************/
                   /* Read the queue name.                           */
                   /**************************************************/
                   if (!prdm_ReadTerminatedWordFromText(pszWord,
                                                   &Terminator,
                                                   (PBYTE)",;",
                                                   &StartPtr))
                   {
                       *pszWord = ';';
                   }

                   while ( (*pszWord != ';') && (*pszWord) )
                   {
                       /**************************************************/
                       /* Read PM_SPOOLER_QUEUE_DD entry with this       */
                       /* queue name. Find out the size of the           */
                       /* PM_SPOOLER_QUEUE_DD entry first.               */
                       /**************************************************/
/*                     if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE ,    CON3201 */
                       if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE ,
                                      (PSZ)"PM_SPOOLER_QUEUE_DD" ,
                                      (PSZ)pszWord,
                                      (PULONG)&IniSize) )
                       {
                           break;
                       }

                       /**************************************************/
                       /* if buffer required is more than what we got    */
                       /**************************************************/
                       if ( IniSize > QDDSize )
                       {
                           break;
                       }

                       /**************************************************/
                       /* Read PM_SPOOLER_QUEUE_DD entry.                */
                       /**************************************************/
/* CON3201             if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,           */
                       if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                            (PSZ)"PM_SPOOLER_QUEUE_DD",
                                            (PSZ)pszWord,
                                            (PVOID)IniBufferQDD,
                                            (PULONG)&IniSize ) )
                       {
                           break;
                       }
                       /**********************************************/
                       /* Read PM_SPOOLER_QUEUE_DDDATA entry with    */
                       /* this queue name. Find out the size of the  */
                       /* PM_SPOOLER_QUEUE_DDDATA entry first.       */
                       /**********************************************/
/* CON3201             if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE,             */
                       if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE,
                                      (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                      (PSZ)pszWord,
                                      (PULONG)&IniSize) )
                       {
                           break;
                       }
                       /**********************************************/
                       /* Read PM_SPOOLER_QUEUE_DDDATA entry.        */
                       /**********************************************/
/*                     if ( !pPrfQueryProfData(                       CON3201 */
                       if ( !PrfQueryProfileData(
                                   HINI_SYSTEMPROFILE,
                                   (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                   (PSZ)pszWord,
                                   (PVOID)IniQDDData,
                                   (PULONG)&IniSize ) )
                       {
                           break;
                       }


                       if ( *IniBufferQDD != ';' &&
                            !prdu_strcmpN((PBYTE)IniBufferQDD,
                                              DriverNameString,
                                              DRIVER_NAME_LEN ) &&
                             *(IniBufferQDD+DRIVER_NAME_LEN) != '.')
                       {
                           /**************************************/
                           /* Put driverName.DeviceName into the */
                           /* IniBufferQDD.                      */
                           /**************************************/
                           for ( pSource = DeviceName_KeyWord, j=1,
                                 pDest = IniBufferQDD; *pSource;j++)
                           {
                               *pDest++ = *pSource++;
                           }
                           *pDest = '\0';      /* null terminator */
                           /****************************************/
                           /* Put devicename in DriverData. PD00280*/
                           /****************************************/
                           if ( IniSize > 40 )
                           {
                               prdu_strcpyN((PBYTE)IniQDDData+8,
                                        (PBYTE)(IniBufferQDD+8), 32);
                           }
                           /******************************************/
                           /* PD00301: Allocate a new buffer and put */
                           /* old driver data in it. Call prdm_dialog*/
                           /* to migrate driver data with uflags=2.  */
                           /* put this new buffer back in PM_SP_Q_   */
                           /* DDData.                                */
                           /******************************************/
                           DriverDataSize = sizeof(DRIVDATA) +
                                            sizeof(DMDriverStruc) - 1;

                        /* Result = SSALLOCSEG( DriverDataSize,         */
                        /*             &SELECTOROF(NewDriverData), 0 ); */
                           Result = SafeSSALLOCMEM( &NewDriverData, /*CON3201*/
                                                DriverDataSize, 0 );/*CON3201*/

                           if ( Result != DOS_OK )
                           {
                               RetVal=(USHORT)IDS_CONVERSION_NO_BUFFER;
                               goto Error_Return;
                           }

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

                           pSource = IniQDDData;
                           pTarget = NewDriverData;

                           for ( i = 0; (i < DriverDataSize) &&
                                        (i < IniSize);
                                        i++ )
                           {
                                *pTarget++ = *pSource++;
                           }

                           DriverData = (PDRIVDATA)NewDriverData;

                           DriverData->cb = sizeof(DRIVDATA) +
                                            sizeof(DMDriverStruc) -1;

                           Result = prdm_Dialog( (PDRIVDATA)DriverData,
                                                 DriverNameString,
                                                 DeviceName_KeyWord+8,
                                                 KeyName,
                                                 (ULONG)2 );

                           /******************************************/
                           /* Write PM_SPOOLER_QUEUE_DD entry for    */
                           /* OS2 1.3 and above. To do that we first */
                           /* read PPRQINFO3 structure and then we   */
                           /* change the DeviceName and DriverData   */
                           /* DeviceName. Then we write the PPRQINFO3*/
                           /* structure back out. PD00280            */
                           /******************************************/
                           if (OS2Level)
                           {
/*                             Result =  pDosPrintQGetInfo(           CON3201 */
                               Result =  SplQueryQueue(
                                                  (PSZ)FNULL,
                                                  (PSZ)pszWord,
                                                  3,
                                                  (PSZ)FNULL,
                                                  0,
                                                  (PULONG)&QSize);
                               /*************************************************/
                               /* Get hold of a segment to store our copy of the*/
                               /* PPRQINFO3 structure. Add DeviceName length.   */
                               /*************************************************/
                            /* Result = SSALLOCSEG(                    */
                            /*           QSize,                        */
                            /*           &SELECTOROF(OldQDDData), 0 ); */
                               Result = SafeSSALLOCMEM(            /* CON3201 */
                                         &OldQDDData,              /* CON3201 */
                                         QSize, 0 );               /* CON3201 */

                               if ( Result != DOS_OK )
                               {
                                    if ( NewDriverData )     /* PD00607    */
                                     /* SSFREESEG(SELECTOROF(NewDriverData));*/
                                        SSFREEMEM(NewDriverData); /* CON3201 */

                                    RetVal=(USHORT)IDS_CONVERSION_NO_BUFFER;
                                    goto Error_Return;
                               }

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

                               /*********************************************/
                               /* Get hold of a segment to store our        */
                               /* new copy of the PPRQINFO3 structure.      */
                               /*********************************************/
                            /* Result = SSALLOCSEG(                    */
                            /*           QSize + DriverDataSize,       */
                            /*           &SELECTOROF(NewQDDData), 0 ); */
                               Result = SafeSSALLOCMEM(              /*CON3201*/
                                        &NewQDDData,                 /*CON3201*/
                                       (QSize + DriverDataSize), 0 );/*CON3201*/

                               if ( Result != DOS_OK )
                               {
                                    if ( NewDriverData )     /* PD00607    */
                                     /* SSFREESEG(SELECTOROF(NewDriverData)); */
                                        SSFREEMEM(NewDriverData); /*CON3201*/

                                    if ( OldQDDData )        /* PD00607    */
                                     /* SSFREESEG(SELECTOROF(OldQDDData)); */
                                        SSFREEMEM(OldQDDData);  /* CON3201 */

                                    RetVal=(USHORT)IDS_CONVERSION_NO_BUFFER;
                                    goto Error_Return;
                               }

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

/*                             Result =  pDosPrintQGetInfo(           CON3201 */
                               Result =  SplQueryQueue(
                                                  (PSZ)FNULL,
                                                  (PSZ)pszWord,
                                                  3,
                                                  (PBYTE)OldQDDData,
                                                  QSize,
                                                  (PULONG)&QSize);

                               QDDData_Old = (PPRQINFO3) OldQDDData;

                               QDDData_New = (PPRQINFO3) NewQDDData;

                               QDDData_New->pszName =
                                         QDDData_Old->pszName;

                               QDDData_New->uPriority =
                                         QDDData_Old->uPriority;

                               QDDData_New->uStartTime =
                                         QDDData_Old->uStartTime;

                               QDDData_New->uUntilTime =
                                         QDDData_Old->uUntilTime;

                            /* QDDData_New->pad1 =          */
                            /*           QDDData_Old->pad1; */
                               QDDData_New->fsType =               /* CON3201 */
                                         QDDData_Old->fsType;      /* CON3201 */

                               QDDData_New->pszSepFile =
                                         QDDData_Old->pszSepFile;

                               QDDData_New->pszPrProc =
                                         QDDData_Old->pszPrProc;

                               QDDData_New->pszParms =
                                         QDDData_Old->pszParms;

                               QDDData_New->pszComment =
                                         QDDData_Old->pszComment;

                               QDDData_New->fsStatus =
                                         QDDData_Old->fsStatus;

                               QDDData_New->cJobs =
                                         QDDData_Old->cJobs;

                               QDDData_New->pszPrinters =
                                         QDDData_Old->pszPrinters;

                               QDDData_New->pszDriverName =
                                         DeviceName_KeyWord;

                               QDDData_New->pDriverData = DriverData;

/*                             Result =  pDosPrintQSetInfo(           CON3201 */
                               Result =  SplSetQueue(
                                                  (PSZ)FNULL,
                                                  (PSZ)pszWord,
                                                  3,
                                                  (PPRQINFO3)QDDData_New,
                                                  QSize+
                                                  DriverDataSize,
                                                  0);
                               if ( OldQDDData )
                                /* SSFREESEG(SELECTOROF(OldQDDData)); */
                                   SSFREEMEM(OldQDDData);  /* CON3201 */

                               if ( NewQDDData )
                                /* SSFREESEG(SELECTOROF(NewQDDData)); */
                                   SSFREEMEM(NewQDDData);  /* CON3201 */
                           }
                           else
                           {
                               *pDest++ = ';';
                               *pDest = '\0';    /* null terminat*/
                               pDest--;

                               /**************************************/
                               /* Write NULL into                    */
                               /* PM_SPOOLER_QUEUE_DDDATA entry.     */
                               /**************************************/
/* CON3201                     Result = pPrfWriteProfData(                    */
                               Result = PrfWriteProfileData(
                                         HINI_SYSTEMPROFILE,
                                         (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                         (PSZ)pszWord,
                                         (PVOID)pDest,
                                         (ULONG)(2));

                               /****************************************/
                               /* Write the original buffer back into  */
                               /* PM_SPOOLER_QUEUE_DDDATA entry.       */
                               /****************************************/
                               *(NewDriverData+DriverDataSize-2) =';';
                               *(NewDriverData+DriverDataSize-1) ='\0';

/*                             Result = pPrfWriteProfData(            CON3201 */
                               Result = PrfWriteProfileData(
                                     HINI_SYSTEMPROFILE,
                                     (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                     (PSZ)pszWord,
                                     (PVOID)NewDriverData,
                                     (ULONG)DriverDataSize);

                               /**********************************/
                               /* Write the buffer into          */
                               /* PM_SPOOLER_QUEUE_DD entry.     */
                               /**********************************/
/* CON3201                     Result = pPrfWriteProfString(                  */
                               Result = PrfWriteProfileString(
                                     HINI_SYSTEMPROFILE,
                                     (PSZ)"PM_SPOOLER_QUEUE_DD",
                                     (PSZ)pszWord,
                                     (PVOID)IniBufferQDD);

                           }

                           if ( NewDriverData )
                            /* SSFREESEG(SELECTOROF(NewDriverData)); */
                               SSFREEMEM(NewDriverData);   /* CON3201 */

                       } /* if ( *IniBufferQDD != ';' )                  */

                       /**************************************************/
                       /* Read the queue name.                           */
                       /**************************************************/
                       if (!prdm_ReadTerminatedWordFromText(pszWord,
                                                       &Terminator,
                                                       (PBYTE)",;",
                                                       &StartPtr))
                       {
                           *pszWord = ';';
                       }

                   } /* while                                            */


               } /* if ( i == LPNameCnt )                                */

           } /* if ( !prdu_strcmpN( (PBYTE)pszWord,DriverNameString,..       */

        } /* while ( Terminator != ';' )                                     */

PM_SPOOLER_PRINTER_NEXT:

        while ( *KeyName++ );            /* get next key name                */

    } /* while ( *KeyName ) */


PM_SPOOLER_QUEUE_DD:

    /*************************************************************************/
    /* Update PM_SPOOLER_QUEUE_DD entry.                                     */
    /*************************************************************************/

    /*************************************************************************/
    /* Find out the size of the PM_SPOOLER_QUEUE_DD entry returned in        */
    /* IniSize.                                                              */
    /*************************************************************************/

/*  if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE ,                       CON3201 */
    if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE ,
                           (PSZ)"PM_SPOOLER_QUEUE_DD" ,
                           (PSZ)FNULL,
                           (PULONG)&IniSize) )
    {
        RetVal = (USHORT)IDS_CONVERSION_COMP;
        goto Error_Return;
    }
    TRACE6(TFUNC, "IniSize", &IniSize, 1);

    /*************************************************************************/
    /* Read PM_SPOOLER_QUEUE_DD entry with a null key name. this             */
    /* returns a list of all listed logical printer name seperated           */
    /* from each other by one null. The list is terminated by two            */
    /* nulls.                                                                */
    /*************************************************************************/
/*  if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,                      CON3201 */
    if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                             (PSZ)"PM_SPOOLER_QUEUE_DD",
                             (PSZ)FNULL,
                             (PVOID)KeyNameBuffer,
                             (PULONG)&IniSize ) )
    {
        RetVal = (USHORT)IDS_CONVERSION_COMP;
        goto Error_Return;
    }
    KeyName =  KeyNameBuffer;

    while ( *KeyName )
    {
        /*********************************************************************/
        /* Find out the size of the PM_SPOOLER_QUEUE_DD entry.               */
        /*********************************************************************/

/*      if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE ,                   CON3201 */
        if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE ,
                               (PSZ)"PM_SPOOLER_QUEUE_DD",
                               (PSZ)KeyName,
                               (PULONG)&IniSize) )
        {
            goto PM_SPOOLER_QUEUE_DD_NEXT;
        }
        TRACE6(TFUNC, "IniSize", &IniSize, 1);
        /*********************************************************************/
        /* Read PM_SPOOLER_QUEUE_DD entry with this KeyName                  */
        /*********************************************************************/
/*      if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,                  CON3201 */
        if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                 (PSZ)"PM_SPOOLER_QUEUE_DD",
                                 (PSZ)KeyName,
                                 (PVOID)OldIniBuffer1,
                                 (PULONG)&IniSize ) )
        {
            goto PM_SPOOLER_QUEUE_DD_NEXT;
        }

        StartPtr = OldIniBuffer1;

        if ( *StartPtr != ';' )
        {
            if ( !prdu_strcmpN((PBYTE)StartPtr,DriverNameString,
                               DRIVER_NAME_LEN ))
            {

                if ( *(StartPtr+DRIVER_NAME_LEN) != '.')
                {
                    /******************************************************/
                    /* Setup the default device name.                     */
                    /******************************************************/
                    prdu_strcpy (DeviceName_KeyWord + DRIVER_NAME_LEN + 1,
                                 Prntr_Name_Dflt);

                    /*********************************************************/
                    /* Put driverName.DeviceName into the                    */
                    /* NewIniBuffer.                                         */
                    /*********************************************************/
                    for ( pSource = DeviceName_KeyWord, j = 1,
                          pDest = NewIniBuffer; *pSource; j++ )
                    {
                        *pDest++ = *pSource++;
                    }

                    *pDest = '\0';     /* null terminator                    */

                    /******************************************/
                    /* Write PM_SPOOLER_QUEUE_DD entry for    */
                    /* OS2 1.3 and above. To do that we first */
                    /* read PPRQINFO3 structure and then we   */
                    /* change the DeviceName and DriverData   */
                    /* DeviceName. Then we write the PPRQINFO3*/
                    /* structure back out. PD00280            */
                    /******************************************/
                    if (OS2Level)
                    {
/*                      Result =  pDosPrintQGetInfo(                  CON3201 */
                        Result =  SplQueryQueue(
                                           (PSZ)FNULL,
                                           (PSZ)KeyName,
                                           3,
                                           (PSZ)FNULL,
                                           0,
                                           (PULONG)&QSize);
                        /***************************************/
                        /* Get hold of a segment to store our  */
                        /* copy of the PPRQINFO3 structure.    */
                        /* Add DeviceName length.              */
                        /***************************************/
                     /* Result = SSALLOCSEG( QSize+MAX_PRNTR_NAME,   */
                     /*                &SELECTOROF(OldQDDData), 0 ); */
                        Result = SafeSSALLOCMEM( &OldQDDData,        /*CON3201*/
                                             (QSize+MAX_PRNTR_NAME), /*CON3201*/
                                             0 );                    /*CON3201*/

                        if ( Result != DOS_OK )
                        {
                             RetVal=(USHORT)IDS_CONVERSION_NO_BUFFER;
                             goto Error_Return;
                        }

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

/*                      Result =  pDosPrintQGetInfo(                  CON3201 */
                        Result =  SplQueryQueue(
                                           (PSZ)FNULL,
                                           (PSZ)KeyName,
                                           3,
                                           (PBYTE)OldQDDData,
                                           QSize,
                                           (PULONG)&QSize);

                        QDDData_Old = (PPRQINFO3) OldQDDData;

                        QDDData_Old->pszDriverName = OldQDDData + QSize;

                        pDest = QDDData_Old->pszDriverName;

                        for (pSource = DeviceName_KeyWord;
                             *pSource; )
                        {
                             *pDest++ = *pSource++;
                        }

                        pDest = '\0';    /* null terminat*/

                        pDest = QDDData_Old->pDriverData->szDeviceName;

                        for (pSource = DeviceName_KeyWord+8;
                             *pSource; )
                        {
                             *pDest++ = *pSource++;
                        }

                        pDest = '\0';    /* null terminat*/

/*                      Result =  pDosPrintQSetInfo(                  CON3201 */
                        Result =  SplSetQueue(
                                           (PSZ)FNULL,
                                           (PSZ)KeyName,
                                           3,
                                           (PPRQINFO3)QDDData_Old,
                                           QSize+MAX_PRNTR_NAME,
                                           0);
                        if ( OldQDDData )
                             /* SSFREESEG(SELECTOROF(OldQDDData)); */
                                SSFREEMEM(OldQDDData);     /* CON3201 */
/* CON3201              Result =  pDosPrintQSetInfo(                          */
                        Result =  SplSetQueue(
                                                    (PSZ)FNULL,
                                                    (PSZ)KeyName,
                                                    (USHORT)3,
                                                    (PSZ)NewIniBuffer,
                                                    (USHORT)j,
                                                    (USHORT)13);
                    }
                    else
                    {
                       /**************************************/
                       /* Write NULL into                    */
                       /* PM_SPOOLER_QUEUE_DDDATA entry.     */
                       /**************************************/
/* CON3201             Result = pPrfWriteProfString(                          */
                       Result = PrfWriteProfileString(
                                      HINI_SYSTEMPROFILE,
                                      (PSZ)"PM_SPOOLER_QUEUE_DDDATA",
                                      (PSZ)KeyName,
                                      (PVOID)FNULL);

                    }

                }  /*if ( *(StartPtr+DRIVER_NAME_LEN)                        */

            } /* if ( !prdu_strcmpN((PBYTE)StartPtr,                         */

        } /* if ( *StartPtr != ';' )                                         */

PM_SPOOLER_QUEUE_DD_NEXT:

        while ( *KeyName++ );               /* Get next key name             */

    } /* while ( *KeyName ) */

    /**********************************************************************/
    /* Delete the old driver if there is one.                             */
    /**********************************************************************/
    if ( OldDriverExist)
    {
        /**********************************************************************/
        /* Delete the old entry. To do that we must write a null buffer.      */
        /**********************************************************************/
/*      Result = pPrfWriteProfString( HINI_SYSTEMPROFILE,             CON3201 */
        Result = PrfWriteProfileString( HINI_SYSTEMPROFILE,
                                      (PSZ)"PM_SPOOLER_DD",
                                      (PSZ)DriverNameString,
                                      (PVOID)FNULL);

        if ( !Result )                /* PD00634: Select it for all levels of */
        {                             /* OS/2.                                */
            /******************************************************************/
            /* Something went       (example: there was a job queued for this */
            /* and we could not delete the driver). We must put back the      */
            /* driver name back in the PM_SPOOLER_PRINTER entry if there is   */
            /* a new device in there. For OS2 1.2 or 1.3 only (PD00591).      */
            /******************************************************************/

            /******************************************************************/
            /* Find out the size of the PM_SPOOLER_PRINTER entry returned in  */
            /* IniSize.                                                       */
            /******************************************************************/

/*          if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE,                CON3201 */
            if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE,
                                  (PSZ)"PM_SPOOLER_PRINTER",
                                  (PSZ)FNULL,
                                  (PULONG)&IniSize) )
            {
                RetVal = (USHORT)IDS_CONVERSION_ERR;
                goto Error_Return;
            }
            /******************************************************************/
            /* Read PM_SPOOLER_PRINTER entry with a null key name. this       */
            /* returns a list of all listed logical printer name seperated    */
            /* from each other by one null. The list is terminated by two     */
            /* nulls.                                                         */
            /******************************************************************/
/*          if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,              CON3201 */
            if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                     (PSZ)"PM_SPOOLER_PRINTER",
                                     (PSZ)FNULL,
                                     (PVOID)KeyNameBuffer,
                                     (PULONG)&IniSize ) )
            {
                RetVal = (USHORT)IDS_CONVERSION_ERR;
                goto Error_Return;
            }

            KeyName =  KeyNameBuffer;
            while ( *KeyName )
            {
                /**************************************************************/
                /* Find out the size of the PM_SPOOLER_PRINTER entry.         */
                /**************************************************************/

/* CON3201      if ( !pPrfQueryProfSz( HINI_SYSTEMPROFILE,                    */
                if ( !PrfQueryProfileSize( HINI_SYSTEMPROFILE,
                                       (PSZ)"PM_SPOOLER_PRINTER",
                                       (PSZ)KeyName,
                                       (PULONG)&IniSize) )
                {
                    RetVal = (USHORT)IDS_CONVERSION_ERR;
                    goto Error_Return;
                }
                /**************************************************************/
                /* Read PM_SPOOLER_PRINTER entry with this KeyName            */
                /**************************************************************/
/*              if ( !pPrfQueryProfData( HINI_SYSTEMPROFILE,          CON3201 */
                if ( !PrfQueryProfileData( HINI_SYSTEMPROFILE,
                                         (PSZ)"PM_SPOOLER_PRINTER",
                                         (PSZ)KeyName,
                                         (PVOID)OldIniBuffer1,
                                         (PULONG)&IniSize ) )
                {
                    RetVal = (USHORT)IDS_CONVERSION_ERR;
                    goto Error_Return;
                }

                StartPtr = OldIniBuffer1;

                /**************************************************************/
                /* first ';' is for logical printer address                   */
                /**************************************************************/

                while ( *StartPtr++ != ';');

             /* (BYTE)Terminator = ','; */
                Terminator = ',';                                  /* CON3201 */

                while ( Terminator != ';' )
                {
                    PrevStartPtr = StartPtr;        /* previous start pointer */

                    if (!prdm_ReadTerminatedWordFromText(pszWord,
                                                     &Terminator,
                                                     (PBYTE)",;",
                                                     &StartPtr))
                    {
                        RetVal = (USHORT)IDS_CONVERSION_ERR;
                        goto Error_Return;
                    }

                   if ( !prdu_strcmpN( (PBYTE)pszWord,DriverNameString,
                                       DRIVER_NAME_LEN ) &&
                       ( pszWord[ DRIVER_NAME_LEN ] == '.') )
                   {
                       /***************************************************/
                       /* Copy the data into NewIniBuffer up to our       */
                       /* driver name.                                    */
                       /***************************************************/
                       for ( pDest = NewIniBuffer, pSource = OldIniBuffer1;
                             pSource < PrevStartPtr;  )
                       {
                           *pDest++ = *pSource++;
                       }
                       /***************************************************/
                       /* This is a new entry and we must put driver name */
                       /* back in there.                                 */
                       /***************************************************/
                       for ( pSource = DriverNameString;
                             *pSource; )
                       {
                            *pDest++ = *pSource++;
                       }

                       *pDest++ = ',';      /* seprator           */

                       /*******************************************/
                       /* Copy the data after our driver name.    */
                       /*******************************************/
                       for ( pSource = PrevStartPtr; *pSource; )
                       {
                           *pDest++ = *pSource++;
                       }

                       *pDest = '\0';       /* null terminator    */

                       /***************************************************/
                       /* Write PM_SPOOLER_PRINTER entry.                 */
                       /***************************************************/
/* CON3201             Result = pPrfWriteProfString( HINI_SYSTEMPROFILE,      */
                       Result = PrfWriteProfileString( HINI_SYSTEMPROFILE,
                                                     (PSZ)"PM_SPOOLER_PRINTER",
                                                     (PSZ)KeyName,
                                                     (PVOID)NewIniBuffer);

                       Terminator = ';';

                   } /* if ( !prdu_strcmpN( (PBYTE)pszWord,DriverNameString,.. */

                } /* while ( Terminator != ';' )                             */

                while ( *KeyName++ );            /* get next key name        */

             } /* while ( *KeyName ) */

             RetVal = (USHORT)IDS_CONVERSION_ERR_OLD;
/*           goto Error_Return; */                         /* PD00591        */
        }
        else                                               /* PD00591        */
        {
            if ( !Result )
            {
                RetVal = (USHORT)IDS_CONVERSION_ERR_OLD;
            }
        }
    }



Error_Return:
    /*************************************************************************/
    /* Free all the memory which may have been allocated during this         */
    /* call.  This is also where we come after an error before exiting.      */
    /*                                                                       */
    /*************************************************************************/
    if ( OldIniBuffer )
     /* SSFREESEG(SELECTOROF(OldIniBuffer)); */
        SSFREEMEM(OldIniBuffer);                                 /* CON3201 */
    if ( OldIniBuffer1 )
     /* SSFREESEG(SELECTOROF(OldIniBuffer1)); */    /* PD00675              */
        SSFREEMEM(OldIniBuffer1);                               /* CON3201 */
    if ( IniBufferQDD )
     /* SSFREESEG(SELECTOROF(IniBufferQDD)); */     /* PD00675              */
        SSFREEMEM(IniBufferQDD);                                /* CON3201 */
    if ( NewIniBuffer )
     /* SSFREESEG(SELECTOROF(NewIniBuffer)); */
        SSFREEMEM(NewIniBuffer);                                /* CON3201 */
    if ( KeyNameBuffer )
     /* SSFREESEG(SELECTOROF(KeyNameBuffer)); */
        SSFREEMEM(KeyNameBuffer);                               /* CON3201 */
    if ( IniQDDData )
     /* SSFREESEG(SELECTOROF(IniQDDData)); */
        SSFREEMEM(IniQDDData);                                  /* CON3201 */

    /*************************************************************************/
    /* Ok .. that's it.                                                      */
    /*************************************************************************/
    return (RetVal);
}
#undef TFUNC


/**********************************************************************/
/*                                                                    */
/*   FUNCTION: prdm_ReadTerminatedWordFromText                        */
/*                                                                    */
/*   PARAMETERS:                                                      */
/*                                                                    */
/*   PBYTE              pszWord;        place to read word into       */
/*   PBYTE              pTerminator;    terminator of the word read   */
/*   PBYTE              AllowedTerminators;                           */
/*   PBYTE far *        pStartPtr;      ptr to where to start reading */
/*                                                                    */
/*                                                                    */
/*   DESCRIPTION:                                                     */
/*                                                                    */
/* This function reads characters starting at StartPtr until it       */
/* reaches one of the AllowedTerminators, or until it meets a null,   */
/* then it copies the word                                            */
/* starting at StartPtr into pszWord, terminating it with a null.     */
/* The terminator that was encountered is recorded and returned.      */
/* The function returns an error if none of the AllowedTerminators    */
/* is reached within 100 characters. It cannot cope with a null       */
/* character for a terminator. StartPtr is updated so that it         */
/* points to the character after the terminator.                      */
/*                                                                    */
/* This function is used for reading spooler and printer .ini         */
/* entries. For instance if we want to read the queue associated      */
/* with a given printer (from SpoolerIniEntry) it might end with a    */
/* ; or (if more than one queue is listed) it might end in ,.         */
/* We need to know which character it ended with so that we know      */
/* whether to look for another queue or not.                          */
/*                                                                    */
/* NOTE: This function doesn't test whether the buffer pszWord is     */
/* big enough for the string being written, except for the 100        */
/* char maximum. This could cause problems if e.g. we get invalid     */
/* spooler data with a printer name of more than 32 characters.       */
/**********************************************************************/
#if 0
USHORT pascal far prdm_ReadTerminatedWordFromText ( pszWord,
                                                  pTerminator,
                                                  AllowedTerminators,
                                                  pStartPtr )

PBYTE              pszWord;
PBYTE              pTerminator;
PBYTE              AllowedTerminators;
PBYTE far *        pStartPtr;
#endif

SHORT prdm_ReadTerminatedWordFromText ( PBYTE  pszWord,            /*CON3201*/
                                        PBYTE  pTerminator,        /*CON3201*/
                                        PBYTE  AllowedTerminators, /*CON3201*/
                                        PBYTE *pStartPtr )         /*CON3201*/

{
    /******************************************************************/
    /* Local variables.                                               */
    /******************************************************************/
    SHORT       i;

    /******************************************************************/
    /* If pszWord is NULL, return an error.                           */
    /******************************************************************/
    if (!pszWord)
        return ERROR_NEG;

    for (i=0;i<100 ;i++ )
    {
        pszWord[i] = *(*pStartPtr)++;
        if (prdu_stroccur(pszWord[i], AllowedTerminators))
        {
            *pTerminator = pszWord[i];
            pszWord[i] = '\0';
            return OK;
        }
    }
    return ERROR_NEG;
}



