コード例 #1
0
HRESULT CLR_RT_FileStream::CreateInstance( CLR_RT_HeapBlock& ref, LPCSTR path, int bufferSize )
{
    NATIVE_PROFILE_CLR_IO();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_BinaryBlob* blob;
    CLR_UINT32                   blobSize = sizeof(CLR_RT_FileStream);
    CLR_RT_FileStream*           fs;
    UnicodeString                pathW;

    LPCSTR     nameSpace;
    LPCSTR     relativePath;
    CLR_UINT32 nameSpaceLength;    

    int inputBufferSize  = 0;
    int outputBufferSize = 0;

    FileSystemVolume*        driver;
    STREAM_DRIVER_DETAILS*   sdd;

    TINYCLR_CHECK_HRESULT(CLR_RT_FileStream::SplitFilePath( path, &nameSpace, &nameSpaceLength, &relativePath ));

    /// Retrieve appropriate driver that handles this namespace.
    if((driver = FileSystemVolumeList::FindVolume( nameSpace, nameSpaceLength )) == NULL)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND);
    }

    if(!(driver->ValidateStreamDriver()))
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_DRIVER);
    }

    sdd = driver->DriverDetails();

    if(sdd->bufferingStrategy == SYSTEM_BUFFERED_IO)
    {
        if(bufferSize == 0)
        {
            inputBufferSize  = (sdd->inputBufferSize  > 0) ? sdd->inputBufferSize  : FS_DEFAULT_BUFFER_SIZE;
            outputBufferSize = (sdd->outputBufferSize > 0) ? sdd->outputBufferSize : FS_DEFAULT_BUFFER_SIZE;
        }
        else
        {
            inputBufferSize  = bufferSize;
            outputBufferSize = bufferSize;
        }

        blobSize += inputBufferSize + outputBufferSize;
    }

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_BinaryBlob::CreateInstance( ref, blobSize, NULL, CLR_RT_FileStream::RelocationHandler, 0 ));

    blob = ref.DereferenceBinaryBlob();
    fs   = (CLR_RT_FileStream*)blob->GetData();

    // Clear the memory
    CLR_RT_Memory::ZeroFill( fs, blobSize );

    fs->m_driver        = driver;
    fs->m_driverDetails = sdd;

    switch(sdd->bufferingStrategy)
    {
        case SYSTEM_BUFFERED_IO: // I/O is asynchronous from a PAL level buffer: the runtime will alocate the necesary memory
            {
                BYTE* inputBuffer = (BYTE*)&(fs[ 1 ]);
                BYTE* outputBuffer = inputBuffer + inputBufferSize;

                TINYCLR_CHECK_HRESULT(fs->AssignStorage( inputBuffer, inputBufferSize, outputBuffer, outputBufferSize ));
            }
            break;
            
        case DRIVER_BUFFERED_IO: // I/O is asynchronous from a HAL level or HW buffer: the runtime will just handle the existing memory
            if((sdd->inputBuffer  == NULL && sdd->canRead ) ||
               (sdd->outputBuffer == NULL && sdd->canWrite))
            {
                TINYCLR_SET_AND_LEAVE(CLR_E_INVALID_DRIVER);
            }

            TINYCLR_CHECK_HRESULT(fs->AssignStorage( sdd->inputBuffer,  sdd->inputBufferSize, 
                                                     sdd->outputBuffer, sdd->outputBufferSize ));
            break;
    }

    TINYCLR_CHECK_HRESULT(pathW.Assign( relativePath ));
    TINYCLR_CHECK_HRESULT(driver->Open( pathW, &(fs->m_handle) ));

    TINYCLR_NOCLEANUP();
}
コード例 #2
0
HRESULT CLR_RT_FindFile::CreateInstance( CLR_RT_HeapBlock& ref, LPCSTR path, LPCSTR searchPattern )
{
    NATIVE_PROFILE_CLR_IO();
    TINYCLR_HEADER();

    CLR_RT_HeapBlock_BinaryBlob* blob;
    CLR_RT_FindFile*             ff;
    UnicodeString                pathW;
    CLR_UINT32                   size;
    CLR_UINT32                   i, j;
    CLR_UINT32                   fullPathBufferSize;

    LPCSTR     nameSpace;
    LPCSTR     relativePath;
    LPCWSTR    relativePathW;
    CLR_UINT32 nameSpaceLength;

    // We will support only the "*" search pattern for now
    if(hal_strncmp_s( searchPattern, "*", 2 ) != 0)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED);
    }

    TINYCLR_CHECK_HRESULT(CLR_RT_FileStream::SplitFilePath( path, &nameSpace, &nameSpaceLength, &relativePath ));
    TINYCLR_CHECK_HRESULT(pathW.Assign( relativePath ));

    relativePathW = (LPCWSTR)pathW;

    fullPathBufferSize = FS_MAX_PATH_LENGTH + nameSpaceLength + 1; // '\' before the namespace

    size = sizeof(CLR_RT_FindFile) + fullPathBufferSize * sizeof(UINT16);  

    TINYCLR_CHECK_HRESULT(CLR_RT_HeapBlock_BinaryBlob::CreateInstance( ref, size, NULL, CLR_RT_FindFile::RelocationHandler, 0 ));

    blob = ref.DereferenceBinaryBlob();
    ff   = (CLR_RT_FindFile*)blob->GetData();

    // Clear the memory
    CLR_RT_Memory::ZeroFill( ff, sizeof(CLR_RT_FindFile) );


    /// Retrieve appropriate driver that handles this namespace.    
    if((ff->m_driver = FileSystemVolumeList::FindVolume( nameSpace, nameSpaceLength )) == NULL)
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_VOLUME_NOT_FOUND);
    }

    // Validate all the find related function are present in the driver
    if(!(ff->m_driver->ValidateFind()))
    {
        TINYCLR_SET_AND_LEAVE(CLR_E_NOT_SUPPORTED);
    }

    ff->m_fullPath = (UINT16*)(&ff[ 1 ]);
    ff->m_fullPathBufferSize = fullPathBufferSize;

    // Copy the '\' and nameSpace
    for(i = 0; i < nameSpaceLength + 1; i++)
    {
        ff->m_fullPath[ i ] = path[ i ];
    }

    // Copy the rest of the path from the UTF16 buffer
    for(j = 0; i < fullPathBufferSize && relativePathW[ j ] != 0; i++, j++)
    {
        ff->m_fullPath[ i ] = relativePathW[ j ];
    }

    // Make sure we always ends with '\\'
    if(ff->m_fullPath[ i - 1 ] != '\\')
    {
        ff->m_fullPath[ i++ ] = '\\';
    }

    ff->m_fi.FileName = &(ff->m_fullPath[ i ]);
    ff->m_fi.FileNameSize = fullPathBufferSize - i;

    TINYCLR_CHECK_HRESULT(ff->m_driver->FindOpen( relativePathW, &(ff->m_handle) ));

    TINYCLR_NOCLEANUP();
}