freefly
驱动牛犊
驱动牛犊
  • 注册日期2001-11-08
  • 最后登录2007-02-11
  • 粉丝0
  • 关注0
  • 积分113分
  • 威望12点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
阅读:3292回复:6

怎样解决Wdm影响关机的问题?????

楼主#
更多 发布于:2002-04-17 16:16
我编一个Wdm监控Ring3 Application,防止Application被恶意杀死,如TerminateProcess.
 当application运行后周期性地向wdm发送deviceiocontrol: startTalk 消息。当wdm持续一定周期没受到该消息的话,就出现蓝屏。当application正常退出时向wdm发送一个deviceiocontrol:endtalk消息,就不出现蓝屏啦。

   可是,我发现我的application在\"退出\"时,注销即Logoff计算机后,如果要选择关闭计算机就会出现一片纯蓝的屏幕,再也没有啦反应。
   请问该怎么解决?????

最新喜欢:

IammeIamme
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-04-17 17:33
你在wdm的close例程干了什么?
Iamme
驱动小牛
驱动小牛
  • 注册日期2001-03-23
  • 最后登录2005-10-11
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-04-18 10:46
说详细些
Go,go ahead
lms2000
驱动牛犊
驱动牛犊
  • 注册日期2001-05-19
  • 最后登录2018-05-30
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望102点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2002-04-18 11:29
ring 3 app 需要处理WM_ENDSESSION
否则会被杀掉而不会发出endtalk,WDM认为ring 3 app不正常退出,所以...
Snare
驱动小牛
驱动小牛
  • 注册日期2002-01-31
  • 最后登录2002-08-23
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-04-18 12:30
这种情况是在Ring3 Application正常关闭以后发生的么?
如果没关闭程序,直接注销或关机,那么就要处理
或用WM_QUERYENDSESSION来阻止系统关闭
我就是我,没什么可说的。
blue
驱动大牛
驱动大牛
  • 注册日期2001-04-25
  • 最后登录2010-10-15
  • 粉丝0
  • 关注0
  • 积分55分
  • 威望12点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-04-18 15:02
我认为有极大的可能是你分配了某些资源,却没有去释放它造成的。
你在“deviceiocontrol: startTalk 消息”分配了什么资源,没有释放,积累到资源耗尽,就死机了;当关机时,由于资源没有释放,造成WDM不能完全 Unload
freefly
驱动牛犊
驱动牛犊
  • 注册日期2001-11-08
  • 最后登录2007-02-11
  • 粉丝0
  • 关注0
  • 积分113分
  • 威望12点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-04-18 17:57
我的这个ring3 application实际上是一个网络计费系统的客户端,而这个wdm是为啦防止客户端application被kill掉。
我的问题是:在程序中能控制计算机注销,当出现注销界面后再选择重新启动或关闭就出现不能彻底关闭计算机的情况。
下面是原马:
===================

#include <vdw.h>
#include \"HelloWdm.h\"
#include \"HelloDev.h\"
#include \"HelloDI.h\"

GUID HelloDevGuid = HELLO_CLASS_GUID;

///////////////////////////////////////////////////////////////////////////////
// Constructor for subclass of KPnpDevice
//
SimpleWdmDevice::SimpleWdmDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KPnpDevice(
Pdo,
KUnitizedName(L\"HelloWdm\", Unit),
FILE_DEVICE_UNKNOWN,
&HelloDevGuid,
0,
DO_POWER_PAGABLE
)
{
    T << \"entered SimpleWdmDevice constructor\\n\";

// check for succes of base class construction

if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
T << TraceError
<< \"Failed to create device, status=\"
<< ULONG(m_ConstructorStatus)
<< \"\\n\";

return;
}

// Attach the PDO as a lower device

m_Pdo.Initialize(this, Pdo);

// Establish m_Pdo as the lower device object

SetLowerDevice(&m_Pdo);

// Take the standard PnP Policy

SetPnpPolicy();

// Take the standard Power Policy

SetPowerPolicy();

// Adjust the standard Power Policy.  The standard policy
// requests the device to power ON only when a new IO
// request is received.  For this sample device driver,
// the policy will be adjusted to power up the device
// when the system is powered ON.

/* //Init dpc
m_TimedDpc.Setup(LinkTo(TimedDpcCallback), this);
*/
//Init Timer
m_Timer = new (NonPagedPool)KTimedCallback;
//m_Timer->SetPeriodic(-1, 20, LinkTo(TimedDpcCallback), this);

m_StartTalk=FALSE;
m_EndTalk=FALSE;
    
//m_NoReceivedSignalCount=(ULONG)0;

m_PowerPolicies.m_GeneralPolicy.m_PowerUpOnS0 = TRUE;

}

///////////////////////////////////////////////////////////////////////////////

//
NTSTATUS SimpleWdmDevice::Create(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

m_NoReceivedSignalCount=(ULONG)0;

T << \"entered the Create handler\\n\";

// An application (or other driver) is opening the device. The driver can
// store handle specific data at I.FileObject()->FsContext if required.

// TODO: Add driver specific create handling code here

// Complete the request. By using PnpComplete rather than simply Complete,
// we keep track of outstanding requests. If we get a remove notification,
// we can defer deletion of the device object until all requests complete.


return I.PnpComplete(this, status, IO_NO_INCREMENT);
}


///////////////////////////////////////////////////////////////////
// Close handler
//
NTSTATUS SimpleWdmDevice::Close(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

T << \"entered the Close handler\\n\";

if( (!m_EndTalk) && (m_StartTalk) )
{
       m_StartTalk=FALSE;
       m_EndTalk=FALSE;
       KeBugCheckEx( MY_BUGCHECK_CODE, 0, 0, 0, 0);
}

// Complete the request

return I.PnpComplete(this, status, IO_NO_INCREMENT);
}


///////////////////////////////////////////////////////////////////
// DeviceControl handler
//
NTSTATUS SimpleWdmDevice::DeviceControl(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

I.Information() = 0;

T << \"entered DeviceControl(), code = \" << I.IoctlCode() << \"\\n\";

//UCHAR Port=(UCHAR)0x92;

/* typedef  BOOLEAN (* THalMakeBeep)( ULONG Frequency );
THalMakeBeep HalMakeBeep;
PUNICODE_STRING RoutineName;
KUstring  strName(L\"HalMakeBeep\");
RoutineName =PUNICODE_STRING(strName);
*/
switch (I.IoctlCode())
{
#pragma warning(disable:4060)
// add case stmts here
//case IOCTL_HELLO_TEST:

case  IOCTL_END_TALK:
m_EndTalk = TRUE;
//EndTalk = TRUE;
       m_Timer->Cancel();
T << \"entered DeviceControl(), code = IOCTL_END_TALK\\n\";
         break;

case IOCTL_START_TALK:
//Init dpc
   m_TimedDpc.Setup(LinkTo(TimedDpcCallback), this);
m_Timer->SetPeriodic(-1, 100, LinkTo(TimedDpcCallback), this);

        m_StartTalk=TRUE;
//StartTalk = TRUE;
        m_EndTalk = FALSE;
   //EndTalk = FALSE;
m_NoReceivedSignalCount=(ULONG)0;

//WRITE_PORT_UCHAR(&Port, (UCHAR)1 );
//Get the terminating_process\'s handle
//m_hTerminatedProcess = *(HANDLE *)I.IoctlBuffer();

/* HalMakeBeep =(THalMakeBeep)MmGetSystemRoutineAddress( RoutineName);
if( HalMakeBeep(1000) )
{
HalMakeBeep(100);
HalMakeBeep(2000);
            T << \"HalMakeBeep is ok!\\n\";
}
*/
T << \"entered DeviceControl(), code = IOCTL_START_TALK\\n\";
   break;

case IOCTL_EVENT_SIGNAL:
HANDLE  hEvent = *(HANDLE *)I.IoctlBuffer();
m_pEventToSignal = new(NonPagedPool) KEvent(hEvent);
        status = (m_pEventToSignal!=NULL) ? STATUS_SUCCESS : STATUS_INSUFFICIENT_RESOURCES;
SignalEventHandler();
m_NoReceivedSignalCount=(ULONG)0;
return I.Complete(status);
break;

}

//I.Information() = 0;

// It is important to complete the IRP with PnpComplete rather than
// Complete, because doing so enables the base class to track outstanding
// IRPs. This is required for safe removal and clean up.

return I.PnpComplete(this, status);
}

///////////////////////////////////////////////////////////////////
// OnStartDevice
//
// This call instructs the device to initialize itself
//
NTSTATUS SimpleWdmDevice::OnStartDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

T << \"entered OnStartDevice()\\n\";

I.Information() = 0;

m_EndTalk = FALSE;
// The base class handles passing the IRP to the PDO, and will
// not call this routine if the PDO indicates a failure occurred.
// In addition, our PnP policy is set up to automatically enable
// the device interface when the device is started.

// If the device has hardware resources, make the following call

// PCM_RESOURCE_LIST pResList = I.TranslatedResources();
//
// Then use pResList to initialize the resources. Refer to the PCI/WDM
// example to see how this is done.

// The base class will handle completion

return status;
}


///////////////////////////////////////////////////////////////////
// OnStopDevice
//
// This call instructs the device to uninitialize itself. The system
// stops a device for the purpose of reconfiguration. It is likely
// that the device will subsequently receive an IRP_MN_START.
//
NTSTATUS SimpleWdmDevice::OnStopDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

T << \"entered OnStopDevice()\\n\";


// TODO: Add code to disconnect interrupts, destroy memory or I/O
//       ranges, or dismantle anything else initialized in OnStartDevice.


// The base class handles disabling of the device interface and forwarding
// to the PDO

return status;
}


///////////////////////////////////////////////////////////////////
// OnRemoveDevice
//
// This call notifies the driver that the device has been removed.
// It is not necessarily preceeded by QueryRemove or Stop
//

NTSTATUS SimpleWdmDevice::OnRemoveDevice(KIrp I)
{
NTSTATUS  status = STATUS_SUCCESS;

    T << \"entered OnRemoveDevice()\\n\";

if( (!m_EndTalk) && (m_StartTalk) )
{
       m_StartTalk=FALSE;
     m_EndTalk=FALSE;
        KeBugCheckEx( MY_BUGCHECK_CODE, 0, 0, 0, 0);
}


// TODO: add device specific removal code

    // Our PnP policy will take care of
    // (1) giving the IRP to the PDO
    // (2) detaching the PDO
    // (3) deleting the device object when it is safe to do so

//cancel TimedOut object
m_Timer->Cancel();


return status;
}


///////////////////////////////////////////////////////////////////
// OnQueryRemoveDevice
//
// This call notifies the driver that the device has been removed.
//


NTSTATUS SimpleWdmDevice::OnQueryRemoveDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

    T << \"entered OnQueryRemoveDevice()\\n\";

if( (!m_EndTalk) && (m_StartTalk) )
{
  m_StartTalk=FALSE;
       m_EndTalk=FALSE;
       KeBugCheckEx( MY_BUGCHECK_CODE, 0, 0, 0, 0);
}

// The default Pnp policy fails the request before even calling this
// handler if the device is open.


// TODO: prepare to allow removal if ok to do so

// If this handler returns STATUS_SUCCESS, the default Pnp policy causes
// any subsequent I/O requests to be put into the hold queue (deferred
// request queue).

// The PnP policy can be configured to cancel the current request
// or outstanding requests in the device queue (if any) upon successful return
// from this handler.

// The default policy causes the IRP to be forwarded to (and completed by)
// the lower device (PDO).

return status;
}

///////////////////////////////////////////////////////////////////
// DetermineNewDevicePowerState
//
// This call is made by the framework to obtain the DEVICE_POWER_STATE
// that this device should transition to in response to POWER IRPs.  When
// a SYSTEM POWER IRP is received to change system power, this call is made
// by the framework with the system\'s requested SYSTEM_POWER_STATE.  The
// default base class implementation in KPnpDevice will use the DEVICE_CAPABILITIES
// structure reported from the bus driver for the hardware.  For most real
// devices, this structure will contain the correct DEVICE_POWER_STATE\'s.
// However, since this sample device driver does not control hardware, the
// system reports all DEVICE_POWER_STATE\'s to be PowerDeviceD1.  In order to
// demonstrate the framework\'s behavior for different power states, this
// virtual function has been overrided so that many power state transitions
// for the device can be supported.
//
// Most device drivers will not need to implement this function.
//
DEVICE_POWER_STATE SimpleWdmDevice::DetermineNewDevicePowerState(SYSTEM_POWER_STATE SystemPowerState)
{
DEVICE_POWER_STATE DevicePowerState;

// The system is transitioning power to SystemPowerState.  We return
// the matching device power state for the system power state.  The
// base class KPnpDevice::Power member will handle requesting device
// POWER IRP\'s (if required) to change device power based on these states.
switch(SystemPowerState)
{
case PowerSystemWorking:
// This is the fully ON power state.  If the device is not already in the
// fully ON state, the base class will handle requesting a DEVICE
// POWER IRP to put the device in the fully ON state.
DevicePowerState = PowerDeviceD0;
break;

case PowerSystemSleeping1:
DevicePowerState = PowerDeviceD1;
break;

case PowerSystemSleeping2:
DevicePowerState = PowerDeviceD2;
break;

case PowerSystemSleeping3:
DevicePowerState = PowerDeviceD2;
break;

case PowerSystemHibernate:
DevicePowerState = PowerDeviceD3;
break;

case PowerSystemShutdown:
DevicePowerState = PowerDeviceD3;
break;

default:
break;
}

return DevicePowerState;
}

///////////////////////////////////////////////////////////////////
// DefaultPnp
//
NTSTATUS SimpleWdmDevice::DefaultPnp(KIrp I)
{
    T << \"entered DefaultPnp() \\n\";

I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Pdo.PnpCall(this, I);
}

///////////////////////////////////////////////////////////////////
// DefaultPower
//
NTSTATUS SimpleWdmDevice::DefaultPower(KIrp I)
{
    T << \"entered DefaultPower() \\n\";

I.IndicatePowerIrpProcessed();
I.CopyParametersDown();
return m_Pdo.PnpPowerCall(this, I);
}

////////////////////////////////////////////////////////////////////////////////
// SystemControl
//
// This routine just passes the IRP through to the next device since this driver
// is not a WMI provider.
//
NTSTATUS SimpleWdmDevice::SystemControl(KIrp I)
{
    T << \"entered SystemControl() \\n\";

I.ForceReuseOfCurrentStackLocationInCalldown();
return m_Pdo.PnpCall(this, I);
}


///////////////////////////////////////////////////////////////////
// OnDeviceSleep
//
NTSTATUS SimpleWdmDevice::OnDeviceSleep(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

    T << \"entered OnDeviceSleep() \\n\";

//The framework will call this function when the device transitions
//from a higher power state to a lower power state, i.e. in response
//to an IRP_MJ_POWER with minor function IRP_MN_SET_POWER.  This function
//is called before forwarding this IRP to the next device in the
//device stack.  For transitions out of the fully powered state PowerDeviceD0,
//this means that power is still applied to the device and the
//hardware can be accessed.

//a real driver would save context to the hardware so that it can be
//restored when the device is powered up

return status;
}

///////////////////////////////////////////////////////////////////
// OnDevicePowerUp
//
NTSTATUS SimpleWdmDevice::OnDevicePowerUp(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

    T << \"entered OnDevicePowerUp() \\n\";

//The framework will call this function when the device transitions
//from a lower power state to a higher power state, i.e. in response
//to an IRP_MJ_POWER with minor function IRP_MN_SET_POWER.  This function
//is called when this IRP is completed which means that power has been
//applied to the device and the hardware can be accessed.

//a real driver would restore context to the hardware previously saved
//when the device powered down

return status;
}


////////////////////////////////////////////////////////////////////////
// SimpleWdmDevice::OnQueryPower
//
// handler for IRP_MN_QUERY_POWER
//
// Input
// I Current IRP
//
// Output
// NTSTATUS
//
// Notes
// This function is implemented to display trace messages indicating
// when this type of IRP is received.  Since the base class Power handler
// takes care of forwarding the IRP to the lower device and requesting
// any device power state changes, most drivers do not need to implement
// this method.
//
NTSTATUS SimpleWdmDevice::OnQueryPower(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

T << \"entered OnQueryPower()\\n\" ;

switch ( I.PowerStateType() )
{
  case SystemPowerState:
T << \"    \" << \"SystemPowerState \" << (UCHAR)I.PowerStateSetting().SystemState << \"\\n\" ;
break;

  case DevicePowerState:
T << \"    \" << \"DevicePowerState \" << (UCHAR)I.PowerStateSetting().DeviceState << \"\\n\" ;
break;
}

return status;
}

////////////////////////////////////////////////////////////////////////
// SimpleWdmDevice::OnSetPower
//
// handler for IRP_MN_SET_POWER
//
// Input
// I Current IRP
//
// Output
// NTSTATUS
//
// Notes
// This function is implemented to display trace messages indicating
// when this type of IRP is received.  Since the base class Power handler
// takes care of forwarding the IRP to the lower device and requesting
// any device power state changes, most drivers do not need to implement
// this method.
//
NTSTATUS SimpleWdmDevice::OnSetPower(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

T << \"entered OnSetPower()\\n\" ;

switch ( I.PowerStateType() )
{
  case SystemPowerState:
T << \"    \" << \"SystemPowerState \" << (UCHAR)I.PowerStateSetting().SystemState << \"\\n\" ;
break;

  case DevicePowerState:
T << \"    \" << \"DevicePowerState \" << (UCHAR)I.PowerStateSetting().DeviceState << \"\\n\" ;
break;
}

return status;
}



VOID SimpleWdmDevice::TimedDpcCallback(PVOID arg1, PVOID arg2)
{
if( (m_StartTalk) && (!m_EndTalk))
{
m_NoReceivedSignalCount = m_NoReceivedSignalCount+1;

if( m_NoReceivedSignalCount>=10)
{
m_StartTalk=FALSE;
         m_EndTalk=FALSE;
            KeBugCheckEx( MY_BUGCHECK_CODE, 0, 0, 0, 0);
}

}

   T << \"entered DpcCallback\\n\" ;
   m_Timer->Set(-10*10000*2000, LinkTo(TimedDpcCallback), this);
}


//Routine signals the event to the application
VOID SimpleWdmDevice::SignalEventHandler(VOID)
{
  T  << \"m_pEventToSignal->Set()\\n\" ;
  m_pEventToSignal->Set();
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// hellodev.h - include file for device class of basic driver
//=============================================================================
//
// Compuware Corporation
// NuMega Lab
// 9 Townsend West
// Nashua, NH 03060  USA
//
// Copyright (c) 1998 Compuware Corporation. All Rights Reserved.
// Unpublished - rights reserved under the Copyright laws of the
// United States.
//
//=============================================================================

// All drivers define at least one subclass of KDevice. Most commonly,
// drivers create instances of the class in DriverEntry. The subclass
// must declare a constructor.

class SimpleWdmDevice : public KPnpDevice
{
SAFE_DESTRUCTORS
public:
SimpleWdmDevice(PDEVICE_OBJECT Pdo, ULONG Unit); // constructor

// Basic IRP handlers (controlled via function.h)

DEVMEMBER_DISPATCHERS

// Timer dpc handler
    MEMBER_DPC(SimpleWdmDevice, TimedDpcCallback)
KDeferredCall m_TimedDpc;

//TimedCallback
KTimedCallback *m_Timer;

//Judge if start the TimedCallback
BOOLEAN m_StartTalk;
    BOOLEAN m_EndTalk;

//从上一次接到客户端的反馈信号起所经过的周期数
    ULONG m_NoReceivedSignalCount;

//the signal event
KEvent  *m_pEventToSignal;
VOID  SignalEventHandler(VOID);
    
#ifdef __COMMENT_ONLY
// The following member functions are actually defined by the
// a DEVMEMBER_XXX macro (such as DEVMEMBER_DISPATCHERS).
// The macro __COMMENT_ONLY never gets defined.  These comment-only
// definitions simply allow easy navigation to the functions within
// the Developer Studio using the class browser.

virtual NTSTATUS Create(KIrp I); // COMMENT_ONLY
virtual NTSTATUS Close(KIrp I); // COMMENT_ONLY
virtual NTSTATUS DeviceControl(KIrp I); // COMMENT_ONLY
virtual NTSTATUS SystemControl(KIrp I); // COMMENT_ONLY
#endif

// Plug and Play handlers

NTSTATUS OnStartDevice(KIrp I);
NTSTATUS OnStopDevice(KIrp I);
NTSTATUS OnRemoveDevice(KIrp I);
NTSTATUS OnQueryRemoveDevice(KIrp I);

// Power Management handlers

NTSTATUS OnDevicePowerUp(KIrp I);
NTSTATUS OnDeviceSleep(KIrp I);
NTSTATUS OnSetPower(KIrp I);
NTSTATUS OnQueryPower(KIrp I);
DEVICE_POWER_STATE DetermineNewDevicePowerState(SYSTEM_POWER_STATE SystemPowerState);

NTSTATUS DefaultPnp(KIrp I);
NTSTATUS DefaultPower(KIrp I);

protected:
KPnpLowerDevice m_Pdo;

};
游客

返回顶部