}
}
}
+ if( NewState & SEL_WRITE ) {
+ TI_DbgPrint(DEBUG_TCP,("Writeable: irp list %s\n",
+ IsListEmpty(&Connection->ReceiveRequest) ?
+ "empty" : "nonempty"));
+
+ while( !IsListEmpty( &Connection->SendRequest ) ) {
+ OSK_UINT SendLen = 0, Sent = 0;
+ OSK_PCHAR SendBuffer = 0;
+
+ Entry = RemoveHeadList( &Connection->SendRequest );
+ Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
+ Complete = Bucket->Request.RequestNotifyObject;
+
+ Irp = Bucket->Request.RequestContext;
+ Mdl = Irp->MdlAddress;
+
+ TI_DbgPrint(DEBUG_TCP,
+ ("Getting the user buffer from %x\n", Mdl));
+
+ NdisQueryBuffer( Mdl, &SendBuffer, &SendLen );
+
+ TI_DbgPrint(DEBUG_TCP,
+ ("Writing %d bytes to %x\n", SendLen, SendBuffer));
+
+ TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
+ TI_DbgPrint
+ (DEBUG_TCP,
+ ("Connection->SocketContext: %x\n",
+ Connection->SocketContext));
+
+ Status = TCPTranslateError
+ ( OskitTCPSend( Connection->SocketContext,
+ SendBuffer,
+ SendLen,
+ &Sent,
+ 0 ) );
+
+ TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
+
+ if( Status == STATUS_SUCCESS ) {
+ TI_DbgPrint(DEBUG_TCP,("Sent %d bytes with status %x\n",
+ Sent, Status));
+
+ Complete( Bucket->Request.RequestContext,
+ STATUS_SUCCESS, Sent );
+ } else if( Status == STATUS_PENDING ) {
+ InsertHeadList
+ ( &Connection->SendRequest, &Bucket->Entry );
+ break;
+ } else {
+ TI_DbgPrint(DEBUG_TCP,
+ ("Completing Send request: %x %x\n",
+ Bucket->Request, Status));
+ Complete( Bucket->Request.RequestContext, Status, 0 );
+ }
+ }
+ }
if( NewState & SEL_FIN ) {
PLIST_ENTRY ListsToErase[4];
InitializeListHead(&Connection->ConnectRequest);
InitializeListHead(&Connection->ListenRequest);
InitializeListHead(&Connection->ReceiveRequest);
+ InitializeListHead(&Connection->SendRequest);
/* Save client context pointer */
Connection->ClientContext = ClientContext;
OSK_UINT FindType,
OSK_SOCKADDR *ReqAddr );
+NTSTATUS TCPMemStartup( void );
void *TCPMalloc( void *ClientData,
OSK_UINT bytes, OSK_PCHAR file, OSK_UINT line );
void TCPFree( void *ClientData,
void *data, OSK_PCHAR file, OSK_UINT line );
+void TCPMemShutdown( void );
int TCPSleep( void *ClientData, void *token, int priority, char *msg,
int tmio );
* 800, 1000 and process the "fast" events at 200, 400, 600, 800, 1000 and the
* "slow" events at 500 and 1000.
*/
-static VOID DDKAPI
+static VOID NTAPI
TimerThread(PVOID Context)
{
LARGE_INTEGER Timeout;
* Status of operation
*/
{
+ NTSTATUS Status;
+
TcpipRecursiveMutexInit( &TCPLock );
ExInitializeFastMutex( &SleepingThreadsLock );
InitializeListHead( &SleepingThreadsList );
InitializeListHead( &SignalledConnections );
+ Status = TCPMemStartup();
+ if ( ! NT_SUCCESS(Status) ) {
+ return Status;
+ }
PortsStartup( &TCPPorts, 1, 0xfffe );
return STATUS_SUCCESS;
WaitForThread.QuadPart = -2500000; /* 250 ms */
- KeSetEvent(&TimerLoopEvent, IO_NO_INCREMENT, TRUE);
- KeWaitForSingleObject(&TimerThreadHandle, Executive, KernelMode,
- FALSE, &WaitForThread);
+ KeSetEvent(&TimerLoopEvent, IO_NO_INCREMENT, FALSE);
+ ZwWaitForSingleObject(TimerThreadHandle, FALSE, &WaitForThread);
/* Deregister this protocol with IP layer */
IPRegisterProtocol(IPPROTO_TCP, NULL);
PortsShutdown( &TCPPorts );
+ TCPMemShutdown();
+
return STATUS_SUCCESS;
}
USHORT RemotePort;
PTDI_BUCKET Bucket;
- DbgPrint("TCPConnect: Called\n");
+ TI_DbgPrint(DEBUG_TCP,("TCPConnect: Called\n"));
Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
if( !Bucket ) return STATUS_NO_MEMORY;
&RemoteAddress,
&RemotePort);
- DbgPrint("Connecting to address %x:%x\n",
- RemoteAddress.Address.IPv4Address,
- RemotePort);
+ TI_DbgPrint(DEBUG_TCP,
+ ("Connecting to address %x:%x\n",
+ RemoteAddress.Address.IPv4Address,
+ RemotePort));
if (!NT_SUCCESS(Status)) {
TI_DbgPrint(DEBUG_TCP, ("Could not AddrBuildAddress in TCPConnect\n"));
NTSTATUS TCPSendData
( PCONNECTION_ENDPOINT Connection,
PCHAR BufferData,
- ULONG PacketSize,
- PULONG DataUsed,
- ULONG Flags) {
+ ULONG SendLength,
+ PULONG BytesSent,
+ ULONG Flags,
+ PTCP_COMPLETION_ROUTINE Complete,
+ PVOID Context ) {
+ UINT Sent = 0;
NTSTATUS Status;
+ PTDI_BUCKET Bucket;
+
+ TI_DbgPrint(DEBUG_TCP,("Called for %d bytes (on socket %x)\n",
+ SendLength, Connection->SocketContext));
ASSERT_KM_POINTER(Connection->SocketContext);
TI_DbgPrint(DEBUG_TCP,("Connection->SocketContext = %x\n",
Connection->SocketContext));
- Status = OskitTCPSend( Connection->SocketContext,
- (OSK_PCHAR)BufferData, PacketSize,
- (PUINT)DataUsed, 0 );
+ Status = TCPTranslateError
+ ( OskitTCPSend( Connection->SocketContext,
+ (OSK_PCHAR)BufferData, SendLength,
+ &Sent, 0 ) );
+
+ TI_DbgPrint(DEBUG_TCP,("OskitTCPSend: %x, %d\n", Status, Sent));
+
+ /* Keep this request around ... there was no data yet */
+ if( Status == STATUS_PENDING ) {
+ /* Freed in TCPSocketState */
+ Bucket = ExAllocatePool( NonPagedPool, sizeof(*Bucket) );
+ if( !Bucket ) {
+ TI_DbgPrint(DEBUG_TCP,("Failed to allocate bucket\n"));
+ TcpipRecursiveMutexLeave( &TCPLock );
+ return STATUS_NO_MEMORY;
+ }
+
+ Bucket->Request.RequestNotifyObject = Complete;
+ Bucket->Request.RequestContext = Context;
+ *BytesSent = 0;
+
+ InsertHeadList( &Connection->SendRequest, &Bucket->Entry );
+ TI_DbgPrint(DEBUG_TCP,("Queued write irp\n"));
+ } else {
+ TI_DbgPrint(DEBUG_TCP,("Got status %x, bytes %d\n", Status, Sent));
+ *BytesSent = Sent;
+ }
TcpipRecursiveMutexLeave( &TCPLock );
+ TI_DbgPrint(DEBUG_TCP,("Status %x\n", Status));
+
return Status;
}
PTDI_BUCKET Bucket;
UINT i = 0;
- ListHead[0] = &Endpoint->ReceiveRequest;
- ListHead[1] = &Endpoint->ConnectRequest;
- ListHead[2] = &Endpoint->ListenRequest;
- ListHead[3] = 0;
+ ListHead[0] = &Endpoint->SendRequest;
+ ListHead[1] = &Endpoint->ReceiveRequest;
+ ListHead[2] = &Endpoint->ConnectRequest;
+ ListHead[3] = &Endpoint->ListenRequest;
TcpipAcquireSpinLock( &Endpoint->Lock, &OldIrql );
- for( i = 0; ListHead[i]; i++ ) {
+ for( i = 0; i < sizeof( ListHead ) / sizeof( ListHead[0] ); i++ ) {
for( Entry = ListHead[i]->Flink;
Entry != ListHead[i];
Entry = Entry->Flink ) {