Programming 版 (精华区)
发信人: zpw (zhao), 信区: Programming
标 题: Using IOXTL METHOD_NEITHER
发信站: 紫 丁 香 (Wed Jul 29 20:59:37 1998), 转信
Using IOCTL METHOD_NEITHER
If you read our earlier tip on METHOD_IN/OUT_DIRECT, you may have been left
wondering about the details of the other IOCTL methods, METHOD_BUFFERED, and
METHOD_NEITHER. This tip explores the latter, lesser known of the two,
METHOD_NEITHER.
If an IOCTL code passed to DeviceIoControl is defined using METHOD_NEITHER, the
operating system performs no address translation or validation of pointers
passed in parameters InputBuffer and OutputBuffer. Because there is relatively
less work for the system to do, it can deliver an IRP that uses METHOD_NEITHER
to a driver faster than it can IRPs that use the other two IOCTL methods.
However, the burden is now on the driver to ensure that the pointers passed to
it are valid. In addition, the driver can use the raw pointers only in the
context of the calling process.
As shown in the diagram, the pointer passed as parameter InputBuffer appears in
field
IoGetCurrentIrpStackLocation(pIrp)->Parameters.DeviceIoControl.Type3InputBuffer.
The pointer passed as parameter OutputBuffer appears in pIrp-> UserBuffer.
Because the operating system has not validated the pointers passed to a driver
in a METHOD_NEITHER IRP, it is crucial to guard against exceptions that could
result from accessing these pointers. A driver can easily trap an exception
that results from dereferencing a bad pointer by bracketing access to the
pointer in a _try/_except block. Here is some Driver::Works code that
illustrates the basic idea:
NTSTATUS MyDevice::DeviceControl(KIrp I)
{
switch (I.IoctlCode())
{
case IOCTL_NEITHER_OPERATION:
PINPUT_DATA pInput = PINPUT_DATA(I.IoctlType3InputBuffer());
PULONG pOutput = I.UserBuffer();
_try
{
NTSTATUS status=Process(pInput, pOutput);
return I.Complete(status);
}
_except ( EXCEPTION_EXECUTE_HANDLER )
{
I.Information()=0;
return I.Complete(STATUS_ACCESS_DENIED);
}
// etc.
}
}
The other important thing to remember about pointers in a METHOD_NEITHER IRP is
that they may be used only in the context of the calling process. If your
driver serializes requests through StartIo, or ever needs to access the buffers
from an arbitrary thread context or at IRQL > PASSIVE_LEVEL, then your driver
must lock down the buffers and map them to system space. The system services
you'll need are MmCreateMdl, MmProbeAndLockPages, and MmGetSystemAddressForMdl.
In summary, METHOD_NEITHER can be useful for certain kinds of requests.
The precaution of structured exception handling (_try/_except) is required when
ever accessing pointers that have not been validated by the system. If the
driver can process the request quickly and without synchronization, then
METHOD_NEITHER provides an easy and efficient mechanism. However, most of the
time it is better to take advantage of the operating system's facilities for
buffer management, using either METHOD_IN/OUT_DIRECT, or METHOD_BUFFERED.
--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: yaoyu.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.365毫秒