// BootModeIntegOpr.cpp : implementation file
//

#include "stdafx.h"
#include "BMPlatform.h"
#include "BootModeIntegOpr.h"

#include "OptionHelpper.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define DEFAULT_CHECK_BAUD_TIMES      3
#define DEFAULT_TIME_OUT        1000
#define MAX_ERASEFLASH_TIMEOUT    5000
#define SECTION_SIZE             0x10000

// Do repartition always
#define REPAR_STRATEGY_DO_ALWAYS        0   
// Stop actions and report error when incompatible partition error occured
#define REPAR_STRATEGY_STOP             1
// Ignore incompatible partition error
#define REPAR_STRATEGY_IGNORE           2
// Do repartion action when imcompatible partition error occured
#define REPAR_STRATEGY_DO               3

extern COptionHelpper ohObject;

/////////////////////////////////////////////////////////////////////////////
// CBootModeIntegOpr

IMPLEMENT_DYNCREATE(CBootModeIntegOpr, CCmdTarget)

CBootModeIntegOpr::CBootModeIntegOpr()
{
//	EnableAutomation();
	
	// To keep the application running as long as an OLE automation 
	//	object is active, the constructor calls AfxOleLockApp.
    m_bCheckBaudRate = FALSE;
    m_bStopOpr = FALSE;
    m_dwOprCookie = 0;

    m_bRcvThread = TRUE;
    m_dwRcvThreadID = 0;
    m_hRcvWindow = NULL;

	m_bRepartion = TRUE;
    
//	AfxOleLockApp();
}

CBootModeIntegOpr::~CBootModeIntegOpr()
{
	// To terminate the application when all objects created with
	// 	with OLE automation, the destructor calls AfxOleUnlockApp.
	
//	AfxOleUnlockApp();
	m_hRcvWindow = NULL;
}


void CBootModeIntegOpr::OnFinalRelease()
{
	// When the last reference for an automation object is released
	// OnFinalRelease is called.  The base class will automatically
	// deletes the object.  Add additional cleanup required for your
	// object before calling the base class.

	CCmdTarget::OnFinalRelease();
}


BEGIN_MESSAGE_MAP(CBootModeIntegOpr, CCmdTarget)
	//{{AFX_MSG_MAP(CBootModeIntegOpr)
		// NOTE - the ClassWizard will add and remove mapping macros here.
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_DISP_MAP(CBootModeIntegOpr, CCmdTarget)
	//{{AFX_DISPATCH_MAP(CBootModeIntegOpr)
	DISP_FUNC(CBootModeIntegOpr, "CheckBaud", CheckBaud)
	DISP_FUNC(CBootModeIntegOpr, "Connect", Connect)
	DISP_FUNC(CBootModeIntegOpr, "Download", Download)
	DISP_FUNC(CBootModeIntegOpr, "EraseFlash", EraseFlash)
	DISP_FUNC(CBootModeIntegOpr, "ReadFlash", ReadFlash)
	DISP_FUNC(CBootModeIntegOpr, "Excute", Excute)
	DISP_FUNC(CBootModeIntegOpr, "Reset", Reset)
    DISP_FUNC(CBootModeIntegOpr, "ReadChipType", ReadChipType)
    DISP_FUNC(CBootModeIntegOpr, "ReadNVItem", ReadNVItem)
    DISP_FUNC(CBootModeIntegOpr, "ChangeBaud", ChangeBaud)
    DISP_FUNC(CBootModeIntegOpr, "EraseFlash2", EraseFlash2)
	DISP_FUNC(CBootModeIntegOpr, "Repartition", Repartition)
	DISP_FUNC(CBootModeIntegOpr, "ExecNandInit", ExecNandInit)
    DISP_FUNC(CBootModeIntegOpr, "ReadFLashType",ReadFlashType)
	DISP_FUNC(CBootModeIntegOpr, "ReadFlashInfo", ReadFlashInfo)
	DISP_FUNC(CBootModeIntegOpr, "DownFlashSpec", DownFlashSpec)
	DISP_FUNC(CBootModeIntegOpr, "ReadSectorSize", ReadSectorSize)
	DISP_FUNC(CBootModeIntegOpr, "ReadFlashAndSave", ReadFlashAndSave)
	//}}AFX_DISPATCH_MAP
END_DISP_MAP(CBootModeIntegOpr)

/////////////////////////////////////////////////////////////////////////////
// CBootModeIntegOpr message handlers

BOOL CBootModeIntegOpr::CheckBaud(long pFileInfo) 
{
    BOOL bRet = FALSE;
    int nTimes = 0;
    BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;
    int nMaxTimes = ohObject.GetCheckBaudTimes( pBMFileInfo->szFileType );
    
    while( !m_bStopOpr )
    {
        if( nMaxTimes != 0 )
        {
            if( nTimes > nMaxTimes )
            {
                m_bCheckBaudRate = FALSE;
                bRet = FALSE;
                break;
            }
        }

        nTimes++;
        
        if(FALSE == m_bCheckBaudRate)
        {
            PostMessageToUplevel( BM_CHECK_BAUDRATE, 
                (WPARAM)m_dwOprCookie, (LPARAM)0 );
            m_bCheckBaudRate = TRUE;
        } 
		
		DWORD dwTimeout = ohObject.GetTimeout(_T("Check Baud"));

		if( _tcscmp(pBMFileInfo->szFileType, _T("FDL")) == 0)
		{
			dwTimeout = ohObject.GetTimeout(_T("CheckBaudRom"));
		}
        
        if(   m_bCheckBaudRate 
            && !m_bmOpr.CheckBaud( dwTimeout ) ) // Failed
        {           
            m_bCheckBaudRate = TRUE;
            continue;
        } 
        
        // Success
        bRet = TRUE;		
        m_bCheckBaudRate = FALSE;        
        break;
    }
    
    return bRet;
}

BOOL CBootModeIntegOpr::Connect(long pFileInfo) 
{
    
    if( !CheckBaud( pFileInfo ) )
    {
        return FALSE;
    }
    
    PostMessageToUplevel( BM_CONNECT, 
        (WPARAM)m_dwOprCookie, (LPARAM)0 );

    int nTimeout = ohObject.GetTimeout( _T("Connect") );
    
    if( !m_bmOpr.Connect( nTimeout ) )
    {
        // Boot code in module has a 
        // bug,it possibly make connect
        // failed at first time,so we
        // try once more.
        if( !m_bmOpr.Connect( nTimeout ) )
        {
            return FALSE;
        }
    }
    return TRUE;
}


BOOL CBootModeIntegOpr::Download(long pFileInfo) 
{
    PostMessageToUplevel( BM_ERASE_FLASH, 
        (WPARAM)m_dwOprCookie, (LPARAM)0 );

    BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;
    DWORD dwTimeout = ohObject.GetTimeout( _T("Erase Flash") );
    if( dwTimeout <= MAX_ERASEFLASH_TIMEOUT )
    {
        dwTimeout = pBMFileInfo->dwCodeSize / SECTION_SIZE * dwTimeout + dwTimeout;
    }

	if(_tcscmp(pBMFileInfo->szFileID,_T("NV"))==0 || 
		_tcscmp(pBMFileInfo->szFileID,_T("NV_REPEAT"))==0 )
	{
		m_bmOpr.SetStartDataInfo(TRUE);
	}
	else
	{
		m_bmOpr.SetStartDataInfo(FALSE);
	}

    if(!m_bmOpr.StartData( 
        pBMFileInfo->dwBase, 
        pBMFileInfo->dwCodeSize, 
        (LPBYTE)pBMFileInfo->lpCode,
        dwTimeout ) )
    {
        return FALSE;
    }
    
    PostMessageToUplevel( BM_DOWNLOAD, 
        (WPARAM)m_dwOprCookie, (LPARAM)pBMFileInfo->dwCodeSize );

    DWORD dwLeft = pBMFileInfo->dwCodeSize;
    DWORD dwMaxLength = pBMFileInfo->dwMaxLength;
    DWORD dwSize = dwMaxLength;

    while( dwLeft > 0 && !m_bStopOpr )
    {
        if(dwLeft > dwMaxLength )
        {
            dwSize = dwMaxLength ;                
        }
        else
        {
            dwSize = dwLeft;
        }
        
        if( !m_bmOpr.MidstData( dwSize, 
            ohObject.GetTimeout( _T("Download") ) ) )
        {
            return FALSE;
        }
        dwLeft -= dwSize;
        PostMessageToUplevel( BM_DOWNLOAD_PROCESS, 
            (WPARAM)m_dwOprCookie, 
            (LPARAM)pBMFileInfo->dwCodeSize - dwLeft );        
        
    }
    if( m_bStopOpr )
    {
        return FALSE;
    }
    if( !m_bmOpr.EndData( ohObject.GetTimeout( _T("EndData") ) ) )
        return FALSE;
    return TRUE;
}

BOOL CBootModeIntegOpr::EraseFlash(long pFileInfo) 
{
    BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;
    
    PostMessageToUplevel( BM_ERASE_FLASH, (WPARAM)m_dwOprCookie, (LPARAM)0 );
    DWORD dwTimeout = ohObject.GetTimeout( _T("Erase Flash") );
    if( dwTimeout <= MAX_ERASEFLASH_TIMEOUT )
    {
        dwTimeout = pBMFileInfo->dwOprSize / SECTION_SIZE * dwTimeout + dwTimeout;
    }
    
    if( !m_bmOpr.StartData( 
        pBMFileInfo->dwBase, 
        pBMFileInfo->dwOprSize, 
        NULL,
        dwTimeout  )  )
    {
        return FALSE;
    }
    if( !m_bmOpr.EndData() )
    {
        return FALSE;
    }
    return TRUE;
}

BOOL CBootModeIntegOpr::EraseFlash2( long pFileInfo  )
{
    BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;

    PostMessageToUplevel( BM_ERASE_FLASH, (WPARAM)m_dwOprCookie, (LPARAM)0 );
    DWORD dwTimeout = ohObject.GetTimeout( _T("Erase Flash") );
    if( dwTimeout <= MAX_ERASEFLASH_TIMEOUT )
    {
        dwTimeout = pBMFileInfo->dwOprSize / SECTION_SIZE * dwTimeout + dwTimeout;
    }
    
    if( !m_bmOpr.EraseFlash( 
        pBMFileInfo->dwBase, 
        pBMFileInfo->dwOprSize, dwTimeout  )  )
    {
        return FALSE;
    }

    return TRUE;    
}

BOOL CBootModeIntegOpr::ReadFlash(long pFileInfo) 
{
    BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;

    // Read NV_LENGTH byte from module
    m_bmOpr.AllocRecvBuffer( pBMFileInfo->dwOprSize );

    DWORD dwBase = pBMFileInfo->dwBase;
    DWORD dwLeft = pBMFileInfo->dwOprSize;
    DWORD dwMaxLength = pBMFileInfo->dwMaxLength;    
    DWORD dwSize = dwMaxLength;    

    PostMessageToUplevel( BM_READ_FLASH, 
        (WPARAM)m_dwOprCookie, (LPARAM)pBMFileInfo->dwOprSize );
    
    if( dwBase & 0x80000000 )
    {
        DWORD dwOffset = 0;
       while(dwLeft > 0 && !m_bStopOpr )
       {
            if(dwLeft > dwMaxLength )
            {
                dwSize = dwMaxLength ;                
            }
            else
            {
                dwSize = dwLeft;
            }
        
            if( !m_bmOpr.ReadPartitionFlash( dwBase,dwSize,dwOffset, 
                ohObject.GetTimeout( _T("Read Flash") ) ) )
            {
                m_bmOpr.FreeRecvBuffer();
                return FALSE;
            }
            dwOffset += dwSize;
            dwLeft -= dwSize;
            PostMessageToUplevel( BM_READ_FLASH_PROCESS, 
                (WPARAM)m_dwOprCookie, 
                (LPARAM)pBMFileInfo->dwOprSize - dwLeft );        
        }
    }
    else
    {
        while(dwLeft > 0 && !m_bStopOpr )
        {
            if(dwLeft > dwMaxLength )
            {
                dwSize = dwMaxLength ;                
            }
            else
            {
                dwSize = dwLeft;
            }
        
            if( !m_bmOpr.ReadFlash( dwBase,dwSize, 
                ohObject.GetTimeout( _T("Read Flash") ) ) )
            {
                m_bmOpr.FreeRecvBuffer();
                return FALSE;
            }
            dwBase += dwSize;
            dwLeft -= dwSize;
            PostMessageToUplevel( BM_READ_FLASH_PROCESS, 
                (WPARAM)m_dwOprCookie, 
                (LPARAM)pBMFileInfo->dwOprSize - dwLeft );        
        }
    }

    if( m_bStopOpr )
        return FALSE;
    return TRUE;
}

BOOL CBootModeIntegOpr::Excute(long pFileInfo) 
{
    UNUSED_ALWAYS( pFileInfo );

    return m_bmOpr.Excute( ohObject.GetTimeout( _T("Excute") ) );
}

BOOL CBootModeIntegOpr::ChangeBaud( long pFileInfo )
{
    UNUSED_ALWAYS( pFileInfo );

    PostMessageToUplevel( BM_CHANGE_BAUD,  (WPARAM)m_dwOprCookie, (LPARAM)0 );     
    
    return m_bmOpr.ChangeBaud( ohObject.GetTimeout( _T("ChangeBaud") ) );
}

BOOL CBootModeIntegOpr::Reset(long pFileInfo) 
{
    UNUSED_ALWAYS( pFileInfo );
    PostMessageToUplevel( BM_RESET, 
        (WPARAM)m_dwOprCookie, 
        (LPARAM)0 );      
	return m_bmOpr.Reset( );
}

BOOL CBootModeIntegOpr::ReadChipType( long pFileInfo )
{
    UNUSED_ALWAYS( pFileInfo );
    m_bmOpr.AllocRecvBuffer( sizeof(DWORD) );
    
    PostMessageToUplevel( BM_READ_CHIPTYPE,  (WPARAM)m_dwOprCookie, (LPARAM)0 );      
    
     if( !m_bmOpr.ReadChipType( 
            ohObject.GetTimeout( _T("Read ChipType") ) ) )
     {
         m_bmOpr.FreeRecvBuffer();
         return FALSE;
     }
     return TRUE;
}

BOOL CBootModeIntegOpr::ReadNVItem( long pFileInfo  )
{
    BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;

    m_bmOpr.AllocRecvBuffer( READ_NVITEM_REP_DATA_LEN );   

    PostMessageToUplevel( BM_READ_NVITEM,  (WPARAM)m_dwOprCookie, (LPARAM)0 );      
    
    if( !m_bmOpr.ReadNVItem( pBMFileInfo->dwBase, 
            pBMFileInfo->dwBase + pBMFileInfo->dwOprSize, 
            (unsigned short)(ohObject.GetNVItemID()),
            ohObject.GetTimeout( _T("Read NVItem") ) ) )
    {
        m_bmOpr.FreeRecvBuffer();
        return FALSE;
    }
    LPBYTE lpRecvBuffer = m_bmOpr.GetRecvBuffer();
    DWORD dwRecvSize = m_bmOpr.GetRecvBufferSize();
    if( dwRecvSize < READ_NVITEM_REP_DATA_LEN )
    {
        m_bmOpr.FreeRecvBuffer(); 
        return FALSE;
    }

    DWORD dwSoruceValue, dwDestValue;
    dwSoruceValue =  *(DWORD*)&lpRecvBuffer[0];    
    dwDestValue   = 0;
    CONVERT_INT( dwSoruceValue, dwDestValue);
    DWORD dwReadStart = dwDestValue;
        
    unsigned short uiSourceValue, uiDestValue;        
    uiSourceValue =  *(unsigned short*)&lpRecvBuffer[ sizeof( DWORD )];
    uiDestValue   = 0;
    CONVERT_SHORT( uiSourceValue, uiDestValue);
    DWORD dwReadLength = uiDestValue;

    if( dwReadStart == -1 || dwReadLength == -1 )
    {
        m_bmOpr.FreeRecvBuffer();
        Log( _T("Read NV Item: NOT find the NVITEM ID.") );
        return FALSE;
    }
/*

    if( dwReadStart % 4 == 2 )
    {
        dwReadStart = dwReadStart  -2 ;
        dwReadLength += 2;   
    }
    else
    {
        dwReadLength += 1;
    }
*/    
    BMFileInfo fileinfo;
    memset( &fileinfo, 0, sizeof( BMFileInfo) );
    fileinfo.dwBase = dwReadStart;
    fileinfo.dwOprSize = dwReadLength;
    fileinfo.dwMaxLength = 0x1000;
    return ReadFlash( (long)&fileinfo );    
}

BOOL CBootModeIntegOpr::Repartition( long pFileInfo  )
{
    UNUSED_ALWAYS( pFileInfo );
	if(m_bRepartion)
	{
		return m_bmOpr.Repartition( ohObject.GetTimeout( _T("Repartition") ) ) ;
	}
	else
	{
		m_bRepartion  = TRUE; // recover to initial value
		return TRUE;
	}
}

BOOL CBootModeIntegOpr::ReadFlashType( long pFileInfo )
{
    UNUSED_ALWAYS( pFileInfo );
    m_bmOpr.AllocRecvBuffer( sizeof(DWORD) );
    if( !m_bmOpr.ReadFlashType( ohObject.GetTimeout( _T("ReadFlashType") ) ) )
    {
        m_bmOpr.FreeRecvBuffer();
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

BOOL CBootModeIntegOpr::ExecNandInit( long pFileInfo )
{
	UNUSED_ALWAYS(pFileInfo);
    BOOL bExcRet = m_bmOpr.Excute( ohObject.GetTimeout( _T("ExecNandInit") ) );
    
	if( bExcRet )
	{
	   m_bRepartion = FALSE;
	   return bExcRet;
	}

	DWORD dwError = m_bmOpr.GetLastErrorCode();

	if(BSL_PHONE_WAIT_INPUT_TIMEOUT == dwError)
	{
		m_bRepartion = FALSE;
		return FALSE;
	}
    
    DWORD dwStrategy = ohObject.GetRepartitionFlag();	
    DWORD dwReadFlashFlag = ohObject.GetReadFlashBefRepFlag();

	m_bRepartion = TRUE;

    switch( dwStrategy )
    {
        case REPAR_STRATEGY_DO_ALWAYS:     
        {
			bExcRet = TRUE;
			// Do repartition always
			if( dwReadFlashFlag == 0)
			{
				bExcRet = Repartition( pFileInfo );
			}
			
            break;
        }
        case REPAR_STRATEGY_STOP:
        {
            if( BSL_REP_INCOMPATIBLE_PARTITION == dwError )
            {
                // Report error
                bExcRet = FALSE;
            }
            break;
        }
        case REPAR_STRATEGY_IGNORE:
        {
            if( BSL_REP_INCOMPATIBLE_PARTITION == dwError )
            {
				m_bRepartion = FALSE;
                // Ignore this error
                bExcRet = TRUE;
				
            }
            break;
        }
        case REPAR_STRATEGY_DO:
        {
            if( BSL_REP_INCOMPATIBLE_PARTITION == dwError )
            {
				m_bRepartion = TRUE;
				bExcRet = TRUE;

                // Repartition
				if(dwReadFlashFlag == 0)
				{
					bExcRet = Repartition( pFileInfo );
				} 				
            }

            break;
        }
        default:
        {
            // Unknown settings
            ASSERT( FALSE );
        }
    }
    	
    return bExcRet;
}

void CBootModeIntegOpr::SetMessageReceiver( BOOL bRcvThread, 
                                      const LPVOID pReceiver,
                                      DWORD dwCookie )
{
    m_dwOprCookie = dwCookie;
    m_bRcvThread = bRcvThread;
    
    if ( bRcvThread )
    {
        m_dwRcvThreadID = ( DWORD) pReceiver;
    }
    else
    {
        m_hRcvWindow = ( HWND )pReceiver;
    }
}    

void CBootModeIntegOpr::PostMessageToUplevel( opr_status_msg msgID, 
                                        WPARAM wParam, LPARAM lParam  )
{
    AFX_MANAGE_STATE( AfxGetStaticModuleState() )

    if( (m_hRcvWindow == NULL) && ( m_dwRcvThreadID == 0) )
    {
        return;
    }
    
    if ( m_bRcvThread )  
    {
        if( m_dwRcvThreadID != 0 )
        {
            PostThreadMessage( m_dwRcvThreadID,  msgID, wParam , lParam );   
        }
    }
    else 
    {
        if( m_hRcvWindow != NULL )
        {
            PostMessage( m_hRcvWindow, msgID, wParam , lParam );            
        }
    }
}

BOOL CBootModeIntegOpr::Initialize(LPCTSTR lpszProgID, long pOpenArgument, 
                                   BOOL bBigEndian, long dwOprCookie, 
                                   BOOL bRcvThread, long pReceiver) 
{
    m_bCheckBaudRate = FALSE;
    m_bStopOpr = FALSE;
	m_bRepartion = TRUE;

    SetMessageReceiver( bRcvThread, (LPVOID)pReceiver, dwOprCookie );
    return m_bmOpr.Initialize( lpszProgID, (LPBYTE)pOpenArgument,
                                bBigEndian, dwOprCookie );
}

void CBootModeIntegOpr::Uninitialize() 
{
    m_bmOpr.Uninitialize();
    m_bCheckBaudRate   = TRUE;
}

void CBootModeIntegOpr::Log(LPCTSTR lpszLog) 
{
    m_bmOpr.Log( lpszLog );
}

void CBootModeIntegOpr::SetIsCheckCrc(BOOL bCheckCrc) 
{
    m_bmOpr.SetIsCheckCrc( bCheckCrc );
}

long CBootModeIntegOpr::GetRecvBuffer() 
{
    return (long)m_bmOpr.GetRecvBuffer();	
}

void CBootModeIntegOpr::FreeRecvBuffer() 
{
    m_bmOpr.FreeRecvBuffer();
}

void CBootModeIntegOpr::StopOpr() 
{
    m_bmOpr.StopOpr();
    m_bStopOpr = TRUE;
}

long CBootModeIntegOpr::GetRecvBufferSize() 
{
	return m_bmOpr.GetRecvBufferSize();
}

long CBootModeIntegOpr::GetChannelPtr() 
{
    return m_bmOpr.GetChannelPtr();
}

void CBootModeIntegOpr::SetChannel(long pChannel) 
{
    m_bmOpr.SetChannel( pChannel );
}

BOOL CBootModeIntegOpr::ReadFlashInfo(long pFileInfo) 
{
	// TODO: Add your dispatch handler code here
    UNUSED_ALWAYS( pFileInfo );
    m_bmOpr.AllocRecvBuffer( sizeof(DWORD)*3 );
    if( !m_bmOpr.ReadFlashInfo( ohObject.GetTimeout( _T("ReadFlashInfo") ) ) )
    {
        m_bmOpr.FreeRecvBuffer();
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

BOOL CBootModeIntegOpr::DownFlashSpec(long pFileInfo) 
{
	// TODO: Add your dispatch handler code here
	BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;
    if( !m_bmOpr.DownFlashSpec( pBMFileInfo->dwCodeSize,(LPBYTE)pBMFileInfo->lpCode,
		          ohObject.GetTimeout( _T("DownFlashSpec") ) ) )
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

BOOL CBootModeIntegOpr::SetDebugLogState(long lState) 
{
	// TODO: Add your dispatch handler code here
	return m_bmOpr.SetDebugLogState(lState);
}

long CBootModeIntegOpr::GetIDsOfNames(LPCTSTR lpszFunName)
{
	for(int i=0;i<(m_oprCount-1);i++)
	{
		if(_tcsicmp(m_oprEntries[i].lpszName,lpszFunName)==0)
		{
			return i;
		}
	}

	return -1;
}
BOOL CBootModeIntegOpr::Invoke(long id,long pFileInfo)
{
	if(id<0 || id>=m_oprCount)
		return FALSE;

	return (this->*(m_oprEntries[id].pFun))(pFileInfo);
}

BOOL CBootModeIntegOpr::ReadSectorSize( long pFileInfo )
{
	UNUSED_ALWAYS( pFileInfo );
    m_bmOpr.AllocRecvBuffer( sizeof(DWORD) );
    if( !m_bmOpr.ReadSectorSize( ohObject.GetTimeout( _T("ReadSectorSize") ) ) )
    {
        m_bmOpr.FreeRecvBuffer();
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}

BOOL CBootModeIntegOpr::ReadFlashAndSave( long pFileInfo )
{
	BMFileInfo* pBMFileInfo = (BMFileInfo*)pFileInfo;
	if(ReadFlash(pFileInfo))
	{
		if(_tcslen(pBMFileInfo->szFileName) == 0)
		{
			Log(_T("File name to save falsh data is empty."));
			return FALSE;
		}

		LPBYTE lpBuf = m_bmOpr.GetRecvBuffer();
		DWORD dwSize = m_bmOpr.GetRecvBufferSize();
		
		if(lpBuf == NULL || dwSize == 0)
		{
			Log(_T("readed buffer is empty."));
			return FALSE;
		}	

		HANDLE hFile = CreateFile(pBMFileInfo->szFileName,
						GENERIC_WRITE,
						FILE_SHARE_READ,           //Exclusive Open
						NULL,                      //Can't Be inherited
						CREATE_ALWAYS,             //Create always
						FILE_ATTRIBUTE_NORMAL,     
						NULL);
		if( hFile == INVALID_HANDLE_VALUE )
		{
			Log(_T("Create file failed."));
			return FALSE;
		}

		DWORD dwRealWrite = 0;

		BOOL bOK = WriteFile(hFile,lpBuf,dwSize,&dwRealWrite,NULL);

		CloseHandle(hFile);
		hFile = INVALID_HANDLE_VALUE;
		if(bOK && dwRealWrite == dwSize )
		{		
			Log(_T("Save readed flash data success."));
			return TRUE;
		}
		else
		{
			Log(_T("Save readed flash data failed."));
			return FALSE;
		}
								
	}
	else
	{
		return FALSE;
	}


}
DWORD CBootModeIntegOpr::GetOprLastErrorCode()
{
	return m_bmOpr.GetLastErrorCode();
}


