阅读:1236回复:3
WDM的问题
我最近在看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 .我不知道它们有什么区别? |
|
|
沙发#
发布于:2004-05-28 13:03
不会你这样问问题吧!除非都看过那个程序。你最好吧程序附上。否则^_^
|
|
板凳#
发布于: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 和应用程序通讯有什么区别? |
|
|
地板#
发布于:2004-05-29 11:03
SerialRead上将所有Read序列化(排队)后的处理
在Read中有,return m_DriverManagedQueue.QueueIrp(I); 他实际是将Read进入队列中 |
|
|