in host/common/hostagenthelpers.cpp [1626:1811]
HRESULT CopyVolumeChunkToLocalFile( HANDLE handleVolume,
char *pchFilename,
SV_LONGLONG sv_longlongLength,
SV_LONGLONG sv_longlongByteOffset,
SV_LONGLONG *psv_longlongBytesRead )
{
HRESULT hr = S_OK;
char *pchBuffer = NULL;
DWORD dwBytesRead = 0;
DWORD dwBytesWritten = 0;
DWORD dwLength = VOLUME_READ_CHUNK_SIZE; //BUGBUG: Remove hardcoded value
HANDLE handleFile = INVALID_HANDLE_VALUE;
do
{
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( "ENTERED CopyVolumeChunkToLocalFile()...\n" );
pchBuffer = new char[ dwLength ];
if( NULL == pchBuffer )
{
hr = E_OUTOFMEMORY;
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED CopyVolumeChunkToLocalFile()... hr = %08X\n", hr );
break;
}
LONG lowpart = (LONG) sv_longlongByteOffset;
LONG highpart = (LONG) ( sv_longlongByteOffset >> 32 );
//BUGBUG: -1 should actually be INVALID_SET_FILE_POINTER. See why it doesn't work
//DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
//DebugPrintf( "CALLING SetFilePointer()...\n" );
if( -1 == SetFilePointer( handleVolume,
lowpart,
&( highpart ),
FILE_BEGIN ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED SetFilePointer()... hr = %08X\n", hr );
break;
}
try
{
CreatePaths::createPathsAsNeeded(pchFilename);
}
catch (std::exception ex)
{
DebugPrintf(SV_LOG_ERROR, "%s failed: %s\n", FUNCTION_NAME, ex.what());
hr = S_FALSE;
break;
}
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( "CALLING CreateFile()...\n" );
// PR#10815: Long Path support
handleFile = SVCreateFile( pchFilename,
GENERIC_WRITE,
FILE_SHARE_WRITE | FILE_SHARE_READ,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL );
if( INVALID_HANDLE_VALUE == handleFile )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED CreateFile(%s)... hr = %08X\n", pchFilename, hr );
break;
}
//BUGBUG: Dump headers into the file here.
//
// Write SVD1 header
//
SVD_PREFIX prefix = { SVD_TAG_HEADER1, 1, 0 };
if( !WriteFile( handleFile,
&prefix,
sizeof( prefix ),
&dwBytesWritten,
NULL ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED WriteFile()... hr = %08X\n", hr );
break;
}
assert( sizeof( prefix ) == dwBytesWritten );
SVD_HEADER1 header = { 0 };
if( !WriteFile( handleFile,
&header,
sizeof( header ),
&dwBytesWritten,
NULL ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED WriteFile()... hr = %08X\n", hr );
break;
}
assert( sizeof( header ) == dwBytesWritten );
//
// Write single dirty block header
//
SVD_PREFIX drtdPrefix = { SVD_TAG_DIRTY_BLOCK_DATA, 1, 0 };
if( !WriteFile( handleFile,
&drtdPrefix,
sizeof( drtdPrefix ),
&dwBytesWritten,
NULL ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED WriteFile()... hr = %08X\n", hr );
break;
}
assert( sizeof( prefix ) == dwBytesWritten );
//
// Write the data for DRTD
//
SVD_DIRTY_BLOCK block = { sv_longlongLength, sv_longlongByteOffset };
if( !WriteFile( handleFile,
&block,
sizeof( block ),
&dwBytesWritten,
NULL ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED WriteFile()... hr = %08X\n", hr );
break;
}
*psv_longlongBytesRead = 0;
SV_LONGLONG sv_longlongBytesRemaining = sv_longlongLength;
while( sv_longlongBytesRemaining > 0 )
{
dwLength = std::min( dwLength, (DWORD) sv_longlongBytesRemaining );
if( FALSE == ReadFile( handleVolume,
pchBuffer,
dwLength,
&dwBytesRead,
NULL ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED ReadFile()... hr = %08X\n", hr );
break;
}
if( 0 == WriteFile( handleFile,
pchBuffer,
dwBytesRead,
&dwBytesWritten,
NULL ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED WriteFile()... hr = %08X\n", hr );
break;
}
assert( dwBytesRead == dwBytesWritten );
sv_longlongBytesRemaining -= dwBytesRead;
*psv_longlongBytesRead += dwBytesRead;
}
}
while( FALSE );
delete[] pchBuffer;
if( 0 == CloseHandle( handleFile ) )
{
hr = HRESULT_FROM_WIN32( GetLastError() );
DebugPrintf( "@ LINE %d in FILE %s \n", __LINE__, __FILE__ );
DebugPrintf( hr, "FAILED CloseHandle()... hr = %08X\n", hr );
}
return( hr );
}