⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 udcfgbin.c

📁 工业组态软件modbus驱动源代码, 包括帮助文件.共享.
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Header: "%n Ver=%v  %f  LastEdit=%w  Locker=%l" */
/* "UDCFGBIN.C Ver=2  20-Nov-97,17:36:02  LastEdit=JIMV  Locker=***_NOBODY_***" */
/***********************************************************************\
*                                                                       *
*       Copyright Wonderware Software Development Corp. 1992-1997       *
*                                                                       *
*               ThisFileName="L:\ww\dde_serv\src\udsample\udcfgbin.c"   *
*               LastEditDate="1997 Nov 20  17:36:00"                    *
*                                                                       *
\***********************************************************************/

/****************************************************************************\
   These routines support reading and writing CFG files as binary structures
\****************************************************************************/

#include <windows.h>
#include <io.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <stat.h>

#include "ntconv.h"
#include "hmemcpy.h"
#include "chainmgr.h"
#include "config.h"
#include "uddefs.h"

/***********************************************************************\
    The routines in this section support storing and scanning a server
    configuration file in the form of binary structures.  Writing and
    reading such structures is easy, although there are a few caveats.

    1. When the binary image of a configuration structure is read from
       or written to a file, differences can arise regarding alignment
       and packing.  This is an issue for Windows NT, where words must
       be on even boundaries and longwords must be on longword (i.e.
       multiple of 4) boundaries.  Structure members may be in a different
       order than specified, and there may be padding between the members.

       One approach is to design the configuration structure to match
       these requirements.  However, the approach used here is less
       susceptible to mistakes in alignment when a structure is changed.

       Each individual structure member of the configuration item is
       read from or written to the disk file, instead of transferring
       the entire structure in a single block.  Since this could lead
       to major inefficiencies in disk access, a buffered file approach
       is used, where blocks of a fixed size are transferred from and
       to the disk, and the individual items are read or written using
       the buffers.  The BUFFERED_FILE structure and routines make this
       buffering and flushing transparent to the programmer.

    2. If the configuration structures change, the functions for
       reading and writing those structures must also be updated.
       In addition, for backward compatibility, the routines for reading
       the structures should also be able to READ previous versions of
       those structures, then convert the configuration to the new format.

       When such a format change is made, the VERSION of the CFG file
       should be updated, and functions such as ReadTopicCfgStruct()
       and ReadBoardCfgStruct() should check the version of the file
       that is being READ and use the corresponding format for input.
       Once the old-format structure has been read in, the function
       should then convert it to the current format -- either directly
       or by daisy-chaining intermediate stages of conversion.

       Handling changes to the VERSION of the CFG file saves the user
       a lot of trouble; but it can be something of a software maintenance
       headache.  One way to reduce this maintenance problem is to use
       routines that read and write CFG files in ASCII text format.
\***********************************************************************/

/********************************************************************
 * External Variables                                               *
 ********************************************************************/

extern BOOL bUsesComPorts;      /* =TRUE if ComPorts are used */
extern BOOL bUsesBoards;        /* =TRUE if Boards are used */
extern WW_CP_PARAMS comPort[];  /* array of comport configurations */
extern CHAIN BoardCfgList;      /* linked list of board configurations */
extern CHAIN TopicCfgList;      /* linked list of topic configurations */

/********************************************************************
 * Prototypes                                                       *
 ********************************************************************/

static BOOL WINAPI ReadPortCfgStruct ( BUFFERED_FILE *SourceFile,
                                       LPWW_CP_PARAMS lpCpParams, long lVersion );
static BOOL WINAPI ReadBoardCfgStruct( BUFFERED_FILE *SourceFile,
                                       LPBOARD_CFG lpBoardCfg, long lVersion );
static BOOL WINAPI ReadTopicCfgStruct( BUFFERED_FILE *SourceFile,
                                       LPTOPIC_CFG lpTopicCfg, long lVersion );
static BOOL WINAPI WritePortCfgStruct ( BUFFERED_FILE *DestFile, LPWW_CP_PARAMS lpCpParams );
static BOOL WINAPI WriteBoardCfgStruct( BUFFERED_FILE *DestFile, LPBOARD_CFG lpBoardCfg );
static BOOL WINAPI WriteTopicCfgStruct( BUFFERED_FILE *DestFile, LPTOPIC_CFG lpTopicCfg );

static UINT WINAPI ConvertOldBaud     ( int iOldBaud     );
static UINT WINAPI ConvertOldParity   ( int iOldParity   );
static UINT WINAPI ConvertOldStopbits ( int iOldStopbits );

/***********************************************************************
 ***********************************************************************
 * Routines for reading CFG files as binary structures                 *
 ***********************************************************************
 ***********************************************************************/

/***********************************************************************/
/** read configuration from file as binary structures
    return TRUE if successful **/

BOOL
WINAPI
ReadConfigsStruct (BUFFERED_FILE *SourceFile, long lVersion)
{
    BOOL         ok;
    int          i;
    WORD         bAnyMore;
    BOARD_CFG    BoardCfg;
    LPBOARD_CFG  lpBoardCfg;
    TOPIC_CFG    TopicCfg;
    LPTOPIC_CFG  lpTopicCfg;

    /* initialize return value */
    ok = TRUE;

    if (bUsesComPorts) {
        /* read the first 4 com ports first (old style) */
        for( i=1; ok && (i<=4); i++) {
            ok = ReadPortCfgStruct( SourceFile, &comPort[i-1], lVersion );
        }
    }

    /* read the boards first */
    if (bUsesBoards) {
        if( ok ) {
            do {
                /* check whether any more boards are in file */
                ok = ReadNextAnyMore( SourceFile, &bAnyMore );
                if (ok && bAnyMore) {
                    /* read board structure from file */
                    ok = ReadBoardCfgStruct( SourceFile, (LPBOARD_CFG) &BoardCfg, lVersion );
                    if( ok ) {
                        /* create structure for new board */
                        lpBoardCfg = BoardCfgAlloc();
                        if (lpBoardCfg == (LPBOARD_CFG) NULL) {
                            ok = FALSE;
                            break;
                        }
                        /* copy board settings into structure */
                        *lpBoardCfg = BoardCfg;
                        /* add board to list */
                        BoardCfgAddToList( lpBoardCfg );
                    }
                }
            } while (ok && bAnyMore);
        } /* end if - ok */
    }

    /* read the topics next */
    if (ok) {
        do {
            /* check whether any more topics are in file */
            ok = ReadNextAnyMore( SourceFile, &bAnyMore );
            if (ok && bAnyMore) {
                /* read topic structure from file */
                ok = ReadTopicCfgStruct( SourceFile, (LPTOPIC_CFG) &TopicCfg, lVersion );
                if( ok ) {
                    /* create structure for new topic */
                    lpTopicCfg = TopicCfgAlloc();
                    if (lpTopicCfg == (LPTOPIC_CFG) NULL) {
                        ok = FALSE;
                        break;
                    }
                    /* copy topic settings to structure */
                    *lpTopicCfg = TopicCfg;
                    /* add topic to list */
                    TopicCfgAddToList(lpTopicCfg);
                }
            }
        } while (ok && bAnyMore);
    } /* end if - ok */

    if (bUsesComPorts) {
        /* now read in ports 5 thru MAX_COMPORT, if they exist */
        if ( ok && ReadNextAnyMore( SourceFile, &bAnyMore )  ) {
            for ( i = 5; ok && bAnyMore && (i <= MAX_COMPORT); i++ ) {
                ok = ReadPortCfgStruct( SourceFile, &comPort[i-1], lVersion );
                if( ok ) {
                    ok = ReadNextAnyMore( SourceFile, &bAnyMore );
                }
            }
        } /* end if - ok */
    }

    /* indicate success or failure */
    return (ok);
} /* ReadConfigsStruct */

/***********************************************************************/
/* read the config COM port structure as a binary image;
   return TRUE if successful */

static
BOOL
WINAPI
ReadPortCfgStruct( BUFFERED_FILE  *SourceFile,
                   LPWW_CP_PARAMS lpCpParams,
                   long           lVersion )
{
    WW_CP_PARAMS  vcur;
    BOOL          ok;
    /* define version 1 config file port record structure */
    typedef struct {
        char       cp_name[6];
        short      cp_baud;
        short      cp_stop;
        short      cp_parity;
        short      cp_replyTimeout;
    }  VER1_COMPORT_CFG;

    /* initialize return value */
    ok = TRUE;

    /* handle according to version of configuration file */
    switch( lVersion ) {
        case 1:     /* version 1 */
          {
            VER1_COMPORT_CFG v1;
            /* clear contents of memory structure */
            memset (&v1, 0, sizeof(v1));
            /* attempt to read version 1 structure from file */
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_name, sizeof(v1.cp_name));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_baud, sizeof(v1.cp_baud));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_stop, sizeof(v1.cp_stop));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_parity, sizeof(v1.cp_parity));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_replyTimeout, sizeof(v1.cp_replyTimeout));
            /* convert version 1 structure to current version */
            SetupDefaultPortCfgParams (&vcur);
            vcur.uBaud         = ConvertOldBaud     (v1.cp_baud);
            vcur.uStopBits     = ConvertOldStopbits (v1.cp_stop);
            vcur.uParity       = ConvertOldParity   (v1.cp_parity);
            vcur.uReplyTimeout = v1.cp_replyTimeout;
            /* return contents of structure */
            *lpCpParams = vcur;
            break;
          }
        default:    /* current version */
            /* clear contents of memory structure */
            memset (&vcur, 0, sizeof(vcur));
            /* attempt to read current version structure from file */
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &vcur, sizeof(vcur));
            /** Note:  The WW_CP_PARAMS structure happens to be identically
                aligned on both Win16 and Win32 platforms, so direct reads
                and writes of the entire structure are OK. **/
            /* return contents of structure */
            *lpCpParams = vcur;
            break;
    } /* switch */

    /* indicate success or failure */
    return (ok);
} /* ReadPortCfgStruct */

/***********************************************************************/
/* read the config BOARD_CFG structure as a binary image;
   return TRUE if successful */

static
BOOL
WINAPI
ReadBoardCfgStruct( BUFFERED_FILE *SourceFile,
                    LPBOARD_CFG   lpBoardCfg,
                    long          lVersion )
{
    BOARD_CFG      vcur;
    BOOL           ok;
    /* define version 1 config file board record structure */
    typedef struct {
        void FAR  *cp_next;
        DWORD      cp_channelID;
        char       cp_name[33];
        WORD       cp_memSegment;
        WORD       cp_ioAddr;
        short      cp_replyTimeout;
    } VER1_BOARD_CFG;

    /* initialize return value */
    ok = TRUE;

    /* handle according to version of configuration file */
    switch( lVersion ) {
        case 1:     /* version 1 */
          {
            VER1_BOARD_CFG v1;
            /* clear contents of memory structure */
            memset (&v1, 0, sizeof(v1));
            /* attempt to read version 1 structure from file */
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_next, sizeof(v1.cp_next));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_channelID, sizeof(v1.cp_channelID));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_name[0], sizeof(v1.cp_name));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_memSegment, sizeof(v1.cp_memSegment));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_ioAddr, sizeof(v1.cp_ioAddr));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &v1.cp_replyTimeout, sizeof(v1.cp_replyTimeout));
            /* convert version 1 structure to current version */
            memset (&vcur, 0, sizeof(vcur));
            vcur.cp_channelID    = v1.cp_channelID;
            strncpy (vcur.cp_name, v1.cp_name, sizeof(vcur.cp_name)-1);
            vcur.cp_replyTimeout = v1.cp_replyTimeout;
            vcur.cp_memSegment   = v1.cp_memSegment;
            vcur.cp_ioAddr       = v1.cp_ioAddr;
            /* return contents of structure */
            *lpBoardCfg = vcur;
            break;
          }
        default:    /* current version */
            /* clear contents of memory structure */
            memset (&vcur, 0, sizeof(vcur));
            /* attempt to read current version structure from file */
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &vcur.cp_chainLink, sizeof(vcur.cp_chainLink));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &vcur.cp_channelID, sizeof(vcur.cp_channelID));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &vcur.cp_name, sizeof(vcur.cp_name));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &vcur.cp_memSegment, sizeof(vcur.cp_memSegment));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &vcur.cp_ioAddr, sizeof(vcur.cp_ioAddr));
            if (ok)
                ok = ReadNextBuffer( SourceFile, (char *) &vcur.cp_replyTimeout, sizeof(vcur.cp_replyTimeout));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -