Re[2]: TDI
От: Zoya_Pobeda  
Дата: 03.12.06 11:12
Оценка:
Здравствуйте, TarasCo, Вы писали:


TC>Вы довольно сумбурно изложили свои мысли, видимо сказалась радость победы на LPT .Ваш драйвер будет сетевым сервером или клиентом? Если клиентом, то когда должно устанавливтаься соединение? Короче говоря, не совсем ясна архитектура. Поэтому и ответ будет таким же неясным. Большинство вызовов (кроме создания транспортных объектов ) могут проходить на DISPATCH_LEVEL и могут быть сделаны в контексте любого потока.


Может быть как сервером, так и клиентом, взависимости от настроек.Но в данном случае меня интересует серверная часть.

Архитектура такова: Девайс ЛПТ, при открытии должен(помимо каких то своих настроек), создавать поток, который будет работать с ТДИ. Все это дело у меня сейчас выглядит примерно так:


NTSTATUS ServerThreadStart(PLPT_DEVICE_EXTENSION  Context)
{
    NTSTATUS        status    = STATUS_SUCCESS;
    PSERVERDATA        pServer = NULL;




    KeInitializeSemaphore(&Context->Tdi_KillEvent, 0, MAXLONG);
    KeInitializeSemaphore(&Context->Tdi_TimeWait, 0, MAXLONG);
    KeInitializeSemaphore(&Context->Tdi_Send, 0, MAXLONG);
    KeInitializeSemaphore(&Context->Tdi_Recv, 0, MAXLONG);

    pServer = ExAllocatePool(NonPagedPool, sizeof(SERVERDATA));
    

    if( NULL == pServer )
    {
        return( STATUS_INSUFFICIENT_RESOURCES );
    }

    memset( pServer, 0, sizeof( SERVERDATA ) );

    pServer->pDevExt = Context;

    status = PsCreateSystemThread(
      &pServer->hTestThread,     // thread handle
      0L,               // desired access
      NULL,             // object attributes
      NULL,             // process handle
      NULL,             // client id
      ServerWorkerThread,  // start routine
      (PVOID )pServer  // start context
      );

    if( !NT_SUCCESS( status ) )
    {
    //    goto errorServerWorkerThread;
    }

    return status;



}

VOID ServerWorkerThread(IN PVOID Context)
{
    NTSTATUS                status    = STATUS_SUCCESS;
    LARGE_INTEGER            DelayTime;
    PVOID                    pEvents[6];
    KWAIT_BLOCK                waitBlocks[6];
    BOOLEAN                    bDeadThread = FALSE;
    PIRP                    pIrp        = NULL;
    IO_STATUS_BLOCK            IoStatus;


    PSERVERDATA                pServer        = (PSERVERDATA)Context;
    PLPT_DEVICE_EXTENSION    pDevExt        = (PLPT_DEVICE_EXTENSION)pServer->pDevExt;

    pServer->pTDIClient = ExAllocatePool(NonPagedPool, sizeof( TDIClientExtension ));

    if( NULL == pServer->pTDIClient )
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto errorTDIClient;
    }

    pServer->pTDIClient->hAddr = INVALID_HANDLE_VALUE;
    pServer->pTDIClient->pAddrFileObj = NULL;
    pServer->pTDIClient->pReqElemsArr = NULL;
    pServer->pTDIClient->pBufferBase = NULL;
    pServer->pTDIClient->pTDIClnConnArr = NULL;

    InitIPAddress(    &pServer->pTDIClient->LocalAddress,
                    INADDR_ANY,
                    ntohs(pDevExt->m_port));

    

    status = TDIClnOpenTransAddr(                    
                                    TCP_DEVICE_NAME_W,
                                    pServer->pTDIClient,
                                    &pServer->pTDIClient->hAddr,
                                    &pServer->pTDIClient->pAddrFileObj
                                 );

    if( !NT_SUCCESS( status ) )
    {
        goto errorOpenTransportAddress;
    }


    pServer->pTDIClient->pTDIClnConnArr =                       
        (pTDIClnConn)ExAllocatePool(
                                   NonPagedPool,
                                   sizeof(TDIClnConn)
                                  );

    if( NULL == pServer->pTDIClient->pTDIClnConnArr )
    {
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto errorOpenConnection;
    }

    pServer->pTDIClient->pTDIClnConnArr->pDevExt = pServer->pTDIClient;
    pServer->pTDIClient->pTDIClnConnArr->hConn = INVALID_HANDLE_VALUE;


    status = TDIClnOpenConnEndPt(    TCP_DEVICE_NAME_W,
                                    &pServer->pTDIClient->pTDIClnConnArr->hConn,
                                    &pServer->pTDIClient->pTDIClnConnArr->pConnFileObj,
                                    pServer->pTDIClient->pTDIClnConnArr);

    if( !NT_SUCCESS( status ) )
    {
        goto errorOpenConnectionEndpoint;
    }

    KeInitializeEvent(&pServer->pTDIClient->pTDIClnConnArr->AccEvent, NotificationEvent, FALSE);                               
    KeInitializeEvent(&pServer->pTDIClient->pTDIClnConnArr->AccEvent, NotificationEvent, FALSE);

    pServer->pTDIClient->pTcpDevObj = IoGetRelatedDeviceObject(pServer->pTDIClient->pAddrFileObj);


    status =                                         
        TDIClnSetEventHandler    (
                                pServer->pTDIClient->pAddrFileObj,
                                pServer->pTDIClient->pTcpDevObj,
                                TDI_EVENT_RECEIVE,
                                TDISrvEventReceive,     
                                NULL                     
                                );

    if( !NT_SUCCESS( status ) )
    {
        goto errorEvent;
    }

    status =                                        
        TDIClnSetEventHandler    (
                                pServer->pTDIClient->pAddrFileObj,
                                pServer->pTDIClient->pTcpDevObj,
                                TDI_EVENT_DISCONNECT,
                                TDISrvEventDisconnect,     
                                NULL                     
                                );

    if( !NT_SUCCESS( status ) )
    {
        goto errorEvent;
    }

    status =                                        
        TDIClnSetEventHandler    (
                                pServer->pTDIClient->pAddrFileObj,
                                pServer->pTDIClient->pTcpDevObj,
                                TDI_EVENT_ERROR_EX,
                                TDISrvEventErrorEx,     
                                NULL                     
                                );

    if( !NT_SUCCESS( status ) )
    {
        goto errorEvent;
    }

    status = TDIClnAssocAddr(                     
                                 pServer->pTDIClient->pTDIClnConnArr->pConnFileObj,
                                 pServer->pTDIClient->pTcpDevObj,
                                 pServer->pTDIClient->hAddr
                                );

    if( !NT_SUCCESS( status ) )
    {
        goto errorEvent;
    }


    pIrp = TdiBuildInternalDeviceControlIrp(TDI_ACCEPT,
                            pServer->pTDIClient->pTcpDevObj,    
                            pServer->pTDIClient->pTDIClnConnArr->pConnFileObj,
                            &pServer->pTDIClient->pTDIClnConnArr->AccEvent, 
                            &IoStatus               
                            );

    if (NULL==pIrp)
    {
        KdPrint(("Error TdiBuildInternalDeviceControlIrp"));
        status = STATUS_INSUFFICIENT_RESOURCES;
        goto errorBuildTDIAccept;
    }

    pServer->pTDIClient->pIrpAccept = pIrp;                      
    status =                                         
            TDIClnSetEventHandler(    pServer->pTDIClient->pAddrFileObj,
                                    pServer->pTDIClient->pTcpDevObj,
                                    TDI_EVENT_CONNECT,
                                    TDISrvEventConnect,
                                    pServer->pTDIClient->pTDIClnConnArr             
                                    );

    if (!NT_SUCCESS(status))
    {
        KdPrint(("Error TDIClnSetEventHandler: TDI_EVENT_CONNECT"));
        goto errorBuildTDIAccept;
    }


    KdPrint(("ServerWorkerThread: Starting... \r\n"));

    pEvents[EV_KILLEVENT]    = (PVOID)&pDevExt->Tdi_KillEvent;
    pEvents[EV_TIMEWAIT]    = (PVOID)&pDevExt->Tdi_TimeWait;
    pEvents[EV_SEND]        = (PVOID)&pDevExt->Tdi_Send;
    pEvents[EV_RECV]        = (PVOID)&pDevExt->Tdi_Recv;

    pEvents[EV_ACC]        = (PVOID)&pServer->pTDIClient->pTDIClnConnArr->AccEvent;
    pEvents[EV_DIS]        = (PVOID)&pServer->pTDIClient->pTDIClnConnArr->DiscEvent;

    while(!bDeadThread)
    {

        

        switch(KeWaitForMultipleObjects(6, pEvents, WaitAny, Executive, KernelMode, FALSE, NULL, waitBlocks))
        {
        case EV_ACC:
            {
                break;
            }
        case EV_DIS:
            {
                break;
            }
        case EV_KILLEVENT:
            {
                bDeadThread = TRUE;
                break;
            }
        case EV_TIMEWAIT:
            {

                break;
            }
        case EV_SEND:
            {
                
                

                break;
            }
        case EV_RECV:
            {

                break;
            }
        }


    }
    KdPrint(("Server Thread: Exiting...\n") );

errorBuildTDIAccept:
    TDIClnDisassocAddr(pServer->pTDIClient->pTDIClnConnArr->pConnFileObj, pServer->pTDIClient->pTcpDevObj);

errorEvent:
    if (INVALID_HANDLE_VALUE!=pServer->pTDIClient->pTDIClnConnArr->hConn) 
     {
         ZwClose(pServer->pTDIClient->pTDIClnConnArr->hConn);
         pServer->pTDIClient->pTDIClnConnArr->hConn = INVALID_HANDLE_VALUE;
     }

     if (NULL!=pServer->pTDIClient->pTDIClnConnArr->pConnFileObj) 
     {
         ObDereferenceObject(pServer->pTDIClient->pTDIClnConnArr->pConnFileObj);
         pServer->pTDIClient->pTDIClnConnArr->pConnFileObj = NULL;
     }


errorOpenConnectionEndpoint:
    ExFreePool( pServer->pTDIClient->pTDIClnConnArr );


errorOpenConnection:
     if (INVALID_HANDLE_VALUE!=pServer->pTDIClient->hAddr) 
     {
         ZwClose(pServer->pTDIClient->hAddr);
         pServer->pTDIClient->hAddr = INVALID_HANDLE_VALUE;
     }

     if (NULL!=pServer->pTDIClient->pAddrFileObj) 
     {
         ObDereferenceObject(pServer->pTDIClient->pAddrFileObj);
         pServer->pTDIClient->pAddrFileObj = NULL;
     }


errorOpenTransportAddress:
    ExFreePool( pServer->pTDIClient );

errorTDIClient:
    ExFreePool( pServer);

    (void)PsTerminateSystemThread( STATUS_SUCCESS );
}


Я думаю теперь намного стало понятнее? Возможен ли такой вариан вообще?
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.