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

📄 connect.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    LpcWrite.Length = sizeof(PORT_VIEW);
    LpcWrite.SectionHandle = CsrSectionHandle;
    LpcWrite.SectionOffset = 0;
    LpcWrite.ViewSize = CsrSectionViewSize.u.LowPart;
    LpcWrite.ViewBase = 0;
    LpcWrite.ViewRemoteBase = 0;
    LpcRead.Length = sizeof(REMOTE_PORT_VIEW);
    LpcRead.ViewSize = 0;
    LpcRead.ViewBase = 0;

    /* Setup the QoS */
    SecurityQos.ImpersonationLevel = SecurityImpersonation;
    SecurityQos.ContextTrackingMode = SECURITY_DYNAMIC_TRACKING;
    SecurityQos.EffectiveOnly = TRUE;

    /* Setup the connection info */
    ConnectionInfo.Version = 0x10000;

    /* Create a SID for us */
    Status = RtlAllocateAndInitializeSid(&NtSidAuthority,
                                          1,
                                          SECURITY_LOCAL_SYSTEM_RID,
                                          0,
                                          0,
                                          0,
                                          0,
                                          0,
                                          0,
                                          0,
                                          &SystemSid);
    if (!NT_SUCCESS(Status))
    {
        /* Failure */
        DPRINT1("Couldn't allocate SID\n");
        NtClose(CsrSectionHandle);
        return Status;
    }

    /* Connect to the port */
    Status = NtSecureConnectPort(&CsrApiPort,
                                 &PortName,
                                 &SecurityQos,
                                 &LpcWrite,
                                 SystemSid,
                                 &LpcRead,
                                 NULL,
                                 &ConnectionInfo,
                                 &ConnectionInfoLength);
    NtClose(CsrSectionHandle);
    if (!NT_SUCCESS(Status))
    {
        /* Failure */
        DPRINT1("Couldn't connect to CSR port\n");
        return Status;
    }

    /* Save the delta between the sections, for capture usage later */
    CsrPortMemoryDelta = (ULONG_PTR)LpcWrite.ViewRemoteBase -
                         (ULONG_PTR)LpcWrite.ViewBase;

    /* Save the Process */
    CsrProcessId = ConnectionInfo.ProcessId;

    /* Save CSR Section data */
    NtCurrentPeb()->ReadOnlySharedMemoryBase = ConnectionInfo.SharedSectionBase;
    NtCurrentPeb()->ReadOnlySharedMemoryHeap = ConnectionInfo.SharedSectionHeap;
    NtCurrentPeb()->ReadOnlyStaticServerData = ConnectionInfo.SharedSectionData;

    /* Create the port heap */
    CsrPortHeap = RtlCreateHeap(0,
                                LpcWrite.ViewBase,
                                LpcWrite.ViewSize,
                                PAGE_SIZE,
                                0,
                                0);
    if (CsrPortHeap == NULL)
    {
        NtClose(CsrApiPort);
        CsrApiPort = NULL;
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Return success */
    return STATUS_SUCCESS;
}

/*
 * @implemented
 */
NTSTATUS
NTAPI
CsrClientConnectToServer(PWSTR ObjectDirectory,
                         ULONG ServerId,
                         PVOID ConnectionInfo,
                         PULONG ConnectionInfoSize,
                         PBOOLEAN ServerToServerCall)
{
    NTSTATUS Status;
    PIMAGE_NT_HEADERS NtHeader;
    UNICODE_STRING CsrSrvName;
    HANDLE hCsrSrv;
    ANSI_STRING CsrServerRoutineName;
    PCSR_CAPTURE_BUFFER CaptureBuffer;
    CSR_API_MESSAGE RosApiMessage;
    CSR_API_MESSAGE2 ApiMessage;
    PCSR_CLIENT_CONNECT ClientConnect = &ApiMessage.ClientConnect;

    /* Validate the Connection Info */
    DPRINT("CsrClientConnectToServer: %lx %p\n", ServerId, ConnectionInfo);
    if (ConnectionInfo && (!ConnectionInfoSize || !*ConnectionInfoSize))
    {
        DPRINT1("Connection info given, but no length\n");
        return STATUS_INVALID_PARAMETER;
    }

    /* Check if we're inside a CSR Process */
    if (InsideCsrProcess)
    {
        /* Tell the client that we're already inside CSR */
        if (ServerToServerCall) *ServerToServerCall = TRUE;
        return STATUS_SUCCESS;
    }

    /*
     * We might be in a CSR Process but not know it, if this is the first call.
     * So let's find out.
     */
    if (!(NtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress)))
    {
        /* The image isn't valid */
        DPRINT1("Invalid image\n");
        return STATUS_INVALID_IMAGE_FORMAT;
    }
    InsideCsrProcess = (NtHeader->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_NATIVE);

    /* Now we can check if we are inside or not */
    if (InsideCsrProcess && !UsingOldCsr)
    {
        /* We're inside, so let's find csrsrv */
        DbgBreakPoint();
        RtlInitUnicodeString(&CsrSrvName, L"csrsrv");
        Status = LdrGetDllHandle(NULL,
                                 NULL,
                                 &CsrSrvName,
                                 &hCsrSrv);
        RtlFreeUnicodeString(&CsrSrvName);

        /* Now get the Server to Server routine */
        RtlInitAnsiString(&CsrServerRoutineName, "CsrCallServerFromServer");
        Status = LdrGetProcedureAddress(hCsrSrv,
                                        &CsrServerRoutineName,
                                        0L,
                                        (PVOID*)&CsrServerApiRoutine);

        /* Use the local heap as port heap */
        CsrPortHeap = RtlGetProcessHeap();

        /* Tell the caller we're inside the server */
        *ServerToServerCall = InsideCsrProcess;
        return STATUS_SUCCESS;
    }

    /* Now check if connection info is given */
    if (ConnectionInfo)
    {
        /* Well, we're defintely in a client now */
        InsideCsrProcess = FALSE;

        /* Do we have a connection to CSR yet? */
        if (!CsrApiPort)
        {
            /* No, set it up now */
            if (!NT_SUCCESS(Status = CsrConnectToServer(ObjectDirectory)))
            {
                /* Failed */
                DPRINT1("Failure to connect to CSR\n");
                return Status;
            }
        }

        /* Setup the connect message header */
        ClientConnect->ServerId = ServerId;
        ClientConnect->ConnectionInfoSize = *ConnectionInfoSize;

        /* Setup a buffer for the connection info */
        CaptureBuffer = CsrAllocateCaptureBuffer(1,
                                                 ClientConnect->ConnectionInfoSize);
        if (CaptureBuffer == NULL)
        {
            return STATUS_INSUFFICIENT_RESOURCES;
        }

        /* Allocate a pointer for the connection info*/
        CsrAllocateMessagePointer(CaptureBuffer,
                                  ClientConnect->ConnectionInfoSize,
                                  &ClientConnect->ConnectionInfo);

        /* Copy the data into the buffer */
        RtlMoveMemory(ClientConnect->ConnectionInfo,
                      ConnectionInfo,
                      ClientConnect->ConnectionInfoSize);

        /* Return the allocated length */
        *ConnectionInfoSize = ClientConnect->ConnectionInfoSize;

        /* Call CSR */
#if 0
        Status = CsrClientCallServer(&ApiMessage,
                                     CaptureBuffer,
                                     CSR_MAKE_OPCODE(CsrSrvClientConnect,
                                                     CSR_SRV_DLL),
                                     sizeof(CSR_CLIENT_CONNECT));
#endif
        Status = CsrClientCallServer(&RosApiMessage,
                                     NULL,
                                     MAKE_CSR_API(CONNECT_PROCESS, CSR_NATIVE),
                                     sizeof(CSR_API_MESSAGE));
    }
    else
    {
        /* No connection info, just return */
        Status = STATUS_SUCCESS;
    }

    /* Let the caller know if this was server to server */
    DPRINT("Status was: 0x%lx. Are we in server: 0x%x\n", Status, InsideCsrProcess);
    if (ServerToServerCall) *ServerToServerCall = InsideCsrProcess;
    return Status;
}

/* EOF */

⌨️ 快捷键说明

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