windows-nt/Source/XPSP1/NT/admin/services/drizzle/newjob/cache.cpp
2020-09-26 16:20:57 +08:00

289 lines
7.7 KiB
C++

/************************************************************************
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
)
{
HANDLE hFile;
bool bOpenExisting;
if (Offset > 0)
{
// BUGBUG storing the creation time via SetFileTime doesn't work due to granularity problems.
// The queue manager needs to find out the size & time and store them in the CFile object,
// and the downloader needs to check them when a download resumes.
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 );
SetError( SOURCE_QMGR_FILE, ERROR_STYLE_WIN32, dwError, "SetFileTime" );
return FALSE;
}
}
}
FILETIME CreationTime;
if (!GetFileTime( hFile, &CreationTime, 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, &CreationTime ) > 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_wupdinfo->FileCreationTime = CreationTime;
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;
}