|
|
/*++
� 1998 Seagate Software, Inc. All rights reserved.
Module Name:
fsaitem.cpp
Abstract:
This class contains represents a scan item (i.e. file or directory) for NTFS 5.0.
Author:
Chuck Bardeen [cbardeen] 1-Dec-1996
Revision History:
--*/
#include "stdafx.h"
#define WSB_TRACE_IS WSB_TRACE_BIT_FSA
#include "wsb.h"
#include "wsbtrak.h"
#include "fsa.h"
#include "mover.h"
#include "fsaitem.h"
#include "fsaprem.h"
static USHORT iCountItem = 0; // Count of existing objects
HRESULT CFsaScanItem::CompareTo( IN IUnknown* pUnknown, OUT SHORT* pResult )
/*++
Implements:
IWsbCollectable::CompareTo().
--*/ { HRESULT hr = S_OK; CComPtr<IFsaScanItem> pScanItem;
WsbTraceIn(OLESTR("CFsaScanItem::CompareTo"), OLESTR(""));
try {
// Did they give us a valid item to compare to?
WsbAssert(0 != pUnknown, E_POINTER);
// We need the IWsbBool interface to get the value of the object.
WsbAffirmHr(pUnknown->QueryInterface(IID_IFsaScanItem, (void**) &pScanItem));
// Compare the rules.
hr = CompareToIScanItem(pScanItem, pResult);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::CompareTo"), OLESTR("hr = <%ls>, result = <%ls>"), WsbHrAsString(hr), WsbPtrToShortAsString(pResult));
return(hr); }
HRESULT CFsaScanItem::CompareToIScanItem( IN IFsaScanItem* pScanItem, OUT SHORT* pResult )
/*++
Implements:
IFsaScanItem::CompareToIScanItem().
--*/ { HRESULT hr = S_OK; CWsbStringPtr path; CWsbStringPtr name;
WsbTraceIn(OLESTR("CFsaScanItem::CompareToIScanItem"), OLESTR(""));
try {
// Did they give us a valid item to compare to?
WsbAssert(0 != pScanItem, E_POINTER);
// Either compare the name or the id.
WsbAffirmHr(pScanItem->GetPath(&path, 0)); WsbAffirmHr(pScanItem->GetName(&name, 0)); hr = CompareToPathAndName(path, name, pResult);
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::CompareToIScanItem"), OLESTR("hr = <%ls>, result = <%ls>"), WsbHrAsString(hr), WsbPtrToShortAsString(pResult));
return(hr); }
HRESULT CFsaScanItem::CompareToPathAndName( IN OLECHAR* path, IN OLECHAR* name, OUT SHORT* pResult )
/*++
Implements:
IFsaScanItem::CompareToPathAndName().
--*/ { HRESULT hr = S_OK; SHORT aResult = 0;
WsbTraceIn(OLESTR("CFsaScanItem::CompareToPathAndName"), OLESTR(""));
try {
// Compare the path.
aResult = (SHORT) _wcsicmp(m_path, path);
// Compare the name.
if (0 == aResult) { aResult = (SHORT) _wcsicmp(m_findData.cFileName, name); }
if (0 != aResult) { hr = S_FALSE; }
if (0 != pResult) { *pResult = aResult; }
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::CompareToPathAndName"), OLESTR("hr = <%ls>, result = <%u>"), WsbHrAsString(hr), aResult);
return(hr); }
HRESULT CFsaScanItem::Copy( IN OLECHAR* dest, IN BOOL /*retainHierarcy*/, IN BOOL /*expandPlaceholders*/, IN BOOL overwriteExisting )
/*++
Implements:
IFsaScanItem::Copy().
--*/ { HRESULT hr = S_OK;
try {
// NOTE : This default behavior causes placeholders
// to be expanded and probably doesn't retain the heirarchy.
WsbAssert(0 != dest, E_POINTER); WsbAssert(CopyFile(m_findData.cFileName, dest, overwriteExisting), E_FAIL);
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::CreateLocalStream( OUT IStream **ppStream )
/*++
Implements:
IFsaScanItem::CreateLocalStream().
--*/ { HRESULT hr = S_OK; LARGE_INTEGER fileSize; CWsbStringPtr volName;
WsbTraceIn(OLESTR("CFsaScanItem::CreateLocalStream"), OLESTR("")); try { CWsbStringPtr localName;
if ( !m_gotPlaceholder) { //
// Get the placeholder info
//
fileSize.LowPart = m_findData.nFileSizeLow; fileSize.HighPart = m_findData.nFileSizeHigh; WsbAffirmHr(IsManaged(0, fileSize.QuadPart)); }
WsbAssert( 0 != ppStream, E_POINTER); WsbAffirmHr( CoCreateInstance( CLSID_CNtFileIo, 0, CLSCTX_SERVER, IID_IDataMover, (void **)&m_pDataMover ) ); //
// Set the device name for the mover so it can set the source infor for the USN journal.
//
WsbAffirmHr(m_pResource->GetPath(&volName, 0)); WsbAffirmHr( m_pDataMover->SetDeviceName(volName)); //WsbAffirmHr(GetFullPathAndName( NULL, 0, &localName, 0));
WsbAffirmHr(GetFullPathAndName( OLESTR("\\\\?\\"), 0, &localName, 0)); WsbAffirmHr( m_pDataMover->CreateLocalStream( localName, MVR_MODE_WRITE | MVR_FLAG_HSM_SEMANTICS | MVR_FLAG_POSIX_SEMANTICS, &m_pStream ) );
LARGE_INTEGER seekTo; ULARGE_INTEGER pos; seekTo.QuadPart = m_placeholder.dataStreamStart; WsbAffirmHr( m_pStream->Seek( seekTo, STREAM_SEEK_SET, &pos ) ); *ppStream = m_pStream; m_pStream.p->AddRef();
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::CreateLocalStream"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::Delete( void )
/*++
Implements:
IFsaScanItem::Delete().
--*/ { HRESULT hr = S_OK; CWsbStringPtr tmpString; HANDLE fileHandle;
try {
// This is the name of the file we want to delete.
WsbAffirmHr(GetFullPathAndName(OLESTR("\\\\?\\"), 0, &tmpString, 0));
// Since we want to be POSIX compliant, we can't use DeleteFile() and instead will
// open with the delete on close flag. This doesn't handle read-only files, so we
// have to change that ourselves.
WsbAffirmHr(MakeReadWrite());
fileHandle = CreateFile(tmpString, GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_POSIX_SEMANTICS | FILE_FLAG_DELETE_ON_CLOSE, 0);
if (INVALID_HANDLE_VALUE == fileHandle) { WsbThrow(HRESULT_FROM_WIN32(GetLastError())); } else { if (!CloseHandle(fileHandle)) { WsbThrow(HRESULT_FROM_WIN32(GetLastError())); } }
} WsbCatch(hr);
return(hr); } #pragma optimize("g", off)
HRESULT CFsaScanItem::FinalConstruct( void )
/*++
Implements:
CComObjectRoot::FinalConstruct().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::FinalConstruct"), OLESTR(""));
try {
WsbAffirmHr(CComObjectRoot::FinalConstruct());
m_handle = INVALID_HANDLE_VALUE; m_gotPhysicalSize = FALSE; m_physicalSize.QuadPart = 0; m_gotPlaceholder = FALSE; m_changedAttributes = FALSE; m_handleRPI = 0;
// Add class to object table
WSB_OBJECT_ADD(CLSID_CFsaScanItemNTFS, this);
} WsbCatch(hr);
iCountItem++;
WsbTraceOut(OLESTR("CFsaScanItem::FinalConstruct"), OLESTR("hr = <%ls>, Count is <%d>"), WsbHrAsString(hr), iCountItem);
return(hr); } #pragma optimize("", on)
void CFsaScanItem::FinalRelease( void )
/*++
Implements:
CComObjectRoot::FinalRelease().
--*/ { WsbTraceIn(OLESTR("CFsaScanItem::FinalRelease"), OLESTR(""));
// Subtract class from object table
WSB_OBJECT_SUB(CLSID_CFsaScanItemNTFS, this);
// Terminate the scan and free the path memory.
if (INVALID_HANDLE_VALUE != m_handle) { FindClose(m_handle); m_handle = INVALID_HANDLE_VALUE; } if (0 != m_handleRPI) { CloseHandle(m_handleRPI); m_handleRPI = 0; }
if (m_pUnmanageDb != NULL) { // Db must be open
(void)m_pUnmanageDb->Close(m_pDbSession); m_pDbSession = 0; m_pUnmanageRec = 0; }
if (TRUE == m_changedAttributes) { //
// We changed it from read only to read/write - put it back.
//
RestoreAttributes(); }
//
// Detach the data mover stream
if (m_pDataMover != 0) { WsbAffirmHr( m_pDataMover->CloseStream() ); }
// Let the parent class do his thing.
CComObjectRoot::FinalRelease();
iCountItem--; WsbTraceOut(OLESTR("CFsaScanItem::FinalRelease"), OLESTR("Count is <%d>"), iCountItem); }
HRESULT CFsaScanItem::FindFirst( IN IFsaResource* pResource, IN OLECHAR* path, IN IHsmSession* pSession )
/*++
Implements:
IFsaScanItem::FindFirst().
--*/ { HRESULT hr = S_OK; CWsbStringPtr findPath; CWsbStringPtr searchName; OLECHAR* slashPtr; DWORD lErr;
WsbTraceIn(OLESTR("CFsaScanItem::FindFirst"), OLESTR("path = <%ls>"), path);
try {
WsbAssert(0 != pResource, E_POINTER); WsbAssert(0 != path, E_POINTER);
// Store off some of the scan information.
m_pResource = pResource; m_pSession = pSession;
// Break up the incoming path into a path and a name.
m_path = path; slashPtr = wcsrchr(m_path, L'\\');
// We could try to support relative path stuff (i.e. current
// directory, but I am not going to do it for now.
WsbAffirm(slashPtr != 0, E_FAIL); searchName = &(slashPtr[1]); slashPtr[1] = 0;
// Get a path that can be used by the find function.
WsbAffirmHr(GetPathForFind(searchName, &findPath, 0));
// Scan starting at the specified path.
m_handle = FindFirstFileEx(findPath, FindExInfoStandard, &m_findData, FindExSearchNameMatch, 0, FIND_FIRST_EX_CASE_SENSITIVE);
lErr = GetLastError();
// If we found a file, then remember the scan handle and
// return the scan item.
WsbAffirm(INVALID_HANDLE_VALUE != m_handle, WSB_E_NOTFOUND);
m_gotPhysicalSize = FALSE; m_physicalSize.QuadPart = 0; m_gotPlaceholder = FALSE;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::FindFirst"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CFsaScanItem::FindNext( void )
/*++
Implements:
IFsaScanItem::FindNext().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::FindNext"), OLESTR(""));
try {
WsbAssert(INVALID_HANDLE_VALUE != m_handle, E_FAIL);
if (TRUE == m_changedAttributes) { //
// We changed it from read only to read/write - put it back.
//
RestoreAttributes(); }
// Continue the scan.
WsbAffirm(FindNextFile(m_handle, &m_findData), WSB_E_NOTFOUND);
m_gotPhysicalSize = FALSE; m_physicalSize.QuadPart = 0; m_gotPlaceholder = FALSE;
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::FindNext"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CFsaScanItem::GetAccessTime( OUT FILETIME* pTime )
/*++
Implements:
IFsaScanItem::GetAccessTime().
--*/ { HRESULT hr = S_OK;
try {
WsbAssert(0 != pTime, E_POINTER); *pTime = m_findData.ftLastAccessTime;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetGroup( OUT OLECHAR** /*pGroup*/, IN ULONG /*bufferSize*/ )
/*++
Implements:
IFsaScanItem::GetGroup().
--*/ { HRESULT hr = S_OK;
try {
hr = E_NOTIMPL;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetLogicalSize( OUT LONGLONG* pSize )
/*++
Implements:
IFsaScanItem::GetLogicalSize().
--*/ { HRESULT hr = S_OK; LARGE_INTEGER logSize;
try {
WsbAssert(0 != pSize, E_POINTER); logSize.LowPart = m_findData.nFileSizeLow; logSize.HighPart = m_findData.nFileSizeHigh; *pSize = logSize.QuadPart;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetModifyTime( OUT FILETIME* pTime )
/*++
Implements:
IFsaScanItem::GetModifyTime().
--*/ { HRESULT hr = S_OK;
try {
WsbAssert(0 != pTime, E_POINTER); *pTime = m_findData.ftLastWriteTime;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetName( OUT OLECHAR** pName, IN ULONG bufferSize )
/*++
Implements:
IFsaScanItem::GetName().
--*/ { HRESULT hr = S_OK; CWsbStringPtr tmpString = m_findData.cFileName;
try {
WsbAssert(0 != pName, E_POINTER); WsbAffirmHr(tmpString.CopyTo(pName, bufferSize));
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetOwner( OUT OLECHAR** /*pOwner*/, IN ULONG /*bufferSize*/ )
/*++
Implements:
IFsaScanItem::GetOwner().
--*/ { HRESULT hr = S_OK;
try {
hr = E_NOTIMPL;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetPath( OUT OLECHAR** pPath, IN ULONG bufferSize )
/*++
Implements:
IFsaScanItem::GetPath().
--*/ { HRESULT hr = S_OK;
try {
WsbAssert(0 != pPath, E_POINTER); WsbAffirmHr(m_path.CopyTo(pPath, bufferSize));
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetPathForFind( IN OLECHAR* searchName, OUT OLECHAR** pPath, IN ULONG bufferSize )
/*++
Implements:
IFsaScanItem::GetPathForFind().
--*/ { HRESULT hr = S_OK; CWsbStringPtr tmpString;
try {
WsbAssert(0 != pPath, E_POINTER);
// Get a buffer.
WsbAffirmHr(tmpString.TakeFrom(*pPath, bufferSize));
try {
// Get the path to the resource of the resource.
//
WsbAffirmHr(m_pResource->GetPath(&tmpString, 0)); WsbAffirmHr(tmpString.Prepend(OLESTR("\\\\?\\"))); //WsbAffirmHr(tmpString.Append(OLESTR("\\")));
// Copy in the path.
//WsbAffirmHr(tmpString.Prepend(OLESTR("\\\\?\\")));
WsbAffirmHr(tmpString.Append(&(m_path[1]))); WsbAffirmHr(tmpString.Append(searchName));
} WsbCatch(hr);
WsbAffirmHr(tmpString.GiveTo(pPath));
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetPathAndName( IN OLECHAR* appendix, OUT OLECHAR** pPath, IN ULONG bufferSize )
/*++
Implements:
IFsaScanItem::GetPathAndName().
--*/ { HRESULT hr = S_OK; CWsbStringPtr tmpString;
try {
WsbAssert(0 != pPath, E_POINTER);
// Get a buffer.
WsbAffirmHr(tmpString.TakeFrom(*pPath, bufferSize));
try {
tmpString = m_path; tmpString.Append(m_findData.cFileName);
if (0 != appendix) { tmpString.Append(appendix); }
} WsbCatch(hr);
// Give responsibility for freeing the memory back to the caller.
WsbAffirmHr(tmpString.GiveTo(pPath));
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetFullPathAndName( IN OLECHAR* prependix, IN OLECHAR* appendix, OUT OLECHAR** pPath, IN ULONG bufferSize )
/*++
Implements:
IFsaScanItem::GetFullPathAndName().
--*/ { HRESULT hr = S_OK; CWsbStringPtr tmpString; CWsbStringPtr tmpString2;
try {
WsbAssert(0 != pPath, E_POINTER);
// Get a buffer.
WsbAffirmHr(tmpString.TakeFrom(*pPath, bufferSize));
try { if (0 != prependix) { tmpString = prependix; // Get the path to the resource of the resource.
WsbAffirmHr(m_pResource->GetPath(&tmpString2, 0)); WsbAffirmHr(tmpString.Append(tmpString2)); } else { WsbAffirmHr(m_pResource->GetPath(&tmpString, 0)); }
// Copy in the path.
WsbAffirmHr(tmpString.Append(&(m_path[1]))); WsbAffirmHr(tmpString.Append(m_findData.cFileName)); if (0 != appendix) { WsbAffirmHr(tmpString.Append(appendix)); }
} WsbCatch(hr);
// Give responsibility for freeing the memory back to the caller.
WsbAffirmHr(tmpString.GiveTo(pPath));
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetPhysicalSize( OUT LONGLONG* pSize )
/*++
Implements:
IFsaScanItem::GetPhysicalSize().
--*/ { HRESULT hr = S_OK; CWsbStringPtr path;
try {
WsbAssert(0 != pSize, E_POINTER);
//WsbAssertHr(GetFullPathAndName(NULL, 0, &path, 0));
WsbAssertHr(GetFullPathAndName(OLESTR("\\\\?\\"), 0, &path, 0));
// Only read this value in once, but wait until it is asked for
// before reading it in (since this call takes time and many scans
// won't need the information.
if (!m_gotPhysicalSize) { m_physicalSize.LowPart = GetCompressedFileSize(path, &m_physicalSize.HighPart); if (MAXULONG == m_physicalSize.LowPart) { // Have to check last error since MAXULONG could be a valid
// value for the low part of the size.
DWORD err = GetLastError();
if (err != NO_ERROR) { WsbTrace(OLESTR("CFsaScanItem::GetPhysicalSize of %ws Last error = %u\n"), (WCHAR *) path, err); }
WsbAffirm(NO_ERROR == err, E_FAIL); } m_gotPhysicalSize = TRUE; }
*pSize = m_physicalSize.QuadPart;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetPremigratedUsn( OUT LONGLONG* pFileUsn )
/*++
Implements:
Routine Description:
Get the USN Journal number for this file from the premigrated list.
Arguments:
pFileUsn - Pointer to File USN to be returned.
Return Value:
S_OK - success
--*/ { HRESULT hr = S_OK;
try { CComPtr<IWsbDbSession> pDbSession; CComPtr<IFsaPremigratedDb> pPremDb; CComPtr<IFsaResourcePriv> pResourcePriv;
WsbAssert(pFileUsn, E_POINTER);
// Get the premigrated list DB
WsbAffirmHr(m_pResource->QueryInterface(IID_IFsaResourcePriv, (void**) &pResourcePriv)); WsbAffirmHr(pResourcePriv->GetPremigrated(IID_IFsaPremigratedDb, (void**) &pPremDb));
// Open the premigration list
WsbAffirmHr(pPremDb->Open(&pDbSession));
try { FSA_PLACEHOLDER PlaceHolder; CComPtr<IFsaPremigratedRec> pPremRec; LONGLONG usn;
// Get a DB entity for the search
WsbAffirmHr(pPremDb->GetEntity(pDbSession, PREMIGRATED_REC_TYPE, IID_IFsaPremigratedRec, (void**) &pPremRec)); WsbAffirmHr(pPremRec->UseKey(PREMIGRATED_BAGID_OFFSETS_KEY_TYPE));
// Find the record
WsbAffirmHr(GetPlaceholder(0, 0, &PlaceHolder)); WsbAffirmHr(pPremRec->SetBagId(PlaceHolder.bagId)); WsbAffirmHr(pPremRec->SetBagOffset(PlaceHolder.fileStart)); WsbAffirmHr(pPremRec->SetOffset(PlaceHolder.dataStreamStart)); WsbAffirmHr(pPremRec->FindEQ());
// Get the stored USN
WsbAffirmHr(pPremRec->GetFileUSN(&usn)); *pFileUsn = usn; } WsbCatch(hr);
// Close the DB
pPremDb->Close(pDbSession);
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetSession( OUT IHsmSession** ppSession )
/*++
Implements:
IFsaScanItem::GetSession().
--*/ { HRESULT hr = S_OK;
try {
WsbAssert(0 != ppSession, E_POINTER);
*ppSession = m_pSession; m_pSession.p->AddRef();
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::GetUncPathAndName( IN OLECHAR* prependix, IN OLECHAR* appendix, OUT OLECHAR** pPath, IN ULONG bufferSize )
/*++
Implements:
IFsaScanItem::GetUncPathAndName().
--*/ { HRESULT hr = S_OK; CWsbStringPtr tmpString; CWsbStringPtr tmpString2;
try {
WsbAssert(0 != pPath, E_POINTER);
// Get a buffer.
WsbAffirmHr(tmpString.TakeFrom(*pPath, bufferSize));
try { if (0 != prependix) { tmpString = prependix; // Get the path to the resource of the resource.
WsbAffirmHr(m_pResource->GetUncPath(&tmpString2, 0)); WsbAffirmHr(tmpString.Append(tmpString2)); } else { WsbAffirmHr(m_pResource->GetPath(&tmpString, 0)); }
// Copy in the path.
WsbAffirmHr(tmpString.Append(&(m_path[1]))); WsbAffirmHr(tmpString.Append(m_findData.cFileName)); if (0 != appendix) { WsbAffirmHr(tmpString.Append(appendix)); }
} WsbCatch(hr);
// Give responsibility for freeing the memory back to the caller.
WsbAffirmHr(tmpString.GiveTo(pPath));
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::IsAParent( void )
/*++
Implements:
IFsaScanItem::IsAParent().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::IsARelativeParent( void )
/*++
Implements:
IFsaScanItem::IsARelativeParent().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) {
// looking for "."
if (m_findData.cFileName[0] == L'.') {
if (m_findData.cFileName[1] == 0) { hr = S_OK; }
// looking for "."
else if (m_findData.cFileName[1] == L'.') {
if (m_findData.cFileName[2] == 0) { hr = S_OK; } } } }
return(hr); }
HRESULT CFsaScanItem::IsCompressed( void )
/*++
Implements:
IFsaScanItem::IsCompressed().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_COMPRESSED) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::IsEncrypted( void )
/*++
Implements:
IFsaScanItem::IsEncrypted().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_ENCRYPTED) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::IsDeleteOK( IN IFsaPostIt *pPostIt )
/*++
Implements:
IFsaScanItem::IsDeleteOK().
--*/ { HRESULT hr = S_OK; WsbTraceIn(OLESTR("CFsaScanItem::IsDeleteOK"), OLESTR(""));
try { //
// Get the version ID from the FSA Post it. This is the
// version of the file at the time of the migrate request
//
LONGLONG workVersionId; WsbAffirmHr(pPostIt->GetFileVersionId(&workVersionId));
//
// Get the version of the file at the time of this scan
//
LONGLONG scanVersionId; WsbAffirmHr(GetVersionId(&scanVersionId));
//
// See if the versions match
//
WsbTrace(OLESTR("CFsaScanItem::IsDeleteOK: workVersionId:<%I64u> scanVersionId:<%I64u>\n"), workVersionId, scanVersionId);
if (workVersionId != scanVersionId) { WsbTrace(OLESTR("CFsaScanItem::IsDeleteOK: File version has changed!\n")); WsbThrow(FSA_E_FILE_CHANGED); }
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::IsDeleteOk"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::IsGroupMemberOf( OLECHAR* /*group*/ )
/*++
Implements:
IFsaScanItem::IsGroupMemberOf().
--*/ { HRESULT hr = S_FALSE;
hr = E_NOTIMPL;
return(hr); }
HRESULT CFsaScanItem::IsHidden( void )
/*++
Implements:
IFsaScanItem::IsHidden().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::IsManageable( IN LONGLONG offset, IN LONGLONG size )
/*++
Implements:
IFsaScanItem::IsManageable().
--*/ { HRESULT hr = S_FALSE; HRESULT hr2; LONGLONG logicalSize; LONGLONG managableSize; LONGLONG maxFileSize; FILETIME time; FILETIME managableTime; BOOL isRelative;
//
// Get some strings for logging and tracing
//
CWsbStringPtr fileName; CWsbStringPtr jobName; try { WsbAffirmHr(GetFullPathAndName( 0, 0, &fileName, 0)); WsbAffirmHr(m_pSession->GetName(&jobName, 0)); } WsbCatch( hr );
WsbTraceIn(OLESTR("CFsaScanItem::IsManageable"), OLESTR("<%ls>"), (OLECHAR *)fileName); try {
// To be managable the item:
// - can't already be managed (premigratted or truncated)
// - can't be a link
// - can't be encrypted
// - can't be sparse
// - can't have extended attributes (reparse point limitation)
// - must have a size bigger than the resource's default size
// - must have a last access time older than the resource's default time
// Managed?
hr2 = IsManaged(offset, size); if (S_FALSE == hr2) {
// A link?
hr2 = IsALink(); if (S_FALSE == hr2) {
// Encrypted?
hr2 = IsEncrypted(); if (S_FALSE == hr2) {
// A sparse?
hr2 = IsSparse(); if (S_FALSE == hr2) {
// A sparse?
hr2 = HasExtendedAttributes(); if (S_FALSE == hr2) {
// Big enough?
WsbAffirmHr(GetLogicalSize(&logicalSize)); WsbAffirmHr(m_pResource->GetManageableItemLogicalSize(&managableSize)); if (logicalSize >= managableSize) {
// Old enough?
WsbAffirmHr(GetAccessTime(&time)); WsbAffirmHr(m_pResource->GetManageableItemAccessTime(&isRelative, &managableTime)); if (WsbCompareFileTimes(time, managableTime, isRelative, FALSE) >= 0) {
// Small enough? (This is according to media size limit !)
CComPtr<IFsaResourcePriv> pResourcePriv; WsbAffirmHr(m_pResource->QueryInterface(IID_IFsaResourcePriv, (void**) &pResourcePriv)); WsbAffirmHr(pResourcePriv->GetMaxFileLogicalSize(&maxFileSize)); if ((logicalSize <= maxFileSize) || (0 == maxFileSize)) {
// It can be managed!!
hr = S_OK; } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_ISTOOLARGE, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); WsbTrace(OLESTR("CFsaScanItem::IsManageable: file not manageable: Logical size = %I64d; Max file size = %I64d\n"), logicalSize, maxFileSize); } } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_ISACCESSED, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); } } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_ISTOOSMALL, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); } } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_HASEA, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); } } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_ISSPARSE, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); } } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_ISENCRYPTED, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); } } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_ISALINK, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); } } else { WsbLogEvent(FSA_MESSAGE_FILESKIPPED_ISMANAGED, 0, NULL, (OLECHAR*) jobName, WsbAbbreviatePath(fileName, 120), WsbHrAsString(hr), NULL); }
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::IsManageable"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::IsMigrateOK( IN IFsaPostIt *pPostIt )
/*++
Implements:
IFsaScanItem::IsMigrateOK().
--*/ { HRESULT hr = S_OK; WsbTraceIn(OLESTR("CFsaScanItem::IsMigrateOK"), OLESTR(""));
try { //
// Make sure the file isn't already managed. This could happen if two jobs were scanning
// the same volume.
//
LONGLONG offset; LONGLONG size;
WsbAffirmHr(pPostIt->GetRequestOffset(&offset)); WsbAffirmHr(pPostIt->GetRequestSize(&size)); if (IsManaged(offset, size) == S_OK) { //
// The file is already managed so skip it
//
WsbTrace(OLESTR("A manage request for an already managed file - skip it!\n")); WsbThrow(FSA_E_FILE_ALREADY_MANAGED); }
//
// Get the version ID from the FSA Post it. This is the
// version of the file at the time of the migrate request
//
LONGLONG workVersionId; WsbAffirmHr(pPostIt->GetFileVersionId(&workVersionId));
//
// Get the version of the file at the time of this scan
//
LONGLONG scanVersionId; WsbAffirmHr(GetVersionId(&scanVersionId));
//
// See if the versions match
//
WsbTrace(OLESTR("CFsaScanItem::IsMigrateOK: workVersionId:<%I64u> scanVersionId:<%I64u>\n"), workVersionId, scanVersionId);
if (workVersionId != scanVersionId) { WsbTrace(OLESTR("CFsaScanItem::IsMigrateOK: File version has changed!\n")); WsbThrow(FSA_E_FILE_CHANGED); }
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::IsMigrateOK"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::IsMbit( void )
/*++
Implements:
IFsaScanItem::IsMbit().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::IsOffline( void ) /*++
Implements:
IFsaScanItem::IsOffline().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_OFFLINE) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::IsOwnerMemberOf( OLECHAR* /*group*/ )
/*++
Implements:
IFsaScanItem::IsOwnerMemberOf().
--*/ { HRESULT hr = S_FALSE;
hr = E_NOTIMPL;
return(hr); }
HRESULT CFsaScanItem::IsReadOnly( void )
/*++
Implements:
IFsaScanItem::IsReadOnly().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_READONLY) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::IsRecallOK( IN IFsaPostIt *pPostIt )
/*++
Implements:
IFsaScanItem::IsRecallOK().
--*/ { HRESULT hr = S_OK; WsbTraceIn(OLESTR("CFsaScanItem::IsRecallOK"), OLESTR(""));
try { LONGLONG offset; LONGLONG size; //
// Make sure the file is still truncated
//
WsbAffirmHr(pPostIt->GetRequestOffset(&offset)); WsbAffirmHr(pPostIt->GetRequestSize(&size)); hr = IsTruncated(offset, size); if (S_OK != hr) { //
// The file is not truncated, so skip it
//
WsbTrace(OLESTR("CFsaScanItem::IsRecallOK - file isn't truncated.\n")); WsbThrow(FSA_E_FILE_NOT_TRUNCATED); }
// Get the version ID from the FSA Post it. This is the
// version of the file at the time of the migrate request
//
LONGLONG workVersionId; WsbAffirmHr(pPostIt->GetFileVersionId(&workVersionId));
//
// Get the version of the file
//
LONGLONG scanVersionId; WsbAffirmHr(GetVersionId(&scanVersionId));
//
// See if the versions match
//
WsbTrace(OLESTR("CFsaScanItem::IsRecallOK: workVersionId:<%I64u> scanVersionId:<%I64u>\n"), workVersionId, scanVersionId);
if (workVersionId != scanVersionId) { WsbTrace(OLESTR("CFsaScanItem::IsRecallOK: File version has changed!\n"));
//
// If the use has changed alternate data streams
// the file version ID may have changed but it is
// OK to recall the file. So if the version ID's
// don't match, then check to see if the truncated
// part of the file is OK. If so, allow the recall
// to happen.
//
//
// Check to see if the whole file is still sparse
//
if (IsTotallySparse() == S_OK) { //
// The file is OK so far to recall but we need
// to make the last modify dates match
//
FSA_PLACEHOLDER placeholder; WsbAffirmHr(pPostIt->GetPlaceholder(&placeholder));; placeholder.fileVersionId = scanVersionId; WsbAffirmHr(pPostIt->SetPlaceholder(&placeholder)); } else { //
// The file has been changed, recalling data will
// overwrite something that has been added since the
// truncation occurred. So don't do anything.
//
WsbTrace(OLESTR("File is no longer sparse.!\n")); WsbThrow(FSA_E_FILE_CHANGED); }
}
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::IsRecallOK"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::IsSparse( void )
/*++
Implements:
IFsaScanItem::IsSparse().
--*/ { HRESULT hr = S_FALSE; LONGLONG size;
WsbTraceIn(OLESTR("CFsaScanItem::IsSparse"), OLESTR("")); if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0) { hr = GetLogicalSize( &size ) ; if ( S_OK == hr ) { hr = CheckIfSparse(0, size ); if ( (FSA_E_FILE_IS_TOTALLY_SPARSE == hr) || (FSA_E_FILE_IS_PARTIALLY_SPARSE == hr) ) { hr = S_OK; } else { hr = S_FALSE; } } } WsbTraceOut(OLESTR("CFsaScanItem::IsSparse"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::IsTotallySparse( void )
/*++
Implements:
IFsaScanItem::IsTotallySparse().
--*/ { HRESULT hr = S_FALSE; LONGLONG size;
WsbTraceIn(OLESTR("CFsaScanItem::IsTotallySparse"), OLESTR("")); if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_SPARSE_FILE) != 0) { hr = GetLogicalSize( &size ) ; if ( S_OK == hr ) { hr = CheckIfSparse(0, size ); if (FSA_E_FILE_IS_TOTALLY_SPARSE == hr) { hr = S_OK; } else { hr = S_FALSE; } } }
WsbTraceOut(OLESTR("CFsaScanItem::IsTotallySparse"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::Manage( IN LONGLONG offset, IN LONGLONG size, IN GUID storagePoolId, IN BOOL truncate )
/*++
Implements:
IFsaScanItem::Manage().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::Manage"), OLESTR(""));
try {
WsbAssert(GUID_NULL != storagePoolId, E_INVALIDARG); WsbAffirmHr(m_pResource->Manage((IFsaScanItem*) this, offset, size, storagePoolId, truncate));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::Manage"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CFsaScanItem::Move( OLECHAR* dest, BOOL /*retainHierarcy*/, BOOL /*expandPlaceholders*/, BOOL overwriteExisting )
/*++
Implements:
IFsaScanItem::Move().
--*/ { HRESULT hr = S_OK; DWORD mode = MOVEFILE_COPY_ALLOWED;
try {
// NOTE : This default behavior causes placeholders
// to be expanded when moving to another volume and probably doesn't
// retain the heirarchy.
WsbAssert(0 != dest, E_POINTER);
if (overwriteExisting) { mode |= MOVEFILE_REPLACE_EXISTING; }
WsbAssert(MoveFileEx(m_findData.cFileName, dest, mode), E_FAIL);
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::Recall( IN LONGLONG offset, IN LONGLONG size, IN BOOL deletePlaceholder )
/*++
Implements:
IFsaScanItem::Recall().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::Recall"), OLESTR(""));
try {
WsbAffirmHr(m_pResource->Recall((IFsaScanItem*) this, offset, size, deletePlaceholder));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::Recall"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CFsaScanItem::Recycle( void )
/*++
Implements:
IFsaScanItem::Recycle().
--*/ { HRESULT hr = S_OK;
try {
// Probably need to look at SHFileOperation().
hr = E_NOTIMPL;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::IsSystem( void )
/*++
Implements:
IFsaScanItem::IsSystem().
--*/ { HRESULT hr = S_FALSE;
if ((m_findData.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) != 0) { hr = S_OK; }
return(hr); }
HRESULT CFsaScanItem::Test( USHORT* passed, USHORT* failed )
/*++
Implements:
IWsbTestable::Test().
--*/ { HRESULT hr = S_OK;
try {
WsbAssert(0 != passed, E_POINTER); WsbAssert(0 != failed, E_POINTER);
*passed = 0; *failed = 0;
} WsbCatch(hr);
return(hr); }
HRESULT CFsaScanItem::Unmanage( IN LONGLONG offset, IN LONGLONG size )
/*++
Implements:
IFsaScanItem::Unmanage().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::Unmanage"), OLESTR("<%ls>"), WsbAbbreviatePath(m_path, 120));
try {
// We only need to worry about files that have placeholder information.
if (IsManaged(offset, size) == S_OK) {
// If the file is truncated, then we need to recall the data
// before deleting the placeholder information.
// NOTE: We set a flag on the Recall so the placeholder will
// be deleted after the file is recalled.
if (IsTruncated(offset, size) == S_OK) { WsbAffirmHr(Recall(offset, size, TRUE)); } else {
// For disaster recovery, it would be better to delete the placeholder
// and THEN remove this file from the premigration list. Unfortunately,
// after deleting the placeholder, the RemovePremigrated call fails
// because it needs to get some information from the placeholder (which
// is gone). So we do it in this order.
hr = m_pResource->RemovePremigrated((IFsaScanItem*) this, offset, size); if (WSB_E_NOTFOUND == hr) { // It's no tragedy if this file wasn't in the list since we were
// going to delete it anyway (although it shouldn't happen) so
// let's continue anyway
hr = S_OK; } WsbAffirmHr(hr); WsbAffirmHr(DeletePlaceholder(offset, size)); } }
} WsbCatch(hr); WsbTraceOut(OLESTR("CFsaScanItem::Unmanage"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CFsaScanItem::Validate( IN LONGLONG offset, IN LONGLONG size )
/*++
Implements:
IFsaScanItem::Validate().
--*/ { HRESULT hr = S_OK; BOOL fileIsTruncated = FALSE; LONGLONG usn = 0;
WsbTraceIn(OLESTR("CFsaScanItem::Validate"), OLESTR("offset = <%I64u>, size = <%I64u>"), offset, size); try { //
// Do some local validation before calling the engine.
//
// We only need to worry about files that have placeholder information.
if (IsManaged(offset, size) == S_OK) { //
// If the file is marked as truncated, make sure it is still truncated.
//
if (IsTruncated(offset, size) == S_OK) { //
// Check to see if the file is totally sparse to see if it is truncated.
//
if (IsTotallySparse() != S_OK) { //
// The file is marked as truncated but is not truncated
// Make it truncated.
//
WsbAffirmHr(Truncate(offset,size)); WsbLogEvent(FSA_MESSAGE_VALIDATE_TRUNCATED_FILE, 0, NULL, WsbAbbreviatePath(m_path, 120), WsbHrAsString(hr), NULL); } fileIsTruncated = TRUE; } }
//
// The last modify date may be updated on a file if the named data streams
// have been modified. So check to see if the dates match. If they don't,
// if the file is trunctated, see if it is still truncated, if so, update the
// modify date in the placeholder to the file's modify date. If the file is
// premigrated and the modify dates don't match, delete the placeholder.
// Get the version ID from the file
LONGLONG scanVersionId; WsbAffirmHr(GetVersionId(&scanVersionId));
// Get the version ID from the placeholder
FSA_PLACEHOLDER scanPlaceholder; WsbAffirmHr(GetPlaceholder(offset, size, &scanPlaceholder));
if (TRUE == fileIsTruncated) {
// Check to see if the dates match
if (scanPlaceholder.fileVersionId != scanVersionId) { WsbTrace(OLESTR("CFsaScanItem::Validate - placeholer version ID = <%I64u>, file version Id = <%I64u>"), scanPlaceholder.fileVersionId, scanVersionId); //
// Update the placeholder information on the reparse point
//
LONGLONG afterPhUsn; scanPlaceholder.fileVersionId = scanVersionId; WsbAffirmHr(CreatePlaceholder(offset, size, scanPlaceholder, FALSE, 0, &afterPhUsn)); WsbLogEvent(FSA_MESSAGE_VALIDATE_RESET_PH_MODIFY_TIME, 0, NULL, WsbAbbreviatePath(m_path, 120), WsbHrAsString(hr), NULL); } } else { // The file is pre-migrated. Verify that it has not changed since we managed it and if it has then unmanage it.
if (Verify(offset, size) != S_OK) { WsbAffirmHr(Unmanage(offset, size)); WsbLogEvent(FSA_MESSAGE_VALIDATE_UNMANAGED_FILE, 0, NULL, WsbAbbreviatePath(m_path, 120), WsbHrAsString(hr), NULL); } }
// Now that all of this stuff is OK, call the engine
if (IsManaged(offset, size) == S_OK) { WsbAffirmHr(m_pResource->Validate((IFsaScanItem*) this, offset, size, usn)); }
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::Validate"), OLESTR("hr = <%ls>"), WsbHrAsString(hr)); return(hr); }
HRESULT CFsaScanItem::FindFirstInDbIndex( IN IFsaResource* pResource, IN IHsmSession* pSession )
/*++
Implements:
IFsaScanItemPriv::FindFirstInDbIndex().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::FindFirstInDbIndex"), OLESTR(""));
try { CComPtr<IFsaResourcePriv> pResourcePriv;
WsbAssert(0 != pResource, E_POINTER);
// Store off some of the scan information.
m_pResource = pResource; m_pSession = pSession;
// If Db is already present (could happen if somebody calls First() twice in a row),
// we close the Db and reopen since we cannot be sure that the resource is the same!
if (m_pUnmanageDb != NULL) { // Db must be open
(void)m_pUnmanageDb->Close(m_pDbSession); m_pDbSession = 0; m_pUnmanageRec = 0; m_pUnmanageDb = 0; }
// Get and open the Unmanage db
// (Note: if this scanning is ever extended to use another DB,
// this method should get additional parameter for which DB to scan)
WsbAffirmHr(m_pResource->QueryInterface(IID_IFsaResourcePriv, (void**) &pResourcePriv)); hr = pResourcePriv->GetUnmanageDb(IID_IFsaUnmanageDb, (void**) &m_pUnmanageDb); if (WSB_E_RESOURCE_UNAVAILABLE == hr) { // Db was not created ==> no files to scan
hr = WSB_E_NOTFOUND; } WsbAffirmHr(hr);
hr = m_pUnmanageDb->Open(&m_pDbSession); if (S_OK != hr) { m_pUnmanageDb = NULL; WsbAffirmHr(hr); }
// Get a record to traverse with and set for sequential traversing
WsbAffirmHr(m_pUnmanageDb->GetEntity(m_pDbSession, UNMANAGE_REC_TYPE, IID_IFsaUnmanageRec, (void**)&m_pUnmanageRec)); WsbAffirmHr(m_pUnmanageRec->SetSequentialScan());
// Get file information
WsbAffirmHr(GetFromDbIndex(TRUE));
} WsbCatch(hr);
WsbTraceOut(OLESTR("CFsaScanItem::FindFirstInDbIndex"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CFsaScanItem::FindNextInDbIndex( void )
/*++
Implements:
IFsaScanItemPriv::FindNextInDbIndex().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::FindNextInDbIndex"), OLESTR(""));
try { WsbAssert(m_pUnmanageDb != NULL, E_FAIL);
// Get file information
WsbAffirmHr(GetFromDbIndex(FALSE));
} WsbCatch(hr); WsbTraceOut(OLESTR("CFsaScanItem::FindNextInDbIndex"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CFsaScanItem::GetFromDbIndex( BOOL first )
/*
Implements:
CFsaScanItem::GetFromDbIndex().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanItem::GetFromDbIndex"), OLESTR(""));
try { IFsaScanItem* pScanItem; HRESULT hrFindFileId = S_OK; LONGLONG fileId; BOOL bCont;
WsbAssert(m_pUnmanageDb != NULL, E_FAIL); WsbAssert(m_pUnmanageRec != NULL, E_FAIL);
do { bCont = FALSE;
// Get first/next record
if (first) { hr = m_pUnmanageRec->First(); } else { hr = m_pUnmanageRec->Next(); } WsbAffirm(S_OK == hr, WSB_E_NOTFOUND);
// Get file id
WsbAffirmHr(m_pUnmanageRec->GetFileId(&fileId)); // Reset some items in case this isn't the first call to FindFileId
// (FindFileId actually "attach" the object to a different file)
if (INVALID_HANDLE_VALUE != m_handle) { FindClose(m_handle); m_handle = INVALID_HANDLE_VALUE; } if (TRUE == m_changedAttributes) { RestoreAttributes(); }
// Find the file from the ID
pScanItem = this; hrFindFileId = m_pResource->FindFileId(fileId, m_pSession, &pScanItem);
// If the FindFileId failed, we just skip that item and get the
// next one. This is to keep the scan from just stopping on this
// item. FindFileId could fail because the file has been deleted
// or open exclusively by somebody else
if (!SUCCEEDED(hrFindFileId)) { WsbTrace(OLESTR("CFsaScanItem::GetFromDbIndex: file id %I64d skipped since FindFileId failed with hr = <%ls>\n"), fileId, WsbHrAsString(hrFindFileId)); first = FALSE; bCont = TRUE; } } while (bCont);
WsbAffirmHr(pScanItem->Release()); // Get rid of extra ref. count (we get extra ref count only when FindFileId succeeds)
} WsbCatch(hr); WsbTraceOut(OLESTR("CFsaScanItem::GetFromDbIndex"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
|