liyousen701118
驱动牛犊
驱动牛犊
  • 注册日期2003-12-09
  • 最后登录2013-05-30
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1236回复:3

WDM的问题

楼主#
更多 发布于:2004-05-28 11:03
我最近在看WDM武安河的书.和看了杨全胜写的驱动程序编写方法.我的问题是:
DEVMEMBER_DISPATCHERS
virtual NTSTATUS OnStartDevice(KIrp I);
virtual NTSTATUS OnStopDevice(KIrp I);
virtual NTSTATUS OnRemoveDevice(KIrp I);
virtual NTSTATUS DefaultPnp(KIrp I);
virtual NTSTATUS DefaultPower(KIrp I);
virtual NTSTATUS OnDevicePowerUp(KIrp I);
virtual NTSTATUS OnDeviceSleep(KIrp I);
void SerialRead(KIrp I);
void SerialWrite(KIrp I);
NTSTATUS SAMPLE_IOCTL_read_Handler(KIrp I);
NTSTATUS SAMPLE_IOCTL_write_Handler(KIrp I);
NTSTATUS SAMPLE_IOCTL_readwrite_Handler(KIrp I);

#ifdef _COMMENT_ONLY

// The following member functions are actually defined by the
// a DEVMEMBER_xxx or MEMBER_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 CleanUp(KIrp I); // COMMENT_ONLY
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
virtual NTSTATUS Read(KIrp I); // COMMENT_ONLY
virtual NTSTATUS Write(KIrp I);
一:我发现在sampledevice.cpp中读和写在serial read(kip i)中修改.而同时在SERIAL READ()后面也有一个NTSTAUS sampledevice::read(kirp i) 却不用改动.请问这是为什么?
二.和应用程序通讯,根据DW设定用READ WRITE 和CONTROLIO .我不知道它们有什么区别?
什么也不懂
zyyz1100
驱动牛犊
驱动牛犊
  • 注册日期2003-01-11
  • 最后登录2009-10-12
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望12点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-05-28 13:03
不会你这样问问题吧!除非都看过那个程序。你最好吧程序附上。否则^_^
liyousen701118
驱动牛犊
驱动牛犊
  • 注册日期2003-12-09
  • 最后登录2013-05-30
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-05-28 14:43
好!我将所有程序附上:
5##################################################
// SampleDevice.cpp
// Implementation of SampleDevice device class
//
// Generated by DriverWizard version DriverStudio 2.7.0 (Build 562)
// Requires Compuware\'s DriverWorks classes
//

#pragma warning(disable:4065) // Allow switch statement with no cases
 
#include <vdw.h>
#include \"..\\SampleDeviceinterface.h\"

#include \"Sample.h\"
#include \"SampleDevice.h\"
#include \"..\\sampleioctl.h\"

#pragma hdrstop(\"Sample.pch\")

extern KTrace t; // Global driver trace object

GUID SampleDevice_Guid = SampleDevice_CLASS_GUID;

////////////////////////////////////////////////////////////////////////
//  SampleDevice::SampleDevice
//
// Routine Description:
// This is the constructor for the Functional Device Object, or FDO.
// It is derived from KPnpDevice, which builds in automatic
//    dispatching of subfunctions of IRP_MJ_POWER and IRP_MJ_PNP to
// virtual member functions.
//
// Parameters:
// Pdo - Physical Device Object - this is a pointer to a system
// device object that represents the physical device.
//
// Unit - Unit number. This is a number to append to the device\'s
// base device name to form the Logical Device Object\'s name
//
// Return Value:
// None  
//
// Comments:
// The object being constructed contains a data member (m_Lower) of type
// KPnpLowerDevice. By initializing it, the driver binds the FDO to the
// PDO and creates an interface to the upper edge of the system class driver.
//

SampleDevice::SampleDevice(PDEVICE_OBJECT Pdo, ULONG Unit) :
KPnpDevice(Pdo, &SampleDevice_Guid)
{
t << \"Entering SampleDevice::SampleDevice (constructor)\\n\";


// Check constructor status
    if ( ! NT_SUCCESS(m_ConstructorStatus) )
{
   return;
}

// Remember our unit number
m_Unit = Unit;

// Initialize the lower device
m_Lower.Initialize(this, Pdo);

    // Inform the base class of the lower edge device object
SetLowerDevice(&m_Lower);

// Initialize the PnP Policy settings to the \"standard\" policy
SetPnpPolicy();

// TODO: Customize the PnP Policy for this device by setting
// flags in m_Policies.

// Initialize the Power Policy settings to the \"standard\" policy
SetPowerPolicy();

// TODO: Customize the Power Policy for this device by setting
// flags in m_PowerPolicies.

}


////////////////////////////////////////////////////////////////////////
//  SampleDevice::~SampleDevice
//
// Routine Description:
// This is the destructor for the Functional Device Object, or FDO.
//
// Parameters:
// None
//
// Return Value:
// None
//
// Comments:
// None
//

SampleDevice::~SampleDevice()
{
t << \"Entering SampleDevice::~SampleDevice() (destructor)\\n\";
}

////////////////////////////////////////////////////////////////////////
//  PNPMinorFunctionName
//
// Routine Description:
// Return a string describing the Plug and Play minor function
//
// Parameters:
// mn - Minor function code
//
// Return Value:
// char * - Ascii name of minor function
//
// Comments:
// This function is used for tracing the IRPs.  Remove the function,
// or conditionalize it for debug-only builds, if you want to save
// space in the driver image.
//

char *PNPMinorFunctionName(ULONG mn)
{
static char* minors[] = {
\"IRP_MN_START_DEVICE\",
\"IRP_MN_QUERY_REMOVE_DEVICE\",
\"IRP_MN_REMOVE_DEVICE\",
\"IRP_MN_CANCEL_REMOVE_DEVICE\",
\"IRP_MN_STOP_DEVICE\",
\"IRP_MN_QUERY_STOP_DEVICE\",
\"IRP_MN_CANCEL_STOP_DEVICE\",
\"IRP_MN_QUERY_DEVICE_RELATIONS\",
\"IRP_MN_QUERY_INTERFACE\",
\"IRP_MN_QUERY_CAPABILITIES\",
\"IRP_MN_QUERY_RESOURCES\",
\"IRP_MN_QUERY_RESOURCE_REQUIREMENTS\",
\"IRP_MN_QUERY_DEVICE_TEXT\",
\"IRP_MN_FILTER_RESOURCE_REQUIREMENTS\",
\"<unknown minor function>\",
\"IRP_MN_READ_CONFIG\",
\"IRP_MN_WRITE_CONFIG\",
\"IRP_MN_EJECT\",
\"IRP_MN_SET_LOCK\",
\"IRP_MN_QUERY_ID\",
\"IRP_MN_QUERY_PNP_DEVICE_STATE\",
\"IRP_MN_QUERY_BUS_INFORMATION\",
\"IRP_MN_DEVICE_USAGE_NOTIFICATION\",
\"IRP_MN_SURPRISE_REMOVAL\",
\"IRP_MN_QUERY_LEGACY_BUS_INFORMATION\"
};

if (mn > 0x18) // IRP_MN_QUERY_LEGACY_BUS_INFORMATION
return \"<unknown minor function>\";
else
return minors[mn];
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::DefaultPnp
//
// Routine Description:
// Default handler for IRP_MJ_PNP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_PNP. IRPs that correspond to
// any virtual members of KpnpDevice that handle minor functions of
// IRP_MJ_PNP and that are not overridden get passed to this routine.
//

NTSTATUS SampleDevice::DefaultPnp(KIrp I)
{
t << \"Entering SampleDevice::DefaultPnp with IRP minor function=\"
 << PNPMinorFunctionName(I.MinorFunction()) << EOL;

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


////////////////////////////////////////////////////////////////////////
//  SampleDevice::DefaultPower
//
// Routine Description:
// Default handler for IRP_MJ_POWER
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the lower device. It is
// the default handler for IRP_MJ_POWER.
//

NTSTATUS SampleDevice::DefaultPower(KIrp I)
{
t << \"Entering SampleDevice::DefaultPower\\n\";

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

////////////////////////////////////////////////////////////////////////////////
//  SampleDevice::SystemControl
//
// Routine Description:
// Default handler for IRP_MJ_SYSTEM_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result returned from lower device
//
// Comments:
// This routine just passes the IRP through to the next device since this driver
// is not a WMI provider.
//

NTSTATUS SampleDevice::SystemControl(KIrp I)
{
t << \"Entering SampleDevice::SystemControl\\n\";

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

////////////////////////////////////////////////////////////////////////
//  SampleDevice::OnStartDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_START_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// Initialize the physical device. Typically, the driver initializes
// physical resources here.  Call I.AllocatedResources() for a list
// of the raw resources that the system has assigned to the device,
// or I.TranslatedResources() for the translated resource list.
//

NTSTATUS SampleDevice::OnStartDevice(KIrp I)
{
t << \"Entering SampleDevice::OnStartDevice\\n\";

NTSTATUS status = STATUS_SUCCESS;

I.Information() = 0;

// The default Pnp policy has already cleared the IRP with the lower device
// Initialize the physical device object.

// Get the list of raw resources from the IRP
PCM_RESOURCE_LIST pResListRaw = I.AllocatedResources();
// Get the list of translated resources from the IRP
PCM_RESOURCE_LIST pResListTranslated = I.TranslatedResources();

// TODO: Add device-specific code to start your device.

    // The base class will handle completion

return status;
}


////////////////////////////////////////////////////////////////////////
//  SampleDevice::OnStopDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_STOP_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is stopped.
// The driver should release any hardware resources
// in this routine.
//
// The base class passes the irp to the lower device.
//

NTSTATUS SampleDevice::OnStopDevice(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << \"Entering SampleDevice::OnStopDevice\\n\";


// TODO: Add device-specific code to stop your device  

return status;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::OnRemoveDevice
//
// Routine Description:
// Handler for IRP_MJ_PNP subfcn IRP_MN_REMOVE_DEVICE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// The system calls this when the device is removed.
// Our PnP policy will take care of
// (1) giving the IRP to the lower device
// (2) detaching the PDO
// (3) deleting the device object
//

NTSTATUS SampleDevice::OnRemoveDevice(KIrp I)
{
t << \"Entering SampleDevice::OnRemoveDevice\\n\";




// TODO: Add device-specific code to remove your device  

return STATUS_SUCCESS;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::OnDevicePowerUp
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to power on state from low power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDevicePowerUp function.
// This function was called by the framework from the completion
// routine of the IRP_MJ_POWER dispatch handler in KPnpDevice.
// The bus driver has completed the IRP and this driver can now
// access the hardware device.  
// This routine runs at dispatch level.
//

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

t << \"Entering SampleDevice::OnDevicePowerUp\\n\";

// TODO: Service the device.
// Restore any context to the hardware device that
// was saved during the handling of a power down request.
// See the OnDeviceSleep function.
// Do NOT complete this IRP.
//
return status;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::OnDeviceSleep
//
// Routine Description:
// Handler for IRP_MJ_POWER with minor function IRP_MN_SET_POWER
// for a request to go to a low power state from a high power state
//
// Parameters:
// I - IRP containing POWER request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the OnDeviceSleep function.
// This function was called by the framework from the IRP_MJ_POWER
// dispatch handler in KPnpDevice prior to forwarding to the PDO.
// The hardware has yet to be powered down and this driver can now
// access the hardware device.  
// This routine runs at passive level.
//

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

t << \"Entering SampleDevice::OnDeviceSleep\\n\";

// TODO: Service the device.
// Save any context to the hardware device that will be required
// during a power up request. See the OnDevicePowerUp function.
// Do NOT complete this IRP.  The base class handles forwarding
// this IRP to the PDO.
//
return status;

// The following macro simply allows compilation at Warning Level 4
// If you reference this parameter in the function simply remove the macro.
UNREFERENCED_PARAMETER(I);
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::Create
//
// Routine Description:
// Handler for IRP_MJ_CREATE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//

NTSTATUS SampleDevice::Create(KIrp I)
{
NTSTATUS status;

t << \"Entering SampleDevice::Create, \" << I << EOL;

// TODO: Add driver specific create handling code here

// Generally a create IRP is targeted at our FDO, so we don\'t need
// to pass it down to the PDO.  We have found for some devices, the
// PDO is not expecting this Irp and returns an error code.
// The default wizard code, therefore completes the Irp here using
// PnpComplete().  The following commented code could be used instead
// of PnpComplete() to pass the Irp to the PDO, which would complete it.
//
// I.ForceReuseOfCurrentStackLocationInCalldown();
// status = m_Lower.PnpCall(this, I);

status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

t << \"SampleDevice::Create Status \" << (ULONG)status << EOL;

return status;
}


////////////////////////////////////////////////////////////////////////
//  SampleDevice::Close
//
// Routine Description:
// Handler for IRP_MJ_CLOSE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//

NTSTATUS SampleDevice::Close(KIrp I)
{
NTSTATUS status;

t << \"Entering SampleDevice::Close, \" << I << EOL;

// TODO: Add driver specific close handling code here

// Generally a close IRP is targeted at our FDO, so we don\'t need
// to pass it down to the PDO.  We have found for some devices, the
// PDO is not expecting this Irp and returns an error code.
// The default wizard code, therefore completes the Irp here using
// PnpComplete().  The following commented code could be used instead
// of PnpComplete() to pass the Irp to the PDO, which would complete it.
//
// I.ForceReuseOfCurrentStackLocationInCalldown();
// status = m_Lower.PnpCall(this, I);

status = I.PnpComplete(this, STATUS_SUCCESS, IO_NO_INCREMENT);

t << \"SampleDevice::Close Status \" << (ULONG)status << EOL;

    return status;
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::Cleanup
//
// Routine Description:
// Handler for IRP_MJ_CLEANUP
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
//

NTSTATUS SampleDevice::CleanUp(KIrp I)
{
t << \"Entering CleanUp, \" << I << EOL;

// TODO: Insert your code to respond to the CLEANUP message.
// This code cleans up the single Wizard created queue.  If you
// have created additional queues, or have any outstanding Irps
// stored in some other fashion in your driver, you should clean
// these up as well for the file object specified in the cleanup Irp.

m_DriverManagedQueue.PnpCleanUp(this, I.FileObject());
return I.PnpComplete(this, STATUS_SUCCESS);
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::SerialRead
//
// Routine Description:
// Handler for serialized READ
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is called when the IRP is removed from the
// STARTIO queue.  This guarantees that multiple requests are
// never processed simultaneously.
//
// This routine is called at dispatch level.
//

void SampleDevice::SerialRead(KIrp I)
{
t << \"Entering SampleDevice::SerialRead, \" << I << EOL;
NTSTATUS status = STATUS_SUCCESS;

PUCHAR pBuffer = (PUCHAR) I.BufferedReadDest();

ULONG   dwTotalSize = I.ReadSize(CURRENT); // Requested read size
//----------------------------------------------------
char buff[512];
int n =512,  j = (n % 26);
for (int i=0; i<n; i++, j=(j + 1)%26)
{ buff = \'a\' + j; }
buff[dwTotalSize]=\'\\0\';    //指定串尾
strcpy((char *)pBuffer,buff);
// 把给应用程序的数据拷贝给返回BUFF
t << \"The string you where read is \\\"\" << buff << \"\\\"\" << EOL;  // 输出调试信息
ULONG   dwBytesRead = strlen(buff); // Count of bytes read  
I.Information() = dwBytesRead;                //  返回给应用程序的信息的字节个数
//---------------------------------------------------------------
// TODO: If the read can be satisfied immediately, set the Information
// and Status fields now, then call NextIrp to complete this IRP
// and start processing the next IRP in the queue.

// TODO: If the data is not yet available, initiate a request to the
// physical device here, and defer the Information, Status,
// and NextIrp handling until the hardware indicates that the
// read is complete.  Typically, this might be handled in a
// DPC that is called after the hardware finishes transferring
// the data.

// TODO: To satisfy the read now, transfer data from the device to
// caller\'s buffer at \"pBuffer\".  Then, indicate how much data was
// transferred:

//I.Information() = dwBytesRead;

I.Status() = status;


// PnpNextIrp completes this IRP and starts processing
// for the next IRP in the driver managed queue.
// TODO: The Wizard creates a single queue for all Irps.
// If you have created additional queues, select
// the appropriate queue for this Irp here.
m_DriverManagedQueue.PnpNextIrp(I);
}


////////////////////////////////////////////////////////////////////////
//  SampleDevice::Read
//
// Routine Description:
// Handler for IRP_MJ_READ
//
// Parameters:
// I Current IRP
//
// Return Value:
// NTSTATUS Result code
//
// Comments:
// This routine handles read requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//

NTSTATUS SampleDevice::Read(KIrp I)
{
t << \"Entering SampleDevice::Read, \" << I << EOL;
// TODO: Check the incoming request.  Replace \"FALSE\" in the following
// line with a check that returns TRUE if the request is not valid.

    if (FALSE) // If (Request is invalid)
{
// Invalid parameter in the Read request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}

// Always ok to read 0 elements.
if (I.ReadSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}

// Queue the IRP for processing in the driver managed queue.
// The actual read function is performed in SerialRead
// TODO: The Wizard creates a single queue for all Irps.
// If you have created additional queues, select
// the appropriate queue for this Irp here.
return m_DriverManagedQueue.QueueIrp(I);
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::SerialWrite
//
// Routine Description:
// Handler for serialized WRITE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is called when the IRP is removed from the
// STARTIO queue.  This guarantees that multiple requests are
// never processed simultaneously.
//

void SampleDevice::SerialWrite(KIrp I)
{
t << \"Entering SampleDevice::SerialWrite, \" << I << EOL;
NTSTATUS status = STATUS_SUCCESS;

PUCHAR pBuffer = (PUCHAR)I.BufferedWriteSource();

ULONG   dwTotalSize = I.WriteSize(CURRENT);
// ULONG   dwBytesSent = 0;
//------------------------------------------ULONG   dwBytesSent = dwTotalSize;
ULONG   dwBytesSent = dwTotalSize;
char buff[512];
strcpy(buff, (char *)pBuffer); // 应用程序写给驱动程序的数据在I.BufferedWriteSource()返回的指针中。
// buff[dwBytesSent] = \'\\0\';
t << \"Write to driver is \\\"\" << buff << \"\\\"\" << EOL;
I.Information() = dwBytesSent; // 返回用户实际写的字节数



//-------------------------------------------

// TODO: If the write can be satisfied immediately, set the Information
// and Status fields now, then call NextIrp to complete this IRP
// and start processing the next IRP in the queue.

// TODO: If the device cannot accept all of the data yet, initiate a
// request to the physical device here, and defer the Information,
// Status, and NextIrp handling until the hardware indicates that
// the write is complete.  Typically, this might be handled in a
// DPC that is called after the hardware finishes transferring
// the data.

// TODO: To satisfy the write now, transfer data to the device
// from caller\'s buffer at \"pBuffer\".  Then, indicate how much
// data was transferred:

//I.Information() = dwBytesSent;

I.Status() = status;


// PnpNextIrp completes this IRP and starts processing
// for the next IRP in the driver managed queue.
// TODO: The Wizard creates a single queue for all Irps.
// If you have created additional queues, select
// the appropriate queue for this Irp here.
m_DriverManagedQueue.PnpNextIrp(I);
}


////////////////////////////////////////////////////////////////////////
//  SampleDevice::Write
//
// Routine Description:
// Handler for IRP_MJ_WRITE
//
// Parameters:
// I - Current IRP
//
// Return Value:
// NTSTATUS - Result code
//
// Comments:
// This routine handles write requests.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//

NTSTATUS SampleDevice::Write(KIrp I)
{
t << \"Entering SampleDevice::Write, \" << I << EOL;
// TODO: Check the incoming request.  Replace \"FALSE\" in the following
// line with a check that returns TRUE if the request is not valid.
    if (FALSE)
{
// Invalid parameter in the Write request
I.Information() = 0;
return I.PnpComplete(this, STATUS_INVALID_PARAMETER);
}

// Always ok to write 0 elements.
if (I.WriteSize() == 0)
{
I.Information() = 0;
return I.PnpComplete(this, STATUS_SUCCESS);
}

// Queue the IRP for processing in the driver managed queue.
// The actual write function is performed in SerialWrite

// TODO: The Wizard creates a single queue for all Irps.
// If you have created additional queues, select
// the appropriate queue for this Irp here.
return m_DriverManagedQueue.QueueIrp(I);
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::DeviceControl
//
// Routine Description:
// Handler for IRP_MJ_DEVICE_CONTROL
//
// Parameters:
// I - Current IRP
//
// Return Value:
// None
//
// Comments:
// This routine is the first handler for Device Control requests.
// Some function codes may be handled immediately,
// while others may be serialized through the StartIo routine.
//
// The KPnpDevice class handles restricting IRP flow
// if the device is stopping or being removed.
//

NTSTATUS SampleDevice::DeviceControl(KIrp I)
{
NTSTATUS status;

t << \"Entering SampleDevice::Device Control, \" << I << EOL;
switch (I.IoctlCode())
{
case SAMPLE_IOCTL_read:
status = SAMPLE_IOCTL_read_Handler(I);
break;

case SAMPLE_IOCTL_write:
status = SAMPLE_IOCTL_write_Handler(I);
break;

case SAMPLE_IOCTL_readwrite:
status = SAMPLE_IOCTL_readwrite_Handler(I);
break;

default:
// Unrecognized IOCTL request
status = STATUS_INVALID_PARAMETER;
break;
}

// If the IRP was queued, or its IOCTL handler deferred processing using some
// driver specific scheme, the status variable is set to STATUS_PENDING.
// In this case we simply return that status, and the IRP will be completed
// later.  Otherwise, complete the IRP using the status returned by the
// IOCTL handler.
if (status == STATUS_PENDING)
{
return status;
}
else
{
return I.PnpComplete(this, status);
}
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::SAMPLE_IOCTL_read_Handler
//
// Routine Description:
// Handler for IO Control Code SAMPLE_IOCTL_read
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the SAMPLE_IOCTL_read function.
// This routine runs at passive level.
//

NTSTATUS SampleDevice::SAMPLE_IOCTL_read_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << \"Entering SampleDevice::SAMPLE_IOCTL_read_Handler, \" << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER

// TODO: Handle the the SAMPLE_IOCTL_read request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.

// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
// I.Information() = 0;
//-----------------------------------------------------
char buff1[512];
ULONG fwLength=0;
strcpy(buff1,\"Welcome to driver!\");
fwLength = strlen(buff1)+1;
if (I.IoctlOutputBufferSize() >= fwLength) {// 如果读入缓冲够长
strcpy((PCHAR)I.IoctlBuffer(),buff1); // 将信息拷给应用程序读入缓冲
I.Information() = fwLength; // 返回信息长度
}
else {
I.Information() = 0; // 否则信息长度为0
         t << \"buff size too small\" << EOL;
}

//-----------------------------------


return status;
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::SAMPLE_IOCTL_write_Handler
//
// Routine Description:
// Handler for IO Control Code SAMPLE_IOCTL_write
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the SAMPLE_IOCTL_write function.
// This routine runs at passive level.
//

NTSTATUS SampleDevice::SAMPLE_IOCTL_write_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << \"Entering SampleDevice::SAMPLE_IOCTL_write_Handler, \" << I << EOL;
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER

// TODO: Handle the the SAMPLE_IOCTL_write request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.

// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
// I.Information() = 0;
//-----------------------------------
char buff[512];
ULONG fwLength=0;
strcpy(buff,(PCHAR)I.IoctlBuffer()); // 拷贝从应用程序得到的命令串到驱动程序局部数据区
t << \"InputPut Data is \\\"\" << buff << \"\\\"\" <<EOL; // 显示从应用程序得到的命令串。

//------------------------------------
   I.Information() = 0;
return status;
}

////////////////////////////////////////////////////////////////////////
//  SampleDevice::SAMPLE_IOCTL_readwrite_Handler
//
// Routine Description:
// Handler for IO Control Code SAMPLE_IOCTL_readwrite
//
// Parameters:
// I - IRP containing IOCTL request
//
// Return Value:
// NTSTATUS - Status code indicating success or failure
//
// Comments:
// This routine implements the SAMPLE_IOCTL_readwrite function.
// This routine runs at passive level.
//

NTSTATUS SampleDevice::SAMPLE_IOCTL_readwrite_Handler(KIrp I)
{
NTSTATUS status = STATUS_SUCCESS;

t << \"Entering SampleDevice::SAMPLE_IOCTL_readwrite_Handler, \" << I << EOL;
//---------------+++++++++++++++++
char buff[512],buff1[512];
ULONG fwLength=0;
strcpy(buff,(PCHAR)I.IoctlBuffer());// 拷贝应用程序来的信息
t << \"InputPut Data is \\\"\" << buff << \"\\\"\" <<EOL;
strcpy(buff1,\"this is feedback from driver! Application give me this string \\\"\");
strcat(buff1,buff);
strcat(buff1,\"\\\"\"); // 以上是组织反馈的信息

fwLength = strlen(buff1)+1;
if (I.IoctlOutputBufferSize() >= fwLength)
{
strcpy((PCHAR)I.IoctlBuffer(),buff1);// 拷贝反馈信息
I.Information() = fwLength; // 设置反馈信息字节数
}
else
{
I.Information() = 0;
t << \"buff size too small\" << EOL;
}

//---------------------------
// TODO: Verify that the input parameters are correct
// If not, return STATUS_INVALID_PARAMETER

// TODO: Handle the the SAMPLE_IOCTL_readwrite request, or
// defer the processing of the IRP (i.e. by queuing) and set
// status to STATUS_PENDING.

// TODO: Assuming that the request was handled here. Set I.Information
// to indicate how much data to copy back to the user.
// I.Information() = 0;

return status;
}

////////////////////////////////////////////////////////////////////////////////
//  SampleDevice_DriverManagedQueue::StartIo
//
// Routine Description:
// This routine is called when an IRP is taken off
// the Driver Managed Queue (used for serializing I/O) and
// presented for processing.
//
// Parameters:
// I - IRP removed from queue
//
// Return Value:
// None
//
// Comments:
//

VOID SampleDevice_DriverManagedQueue::StartIo(KIrp I)
{
t  << \"Entering SampleDevice_DriverManagedQueue StartIo, \" << I;

// The KDriverManagedQueueEx class gives us the Irp in a non-cancelable state
// (cancel routine set to NULL) so we can process it without having to worry
// about clearing the cancel routine first, as is the case with system queuing,
// or the legacy class KDriverManagedQueue. You may want to set a different cancel
// routine here, or at other points during the processing of this Irp.

// Find the device class so we can call the serialized
// routines in the device class.  The handlers can be
// moved to the DriverManagedQueue class if it is more
// convenient.
SampleDevice *pDev = (SampleDevice *) KDevicePTR(I.DeviceObject());

// Start processing request.

// Switch on the IRP\'s function:
switch (I.MajorFunction())
{
case IRP_MJ_READ:
pDev->SerialRead(I);
break;

case IRP_MJ_WRITE:
pDev->SerialWrite(I);
break;

case IRP_MJ_DEVICE_CONTROL:
switch (I.IoctlCode())
{
default:
// We queued a request that shouldn\'t have been queued
// (should never get here)
ASSERT(FALSE);
break;
}
break;

default:
// Error - unexpected IRP received
// NextIrp completes this IRP and starts processing
// for the next IRP in the queue.
ASSERT(FALSE);
I.Status() = STATUS_INVALID_PARAMETER;
PnpNextIrp(I);
break;
}
}


我的问题是上面为什么在SERIAL READ(WRITE)中修改.而不在下面::READ()中,为什么?
另一个问题是READ(WRITE)和CONTROLIO 和应用程序通讯有什么区别?
什么也不懂
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-05-29 11:03
SerialRead上将所有Read序列化(排队)后的处理
在Read中有,return m_DriverManagedQueue.QueueIrp(I);
他实际是将Read进入队列中
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
游客

返回顶部