Hello,
I have about 1 day’s experience with Win2K drivers so bear with me if
my question is overly trivial.
I’m trying to create something that is capable of observing all TCP/IP
traffic entering or leaving the local machine, regardless of physical
layer. I figured the best way to do this would be to write a TDI
driver. My current approach is basically as follows:
- Call ZwCreateFile() to get a handle to \device\tcp
- Call ObReferenceObjectByHandle() to get the corresponding file
object - Call IoGetRelatedDeviceObject() to get the device object
- Call TdiBuildInternalDeviceIrp() and TdiBuildSetEventHandler() to
build
an IRP to register a function that will be called by the transport
driver
when it receives something. - Call IoCallDevice() to send the IRP to the lower level.
I’m having trouble here, though, because IoCallDevice() returns
0xC0000010 (invalid device request) when I try to send the IRP. I
have no idea why this is happening; from what I can tell, I’m
adhering to the steps outlined in the DDK for accomplishing this sort
of thing. Does anybody know why this might be happening? [code is
included at the end of this message]
Also, a less specific question – is this a good approach for what I’m
trying to do? I’ve been looking at other driver source code from
various places and am wondering if I should be just using
CreateDevice() and then IoAttachDevice() to attach to the \device\tcp
chain. Assumedly, I would then be catching every request going to
\device\tcp, and I could do what I wanted with the data and then have
a dispatch routine to pass on the IRP when I was finished. Is this
possible, and if so, what are the advantages/disadvantages compared to
the first approach?
Thanks in advance,
-chris
— [start code]
HANDLE tcpip;
PVOID pfileobject;
PVOID pdeviceobject;
NTSTATUS tdidrv_ClientEventReceive (
IN PVOID TdiEventContext,
IN CONNECTION_CONTEXT ConnectionContext,
IN ULONG ReceiveFlags,
IN ULONG BytesIndicated,
IN ULONG BytesAvailable,
OUT ULONG *BytesTaken,
IN PVOID Tsdu,
OUT PIRP *IoRequestPacket
)
{
#if DEBUG
DbgPrint(“tdidrv_ClientEventReceive() got called\n”);
#endif
return STATUS_SUCCESS;
}
NTSTATUS DriverUnload(
IN PDRIVER_OBJECT DriverObject
)
{
#if DEBUG
DbgPrint(“Calling ObDereference() and ZwClose()\n”);
#endif
ObDereferenceObject(pfileobject);
ZwClose(tcpip);
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
IO_STATUS_BLOCK io_status;
OBJECT_ATTRIBUTES obj_attrib;
NTSTATUS dstatus;
OBJECT_HANDLE_INFORMATION obj_handle_info;
PIRP mypirp;
WCHAR name = L"\device\tcp";
UNICODE_STRING u_name;
RtlInitUnicodeString(&u_name, name);
DriverObject->DriverUnload = DriverUnload;
InitializeObjectAttributes(&obj_attrib,
&u_name,
OBJ_CASE_INSENSITIVE,
NULL,
NULL);
dstatus = ZwCreateFile(&tcpip,
GENERIC_READ | GENERIC_WRITE,
&obj_attrib,
&io_status,
0L,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE,
FILE_OPEN,
FILE_DIRECTORY_FILE,
NULL,
0L);
#if DEBUG
DbgPrint(“\n.\n.\nZwCreateFile() return code: %08X\n”, dstatus);
DbgPrint(“Handle to %ws: %08X\n”, name, (unsigned long) tcpip);
#endif
if (dstatus) {
DbgPrint(“ZwCreateFile() failed\n”);
return STATUS_INSUFFICIENT_RESOURCES;
}
dstatus = ObReferenceObjectByHandle(tcpip,
FILE_READ_ACCESS,
NULL,
KernelMode,
&pfileobject,
&obj_handle_info);
#if DEBUG
DbgPrint(“ObReferenceObjectByHandle() return code: %08X\n”, dstatus);
DbgPrint(“Pointer to file object: %08X\n”, pfileobject);
#endif
if (dstatus) {
DbgPrint(“ObReferenceObjectByHandle() failed\n”);
ZwClose(tcpip);
return STATUS_INSUFFICIENT_RESOURCES;
}
pdeviceobject = IoGetRelatedDeviceObject(pfileobject);
if (pdeviceobject == NULL) {
DbgPrint(“IoGetRelatedDeviceObject() failed\n”);
ZwClose(tcpip);
return STATUS_INSUFFICIENT_RESOURCES;
}
#if DEBUG
DbgPrint(“Pointer to related device object: %08X\n”, pdeviceobject);
#endif
mypirp = TdiBuildInternalDeviceControlIrp(TDI_SET_EVENT_HANDLER,
pdeviceobject,
pfileobject, NULL,
&io_status);
#if DEBUG
DbgPrint(“Pointer to mypirp: %08X\n”, mypirp);
#endif
if (mypirp == NULL) {
DbgPrint(“TdiBuildInternalDeviceControlIrp() failed\n”);
ZwClose(tcpip);
ObDereferenceObject(pfileobject);
return STATUS_INSUFFICIENT_RESOURCES;
}
TdiBuildSetEventHandler(mypirp,
pdeviceobject,
pfileobject,
NULL,
NULL,
TDI_EVENT_RECEIVE,
tdidrv_ClientEventReceive,
NULL);
//
// THIS IoCallDriver() CALL IS FAILING WITH STATUS 0xC0000010
dstatus = IoCallDriver(pdeviceobject,
mypirp);
#if DEBUG
DbgPrint(“IoCallDriver() return code: %08X\n”, dstatus);
#endif
if (dstatus) {
DbgPrint(“IoCallDriver() failed\n”);
ZwClose(tcpip);
ObDereferenceObject(pfileobject);
return STATUS_INSUFFICIENT_RESOURCES;
}
return STATUS_SUCCESS;
}
— [end code]
You are currently subscribed to ntdev as: $subst(‘Recip.EmailAddr’)
To unsubscribe send a blank email to leave-ntdev-$subst(‘Recip.MemberIDChar’)@lists.osr.com