コード例 #1
0
ファイル: reply.c プロジェクト: reactos/reactos
VOID
NTAPI
LpcpMoveMessage(IN PPORT_MESSAGE Destination,
                IN PPORT_MESSAGE Origin,
                IN PVOID Data,
                IN ULONG MessageType,
                IN PCLIENT_ID ClientId)
{
    LPCTRACE((LPC_REPLY_DEBUG | LPC_SEND_DEBUG),
             "Destination/Origin: %p/%p. Data: %p. Length: %lx\n",
             Destination,
             Origin,
             Data,
             Origin->u1.Length);

    /* Set the Message size */
    Destination->u1.Length = Origin->u1.Length;

    /* Set the Message Type */
    Destination->u2.s2.Type = !MessageType ?
                              Origin->u2.s2.Type : MessageType & 0xFFFF;

    /* Check if we have a Client ID */
    if (ClientId)
    {
        /* Set the Client ID */
        Destination->ClientId.UniqueProcess = ClientId->UniqueProcess;
        Destination->ClientId.UniqueThread = ClientId->UniqueThread;
    }
    else
    {
        /* Otherwise, copy it */
        Destination->ClientId.UniqueProcess = Origin->ClientId.UniqueProcess;
        Destination->ClientId.UniqueThread = Origin->ClientId.UniqueThread;
    }

    /* Copy the MessageId and ClientViewSize */
    Destination->MessageId = Origin->MessageId;
    Destination->ClientViewSize = Origin->ClientViewSize;

    /* Copy the Message Data */
    RtlCopyMemory(Destination + 1,
                  Data,
                  ALIGN_UP_BY(Destination->u1.s1.DataLength, sizeof(ULONG)));
}
コード例 #2
0
ファイル: rxact.c プロジェクト: Strongc/reactos
NTSTATUS
NTAPI
RtlAddAttributeActionToRXact(
    PRXACT_CONTEXT Context,
    ULONG ActionType,
    PUNICODE_STRING KeyName,
    HANDLE KeyHandle,
    PUNICODE_STRING ValueName,
    ULONG ValueType,
    PVOID ValueData,
    ULONG ValueDataSize)
{
    ULONG ActionSize;
    ULONG RequiredSize;
    ULONG BufferSize;
    ULONG CurrentOffset;
    PRXACT_DATA NewData;
    PRXACT_ACTION Action;

    /* Validate ActionType parameter */
    if ((ActionType != RXactDeleteKey) && (ActionType != RXactSetValueKey))
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Calculate the size of the new action record */
    ActionSize = ALIGN_UP_BY(ValueName->Length, sizeof(ULONG)) +
                 ALIGN_UP_BY(ValueDataSize, sizeof(ULONG)) +
                 ALIGN_UP_BY(KeyName->Length, sizeof(ULONG)) +
                 ALIGN_UP_BY(sizeof(RXACT_ACTION), sizeof(ULONG));

    /* Calculate the new buffer size we need */
    RequiredSize = ActionSize + Context->Data->CurrentSize;

    /* Check for integer overflow */
    if (RequiredSize < ActionSize)
    {
        return STATUS_NO_MEMORY;
    }

    /* Check if the buffer is large enough */
    BufferSize = Context->Data->BufferSize;
    if (RequiredSize > BufferSize)
    {
        /* Increase by a factor of 2, until it is large enough */
        while (BufferSize < RequiredSize)
        {
            BufferSize *= 2;
        }

        /* Allocate a new buffer from the heap */
        NewData = RtlAllocateHeap(RtlGetProcessHeap(), 0, BufferSize);
        if (NewData == NULL)
        {
            return STATUS_NO_MEMORY;
        }

        /* Copy the old buffer to the new one */
        RtlCopyMemory(NewData, Context->Data, Context->Data->CurrentSize);

        /* Free the old buffer and use the new one */
        RtlFreeHeap(RtlGetProcessHeap(), 0, Context->Data);
        Context->Data = NewData;
        NewData->BufferSize = BufferSize;
    }

    /* Get the next action record */
    Action = (RXACT_ACTION *)((PUCHAR)Context->Data + Context->Data->CurrentSize);

    /* Fill in the fields */
    Action->Size = ActionSize;
    Action->Type = ActionType;
    Action->KeyName = *KeyName;
    Action->ValueName = *ValueName;
    Action->ValueType = ValueType;
    Action->ValueDataSize = ValueDataSize;
    Action->KeyHandle = KeyHandle;

    /* Copy the key name (and convert the pointer to a buffer offset) */
    CurrentOffset = Context->Data->CurrentSize + sizeof(RXACT_ACTION);
    Action->KeyName.Buffer = UlongToPtr(CurrentOffset);
    RtlCopyMemory((PUCHAR)Context->Data + CurrentOffset,
                  KeyName->Buffer,
                  KeyName->Length);

    /* Copy the value name (and convert the pointer to a buffer offset) */
    CurrentOffset += ALIGN_UP_BY(KeyName->Length, sizeof(ULONG));
    Action->ValueName.Buffer = UlongToPtr(CurrentOffset);
    RtlCopyMemory((PUCHAR)Context->Data + CurrentOffset,
                  ValueName->Buffer,
                  ValueName->Length);

    /* Update the offset */
    CurrentOffset += ALIGN_UP_BY(ValueName->Length, sizeof(ULONG));

    /* Is this a set action? */
    if (ActionType == RXactSetValueKey)
    {
        /* Copy the key value data as well */
        Action->ValueData = UlongToPtr(CurrentOffset);
        RtlCopyMemory((PUCHAR)Context->Data + CurrentOffset,
                      ValueData,
                      ValueDataSize);
        CurrentOffset += ALIGN_UP_BY(ValueDataSize, sizeof(ULONG));
    }

    /* Update data site and action count */
    Context->Data->CurrentSize = CurrentOffset;
    Context->Data->ActionCount++;

    return STATUS_SUCCESS;
}
コード例 #3
0
ファイル: heap.c プロジェクト: killvxk/NT_OS
PVOID
HeapCreate(
    SIZE_T MaximumSize,
    TYPE_OF_MEMORY MemoryType)
{
    PHEAP Heap;
    PHEAP_BLOCK Block;
    SIZE_T Remaining;
    USHORT PreviousSize;
    TRACE("HeapCreate(MemoryType=%ld)\n", MemoryType);

    /* Allocate some memory for the heap */
    MaximumSize = ALIGN_UP_BY(MaximumSize, MM_PAGE_SIZE);
    Heap = /*MmAllocateMemoryWithType*/VaToPa(MmHeapAllocEx(MaximumSize/*, MemoryType*/));
    if (!Heap)
    {
        ERR("HEAP: Failed to allocate heap of size 0x%lx, Type\n",
            MaximumSize, MemoryType);
        return NULL;
    }

    /* Initialize the heap header */
    Heap->MaximumSize = MaximumSize;
    Heap->CurrentAllocBytes = 0;
    Heap->MaxAllocBytes = 0;
    Heap->NumAllocs = 0;
    Heap->NumFrees = 0;
    Heap->LargestAllocation = 0;

    /* Calculate what's left to process */
    Remaining = (MaximumSize - sizeof(HEAP)) / sizeof(HEAP_BLOCK);
    TRACE("Remaining = %ld\n", Remaining);

    /* Substract 2 for the terminating entry (header + free entry) */
    Remaining -= 2;

    Block = &Heap->Blocks;
    PreviousSize = 0;

    /* Create free blocks */
    while (Remaining > 1)
    {
        /* Initialize this free block */
        Block->Size = (USHORT)min(MAXUSHORT, Remaining - 1);
        Block->PreviousSize = PreviousSize;
        Block->Tag = 0;
        Block->Data[0].Flink = (Block - &Heap->Blocks) + Block->Size + 1;
        Block->Data[0].Blink = (Block - &Heap->Blocks) - 1 - PreviousSize;

        /* Substract current block size from remainder */
        Remaining -= (Block->Size + 1);

        /* Go to next block */
        PreviousSize = Block->Size;
        Block = Block + Block->Size + 1;

        TRACE("Remaining = %ld\n", Remaining);
    }

    /* Now finish with a terminating block */
    Heap->TerminatingBlock = Block - &Heap->Blocks;
    Block->Size = 0;
    Block->PreviousSize = PreviousSize;
    Block->Tag = 'dnE#';
    Block->Data[0].Flink = 0;
    Block->Data[0].Blink = (Block - &Heap->Blocks) - 1 - PreviousSize;
    Heap->Blocks.Data[0].Blink = Heap->TerminatingBlock;

    return Heap;
}
コード例 #4
0
ファイル: pcmem.c プロジェクト: RPG-7/reactos
PFREELDR_MEMORY_DESCRIPTOR
PcMemGetMemoryMap(ULONG *MemoryMapSize)
{
    ULONG i, EntryCount;
    ULONG ExtendedMemorySizeAtOneMB;
    ULONG ExtendedMemorySizeAtSixteenMB;
    ULONG EbdaBase, EbdaSize;
    TRACE("PcMemGetMemoryMap()\n");

    EntryCount = PcMemGetBiosMemoryMap(PcMemoryMap, MAX_BIOS_DESCRIPTORS);

    /* If the BIOS didn't provide a memory map, synthesize one */
    if (EntryCount == 0)
    {
        GetExtendedMemoryConfiguration(&ExtendedMemorySizeAtOneMB,
                                       &ExtendedMemorySizeAtSixteenMB);

        /* Conventional memory */
        AddMemoryDescriptor(PcMemoryMap,
                            MAX_BIOS_DESCRIPTORS,
                            0,
                            PcMemGetConventionalMemorySize() * 1024 / PAGE_SIZE,
                            LoaderFree);

        /* Extended memory */
        PcMapCount = AddMemoryDescriptor(PcMemoryMap,
                                         MAX_BIOS_DESCRIPTORS,
                                         1024 * 1024 / PAGE_SIZE,
                                         ExtendedMemorySizeAtOneMB * 1024 / PAGE_SIZE,
                                         LoaderFree);

        if (ExtendedMemorySizeAtSixteenMB != 0)
        {
            /* Extended memory at 16MB */
            PcMapCount = AddMemoryDescriptor(PcMemoryMap,
                                             MAX_BIOS_DESCRIPTORS,
                                             0x1000000 / PAGE_SIZE,
                                             ExtendedMemorySizeAtSixteenMB * 64 * 1024 / PAGE_SIZE,
                                             LoaderFree);
        }

        /* Check if we have an EBDA and get it's location */
        if (GetEbdaLocation(&EbdaBase, &EbdaSize))
        {
            /* Add the descriptor */
            PcMapCount = AddMemoryDescriptor(PcMemoryMap,
                                             MAX_BIOS_DESCRIPTORS,
                                             (EbdaBase / PAGE_SIZE),
                                             ADDRESS_AND_SIZE_TO_SPAN_PAGES(EbdaBase, EbdaSize),
                                             LoaderFirmwarePermanent);
        }
    }

    /* Setup some protected ranges */
    SetMemory(0x000000, 0x01000, LoaderFirmwarePermanent); // Realmode IVT / BDA
    SetMemory(0x0A0000, 0x50000, LoaderFirmwarePermanent); // Video memory
    SetMemory(0x0F0000, 0x10000, LoaderSpecialMemory); // ROM
    SetMemory(0xFFF000, 0x01000, LoaderSpecialMemory); // unusable memory (do we really need this?)

    /* Reserve some static ranges for freeldr */
    ReserveMemory(0x1000, STACKLOW - 0x1000, LoaderFirmwareTemporary, "BIOS area");
    ReserveMemory(STACKLOW, STACKADDR - STACKLOW, LoaderOsloaderStack, "FreeLdr stack");
    ReserveMemory(FREELDR_BASE, FrLdrImageSize, LoaderLoadedProgram, "FreeLdr image");

    /* Default to 1 page above freeldr for the disk read buffer */
    DiskReadBuffer = (PUCHAR)ALIGN_UP_BY(FREELDR_BASE + FrLdrImageSize, PAGE_SIZE);
    DiskReadBufferSize = PAGE_SIZE;

    /* Scan for free range above freeldr image */
    for (i = 0; i < PcMapCount; i++)
    {
        if ((PcMemoryMap[i].BasePage > (FREELDR_BASE / PAGE_SIZE)) &&
            (PcMemoryMap[i].MemoryType == LoaderFree))
        {
            /* Use this range for the disk read buffer */
            DiskReadBuffer = (PVOID)(PcMemoryMap[i].BasePage * PAGE_SIZE);
            DiskReadBufferSize = min(PcMemoryMap[i].PageCount * PAGE_SIZE,
                                     MAX_DISKREADBUFFER_SIZE);
            break;
        }
    }

    TRACE("DiskReadBuffer=%p, DiskReadBufferSize=%lx\n",
          DiskReadBuffer, DiskReadBufferSize);

    /* Now reserve the range for the disk read buffer */
    ReserveMemory((ULONG_PTR)DiskReadBuffer,
                  DiskReadBufferSize,
                  LoaderFirmwareTemporary,
                  "Disk read buffer");

    TRACE("Dumping resulting memory map:\n");
    for (i = 0; i < PcMapCount; i++)
    {
        TRACE("BasePage=0x%lx, PageCount=0x%lx, Type=%s\n",
              PcMemoryMap[i].BasePage,
              PcMemoryMap[i].PageCount,
              MmGetSystemMemoryMapTypeString(PcMemoryMap[i].MemoryType));
    }

    *MemoryMapSize = PcMapCount;
    return PcMemoryMap;
}
コード例 #5
0
ファイル: pcmem.c プロジェクト: RPG-7/reactos
static
ULONG
PcMemGetBiosMemoryMap(PFREELDR_MEMORY_DESCRIPTOR MemoryMap, ULONG MaxMemoryMapSize)
{
    REGS Regs;
    ULONGLONG RealBaseAddress, EndAddress, RealSize;
    TYPE_OF_MEMORY MemoryType;
    ULONG Size;
    ASSERT(PcBiosMapCount == 0);

    TRACE("GetBiosMemoryMap()\n");

    /* Make sure the usable memory is large enough. To do this we check the 16
       bit value at address 0x413 inside the BDA, which gives us the usable size
       in KB */
    Size = (*(PUSHORT)(ULONG_PTR)0x413) * 1024;
    if (Size < MEMORY_MARGIN)
    {
        FrLdrBugCheckWithMessage(
            MEMORY_INIT_FAILURE,
            __FILE__,
            __LINE__,
            "The BIOS reported a usable memory range up to 0x%x, which is too small!\n\n"
            "If you see this, please report to the ReactOS team!",
            Size);
    }


    /* Int 15h AX=E820h
     * Newer BIOSes - GET SYSTEM MEMORY MAP
     *
     * AX = E820h
     * EAX = 0000E820h
     * EDX = 534D4150h ('SMAP')
     * EBX = continuation value or 00000000h to start at beginning of map
     * ECX = size of buffer for result, in bytes (should be >= 20 bytes)
     * ES:DI -> buffer for result
     * Return:
     * CF clear if successful
     * EAX = 534D4150h ('SMAP')
     * ES:DI buffer filled
     * EBX = next offset from which to copy or 00000000h if all done
     * ECX = actual length returned in bytes
     * CF set on error
     * AH = error code (86h)
     */
    Regs.x.ebx = 0x00000000;

    while (PcBiosMapCount < MAX_BIOS_DESCRIPTORS)
    {
        /* Setup the registers for the BIOS call */
        Regs.x.eax = 0x0000E820;
        Regs.x.edx = 0x534D4150; /* ('SMAP') */
        /* Regs.x.ebx = 0x00000001;  Continuation value already set */
        Regs.x.ecx = sizeof(BIOS_MEMORY_MAP);
        Regs.w.es = BIOSCALLBUFSEGMENT;
        Regs.w.di = BIOSCALLBUFOFFSET;
        Int386(0x15, &Regs, &Regs);

        TRACE("Memory Map Entry %d\n", PcBiosMapCount);
        TRACE("Int15h AX=E820h\n");
        TRACE("EAX = 0x%x\n", Regs.x.eax);
        TRACE("EBX = 0x%x\n", Regs.x.ebx);
        TRACE("ECX = 0x%x\n", Regs.x.ecx);
        TRACE("CF set = %s\n", (Regs.x.eflags & EFLAGS_CF) ? "TRUE" : "FALSE");

        /* If the BIOS didn't return 'SMAP' in EAX then
         * it doesn't support this call. If CF is set, we're done */
        if (Regs.x.eax != 0x534D4150 || !INT386_SUCCESS(Regs))
        {
            break;
        }

        /* Copy data to global buffer */
        RtlCopyMemory(&PcBiosMemoryMap[PcBiosMapCount], (PVOID)BIOSCALLBUFFER, Regs.x.ecx);

        TRACE("BaseAddress: 0x%llx\n", PcBiosMemoryMap[PcBiosMapCount].BaseAddress);
        TRACE("Length: 0x%llx\n", PcBiosMemoryMap[PcBiosMapCount].Length);
        TRACE("Type: 0x%lx\n", PcBiosMemoryMap[PcBiosMapCount].Type);
        TRACE("Reserved: 0x%lx\n", PcBiosMemoryMap[PcBiosMapCount].Reserved);
        TRACE("\n");

        /* Check if this is free memory */
        if (PcBiosMemoryMap[PcBiosMapCount].Type == BiosMemoryUsable)
        {
            MemoryType = LoaderFree;

            /* Align up base of memory range */
            RealBaseAddress = ALIGN_UP_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
                                          PAGE_SIZE);

            /* Calculate aligned EndAddress */
            EndAddress = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
                         PcBiosMemoryMap[PcBiosMapCount].Length;
            EndAddress = ALIGN_DOWN_BY(EndAddress, PAGE_SIZE);

            /* Check if there is anything left */
            if (EndAddress <= RealBaseAddress)
            {
                /* This doesn't span any page, so continue with next range */
                continue;
            }

            /* Calculate the length of the aligned range */
            RealSize = EndAddress - RealBaseAddress;
        }
        else
        {
            if (PcBiosMemoryMap[PcBiosMapCount].Type == BiosMemoryReserved)
                MemoryType = LoaderFirmwarePermanent;
            else
                MemoryType = LoaderSpecialMemory;

            /* Align down base of memory area */
            RealBaseAddress = ALIGN_DOWN_BY(PcBiosMemoryMap[PcBiosMapCount].BaseAddress,
                                            PAGE_SIZE);

            /* Calculate the length after aligning the base */
            RealSize = PcBiosMemoryMap[PcBiosMapCount].BaseAddress +
                       PcBiosMemoryMap[PcBiosMapCount].Length - RealBaseAddress;
            RealSize = ALIGN_UP_BY(RealSize, PAGE_SIZE);
        }

        /* Check if we can add this descriptor */
        if ((RealSize >= MM_PAGE_SIZE) && (PcMapCount < MaxMemoryMapSize))
        {
            /* Add the descriptor */
            PcMapCount = AddMemoryDescriptor(PcMemoryMap,
                                           MAX_BIOS_DESCRIPTORS,
                                           (PFN_NUMBER)(RealBaseAddress / MM_PAGE_SIZE),
                                           (PFN_NUMBER)(RealSize / MM_PAGE_SIZE),
                                           MemoryType);
        }

        PcBiosMapCount++;

        /* If the continuation value is zero or the
         * carry flag is set then this was
         * the last entry so we're done */
        if (Regs.x.ebx == 0x00000000)
        {
            TRACE("End Of System Memory Map!\n\n");
            break;
        }
    }

    TRACE("GetBiosMemoryMap end, PcBiosMapCount = %ld\n", PcBiosMapCount);
    return PcBiosMapCount;
}
コード例 #6
0
ファイル: descriptor.c プロジェクト: reactos/reactos
BOOLEAN
MmMdFindSatisfyingRegion (
    _In_ PBL_MEMORY_DESCRIPTOR Descriptor,
    _Out_ PBL_MEMORY_DESCRIPTOR NewDescriptor,
    _In_ ULONGLONG Pages,
    _In_ PBL_ADDRESS_RANGE BaseRange,
    _In_ PBL_ADDRESS_RANGE VirtualRange,
    _In_ BOOLEAN TopDown,
    _In_ BL_MEMORY_TYPE MemoryType,
    _In_ ULONG Flags,
    _In_ ULONG Alignment
    )
{
    ULONGLONG BaseMin, BaseMax;
    ULONGLONG VirtualPage, BasePage;

    /* Extract the minimum and maximum range */
    BaseMin = BaseRange->Minimum;
    BaseMax = BaseRange->Maximum;

    /* Don't go below where the descriptor starts */
    if (BaseMin < Descriptor->BasePage)
    {
        BaseMin = Descriptor->BasePage;
    }

    /* Don't go beyond where the descriptor ends */
    if (BaseMax > (Descriptor->BasePage + Descriptor->PageCount - 1))
    {
        BaseMax = (Descriptor->BasePage + Descriptor->PageCount - 1);
    }

    /* Check for start overflow */
    if (BaseMin > BaseMax)
    {
        EfiPrintf(L"Descriptor overflow\r\n");
        return FALSE;
    }

    /* Align the base as required */
    if (Alignment != 1)
    {
        BaseMin = ALIGN_UP_BY(BaseMin, Alignment);
    }

    /* Check for range overflow */
    if (((BaseMin + Pages - 1) < BaseMin) || ((BaseMin + Pages - 1) > BaseMax))
    {
        return FALSE;
    }

    /* Check if this was a top-down request */
    if (TopDown)
    {
        /* Then get the highest page possible */
        BasePage = BaseMax - Pages + 1;
        if (Alignment != 1)
        {
            /* Align it as needed */
            BasePage = ALIGN_DOWN_BY(BasePage, Alignment);
        }
    }
    else
    {
        /* Otherwise, get the lowest page possible */
        BasePage = BaseMin;
    }

    /* If a virtual address range was passed in, this must be a virtual descriptor */
    if (((VirtualRange->Minimum) || (VirtualRange->Maximum)) &&
        !(Descriptor->VirtualPage))
    {
        return FALSE;
    }

    /* Any mapped page already? */
    if (Descriptor->VirtualPage)
    {
        EfiPrintf(L"Virtual memory not yet supported\r\n");
        return FALSE;
    }
    else
    {
        /* Nothing to worry about */
        VirtualPage = 0;
    }

    /* Bail out if the memory type attributes don't match */
    if ((((Flags & 0xFF) & (Descriptor->Flags & 0xFF)) != (Flags & 0xFF)) ||
        (((Flags & 0xFF00) & (Descriptor->Flags & 0xFF00)) != (Flags & 0xFF00)))
    {
        EfiPrintf(L"Incorrect memory attributes\r\n");
        return FALSE;
    }

    /* Bail out if the allocation flags don't match */
    if (((Flags ^ Descriptor->Flags) & (BlMemoryRuntime | BlMemoryReserved | BlMemoryUnknown)))
    {
        //EfiPrintf(L"Incorrect memory allocation flags\r\n");
        return FALSE;
    }

    /* Bail out if the type doesn't match */
    if (Descriptor->Type != MemoryType)
    {
        //EfiPrintf(L"Incorrect descriptor type: %lx %lx\r\n", Descriptor->Type, MemoryType);
        return FALSE;
    }

    /* We have a matching region, fill out the descriptor for it */
    NewDescriptor->BasePage = BasePage;
    NewDescriptor->PageCount = Pages;
    NewDescriptor->Type = Descriptor->Type;
    NewDescriptor->VirtualPage = VirtualPage;
    NewDescriptor->Flags = Descriptor->Flags;
    //EfiPrintf(L"Found a matching descriptor: %08I64X with %08I64X pages\r\n", BasePage, Pages);
    return TRUE;
}