⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tcpserver.c

📁 网络驱动开发
💻 C
📖 第 1 页 / 共 3 页
字号:
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//

NTSTATUS
TCPS_AllocateSessionPool(
   PTCPS_SERVER   pServer,
   INT            nNumberOfSessions    // Number Of Sessions To Allocate
   )
{
   PTCPS_SESSION  pSession;
   NTSTATUS       Status;
   INT            i, NumAllocated = 0;

   for( i = 0; i < nNumberOfSessions; ++i )
   {
      Status = TCPS_AllocateSession(
                  pServer,
                  &pSession
                  );

      if( !NT_SUCCESS( Status ) )
      {
         break;
      }

      //
      // Add The Session To The Free Session List
      //
		InsertTailList(
			&pServer->m_FreeSessionList,
			&pSession->m_ListElement
			);

      ++NumAllocated;
   }

   return( NumAllocated > 0 ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_TestThread
//
// Purpose
//
// Parameters
//
// Return Value
//
// Remarks
//

VOID
TCPS_TestThread(
   IN PVOID pContext
   )
{
   NTSTATUS             Status = STATUS_SUCCESS;
   NDIS_STATUS          nNdisStatus;
   PTTCP_TEST_START_CMD pStartCmd = NULL;
   PTCPS_SERVER         pServer = (PTCPS_SERVER )pContext;
   LARGE_INTEGER        DelayTime;

   KdPrint(("TCPS_TestThread: Starting...\n") );

   //
   // Initialize Default Settings
   //
   Status = STATUS_SUCCESS;      // Always Indicate I/O Success

   //
   // Locate Test Session Parameter Buffer
   //
   pServer = (PTCPS_SERVER )pContext;

   //
   // Perform Additional Initialization Of TCPS_SERVER Structure
   //
   InitializeListHead( &pServer->m_ActiveSessionList );
   InitializeListHead( &pServer->m_FreeSessionList );

   //
   // Setup Local TDI Address
   //
   KS_InitIPAddress(
      &pServer->m_LocalAddress,
      INADDR_ANY,                   // Any Local Address
      pServer->m_TestParams.m_Port  // Specific Port
      );

   //
   // Open Transport Address
   //
   Status = KS_OpenTransportAddress(
                  TCP_DEVICE_NAME_W,
                  (PTRANSPORT_ADDRESS )&pServer->m_LocalAddress,
                  &pServer->m_KS_Address
                  );

   if( !NT_SUCCESS( Status ) )
   {
      //
      // Address Object Could Not Be Created
      //
      goto ExitTheThread;
   }

   //
   // Setup Event Handlers On The Server Address Object
   //
   Status = KS_SetEventHandlers(
                  &pServer->m_KS_Address,
                  pServer,       // Event Context
                  NULL,          // ConnectEventHandler
                  TCPS_DisconnectEventHandler,
                  TCPS_SessionErrorEventHandler,
                  NULL,          // ReceiveEventHandler,
                  NULL,          // ReceiveDatagramEventHandler
                  TCPS_ReceiveExpeditedEventHandler
                  );

   if( !NT_SUCCESS( Status ) )
   {
      //
      // Event Handlers Could Not Be Set
      //
      goto ExitTheThread;
   }

   KdPrint(("TCPS_TestThread: Set Event Handlers On The Server Address Object\n") );

   //
   // Allocate Free Sessions, Used To Accept Connections
   //
//   Status = TCPS_AllocateSessionPool( pServer, 4 );
   Status = TCPS_AllocateSessionPool( pServer, 1 );

   if( !NT_SUCCESS( Status ) )
   {
      goto ExitTheThread;
   }

   KdPrint(("TCPS_TestThread: Session Pool Allocated\n") );

   //
   // Add The Server To The Active Server List
   //
	InsertTailList(
		&g_TCPServerList,
		&pServer->m_ListElement
		);

   Status = KeWaitForSingleObject(
               &g_TCPS_KillEvent,  // Object to wait on.
               Executive,  // Reason for waiting
               KernelMode, // Processor mode
               FALSE,      // Alertable
               NULL        // Timeout
               );

   //
   // ATTENTION!!! Test Exit...
   //

   KdPrint(( "Waiting After Disconnect...\n" ));

   DelayTime.QuadPart = 10*1000*1000*5;   // 5 Seconds

   KeDelayExecutionThread( KernelMode, FALSE, &DelayTime );

   //
   // Exit The Thread
   //
ExitTheThread:

   KdPrint(("TCPS_TestThread: Exiting...\n") );

   RemoveEntryList( &pServer->m_ListElement );

   //
   // Close Active Sessions
   //

   //
   // Free The Free Session Pool
   //
   ASSERT( IsListEmpty( &pServer->m_ActiveSessionList ) );

   TCPS_FreeSessionPool( pServer );

   ASSERT( IsListEmpty( &pServer->m_FreeSessionList ) );

   //
   // Close The Transport Address
   //
   KS_CloseTransportAddress( &pServer->m_KS_Address );

   NdisFreeMemory( pServer, sizeof( TCPS_SERVER ), 0 );

   (void)PsTerminateSystemThread( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_StartTest
//
// Purpose
// Start A TTCP TCP Server Test
//
// Parameters
//    pDeviceObject - Pointer to the device object.
//    pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//

NTSTATUS
TCPS_StartTest(
   IN PDEVICE_OBJECT pDeviceObject,
   IN PIRP pIrp
   )
{
   NDIS_STATUS          nNdisStatus;
   PTTCP_TEST_START_CMD pStartCmd = NULL;
   PTCPS_SERVER         pServer = NULL;

   //
   // Initialize Default Settings
   //
   pIrp->IoStatus.Information = sizeof( ULONG );  // For m_Status

   //
   // Locate Test Start Command Buffer
   //
   pStartCmd = (PTTCP_TEST_START_CMD )pIrp->AssociatedIrp.SystemBuffer;

   pStartCmd->m_Status = STATUS_UNSUCCESSFUL;

   TDITTCP_DumpTestParams( &pStartCmd->m_TestParams );

   //
   // Allocate Memory For The Test Session
   //
   nNdisStatus = NdisAllocateMemory(
                  &pServer,
                  sizeof( TCPS_SERVER ),
                  0,       // Allocate non-paged system-space memory
                  HighestAcceptableMax
                  );

   if( !NT_SUCCESS( nNdisStatus ) )
   {
      return( nNdisStatus );
   }

   NdisZeroMemory( pServer, sizeof( TCPS_SERVER ) );

   NdisMoveMemory(
      &pServer->m_TestParams,
      &pStartCmd->m_TestParams,
      sizeof( TDITTCP_TEST_PARAMS )
      );

   //
   // Start The Thread That Will Execute The Test
   //
   PsCreateSystemThread(
      &pServer->m_hTestThread,   // thread handle
      0L,                        // desired access
      NULL,                      // object attributes
      NULL,                      // process handle
      NULL,                      // client id
      TCPS_TestThread,           // start routine
      (PVOID )pServer            // start context
      );

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceIoControl (IRP_MJ_DEVICE_CONTROL Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Server device IOCTL requests.
//
// Parameters
//    pDeviceObject - Pointer to the device object.
//    pIrp - Pointer to the request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//

NTSTATUS
TCPS_DeviceIoControl(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp
    )
{
   PDEVICE_EXTENSION    pDeviceExtension;
   NTSTATUS             Status;
   PIO_STACK_LOCATION   pIrpSp;
   ULONG                nFunctionCode;

   KdPrint(("TCPS_DeviceIoControl: Entry...\n") );

   pDeviceExtension = pDeviceObject->DeviceExtension;

   pIrp->IoStatus.Information = 0;      // Nothing Returned Yet

   pIrpSp = IoGetCurrentIrpStackLocation(pIrp);

   nFunctionCode=pIrpSp->Parameters.DeviceIoControl.IoControlCode;

   switch( nFunctionCode )
   {
      case IOCTL_TCP_SERVER_START_TEST:
         Status = TCPS_StartTest( pDeviceObject, pIrp );
         break;

      default:
         KdPrint((  "FunctionCode: 0x%8.8X\n", nFunctionCode ));
         Status = STATUS_UNSUCCESSFUL;
         break;
   }

   TdiCompleteRequest( pIrp, Status );

   return( Status );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceCleanup (IRP_MJ_CLEANUP Dispatch Routine)
//
// Purpose
// This is the dispatch routine for TDI TTCP TCP Server device cleanup
// requests.
//
// Parameters
//    pDeviceObject - Pointer to the device object.
//    pFlushIrp - Pointer to the flush request packet.
//
// Return Value
// Status is returned.
//
// Remarks
//

NTSTATUS
TCPS_DeviceCleanup(
    IN PDEVICE_OBJECT pDeviceObject,
    IN PIRP pIrp
    )
{
   PDEVICE_EXTENSION    pDeviceExtension;

   KdPrint(("TCPS_DeviceCleanup: Entry...\n"));

   pDeviceExtension = pDeviceObject->DeviceExtension;

   pIrp->IoStatus.Status = STATUS_SUCCESS;
   pIrp->IoStatus.Information = 0;

   return( STATUS_SUCCESS );
}


/////////////////////////////////////////////////////////////////////////////
//// TCPS_DeviceUnload
//
// Purpose
//
// Parameters
//   pDeviceObject - Pointer to device object created by system.
//
// Return Value
//
// Remarks
//

VOID
TCPS_DeviceUnload(
   IN PDEVICE_OBJECT pDeviceObject
   )
{
   PDEVICE_EXTENSION pDeviceExtension;
   PTCPS_SERVER      pServer = NULL;
   KEVENT            TCPS_UnloadEvent;
   LARGE_INTEGER     UnloadWait;
   NTSTATUS          Status;

   KdPrint(("TCPS_DeviceUnload: Entry...\n") );

   pDeviceExtension = pDeviceObject->DeviceExtension;

   KeSetEvent( &g_TCPS_KillEvent, 0, FALSE);

   //
   // Initialize The Sever Unload Event
   //
   KeInitializeEvent(
      &TCPS_UnloadEvent,
      NotificationEvent,
      FALSE
      );

   while( !IsListEmpty( &g_TCPServerList ) )
   {
//      UnloadWait.QuadPart = -(10 * 1000 * 3000);
      UnloadWait.QuadPart = -(10 * 1000 * 3000);

      Status = KeWaitForSingleObject(
                  &TCPS_UnloadEvent,  // Object to wait on.
                  Executive,  // Reason for waiting
                  KernelMode, // Processor mode
                  FALSE,      // Alertable
                  &UnloadWait // Timeout
                  );
   }

   //
   // Destroy The Symbolic Link
   //
   if( g_bSymbolicLinkCreated )
   {
      UNICODE_STRING UnicodeDeviceName;

      NdisInitUnicodeString(
         &UnicodeDeviceName,
         TDI_TCP_SERVER_DEVICE_NAME_W
         );

      KS_CreateSymbolicLink(
         &UnicodeDeviceName,
         FALSE
         );
  }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -