www.pudn.com > aspfile.zip > GetFile.cpp, change:1998-11-25,size:5013b


/* 
	$Workfile: GetFile.cpp$ 
	$Header: GetFile.h$ 
 
	Copyright © 1997-1998 Shimon Pozin®. 
	All rights reserved :-) 
 
	@doc 
	@module GetFile.cpp - Manipulates FileSystemObject within ASP | 
 
	This file manipulates an arbitrary binary file. GetFile method uses 
	BinaryWrite() method of IResponse in order to send a file from 
	server to client. This might be useful if client does not have read 
	permissions for the directory where the file is located. 
*/ 
// GetFile.cpp : Implementation of CGetFile 
#include "stdafx.h" 
#include <comdef.h>		// for _variant_t 
#include <new>			// for new stuff of STL! 
#include "ASPFile.h" 
#include "GetFile.h" 
 
///////////////////////////////////////////////////////////////////////////// 
// CGetFile 
 
STDMETHODIMP CGetFile::InterfaceSupportsErrorInfo(REFIID riid) 
{ 
	static const IID* arr[] =  
	{ 
		&IID_IGetFile, 
	}; 
	for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++) 
	{ 
		if (InlineIsEqualGUID(*arr[i],riid)) 
			return S_OK; 
	} 
	return S_FALSE; 
} 
 
STDMETHODIMP CGetFile::OnStartPage (IUnknown* pUnk)   
{ 
	if(!pUnk) 
		return E_POINTER; 
 
	CComPtr<IScriptingContext> spContext; 
	HRESULT hr; 
 
	// Get the IScriptingContext Interface 
	hr = pUnk->QueryInterface(IID_IScriptingContext, (void **)&spContext); 
	if(FAILED(hr)) 
		return hr; 
 
	// Get Request Object Pointer 
	hr = spContext->get_Request(&m_piRequest); 
	if(FAILED(hr)) 
	{ 
		spContext.Release(); 
		return hr; 
	} 
 
	// Get Response Object Pointer 
	hr = spContext->get_Response(&m_piResponse); 
	if(FAILED(hr)) 
	{ 
		m_piRequest.Release(); 
		return hr; 
	} 
	 
	// Get Server Object Pointer 
	hr = spContext->get_Server(&m_piServer); 
	if(FAILED(hr)) 
	{ 
		m_piRequest.Release(); 
		m_piResponse.Release(); 
		return hr; 
	} 
	 
	// Get Session Object Pointer 
	hr = spContext->get_Session(&m_piSession); 
	if(FAILED(hr)) 
	{ 
		m_piRequest.Release(); 
		m_piResponse.Release(); 
		m_piServer.Release(); 
		return hr; 
	} 
 
	// Get Application Object Pointer 
	hr = spContext->get_Application(&m_piApplication); 
	if(FAILED(hr)) 
	{ 
		m_piRequest.Release(); 
		m_piResponse.Release(); 
		m_piServer.Release(); 
		m_piSession.Release(); 
		return hr; 
	} 
	m_bOnStartPageCalled = TRUE; 
	return S_OK; 
} 
 
STDMETHODIMP CGetFile::OnEndPage ()   
{ 
	m_bOnStartPageCalled = FALSE; 
	// Release all interfaces 
	m_piRequest.Release(); 
	m_piResponse.Release(); 
	m_piServer.Release(); 
	m_piSession.Release(); 
	m_piApplication.Release(); 
 
	return S_OK; 
} 
 
 
/* 
	Name:				CGetFile::GetFile 
	Type:				Public 
	Override:			No 
	@mfunc 
	Description: 
		Send binary file from server to client. To send a binary file from server 
		one should create a VARIANT, containing a SAFEARRAY of binary data. Elements 
		of the SAFEARRAY must be of type VT_ARRAY | UI1. 
		If you want to compile this in plain debug, not in UNICODE, you must use 
		boring stuff of USES_CONVERSION etc. for CreateFile. 
	@parm 				VARIANT	 | vFileName	 | File name 
	@rdesc				STDMETHODIMP - S_OK if suceeded, E_FAIL otherwise 
*/ 
#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; 
}