An ASP Component to Send Arbitary Large File from Server to Client

#define RETURN { hr = E_FAIL; goto Cleanup; } // don’t kill me! Look at last examples of MS
// under http://www.microsoft.com/data/xml
// You can’t catch me! 🙂
STDMETHODIMP CGetFile::GetFile(VARIANT vFileName)
{
_variant_t vReturnBuffer;
LPSAFEARRAY psaFile;
HANDLE hFile;
DWORD dwSizeOfFile;
DWORD dwNumberOfBytesRead;
BOOL bResult;
unsigned char *pReturnBuffer = NULL;
long k;
HRESULT hr = S_OK;

// Create file in this case only OPENS an existing file (or fails
// if the file does not exist!)
hFile = ::CreateFile(
vFileName.bstrVal, // name of the file
GENERIC_READ, // desired access
FILE_SHARE_READ, // shared access
NULL, // security attributes
OPEN_EXISTING, // creation disposition – open only if existing!
FILE_FLAG_SEQUENTIAL_SCAN, // flag attributes
NULL );

if( hFile == INVALID_HANDLE_VALUE )
{
return E_FAIL;
}

dwSizeOfFile = ::GetFileSize( hFile, NULL );
if (dwSizeOfFile == 0xFFFFFFFF)
{
return E_FAIL;
}

try
{
pReturnBuffer = new unsigned char[dwSizeOfFile];
}
catch( std::bad_alloc& )
{
return E_FAIL;
}

// Get the binary content of the file
bResult = ::ReadFile( hFile, pReturnBuffer, dwSizeOfFile, &dwNumberOfBytesRead, NULL );
if( FALSE == bResult )
{
RETURN(E_FAIL);
}

psaFile = ::SafeArrayCreateVector( VT_UI1 /*unsigned char*/, 0, dwSizeOfFile );

if( !psaFile )
{
RETURN(E_FAIL);
}

// Fill in the SAFEARRAY with the binary content of the file
for( k = 0; k < (int) dwSizeOfFile; k++ )
{
if( FAILED(::SafeArrayPutElement( psaFile, &k, &pReturnBuffer[k] )) )
{
RETURN(E_FAIL);
}
}

vReturnBuffer.vt = VT_ARRAY | VT_UI1;
V_ARRAY(&vReturnBuffer) = psaFile;

m_piResponse->BinaryWrite(vReturnBuffer);

Cleanup:

if( pReturnBuffer )
delete [] pReturnBuffer;

return SUCCEEDED(hr) ? S_OK : E_FAIL;
}

As you see, the idea is simple: to read the binary content of the file, to pack it into safearray and then to pass as a parameter to IResponse::BinaryWrite(). The process is pretty straightforward

Download source and demo project – 62 KB

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read