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.
364 lines
11 KiB
364 lines
11 KiB
//+-------------------------------------------------------------------------
|
|
//
|
|
// 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
|
|
|