You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
290 lines
8.1 KiB
290 lines
8.1 KiB
/************************************************************************
|
|
|
|
Copyright (c) 2000 - 2000 Microsoft Corporation
|
|
|
|
Module Name :
|
|
|
|
cache.cpp
|
|
|
|
Abstract :
|
|
|
|
Sources files for file cache management
|
|
|
|
Author :
|
|
|
|
Revision History :
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include <accctrl.h>
|
|
#include <aclapi.h>
|
|
|
|
#if !defined(BITS_V12_ON_NT4)
|
|
#include "cache.tmh"
|
|
#endif
|
|
|
|
BOOL
|
|
CProgressiveDL::OpenLocalDownloadFile(
|
|
LPCTSTR Path,
|
|
UINT64 Offset,
|
|
UINT64 Size,
|
|
FILETIME UrlModificationTime, // 0 if unknown
|
|
FILETIME * pFileCreationTime
|
|
)
|
|
{
|
|
HANDLE hFile;
|
|
|
|
bool bOpenExisting;
|
|
|
|
if (Offset > 0)
|
|
{
|
|
// Storing the creation time via SetFileTime doesn't provide ironclad reliability due to granularity problems.
|
|
// A tighter condition for a changed server file would be to check the "etag" header if available from the server.
|
|
|
|
bOpenExisting = true;
|
|
|
|
hFile = CreateFile( Path,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
0,
|
|
NULL );
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
LogError("error %!winerr!, opening '%S'", dwError, Path );
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "CreateFile" );
|
|
return FALSE;
|
|
}
|
|
|
|
LARGE_INTEGER liFileSize;
|
|
|
|
if ( !GetFileSizeEx( hFile, &liFileSize ) )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle( hFile );
|
|
LogError("error %!winerr!, retrieving size of '%S'", dwError, Path );
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "GetFileSizeEx" );
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
if ( Size != liFileSize.QuadPart )
|
|
{
|
|
|
|
CloseHandle( hFile );
|
|
LogError("File size of '%S' changed", Path );
|
|
m_pQMInfo->result = QM_SERVER_FILE_CHANGED;
|
|
return FALSE;
|
|
}
|
|
|
|
LARGE_INTEGER liOffset;
|
|
|
|
liOffset.QuadPart = Offset;
|
|
|
|
if (!SetFilePointerEx( hFile,
|
|
liOffset,
|
|
NULL, // don't need the new file pointer
|
|
FILE_BEGIN ))
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle( hFile );
|
|
LogError("error %!winerr!, seeking to current position in '%S'", dwError, Path );
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
bOpenExisting = false;
|
|
|
|
hFile = CreateFile( Path,
|
|
GENERIC_READ | GENERIC_WRITE,
|
|
0,
|
|
NULL,
|
|
CREATE_ALWAYS,
|
|
FILE_ATTRIBUTE_HIDDEN,
|
|
NULL );
|
|
|
|
if (hFile == INVALID_HANDLE_VALUE )
|
|
{
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, GetLastError(), "CreateFile" );
|
|
return FALSE;
|
|
}
|
|
|
|
// Reserve space for the file upfront.
|
|
|
|
LARGE_INTEGER liOffset;
|
|
liOffset.QuadPart = Size;
|
|
|
|
if (!SetFilePointerEx( hFile,
|
|
liOffset,
|
|
NULL,
|
|
FILE_BEGIN ))
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle( hFile );
|
|
LogError( "error %!winerr! setting end of file, out of disk space?", dwError );
|
|
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
|
|
return FALSE;
|
|
}
|
|
|
|
if ( !SetEndOfFile( hFile ) )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle( hFile );
|
|
LogError( "error %!winerr! setting end of file, out of disk space?", dwError );
|
|
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
|
|
return FALSE;
|
|
}
|
|
|
|
liOffset.QuadPart = 0;
|
|
if (!SetFilePointerEx( hFile,
|
|
liOffset,
|
|
NULL,
|
|
FILE_BEGIN ))
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle( hFile );
|
|
LogError( "error %!winerr! returning to the beginning of the file", dwError );
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFilePointerEx" );
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
if ( UrlModificationTime.dwHighDateTime ||
|
|
UrlModificationTime.dwLowDateTime )
|
|
{
|
|
|
|
if (!SetFileTime( hFile, &UrlModificationTime, NULL, NULL ) )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle( hFile );
|
|
LogError( "error %!winerr! setting creation time", dwError );
|
|
|
|
if (dwError == ERROR_INVALID_PARAMETER)
|
|
{
|
|
dwError = BG_E_INVALID_SERVER_RESPONSE;
|
|
}
|
|
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFileTime" );
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!GetFileTime( hFile, pFileCreationTime, NULL, NULL ) )
|
|
{
|
|
|
|
DWORD dwError = GetLastError();
|
|
CloseHandle( hFile );
|
|
LogError( "error %!winerr!, unable to get file creation time", dwError );
|
|
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "GetFileTime" );
|
|
return FALSE;
|
|
}
|
|
|
|
if ( bOpenExisting )
|
|
{
|
|
|
|
if ( UrlModificationTime.dwHighDateTime ||
|
|
UrlModificationTime.dwLowDateTime )
|
|
{
|
|
|
|
if ( CompareFileTime( &UrlModificationTime, pFileCreationTime ) > 0 )
|
|
{
|
|
// UrlModificationTime is newer
|
|
CloseHandle( hFile );
|
|
LogError("File time of '%S' changed", Path );
|
|
m_pQMInfo->result = QM_SERVER_FILE_CHANGED;
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_hFile = hFile;
|
|
m_CurrentOffset = Offset;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL CProgressiveDL::CloseLocalFile()
|
|
{
|
|
|
|
if (m_hFile == INVALID_HANDLE_VALUE)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
CloseHandle( m_hFile );
|
|
m_hFile = INVALID_HANDLE_VALUE;
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CProgressiveDL::WriteBlockToCache(
|
|
LPBYTE lpBuffer,
|
|
DWORD dwRead
|
|
)
|
|
{
|
|
DWORD dwWritten = 0;
|
|
|
|
ASSERT( m_hFile != INVALID_HANDLE_VALUE );
|
|
|
|
if (! WriteFile( m_hFile,
|
|
lpBuffer,
|
|
dwRead,
|
|
&dwWritten,
|
|
NULL)
|
|
|| (dwRead != dwWritten))
|
|
{
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, GetLastError(), "WriteFile" );
|
|
return FALSE;
|
|
}
|
|
|
|
m_CurrentOffset += dwWritten;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL
|
|
CProgressiveDL::SetFileTimes()
|
|
{
|
|
|
|
ASSERT( m_hFile != INVALID_HANDLE_VALUE );
|
|
|
|
if ( !m_wupdinfo->UrlModificationTime.dwHighDateTime &&
|
|
!m_wupdinfo->UrlModificationTime.dwLowDateTime )
|
|
{
|
|
LogWarning( "Server doesn't support modification times, can't set it on the files." );
|
|
return TRUE;
|
|
}
|
|
|
|
if ( !SetFileTime( m_hFile,
|
|
&m_wupdinfo->UrlModificationTime,
|
|
&m_wupdinfo->UrlModificationTime,
|
|
&m_wupdinfo->UrlModificationTime ) )
|
|
{
|
|
DWORD dwError = GetLastError();
|
|
LogError( "Unable to get times on the local file, error %!winerr!", dwError );
|
|
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFileTime" );
|
|
return FALSE;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|