|
|
/*++
� 1998 Seagate Software, Inc. All rights reserved.
Module Name:
fsascan.cpp
Abstract:
This class represents a scanning process that is being carried out upon one FsaResource.
Author:
Chuck Bardeen [cbardeen] 16-Feb-1997
Revision History:
--*/
#include "stdafx.h"
#include "wsb.h"
#include "fsa.h"
#include "job.h"
#include "hsmscan.h"
#define WSB_TRACE_IS WSB_TRACE_BIT_JOB
DWORD HsmStartScanner( void* pVoid )
/*++
--*/ { return(((CHsmScanner*) pVoid)->StartScan()); }
HRESULT CHsmScanner::Cancel( HSM_JOB_EVENT event )
/*++
Implements:
IHsmScanner::Cancel().
--*/ { HRESULT hr = S_OK;
try {
// If we have started, but haven't finished, then change the state of the job. The thread
// will exit on it's own.
if ((HSM_JOB_STATE_IDLE != m_state) && (HSM_JOB_STATE_DONE != m_state) && (HSM_JOB_STATE_FAILED != m_state) && (HSM_JOB_STATE_CANCELLED != m_state)) {
if (HSM_JOB_EVENT_CANCEL == event) { WsbAffirmHr(SetState(HSM_JOB_STATE_CANCELLED)); } else if (HSM_JOB_EVENT_SUSPEND == event) { WsbAffirmHr(SetState(HSM_JOB_STATE_SUSPENDED)); } else if (HSM_JOB_EVENT_FAIL == event) { WsbAffirmHr(SetState(HSM_JOB_STATE_FAILED)); } else { WsbAssert(FALSE, E_UNEXPECTED); } }
} WsbCatch(hr);
return(hr); }
HRESULT CHsmScanner::DoIfMatches( IN IFsaScanItem* pScanItem )
/*++
Implements:
IHsmScanner::DoIfMatches().
--*/ { HRESULT hr = S_OK; HRESULT hrDo = S_OK; HRESULT hrShould = S_OK; BOOL notMatched = TRUE; BOOL shouldDo = FALSE; CComPtr<IHsmRuleStack> pRuleStack;
WsbTraceIn(OLESTR("CFsaScanner::DoIfMatches"), OLESTR(""));
try {
// Each policy has it's own rule stack, check each one of until a match is found (if
// one exists).
WsbAffirmHr(m_pEnumStacks->First(IID_IHsmRuleStack, (void**) &pRuleStack)); while (notMatched) {
hr = pRuleStack->DoesMatch(pScanItem, &shouldDo);
if (S_OK == hr) { notMatched = FALSE; if (!shouldDo) { hrShould = JOB_E_FILEEXCLUDED; } } else if (S_FALSE == hr) { pRuleStack = 0; WsbAffirmHr(m_pEnumStacks->Next(IID_IHsmRuleStack, (void**) &pRuleStack)); } else { // Something totally unexpected happened so we'd better quit
WsbThrow(hr); } }
} WsbCatchAndDo(hr,
if (WSB_E_NOTFOUND == hr) { hrShould = JOB_E_DOESNTMATCH; hr = S_OK; } else { hrShould = hr; }
);
// Just Do It!!
if (SUCCEEDED(hr) && shouldDo) {
hrDo = pRuleStack->Do(pScanItem);
// Tell the session if we ended up skipping the file or not.
m_pSession->ProcessItem(HSM_JOB_PHASE_SCAN, HSM_JOB_ACTION_SCAN, pScanItem, hrDo);
} else {
// Tell the session if we decided to skip the file.
m_pSession->ProcessItem(HSM_JOB_PHASE_SCAN, HSM_JOB_ACTION_SCAN, pScanItem, hrShould); }
WsbTraceOut(OLESTR("CFsaScanner::DoIfMatches"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); } #pragma optimize("g", off)
HRESULT CHsmScanner::FinalConstruct( void )
/*++
Implements:
CComObjectRoot::FinalConstruct().
--*/ { HRESULT hr = S_OK; try {
WsbAffirmHr(CComObjectRoot::FinalConstruct());
m_state = HSM_JOB_STATE_IDLE; m_priority = HSM_JOB_PRIORITY_NORMAL; m_threadHandle = 0; m_threadId = 0; m_threadHr = S_OK; m_eventCookie = 0; m_skipHiddenItems = TRUE; m_skipSystemItems = TRUE; m_useRPIndex = FALSE; m_useDbIndex = FALSE; m_event = 0;
// Create a collection for the rule stacks, and store an enumerator to it.
WsbAffirmHr(CoCreateInstance(CLSID_CWsbOrderedCollection, NULL, CLSCTX_ALL, IID_IWsbCollection, (void**) &m_pRuleStacks)); WsbAffirmHr(m_pRuleStacks->Enum(&m_pEnumStacks));
} WsbCatch(hr);
return(hr); } #pragma optimize("", on)
void CHsmScanner::FinalRelease( void )
/*++
Implements:
CComObjectRoot::FinalRelease().
--*/ { HRESULT hr = S_OK; // Cleanup the thread we were using.
if (m_threadHandle != 0) { m_state = HSM_JOB_STATE_DONE; if (0 != m_event) { SetEvent(m_event); }
// Should we wait for the thread to end?
CloseHandle(m_threadHandle); m_threadHandle = 0; } if (m_event) { CloseHandle(m_event); m_event = 0; }
CComObjectRoot::FinalRelease(); }
HRESULT CHsmScanner::LowerPriority( void )
/*++
--*/ { HRESULT hr = S_OK;
try {
WsbAssert(0 != m_threadHandle, E_UNEXPECTED); WsbAssert(m_pSession != 0, E_UNEXPECTED);
switch(m_priority) { case HSM_JOB_PRIORITY_IDLE: WsbAffirm(FALSE, E_UNEXPECTED); break;
case HSM_JOB_PRIORITY_LOWEST: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_IDLE)); m_priority = HSM_JOB_PRIORITY_IDLE; break;
case HSM_JOB_PRIORITY_LOW: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_LOWEST)); m_priority = HSM_JOB_PRIORITY_LOWEST; break;
case HSM_JOB_PRIORITY_NORMAL: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_BELOW_NORMAL)); m_priority = HSM_JOB_PRIORITY_LOW; break;
case HSM_JOB_PRIORITY_HIGH: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_NORMAL)); m_priority = HSM_JOB_PRIORITY_NORMAL; break;
case HSM_JOB_PRIORITY_HIGHEST: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_ABOVE_NORMAL)); m_priority = HSM_JOB_PRIORITY_HIGH; break;
default: case HSM_JOB_PRIORITY_CRITICAL: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_HIGHEST)); m_priority = HSM_JOB_PRIORITY_HIGHEST; break; }
WsbAffirmHr(m_pSession->ProcessPriority(HSM_JOB_PHASE_SCAN, m_priority));
} WsbCatch(hr);
return(hr); }
HRESULT CHsmScanner::Pause( void )
/*++
Implements:
IHsmScanner::Pause().
--*/ { HRESULT hr = S_OK;
WsbTraceIn(OLESTR("CFsaScanner::Pause"), OLESTR(""));
// Lock();
try {
// If we are running, then suspend the thread.
WsbAssert((HSM_JOB_STATE_STARTING == m_state) || (HSM_JOB_STATE_ACTIVE == m_state) || (HSM_JOB_STATE_RESUMING == m_state), E_UNEXPECTED);
// Set state to pausing -- the thread will pause itself when it
// sees the state
WsbAffirmHr(SetState(HSM_JOB_STATE_PAUSING));
} WsbCatch(hr); // Unlock();
WsbTraceOut(OLESTR("CFsaScanner::Pause"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CHsmScanner::PopRules( IN OLECHAR* path )
/*++
--*/ { HRESULT hr = S_OK; CComPtr<IHsmRuleStack> pRuleStack;
try {
// Each policy has it's own rule stack, and each of them will need to have rules removed
// from it for this directory (if any rules were added).
for (hr = m_pEnumStacks->First(IID_IHsmRuleStack, (void**) &pRuleStack); SUCCEEDED(hr); hr = m_pEnumStacks->Next(IID_IHsmRuleStack, (void**) &pRuleStack)) {
WsbAffirmHr(pRuleStack->Pop(path)); pRuleStack = 0; }
if (WSB_E_NOTFOUND == hr) { hr = S_OK; }
} WsbCatch(hr); return(hr); }
HRESULT CHsmScanner::ProcessSessionEvent( IN IHsmSession* pSession, IN HSM_JOB_PHASE phase, IN HSM_JOB_EVENT event )
/*++
--*/ { HRESULT hr = S_OK;
try { WsbAssert(0 != pSession, E_POINTER);
// If the phase applies to use (SCAN or ALL), then do any work required by the
// event.
if ((HSM_JOB_PHASE_ALL == phase) || (HSM_JOB_PHASE_SCAN == phase)) {
switch(event) {
case HSM_JOB_EVENT_SUSPEND: case HSM_JOB_EVENT_CANCEL: case HSM_JOB_EVENT_FAIL: WsbAffirmHr(Cancel(event)); break;
case HSM_JOB_EVENT_PAUSE: WsbAffirmHr(Pause()); break;
case HSM_JOB_EVENT_RESUME: WsbAffirmHr(Resume()); break;
case HSM_JOB_EVENT_RAISE_PRIORITY: WsbAffirmHr(RaisePriority()); break;
case HSM_JOB_EVENT_LOWER_PRIORITY: WsbAffirmHr(LowerPriority()); break;
default: case HSM_JOB_EVENT_START: WsbAssert(FALSE, E_UNEXPECTED); break; } }
} WsbCatch(hr);
return(S_OK); }
HRESULT CHsmScanner::PushRules( IN OLECHAR* path )
/*++
--*/ { HRESULT hr = S_OK; CComPtr<IHsmRuleStack> pRuleStack;
try {
// Save an indicator to where we are in the scan, so we can use it if we are interrupted
// or need to give an indication to the session.
m_currentPath = path;
// Each policy has it's own rule stack, and each of them will need to have rules added
// for this directory (if any rules exist).
for (hr = m_pEnumStacks->First(IID_IHsmRuleStack, (void**) &pRuleStack); SUCCEEDED(hr); hr = m_pEnumStacks->Next(IID_IHsmRuleStack, (void**) &pRuleStack)) {
WsbAffirmHr(pRuleStack->Push(path)); pRuleStack = 0; }
if (WSB_E_NOTFOUND == hr) { hr = S_OK; } } WsbCatch(hr);
return(hr); }
HRESULT CHsmScanner::RaisePriority( void )
/*++
--*/ { HRESULT hr = S_OK;
try {
WsbAssert(0 != m_threadHandle, E_UNEXPECTED); WsbAssert(m_pSession != 0, E_UNEXPECTED);
switch(m_priority) {
case HSM_JOB_PRIORITY_IDLE: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_LOWEST)); m_priority = HSM_JOB_PRIORITY_LOWEST; break;
case HSM_JOB_PRIORITY_LOWEST: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_BELOW_NORMAL)); m_priority = HSM_JOB_PRIORITY_LOW; break;
case HSM_JOB_PRIORITY_LOW: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_NORMAL)); m_priority = HSM_JOB_PRIORITY_NORMAL; break;
case HSM_JOB_PRIORITY_NORMAL: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_ABOVE_NORMAL)); m_priority = HSM_JOB_PRIORITY_HIGH; break;
case HSM_JOB_PRIORITY_HIGH: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_HIGHEST)); m_priority = HSM_JOB_PRIORITY_HIGHEST; break;
case HSM_JOB_PRIORITY_HIGHEST: WsbAffirmStatus(SetThreadPriority(m_threadHandle, THREAD_PRIORITY_TIME_CRITICAL)); m_priority = HSM_JOB_PRIORITY_CRITICAL; break;
default: case HSM_JOB_PRIORITY_CRITICAL: WsbAffirm(FALSE, E_UNEXPECTED); break; }
WsbAffirmHr(m_pSession->ProcessPriority(HSM_JOB_PHASE_SCAN, m_priority));
} WsbCatch(hr);
return(hr); }
HRESULT CHsmScanner::Resume( void )
/*++
Implements:
IHsmScanner::Resume().
--*/ { HRESULT hr = S_OK; HSM_JOB_STATE oldState;
WsbTraceIn(OLESTR("CFsaScanner::Resume"), OLESTR(""));
// Lock();
try {
// If we are paused, then suspend the thread.
WsbAffirm((HSM_JOB_STATE_PAUSING == m_state) || (HSM_JOB_STATE_PAUSED == m_state), E_UNEXPECTED);
oldState = m_state; WsbAffirmHr(SetState(HSM_JOB_STATE_RESUMING));
// If we are unable to resume, then return to the former state.
try { WsbAffirm(SetEvent(m_event), HRESULT_FROM_WIN32(GetLastError())); } WsbCatchAndDo(hr, SetState(oldState););
} WsbCatch(hr); // Unlock();
WsbTraceOut(OLESTR("CFsaScanner::Resume"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CHsmScanner::ScanPath( IN OLECHAR* dirPath )
/*++
--*/ { HRESULT hr = S_OK; CComPtr<IFsaScanItem> pScanItem; CWsbStringPtr searchPath;
WsbTraceIn(OLESTR("CFsaScanner::ScanPath"), OLESTR("%ls"), WsbAbbreviatePath(dirPath, WSB_TRACE_BUFF_SIZE));
try {
WsbAssert(0 != dirPath, E_POINTER); WsbAssert(0 != dirPath[0], E_INVALIDARG);
// Pop the rules for this files. This sets the context for the scan to follow.
WsbAffirmHr(PushRules(dirPath));
try {
// Iterate over all the files and directories in the specified path.
searchPath = dirPath; if (searchPath[(int) (wcslen(searchPath) - 1)] == L'\\') { WsbAffirmHr(searchPath.Append("*")); } else { WsbAffirmHr(searchPath.Append("\\*")); }
if (m_useDbIndex) { hr = m_pResource->FindFirstInDbIndex(m_pSession, &pScanItem); } else if (m_useRPIndex) { hr = m_pResource->FindFirstInRPIndex(m_pSession, &pScanItem); } else { hr = m_pResource->FindFirst(searchPath, m_pSession, &pScanItem); } while (SUCCEEDED(hr) && ((HSM_JOB_STATE_ACTIVE == m_state) || (HSM_JOB_STATE_RESUMING == m_state) || (HSM_JOB_STATE_PAUSING == m_state))) { // Check for a pause request
// Lock();
if (HSM_JOB_STATE_PAUSING == m_state) { hr = SetState(HSM_JOB_STATE_PAUSED); // Unlock();
WsbAffirmHr(hr);
// Suspend the thread here & wait for resume signal
WsbTrace(OLESTR("CHsmScanner::ScanPath: pausing\n")); WaitForSingleObject(m_event, 0xffffffff); WsbTrace(OLESTR("CHsmScanner::ScanPath: woke up, state = %d\n"), (int)m_state);
// Lock();
if (HSM_JOB_STATE_RESUMING != m_state) { // Unlock();
break; } hr = SetState(HSM_JOB_STATE_ACTIVE); if (S_OK != hr) { // Unlock();
WsbThrow(hr); } } // Unlock();
// Skip hidden and/or system items if so configured.
if (!((m_skipHiddenItems && (pScanItem->IsHidden() == S_OK)) || (m_skipSystemItems && (pScanItem->IsSystem() == S_OK)))) {
// Ignore ".", "..", symbolic links and mount points.
if ((pScanItem->IsARelativeParent() == S_FALSE) && (pScanItem->IsALink() == S_FALSE)) {
// Recursively scan subdirectories.
if (pScanItem->IsAParent() == S_OK) { WsbAffirmHr(pScanItem->GetPathAndName(OLESTR(""), &searchPath, 0)); WsbAffirmHr(ScanPath(searchPath)); }
// If this file matches a policy then perform the action.
else { WsbAffirmHr(DoIfMatches(pScanItem)); } } else { WsbTrace(OLESTR("CHsmScanner::ScanPath skipping - symbolic link, '.', or '..'\n")); } } else { WsbTrace(OLESTR("CHsmScanner::ScanPath skipping - hidden/system\n")); } if (m_useDbIndex) { hr = m_pResource->FindNextInDbIndex(pScanItem); } else if (m_useRPIndex) { hr = m_pResource->FindNextInRPIndex(pScanItem); } else { hr = m_pResource->FindNext(pScanItem); } }
// If we broke out as a result of end of scan or some other error ...
if (hr != S_OK) { WsbAssert(hr == WSB_E_NOTFOUND, hr); hr = S_OK; }
} WsbCatch(hr);
// Pop the rules for this directory. This restores the context as we pop back up the directory
// structure.
WsbAffirmHr(PopRules(dirPath));
} WsbCatchAndDo(hr, if (JOB_E_DIREXCLUDED == hr) {hr = S_OK;});
WsbTraceOut(OLESTR("CFsaScanner::ScanPath"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CHsmScanner::SetState( IN HSM_JOB_STATE state )
/*++
--*/ { HRESULT hr = S_OK; BOOL bLog = TRUE;
WsbTraceIn(OLESTR("CFsaScanner::SetState"), OLESTR("old state = %d, new state = %d"), (int)m_state, (int)state);
// Lock();
try {
// Change the state and report the change to the session.
m_state = state; WsbAffirmHr(m_pSession->ProcessState(HSM_JOB_PHASE_SCAN, m_state, m_currentPath, bLog));
} WsbCatch(hr); // Unlock();
WsbTraceOut(OLESTR("CFsaScanner::SetState"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
HRESULT CHsmScanner::Start( IN IHsmSession* pSession, IN OLECHAR* path )
/*++
Implements:
IHsmScanner::Start().
--*/ { HRESULT hr = S_OK; CComPtr<IHsmJobDef> pDef; CComPtr<IHsmPolicy> pPolicy; CComPtr<IHsmRuleStack> pRuleStack; CComPtr<IWsbEnum> pEnumPolicies; CComPtr<IConnectionPointContainer> pCPC; CComPtr<IConnectionPoint> pCP; CComPtr<IHsmSessionSinkEveryEvent> pSink; DWORD cookie;
try {
// Make sure that we were given a session, and that we haven't started already.
WsbAssert(0 != pSession, E_POINTER); WsbAssert(HSM_JOB_STATE_IDLE == m_state, E_UNEXPECTED);
// Store off the session.
m_pSession = pSession;
// If no directory was specified, then start in the root of the resource.
if ((0 != path) && (0 != *path)) { m_startingPath = path; } else { m_startingPath = OLESTR("\\"); }
m_currentPath = m_startingPath;
// Tell them we are starting.
WsbAffirmHr(SetState(HSM_JOB_STATE_STARTING));
// Create an event to control pause/resume for the scan.
if (0 == m_event) { CWsbStringPtr nameString; GUID id; WsbAffirmHr(m_pSession->GetIdentifier(&id)); nameString = id; nameString.Prepend(OLESTR("Scanner Pause and Resume Event for session ")); m_event = CreateEvent(NULL, FALSE, FALSE, nameString); } // Ask the session to advise of every event.
WsbAffirmHr(pSession->QueryInterface(IID_IConnectionPointContainer, (void**) &pCPC)); WsbAffirmHr(pCPC->FindConnectionPoint(IID_IHsmSessionSinkEveryEvent, &pCP)); WsbAffirmHr(((IUnknown*) (IHsmScanner*) this)->QueryInterface(IID_IHsmSessionSinkEveryEvent, (void**) &pSink)); WsbAffirmHr(pCP->Advise(pSink, &cookie));
// Store off the information needed to latter unadvise.
m_eventCookie = cookie;
try { // Locate the resource that is being scanned.
WsbAffirmHr(m_pSession->GetResource(&m_pResource));
// Create and initialize a rule stack for each policy.
WsbAffirmHr(pSession->GetJob(&m_pJob)); WsbAffirmHr(m_pJob->GetDef(&pDef)); WsbAffirmHr(pDef->EnumPolicies(&pEnumPolicies));
for (hr = pEnumPolicies->First(IID_IHsmPolicy, (void**) &pPolicy); SUCCEEDED(hr); hr = pEnumPolicies->Next(IID_IHsmPolicy, (void**) &pPolicy)) {
WsbAffirmHr(CoCreateInstance(CLSID_CHsmRuleStack, NULL, CLSCTX_ALL, IID_IHsmRuleStack, (void**) &pRuleStack)); WsbAffirmHr(pRuleStack->Init(pPolicy, m_pResource)); WsbAffirmHr(m_pRuleStacks->Add(pRuleStack));
pRuleStack = 0; pPolicy = 0; }
if (WSB_E_NOTFOUND == hr) { hr = S_OK; }
// Determine whether hidden and system items should be skipped?
if (pDef->SkipHiddenItems() == S_FALSE) { m_skipHiddenItems = FALSE; }
if (pDef->SkipSystemItems() == S_FALSE) { m_skipSystemItems = FALSE; }
// Determine whether to use the Reparse Point Index for the scan?
if (pDef->UseRPIndex() == S_OK) { m_useRPIndex = TRUE; } // Determine whether to use the Database Index for the scan?
if (pDef->UseDbIndex() == S_OK) { m_useDbIndex = TRUE; }
try { // Now that we have prepared, create the thread that will do the scanning!
WsbAffirm((m_threadHandle = CreateThread(0, 0, HsmStartScanner, (void*) this, 0, &m_threadId)) != 0, HRESULT_FROM_WIN32(GetLastError()));
} WsbCatchAndDo(hr, SetState(HSM_JOB_STATE_FAILED););
if (FAILED(hr)) { WsbThrow(hr); }
} WsbCatchAndDo(hr, pCP->Unadvise(m_eventCookie); m_eventCookie = 0; );
} WsbCatch(hr);
return(hr); }
HRESULT CHsmScanner::StartScan( void )
/*++
--*/ { HRESULT hr = S_OK; HRESULT hr2 = S_OK; CComPtr<IConnectionPointContainer> pCPC; CComPtr<IConnectionPoint> pCP;
WsbTraceIn(OLESTR("CFsaScanner::StartScan"), OLESTR(""));
try { CComPtr<IFsaTruncator> pTruncator; CComPtr<IHsmSession> pTruncatorSession;
CComPtr<IHsmJobDef> pDef; CComPtr<IHsmActionOnResourcePreScan> pActionPreScan;
// The thread is running.
WsbAffirmHr(SetState(HSM_JOB_STATE_ACTIVE));
// To avoid having the RP Index order changed by the truncator,
// we pause the truncator
if (m_useRPIndex) { WsbAffirmHr(m_pResource->GetTruncator(&pTruncator)); if (pTruncator) { WsbAffirmHr(pTruncator->GetSession(&pTruncatorSession)); if (pTruncatorSession) { WsbAffirmHr(pTruncatorSession->ProcessEvent(HSM_JOB_PHASE_ALL, HSM_JOB_EVENT_PAUSE)); } } }
// Get the pre-scan action and do it (if exists)
WsbAffirmHr(m_pJob->GetDef(&pDef)); WsbAffirmHr(pDef->GetPreScanActionOnResource(&pActionPreScan)); if (pActionPreScan) { WsbTrace(OLESTR("CHsmScanner::StartScan: doing pre-scan action\n"));
//Don't throw hr - we need the cleanup code that is done after the scanning
hr = pActionPreScan->Do(m_pResource, m_pSession); }
// Start with the first path and scan the resource (only if pre-scan succeeded)
if (SUCCEEDED(hr)) { m_threadHr = ScanPath(m_startingPath); }
// Resume the truncator if we paused it
if (pTruncatorSession) { pTruncatorSession->ProcessEvent(HSM_JOB_PHASE_ALL, HSM_JOB_EVENT_RESUME); }
// Clear out the information about the thread;
WsbAffirmStatus(CloseHandle(m_threadHandle)); m_threadId = 0; m_threadHandle = 0;
} WsbCatch(hr);
// The thread is exiting, so record
if (FAILED(hr) || FAILED(m_threadHr)) { hr2 = SetState(HSM_JOB_STATE_FAILED); if (FAILED(hr2)) { m_pSession->ProcessHr(HSM_JOB_PHASE_ALL, __FILE__, __LINE__, hr2); } } else { hr2 = SetState(HSM_JOB_STATE_DONE); if (FAILED(hr2)) { m_pSession->ProcessHr(HSM_JOB_PHASE_ALL, __FILE__, __LINE__, hr2); } }
// Regardless of how this thread is exiting, we need to unadvise from the session.
// Indicate that we no longer want to be advised of events.
if ((m_pSession != 0) && (m_eventCookie != 0)) { try { WsbAffirmHr(m_pSession->QueryInterface(IID_IConnectionPointContainer, (void**) &pCPC)); WsbAffirmHr(pCPC->FindConnectionPoint(IID_IHsmSessionSinkEveryEvent, &pCP)); pCP->Unadvise(m_eventCookie); } WsbCatch(hr); }
WsbTraceOut(OLESTR("CFsaScanner::StartScan"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
return(hr); }
|