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

/////////////////////////////////////////////////////////////////////////////
//
//  File name: MEMSRCH.CPP
//
//  Description: The implementation file for the class: CMemorySearch.
//
//  Author: Chen Jun
//
//  Date: 04/29/95
//
//  Modification:
//      1. 04/29/95, Initial version of the class: CMemorySearch.
//
/////////////////////////////////////////////////////////////////////////////


/////////////////////////////////////////////////////////////////////////////
// Include files.
#include "stdafx.h"
#include "resource.h"

#include "memsrch.h"
#include "hosterrs.h"
extern RETCODE EXPORT ErrGetErrorText(U32 errorCode, LPSTR lpszError ...);
extern RETCODE EXPORT ErrGetErrorText(U32 errorCode, CString& strError ...);


/////////////////////////////////////////////////////////////////////////////
// Debug flags.
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif


/////////////////////////////////////////////////////////////////////////////
// Type definitions.


/////////////////////////////////////////////////////////////////////////////
// Macro definitions.


/////////////////////////////////////////////////////////////////////////////
// Global variables.


/////////////////////////////////////////////////////////////////////////////
// Static variables.


/////////////////////////////////////////////////////////////////////////////
// External variables.


/////////////////////////////////////////////////////////////////////////////
// Global function prototypes.
void SearchCmd(int nArgc, char* pszArgv[]);
BOOL MemServerSearch(unsigned short uStart, unsigned short uEnd,
    unsigned char uchType, char* pszPattern, int nInsensitive,
    unsigned short& uRetAddr);


/////////////////////////////////////////////////////////////////////////////
// Local function prototypes.


/////////////////////////////////////////////////////////////////////////////
// External function prototypes.
#ifndef _SERVER_NO_ABI
    extern STATUS AbiSearch(ADDR addr1, ADDR addr2, 
                            SEARCH_INFO searchInfo, ADDR* retAddr);
#endif  // _SERVER_NO_ABI
extern BOOL GetCpuStatus(unsigned char &);
extern void ShowLine(char *);


/////////////////////////////////////////////////////////////////////////////
// Executable codes.

/////////////////////////////////////////////////////////////////////////////
// Public functions.

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   SearchCmd().
//
//  Description: The main control routine of Search command.
//
//  Input:  nArgc - Number of input parameters.
//          pszArgv - Input parameters.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void SearchCmd(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( 4 == nArgc || 5 == nArgc || 6 == nArgc );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    // Search EMM contents.
   char tempstr[128];    
    CMemorySearch* pMemorySearch = new CMemorySearch;
    if ( !pMemorySearch ) {
        AfxMessageBox("Insufficient Memory !");
        ASSERT( FALSE );
        return;
    }
    else {
       unsigned char result;         
       if ( ::GetCpuStatus(result) ) {
          if ( 1/*STATUS_GO*/ == result ) {
            ::ErrGetErrorText( ER_GOFLY_ERR_MSG, tempstr );
            ::ShowLine (/*"EP running. Stop EP first"*/tempstr);
          }    
          else {
           pMemorySearch->SearchAction(nArgc, pszArgv);
          }           
       }   
       delete pMemorySearch;       
    }

//    CMemorySearch objSearch;
//    objSearch.MemorySearch(nArgc, pszArgv);


}   // End of SearchCmd().


// Memory Search server.
BOOL MemServerSearch(unsigned short uStart, unsigned short uEnd,
    unsigned char uchType, char* pszPattern, int nInsensitive,
    unsigned short& uRetAddr)
{
    // Assertion of the input parameters.

    // Search EMM contents.
    CMemorySearch* pMemorySearch = new CMemorySearch;
    if ( !pMemorySearch ) {
        AfxMessageBox("Insufficient Memory !");
        ASSERT( FALSE );
        return (FALSE);
    }
    else {
        BOOL isMatch = pMemorySearch->MemServerSearch(uStart, uEnd, uchType,
            pszPattern, nInsensitive, uRetAddr);
        delete pMemorySearch;
        return (isMatch);
    }

}   // End of MemServerSearch().


/////////////////////////////////////////////////////////////////////////////
// Implementation codes of class: CMemorySearch.

/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CMemorySearch::CMemorySearch().
//
//  Description: The construction of the class: CMemorySearch.
//
//  Input:  None.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
CMemorySearch::CMemorySearch()
{

}   // End of CMemorySearch::CMemorySearch().


/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CMemorySearch::~CMemorySearch().
//
//  Description: The destruction of the class: CMemorySearch.
//
//  Input:  None.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
CMemorySearch::~CMemorySearch()
{

}   // End of CMemorySearch::~CMemorySearch().



/////////////////////////////////////////////////////////////////////////////
//
//  Name:   CMemorySearch::SearchAction().
//
//  Description: Search EMM.
//
//  Input:  None.
//
//  Output: None.
//
//  Return: None.
//
/////////////////////////////////////////////////////////////////////////////
void CMemorySearch::SearchAction(int nArgc, char* pszArgv[])
{
    // Assertion of the input parameters.
    ASSERT( 4 == nArgc || 5 == nArgc || 6 == nArgc );
    for ( int i = 0; i < nArgc; i++ ) {
        ASSERT( pszArgv[i] );
    }
    
    // Set Start address, End address & Pattern.
    switch ( nArgc ) {
        case 4:
            // Search adr1 adr2 {"string"|data}
            SetAddrVar(pszArgv[1], m_StartAddr);
            SetAddrVar(pszArgv[2], m_EndAddr);
            SetPattern(pszArgv[3]);
            SetInsensitive(0);
            break;
        case 5:
            if ( !stricmp(pszArgv[3], "INSENSITIVE") ) {
                // SEarch adr1 adr2 Insensitive "string"
                SetAddrVar(pszArgv[1], m_StartAddr);
                SetAddrVar(pszArgv[2], m_EndAddr);
                SetPattern(pszArgv[4]);
                SetInsensitive(1);
            }
            else {
                // SEarch adr1 Length length {"string"|data..}
                SetAddrVar(pszArgv[1], m_StartAddr);
                SetAddrVar(pszArgv[1], pszArgv[3], m_EndAddr);
                SetPattern(pszArgv[4]);
                SetInsensitive(0);
            }
            break;
        case 6:
            // SEarch adr1 Length length Insensitive "string"
            SetAddrVar(pszArgv[1], m_StartAddr);
            SetAddrVar(pszArgv[1], pszArgv[3], m_EndAddr);
            SetPattern(pszArgv[5]);
            SetInsensitive(1);
            break;
        default:
            ASSERT( FALSE );
            return;
    }
    
    // Set SearchInfo.
    SetSearchInfo();
    
    // Set the default memory space.
    if ( ':' != pszArgv[1][1] ) {
        m_StartAddr.m_uchType = MEM_EXTERNAL;
    }
    m_EndAddr.m_uchType = m_StartAddr.m_uchType;
    
    // Memory Search kernel routine.
    MemorySearchKernel();
        
}   // End of CMemorySearch::SearchAction().


void CMemorySearch::SetInsensitive(int nInsensitive)
{
    // Assertion of the input parameters.
    ASSERT( 0 == nInsensitive || 1 == nInsensitive );
    
    // Set the insensitive flag.
    m_uchInsensitive = (unsigned char) nInsensitive;

}   // End of CMemorySearch::SetInsensitive().


void CMemorySearch::SetPattern(char* pszPattern)
{
    // Assertion of the input parameters.
    ASSERT( pszPattern );
    
    // Set the pattern buffer.
    if ( '\"' == *pszPattern ) {
        // Set "string".
        m_chPatternLen = (char)(strlen(pszPattern) - 2);
        pszPattern[m_chPatternLen+1] = 0;
        strcpy(m_pchSearch, pszPattern+1);
    }
    else {
        // Set Data: "12 34 ".
        m_chPatternLen = 0;
        while ( *pszPattern ) {
            char pszData[3];
            memset(pszData, 0, sizeof(pszData));
            for ( int i = 0; i <= 2; i++ ) {
                if ( ' ' != *pszPattern ) {
                    pszData[i] = *pszPattern++;
                }
                else {
                    pszPattern++;
                    break;
                }
            }
            StrToVar(pszData);
            m_pchSearch[m_chPatternLen++] = (BYTE) m_ulVar;
        }
    }

}   // End of CMemorySearch::SetPattern().


void CMemorySearch::SetSearchInfo(void)
{
    // Assertion of the input parameters.
    ASSERT( 0 == m_uchInsensitive || 1 == m_uchInsensitive );
    ASSERT( m_chPatternLen >= 1 && m_chPatternLen <= MAX_SEARCH_SIZE );
    
    // Set m_SearchInfo.
    m_SearchInfo.uchInsensitive = m_uchInsensitive;
    m_SearchInfo.chPatternLen = m_chPatternLen;
    for ( int i = 0; i < m_chPatternLen; i++ ) {
        m_SearchInfo.pchPattern[i] = m_pchSearch[i];
    }

}   // End of CMemorySearch::SetSearchInfo().


void CMemorySearch::MemorySearchKernel(void)
{
    // Assertion of the input parameters.
    
    // Call Abi routine.
    m_nErrorID = AbiSearch((ADDR&) m_StartAddr, (ADDR&) m_EndAddr,
                           (SEARCH_INFO&) m_SearchInfo, &(ADDR&) m_RetAddr);
    if ( 5 == m_nErrorID ) {
        // No matched data.
        ShowLine("No such data matched.");
        m_bServerRet = FALSE;
    }
    else if ( 6 == m_nErrorID ) {
        // The data matched.
        DisplayMatchedAddr();
        m_bServerRet = TRUE;
    }
    else if ( 0 != m_nErrorID ) {
        // Display error message.
        DisplayErrorMessage();
        m_bServerRet = FALSE;
    }
    else {
        ASSERT( FALSE );
    }
    
        
}   // End of CMemorySearch::MemorySearchKernel().


void CMemorySearch::DisplayMatchedAddr(void)
{
    // Assertion of the input parameters.
    
    // Format result string.
    strcpy(m_pszResult, "Data matched at: ");
    
    char chType;
    switch ( m_RetAddr.m_uchType ) {
        case MEM_PROGRAM:
            chType = 'P';
            break;
        case MEM_EXTERNAL:
            chType = 'X';
            break;
        case MEM_INTERNAL:
            chType = 'I';
            break;
        case MEM_SFR:
            chType = 'R';
            break;
        case MEM_BIT:
            chType = 'B';
            break;
        default:
            ASSERT( FALSE );
            break;
    }
    
    char pszAddr[20];
    wsprintf(pszAddr, "%c:%04X", chType, m_RetAddr.m_uAddr);
    strcat(m_pszResult, pszAddr);
        
    // Display the Search result.
    ShowLine(m_pszResult);

}   // End of CMemorySearch::DisplayMatchedAddr().


// Memory Search server.
BOOL CMemorySearch::MemServerSearch(unsigned short uStart,
    unsigned short uEnd, unsigned char uchType, char* pszPattern,
    int nInsensitive, unsigned short& uRetAddr)
{
    // Assertion of the input parameters.
    ASSERT( uchType >= MEM_PROGRAM && uchType <= MEM_BIT );

    // Set the server flag.
    m_isServer = TRUE;
        
    // Set parameters.
    m_StartAddr = CMemoryAddr(uStart, uchType);
    m_EndAddr = CMemoryAddr(uEnd, uchType);
    SetPattern(pszPattern);
    SetInsensitive(nInsensitive);
    SetSearchInfo();
    
    // Memory Search kernel routine.
    MemorySearchKernel();
    uRetAddr = m_RetAddr.m_uAddr;
    return (m_bServerRet);

}   // End of CMemorySearch::MemServerSearch().

//////////////////////////////// End of File ////////////////////////////////
