365 lines
10 KiB
C++
365 lines
10 KiB
C++
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Microsoft Windows
|
||
|
// Copyright (C) Microsoft Corporation, 1992 - 2000.
|
||
|
//
|
||
|
// File: cidaemon.cxx
|
||
|
//
|
||
|
// Contents: CI Daemon
|
||
|
//
|
||
|
// History: 07-Jun-94 DwightKr Created
|
||
|
// 18-Dec-97 KLam Removed uneeded inclusion of shtole.hxx
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
#include <pch.cxx>
|
||
|
#pragma hdrstop
|
||
|
|
||
|
#include <dmnproxy.hxx>
|
||
|
|
||
|
#include "cidaemon.hxx"
|
||
|
#include <ciregkey.hxx>
|
||
|
|
||
|
DECLARE_INFOLEVEL(ci)
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CCiDaemon::CCiDaemon
|
||
|
//
|
||
|
// Synopsis: Contructor of the CCiDaemon class. Creates all the necessary
|
||
|
// objects to start filtering in the daemon process for a
|
||
|
// catalog.
|
||
|
//
|
||
|
// Arguments: [nameGen] - Object used to generated shared memory and
|
||
|
// event object names.
|
||
|
// [dwMemSize] - Shared memory size.
|
||
|
// [dwParentId] - ProcessId of the parent process.
|
||
|
//
|
||
|
// History: 1-06-97 srikants Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
CCiDaemon::CCiDaemon( CSharedNameGen & nameGen,
|
||
|
DWORD dwMemSize,
|
||
|
DWORD dwParentId )
|
||
|
: _proxy( nameGen, dwMemSize, dwParentId )
|
||
|
{
|
||
|
//
|
||
|
// Retrieve startup data for the client and then create an instance
|
||
|
// of the client control.
|
||
|
//
|
||
|
|
||
|
ULONG cbData;
|
||
|
GUID clsidClientMgr;
|
||
|
BYTE const * pbData = _proxy.GetStartupData( clsidClientMgr, cbData );
|
||
|
if ( 0 == pbData )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ERROR, "Failed to get startup data\n" ));
|
||
|
THROW( CException( STATUS_UNSUCCESSFUL ) );
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create the admin params and a simple wrapper class.
|
||
|
//
|
||
|
CCiAdminParams *pAdminParams = new CCiAdminParams;
|
||
|
_xAdminParams.Set( pAdminParams );
|
||
|
_xFwParams.Set( new CCiFrameworkParams( _xAdminParams.GetPointer() ) );
|
||
|
|
||
|
//
|
||
|
// Create the filter client object based on the Client Manager classid
|
||
|
//
|
||
|
|
||
|
// Win4Assert( FALSE );
|
||
|
|
||
|
ICiCFilterClient *pTmpFilterClient;
|
||
|
SCODE sc = CoCreateInstance( clsidClientMgr,
|
||
|
NULL,
|
||
|
CLSCTX_ALL,
|
||
|
IID_ICiCFilterClient,
|
||
|
(PVOID*)&pTmpFilterClient );
|
||
|
if (!SUCCEEDED( sc )) {
|
||
|
ciDebugOut(( DEB_ERROR, "Unable to bind to filter client - %x\n", sc ));
|
||
|
THROW( CException( sc ));
|
||
|
}
|
||
|
|
||
|
XInterface<ICiCFilterClient> xFilterClient( pTmpFilterClient );
|
||
|
|
||
|
//
|
||
|
// Initialize the filter client
|
||
|
//
|
||
|
|
||
|
sc = xFilterClient->Init( pbData, cbData, _xAdminParams.GetPointer( ));
|
||
|
if (!SUCCEEDED( sc )) {
|
||
|
ciDebugOut(( DEB_ERROR, "FilterClient->Init failed - %x\n", sc ));
|
||
|
THROW( CException( sc ));
|
||
|
}
|
||
|
|
||
|
// Set the process class and thread priority after admin params
|
||
|
// are initialized by Init() above.
|
||
|
|
||
|
_proxy.SetPriority( _xFwParams->GetThreadClassFilter(),
|
||
|
_xFwParams->GetThreadPriorityFilter() );
|
||
|
|
||
|
//
|
||
|
// Set the pagefile limit. This protects against excessive VM usage.
|
||
|
//
|
||
|
|
||
|
QUOTA_LIMITS QuotaLimit;
|
||
|
|
||
|
NTSTATUS Status = NtQueryInformationProcess( NtCurrentProcess(),
|
||
|
ProcessQuotaLimits,
|
||
|
&QuotaLimit,
|
||
|
sizeof(QuotaLimit),
|
||
|
0 );
|
||
|
|
||
|
if ( NT_SUCCESS(Status) )
|
||
|
{
|
||
|
Win4Assert( _xFwParams->GetMaxDaemonVmUse() * 1024 > _xFwParams->GetMaxDaemonVmUse() ); // Overflow check.
|
||
|
|
||
|
//
|
||
|
// The slop is because we don't want to totally trash the system with a memory allocation, but
|
||
|
// once a leak has occurred all sorts of legitimate allocations will also fail. So in the daemon
|
||
|
// we allow you to allocate memory slightly beyond the max, but in the watchdog checks we bail
|
||
|
// when the limit is hit.
|
||
|
//
|
||
|
|
||
|
QuotaLimit.PagefileLimit = (_xFwParams->GetMaxDaemonVmUse() + _xFwParams->GetMaxDaemonVmUse() / 10) * 1024;
|
||
|
|
||
|
Status = NtSetInformationProcess( NtCurrentProcess(),
|
||
|
ProcessQuotaLimits,
|
||
|
&QuotaLimit,
|
||
|
sizeof(QuotaLimit) );
|
||
|
|
||
|
if ( !NT_SUCCESS(Status) )
|
||
|
{
|
||
|
ciDebugOut(( DEB_ERROR, "Error 0x%x setting pagefile quota.\n", Status ));
|
||
|
|
||
|
THROW( CException( Status ) );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// get ICiCLangRes interface pointer; used to set a CLangList instance
|
||
|
//
|
||
|
|
||
|
ICiCLangRes * pICiCLangRes = 0;
|
||
|
|
||
|
sc = xFilterClient->QueryInterface(IID_ICiCLangRes, (void **) &pICiCLangRes);
|
||
|
|
||
|
if ( FAILED(sc) )
|
||
|
{
|
||
|
THROW( CException(sc) );
|
||
|
}
|
||
|
|
||
|
XInterface<ICiCLangRes> xICiCLangRes(pICiCLangRes);
|
||
|
|
||
|
_xLangList.Set( new CLangList(pICiCLangRes) );
|
||
|
pAdminParams->SetLangList( _xLangList.GetPointer() );
|
||
|
|
||
|
//
|
||
|
// Now create the filter daemon class.
|
||
|
//
|
||
|
ULONG cbEntryBuf;
|
||
|
BYTE * pbEntryBuf = _proxy.GetEntryBuffer( cbEntryBuf );
|
||
|
|
||
|
CFilterDaemon * pFilterDaemon =
|
||
|
new CFilterDaemon( _proxy,
|
||
|
_xFwParams.GetReference(),
|
||
|
_xLangList.GetReference(),
|
||
|
pbEntryBuf,
|
||
|
cbEntryBuf,
|
||
|
xFilterClient.GetPointer( ) );
|
||
|
|
||
|
_xFilterDaemon.Set( pFilterDaemon );
|
||
|
}
|
||
|
|
||
|
CCiDaemon::~CCiDaemon()
|
||
|
{
|
||
|
// ShutdownDaemonClient();
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Member: CCiDaemon::FilterDocuments
|
||
|
//
|
||
|
// Synopsis: Filters documents until death of the thread or process
|
||
|
//
|
||
|
// History: 1-06-97 srikants Created
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
void CCiDaemon::FilterDocuments()
|
||
|
{
|
||
|
SCODE scode;
|
||
|
|
||
|
do
|
||
|
{
|
||
|
scode = _xFilterDaemon->DoUpdates();
|
||
|
}
|
||
|
while (scode == FDAEMON_W_WORDLISTFULL );
|
||
|
}
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: Usage, public
|
||
|
//
|
||
|
// Purpose: Displays usage message
|
||
|
//
|
||
|
// History: 06-Jun-94 DwightKr Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
void Usage()
|
||
|
{
|
||
|
printf("This program is part of the Ci Filter Service and can not be run standalone.\n");
|
||
|
ciDebugOut( (DEB_ITRACE, "Ci Filter Daemon: Bad command line parameters\n" ));
|
||
|
}
|
||
|
|
||
|
//+---------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: RunTheDaemon
|
||
|
//
|
||
|
// Synopsis: The main function for the downlevel daemon process.
|
||
|
//
|
||
|
// Arguments: [argc] -
|
||
|
// [argv] -
|
||
|
//
|
||
|
// History: 2-04-96 srikants Created
|
||
|
//
|
||
|
// Notes: This method is currently invoked if argc == 8. We can
|
||
|
// change that to explicitly pass something in the first
|
||
|
// parameter.
|
||
|
//
|
||
|
//----------------------------------------------------------------------------
|
||
|
|
||
|
NTSTATUS RunTheDaemon( int argc, WCHAR * argv[] )
|
||
|
{
|
||
|
|
||
|
#if DBG==1
|
||
|
ciInfoLevel = DEB_ERROR | DEB_WARN | DEB_IWARN | DEB_IERROR;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// Win4Assert( !"Break In" );
|
||
|
|
||
|
if ( argc != 5 ||
|
||
|
0 != _wcsicmp( DL_DAEMON_ARG1_W, argv[1] ) ||
|
||
|
wcslen( argv[2] ) >= MAX_PATH )
|
||
|
{
|
||
|
printf( "%ws %ws <catalog-dir> <SharedMemSize> <ParentId>\n",
|
||
|
argv[0], DL_DAEMON_ARG1_W );
|
||
|
return STATUS_INVALID_PARAMETER;
|
||
|
}
|
||
|
|
||
|
WCHAR *pwcCatalog = argv[2];
|
||
|
DWORD dwMemSize = _wtol( argv[3] );
|
||
|
DWORD iParentId = _wtol( argv[4] );
|
||
|
|
||
|
NTSTATUS status = STATUS_SUCCESS;
|
||
|
|
||
|
TRY
|
||
|
{
|
||
|
XCom xcom;
|
||
|
|
||
|
XPtr<CSharedNameGen> xNameGen( new CSharedNameGen( pwcCatalog ) );
|
||
|
|
||
|
CCiDaemon ciDaemon( xNameGen.GetReference(),
|
||
|
dwMemSize,
|
||
|
iParentId );
|
||
|
//
|
||
|
// Namegen is a fairly big class. Delete the memory.
|
||
|
//
|
||
|
xNameGen.Free();
|
||
|
|
||
|
ciDaemon.FilterDocuments();
|
||
|
}
|
||
|
CATCH( CException, e)
|
||
|
{
|
||
|
status = e.GetErrorCode();
|
||
|
ciDebugOut(( DEB_ERROR, "DL Filter Daemon:Exiting process, error = 0x%X\n",
|
||
|
e.GetErrorCode() ));
|
||
|
}
|
||
|
END_CATCH
|
||
|
|
||
|
ciDebugOut( (DEB_ITRACE, "DL Filter Daemon: Leaving main()\n" ));
|
||
|
|
||
|
return status;
|
||
|
} //RunTheDaemon
|
||
|
|
||
|
//+-------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: main, public
|
||
|
//
|
||
|
// Purpose: Application entry point, sets up the service entry point
|
||
|
// and registers the entry point with the service control
|
||
|
// dispatcher.
|
||
|
//
|
||
|
// Arguments: [argc] - number of arguments passed
|
||
|
// [argv] - arguments
|
||
|
//
|
||
|
// History: 06-Jun-94 DwightKr Created
|
||
|
//
|
||
|
//--------------------------------------------------------------------------
|
||
|
|
||
|
extern "C" int __cdecl wmain( int argc, WCHAR *argv[] )
|
||
|
{
|
||
|
NTSTATUS status = STATUS_SUCCESS;
|
||
|
|
||
|
CNoErrorMode noError;
|
||
|
|
||
|
CTranslateSystemExceptions translate;
|
||
|
|
||
|
TRY
|
||
|
{
|
||
|
#if DBG==1 || CIDBG==1
|
||
|
ciInfoLevel = DEB_ERROR | DEB_WARN | DEB_IWARN | DEB_IERROR;
|
||
|
#endif // DBG==1 || CIDBG==1
|
||
|
|
||
|
#if CIDBG == 1
|
||
|
BOOL fRun = TRUE; // FALSE --> Stop
|
||
|
|
||
|
TRY
|
||
|
{
|
||
|
CRegAccess reg( RTL_REGISTRY_CONTROL, wcsRegAdmin );
|
||
|
|
||
|
ULONG ulVal = reg.Read( L"StopCiDaemonOnStartup", (ULONG)0 );
|
||
|
|
||
|
if ( 1 == ulVal )
|
||
|
fRun = FALSE;
|
||
|
}
|
||
|
CATCH( CException, e )
|
||
|
{
|
||
|
}
|
||
|
END_CATCH;
|
||
|
|
||
|
unsigned long OldWin4AssertLevel = SetWin4AssertLevel(ASSRT_MESSAGE | ASSRT_POPUP);
|
||
|
|
||
|
Win4Assert( fRun );
|
||
|
|
||
|
SetWin4AssertLevel( OldWin4AssertLevel );
|
||
|
#endif // CIDBG
|
||
|
|
||
|
if ( argc > 2 && 0 == _wcsicmp( argv[1], DL_DAEMON_ARG1_W ) )
|
||
|
{
|
||
|
status = RunTheDaemon( argc, argv );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Usage();
|
||
|
return 0;
|
||
|
}
|
||
|
}
|
||
|
CATCH( CException, e)
|
||
|
{
|
||
|
ciDebugOut(( DEB_ERROR,
|
||
|
"Unhandled error in CiDaemon: 0x%x\n",
|
||
|
e.GetErrorCode() ));
|
||
|
}
|
||
|
END_CATCH
|
||
|
|
||
|
// Shutdown Kyle OLE now or it'll AV later.
|
||
|
|
||
|
CIShutdown();
|
||
|
|
||
|
return status;
|
||
|
} //wmain
|
||
|
|