NTSTATUS AfdRegisterEventHandlers( PAFDFCB FCB) { NTSTATUS Status; assert(FCB->TdiAddressObject); /* Report errors for all types of sockets */ Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_ERROR, (PVOID)AfdEventError, (PVOID)FCB); if (!NT_SUCCESS(Status)) { return Status; } switch (FCB->SocketType) { case SOCK_STREAM: Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_DISCONNECT, (PVOID)AfdEventDisconnect, (PVOID)FCB); if (!NT_SUCCESS(Status)) { return Status; } Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE, (PVOID)AfdEventReceive, (PVOID)FCB); if (!NT_SUCCESS(Status)) { return Status; } Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE_EXPEDITED, (PVOID)ClientEventReceiveExpedited, (PVOID)FCB); if (!NT_SUCCESS(Status)) { return Status; } Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_CHAINED_RECEIVE, (PVOID)ClientEventChainedReceive, (PVOID)FCB); if (!NT_SUCCESS(Status)) { return Status; } break; case SOCK_DGRAM: case SOCK_RAW: Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE_DATAGRAM, (PVOID)AfdEventReceiveDatagramHandler, (PVOID)FCB); if (!NT_SUCCESS(Status)) { return Status; } } return STATUS_SUCCESS; }
NTSTATUS AfdDeregisterEventHandlers( PAFDFCB FCB) { NTSTATUS Status; Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_ERROR, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } switch (FCB->SocketType) { case SOCK_STREAM: Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_DISCONNECT, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE_EXPEDITED, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_CHAINED_RECEIVE, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } break; case SOCK_DGRAM: case SOCK_RAW: Status = TdiSetEventHandler(FCB->TdiAddressObject, TDI_EVENT_RECEIVE_DATAGRAM, NULL, NULL); if (!NT_SUCCESS(Status)) { return Status; } } return STATUS_SUCCESS; }
NTSTATUS TdiSendMessage( ULONG Ip, USHORT Port, PCHAR Message, ULONG Length ) { PFILE_OBJECT ConnectionFileObject, AddressFileObject; HANDLE AddressHandle, ConnectionHandle; CHAR Buffer[80], Data[] = "Hello from Gary"; NTSTATUS Status; KEVENT Done; KeInitializeEvent(&Done, NotificationEvent, FALSE); Status = TdiCreateConnection(&ConnectionHandle, &ConnectionFileObject); if (!NT_SUCCESS(Status)) return Status; Status = TdiCreateAddress(&AddressHandle, &AddressFileObject, SOCK_STREAM, 0, 0); if (!NT_SUCCESS(Status)) return Status; do { IO_STATUS_BLOCK IoStatus; KEVENT Event; Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_DISCONNECT, TdiEventDisconnect, &Done); if (!NT_SUCCESS(Status)) break; Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_ERROR, TdiEventError, 0); if (!NT_SUCCESS(Status)) break; Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_RECEIVE, TdiEventReceive, 0); if (!NT_SUCCESS(Status)) break; Status = TdiBind(ConnectionFileObject, AddressHandle); if (!NT_SUCCESS(Status)) break; Status = TdiConnect(ConnectionFileObject, Ip, Port, NULL); if (!NT_SUCCESS(Status)) break; Status = TdiSend(ConnectionFileObject, Message, Length); if (!NT_SUCCESS(Status)) break; Status = TdiDisconnect(ConnectionFileObject); if (!NT_SUCCESS(Status)) break; KeWaitForSingleObject(&Done, UserRequest, KernelMode, FALSE, 0); } while (0); ObDereferenceObject(ConnectionFileObject); ObDereferenceObject(AddressFileObject); ZwClose(ConnectionHandle); ZwClose(AddressHandle); return Status; }
NTSTATUS TdiTest() { PFILE_OBJECT ConnectionFileObject, AddressFileObject; HANDLE AddressHandle, ConnectionHandle; CHAR Buffer[80], Data[] = "Hello from Gary"; NTSTATUS Status; KEVENT Done; KeInitializeEvent(&Done, NotificationEvent, FALSE); Status = TdiCreateConnection(&ConnectionHandle, &ConnectionFileObject); if (!NT_SUCCESS(Status)) return Status; Status = TdiCreateAddress(&AddressHandle, &AddressFileObject, SOCK_STREAM, 0, 0); if (!NT_SUCCESS(Status)) return Status; do { IO_STATUS_BLOCK IoStatus = {0}; KEVENT Event; Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_DISCONNECT, TdiEventDisconnect, &Done); if (!NT_SUCCESS(Status)) break; Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_ERROR, TdiEventError, 0); if (!NT_SUCCESS(Status)) break; Status = TdiSetEventHandler(AddressFileObject, TDI_EVENT_RECEIVE, TdiEventReceive, 0); if (!NT_SUCCESS(Status)) break; Status = TdiBind(ConnectionFileObject, AddressHandle); if (!NT_SUCCESS(Status)) break; Status = TdiConnect(ConnectionFileObject, 0x41A1F6A8, 0x700, NULL); if (!NT_SUCCESS(Status)) break; KeInitializeEvent(&Event, NotificationEvent, FALSE); // Status = TdiRecv(ConnectionFileObject, Buffer, sizeof Buffer, &Event, &IoStatus); // if (!NT_SUCCESS(Status)) break; Status = TdiSend(ConnectionFileObject, Data, sizeof Data); if (!NT_SUCCESS(Status)) break; Status = TdiSend(ConnectionFileObject, Data, sizeof Data); if (!NT_SUCCESS(Status)) break; Status = TdiSend(ConnectionFileObject, Data, sizeof Data); if (!NT_SUCCESS(Status)) break; Status = TdiDisconnect(ConnectionFileObject); if (!NT_SUCCESS(Status)) break; Status = KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, 0); if (Status == STATUS_SUCCESS) Status = IoStatus.Status; DbgPrint("Status = %lx, IoStatus.Status = %lx, IoStatus.Information = %ld\n", Status, IoStatus.Status, IoStatus.Information); KeWaitForSingleObject(&Done, UserRequest, KernelMode, FALSE, 0); } while (0); ObDereferenceObject(ConnectionFileObject); ObDereferenceObject(AddressFileObject); ZwClose(ConnectionHandle); ZwClose(AddressHandle); return Status; }