Leaked source code of windows server 2003
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.
 
 
 
 
 
 

817 lines
23 KiB

/*++
Copyright (c) 1998 Microsoft Corporation
Module Name :
RwpFunctions.cxx
Abstract:
Implements the behaviors of the "Rogue Worker Process" --
to test Application Manager
Author:
David Wang ( t-dwang ) 14-Jun-1999 Initial
Project:
Duct-Tape
--*/
/*********************************************************
* Include Headers
*********************************************************/
#include "precomp.hxx"
#include "RwpFunctions.hxx"
/*********************************************************
* local functions
*********************************************************/
BOOL DoGetPidTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe);
BOOL DoPingReplyTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe);
BOOL DoSendCountersTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe);
BOOL DoHResultTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe);
BOOL DoWorkerRequestShutdownTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe);
BOOL DoInvalidOpcodeTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe);
void RWP_Write_LONG_to_Registry(const WCHAR* szSubKey, LONG lValue);
// These are for the new RWP tests
LONG OpCodeToTest;
LONG DataLength;
LONG UseDataLength;
LONG DataPointerType;
LONG NumberOfCalls;
LONG AttackDuration;
LONG TestStarted;
LONG TestCompleted;
// These are for old RWP tests
LONG RwpBehaviorExhibited;
LONG PingBehavior, PingCount;
LONG ShutdownBehavior, ShutdownCount;
LONG RotationBehavior, RotationCount;
LONG StartupBehavior, StartupCount;
LONG HealthBehavior, HealthCount;
LONG RecycleBehavior, RecycleCount;
LONG AppPoolBehavior;
LONG RWP_EXTRA_DEBUG;
LONG RWP_AppPoolTest(void)
{
return AppPoolBehavior == RWP_APPPOOL_BOGUS ? TRUE : FALSE;
}
LONG RWP_IPM_BadParamTest(LONG OpCode, HRESULT* phr, IPM_MESSAGE_PIPE* pPipe)
{
BOOL bRet = FALSE;
DBGPRINTF((DBG_CONTEXT, "In RWP_IPM_BadParamTest()\n"));
if(OpCode != OpCodeToTest)
return FALSE;
bRet = TRUE;
// we need to indicate we have actually gotten to the
// code in w3wp that calls our test
if(OpCodeToTest != RWP_IPM_OP_NONE)
RWP_Write_LONG_to_Registry(RWP_CONFIG_TEST_STARTED, 1);
switch(OpCodeToTest)
{
case RWP_IPM_OP_NONE:
bRet = FALSE;
break;
case RWP_IPM_OP_GETPID:
bRet = DoGetPidTest(phr, pPipe);
break;
case RWP_IPM_OP_PING_REPLY:
bRet = DoPingReplyTest(phr, pPipe);
break;
case RWP_IPM_OP_SEND_COUNTERS:
bRet = DoSendCountersTest(phr, pPipe);
break;
case RWP_IPM_OP_HRESULT:
bRet = DoHResultTest(phr, pPipe);
break;
case RWP_IPM_OP_WORKER_REQUESTS_SHUTDOWN:
bRet = DoWorkerRequestShutdownTest(phr, pPipe);
break;
case RWP_IPM_OP_INVALID:
bRet = DoInvalidOpcodeTest(phr, pPipe);
break;
default:
bRet = FALSE;
break;
}
if(bRet)
RWP_Write_LONG_to_Registry(RWP_CONFIG_TEST_COMPLETION_STATUS, RWP_TEST_STATUS_COMPLETE);
else
RWP_Write_LONG_to_Registry(RWP_CONFIG_TEST_COMPLETION_STATUS, RWP_TEST_STATUS_ERROR);
return bRet;
}
BOOL DoGetPidTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe)
{
DWORD dwDataLength;
DWORD * pData = NULL;
DBGPRINTF((DBG_CONTEXT, "In DoGetPidTest()\n"));
DWORD dwId = GetCurrentProcessId();
dwDataLength = UseDataLength ? DataLength : sizeof(dwId);
switch(DataPointerType)
{
default:
case RWP_DATA_POINTER_TYPE_VALID:
pData = &dwId;
break;
case RWP_DATA_POINTER_TYPE_NULL:
pData = NULL;
break;
case RWP_DATA_POINTER_TYPE_INVALID:
pData = (DWORD*) 1;
break;
}
*phr = pPipe->WriteMessage(IPM_OP_GETPID,
dwDataLength,
pData);
return TRUE;
}
BOOL DoPingReplyTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe)
{
DWORD dwDataLength;
DWORD * pData = NULL;
DWORD dwData = 42; // just some random data
DBGPRINTF((DBG_CONTEXT, "In DoPingReplyTest()\n"));
dwDataLength = UseDataLength ? DataLength : 0;
switch(DataPointerType)
{
default:
case RWP_DATA_POINTER_TYPE_VALID:
pData = &dwData;
break;
case RWP_DATA_POINTER_TYPE_NULL:
pData = NULL;
break;
case RWP_DATA_POINTER_TYPE_INVALID:
pData = (DWORD*) 1;
break;
}
*phr = pPipe->WriteMessage(
IPM_OP_PING_REPLY, // ping reply opcode
dwDataLength,
pData
);
return TRUE;
}
BOOL DoSendCountersTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe)
{
DWORD dwDataLength;
DWORD * pData = NULL;
DWORD dwData = 42; // just some random data
DBGPRINTF((DBG_CONTEXT, "In DoSendCountersTest()\n"));
dwDataLength = UseDataLength ? DataLength : sizeof(dwData);
BYTE* pBuffer = NULL;
switch(DataPointerType)
{
default:
case RWP_DATA_POINTER_TYPE_VALID:
if((UseDataLength) && (DataLength > 0))
{
pBuffer = new BYTE[DataLength];
pData = (DWORD*) pBuffer;
}
else
{
pData = &dwData;
}
break;
case RWP_DATA_POINTER_TYPE_NULL:
pData = NULL;
break;
case RWP_DATA_POINTER_TYPE_INVALID:
pData = (DWORD*) 1;
break;
}
for(int i = 0; i < NumberOfCalls; i++)
{
*phr = pPipe->WriteMessage(
IPM_OP_SEND_COUNTERS, // ping reply opcode
dwDataLength,
pData
);
}
if(pBuffer)
delete [] pBuffer;
return TRUE;
}
BOOL DoHResultTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe)
{
// Test 67034 needs special processing
DWORD dwDataLength;
HRESULT * pData = NULL;
DWORD dwTickCount;
DWORD dwStopTickCount;
DWORD dwAttackDurationMsec;
HRESULT hrToSend = S_OK;
DBGPRINTF((DBG_CONTEXT, "In DoHResultTest()\n"));
dwDataLength = UseDataLength ? DataLength : sizeof(hrToSend);
switch(DataPointerType)
{
default:
case RWP_DATA_POINTER_TYPE_VALID:
pData = &hrToSend;
break;
case RWP_DATA_POINTER_TYPE_NULL:
pData = NULL;
break;
case RWP_DATA_POINTER_TYPE_INVALID:
pData = (HRESULT*) 1;
break;
}
if(AttackDuration == 0)
{
*phr = pPipe->WriteMessage(
IPM_OP_HRESULT, // ping reply opcode
dwDataLength,
pData
);
}
else
{
// we're doing a DoS attack for some amount of time
dwTickCount = GetTickCount();
// convert duration to msec
dwAttackDurationMsec = AttackDuration * 60 * 1000;
dwStopTickCount = dwTickCount + dwAttackDurationMsec;
while(dwTickCount < dwStopTickCount)
{
*phr = pPipe->WriteMessage(
IPM_OP_HRESULT, // ping reply opcode
dwDataLength,
pData
);
dwTickCount = GetTickCount();
}
}
return TRUE;
}
BOOL DoWorkerRequestShutdownTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe)
{
DWORD dwDataLength;
IPM_WP_SHUTDOWN_MSG * pData = NULL;
IPM_WP_SHUTDOWN_MSG reason = IPM_WP_RESTART_COUNT_REACHED;
DBGPRINTF((DBG_CONTEXT, "In DoWorkerRequestShutdownTest()\n"));
dwDataLength = UseDataLength ? DataLength : sizeof(reason);
switch(DataPointerType)
{
default:
case RWP_DATA_POINTER_TYPE_VALID:
pData = &reason;
break;
case RWP_DATA_POINTER_TYPE_NULL:
pData = NULL;
break;
case RWP_DATA_POINTER_TYPE_INVALID:
pData = (IPM_WP_SHUTDOWN_MSG *) 1;
break;
case RWP_DATA_POINTER_TYPE_INVALID_REASON:
reason = (IPM_WP_SHUTDOWN_MSG) ((IPM_WP_SHUTDOWN_MSG)2*IPM_WP_MAXIMUM);
pData = &reason;
break;
}
*phr = pPipe->WriteMessage(
IPM_OP_WORKER_REQUESTS_SHUTDOWN, // ping reply opcode
dwDataLength,
pData
);
return TRUE;
}
BOOL DoInvalidOpcodeTest(HRESULT* phr, IPM_MESSAGE_PIPE* pPipe)
{
// Just use params for a shutdown reply
DWORD dwDataLength;
IPM_WP_SHUTDOWN_MSG * pData = NULL;
DBGPRINTF((DBG_CONTEXT, "In DoInvalidOpcodeTest()\n"));
IPM_WP_SHUTDOWN_MSG reason = IPM_WP_RESTART_COUNT_REACHED;
pData = &reason;
dwDataLength = sizeof(reason);
*phr = pPipe->WriteMessage(
(IPM_OPCODE) 50,
dwDataLength,
pData
);
return TRUE;
}
LONG RWP_Ping_Behavior(HRESULT* hr, IPM_MESSAGE_PIPE* pPipe)
{
*hr = S_OK;
int i = 0;
switch (PingBehavior)
{
//
//Don't respond to pings
//
case RWP_PING_NO_ANSWER:
DBGPRINTF((DBG_CONTEXT, "Rogue: Not responding to Ping\n"));
break;
//
//Responding with n pings
//
case RWP_PING_MULTI_ANSWER:
DBGPRINTF((DBG_CONTEXT, "Rogue: Responding to Ping %d times", PingCount));
for (i = 0; i < PingCount; i++)
{
*hr = pPipe->WriteMessage(
IPM_OP_PING_REPLY, // ping reply opcode
0, // no data to send
NULL // pointer to no data
);
}
break;
//
//Respond after n seconds
//
case RWP_PING_DELAY_ANSWER:
DBGPRINTF((DBG_CONTEXT, "Rogue: Delay responding to Ping for %d seconds", PingCount));
RWP_Sleep_For(PingCount);
//return 0 so that we'll keep going (this is a delay, not fail)
return (RWP_NO_MISBEHAVE);
break;
default:
DBGPRINTF((DBG_CONTEXT, "Rogue: Unknown Ping Behavior = %d\n", PingBehavior));
break;
}
return (PingBehavior);
} // RWP_Ping_Behavior
LONG RWP_Shutdown_Behavior(HRESULT* hr)
{
*hr = S_OK;
switch (ShutdownBehavior)
{
case RWP_SHUTDOWN_NOT_OBEY:
//
//Not shutting down, period
//
DBGPRINTF((DBG_CONTEXT, "Rogue: Not shutting down\n"));
break;
case RWP_SHUTDOWN_DELAY:
//
//Sleeping for n seconds before continuing on
//
DBGPRINTF((DBG_CONTEXT, "Rogue: Sleeping for %d seconds before shutdown\n", ShutdownCount));
RWP_Sleep_For(ShutdownCount);
//return 0 so that we'll keep going (this is a delay, not fail)
return (RWP_NO_MISBEHAVE);
break;
default:
DBGPRINTF((DBG_CONTEXT, "Rogue: Unknown Shutdown Behavior\n"));
break;
}
return (ShutdownBehavior);
} // RWP_Shutdown_Behavior
LONG RWP_Rotation_Behavior(HRESULT* pHr, IPM_MESSAGE_PIPE* pPipe)
{
*pHr = S_OK;
IPM_WP_SHUTDOWN_MSG reason;
switch (RotationBehavior)
{
case RWP_ROTATION_INVALID_REASON:
DBGPRINTF((DBG_CONTEXT, "Rogue: Sending Invalid shut-down reason\n"));
reason = IPM_WP_MINIMUM;
*pHr = pPipe->WriteMessage(
IPM_OP_WORKER_REQUESTS_SHUTDOWN, // sends shut-down message
sizeof(reason), // data to send
(BYTE *)&reason // pointer to data
);
break;
default:
DBGPRINTF((DBG_CONTEXT, "Rogue: Unknown Rotation Behavior\n"));
break;
}
return (RotationBehavior);
}
LONG RWP_Startup_Behavior(HRESULT* rc)
{
//
//modify rc accordingly
//
*rc = NO_ERROR;
switch (StartupBehavior)
{
case RWP_STARTUP_NOT_OBEY:
//
//Don't register with WAS
//
DBGPRINTF((DBG_CONTEXT, "Rogue: Not registering with WAS\n"));
break;
case RWP_STARTUP_DELAY:
//
//Delay starting up the thread message loop
//
DBGPRINTF((DBG_CONTEXT, "Rogue: Delay starting up for %d\n", StartupCount));
RWP_Sleep_For(StartupCount);
//return 0 so that we'll keep going (this is a delay, not fail)
return (RWP_NO_MISBEHAVE);
case RWP_STARTUP_NOT_REGISTER_FAIL:
//
//Quit before registering with UL
//
DBGPRINTF((DBG_CONTEXT, "Rogue: Not starting up (unregistered)... shutting down\n"));
// BUGBUG - what is this?
//wpContext->IndicateShutdown(SHUTDOWN_REASON_ADMIN);
//return 0 so that it enters (and subsequently exits) the thread loop
return (RWP_NO_MISBEHAVE);
//
//It looks like the place to modify is in wpcontext.cxx,
//when it tries to initialize IPM if requested
//
default:
break;
}
return (StartupBehavior);
}
LONG RWP_Health_Behavior()
{
return 0;
}
/*
LONG RWP_Recycle_Behavior() {
}
*/
void RWP_Sleep_For(LONG lTime) {
SleepEx(
(DWORD)lTime * 1000, //sleep for lTimeToSleep * 1000 milliseconds (4 second increments)
FALSE); // not alertable
DBGPRINTF((DBG_CONTEXT, "Done sleeping \n"));
}
void RWP_Display_Behavior()
{
DBGPRINTF((DBG_CONTEXT, "Rogue Behavior Status\n"));
switch(PingBehavior)
{
case RWP_NO_MISBEHAVE:
DBGPRINTF((DBG_CONTEXT, RWP_NO_PING_MISBEHAVE_MSG));
break;
case RWP_PING_NO_ANSWER:
DBGPRINTF((DBG_CONTEXT, RWP_PING_NO_ANSWER_MSG));
break;
case RWP_PING_MULTI_ANSWER:
DBGPRINTF((DBG_CONTEXT, "%s %d\n", RWP_PING_MULTI_ANSWER_MSG, PingCount));
break;
case RWP_PING_DELAY_ANSWER:
DBGPRINTF((DBG_CONTEXT, "%s %d\n", RWP_PING_DELAY_ANSWER_MSG, PingCount));
break;
default:
DBGPRINTF((DBG_CONTEXT, "Ping behavior set to unknown value"));
break;
}
switch(StartupBehavior)
{
case RWP_NO_MISBEHAVE:
DBGPRINTF((DBG_CONTEXT, RWP_NO_STARTUP_MISBEHAVE_MSG));
break;
case RWP_STARTUP_NOT_OBEY:
DBGPRINTF((DBG_CONTEXT, RWP_STARTUP_NOT_OBEY_MSG));
break;
case RWP_STARTUP_DELAY:
DBGPRINTF((DBG_CONTEXT, "%s %d\n", RWP_STARTUP_DELAY_MSG, StartupCount));
break;
case RWP_STARTUP_NOT_REGISTER_FAIL:
DBGPRINTF((DBG_CONTEXT, RWP_STARTUP_NOT_REGISTER_FAIL_MSG));
break;
default:
DBGPRINTF((DBG_CONTEXT, "Startup behavior set to unknown value"));
break;
}
switch(ShutdownBehavior)
{
case RWP_NO_MISBEHAVE:
DBGPRINTF((DBG_CONTEXT, RWP_NO_SHUTDOWN_MISBEHAVE_MSG));
break;
case RWP_SHUTDOWN_NOT_OBEY:
DBGPRINTF((DBG_CONTEXT, RWP_SHUTDOWN_NOT_OBEY_MSG));
break;
case RWP_SHUTDOWN_DELAY:
DBGPRINTF((DBG_CONTEXT, RWP_SHUTDOWN_DELAY_MSG, ShutdownCount));
break;
default:
DBGPRINTF((DBG_CONTEXT, "Shutdown behavior set to unknown value"));
break;
}
switch(RotationBehavior)
{
case RWP_NO_MISBEHAVE:
DBGPRINTF((DBG_CONTEXT, RWP_NO_ROTATION_MISBEHAVE_MSG));
break;
case RWP_ROTATION_INVALID_REASON:
DBGPRINTF((DBG_CONTEXT, RWP_ROTATION_INVALID_REASON_MSG));
break;
default:
DBGPRINTF((DBG_CONTEXT, "Rotation behavior set to unknown value"));
break;
}
switch(RecycleBehavior)
{
case RWP_NO_MISBEHAVE:
DBGPRINTF((DBG_CONTEXT, RWP_NO_RECYCLE_MISBEHAVE_MSG));
break;
case RWP_RECYCLE_NOT_OBEY:
DBGPRINTF((DBG_CONTEXT, RWP_RECYCLE_NOT_OBEY_MSG));
break;
case RWP_RECYCLE_DELAY:
DBGPRINTF((DBG_CONTEXT, "%s %d\n", RWP_RECYCLE_DELAY_MSG, RecycleCount));
break;
default:
DBGPRINTF((DBG_CONTEXT, "Shutdown behavior set to unknown value"));
break;
}
switch(HealthBehavior)
{
case RWP_NO_MISBEHAVE:
DBGPRINTF((DBG_CONTEXT, RWP_NO_HEALTH_MISBEHAVE_MSG));
break;
case RWP_HEALTH_OK:
DBGPRINTF((DBG_CONTEXT, RWP_HEALTH_OK_MSG));
break;
case RWP_HEALTH_NOT_OK:
DBGPRINTF((DBG_CONTEXT, RWP_HEALTH_NOT_OK_MSG));
break;
case RWP_HEALTH_TERMINALLY_ILL:
DBGPRINTF((DBG_CONTEXT, RWP_HEALTH_TERMINALLY_ILL_MSG));
break;
default:
break;
}
}
void RWP_Read_LONG_from_Registry(HKEY hkey, const WCHAR* szSubKey, LONG* lValue)
{
LONG lResult;
DWORD dwType;
DWORD len = sizeof(lValue);
HKEY myKey;
lResult = RegQueryValueEx(
hkey,
szSubKey,
0,
&dwType,
(LPBYTE)lValue,
&len);
if (lResult != ERROR_SUCCESS)
{
//sets default = 0 (no misbehave)
*lValue = RWP_NO_MISBEHAVE;
/*
//key does not exist -- try to create it
lResult = RegCreateKeyEx(
hkey,
szSubKey,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&myKey,
&dwType);
*/
}
}
void RWP_Write_LONG_to_Registry(const WCHAR* szSubKey, LONG lValue)
{
LONG lResult;
HKEY hkMyKey;
lResult = RegOpenKeyEx(
HKEY_LOCAL_MACHINE, //root key
RWP_CONFIG_LOCATION, //sub key
0, //reserved - must be 0
KEY_ALL_ACCESS, //SAM
&hkMyKey); //my pointer to HKEY
if (lResult != ERROR_SUCCESS)
{
DBGPRINTF((DBG_CONTEXT, "Unable to open configuration key. RegOpenKeyEx returned %d\n", lResult));
return;
}
lResult = RegSetValueEx(
hkMyKey,
szSubKey,
0,
REG_DWORD,
(LPBYTE)&lValue,
sizeof(lValue));
RegCloseKey(hkMyKey);
ASSERT(lResult == ERROR_SUCCESS);
return;
}
BOOL RWP_Read_Config(const WCHAR* szRegKey)
{
BOOL bSuccess = FALSE;
HKEY hkMyKey;
LONG lResult;
DWORD dwDisp;
DWORD dwLastError = 0;
//
// Initialize to default values
//
// New behavior
OpCodeToTest = RWP_IPM_OP_NONE;
DataLength = 0; // 0 means set it to the actual data length
UseDataLength = FALSE; // by default we'll use the valid data length
DataPointerType = RWP_DATA_POINTER_TYPE_VALID;
NumberOfCalls = 1;
AttackDuration = 0;
PingBehavior = RWP_NO_MISBEHAVE;
ShutdownBehavior = RWP_NO_MISBEHAVE;
StartupBehavior = RWP_NO_MISBEHAVE;
HealthBehavior = RWP_NO_MISBEHAVE;
RecycleBehavior = RWP_NO_MISBEHAVE;
AppPoolBehavior = RWP_NO_MISBEHAVE;
RWP_EXTRA_DEBUG = RWP_DEBUG_OFF;
lResult = RegOpenKeyEx(
HKEY_LOCAL_MACHINE, //root key
szRegKey, //sub key
0, //reserved - must be 0
KEY_ALL_ACCESS, //SAM
&hkMyKey); //my pointer to HKEY
if (lResult != ERROR_SUCCESS)
{
DBGPRINTF((DBG_CONTEXT, "Unable to open configuration key. RegOpenKeyEx returned %d\n", lResult));
}
else
{ //my key exists. Read in config info and validate
DBGPRINTF((DBG_CONTEXT, "Key exists\n"));
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_OPCODE_TO_TEST, &OpCodeToTest);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_IPM_DATA_LENGTH, &DataLength);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_IPM_USE_DATA_LENGTH, &UseDataLength);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_IPM_POINTER_TYPE, &DataPointerType);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_NUMBER_OF_CALLS, &NumberOfCalls);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_ATTACK_DURATION, &AttackDuration);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_PING_BEHAVIOR, &PingBehavior);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_SHUTDOWN_BEHAVIOR, &ShutdownBehavior);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_ROTATION_BEHAVIOR, &RotationBehavior);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_STARTUP_BEHAVIOR, &StartupBehavior);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_HEALTH_BEHAVIOR, &HealthBehavior);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_RECYCLE_BEHAVIOR, &RecycleBehavior);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_APP_POOL_BEHAVIOR, &AppPoolBehavior);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_PING_COUNT, &PingCount);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_SHUTDOWN_COUNT, &ShutdownCount);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_ROTATION_COUNT, &RotationCount);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_STARTUP_COUNT, &StartupCount);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_HEALTH_COUNT, &HealthCount);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_RECYCLE_COUNT, &RecycleCount);
RWP_Read_LONG_from_Registry(hkMyKey, RWP_CONFIG_EXTRA_DEBUG, &RWP_EXTRA_DEBUG);
}
bSuccess = TRUE;
RegCloseKey(hkMyKey);
//
//Declare our intentions
//
RWP_Display_Behavior();
DBGPRINTF((DBG_CONTEXT, "Finished Configurations\n"));
//TODO: Display PID and command line info...
return (bSuccess);
}
/*
Methods modified:
iiswp.cxx
wpipm.cxx (3 places - handleping, handleshutdown, pipedisconnected)
*/