956 lines
27 KiB
C++
956 lines
27 KiB
C++
|
// FrcOwn.cpp : Implementation of CForceOwnership
|
||
|
|
||
|
#include "pch.cxx"
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#define TRKDATA_ALLOCATE
|
||
|
#include <trklib.hxx>
|
||
|
#include <trksvr.hxx>
|
||
|
#undef TRKDATA_ALLOCATE
|
||
|
|
||
|
#include "stdafx.h"
|
||
|
#include "ITrkAdmn.h"
|
||
|
#include "FrcOwn.h"
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CTrkForceOwnership::Volumes(BSTR bstrUncPath, long scope )
|
||
|
{
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
HANDLE hFile = NULL;
|
||
|
CVolumeId volid;
|
||
|
|
||
|
CMachineId mcid( (LPWSTR) bstrUncPath );
|
||
|
CRpcClientBinding rc;
|
||
|
|
||
|
CPCVolumes cpcVolumes( &mcid, &_voltab, &_refreshSequenceStorage );
|
||
|
TRpcPipeControl< TRK_VOLUME_TRACKING_INFORMATION_PIPE,
|
||
|
TRK_VOLUME_TRACKING_INFORMATION,
|
||
|
CPCVolumes
|
||
|
> cpipeVolumes( &cpcVolumes );
|
||
|
|
||
|
rc.Initialize( mcid );
|
||
|
|
||
|
if( TRKINFOSCOPE_VOLUME == scope )
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
IO_STATUS_BLOCK Iosb;
|
||
|
FILE_FS_OBJECTID_INFORMATION fsobOID;
|
||
|
|
||
|
status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
|
||
|
FILE_OPEN_NO_RECALL, NULL, &hFile );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
hFile = NULL;
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
|
||
|
FileFsObjectIdInformation );
|
||
|
|
||
|
if( STATUS_OBJECT_NAME_NOT_FOUND == status )
|
||
|
{
|
||
|
TRK_VOLUME_TRACKING_INFORMATION volinfo;
|
||
|
|
||
|
volinfo.volindex = -1;
|
||
|
cpcVolumes.Push( &volinfo, 1 );
|
||
|
hr = S_OK;
|
||
|
goto Exit;
|
||
|
}
|
||
|
else if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
|
||
|
volid.Load( &volid, fsobOID );
|
||
|
|
||
|
NtClose( hFile );
|
||
|
hFile = NULL;
|
||
|
}
|
||
|
else if( TRKINFOSCOPE_MACHINE != scope )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::VolumeStatus (%l)"), scope ));
|
||
|
TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
|
||
|
}
|
||
|
|
||
|
|
||
|
RpcTryExcept
|
||
|
{
|
||
|
hr = GetVolumeTrackingInformation( rc, volid, static_cast<TrkInfoScope>(scope), cpipeVolumes );
|
||
|
if( SUCCEEDED(hr) && SUCCEEDED(cpcVolumes.GetHResult()) )
|
||
|
hr = TriggerVolumeClaims( rc, cpcVolumes.Count(), cpcVolumes.GetVolIds() );
|
||
|
}
|
||
|
RpcExcept( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = RpcExceptionCode();
|
||
|
}
|
||
|
RpcEndExcept;
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( NULL != hFile )
|
||
|
NtClose( hFile );
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CTrkForceOwnership::Files(BSTR bstrUncPath, long scope)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
HANDLE hFile = NULL;
|
||
|
|
||
|
CPCFiles cpcFiles( &_idt );
|
||
|
TRpcPipeControl< TRK_FILE_TRACKING_INFORMATION_PIPE,
|
||
|
TRK_FILE_TRACKING_INFORMATION,
|
||
|
CPCFiles
|
||
|
> cpipeFiles( &cpcFiles);
|
||
|
|
||
|
CMachineId mcid( (LPWSTR) bstrUncPath );
|
||
|
CRpcClientBinding rc;
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
CDomainRelativeObjId droidCurrent, droidBirth;
|
||
|
|
||
|
if( TRKINFOSCOPE_ONE_FILE == scope )
|
||
|
{
|
||
|
|
||
|
// BUGBUG P2: Optimize this; we don't need droidBirth
|
||
|
status = GetDroids( bstrUncPath, &droidCurrent, &droidBirth, RGO_READ_OBJECTID );
|
||
|
|
||
|
if( STATUS_OBJECT_NAME_NOT_FOUND == status )
|
||
|
{
|
||
|
TRK_FILE_TRACKING_INFORMATION fileinfo;
|
||
|
|
||
|
_tcscpy( fileinfo.tszFilePath, TEXT("") );
|
||
|
fileinfo.hr = HRESULT_FROM_NT( status );
|
||
|
|
||
|
cpcFiles.Push( &fileinfo, 1 );
|
||
|
hr = S_OK;
|
||
|
goto Exit;
|
||
|
}
|
||
|
else if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed GetDroids (%s)"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
}
|
||
|
else if( TRKINFOSCOPE_VOLUME == scope )
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
IO_STATUS_BLOCK Iosb;
|
||
|
FILE_FS_OBJECTID_INFORMATION fsobOID;
|
||
|
CVolumeId volid;
|
||
|
|
||
|
status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
|
||
|
FILE_OPEN_NO_RECALL, NULL, &hFile );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
hFile = NULL;
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
|
||
|
FileFsObjectIdInformation );
|
||
|
|
||
|
if( STATUS_OBJECT_NAME_NOT_FOUND == status )
|
||
|
{
|
||
|
TRK_FILE_TRACKING_INFORMATION fileinfo;
|
||
|
|
||
|
_tcscpy( fileinfo.tszFilePath, TEXT("") );
|
||
|
fileinfo.hr = HRESULT_FROM_NT( status );
|
||
|
|
||
|
cpcFiles.Push( &fileinfo, 1 );
|
||
|
hr = S_OK;
|
||
|
goto Exit;
|
||
|
}
|
||
|
else if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
volid.Load( &volid, fsobOID );
|
||
|
droidCurrent = CDomainRelativeObjId( volid, CObjId() );
|
||
|
|
||
|
NtClose( hFile );
|
||
|
hFile = NULL;
|
||
|
}
|
||
|
else if( TRKINFOSCOPE_MACHINE != scope )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::FileStatus (%d)"), scope ));
|
||
|
TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
|
||
|
}
|
||
|
|
||
|
rc.Initialize( mcid );
|
||
|
|
||
|
RpcTryExcept
|
||
|
{
|
||
|
hr = GetFileTrackingInformation( rc, droidCurrent, static_cast<TrkInfoScope>(scope), cpipeFiles );
|
||
|
}
|
||
|
RpcExcept( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( RpcExceptionCode() );
|
||
|
}
|
||
|
RpcEndExcept;
|
||
|
if( FAILED(hr) ) goto Exit;
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( NULL != hFile )
|
||
|
NtClose( hFile );
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
STDMETHODIMP
|
||
|
CTrkForceOwnership::VolumeStatus(BSTR bstrUncPath, long scope,
|
||
|
VARIANT *pvarlongVolIndex, VARIANT *pvarbstrVolId, VARIANT *pvarlongStatus)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
HANDLE hFile = NULL;
|
||
|
SAFEARRAYBOUND sabound;
|
||
|
CVolumeId volid;
|
||
|
|
||
|
// Determine the machine ID
|
||
|
CMachineId mcid( (LPWSTR) bstrUncPath );
|
||
|
CRpcClientBinding rc;
|
||
|
|
||
|
// This is used by the RPC server to pull the bstrUncPath
|
||
|
CPCPath cpcPath( bstrUncPath );
|
||
|
TRpcPipeControl< TCHAR_PIPE, TCHAR, CPCPath> cpipePath( &cpcPath );
|
||
|
|
||
|
// This is used by the RPC server to push the volume information
|
||
|
CPCVolumeStatus cpcVolumeStatus( &_voltab );
|
||
|
TRpcPipeControl< TRK_VOLUME_TRACKING_INFORMATION_PIPE, TRK_VOLUME_TRACKING_INFORMATION, CPCVolumeStatus
|
||
|
> cpipeVolumeStatus( &cpcVolumeStatus );
|
||
|
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
|
||
|
// Initialize the outputs
|
||
|
VariantInit( pvarlongVolIndex );
|
||
|
VariantInit( pvarbstrVolId );
|
||
|
VariantInit( pvarlongStatus );
|
||
|
|
||
|
// Initialize the pipe callback
|
||
|
cpcVolumeStatus.Initialize( &mcid, pvarlongVolIndex, pvarbstrVolId, pvarlongStatus );
|
||
|
|
||
|
// Connect to the workstation in question
|
||
|
rc.Initialize( mcid );
|
||
|
|
||
|
if( TRKINFOSCOPE_VOLUME == scope )
|
||
|
{
|
||
|
IO_STATUS_BLOCK Iosb;
|
||
|
FILE_FS_OBJECTID_INFORMATION fsobOID;
|
||
|
|
||
|
status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
|
||
|
FILE_OPEN_NO_RECALL, NULL, &hFile );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
hFile = NULL;
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
|
||
|
FileFsObjectIdInformation );
|
||
|
|
||
|
if( STATUS_OBJECT_NAME_NOT_FOUND == status )
|
||
|
{
|
||
|
TRK_VOLUME_TRACKING_INFORMATION volinfo;
|
||
|
|
||
|
volinfo.volindex = -1;
|
||
|
cpcVolumeStatus.Push( &volinfo, 1 );
|
||
|
hr = S_OK;
|
||
|
goto Exit;
|
||
|
}
|
||
|
else if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
volid.Load( &volid, fsobOID );
|
||
|
|
||
|
NtClose( hFile );
|
||
|
hFile = NULL;
|
||
|
}
|
||
|
else if( TRKINFOSCOPE_MACHINE != scope )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::VolumeStatus (%l)"), scope ));
|
||
|
TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
|
||
|
}
|
||
|
|
||
|
|
||
|
RpcTryExcept
|
||
|
{
|
||
|
hr = GetVolumeTrackingInformation( rc, volid, static_cast<TrkInfoScope>(scope), cpipeVolumeStatus );
|
||
|
}
|
||
|
RpcExcept( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( RpcExceptionCode() );
|
||
|
}
|
||
|
RpcEndExcept;
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed call to GetVolumeTrackInformation")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
if( FAILED(cpcVolumeStatus.GetHResult()) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed in VolumeStatus pipe callback")));
|
||
|
TrkRaiseException( cpcVolumeStatus.GetHResult() );
|
||
|
}
|
||
|
|
||
|
// Truncate the safearrays
|
||
|
cpcVolumeStatus.Compact();
|
||
|
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
cpcVolumeStatus.UnInitialize();
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
VariantClear( pvarlongVolIndex );
|
||
|
VariantClear( pvarbstrVolId );
|
||
|
VariantClear( pvarlongStatus );
|
||
|
}
|
||
|
|
||
|
if( NULL != hFile )
|
||
|
NtClose( hFile );
|
||
|
|
||
|
return( hr );
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPCVolumeStatus::Initialize( CMachineId *pmcid, VARIANT *pvarlongVolIndex, VARIANT *pvarbstrVolId, VARIANT *pvarlongStatus )
|
||
|
{
|
||
|
_pmcid = pmcid;
|
||
|
_pvarlongVolIndex = pvarlongVolIndex;
|
||
|
_pvarbstrVolId = pvarbstrVolId;
|
||
|
_pvarlongStatus = pvarlongStatus;
|
||
|
|
||
|
_iArrays = 0;
|
||
|
_hr = S_OK;
|
||
|
_sabound.lLbound = 0;
|
||
|
_sabound.cElements = NUM_VOLUMES;
|
||
|
|
||
|
_fInitialized = TRUE;
|
||
|
|
||
|
_pvarlongVolIndex->parray = SafeArrayCreate( VT_I4, 1, &_sabound );
|
||
|
if( NULL == _pvarlongVolIndex->parray )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
_pvarlongVolIndex->vt = VT_I4 | VT_ARRAY;
|
||
|
|
||
|
_pvarbstrVolId->parray = SafeArrayCreate( VT_BSTR, 1, &_sabound );
|
||
|
if( NULL == _pvarbstrVolId->parray )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
_pvarbstrVolId->vt = VT_BSTR | VT_ARRAY;
|
||
|
|
||
|
_pvarlongStatus->parray = SafeArrayCreate( VT_I4, 1, &_sabound );
|
||
|
if( NULL == _pvarlongStatus->parray )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
_pvarlongStatus->vt = VT_I4 | VT_ARRAY;
|
||
|
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPCVolumeStatus::UnInitialize()
|
||
|
{
|
||
|
// Nothing to do, the Variants are cleaned by the caller
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPCVolumeStatus::Push( TRK_VOLUME_TRACKING_INFORMATION *pVolInfo, unsigned long cElems )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ADMIN, TEXT("CPCVolumeStatus received %d elements"), cElems ));
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
HRESULT hrGet;
|
||
|
ULONG iElem = 0;
|
||
|
BSTR bstrVolId = NULL;
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
for( iElem = 0; iElem < cElems; iElem++ )
|
||
|
{
|
||
|
CMachineId mcidCheck;
|
||
|
CVolumeSecret volsecCheck;
|
||
|
SequenceNumber seqCheck;
|
||
|
CVolumeId volNULL;
|
||
|
|
||
|
TCHAR tszVolId[ 40 ];
|
||
|
TCHAR *ptszVolId = tszVolId;
|
||
|
|
||
|
long VolOwnership = OBJOWN_UNKNOWN;
|
||
|
|
||
|
if( pVolInfo[iElem].volume != volNULL )
|
||
|
hrGet = _pvoltab->GetVolumeInfo( pVolInfo[iElem].volume, &mcidCheck, &volsecCheck, &seqCheck );
|
||
|
|
||
|
if( _iArrays >= static_cast<LONG>(_sabound.cElements) )
|
||
|
{
|
||
|
TrkAssert( !TEXT("Not yet implemented") );
|
||
|
// BUGBUG: do a SafeArrayReDim
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
TrkAssert( sizeof(long) == sizeof(pVolInfo[iElem].volindex) );
|
||
|
hr = SafeArrayPutElement( _pvarlongVolIndex->parray, &_iArrays, &pVolInfo[iElem].volindex );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
// BUGBUG: Add a Serialize(BSTR) method to CVolumeId
|
||
|
pVolInfo[iElem].volume.Stringize( ptszVolId );
|
||
|
|
||
|
bstrVolId = SysAllocString( tszVolId );
|
||
|
if( NULL == bstrVolId )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SysAllocString")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayPutElement( _pvarbstrVolId->parray, &_iArrays, bstrVolId );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
if( S_OK != hrGet )
|
||
|
{
|
||
|
VolOwnership = OBJOWN_DOESNT_EXIST;
|
||
|
}
|
||
|
else if( mcidCheck == *_pmcid )
|
||
|
{
|
||
|
VolOwnership = OBJOWN_OWNED;
|
||
|
}
|
||
|
else if( volNULL == pVolInfo[iElem].volume )
|
||
|
{
|
||
|
VolOwnership = OBJOWN_NO_ID;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
VolOwnership = OBJOWN_NOT_OWNED;
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayPutElement( _pvarlongStatus->parray, &_iArrays, &VolOwnership );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElemnt")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
SysFreeString( bstrVolId ); bstrVolId = NULL;
|
||
|
_iArrays++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
if( NULL != bstrVolId )
|
||
|
SysFreeString( bstrVolId );
|
||
|
|
||
|
if( !FAILED(_hr) )
|
||
|
_hr = hr;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPCVolumeStatus::Compact()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
_sabound.cElements = _iArrays;
|
||
|
|
||
|
hr = SafeArrayRedim( _pvarlongVolIndex->parray, &_sabound );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayRedim( _pvarbstrVolId->parray, &_sabound );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayRedim( _pvarlongStatus->parray, &_sabound );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPCVolumes::Push( TRK_VOLUME_TRACKING_INFORMATION *pVolInfo, unsigned long cElems )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ADMIN, TEXT("CPCVolumeStatus received %d elements"), cElems ));
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
ULONG iElem = 0;
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
for( iElem = 0; iElem < cElems; iElem++ )
|
||
|
{
|
||
|
|
||
|
hr = _pvoltab->SetMachine( pVolInfo[iElem].volume, *_pmcid );
|
||
|
if( TRK_S_VOLUME_NOT_FOUND == hr )
|
||
|
_pvoltab->CreateVolume(
|
||
|
pVolInfo[iElem].volume,
|
||
|
*_pmcid,
|
||
|
CVolumeSecret(),
|
||
|
_pRefreshSequenceStorage->GetSequenceNumber() );
|
||
|
|
||
|
// BUGBUG P1: Handle this error
|
||
|
TrkAssert( SUCCEEDED(hr) );
|
||
|
|
||
|
_rgvolid[ _cVolIds++ ] = pVolInfo[iElem].volume;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
if( !FAILED(_hr) )
|
||
|
_hr = hr;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
void
|
||
|
CPCFiles::Push( TRK_FILE_TRACKING_INFORMATION *pFileInfo, unsigned long cElems )
|
||
|
{
|
||
|
ULONG iFile;
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
// BUGBUG P2: Instead of a loop, batch these up
|
||
|
for( iFile = 0; iFile < cElems; iFile++ )
|
||
|
{
|
||
|
_pidt->Delete( pFileInfo[iFile].droidBirth );
|
||
|
|
||
|
TrkVerify( _pidt->Add( pFileInfo[iFile].droidBirth, pFileInfo[iFile].droidLast,
|
||
|
pFileInfo[iFile].droidBirth ));
|
||
|
}
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ERROR, TEXT("CPCFiles::Push had an exception (%08x)"), GetExceptionCode() ));
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void
|
||
|
CPCFileStatus::Push( TRK_FILE_TRACKING_INFORMATION *pFileInfo, unsigned long cElems )
|
||
|
{
|
||
|
TrkLog(( TRKDBG_ADMIN, TEXT("CPCFileStatus received %d elements"), cElems ));
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
ULONG iElem = 0;
|
||
|
BSTR bstr = NULL;
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
for( iElem = 0; iElem < cElems; iElem++ )
|
||
|
{
|
||
|
BOOL fExistsInTable = FALSE;
|
||
|
BOOL fAtBirthplace = FALSE;
|
||
|
|
||
|
CDomainRelativeObjId droidBirthCheck;
|
||
|
CDomainRelativeObjId droidNowCheck;
|
||
|
const CDomainRelativeObjId droidNULL;
|
||
|
TCHAR tszDroid[ MAX_PATH ];
|
||
|
long FileOwnership;
|
||
|
|
||
|
if( droidNULL == pFileInfo[iElem].droidBirth
|
||
|
||
|
||
|
pFileInfo[iElem].droidBirth == pFileInfo[iElem].droidLast )
|
||
|
{
|
||
|
fAtBirthplace = TRUE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
fExistsInTable = _pidt->Query( pFileInfo[iElem].droidBirth, &droidNowCheck, &droidBirthCheck );
|
||
|
}
|
||
|
|
||
|
if( _iArrays >= static_cast<LONG>(_sabound.cElements) )
|
||
|
{
|
||
|
TrkAssert( !TEXT("Not yet impelemented") );
|
||
|
// BUGBUG: do a SafeArrayReDim
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
bstr = SysAllocString( pFileInfo[iElem].tszFilePath );
|
||
|
if( NULL == bstr )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SysAllocString")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayPutElement( _pvarrgbstrFileName->parray, &_iArrays, bstr );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
SysFreeString( bstr ); bstr = NULL;
|
||
|
|
||
|
// BUGBUG: Add a Serialize(BSTR) method to CDroid
|
||
|
pFileInfo[iElem].droidBirth.Stringize( tszDroid, sizeof(tszDroid) );
|
||
|
bstr = SysAllocString( tszDroid );
|
||
|
if( NULL == bstr )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SysAllocString")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayPutElement( _pvarrgbstrFileId->parray, &_iArrays, bstr );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElement")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
if( fAtBirthplace )
|
||
|
FileOwnership = OBJOWN_OWNED;
|
||
|
|
||
|
else if( !fExistsInTable )
|
||
|
FileOwnership = OBJOWN_DOESNT_EXIST;
|
||
|
|
||
|
else if( droidNowCheck == pFileInfo[iElem].droidLast
|
||
|
&&
|
||
|
droidBirthCheck == pFileInfo[iElem].droidBirth )
|
||
|
FileOwnership = OBJOWN_OWNED;
|
||
|
|
||
|
else
|
||
|
FileOwnership = OBJOWN_NOT_OWNED;
|
||
|
|
||
|
|
||
|
hr = SafeArrayPutElement( _pvarrglongStatus->parray, &_iArrays, &FileOwnership );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayPutElemnt")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
_iArrays++;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
if( NULL != bstr )
|
||
|
SysFreeString( bstr );
|
||
|
|
||
|
if( !FAILED(_hr) )
|
||
|
_hr = hr;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
CPCFileStatus::Initialize( CMachineId *pmcid, VARIANT *pvarrgbstrFileName,
|
||
|
VARIANT *pvarrgbstrFileId, VARIANT *pvarrglongStatus )
|
||
|
{
|
||
|
_pmcid = pmcid;
|
||
|
_pvarrgbstrFileName = pvarrgbstrFileName;
|
||
|
_pvarrgbstrFileId = pvarrgbstrFileId;
|
||
|
_pvarrglongStatus = pvarrglongStatus;
|
||
|
|
||
|
_iArrays = 0;
|
||
|
_hr = S_OK;
|
||
|
_sabound.lLbound = 0;
|
||
|
_sabound.cElements = 10;
|
||
|
|
||
|
_fInitialized = TRUE;
|
||
|
|
||
|
_pvarrgbstrFileName->parray = SafeArrayCreate( VT_BSTR, 1, &_sabound );
|
||
|
if( NULL == _pvarrgbstrFileName->parray )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
_pvarrgbstrFileName->vt = VT_BSTR | VT_ARRAY;
|
||
|
|
||
|
_pvarrgbstrFileId->parray = SafeArrayCreate( VT_BSTR, 1, &_sabound );
|
||
|
if( NULL == _pvarrgbstrFileId->parray )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
_pvarrgbstrFileId->vt = VT_BSTR | VT_ARRAY;
|
||
|
|
||
|
_pvarrglongStatus->parray = SafeArrayCreate( VT_I4, 1, &_sabound );
|
||
|
if( NULL == _pvarrglongStatus->parray )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed SafeArrayCreate")));
|
||
|
TrkRaiseWin32Error( E_OUTOFMEMORY );
|
||
|
}
|
||
|
_pvarrglongStatus->vt = VT_I4 | VT_ARRAY;
|
||
|
|
||
|
|
||
|
} // CPCFileStatus::Initialize
|
||
|
|
||
|
|
||
|
|
||
|
void
|
||
|
CPCFileStatus::Compact()
|
||
|
{
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
_sabound.cElements = _iArrays;
|
||
|
|
||
|
hr = SafeArrayRedim( _pvarrgbstrFileName->parray, &_sabound );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayRedim( _pvarrgbstrFileId->parray, &_sabound );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
hr = SafeArrayRedim( _pvarrglongStatus->parray, &_sabound );
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't redim safearray")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
STDMETHODIMP CTrkForceOwnership::FileStatus(BSTR bstrUncPath, long scope,
|
||
|
VARIANT * pvarrgbstrFileName, VARIANT *pvarrgbstrFileId, VARIANT * pvarrglongStatus)
|
||
|
{
|
||
|
HRESULT hr = E_FAIL;
|
||
|
SAFEARRAYBOUND sabound;
|
||
|
HANDLE hFile = NULL;
|
||
|
|
||
|
// Determine the machine ID
|
||
|
CMachineId mcid( (LPWSTR) bstrUncPath );
|
||
|
CRpcClientBinding rc;
|
||
|
|
||
|
// This is used by the RPC server to push the volume information
|
||
|
CPCFileStatus cpcFileStatus( &_idt );
|
||
|
TRpcPipeControl< TRK_FILE_TRACKING_INFORMATION_PIPE, TRK_FILE_TRACKING_INFORMATION, CPCFileStatus
|
||
|
> cpipeFileStatus( &cpcFileStatus );
|
||
|
|
||
|
|
||
|
__try
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
|
||
|
// Initialize the outputs
|
||
|
VariantInit( pvarrgbstrFileName );
|
||
|
VariantInit( pvarrgbstrFileId );
|
||
|
VariantInit( pvarrglongStatus );
|
||
|
|
||
|
CDomainRelativeObjId droidCurrent, droidBirth;
|
||
|
|
||
|
// Initialize the pipe callback
|
||
|
cpcFileStatus.Initialize( &mcid, pvarrgbstrFileName, pvarrgbstrFileId, pvarrglongStatus );
|
||
|
|
||
|
if( TRKINFOSCOPE_ONE_FILE == scope )
|
||
|
{
|
||
|
|
||
|
// BUGBUG P2: Optimize this; we don't need droidBirth
|
||
|
status = GetDroids( bstrUncPath, &droidCurrent, &droidBirth, RGO_READ_OBJECTID );
|
||
|
|
||
|
if( STATUS_OBJECT_NAME_NOT_FOUND == status )
|
||
|
{
|
||
|
TRK_FILE_TRACKING_INFORMATION fileinfo;
|
||
|
|
||
|
_tcscpy( fileinfo.tszFilePath, TEXT("") );
|
||
|
fileinfo.hr = HRESULT_FROM_NT( status );
|
||
|
|
||
|
cpcFileStatus.Push( &fileinfo, 1 );
|
||
|
hr = S_OK;
|
||
|
goto Exit;
|
||
|
}
|
||
|
else if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed GetDroids (%s)"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
}
|
||
|
else if( TRKINFOSCOPE_VOLUME == scope )
|
||
|
{
|
||
|
NTSTATUS status;
|
||
|
IO_STATUS_BLOCK Iosb;
|
||
|
FILE_FS_OBJECTID_INFORMATION fsobOID;
|
||
|
CVolumeId volid;
|
||
|
|
||
|
status = TrkCreateFile( bstrUncPath, SYNCHRONIZE | FILE_READ_ATTRIBUTES, FILE_ATTRIBUTE_NORMAL,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN,
|
||
|
FILE_OPEN_NO_RECALL, NULL, &hFile );
|
||
|
if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
hFile = NULL;
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Couldn't open volume %s"), bstrUncPath ));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
|
||
|
status = NtQueryVolumeInformationFile( hFile, &Iosb, &fsobOID, sizeof(fsobOID),
|
||
|
FileFsObjectIdInformation );
|
||
|
|
||
|
if( STATUS_OBJECT_NAME_NOT_FOUND == status )
|
||
|
{
|
||
|
TRK_FILE_TRACKING_INFORMATION fileinfo;
|
||
|
|
||
|
_tcscpy( fileinfo.tszFilePath, TEXT("") );
|
||
|
fileinfo.hr = HRESULT_FROM_NT( status );
|
||
|
|
||
|
cpcFileStatus.Push( &fileinfo, 1 );
|
||
|
hr = S_OK;
|
||
|
goto Exit;
|
||
|
}
|
||
|
else if( !NT_SUCCESS(status) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed NtQueryVolumeInformationFile (%s)"), bstrUncPath));
|
||
|
TrkRaiseNtStatus( status );
|
||
|
}
|
||
|
volid.Load( &volid, fsobOID );
|
||
|
droidCurrent = CDomainRelativeObjId( volid, CObjId() );
|
||
|
|
||
|
NtClose( hFile );
|
||
|
hFile = NULL;
|
||
|
}
|
||
|
else if( TRKINFOSCOPE_MACHINE != scope )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Bad scope to CTrkForceOwnership::FileStatus (%d)"), scope ));
|
||
|
TrkRaiseWin32Error( ERROR_INVALID_PARAMETER );
|
||
|
}
|
||
|
|
||
|
// Connect to the workstation in question
|
||
|
rc.Initialize( mcid );
|
||
|
|
||
|
// Get the volume status info
|
||
|
RpcTryExcept
|
||
|
{
|
||
|
hr = GetFileTrackingInformation( rc, droidCurrent, static_cast<TrkInfoScope>(scope), cpipeFileStatus );
|
||
|
}
|
||
|
RpcExcept( BreakOnDebuggableException() )
|
||
|
{
|
||
|
hr = HRESULT_FROM_WIN32( RpcExceptionCode() );
|
||
|
}
|
||
|
RpcEndExcept;
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed call to GetFileTrackInformation")));
|
||
|
TrkRaiseException( hr );
|
||
|
}
|
||
|
|
||
|
if( FAILED(cpcFileStatus.GetHResult()) )
|
||
|
{
|
||
|
TrkLog((TRKDBG_ERROR, TEXT("Failed in FileStatus pipe callback")));
|
||
|
TrkRaiseException( cpcFileStatus.GetHResult() );
|
||
|
}
|
||
|
// Truncate the safearrays
|
||
|
cpcFileStatus.Compact();
|
||
|
|
||
|
}
|
||
|
__except( BreakOnDebuggableException() )
|
||
|
{
|
||
|
cpcFileStatus.UnInitialize();
|
||
|
hr = GetExceptionCode();
|
||
|
}
|
||
|
|
||
|
Exit:
|
||
|
|
||
|
if( NULL != hFile )
|
||
|
NtClose( hFile );
|
||
|
|
||
|
if( FAILED(hr) )
|
||
|
{
|
||
|
VariantClear( pvarrgbstrFileName );
|
||
|
VariantClear( pvarrgbstrFileId );
|
||
|
VariantClear( pvarrglongStatus );
|
||
|
}
|
||
|
|
||
|
return( hr );
|
||
|
}
|