BOOL SF_BS_Driver::EraseBlock(void *context, ByteAddress phyAddr)
{
    NATIVE_PROFILE_HAL_DRIVERS_FLASH();

    UINT32 iRegion, iRange, BytesPerSector, i, j, k;
    
    unsigned char * Buff;
    
    Buff = (unsigned char *)private_malloc(0x10000);

    MEMORY_MAPPED_SERIAL_BLOCK_CONFIG* config = (MEMORY_MAPPED_SERIAL_BLOCK_CONFIG*)context;
    const BlockDeviceInfo *    deviceInfo = config->BlockConfig.BlockDeviceInformation;

    if (deviceInfo->Attribute.WriteProtected) return FALSE;

    if (!deviceInfo->FindRegionFromAddress(phyAddr, iRegion, iRange)) return FALSE;

    const BlockRegionInfo* pRegion = &deviceInfo->Regions[iRegion];

    BytesPerSector = deviceInfo->BytesPerSector;

    SF_Sector_Erase(/*i * SF_SECTOR_SIZE*/phyAddr);

    return TRUE;
}
BOOL Piezo_Driver::Tone( UINT32 Frequency_Hertz, UINT32 Duration_Milliseconds )
{
    // Not sure why this is neccessary.  Calling the Piezo::Tone function from with-in an ISR
    // should be a valid scenario.  Lorenzo and I (Zach) can not determine
    // why this assert is needed; therefore, it is being commented out (for now).
    //ASSERT(!SystemState_Query( SYSTEM_STATE_ISR ));

    GLOBAL_LOCK(irq);

    // special to clear queue
    if(Frequency_Hertz == TONE_CLEAR_BUFFER)
    {
        // let active note to finish on it's own
        EmptyQueue();
    }
    else
    {
        // 0 length tone isn't wrong persay, but if a NULL op, so drop it gracefully, as a success
        if(Duration_Milliseconds > 0)
        {
            PIEZO_TONE* Tone = g_Piezo_Driver.m_ToneToRelease.ExtractFirstNode();

            if(Tone == NULL)
            {
                //
                // Re-enable interrupts when allocating memory.
                //
                irq.Release();

                Tone = (PIEZO_TONE*)private_malloc( sizeof(PIEZO_TONE) );

                Tone->Initialize();

                irq.Acquire();
            }

            if(Tone == NULL)
            {
                // No memory, just drop this tone and fail the call
                ASSERT(0);
                return FALSE;
            }

            Tone->Frequency_Hertz       = Frequency_Hertz;
            Tone->Duration_Milliseconds = Duration_Milliseconds;

            DEBUG_TRACE3(0, "Tone(%4d,%4d)=%d\r\n", Frequency_Hertz, Duration_Milliseconds, g_Piezo_Driver.m_ToneToPlay.NumOfNodes() );

            g_Piezo_Driver.m_ToneToPlay.LinkAtBack( Tone );

            if(g_Piezo_Driver.m_TonePlaying == NULL)
            {
                StartNext();
            }
        }
    }

    return TRUE;
}
BOOL PolyphonicPiezo_Driver::Tone( const PIEZO_POLY_TONE& ToneRef )
{
    ASSERT(!SystemState_Query(SYSTEM_STATE_ISR));

    GLOBAL_LOCK(irq);

    // special to clear queue
    if(ToneRef.Period[0] == TONE_CLEAR_BUFFER)
    {
        // let active note to finish on it's own
        EmptyQueue();
    }
    else
    {
        // 0 length tone isn't wrong persay, but if a NULL op, so drop it gracefully, as a success
        if(ToneRef.Duration_MicroSeconds > 0)
        {
            PIEZO_POLY_TONE* Tone = g_PolyphonicPiezo_Driver.m_ToneToRelease.ExtractFirstNode();

            if(Tone == NULL)
            {
                //
                // Re-enable interrupts when allocating memory.
                //
                irq.Release();

                Tone = (PIEZO_POLY_TONE*)private_malloc( sizeof(PIEZO_POLY_TONE) );

                irq.Acquire();
            }

            if(Tone == NULL)
            {
                // No memory, just drop this tone and fail the call
                ASSERT(0);
                return FALSE;
            }

            *Tone = ToneRef;

            Tone->Initialize();

            DEBUG_TRACE2( 0, "Tone(%4d)=%d\r\n", ToneRef.Duration_MicroSeconds, g_PolyphonicPiezo_Driver.m_ToneToPlay.NumOfNodes() );

            g_PolyphonicPiezo_Driver.m_ToneToPlay.LinkAtBack( Tone );

            if(g_PolyphonicPiezo_Driver.m_TonePlaying == NULL)
            {
                StartNext();
            }
        }
    }

    return TRUE;
}
示例#4
0
PCRE2_EXP_DEFN pcre2_general_context * PCRE2_CALL_CONVENTION
pcre2_general_context_create(void *(*private_malloc)(size_t, void *),
  void (*private_free)(void *, void *), void *memory_data)
{
pcre2_general_context *gcontext;
if (private_malloc == NULL) private_malloc = default_malloc;
if (private_free == NULL) private_free = default_free;
gcontext = private_malloc(sizeof(pcre2_real_general_context), memory_data);
if (gcontext == NULL) return NULL;
gcontext->memctl.malloc = private_malloc;
gcontext->memctl.free = private_free;
gcontext->memctl.memory_data = memory_data;
return gcontext;
}
BOOL HAL_CONFIG_BLOCK::CompactBlock(HAL_CONFIG_BLOCK_STORAGE_DATA& blData, const ConfigurationSector* cfgStatic, const HAL_CONFIG_BLOCK* cfgEnd)
{
    BOOL fRet = FALSE;
    
    int saveLength = (UINT32)cfgEnd - blData.ConfigAddress;
    
    //
    UINT8 *pBackup = (UINT8*)private_malloc( saveLength );

    if(pBackup)
    {
        int writeLength = cfgStatic->ConfigurationLength;
        UINT8* pNextCfg = pBackup;

        const HAL_CONFIG_BLOCK* cfgStart = (const HAL_CONFIG_BLOCK*)((UINT32)cfgStatic + cfgStatic->ConfigurationLength);
        memcpy(pNextCfg, cfgStatic, cfgStatic->ConfigurationLength);
        pNextCfg += cfgStatic->ConfigurationLength;

        while(cfgStart < cfgEnd)
        {
            if(cfgStart->Size > 0)
            {
                HAL_DRIVER_CONFIG_HEADER* pCfgHeader = (HAL_DRIVER_CONFIG_HEADER*)&cfgStart[1];

                if(pCfgHeader->Enable)
                {
                    int len = sizeof(HAL_CONFIG_BLOCK) + HAL_CONFIG_BLOCK::RoundLength(cfgStart->Size);

                    memcpy( pNextCfg, cfgStart, len );

                    pNextCfg += len;
                    writeLength += len;
                }
            }
            cfgStart = cfgStart->Next();
        }

        blData.Device->EraseBlock(blData.ConfigAddress);

        fRet = blData.Device->Write((UINT32)blData.ConfigAddress, writeLength, pBackup, FALSE);

        // if the heap is not yet initialized this does nothing
        private_free( pBackup );
    }

    return fRet;
}
BYTE* FAT_SectorCache::GetSector( UINT32 sectorIndex, BOOL forWrite )
{
    if(sectorIndex > m_sectorCount)  //sectorIndex out of range of this device
        return NULL;

    FAT_CacheLine* cacheLine = GetCacheLine( sectorIndex );

    if(!cacheLine)
    {
        cacheLine = GetUnusedCacheLine();

        if(!cacheLine->m_buffer)
        {
            cacheLine->m_buffer = (BYTE*)private_malloc( SECTORCACHE_LINESIZE );

            if(!cacheLine->m_buffer) return NULL;
        }

        cacheLine->m_begin         = sectorIndex - (sectorIndex % m_sectorsPerLine);
        cacheLine->m_bsByteAddress = m_baseByteAddress + cacheLine->m_begin * m_bytesPerSector;
        cacheLine->m_flags         = 0;

        if(!m_blockStorageDevice->Read( cacheLine->m_bsByteAddress, SECTORCACHE_LINESIZE, cacheLine->m_buffer ))
        {
            private_free( cacheLine->m_buffer );
            
            cacheLine->m_buffer = NULL;
            
            return NULL;
        }
    }

    if(forWrite) cacheLine->SetDirty( TRUE );

    if((cacheLine->GetLRUCounter()) != m_LRUCounter)
    {
        m_LRUCounter++;

        cacheLine->SetLRUCOunter( m_LRUCounter );
    }

    return cacheLine->m_buffer + (sectorIndex - cacheLine->m_begin) * m_bytesPerSector;
}
示例#7
0
文件: layer.c 项目: NASAHackTO/mesh
static struct thread_entry * layer_thread_lookup()
{
	struct thread_entry *thread;

	if(!thread_table) {
		thread_table = hashtable_create(127);
	}

	thread = (struct thread_entry*)hashtable_lookup(thread_table, layer_pthread_self());
	if(!thread) {

		thread = private_malloc(sizeof(*thread));
		thread->current = 0;
		thread->overflow = 0;
		thread->tid = layer_pthread_self();

		if(!hashtable_insert(thread_table,thread->tid,thread)) {
			layer_fatal("out of memory");
		}
	}

	return thread;
}
示例#8
0
文件: layer.c 项目: NASAHackTO/mesh
// PZK 11/3/11: changed name to const to avoid warnings
int layer_register( const char *library_name, int is_agent )
{
	struct layer_entry *layer;

	layer = private_malloc(sizeof(struct layer_entry));
	layer->table = hashtable_create( 127 );

	layer->is_agent = is_agent;
	layer->name = (char *) library_name;
	layer->handle = 0;
	layer->prev = 0;
	layer->next = 0;

	if(!layer_head) {
		layer_head = layer;
	} else {
		struct layer_entry *j;
		for(j=layer_head;j->next;j=j->next) {} 
		j->next = layer;
		layer->prev = j;
	}

	return 1;
}
BOOL SF_BS_Driver::Write(void *context, ByteAddress Address, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite )
{
    NATIVE_PROFILE_PAL_FLASH();

    BYTE * pData;
    BYTE * pBuf = NULL;
    MEMORY_MAPPED_SERIAL_BLOCK_CONFIG* config = (MEMORY_MAPPED_SERIAL_BLOCK_CONFIG*)context;
    const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation;
    
    UINT32 region, range;

    if(ReadModifyWrite) 
    {
        BOOL fRet = TRUE;
        
        if(!deviceInfo->FindRegionFromAddress(Address, region, range)) return FALSE;

        UINT32      bytesPerBlock   = deviceInfo->Regions[region].BytesPerBlock;
        UINT32      regionEnd       = deviceInfo->Regions[region].Start + deviceInfo->Regions[region].Size();
        UINT32      offset          = Address % bytesPerBlock;
        ByteAddress addr            = Address;
        ByteAddress addrEnd         = Address + NumBytes;
        UINT32      index           = 0;

        pBuf = (BYTE*)private_malloc(bytesPerBlock);

        if(pBuf == NULL)
        {
 
            return FALSE;
        }

        while(fRet && addr < addrEnd)
        {
            ByteAddress sectAddr = (addr - offset);
             
            if(offset == 0 && NumBytes >= bytesPerBlock)
            {
                pData = &pSectorBuff[index];
            }
            else
            {
                int bytes = __min(bytesPerBlock - offset, NumBytes); 
                
                //memcpy( &pBuf[0]     , (void*)sectAddr    , bytesPerBlock );
                Read(context, sectAddr, bytesPerBlock, (BYTE *)&pBuf[0]);
                memcpy( &pBuf[offset], &pSectorBuff[index], bytes         );

                pData = pBuf;
            }

            if(!EraseBlock( context, sectAddr ))
{
                fRet = FALSE;
                break;
            }

            fRet = WriteX(context, sectAddr, bytesPerBlock, pData, ReadModifyWrite, TRUE);

            NumBytes -= bytesPerBlock - offset;
            addr     += bytesPerBlock - offset;
            index    += bytesPerBlock - offset;
            offset    = 0;

            if(NumBytes > 0 && addr >= regionEnd)
            {
                region++;

                if(region >= deviceInfo->NumRegions)
                {
                    fRet = FALSE;
                }
                else
                {
                    regionEnd       = deviceInfo->Regions[region].Start + deviceInfo->Regions[region].Size();
                    bytesPerBlock   = deviceInfo->Regions[region].BytesPerBlock;

                    private_free(pBuf);

                    pBuf = (BYTE*)private_malloc(bytesPerBlock);

                    if(pBuf == NULL)
                    {
                        fRet = FALSE;
                    }
                }
            }
                
        }

        if(pBuf != NULL)
        {
            private_free(pBuf);
        }

        return fRet;            
    }
    else
    {
        return WriteX(context, Address, NumBytes, pSectorBuff, ReadModifyWrite, TRUE);
    }
}
BOOL HAL_CONFIG_BLOCK::ApplyConfig( const char* Name, void* Address, size_t Length, void** newAlloc )
{
#if defined(HAL_REDUCESIZE)
    // No config update.
    return FALSE;
#else
    BYTE* pXipConfigBuf = NULL;
    HAL_CONFIG_BLOCK_STORAGE_DATA blData;
    const HAL_CONFIG_BLOCK *header = NULL;

    if(!GetConfigSectorAddress(blData)) return FALSE;

    if(g_ConfigurationSector.ConfigurationLength == 0xFFFFFFFF) return FALSE;

    if(blData.isXIP)
    {
        header = (const HAL_CONFIG_BLOCK*)(blData.ConfigAddress + g_ConfigurationSector.ConfigurationLength);
    }
    else
    {
        pXipConfigBuf = (BYTE*)private_malloc(blData.BlockLength);

        if(pXipConfigBuf != NULL)

        {
            blData.Device->Read( blData.ConfigAddress, blData.BlockLength, pXipConfigBuf );

            header = (const HAL_CONFIG_BLOCK*)&pXipConfigBuf[g_ConfigurationSector.ConfigurationLength];
        }
    }

    if(header != NULL)
    {
        header = header->Find(Name, FALSE, FALSE);
    }

    if(header)
    {
        if(newAlloc != NULL)
        {
            *newAlloc = private_malloc(header->Size);

            if(*newAlloc)
            {
                memcpy( *newAlloc, header->Data(), header->Size );

                return TRUE;
            }
        }
        else if(header->Size == Length)
        {
            if(Address)
            {
                memcpy( Address, header->Data(), Length );
            }

            return TRUE;
        }
    }

    if(pXipConfigBuf != NULL)
    {
        private_free(pXipConfigBuf);
    }

    return FALSE;
#endif
}
BOOL HAL_CONFIG_BLOCK::UpdateBlockWithName( const char* Name, void* Data, size_t Length, BOOL isChipRO )
{
#if defined(HAL_REDUCESIZE)
    return FALSE;
#else

    if(Name == NULL) return FALSE;

    BOOL fRet = FALSE;
    BYTE* pXipConfigBuf = NULL;
    const HAL_CONFIG_BLOCK *pLastConfig = NULL;
    HAL_CONFIG_BLOCK_STORAGE_DATA blData;

    if(!GetConfigSectorAddress(blData)) return FALSE;

    if(g_ConfigurationSector.ConfigurationLength == 0xFFFFFFFF)
    {
        return FALSE;
    }

    const ConfigurationSector* pStaticCfg = NULL;

    const HAL_CONFIG_BLOCK *pConfig = NULL;

    GLOBAL_LOCK(irq);

    if(blData.isXIP)
    {
        pConfig = (const HAL_CONFIG_BLOCK*)(blData.ConfigAddress+ g_ConfigurationSector.ConfigurationLength);
        pStaticCfg = &g_ConfigurationSector;
    }
    else
    {
        pXipConfigBuf = (BYTE*)private_malloc(blData.BlockLength);

        if(pXipConfigBuf != NULL)
        {
            blData.Device->Read( blData.ConfigAddress, blData.BlockLength, pXipConfigBuf );

            pConfig = (const HAL_CONFIG_BLOCK*)&pXipConfigBuf[g_ConfigurationSector.ConfigurationLength];

            pStaticCfg = (const ConfigurationSector*)pXipConfigBuf;
        }
        else
        {
            return FALSE;
        }
    }

    if(pConfig != NULL)
    {
        pConfig = pConfig->Find(Name, FALSE, TRUE);

        pLastConfig = pConfig->Find("", FALSE, TRUE);
    }

    if(pConfig != NULL)
    {
        const void* physAddr;
        const void* physEnd;

        // try compacting the config block if the first attempt to update fails
        for(int i=0; i<2; i++)
        {
            // if we could not get the last config then we must be full
            if(pLastConfig != NULL)
            {
                if(blData.isXIP)
                {
                    physAddr = (const void*)pConfig;
                    physEnd  = (const void*)pLastConfig;
                }
                else
                {
                    physAddr = (const void*)(blData.ConfigAddress + ((size_t)pConfig - (size_t)pXipConfigBuf));
                    physEnd  = (const void*)(blData.ConfigAddress + ((size_t)pLastConfig - (size_t)pXipConfigBuf));

                    private_free(pXipConfigBuf);
                    pXipConfigBuf = NULL;
                }

                if(Data != NULL)
                {
                    HAL_CONFIG_BLOCK header;

                    header.Prepare( Name, Data, Length );

                    fRet = UpdateBlock( blData, physAddr, (const HAL_CONFIG_BLOCK*)&header, Data, Length, physEnd, isChipRO );
                }
                else if(physAddr != physEnd)
                {
                    fRet = UpdateBlock( blData, physAddr, NULL, NULL, 0, physEnd, isChipRO );
                }
                else
                {
                    fRet = TRUE;
                }

                if(fRet) break;
            }
        
            CompactBlock( blData, pStaticCfg, pLastConfig );

            if(!blData.isXIP && pXipConfigBuf != NULL)
            {
                blData.Device->Read( blData.ConfigAddress, blData.BlockLength, pXipConfigBuf );
            
                pConfig = (const HAL_CONFIG_BLOCK*)&pXipConfigBuf[g_ConfigurationSector.ConfigurationLength];
            }
            else
            {
                pConfig = (const HAL_CONFIG_BLOCK*)(blData.ConfigAddress + g_ConfigurationSector.ConfigurationLength);
            }

            pConfig = pConfig->Find(Name, FALSE, TRUE);

            pLastConfig = pConfig->Find("", FALSE, TRUE);            
        }
    }


    if(pXipConfigBuf != NULL)
    {
        private_free(pXipConfigBuf);
    }

    return fRet;
#endif
}
示例#12
0
void FS_MountVolume( LPCSTR nameSpace, UINT32 serialNumber, UINT32 deviceFlags, BlockStorageDevice* blockStorageDevice )
{
    FileSystemVolume* volume = NULL;
    UINT32 numVolumes = 0;
    FILESYSTEM_DRIVER_INTERFACE* fsDriver = NULL;
    STREAM_DRIVER_INTERFACE* streamDriver = NULL;
    UINT32 i;
    
    if(!nameSpace || !blockStorageDevice)
    {
        return;
    }

    //--//

    // free up any memory taken up by this block storage device in the zombie list
    // so at any given time, we'll only have one set of FileSystemVolume per block 
    // storage device. Here we release (private_free) the memory that was allocated
    // in the previous insertion, later, prior to AddVolume, we'll allocate new memory
    // needed for this insertion.
    FileSystemVolume* current = FileSystemVolumeList::s_zombieVolumeList.FirstValidNode();
    FileSystemVolume* next;
    
    while(current)
    {
        next = current->Next();

        if(!(next && next->Next()))
        {    
            next = NULL;
        }

        // We'll only free the memory of this storage device
        if(current->m_volumeId.blockStorageDevice == blockStorageDevice)
        {
            current->Unlink();

            private_free( current );
        }

        current = next;
    }

    //--//

    /// First we find the FSDriver that will mount the block storage
    for (i = 0; i < g_InstalledFSCount; i++)
    {
        if (g_AvailableFSInterfaces[i].fsDriver && g_AvailableFSInterfaces[i].fsDriver->IsLoadableMedia &&
            g_AvailableFSInterfaces[i].fsDriver->IsLoadableMedia( blockStorageDevice, &numVolumes ))
        {
            fsDriver = g_AvailableFSInterfaces[i].fsDriver;
            streamDriver = g_AvailableFSInterfaces[i].streamDriver;
            break;
        }
    }

    if (!fsDriver)
    {
        numVolumes = 1;
    }

    for (i = 0; i < numVolumes; i++)
    {
        // Allocate the memory for this FileSystemVolume
        volume = (FileSystemVolume*)private_malloc( sizeof(FileSystemVolume) );

        if(!volume) // allocation failed
        {
            return;
        }

        // initialize content to 0
        memset( volume, 0, sizeof(FileSystemVolume) );

        if(!FileSystemVolumeList::AddVolume( volume, nameSpace, serialNumber, deviceFlags,
                                            streamDriver, fsDriver, blockStorageDevice, i, (fsDriver) ? TRUE : FALSE )) // init only when we have a valid fsDriver
        {
            // If for some reason, AddVolume fails, we'll keep trying other volumes
            private_free( volume );
            continue;
        }

        // Now we can notify managed code
        PostManagedEvent( EVENT_STORAGE, EVENT_SUBCATEGORY_MEDIAINSERT, 0, (UINT32)volume );
    }
}
int RTIP_SOCKETS_Driver::GetAddrInfo(  const char* nodename, 
                                            char* servname, 
                                            const SOCK_addrinfo* hints, 
                                            SOCK_addrinfo** res )
{ 
    if(res == NULL || nodename == NULL) 
    {
        set_errno(EINVAL);
        return SOCK_SOCKET_ERROR;
    }


    *res = NULL;

    PFHOSTENT pHost = NULL;
    struct hostentext localHost;

    if(nodename[0] == '\0')
    {
        IFACE_INFO info;

        if(SOCK_SOCKET_ERROR != xn_interface_info(g_RTIP_SOCKETS_Driver.m_interfaces[0].m_interfaceNumber, &info ))
        {
            memset(&localHost, 0, sizeof(localHost));

            localHost.ip_addr.s_un.S_addr = *(UINT32*)info.my_ip_address;

            pHost = &localHost;
        }
    }
    else
    {
        // this method will be called to get both IP address from name and name from IP address, so nodename
        // can either be "www.xxx.com" or "xxx.xxx.xxx.xxx".  Therefore we will need to first get the IP bytes
        // gethostbyname will do this for either name or IP format, then we will need to get the name
        // by calling gethostbyaddr to get the host name.

        // first call is to get the IP bytes from string version (name or IP)
        pHost = gethostbyname((RTP_PFCHAR)nodename);

        // second call to get the host name
        if(pHost != NULL)
        {
            pHost = gethostbyaddr((RTP_PFCHAR)&pHost->ip_addr.s_un.S_addr, sizeof(UINT32), PF_INET);

            if(!pHost)
            {
                DEBUG_HANDLE_SOCKET_ERROR( "gethostbyaddr", FALSE );
            }
        }
        else
        {
            DEBUG_HANDLE_SOCKET_ERROR( "gethostbyname", FALSE );

        }
    }

    if(pHost)
    {
        SOCK_addrinfo* pAddrInfo = (SOCK_addrinfo*) private_malloc(sizeof(SOCK_addrinfo));

        if(pAddrInfo)
        {
            memset(pAddrInfo, 0, sizeof(SOCK_addrinfo));

            pAddrInfo->ai_family = RTP_NET_AF_INET;

            SOCK_sockaddr_in *pSockaddr = (SOCK_sockaddr_in*) private_malloc(sizeof(SOCK_sockaddr_in));

            if(pSockaddr)
            {
                memset(pSockaddr, 0, sizeof(SOCK_sockaddr_in));
                
                pSockaddr->sin_addr.S_un.S_addr = pHost->ip_addr.s_un.S_addr;
                pSockaddr->sin_family           = RTP_NET_AF_INET;

                pAddrInfo->ai_addr    = (SOCK_sockaddr*)pSockaddr;
                pAddrInfo->ai_addrlen = sizeof(SOCK_sockaddr_in);
            }

            if(pHost->sz_name != NULL)
            {
                int len = hal_strlen_s(pHost->sz_name);

                if(len > 0)
                {
                    int buffer_size = sizeof(char) * len + 1;
                    
                    pAddrInfo->ai_canonname = (char*) private_malloc(buffer_size);

                    if(pAddrInfo->ai_canonname)
                    {
                        hal_strcpy_s(pAddrInfo->ai_canonname, buffer_size, pHost->sz_name);
                    }
                }
            }
            
            *res = pAddrInfo;
        }
    }
    
    return (*res == NULL? SOCK_SOCKET_ERROR: 0);
}
BOOL MicroBooterUpdateProvider::InstallUpdate( MFUpdate* pUpdate, UINT8* pValidation, INT32 validationLen )
{
    if(pUpdate->Providers->Storage == NULL) return FALSE;

    if(!pUpdate->IsValidated()) return FALSE;

    switch(pUpdate->Header.UpdateType)
    {
        case MFUPDATE_UPDATETYPE_FIRMWARE:
            {
                HAL_UPDATE_CONFIG cfg;

                if(sizeof(cfg.UpdateSignature) < validationLen) return FALSE;
                
                cfg.Header.Enable = TRUE;
                cfg.UpdateID = pUpdate->Header.UpdateID;

                if(validationLen == sizeof(UINT32))
                {
                    cfg.UpdateSignType = HAL_UPDATE_CONFIG_SIGN_TYPE__CRC;
                }
                else
                {
                    cfg.UpdateSignType = HAL_UPDATE_CONFIG_SIGN_TYPE__SIGNATURE;
                }
                
                memcpy( cfg.UpdateSignature, pValidation, validationLen );

                if(HAL_CONFIG_BLOCK::UpdateBlockWithName(cfg.GetDriverName(), &cfg, sizeof(cfg), FALSE))
                {
                    CPU_Reset();
                }
            }
            break;
            
        case MFUPDATE_UPDATETYPE_ASSEMBLY:
            {
                BlockStorageStream stream;
                
                if(NULL == BlockStorageList::GetFirstDevice())
                {
                    BlockStorageList::Initialize();
                
                    BlockStorage_AddDevices();
                
                    BlockStorageList::InitializeDevices();
                }

                if(stream.Initialize(BlockUsage::DEPLOYMENT))
                {
                    if(pUpdate->Header.UpdateSubType == MFUPDATE_UPDATESUBTYPE_ASSEMBLY_REPLACE_DEPLOY)
                    {
                        do
                        {
                            stream.Erase(stream.Length);
                        }
                        while(stream.NextStream());

                        stream.Initialize(BlockUsage::DEPLOYMENT);
                    }
                    
                    do
                    {
                        UINT8 buf[512];
                        INT32 offset = 0;
                        INT32 len = sizeof(buf);
                        const BlockDeviceInfo* deviceInfo = stream.Device->GetDeviceInfo();
                        BOOL isXIP = deviceInfo->Attribute.SupportsXIP;
                        
                        const CLR_RECORD_ASSEMBLY* header;
                        INT32  headerInBytes = sizeof(CLR_RECORD_ASSEMBLY);
                        BYTE * headerBuffer  = NULL;
                        
                        if(!isXIP)
                        {
                            headerBuffer = (BYTE*)private_malloc( headerInBytes );  if(!headerBuffer) return FALSE;
                            memset( headerBuffer, 0,  headerInBytes );
                        }
                        
                        while(TRUE)
                        {
                            if(!stream.Read( &headerBuffer, headerInBytes )) break;
                        
                            header = (const CLR_RECORD_ASSEMBLY*)headerBuffer;
                        
                            // check header first before read
                            if(!header->GoodHeader())
                            {
                                stream.Seek(-headerInBytes);
                                
                                if(stream.IsErased(pUpdate->Header.UpdateSize))
                                {
                                    while(offset < pUpdate->Header.UpdateSize)
                                    {
                                        if((pUpdate->Header.UpdateSize - offset) < len)
                                        {
                                            len = pUpdate->Header.UpdateSize - offset;
                                        }
                                        
                                        offset += pUpdate->Providers->Storage->Read(pUpdate->StorageHandle, offset, buf, len);

                                        stream.Write(buf, len);
                                    }

                                    ClrReboot();
                                    return TRUE;
                                }
                                break;
                            }
                        
                            UINT32 AssemblySizeInByte = ROUNDTOMULTIPLE(header->TotalSize(), CLR_UINT32);
                        
                            stream.Seek( AssemblySizeInByte );
                        }
                        if(!isXIP) private_free( headerBuffer );
                    
                    }
                    while(stream.NextStream());
                }

            }
            break;
    }
    
    return FALSE;
}