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

📄 api.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/*++
 * @name CsrCallServerFromServer
 * @implemented NT4
 *
 * The CsrCallServerFromServer routine calls a CSR API from within a server.
 * It avoids using LPC messages since the request isn't coming from a client.
 *
 * @param ReceiveMsg
 *        Pointer to the CSR API Message to send to the server.
 *
 * @param ReplyMsg
 *        Pointer to the CSR API Message to receive from the server.
 *
 * @return STATUS_SUCCESS in case of success, STATUS_ILLEGAL_FUNCTION
 *         if the opcode is invalid, or STATUS_ACCESS_VIOLATION if there
 *         was a problem executing the API.
 *
 * @remarks None.
 *
 *--*/
NTSTATUS
NTAPI
CsrCallServerFromServer(PCSR_API_MESSAGE ReceiveMsg,
                        PCSR_API_MESSAGE ReplyMsg)
{
    ULONG ServerId;
    PCSR_SERVER_DLL ServerDll;
    ULONG ApiId;
    ULONG Reply;
    NTSTATUS Status;

    /* Get the Server ID */
    ServerId = CSR_SERVER_ID_FROM_OPCODE(ReceiveMsg->Opcode);

    /* Make sure that the ID is within limits, and the Server DLL loaded */
    if ((ServerId >= CSR_SERVER_DLL_MAX) ||
        (!(ServerDll = CsrLoadedServerDll[ServerId])))
    {
        /* We are beyond the Maximum Server ID */
        ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
        return STATUS_ILLEGAL_FUNCTION;
    }
    else
    {
        /* Get the API ID */
        ApiId = CSR_API_ID_FROM_OPCODE(ReceiveMsg->Opcode);

        /* Normalize it with our Base ID */
        ApiId -= ServerDll->ApiBase;

        /* Make sure that the ID is within limits, and the entry exists */
        if ((ApiId >= ServerDll->HighestApiSupported) ||
            (ServerDll->ValidTable && !ServerDll->ValidTable[ApiId]))
        {
            /* We are beyond the Maximum API ID, or it doesn't exist */
            ReplyMsg->Status = (ULONG)STATUS_ILLEGAL_FUNCTION;
            return STATUS_ILLEGAL_FUNCTION;
        }
    }

    /* Validation complete, start SEH */
    _SEH_TRY
    {
        /* Call the API and get the result */
        Status = (ServerDll->DispatchTable[ApiId])(ReceiveMsg, &Reply);

        /* Return the result, no matter what it is */
        ReplyMsg->Status = Status;
    }
    _SEH_HANDLE
    {
        /* If we got an exception, return access violation */
        ReplyMsg->Status = STATUS_ACCESS_VIOLATION;
    }
    _SEH_END;

    /* Return success */
    return STATUS_SUCCESS;
}

/*++
 * @name CsrConnectToUser
 * @implemented NT4
 *
 * The CsrConnectToUser connects to the User subsystem.
 *
 * @param None
 *
 * @return A pointer to the CSR Thread
 *
 * @remarks None.
 *
 *--*/
PCSR_THREAD
NTAPI
CsrConnectToUser(VOID)
{
    NTSTATUS Status;
    ANSI_STRING DllName;
    UNICODE_STRING TempName;
    HANDLE hUser32;
    STRING StartupName;
    PTEB Teb = NtCurrentTeb();
    PCSR_THREAD CsrThread;

    /* Check if we didn't already find it */
    if (!CsrClientThreadSetup)
    {
        /* Get the DLL Handle for user32.dll */
        RtlInitAnsiString(&DllName, "user32");
        RtlAnsiStringToUnicodeString(&TempName, &DllName, TRUE);
        Status = LdrGetDllHandle(NULL,
                                 NULL,
                                 &TempName,
                                 &hUser32);
        RtlFreeUnicodeString(&TempName);

        /* If we got teh handle, get the Client Thread Startup Entrypoint */
        if (NT_SUCCESS(Status))
        {
            RtlInitAnsiString(&StartupName,"ClientThreadSetup");
            Status = LdrGetProcedureAddress(hUser32,
                                            &StartupName,
                                            0,
                                            (PVOID)&CsrClientThreadSetup);
        }
    }

    /* Connect to user32 */
    CsrClientThreadSetup();

    /* Save pointer to this thread in TEB */
    CsrThread = CsrLocateThreadInProcess(NULL, &Teb->Cid);
    if (CsrThread) Teb->CsrClientThread = CsrThread;

    /* Return it */
    return CsrThread;
}

/*++
 * @name CsrQueryApiPort
 * @implemented NT4
 *
 * The CsrQueryApiPort routine returns a handle to the CSR API LPC port.
 *
 * @param None.
 *
 * @return A handle to the port.
 *
 * @remarks None.
 *
 *--*/
HANDLE
NTAPI
CsrQueryApiPort(VOID)
{
    DPRINT("CSRSRV: %s called\n", __FUNCTION__);
    return CsrApiPort;
}

/*++
 * @name CsrCaptureArguments
 * @implemented NT5.1
 *
 * The CsrCaptureArguments routine validates a CSR Capture Buffer and
 * re-captures it into a server CSR Capture Buffer.
 *
 * @param CsrThread
 *        Pointer to the CSR Thread performing the validation.
 *
 * @param ApiMessage
 *        Pointer to the CSR API Message containing the Capture Buffer
 *        that needs to be validated.
 *
 * @return TRUE if validation succeeded, FALSE otherwise.
 *
 * @remarks None.
 *
 *--*/
BOOLEAN
NTAPI
CsrCaptureArguments(IN PCSR_THREAD CsrThread,
                    IN PCSR_API_MESSAGE ApiMessage)
{
    PCSR_CAPTURE_BUFFER LocalCaptureBuffer = NULL;
    ULONG LocalLength = 0;
    PCSR_CAPTURE_BUFFER RemoteCaptureBuffer = NULL;
    SIZE_T BufferDistance = 0;
    ULONG PointerCount = 0;
    ULONG_PTR **PointerOffsets = NULL;
    ULONG_PTR *CurrentPointer = NULL;

    /* Use SEH to make sure this is valid */
    _SEH_TRY
    {
        /* Get the buffer we got from whoever called NTDLL */
        LocalCaptureBuffer = ApiMessage->CsrCaptureData;
        LocalLength = LocalCaptureBuffer->Size;

        /* Now check if the buffer is inside our mapped section */
        if (((ULONG_PTR)LocalCaptureBuffer < CsrThread->Process->ClientViewBase) ||
            (((ULONG_PTR)LocalCaptureBuffer + LocalLength) >= CsrThread->Process->ClientViewBounds))
        {
            /* Return failure */
            ApiMessage->Status = STATUS_INVALID_PARAMETER;
            _SEH_YIELD(return FALSE);
        }

        /* Check if the Length is valid */
        if (((LocalCaptureBuffer->PointerCount * 4 + sizeof(CSR_CAPTURE_BUFFER)) >
            LocalLength) ||(LocalLength > MAXWORD))
        {
            /* Return failure */
            ApiMessage->Status = STATUS_INVALID_PARAMETER;
            _SEH_YIELD(return FALSE);
        }
    }
    _SEH_HANDLE
    {
        /* Return failure */
        ApiMessage->Status = STATUS_INVALID_PARAMETER;
        _SEH_YIELD(return FALSE);
    } _SEH_END;

    /* We validated the incoming buffer, now allocate the remote one */
    RemoteCaptureBuffer = RtlAllocateHeap(CsrHeap, 0, LocalLength);
    if (!RemoteCaptureBuffer)
    {
        /* We're out of memory */
        ApiMessage->Status = STATUS_NO_MEMORY;
        return FALSE;
    }

    /* Copy the client's buffer */
    RtlMoveMemory(RemoteCaptureBuffer, LocalCaptureBuffer, LocalLength);

    /* Copy the length */
    RemoteCaptureBuffer->Size = LocalLength;

    /* Calculate the difference between our buffer and the client's */
    BufferDistance = (ULONG_PTR)RemoteCaptureBuffer - (ULONG_PTR)LocalCaptureBuffer;

    /* Save the pointer count and offset pointer */
    PointerCount = RemoteCaptureBuffer->PointerCount;
    PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1);

    /* Start the loop */
    while (PointerCount)
    {
        /* Get the current pointer */
        if ((CurrentPointer = *PointerOffsets++))
        {
            /* Add it to the CSR Message structure */
            CurrentPointer += (ULONG_PTR)ApiMessage;

            /* Validate the bounds of the current pointer */
            if ((*CurrentPointer >= CsrThread->Process->ClientViewBase) &&
                (*CurrentPointer < CsrThread->Process->ClientViewBounds))
            {
                /* Modify the pointer to take into account its new position */
                *CurrentPointer += BufferDistance;
            }
            else
            {
                /* Invalid pointer, fail */
                ApiMessage->Status = (ULONG)STATUS_INVALID_PARAMETER;
            }
        }

        /* Move to the next Pointer */
        PointerCount--;
    }

    /* Check if we got success */
    if (ApiMessage->Status != STATUS_SUCCESS)
    {
        /* Failure. Free the buffer and return*/
        RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
        return FALSE;
    }
    else
    {
        /* Success, save the previous buffer */
        RemoteCaptureBuffer->PreviousCaptureBuffer = LocalCaptureBuffer;
        ApiMessage->CsrCaptureData = RemoteCaptureBuffer;
    }

    /* Success */
    return TRUE;
}

/*++
 * @name CsrReleaseCapturedArguments
 * @implemented NT5.1
 *
 * The CsrReleaseCapturedArguments routine releases a Capture Buffer
 * that was previously captured with CsrCaptureArguments.
 *
 * @param ApiMessage
 *        Pointer to the CSR API Message containing the Capture Buffer
 *        that needs to be released.
 *
 * @return None.
 *
 * @remarks None.
 *
 *--*/
VOID
NTAPI
CsrReleaseCapturedArguments(IN PCSR_API_MESSAGE ApiMessage)
{
    PCSR_CAPTURE_BUFFER RemoteCaptureBuffer;
    PCSR_CAPTURE_BUFFER LocalCaptureBuffer;
    SIZE_T BufferDistance;
    ULONG PointerCount;
    ULONG_PTR **PointerOffsets;
    ULONG_PTR *CurrentPointer;

    /* Get the capture buffers */
    RemoteCaptureBuffer = ApiMessage->CsrCaptureData;
    LocalCaptureBuffer = RemoteCaptureBuffer->PreviousCaptureBuffer;

    /* Free the previous one */
    RemoteCaptureBuffer->PreviousCaptureBuffer = NULL;

    /* Find out the difference between the two buffers */
    BufferDistance = (ULONG_PTR)LocalCaptureBuffer - (ULONG_PTR)RemoteCaptureBuffer;

    /* Save the pointer count and offset pointer */
    PointerCount = RemoteCaptureBuffer->PointerCount;
    PointerOffsets = (ULONG_PTR**)(RemoteCaptureBuffer + 1);

    /* Start the loop */
    while (PointerCount)
    {
        /* Get the current pointer */
        if ((CurrentPointer = *PointerOffsets++))
        {
            /* Add it to the CSR Message structure */
            CurrentPointer += (ULONG_PTR)ApiMessage;

            /* Modify the pointer to take into account its new position */
            *CurrentPointer += BufferDistance;
        }

        /* Move to the next Pointer */
        PointerCount--;
    }

    /* Copy the data back */
    RtlMoveMemory(LocalCaptureBuffer,
                  RemoteCaptureBuffer,
                  RemoteCaptureBuffer->Size);

    /* Free our allocated buffer */
    RtlFreeHeap(CsrHeap, 0, RemoteCaptureBuffer);
}

/*++
 * @name CsrValidateMessageBuffer
 * @implemented NT5.1
 *
 * The CsrValidateMessageBuffer routine validates a captured message buffer
 * present in the CSR Api Message
 *
 * @param ApiMessage
 *        Pointer to the CSR API Message containing the CSR Capture Buffer.
 *
 * @param Buffer
 *        Pointer to the message buffer to validate.
 *
 * @param ArgumentSize
 *        Size of the message to check.
 *
 * @param ArgumentCount
 *        Number of messages to check.
 *
 * @return TRUE if validation suceeded, FALSE otherwise.
 *
 * @remarks None.
 *
 *--*/
BOOLEAN
NTAPI
CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage,
                         IN PVOID *Buffer,
                         IN ULONG ArgumentSize,
                         IN ULONG ArgumentCount)
{
    PCSR_CAPTURE_BUFFER CaptureBuffer = ApiMessage->CsrCaptureData;
    SIZE_T BufferDistance;
    ULONG PointerCount;
    ULONG_PTR **PointerOffsets;
    ULONG_PTR *CurrentPointer;
    ULONG i;

    /* Make sure there are some arguments */
    if (!ArgumentCount) return FALSE;

    /* Check if didn't get a buffer and there aren't any arguments to check */
    if (!(*Buffer) && (!(ArgumentCount * ArgumentSize))) return TRUE;

    /* Check if we have no capture buffer */
    if (!CaptureBuffer)
    {
        /* In this case, check only the Process ID */
        if (NtCurrentTeb()->Cid.UniqueProcess ==
            ApiMessage->Header.ClientId.UniqueProcess)
        {
            /* There is a match, validation succeeded */
            return TRUE;
        }
    }
    else
    {
        /* Make sure that there is still space left in the buffer */
        if ((CaptureBuffer->Size - (ULONG_PTR)*Buffer + (ULONG_PTR)CaptureBuffer) <
            (ArgumentCount * ArgumentSize))
        {
            /* Find out the difference between the two buffers */
            BufferDistance = (ULONG_PTR)Buffer - (ULONG_PTR)ApiMessage;

             /* Save the pointer count */
            PointerCount = CaptureBuffer->PointerCount;
            PointerOffsets = (ULONG_PTR**)(CaptureBuffer + 1);

            /* Start the loop */
            for (i = 0; i < PointerCount; i++)
            {
                /* Get the current pointer */
                CurrentPointer = *PointerOffsets++;

                /* Check if its' equal to the difference */
                if (*CurrentPointer == BufferDistance) return TRUE;
            }
        }
    }

    /* Failure */
    return FALSE;
}

/*++
 * @name CsrValidateMessageString
 * @implemented NT5.1
 *
 * The CsrValidateMessageString validates a captured Wide-Character String
 * present in a CSR API Message.
 *
 * @param ApiMessage
 *        Pointer to the CSR API Message containing the CSR Capture Buffer.
 *
 * @param MessageString
 *        Pointer to the buffer containing the string to validate.
 *
 * @return TRUE if validation suceeded, FALSE otherwise.
 *
 * @remarks None.
 *
 *--*/
BOOLEAN
NTAPI
CsrValidateMessageString(IN PCSR_API_MESSAGE ApiMessage,
                         IN LPWSTR *MessageString)
{
    DPRINT("CSRSRV: %s called\n", __FUNCTION__);
    return FALSE;
}

/* EOF */

⌨️ 快捷键说明

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