windows-nt/Source/XPSP1/NT/inetsrv/query/daemon/cidaemon.cxx
2020-09-26 16:20:57 +08:00

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