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

📄 connect.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
        }

        /* Update the base */
        ClientView->ViewBase = Port->ClientSectionBase;
    }
    else
    {
        /* No section */
        SectionToMap = NULL;
    }

    /* Normalize connection information */
    if (ConnectionInfoLength > Port->MaxConnectionInfoLength)
    {
        /* Use the port's maximum allowed value */
        ConnectionInfoLength = Port->MaxConnectionInfoLength;
    }

    /* Allocate a message from the port zone */
    Message = LpcpAllocateFromPortZone();
    if (!Message)
    {
        /* Fail if we couldn't allocate a message */
        if (SectionToMap) ObDereferenceObject(SectionToMap);
        ObDereferenceObject(ClientPort);
        return STATUS_NO_MEMORY;
    }

    /* Set pointer to the connection message and fill in the CID */
    ConnectMessage = (PLPCP_CONNECTION_MESSAGE)(Message + 1);
    Message->Request.ClientId = Thread->Cid;

    /* Check if we have a client view */
    if (ClientView)
    {
        /* Set the view size */
        Message->Request.ClientViewSize = ClientView->ViewSize;

        /* Copy the client view and clear the server view */
        RtlMoveMemory(&ConnectMessage->ClientView,
                      ClientView,
                      sizeof(PORT_VIEW));
        RtlZeroMemory(&ConnectMessage->ServerView, sizeof(REMOTE_PORT_VIEW));
    }
    else
    {
        /* Set the size to 0 and clear the connect message */
        Message->Request.ClientViewSize = 0;
        RtlZeroMemory(ConnectMessage, sizeof(LPCP_CONNECTION_MESSAGE));
    }

    /* Set the section and client port. Port is NULL for now */
    ConnectMessage->ClientPort = NULL;
    ConnectMessage->SectionToMap = SectionToMap;

    /* Set the data for the connection request message */
    Message->Request.u1.s1.DataLength = sizeof(LPCP_CONNECTION_MESSAGE) +
                                        ConnectionInfoLength;
    Message->Request.u1.s1.TotalLength = sizeof(LPCP_MESSAGE) +
                                         Message->Request.u1.s1.DataLength;
    Message->Request.u2.s2.Type = LPC_CONNECTION_REQUEST;

    /* Check if we have connection information */
    if (ConnectionInformation)
    {
        /* Copy it in */
        RtlMoveMemory(ConnectMessage + 1,
                      ConnectionInformation,
                      ConnectionInfoLength);
    }

    /* Acquire the port lock */
    KeAcquireGuardedMutex(&LpcpLock);

    /* Check if someone already deleted the port name */
    if (Port->Flags & LPCP_NAME_DELETED)
    {
        /* Fail the request */
        KeReleaseGuardedMutex(&LpcpLock);
        Status = STATUS_OBJECT_NAME_NOT_FOUND;
        goto Cleanup;
    }

    /* Associate no thread yet */
    Message->RepliedToThread = NULL;

    /* Generate the Message ID and set it */
    Message->Request.MessageId =  LpcpNextMessageId++;
    if (!LpcpNextMessageId) LpcpNextMessageId = 1;
    Thread->LpcReplyMessageId = Message->Request.MessageId;

    /* Insert the message into the queue and thread chain */
    InsertTailList(&Port->MsgQueue.ReceiveHead, &Message->Entry);
    InsertTailList(&Port->LpcReplyChainHead, &Thread->LpcReplyChain);
    Thread->LpcReplyMessage = Message;

    /* Now we can finally reference the client port and link it*/
    ObReferenceObject(ClientPort);
    ConnectMessage->ClientPort = ClientPort;

    /* Release the lock */
    KeReleaseGuardedMutex(&LpcpLock);
    LPCTRACE(LPC_CONNECT_DEBUG,
             "Messages: %p/%p. Ports: %p/%p. Status: %lx\n",
             Message,
             ConnectMessage,
             Port,
             ClientPort,
             Status);

    /* If this is a waitable port, set the event */
    if (Port->Flags & LPCP_WAITABLE_PORT) KeSetEvent(&Port->WaitEvent,
                                                     1,
                                                     FALSE);

    /* Release the queue semaphore */
    LpcpCompleteWait(Port->MsgQueue.Semaphore);

    /* Now wait for a reply */
    LpcpConnectWait(&Thread->LpcReplySemaphore, PreviousMode);

    /* Check if our wait ended in success */
    if (Status != STATUS_SUCCESS) goto Cleanup;

    /* Free the connection message */
    SectionToMap = LpcpFreeConMsg(&Message, &ConnectMessage, Thread);

    /* Check if we got a message back */
    if (Message)
    {
        /* Check for new return length */
        if ((Message->Request.u1.s1.DataLength -
             sizeof(LPCP_CONNECTION_MESSAGE)) < ConnectionInfoLength)
        {
            /* Set new normalized connection length */
            ConnectionInfoLength = Message->Request.u1.s1.DataLength -
                                   sizeof(LPCP_CONNECTION_MESSAGE);
        }

        /* Check if we had connection information */
        if (ConnectionInformation)
        {
            /* Check if we had a length pointer */
            if (ConnectionInformationLength)
            {
                /* Return the length */
                *ConnectionInformationLength = ConnectionInfoLength;
            }

            /* Return the connection information */
            RtlMoveMemory(ConnectionInformation,
                          ConnectMessage + 1,
                          ConnectionInfoLength );
        }

        /* Make sure we had a connected port */
        if (ClientPort->ConnectedPort)
        {
            /* Get the message length before the port might get killed */
            PortMessageLength = Port->MaxMessageLength;

            /* Insert the client port */
            Status = ObInsertObject(ClientPort,
                                    NULL,
                                    PORT_ALL_ACCESS,
                                    0,
                                    (PVOID *)NULL,
                                    &Handle);
            if (NT_SUCCESS(Status))
            {
                /* Return the handle */
                *PortHandle = Handle;
                LPCTRACE(LPC_CONNECT_DEBUG,
                         "Handle: %lx. Length: %lx\n",
                         Handle,
                         PortMessageLength);

                /* Check if maximum length was requested */
                if (MaxMessageLength) *MaxMessageLength = PortMessageLength;

                /* Check if we had a client view */
                if (ClientView)
                {
                    /* Copy it back */
                    RtlMoveMemory(ClientView,
                                  &ConnectMessage->ClientView,
                                  sizeof(PORT_VIEW));
                }

                /* Check if we had a server view */
                if (ServerView)
                {
                    /* Copy it back */
                    RtlMoveMemory(ServerView,
                                  &ConnectMessage->ServerView,
                                  sizeof(REMOTE_PORT_VIEW));
                }
            }
        }
        else
        {
            /* No connection port, we failed */
            if (SectionToMap) ObDereferenceObject(SectionToMap);

            /* Check if it's because the name got deleted */
            if (Port->Flags & LPCP_NAME_DELETED)
            {
                /* Set the correct status */
                Status = STATUS_OBJECT_NAME_NOT_FOUND;
            }
            else
            {
                /* Otherwise, the caller refused us */
                Status = STATUS_PORT_CONNECTION_REFUSED;
            }

            /* Kill the port */
            ObDereferenceObject(ClientPort);
        }

        /* Free the message */
        LpcpFreeToPortZone(Message, FALSE);
        return Status;
    }

    /* No reply message, fail */
    if (SectionToMap) ObDereferenceObject(SectionToMap);
    ObDereferenceObject(ClientPort);
    return STATUS_PORT_CONNECTION_REFUSED;

Cleanup:
    /* We failed, free the message */
    SectionToMap = LpcpFreeConMsg(&Message, &ConnectMessage, Thread);

    /* Check if the semaphore got signaled */
    if (KeReadStateSemaphore(&Thread->LpcReplySemaphore))
    {
        /* Wait on it */
        KeWaitForSingleObject(&Thread->LpcReplySemaphore,
                              KernelMode,
                              Executive,
                              FALSE,
                              NULL);
    }

    /* Check if we had a message and free it */
    if (Message) LpcpFreeToPortZone(Message, FALSE);

    /* Dereference other objects */
    if (SectionToMap) ObDereferenceObject(SectionToMap);
    ObDereferenceObject(ClientPort);

    /* Return status */
    return Status;
}

/*
 * @implemented
 */
NTSTATUS
NTAPI
NtConnectPort(OUT PHANDLE PortHandle,
              IN PUNICODE_STRING PortName,
              IN PSECURITY_QUALITY_OF_SERVICE Qos,
              IN PPORT_VIEW ClientView,
              IN PREMOTE_PORT_VIEW ServerView,
              OUT PULONG MaxMessageLength,
              IN PVOID ConnectionInformation,
              OUT PULONG ConnectionInformationLength)
{
    /* Call the newer API */
    return NtSecureConnectPort(PortHandle,
                               PortName,
                               Qos,
                               ClientView,
                               NULL,
                               ServerView,
                               MaxMessageLength,
                               ConnectionInformation,
                               ConnectionInformationLength);
}

/* EOF */

⌨️ 快捷键说明

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