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.
1622 lines
38 KiB
1622 lines
38 KiB
/*++
|
|
|
|
(c) 1998 Seagate Software, Inc. All rights reserved.
|
|
|
|
Module Name:
|
|
|
|
fsaftclt.cpp
|
|
|
|
Abstract:
|
|
|
|
This class represents a user who the filter has detected accessing a file with placeholder information.
|
|
|
|
Author:
|
|
|
|
Chuck Bardeen [cbardeen] 12-Feb-1997
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "stdafx.h"
|
|
extern "C" {
|
|
#include <ntseapi.h>
|
|
#include <wchar.h>
|
|
#include <lmaccess.h>
|
|
#include <lmserver.h>
|
|
#include <lmshare.h>
|
|
#include <lmapibuf.h>
|
|
#include <lmerr.h>
|
|
|
|
// #define MAC_SUPPORT // NOTE: You must define MAC_SUPPORT in fsafltr.cpp to enable all the code
|
|
|
|
#ifdef MAC_SUPPORT
|
|
#include <macfile.h>
|
|
#endif
|
|
}
|
|
|
|
|
|
#define WSB_TRACE_IS WSB_TRACE_BIT_FSA
|
|
|
|
#include "wsb.h"
|
|
#include "fsa.h"
|
|
#include "fsaftclt.h"
|
|
|
|
static USHORT iCountFtclt = 0; // Count of existing objects
|
|
|
|
//
|
|
// We need to dynamically load the DLL for MAC support because it is not there if
|
|
// the MAC service is not installed.
|
|
//
|
|
#ifdef MAC_SUPPORT
|
|
HANDLE FsaDllSfm = 0;
|
|
BOOL FsaMacSupportInstalled = FALSE;
|
|
|
|
extern "C" {
|
|
DWORD (*pAfpAdminConnect) (LPWSTR lpwsServerName, PAFP_SERVER_HANDLE phAfpServer);
|
|
VOID (*pAfpAdminDisconnect) (AFP_SERVER_HANDLE hAfpServer);
|
|
VOID (*pAfpAdminBufferFree) (PVOID pBuffer);
|
|
DWORD (*pAfpAdminSessionEnum) (AFP_SERVER_HANDLE hAfpServer, LPBYTE *lpbBuffer,
|
|
DWORD dwPrefMaxLen, LPDWORD lpdwEntriesRead, LPDWORD lpdwTotalEntries,
|
|
LPDWORD lpdwResumeHandle);
|
|
}
|
|
#endif
|
|
|
|
DWORD FsaIdentifyThread(void *pNotifyInterface);
|
|
|
|
|
|
|
|
DWORD FsaIdentifyThread(
|
|
void* pVoid
|
|
)
|
|
|
|
/*++
|
|
Entry point of the thread that performs identify operation with remote clients.
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr;
|
|
|
|
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
|
hr = ((CFsaFilterClient*) pVoid)->IdentifyThread();
|
|
CoUninitialize();
|
|
return(hr);
|
|
}
|
|
|
|
//
|
|
// Get RsNotify interface (being used here in identify thread -
|
|
// similar utility function is being used in RsLnk)
|
|
//
|
|
static
|
|
HRESULT
|
|
GetNotifyClientInterface(
|
|
IN OLECHAR * machineName,
|
|
OUT IFsaRecallNotifyClient ** ppClient
|
|
)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
//
|
|
// Make sure parameters OK and OUTs initially cleared
|
|
//
|
|
|
|
WsbAffirmPointer ( ppClient );
|
|
*ppClient = 0;
|
|
|
|
//
|
|
// If connecting local, things work better to use NULL
|
|
// for the computer name
|
|
//
|
|
|
|
if ( machineName ) {
|
|
|
|
CWsbStringPtr localMachine;
|
|
WsbAffirmHr( WsbGetComputerName( localMachine ) );
|
|
|
|
if( _wcsicmp( localMachine, machineName ) == 0 ) {
|
|
|
|
machineName = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
// Set server info
|
|
//
|
|
COSERVERINFO csi;
|
|
COAUTHINFO cai;
|
|
memset ( &csi, 0, sizeof ( csi ) );
|
|
memset ( &cai, 0, sizeof ( cai ) );
|
|
|
|
// Set machine name
|
|
csi.pwszName = machineName;
|
|
|
|
// Create a proxy with security settings of no authentication (note that RsNotify is running with this security)
|
|
cai.dwAuthnSvc = RPC_C_AUTHN_WINNT;
|
|
cai.dwAuthzSvc = RPC_C_AUTHZ_DEFAULT;
|
|
cai.pwszServerPrincName = NULL;
|
|
cai.dwImpersonationLevel = RPC_C_IMP_LEVEL_IMPERSONATE;
|
|
cai.pAuthIdentityData = NULL;
|
|
cai.dwCapabilities = EOAC_NONE;
|
|
|
|
cai.dwAuthnLevel = RPC_C_AUTHN_LEVEL_NONE;
|
|
|
|
csi.pAuthInfo = &cai;
|
|
|
|
//
|
|
// We want IFsaRecallNotifyClient back
|
|
//
|
|
|
|
MULTI_QI mqi;
|
|
memset ( &mqi, 0, sizeof ( mqi ) );
|
|
mqi.pIID = &IID_IFsaRecallNotifyClient;
|
|
|
|
//
|
|
// Make the connection...
|
|
//
|
|
|
|
WsbAffirmHr ( CoCreateInstanceEx (
|
|
CLSID_CFsaRecallNotifyClient, 0,
|
|
CLSCTX_NO_FAILURE_LOG | ( machineName ? CLSCTX_REMOTE_SERVER : CLSCTX_LOCAL_SERVER ),
|
|
&csi, 1, &mqi ) );
|
|
WsbAffirmHr ( mqi.hr );
|
|
|
|
//
|
|
// We need to make sure we clean up correctly if any interface
|
|
// post-processing fails, so assign over to a smart pointer for
|
|
// the time being
|
|
//
|
|
|
|
CComPtr<IFsaRecallNotifyClient> pClientTemp = (IFsaRecallNotifyClient*)mqi.pItf;
|
|
mqi.pItf->Release ( );
|
|
|
|
//
|
|
// Finally, we need to set the security on the procy to allow the
|
|
// anonymous connection. Values should be the same as above (COAUTHINFO)
|
|
// We need to make sure this is a remote machine first. Otherwise, we
|
|
// get an error of E_INVALIDARG.
|
|
//
|
|
if( machineName ) {
|
|
|
|
CComPtr<IClientSecurity> pSecurity;
|
|
WsbAffirmHr( pClientTemp->QueryInterface( IID_IClientSecurity, (void**)&pSecurity ) );
|
|
|
|
WsbAffirmHr( pSecurity->SetBlanket ( pClientTemp, RPC_C_AUTHN_NONE, RPC_C_AUTHZ_NONE, 0, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, 0, 0 ) );
|
|
|
|
}
|
|
|
|
//
|
|
// Finally, assign over and AddRef the return.
|
|
//
|
|
|
|
*ppClient = pClientTemp;
|
|
(*ppClient)->AddRef ( );
|
|
|
|
} WsbCatch ( hr );
|
|
|
|
return ( hr );
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::CheckRecallLimit(
|
|
IN DWORD minRecallInterval,
|
|
IN DWORD maxRecalls,
|
|
IN BOOLEAN exemptAdmin
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IWsbCollectable::CheckRecallLimit().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
FILETIME now, last;
|
|
LARGE_INTEGER tNow, tLast;
|
|
ULONG rCount;
|
|
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::CheckRecallLimit"), OLESTR(""));
|
|
|
|
try {
|
|
//
|
|
// Now check for runaway recall limits if the user is not
|
|
// an administrator
|
|
//
|
|
|
|
if ((!m_isAdmin) || (!exemptAdmin)) {
|
|
//
|
|
// See if the time since the end of the last recall is
|
|
// less than m_minRecallInterval (in seconds) and if so,
|
|
// increment the count.
|
|
// If not, then reset the count (if we were not
|
|
// already triggered).
|
|
// If the count is equal to the max then set the trigger.
|
|
//
|
|
WsbTrace(OLESTR("CHsmFilter::IoctlThread: Not an administrator or admin is not exempt.\n"));
|
|
GetSystemTimeAsFileTime(&now);
|
|
tNow.LowPart = now.dwLowDateTime;
|
|
tNow.HighPart = now.dwHighDateTime;
|
|
|
|
GetLastRecallTime(&last);
|
|
|
|
tLast.LowPart = last.dwLowDateTime;
|
|
tLast.HighPart = last.dwHighDateTime;
|
|
//
|
|
// Get the time (in 100 nano-second units)
|
|
// from the end of the last recall until now.
|
|
//
|
|
tNow.QuadPart -= tLast.QuadPart;
|
|
//
|
|
// Convert to seconds and check against the interval time
|
|
//
|
|
tNow.QuadPart /= (LONGLONG) 10000000;
|
|
if (tNow.QuadPart < (LONGLONG) minRecallInterval) {
|
|
//
|
|
// This one counts - increment the count
|
|
// and check for a trigger.
|
|
//
|
|
GetRecallCount(&rCount);
|
|
rCount++;
|
|
SetRecallCount(rCount);
|
|
|
|
WsbTrace(OLESTR("CHsmFilterClient::CheckRecallLimit: Recall count bumped to %ls.\n"),
|
|
WsbLongAsString(rCount));
|
|
|
|
if (rCount >= maxRecalls) {
|
|
//
|
|
// Hit the runaway recall limit. Set the
|
|
// limit flag.
|
|
//
|
|
WsbTrace(OLESTR("CHsmFilter::IoctlThread: Hit the runaway recall limit!!!.\n"));
|
|
SetHitRecallLimit(TRUE);
|
|
}
|
|
} else {
|
|
//
|
|
// Reset the count if they are not already triggered.
|
|
// If they are triggered then reset the trigger and
|
|
// limit if it has been a respectable time.
|
|
// TBD - What is a respectable time??
|
|
//
|
|
if (HitRecallLimit() != S_FALSE) {
|
|
if (tNow.QuadPart > (LONGLONG) minRecallInterval * 100) {
|
|
//
|
|
// A respectable time has passed - reset the trigger and count.
|
|
//
|
|
WsbTrace(OLESTR("CHsmFilterClient::CheckRecallLimit: Resetting recall limit trigger and count.\n"));
|
|
SetHitRecallLimit(FALSE);
|
|
SetRecallCount(0);
|
|
m_loggedLimitError = FALSE;
|
|
}
|
|
} else {
|
|
//
|
|
// This one did not count and they were not already triggered.
|
|
// Reset the count to zero.
|
|
//
|
|
WsbTrace(OLESTR("CHsmFilterClient::CheckRecallLimit: Resetting recall count.\n"));
|
|
SetRecallCount(0);
|
|
}
|
|
}
|
|
//
|
|
// Fail if the limit is hit.
|
|
//
|
|
WsbAffirm(HitRecallLimit() == S_FALSE, FSA_E_HIT_RECALL_LIMIT);
|
|
}
|
|
|
|
} WsbCatch(hr);
|
|
|
|
// NOTE - IF RUNAWAY RECALL BEHAVIOR CHANGES TO TRUNCATE ON CLOSE, CHANGE
|
|
// FSA_MESSAGE_HIT_RECALL_LIMIT_ACCESSDENIED TO FSA_MESSAGE_HIT_RECALL_LIMIT_TRUNCATEONCLOSE.
|
|
|
|
if ( (hr == FSA_E_HIT_RECALL_LIMIT) && (!m_loggedLimitError)) {
|
|
WsbLogEvent(FSA_MESSAGE_HIT_RECALL_LIMIT_ACCESSDENIED, 0, NULL, (WCHAR *) m_userName, NULL);
|
|
m_loggedLimitError = TRUE;
|
|
}
|
|
|
|
WsbTraceOut(OLESTR("CHsmFilterClient::CheckRecallLimit"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::CompareBy(
|
|
FSA_FILTERCLIENT_COMPARE by
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::CompareBy().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
m_compareBy = by;
|
|
m_isDirty = TRUE;
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::CompareTo(
|
|
IN IUnknown* pUnknown,
|
|
OUT SHORT* pResult
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IWsbCollectable::CompareTo().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IFsaFilterClient> pClient;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::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_IFsaFilterClient, (void**) &pClient));
|
|
|
|
// Compare the rules.
|
|
hr = CompareToIClient(pClient, pResult);
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CHsmFilterClient::CompareTo"), OLESTR("hr = <%ls>, result = <%ls>"), WsbHrAsString(hr), WsbPtrToShortAsString(pResult));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::CompareToAuthenticationId(
|
|
IN LONG luidHigh,
|
|
IN ULONG luidLow,
|
|
OUT SHORT* pResult
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::CompareToAuthenticationId().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SHORT aResult;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::CompareToAuthenticationId"), OLESTR(""));
|
|
|
|
try {
|
|
|
|
if (m_luidHigh > luidHigh) {
|
|
aResult = 1;
|
|
} else if (m_luidHigh < luidHigh) {
|
|
aResult = -1;
|
|
} else if (m_luidLow > luidLow) {
|
|
aResult = 1;
|
|
} else if (m_luidLow < luidLow) {
|
|
aResult = -1;
|
|
} else {
|
|
aResult = 0;
|
|
}
|
|
|
|
if (0 != aResult) {
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
if (0 != pResult) {
|
|
*pResult = aResult;
|
|
}
|
|
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::CompareToAuthenticationId"), OLESTR("hr = <%ls>, result = <%d>"), WsbHrAsString(hr), aResult);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::CompareToIClient(
|
|
IN IFsaFilterClient* pClient,
|
|
OUT SHORT* pResult
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::CompareToIClient().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CWsbStringPtr name;
|
|
LONG luidHigh;
|
|
ULONG luidLow;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::CompareToIClient"), OLESTR(""));
|
|
|
|
try {
|
|
|
|
// Did they give us a valid item to compare to?
|
|
WsbAssert(0 != pClient, E_POINTER);
|
|
|
|
switch (m_compareBy) {
|
|
case FSA_FILTERCLIENT_COMPARE_ID:
|
|
WsbAffirmHr(pClient->GetAuthenticationId(&luidHigh, &luidLow));
|
|
hr = CompareToAuthenticationId(luidHigh, luidLow, pResult);
|
|
break;
|
|
case FSA_FILTERCLIENT_COMPARE_MACHINE:
|
|
WsbAffirmHr(pClient->GetMachineName(&name, 0));
|
|
hr = CompareToMachineName(name, pResult);
|
|
break;
|
|
default:
|
|
WsbAssert(FALSE, E_UNEXPECTED);
|
|
}
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::CompareToIClient"), OLESTR("hr = <%ls>, result = <%ls>"), WsbHrAsString(hr), WsbPtrToShortAsString(pResult));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::CompareToMachineName(
|
|
IN OLECHAR* name,
|
|
OUT SHORT* pResult
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::CompareToMachineName().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
SHORT aResult;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::CompareToMachineName"), OLESTR(""));
|
|
|
|
try {
|
|
|
|
aResult = (SHORT)wcscmp(name, m_machineName); // TBD - Case sensitive or not?
|
|
|
|
if (0 != aResult) {
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
if (0 != pResult) {
|
|
*pResult = aResult;
|
|
}
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::CompareToMachineName"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::FinalConstruct(
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
CComObjectRoot::FinalConstruct().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::FinalConstruct"),OLESTR(""));
|
|
try {
|
|
|
|
WsbAffirmHr(CWsbCollectable::FinalConstruct());
|
|
|
|
m_compareBy = FSA_FILTERCLIENT_COMPARE_ID;
|
|
m_luidHigh = 0;
|
|
m_luidLow = 0;
|
|
m_hasRecallDisabled = FALSE;
|
|
m_hitRecallLimit = FALSE;
|
|
m_lastRecallTime.dwLowDateTime = 0;
|
|
m_lastRecallTime.dwHighDateTime = 0;
|
|
m_identified = FALSE;
|
|
m_tokenSource = L"";
|
|
m_msgCounter = 1;
|
|
m_identifyThread = NULL;
|
|
m_isAdmin = FALSE;
|
|
m_loggedLimitError = FALSE;
|
|
m_recallCount = 0;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
iCountFtclt++;
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::FinalConstruct"),OLESTR("Count is <%d>"), iCountFtclt);
|
|
|
|
return(hr);
|
|
}
|
|
void
|
|
CFsaFilterClient::FinalRelease(
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
CComObjectRoot::FinalRelease().
|
|
|
|
--*/
|
|
{
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::FinalRelease"),OLESTR(""));
|
|
|
|
if (NULL != m_identifyThread) {
|
|
CloseHandle(m_identifyThread);
|
|
m_identifyThread = NULL;
|
|
}
|
|
|
|
CWsbCollectable::FinalRelease();
|
|
|
|
iCountFtclt--;
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::FinalRelease"),OLESTR("Count is <%d>"), iCountFtclt);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetClassID(
|
|
OUT CLSID* pClsid
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IPersist::GetClassID().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::GetClassID"), OLESTR(""));
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pClsid, E_POINTER);
|
|
*pClsid = CLSID_CFsaFilterClientNTFS;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::GetClassID"), OLESTR("hr = <%ls>, CLSID = <%ls>"), WsbHrAsString(hr), WsbGuidAsString(*pClsid));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetAuthenticationId(
|
|
OUT LONG* pLuidHigh,
|
|
OUT ULONG* pLuidLow
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::GetAuthenticationId().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pLuidHigh, E_POINTER);
|
|
WsbAssert(0 != pLuidLow, E_POINTER);
|
|
|
|
*pLuidHigh = m_luidHigh;
|
|
*pLuidLow = m_luidLow;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetDomainName(
|
|
OUT OLECHAR** pName,
|
|
IN ULONG bufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::GetDomainName().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pName, E_POINTER);
|
|
WsbAffirmHr(m_domainName.CopyTo(pName, bufferSize));
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetIsAdmin(
|
|
OUT BOOLEAN *pIsAdmin
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IPersist::GetIsAdmin().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::GetIsAdmin"), OLESTR(""));
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pIsAdmin, E_POINTER);
|
|
*pIsAdmin = m_isAdmin;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::GetIsAdmin"), OLESTR("hr = <%ls>, isAdmin = <%u>"), WsbHrAsString(hr), *pIsAdmin);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetLastRecallTime(
|
|
OUT FILETIME* pTime
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::GetLastRecallTime().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pTime, E_POINTER);
|
|
*pTime = m_lastRecallTime;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetMachineName(
|
|
OUT OLECHAR** pName,
|
|
IN ULONG bufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::GetMachineName().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pName, E_POINTER);
|
|
WsbAffirmHr(m_machineName.CopyTo(pName, bufferSize));
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetRecallCount(
|
|
OUT ULONG* pCount
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::GetRecallCount().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pCount, E_POINTER);
|
|
*pCount = m_recallCount;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetUserName(
|
|
OUT OLECHAR** pName,
|
|
IN ULONG bufferSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::GetUserName().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pName, E_POINTER);
|
|
WsbAffirmHr(m_userName.CopyTo(pName, bufferSize));
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::GetSizeMax(
|
|
OUT ULARGE_INTEGER* pSize
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IPersistStream::GetSizeMax().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::GetSizeMax"), OLESTR(""));
|
|
|
|
try {
|
|
|
|
WsbAssert(0 != pSize, E_POINTER);
|
|
pSize->QuadPart = 0;
|
|
|
|
// WE don't need to persist these.
|
|
hr = E_NOTIMPL;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::GetSizeMax"), OLESTR("hr = <%ls>, Size = <%ls>"), WsbHrAsString(hr), WsbPtrToUliAsString(pSize));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::HasRecallDisabled(
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::HasRecallDisabled().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::HasRecallDisabled"), OLESTR(""));
|
|
|
|
if (!m_hasRecallDisabled) {
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
WsbTraceOut(OLESTR("CHsmFilterClient::HasRecallDisabled"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::HitRecallLimit(
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::HitRecallLimit().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::HitRecallLimit"), OLESTR(""));
|
|
|
|
if (!m_hitRecallLimit) {
|
|
hr = S_FALSE;
|
|
}
|
|
|
|
WsbTraceOut(OLESTR("CHsmFilterClient::HitRecallLimit"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::IdentifyThread(
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
CFsaFilterClient::IdentifyThread().
|
|
|
|
Notes:
|
|
Unlike recall start/stop messages that were moved to RsLnk.exe (bugs 570471, 571109),
|
|
the identification is still being done from RsServ for the following reasons:
|
|
1) There is only one IdentifyThread - moving this thread to RsLnk solves nothing
|
|
2) The notification process actally needs to know whether an identification is taking
|
|
place, so it could delay the notification (wait for the thread to be done).
|
|
|
|
--*/
|
|
{
|
|
#define WSB_BUFF_SIZE 1024
|
|
|
|
HRESULT hr = S_OK;
|
|
BOOL done, guestUser, noUser;
|
|
DWORD res, totalEnt, numEnt;
|
|
UCHAR *buff = NULL;
|
|
NET_API_STATUS status;
|
|
SESSION_INFO_1 *sess;
|
|
CWsbStringPtr pipePath;
|
|
ULONG holdOff = 0;
|
|
#ifdef MAC_SUPPORT
|
|
LPBYTE macBuff = NULL;
|
|
PAFP_SESSION_INFO macInfo;
|
|
AFP_SERVER_HANDLE macHandle = 0;
|
|
DWORD macResume = 0;
|
|
DWORD macTotalEntries, macTotalRead;
|
|
DWORD result;
|
|
#endif
|
|
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::IdentifyThread"), OLESTR(""));
|
|
|
|
try {
|
|
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread Flag: %x Client ID: %x:%x Source: %ls\n"),
|
|
m_identified, m_luidHigh, m_luidLow, (WCHAR *) m_tokenSource);
|
|
|
|
//
|
|
// If already identified then we bail out here.
|
|
//
|
|
WsbAffirm(m_identified == FALSE, S_OK);
|
|
|
|
|
|
done = FALSE;
|
|
res = 0;
|
|
|
|
noUser = FALSE;
|
|
if (_wcsicmp(m_userName, L"GUEST") == 0) {
|
|
/* It is the guest user - find all sessions and
|
|
send to ones marked guest */
|
|
guestUser = TRUE;
|
|
} else {
|
|
guestUser = FALSE;
|
|
if (wcslen(m_userName) == 0) {
|
|
noUser = TRUE;
|
|
}
|
|
}
|
|
|
|
CComPtr<IFsaRecallNotifyClient> pRecallClient;
|
|
|
|
WsbAffirmHr(WsbGetComputerName( pipePath ));
|
|
|
|
WsbAffirmHr(pipePath.Prepend("\\\\"));
|
|
WsbAffirmHr(pipePath.Append("\\pipe\\"));
|
|
WsbAffirmHr(pipePath.Append(WSB_PIPE_NAME));
|
|
|
|
while ( done == FALSE ) {
|
|
|
|
if ( (guestUser == FALSE) && (noUser == FALSE) ) {
|
|
|
|
// If NetSessionEnum fails, try calling again for all users
|
|
status = NetSessionEnum(NULL, NULL, m_userName, 1, &buff,
|
|
WSB_BUFF_SIZE, &numEnt, &totalEnt, &res);
|
|
|
|
if (status != 0) {
|
|
status = NetSessionEnum(NULL, NULL, NULL, 1, &buff,
|
|
WSB_BUFF_SIZE, &numEnt, &totalEnt, &res);
|
|
}
|
|
} else {
|
|
status = NetSessionEnum( NULL, NULL, NULL, 1, &buff,
|
|
WSB_BUFF_SIZE, &numEnt, &totalEnt, &res );
|
|
}
|
|
|
|
if ((status == NERR_Success) || (status == ERROR_MORE_DATA)) {
|
|
|
|
WsbTrace(OLESTR("CHsmFilterClient::IdentifyThread: NetSessionEnum output: Total entries=%ls , Read entries=%ls \n"),
|
|
WsbLongAsString(totalEnt), WsbLongAsString(numEnt));
|
|
|
|
if (status != ERROR_MORE_DATA) {
|
|
done = TRUE;
|
|
}
|
|
|
|
sess = (SESSION_INFO_1 *) buff;
|
|
|
|
while ( numEnt != 0 ) {
|
|
//
|
|
// If the request was made from the user GUEST then
|
|
// we enumerate all sessions and send the
|
|
// identification request to all the machines with
|
|
// sessions marked as GUEST. This is because the
|
|
// session may have some other user name but the
|
|
// request could still have GUEST access.
|
|
//
|
|
if (((guestUser) && (sess->sesi1_user_flags & SESS_GUEST)) ||
|
|
(!guestUser)) {
|
|
|
|
//
|
|
// Send the identify request message
|
|
//
|
|
|
|
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread - Sending identify request to %ls (local machine = %ls)\n"),
|
|
sess->sesi1_cname, (WCHAR *) pipePath);
|
|
|
|
hr = GetNotifyClientInterface ( sess->sesi1_cname, &pRecallClient );
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
|
|
hr = pRecallClient->IdentifyWithServer( pipePath );
|
|
if (hr != S_OK) {
|
|
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread - error Identifing (%ls)\n"),
|
|
WsbHrAsString(hr));
|
|
}
|
|
} else {
|
|
WsbTrace(OLESTR("CFsaFilterClient::IdentifyThread - error getting notify client interface hr = %ls (%x)\n"),
|
|
WsbHrAsString( hr ), hr);
|
|
}
|
|
hr = S_OK;
|
|
pRecallClient.Release ( );
|
|
}
|
|
|
|
sess++;
|
|
numEnt--;
|
|
}
|
|
|
|
NetApiBufferFree(buff);
|
|
buff = NULL;
|
|
} else {
|
|
done = TRUE;
|
|
}
|
|
}
|
|
|
|
#ifdef MAC_SUPPORT
|
|
//
|
|
// Done with LAN manager scan, now do a MAC scan.
|
|
//
|
|
if ( (FsaMacSupportInstalled) && ((pAfpAdminConnect)(NULL, &macHandle) == NO_ERROR) ) {
|
|
//
|
|
// We have connected to the MAC service - do a session enumeration
|
|
//
|
|
macResume = 0;
|
|
done = FALSE;
|
|
while (done == FALSE) {
|
|
result = (pAfpAdminSessionEnum)(macHandle, &macBuff, -1,
|
|
&macTotalRead, &macTotalEntries, &macResume);
|
|
|
|
if ((result == NO_ERROR) || (result == ERROR_MORE_DATA)) {
|
|
//
|
|
// Read some entries - send the message to each one
|
|
//
|
|
if (macTotalRead == macTotalEntries) {
|
|
done = TRUE;
|
|
}
|
|
|
|
macInfo = (PAFP_SESSION_INFO) macBuff;
|
|
while ( macTotalRead != 0 ) {
|
|
//
|
|
// Send to each matching user
|
|
//
|
|
if ( ( NULL != macInfo->afpsess_ws_name ) &&
|
|
( _wcsicmp(m_userName, macInfo->afpsess_username ) == 0 ) ) {
|
|
|
|
WsbTrace(OLESTR("CHsmFilterClient::IdentifyThread: Send Identify to MAC %ls.\n"),
|
|
macInfo->afpsess_ws_name);
|
|
|
|
//
|
|
// Send the identify request message
|
|
//
|
|
|
|
hr = GetNotifyClientInterface ( sess->sesi1_cname, &pRecallClient );
|
|
if ( SUCCEEDED ( hr ) ) {
|
|
pRecallClient->IdentifyWithServer ( pipePath );
|
|
}
|
|
|
|
hr = S_OK;
|
|
pRecallClient.Release ( );
|
|
}
|
|
macInfo++;
|
|
macTotalRead--;
|
|
}
|
|
|
|
(pAfpAdminBufferFree)(macBuff);
|
|
macBuff = NULL;
|
|
} else {
|
|
done = TRUE;
|
|
}
|
|
(pAfpAdminDisconnect)(macHandle);
|
|
macHandle = 0;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
} WsbCatch(hr);
|
|
|
|
if (buff != NULL) {
|
|
NetApiBufferFree(buff);
|
|
}
|
|
|
|
#ifdef MAC_SUPPORT
|
|
|
|
if (FsaMacSupportInstalled) {
|
|
if (macBuff != NULL) {
|
|
(pAfpAdminBufferFree)(macBuff);
|
|
}
|
|
if (macHandle != 0) {
|
|
(pAfpAdminDisconnect)(macHandle);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::IdentifyThread"), OLESTR("hr = %ls"), WsbHrAsString(hr));
|
|
return(hr);
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::Load(
|
|
IN IStream* pStream
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IPersistStream::Load().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::Load"), OLESTR(""));
|
|
|
|
try {
|
|
WsbAssert(0 != pStream, E_POINTER);
|
|
|
|
// No persistence.
|
|
hr = E_NOTIMPL;
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::Load"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::Save(
|
|
IN IStream* pStream,
|
|
IN BOOL clearDirty
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IPersistStream::Save().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CComPtr<IPersistStream> pPersistStream;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::Save"), OLESTR("clearDirty = <%ls>"), WsbBoolAsString(clearDirty));
|
|
|
|
try {
|
|
WsbAssert(0 != pStream, E_POINTER);
|
|
|
|
// No persistence.
|
|
hr = E_NOTIMPL;
|
|
|
|
// If we got it saved and we were asked to clear the dirty bit, then
|
|
// do so now.
|
|
if (clearDirty) {
|
|
m_isDirty = FALSE;
|
|
}
|
|
|
|
} WsbCatch(hr);
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::Save"), OLESTR("hr = <%ls>"), WsbHrAsString(hr));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SendRecallInfo(
|
|
IFsaFilterRecall *pRecall,
|
|
BOOL starting,
|
|
HRESULT rHr
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
CFsaFilterClient::SendRecallInfo
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::SendRecallInfo"), OLESTR(""));
|
|
|
|
if( ! m_identified && ( m_identifyThread != NULL ) ) {
|
|
|
|
//
|
|
// Wait for up to 10 seconds for identify thread to complete if
|
|
// Client not yet identified
|
|
// Note that after fix to 570399, once the thread is created, the handle will only be valid
|
|
// (till the object is destructed), only that if the thread is not running, the handle would
|
|
// be signaled and the wait will finish immediately
|
|
//
|
|
WaitForSingleObject( m_identifyThread, 10000 );
|
|
}
|
|
|
|
//
|
|
// Let the client know that the recall is starting or is finished
|
|
//
|
|
|
|
if ( m_identified ) {
|
|
|
|
try {
|
|
WsbTrace(OLESTR("CFsaFilterClient::SendRecallInfo - Client (%ls) is being notified of recall status (starting = %u hr = %x).\n"),
|
|
(WCHAR *) m_machineName, starting, rHr);
|
|
|
|
//
|
|
// Create intermediate server object which will be the client's
|
|
// connection back to the service. This object acts as a middle
|
|
// man to overcome the admin-only access into the FSA service.
|
|
//
|
|
CComPtr<IFsaRecallNotifyServer> pRecallServer;
|
|
WsbAffirmHr(CoCreateInstance(CLSID_CFsaRecallNotifyServer, 0, CLSCTX_NO_FAILURE_LOG | CLSCTX_ALL, IID_IFsaRecallNotifyServer, (void**)&pRecallServer));
|
|
WsbAffirmHr(pRecallServer->Init(pRecall));
|
|
|
|
//
|
|
// Use same object (different interface) to send the notifications
|
|
// (bugs 570471, 571109)
|
|
//
|
|
CComPtr<IFsaRecallNotifySend> pRecallNotify;
|
|
WsbAffirmHr(pRecallServer->QueryInterface(IID_IFsaRecallNotifySend, (void**)&pRecallNotify));
|
|
CComPtr<IFsaRecallNotifyClient> pRecallClient;
|
|
hr = pRecallNotify->SendNotification(m_machineName, starting, rHr);
|
|
if (hr != S_OK) {
|
|
WsbTrace(OLESTR("CFsaFilterClient::SendRecallInfo - failed in SendNotification (%ls)\n"),
|
|
WsbHrAsString(hr));
|
|
}
|
|
|
|
} WsbCatch(hr);
|
|
}
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::SendRecallInfo"), OLESTR("hr = %ls"), WsbHrAsString(hr));
|
|
return(hr);
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetAuthenticationId(
|
|
IN LONG luidHigh,
|
|
IN ULONG luidLow
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetAuthenticationId().
|
|
|
|
--*/
|
|
{
|
|
m_luidHigh = luidHigh;
|
|
m_luidLow = luidLow;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetDomainName(
|
|
IN OLECHAR* name
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetDomainName().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
m_domainName = name;
|
|
WsbAssert(m_domainName != 0, E_UNEXPECTED);
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetIsAdmin(
|
|
IN BOOLEAN isAdmin
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetIsAdmin().
|
|
|
|
--*/
|
|
{
|
|
m_isAdmin = isAdmin;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetLastRecallTime(
|
|
IN FILETIME time
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetLastRecallTime().
|
|
|
|
--*/
|
|
{
|
|
m_lastRecallTime = time;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetMachineName(
|
|
IN OLECHAR* name
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetMachineName().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
WsbAssert(name != 0, E_UNEXPECTED);
|
|
|
|
m_machineName = name;
|
|
m_identified = TRUE;
|
|
|
|
WsbTrace(OLESTR("CFsaFilterClient::SetMachineName Flag: %x Client ID: %x:%x Source: %ls == %ls\n"),
|
|
m_identified, m_luidLow, m_luidHigh, (WCHAR *) m_tokenSource, (WCHAR *) m_machineName);
|
|
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetRecallCount(
|
|
IN ULONG count
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetRecallCount().
|
|
|
|
--*/
|
|
{
|
|
m_recallCount = count;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetUserName(
|
|
IN OLECHAR* name
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetUserName().
|
|
|
|
--*/
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
try {
|
|
|
|
m_userName = _wcsupr(name);
|
|
WsbAssert(m_userName != 0, E_UNEXPECTED);
|
|
|
|
} WsbCatch(hr);
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetHasRecallDisabled(
|
|
IN BOOL hasBeen
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetHasRecallDisabled().
|
|
|
|
--*/
|
|
{
|
|
m_hasRecallDisabled = hasBeen;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetHitRecallLimit(
|
|
IN BOOL hasBeen
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetHitRecallLimit().
|
|
|
|
--*/
|
|
{
|
|
m_hitRecallLimit = hasBeen;
|
|
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::SetTokenSource(
|
|
IN CHAR *source
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
IFsaFilterClient::SetTokenSource()
|
|
|
|
--*/
|
|
{
|
|
OLECHAR tSource[TOKEN_SOURCE_LENGTH + 1];
|
|
memset (tSource, 0, sizeof (tSource));
|
|
|
|
if (-1 == mbstowcs((WCHAR *) tSource, source, TOKEN_SOURCE_LENGTH)) {
|
|
return E_INVALIDARG;
|
|
}
|
|
|
|
m_tokenSource = tSource;
|
|
return(S_OK);
|
|
}
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::StartIdentify(
|
|
void
|
|
)
|
|
|
|
/*++
|
|
|
|
Implements:
|
|
|
|
CFsaFilterClient::StartIdentify().
|
|
|
|
--*/
|
|
{
|
|
#define WSB_BUFF_SIZE 1024
|
|
|
|
HRESULT hr = S_OK;
|
|
DWORD tid;
|
|
|
|
|
|
WsbTraceIn(OLESTR("CFsaFilterClient::StartIdentify"), OLESTR(""));
|
|
|
|
try {
|
|
WsbTrace(OLESTR("CFsaFilterClient::StartIdentify Flag: %x Client ID: %x:%x Source: %ls\n"),
|
|
m_identified, m_luidHigh, m_luidLow, (WCHAR *) m_tokenSource);
|
|
|
|
//
|
|
// If already identified then we bail out here.
|
|
//
|
|
WsbAffirm(m_identified == FALSE, S_OK);
|
|
//
|
|
// If the request is from User32 then it is local
|
|
//
|
|
|
|
if (_wcsicmp(m_tokenSource, L"User32") == 0) {
|
|
|
|
//
|
|
// Identified as the local machine.
|
|
// Set the name and bail out with S_OK
|
|
//
|
|
WsbAffirmHr(WsbGetComputerName( m_machineName ));
|
|
m_identified = TRUE;
|
|
|
|
WsbTrace(OLESTR("CHsmFilterClient::StartIdentify: Identified as %ls.\n"),
|
|
(WCHAR *) m_machineName);
|
|
|
|
WsbThrow( S_OK );
|
|
} else {
|
|
//
|
|
// This code assumes that only one thread (IoctlThread) can execute
|
|
// (otherwise, it should be protected by a CS)
|
|
//
|
|
// Start the identification thread (if one is not running yet)
|
|
//
|
|
DWORD dwWaitStatus = 0;
|
|
if ( (NULL == m_identifyThread) ||
|
|
((dwWaitStatus = WaitForSingleObject(m_identifyThread, 0)) == WAIT_OBJECT_0) ) {
|
|
// Thread is not running
|
|
WsbTrace(OLESTR("CHsmFilterClient::StartIdentify: Starting ID thread.\n"));
|
|
HANDLE hTempThread = NULL;
|
|
|
|
WsbAffirm((hTempThread = CreateThread(0, 0, FsaIdentifyThread, (void*) this, 0, &tid)) != 0, HRESULT_FROM_WIN32(GetLastError()));
|
|
if (hTempThread == NULL) {
|
|
WsbAssertHr(E_FAIL);
|
|
}
|
|
|
|
HANDLE hPrevThread = (HANDLE)InterlockedExchangePointer(&(void *)m_identifyThread, (void *)hTempThread);
|
|
if (hPrevThread != NULL) {
|
|
CloseHandle(hPrevThread);
|
|
}
|
|
|
|
} else {
|
|
WsbTrace(OLESTR("CFsaFilterClient::StartIdentify: thread is null or waut failed. thread=%p wait=%lu err=%lu\n"),
|
|
(void *)m_identifyThread, dwWaitStatus, GetLastError());
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} WsbCatch(hr);
|
|
|
|
|
|
WsbTraceOut(OLESTR("CFsaFilterClient::StartIdentify"), OLESTR("hr = %ls"), WsbHrAsString(hr));
|
|
|
|
return(hr);
|
|
}
|
|
|
|
|
|
|
|
HRESULT
|
|
CFsaFilterClient::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);
|
|
}
|