
/***************************************************************************
**
**    $Header:   D:/EPSLDV1/SRC/LOG/LDRSRV.CPP   1.8   20 Jun 1996 09:29:00   ZJRD  $
**
**    $Log:   D:/EPSLDV1/SRC/LOG/LDRSRV.CPP  $
** 
**    Rev 1.8   20 Jun 1996 09:29:00   ZJRD
** EasyPack/SLD Version 1.20a
** 
**    Rev 1.7   11 Jun 1996 10:28:44   ZJRD
** EasyPack/SLD Version 1.97
** 
**    Rev 1.5   05 Jun 1996 14:57:22   ZJRD
** No change.
** 
**    Rev 1.4   29 May 1996 09:35:00   ZJRD
** No change.
** 
**    Rev 1.3   16 May 1996 09:08:02   ZJRD
** No change.
** 
**    Rev 1.2   10 May 1996 09:09:34   ZJRD
** No change.
** 
**    Rev 1.1   02 May 1996 10:25:28   ZJRD
** EasyPack/SLD Version 1.92
** 
**    Rev 1.31   18 Apr 1996 13:00:10   Shirley
** No change.
** 
**    Rev 1.30   12 Apr 1996 10:35:28   Shirley
** EasyPack/SLD Version 1.90
** 
**    Rev 1.28   15 Feb 1996 08:50:42   Shirley
** No change.
** 
**    Rev 1.27   12 Feb 1996 14:05:24   Shirley
** No change.
** 
**    Rev 1.26   06 Feb 1996 15:31:56   Shirley
** No change.
** 
**    Rev 1.25   06 Feb 1996 13:45:10   Shirley
** No change.
** 
**    Rev 1.24   01 Feb 1996 10:17:58   Shirley
** No change.
** 
**    Rev 1.23   26 Jan 1996 09:16:06   Shirley
** No change.
** 
**    Rev 1.22   25 Jan 1996 13:15:58   Shirley
** No change.
** 
**    Rev 1.21   24 Jan 1996 10:33:52   Shirley
** No change.
** 
**    Rev 1.20   23 Jan 1996 11:28:26   Shirley
** No change.
** 
**    Rev 1.19   18 Jan 1996 10:15:10   Shirley
** No change.
** 
**    Rev 1.18   15 Jan 1996 16:17:18   Shirley
** No change.
** 
**    Rev 1.17   04 Jan 1996 11:08:22   Shirley
** EasyPack/SLD Version 0.34
** 
**    Rev 1.16   30 Nov 1995 09:14:12   Shirley
** No change.
** 
**    Rev 1.15   28 Nov 1995 15:33:06   Shirley
** No change.
** 
**    Rev 1.14   21 Nov 1995 11:23:34   Shirley
** No change.
** 
**    Rev 1.13   13 Nov 1995 09:25:56   Shirley
** No change.
** 
**    Rev 1.12   12 Nov 1995 11:29:36   Shirley
** No change.
** 
**    Rev 1.11   08 Nov 1995 16:33:02   Shirley
** No change.
** 
**    Rev 1.10   08 Nov 1995 12:45:00   Shirley
** EasyPack/SLD Version 0.22
** 
**    Rev 1.9   02 Nov 1995 10:03:32   Shirley
** No change.
** 
**    Rev 1.8   27 Oct 1995 16:46:42   Shirley
** No change.
** 
**    Rev 1.7   27 Oct 1995 13:45:42   Shirley
** No change.
** 
**    Rev 1.6   25 Oct 1995 14:27:16   Shirley
** No change.
** 
**    Rev 1.5   18 Oct 1995 14:51:26   Shirley
** No change.
** 
**    Rev 1.4   13 Oct 1995 13:20:50   Shirley
** No change.
** 
**    Rev 1.3   29 Sep 1995 09:51:36   Shirley
** No change.
** 
**    Rev 1.2   20 Sep 1995 10:53:34   Shirley
** EasyPack/SLD Version 0.1b
** 
**    Rev 1.1   15 Sep 1995 09:48:16   Shirley
** No change.
** 
**    Rev 1.0   07 Sep 1995 09:54:32   Shirley
** Initial revision.
**
****************************************************************************/

/****************************************************************************
**
**  Name:  LDRSRV.CPP
**
**  Description:
**      Some foundamental function for Loader Server.
**
**  Status:  CODED
**
**    Rev 1.0   1 Sept. 1995 8:30:00am   Gates Hua, Jamoon Zhou
** Initial revision.
**
**  Copyright (C) 1995 Microtek International.  All rights reserved.
**
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#include "stdafx.h"
//#include <ctype.h>
#include <io.h>
//#include <sys\timeb.h>
#include <sys\types.h>
#include <sys\stat.h>
#include "symblsvr.h"
#include "ldr.h"                      

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/
/***************************************************************************
*                                                                          *
*  GetLpFileRef - Get load file reference string                           *
*  parameter :                                                             *
*       str  --  load file reference string ( output )                     *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::GetLpFileRef( CString& str )
{                                   
    if ( IsSymbolLoaded() != TRUE ) return -1;
    str = m_lpFileRef ;
    return GOOD;
}


/***************************************************************************
*                                                                          *
*  UngetOneByte - Get one byte from load buffer                            *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::UngetOneByte()
{                                        
    if ( GOOD != SeekLoadFile(-1L,1) ) return FAILURE;
    return GOOD;
}
    
/***************************************************************************
*                                                                          *
*  GetOneByte - Get one byte from load buffer                              *
*  parameter :                                                             *
*       ch  --  byte pointer ( output )                                    *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::GetOneByte(U8 *ch)
{                                   
    if (m_uBufPos < m_uBufSize) {
        *ch = m_lpBuffer[m_uBufPos];
        m_uBufPos++;
    }
    else {              
        m_uBufInFilePos += m_uBufSize;
        m_uBufSize = (U16)_lread(m_loaderFile , m_lpBuffer , LDR_BUFSIZE);
        if ( m_uBufSize == 0 ) return( FAILURE );
        *ch = *m_lpBuffer;
        m_uBufPos = 1;
    }   
    return GOOD;
}

/***************************************************************************
*                                                                          *
*  PeekByte - Peek one byte from load buffer                              *
*  parameter :                                                             *
*       ch  --  byte pointer ( output )                                    *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::PeekByte(U8 *ch)
{                                   
    if (m_uBufPos < m_uBufSize) {
        *ch = m_lpBuffer[m_uBufPos];
    }
    else {              
        m_uBufInFilePos += m_uBufSize;
        m_uBufSize = (U16)_lread(m_loaderFile , m_lpBuffer , LDR_BUFSIZE);
        if ( m_uBufSize == 0 ) return( FAILURE );
        *ch = *m_lpBuffer;
        m_uBufPos = 0;
    }   
    return GOOD;
}
    
    
/***************************************************************************
*                                                                          *
*  GetBytes - Get n byte from load buffer                                  *
*  parameter :                                                             *
*       ch  --  byte pointer ( output )                                    *
*       num  --  byte number ( input )                                     *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::GetBytes(U8 *ch , int num)
{                                   
    int i , j;
    U8 *temp;
    
    temp = ch;
    i = 0;

    while ( i < num ) {
        if (m_uBufPos >= m_uBufSize) {
            m_uBufInFilePos += m_uBufSize;
            m_uBufSize = (U16)_lread(m_loaderFile , 
                            m_lpBuffer , LDR_BUFSIZE);
            if ( m_uBufSize == 0 ) return( FAILURE );
            m_uBufPos = 0;
        }
        j = m_uBufSize - m_uBufPos;
        j = ( j > (num - i) ) ? (num - i) : j;
        memcpy( &ch[i] , &m_lpBuffer[m_uBufPos] , j);
        i += j;
        m_uBufPos += (U16) j;
    }        
    return GOOD;
}
    
/***************************************************************************
*                                                                          *
*  GetName - Get one name from load buffer                                 *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
unsigned char *LoaderServer::GetName(void)
{                                   
    U8 ch;
    unsigned char *str;
    
    if ( GetOneByte(&ch) == FAILURE ) {
        return 0;
    }
    str = new unsigned char[ch+1];
//    ASSERT (str);
    if ( str == 0 ) {
        return 0;
    }
    if ( GetBytes(str , ch) == -1 ) {
        delete str;
        return 0;
    }
    str[ch] = '\0';
    if ( ch > MAX_SYMNAME_LENGTH ) {
        str[MAX_SYMNAME_LENGTH] = '\0';
    }
    
    return str;
}
    
/***************************************************************************
*                                                                          *
*  GetFileName - split a string to a file name and path                    *
*  parameter :                                                             *
*       lpFileRef  --  string include name and path .                      *
*       mode       --  0  split to m_lpFileName and m_lpFileRef            *
*                      1  split to m_lpModuleName and m_lpModuleRef        *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::GetFileName(LPSTR lpFileRef, int mode) {
    int found = 0;
    int i;
    int pathLength;
    LPSTR tmpPtr = lpFileRef;
             
        
    if ( (mode != 0)&&(mode != 1) ) 
        return(FAILURE);
                     
    if ((pathLength = lstrlen(lpFileRef)) == 0)
        return(GOOD);

//  Algorithm:
//      Search from right to left for the last slash or a colon,
//      if found
//          copy name and path
//      else only name is specified
//          copy name and set reference to empty tring.
//      return results

    for (i = pathLength; i > 0 && !found; i--) {
        if ((i < pathLength) && (((char)*(tmpPtr+i) == '\\') ||
            ((char)*(tmpPtr+i) == '/') || ((char)*(tmpPtr+i) == ':')) ) {
            if ( mode == 0 ) {
                m_lpFileName = new char[pathLength - i];
//              ASSERT( m_lpFileName );
                if ( m_lpFileName == 0 ) {
                    return( FAILURE );
                }
                lstrcpy(m_lpFileName , (LPSTR)(tmpPtr+i+1) );
                m_lpFileRef = new char[i+2];
//              ASSERT( m_lpFileRef );
                if ( m_lpFileRef  == 0 ) {
                    return( FAILURE );
                }
                *(tmpPtr+i+1) = '\0';
                lstrcpy(m_lpFileRef, (LPSTR)tmpPtr); 
                found = 1;
            }
            else if ( mode == 1 ) {
                m_lpModuleName = new char[pathLength - i];
//              ASSERT( m_lpModuleName );
                if ( m_lpModuleName == 0 ) return( FAILURE );
                lstrcpy(m_lpModuleName , (LPSTR)(tmpPtr+i+1) );
                m_lpModuleRef = new char[i+2];
//              ASSERT( m_lpModuleRef );
                if ( m_lpModuleRef == 0 ) return( FAILURE );
                *(tmpPtr+i+1) = '\0';
                lstrcpy(m_lpModuleRef, (LPSTR)tmpPtr); 
                found = 1;
            }                     
        }
    }

/* There is no path reference in lpFileRef */

    if (!found) {
        if ( mode == 0 ) {
            m_lpFileName = new char[pathLength + 1];
//              ASSERT( m_lpFileName );
            if ( m_lpFileName == 0 ) return( FAILURE );
            lstrcpy(m_lpFileName , lpFileRef);
            m_lpFileRef = 0;
        }
        else if ( mode == 1 ) {              
            m_lpModuleName = new char[pathLength + 1];
//          ASSERT( m_lpModuleName );
            if ( m_lpModuleName == 0 ) return( FAILURE );
            lstrcpy(m_lpModuleName , lpFileRef);
            m_lpModuleRef = 0;
        }
    }
    return(GOOD);
} /* GetFileName */
    
/***************************************************************************
*                                                                          *
*  OpenLoadFile - Open load file                                           *
*  parameter :                                                             *
*       None (Information all in class LoaderServer)                       *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::OpenLoadFile(void)
{                       
    OFSTRUCT pof;
    int len;        
    CString filename;
                     
    filename = m_lpFileRef;
    filename += m_lpFileName;                         
//    if ((m_loaderFile=_lopen(filename.GetBuffer(filename.GetLength()), READ))
//         == HFILE_ERROR)
    if ((m_loaderFile=_lopen(filename.GetBuffer(filename.GetLength()), 
        READ | OF_SHARE_DENY_WRITE)) == HFILE_ERROR)
        return ( FAILURE );
    OpenFile(filename.GetBuffer(filename.GetLength()), &pof, OF_PARSE);
    len = lstrlen(pof.szPathName); 
    if (m_lpFileRef) delete m_lpFileRef;
    m_lpFileRef = new char[len+2];      
//    ASSERT( m_lpFileRef );
    if ( m_lpFileRef == 0 ) return ( FAILURE );
    lstrcpy((LPSTR)m_lpFileRef, (LPSTR)&pof.szPathName);
    m_fileLen = _filelength(m_loaderFile);
    
    if (m_lpBuffer) delete m_lpBuffer;
    m_lpBuffer = new U8[LDR_BUFSIZE];
//  ASSERT( m_lpBuffer );
    if ( m_lpBuffer == 0 ) return( FAILURE );
    m_uBufInFilePos = 0;
    m_uBufPos = 0;
    m_uBufSize = 0;
    
   	struct _stat s;
	if (_fstat(m_loaderFile, &s) == 0)
		m_ctime = CTime(s.st_ctime);

    return(GOOD);
}

/***************************************************************************
*                                                                          *
*  CloseLoadFile - Close load file                                         *
*  parameter :                                                             *
*       None (Information all in class LoaderServer)                       *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::CloseLoadFile(void)
{           
    if (_lclose(m_loaderFile) != 0)
        return ( FAILURE );
    m_loaderFile = -1;
    if (m_lpBuffer) delete m_lpBuffer;
    m_lpBuffer = 0;
    m_uBufInFilePos = 0;
    m_uBufPos = 0;
    m_uBufSize = 0;
    return(GOOD);
}

/***************************************************************************
*                                                                          *
*  SeekLoadFile - lseek load file                                          *
*  parameter :                                                             *
*       off -- file pointer offset                                         *
*       nOrg -- Specifies the start position and direction of the pointer  *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::SeekLoadFile(long off , int nOrg)
{                                               
    if ( nOrg == 1 ) {
        long i;
        i = off + (long)m_uBufPos;
        if ( (i>=0L) && (i<(long)m_uBufSize) ) {
            m_uBufPos = (U16) i;
            return GOOD;
        }
        nOrg = 0;
        off = (long) (m_uBufInFilePos+m_uBufPos) + off;
    }
    if ((m_uBufInFilePos=_llseek(m_loaderFile,off,nOrg))==HFILE_ERROR)
        return ( FAILURE );
    m_uBufSize = (U16) _lread(m_loaderFile , m_lpBuffer , LDR_BUFSIZE);
    if ( m_uBufSize == 0 ) return( FAILURE );
    m_uBufPos = 0;
    return( GOOD );
}            

/***************************************************************************
*                                                                          *
*  BinToU16 - convert 2 byte to U16 value                                  *
*  parameter :                                                             *
*       s  --  byte pointer ( input )                                      *
*  return value :                                                          *
*       U16 value                                                          *
*                                                                          *
***************************************************************************/
U16 LoaderServer::BinToU16(U8 *s)
{
    U16 ui ;
       
    if ( m_absflag ) {
        ui = (U16) s[1] ;
        ui = (ui<<8) + (U8)s[0];
    }
    else {   
        ui = (U16) s[0];
        ui = (ui<<8) + (U8)s[1];
    }
    return (ui);
}

/***************************************************************************
*                                                                          *
*  BinToU32 - convert 4 byte to U32 value                                  *
*  parameter :                                                             *
*       s  --  byte pointer ( input )                                      *
*  return value :                                                          *
*       U32 value                                                          *
*                                                                          *
***************************************************************************/
U32 LoaderServer::BinToU32(U8 *s)
{
    U32 ul;

    if ( m_absflag ) {
        ul = (U32) s[3];
        ul = (ul<<8) + (U8) s[2];
        ul = (ul<<8) + (U8) s[1];
        ul = (ul<<8) + (U8) s[0];
    }
    else {
        ul = (U32) s[0];
        ul = (ul<<8) + (U8) s[1];
        ul = (ul<<8) + (U8) s[2];
        ul = (ul<<8) + (U8) s[3];
    }
    return (ul);
}


/***************************************************************************
*                                                                          *
*  VALToU32 - convert OMF251 5 bytes VALUE to U32 value                    *
*  parameter :                                                             *
*       s  --  byte pointer ( input )                                      *
*             s[0] = 0 value in unit bytes                                 *
*                  = 1 value in unit bits                                  *
*  return value :                                                          *
*       U32 value                                                          *
*                                                                          *
***************************************************************************/
/*
U32 LoaderServer::VALToU32(U8 *s)
{
    U32 ul;

    if ( m_absflag ) {
        ul = (U32) s[4];
        ul = (ul<<8) + (U8) s[3];
        ul = (ul<<8) + (U8) s[2];
        ul = (ul<<8) + (U8) s[1];
    }
    else {
        ul = (U32) s[1];
        ul = (ul<<8) + (U8) s[2];
        ul = (ul<<8) + (U8) s[3];
        ul = (ul<<8) + (U8) s[4];
    }
    return (ul);
}
*/
    
/***************************************************************************
*                                                                          *
*  ModuleNodeInit - initial a moduleBlock                                  *
*  parameter :                                                             *
*       None                                                               *
*  return value :                                                          *
*       0  ---  OK                 -1  ---  failure                        *
*                                                                          *
***************************************************************************/
int LoaderServer::ModuleNodeInit(void)
{
    m_modNode.codeaddr.segType = (SEGMENTTYPE) SEG_CODE;
    m_modNode.codeaddr.startAddr = DEFAULT_START_ADDR;
    m_modNode.codeaddr.endAddr = DEFAULT_END_ADDR;
    m_modNode.time.year = -1;
    m_modNode.time.hour = -1;
    m_modNode.offset = 0;
    m_modNode.symno = 0;
    m_modNode.blkcnt = 0;
    m_modNode.linecnt = 0;
    m_modNode.scope = 0;
    m_modNode.tfileoffset = 0;
    return GOOD;
}   

/******************************** E O F ***********************************/
