Пример #1
0
BOOL WINAPI
IsValidDevmodeW(PDEVMODEW pDevmode, size_t DevmodeSize)
{
    PMINIMUM_SIZE_TABLE pTable = MinimumSizeW;
    WORD wRequiredSize;

    TRACE("IsValidDevmodeW(%p, %lu)\n", pDevmode, DevmodeSize);

    // Check if a Devmode was given at all.
    if (!pDevmode)
        goto Failure;

    // Verify that DevmodeSize is large enough to hold the public and private members of the structure.
    if (DevmodeSize < pDevmode->dmSize + pDevmode->dmDriverExtra)
        goto Failure;

    // If the structure has private members, the public structure must be 32-bit packed.
    if (pDevmode->dmDriverExtra && pDevmode->dmSize % 4)
        goto Failure;

    // Now determine the minimum possible dmSize based on the given fields in dmFields.
    wRequiredSize = FIELD_OFFSET(DEVMODEW, dmFields) + RTL_FIELD_SIZE(DEVMODEW, dmFields);

    while (pTable->dwField)
    {
        if (pDevmode->dmFields & pTable->dwField)
        {
            wRequiredSize = pTable->wSize;
            break;
        }

        pTable++;
    }

    // Verify that the value in dmSize is big enough for the used fields.
    if (pDevmode->dmSize < wRequiredSize)
        goto Failure;

    // Check if dmDeviceName and (if used) dmFormName are null-terminated.
    // Fix this if they aren't.
    _FixStringW(pDevmode->dmDeviceName, sizeof(pDevmode->dmDeviceName));
    if (pDevmode->dmFields & DM_FORMNAME)
        _FixStringW(pDevmode->dmFormName, sizeof(pDevmode->dmFormName));

    // Return success without setting the error code.
    return TRUE;

Failure:
    SetLastError(ERROR_INVALID_DATA);
    return FALSE;
}
Пример #2
0
NTSTATUS NTAPI
ConDrvWriteConsoleOutputString(IN PCONSOLE Console,
                               IN PTEXTMODE_SCREEN_BUFFER Buffer,
                               IN CODE_TYPE CodeType,
                               IN PVOID StringBuffer,
                               IN ULONG NumCodesToWrite,
                               IN PCOORD WriteCoord,
                               // OUT PCOORD EndCoord,
                               OUT PULONG NumCodesWritten OPTIONAL)
{
    NTSTATUS Status = STATUS_SUCCESS;
    PVOID WriteBuffer = NULL;
    PWCHAR tmpString = NULL;
    ULONG X, Y, Length; // , Written = 0;
    ULONG CodeSize;
    PCHAR_INFO Ptr;

    if (Console == NULL || Buffer == NULL || WriteCoord == NULL /* || EndCoord == NULL */)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Validity checks */
    ASSERT(Console == Buffer->Header.Console);
    ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToWrite == 0));

    //
    // FIXME: Make overflow checks on WriteCoord !!!!!!
    //

    if (NumCodesWritten) *NumCodesWritten = 0;

    switch (CodeType)
    {
        case CODE_ASCII:
            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
            break;

        case CODE_UNICODE:
            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
            break;

        case CODE_ATTRIBUTE:
            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
            break;

        default:
            return STATUS_INVALID_PARAMETER;
    }

    if (CodeType == CODE_ASCII)
    {
        /* Convert the ASCII string into Unicode before writing it to the console */
        Length = MultiByteToWideChar(Console->OutputCodePage, 0,
                                     (PCHAR)StringBuffer,
                                     NumCodesToWrite,
                                     NULL, 0);
        tmpString = WriteBuffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length * sizeof(WCHAR));
        if (WriteBuffer)
        {
            MultiByteToWideChar(Console->OutputCodePage, 0,
                                (PCHAR)StringBuffer,
                                NumCodesToWrite,
                                (PWCHAR)WriteBuffer, Length);
        }
        else
        {
            Status = STATUS_NO_MEMORY;
        }

        // FIXME: Quick fix: fix the CodeType and CodeSize since the
        // ASCII string was converted into UNICODE.
        // A proper fix needs to be written.
        CodeType = CODE_UNICODE;
        CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
    }
    else
    {
        /* For CODE_UNICODE or CODE_ATTRIBUTE, we are already OK */
        WriteBuffer = StringBuffer;
    }

    if (WriteBuffer == NULL || !NT_SUCCESS(Status)) goto Cleanup;

    X = WriteCoord->X;
    Y = (WriteCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;
    Length = NumCodesToWrite;
    // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work
    // Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X]; // May work

    while (Length--)
    {
        // Ptr = ConioCoordToPointer(Buffer, X, Y); // Doesn't work either
        Ptr = &Buffer->Buffer[X + Y * Buffer->ScreenBufferSize.X];

        switch (CodeType)
        {
            case CODE_ASCII:
            case CODE_UNICODE:
                Ptr->Char.UnicodeChar = *(PWCHAR)WriteBuffer;
                break;

            case CODE_ATTRIBUTE:
                Ptr->Attributes = *(PWORD)WriteBuffer;
                break;
        }
        WriteBuffer = (PVOID)((ULONG_PTR)WriteBuffer + CodeSize);
        // ++Ptr;

        // Written++;
        if (++X == Buffer->ScreenBufferSize.X)
        {
            X = 0;

            if (++Y == Buffer->ScreenBufferSize.Y)
            {
                Y = 0;
            }
        }
    }

    if ((PCONSOLE_SCREEN_BUFFER)Buffer == Console->ActiveBuffer)
    {
        SMALL_RECT UpdateRect;
        ConioComputeUpdateRect(Buffer, &UpdateRect, WriteCoord, NumCodesToWrite);
        TermDrawRegion(Console, &UpdateRect);
    }

    // EndCoord->X = X;
    // EndCoord->Y = (Y + Buffer->ScreenBufferSize.Y - Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;

Cleanup:
    if (tmpString) RtlFreeHeap(RtlGetProcessHeap(), 0, tmpString);

    if (NumCodesWritten) *NumCodesWritten = NumCodesToWrite; // Written;
    return Status;
}
Пример #3
0
NTSTATUS NTAPI
ConDrvReadConsoleOutputString(IN PCONSOLE Console,
                              IN PTEXTMODE_SCREEN_BUFFER Buffer,
                              IN CODE_TYPE CodeType,
                              OUT PVOID StringBuffer,
                              IN ULONG NumCodesToRead,
                              IN PCOORD ReadCoord,
                              // OUT PCOORD EndCoord,
                              OUT PULONG NumCodesRead OPTIONAL)
{
    SHORT Xpos, Ypos;
    PVOID ReadBuffer;
    ULONG i;
    ULONG CodeSize;
    PCHAR_INFO Ptr;

    if (Console == NULL || Buffer == NULL || ReadCoord == NULL /* || EndCoord == NULL */)
    {
        return STATUS_INVALID_PARAMETER;
    }

    /* Validity checks */
    ASSERT(Console == Buffer->Header.Console);
    ASSERT((StringBuffer != NULL) || (StringBuffer == NULL && NumCodesToRead == 0));

    //
    // FIXME: Make overflow checks on ReadCoord !!!!!!
    //

    if (NumCodesRead) *NumCodesRead = 0;

    switch (CodeType)
    {
        case CODE_ASCII:
            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, AsciiChar);
            break;

        case CODE_UNICODE:
            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, UnicodeChar);
            break;

        case CODE_ATTRIBUTE:
            CodeSize = RTL_FIELD_SIZE(CODE_ELEMENT, Attribute);
            break;

        default:
            return STATUS_INVALID_PARAMETER;
    }

    ReadBuffer = StringBuffer;
    Xpos = ReadCoord->X;
    Ypos = (ReadCoord->Y + Buffer->VirtualY) % Buffer->ScreenBufferSize.Y;

    /*
     * MSDN (ReadConsoleOutputAttribute and ReadConsoleOutputCharacter) :
     *
     * If the number of attributes (resp. characters) to be read from extends
     * beyond the end of the specified screen buffer row, attributes (resp.
     * characters) are read from the next row. If the number of attributes
     * (resp. characters) to be read from extends beyond the end of the console
     * screen buffer, attributes (resp. characters) up to the end of the console
     * screen buffer are read.
     *
     * TODO: Do NOT loop up to NumCodesToRead, but stop before
     * if we are going to overflow...
     */
    // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work
    for (i = 0; i < min(NumCodesToRead, (ULONG)Buffer->ScreenBufferSize.X * Buffer->ScreenBufferSize.Y); ++i)
    {
        // Ptr = ConioCoordToPointer(Buffer, Xpos, Ypos); // Doesn't work either
        Ptr = &Buffer->Buffer[Xpos + Ypos * Buffer->ScreenBufferSize.X];

        switch (CodeType)
        {
            case CODE_ASCII:
                ConsoleOutputUnicodeToAnsiChar(Console, (PCHAR)ReadBuffer, &Ptr->Char.UnicodeChar);
                break;

            case CODE_UNICODE:
                *(PWCHAR)ReadBuffer = Ptr->Char.UnicodeChar;
                break;

            case CODE_ATTRIBUTE:
                *(PWORD)ReadBuffer = Ptr->Attributes;
                break;
        }
        ReadBuffer = (PVOID)((ULONG_PTR)ReadBuffer + CodeSize);
        // ++Ptr;

        Xpos++;

        if (Xpos == Buffer->ScreenBufferSize.X)
        {
            Xpos = 0;
            Ypos++;

            if (Ypos == Buffer->ScreenBufferSize.Y)
            {
                Ypos = 0;
            }
        }
    }

    // EndCoord->X = Xpos;
    // EndCoord->Y = (Ypos - Buffer->VirtualY + Buffer->ScreenBufferSize.Y) % Buffer->ScreenBufferSize.Y;

    if (NumCodesRead)
        *NumCodesRead = (ULONG)((ULONG_PTR)ReadBuffer - (ULONG_PTR)StringBuffer) / CodeSize;
    // <= NumCodesToRead

    return STATUS_SUCCESS;
}
static
VOID RSSCalcHash_Unsafe(
                PARANDIS_RSS_PARAMS *RSSParameters,
                PVOID dataBuffer,
                PNET_PACKET_INFO packetInfo)
{
    HASH_CALC_SG_BUF_ENTRY sgBuff[3];
    ULONG hashTypes = NDIS_RSS_HASH_TYPE_FROM_HASH_INFO(RSSParameters->ActiveHashingSettings.HashInformation);

    if(packetInfo->isIP4)
    {
        if(packetInfo->isTCP && (hashTypes & NDIS_HASH_TCP_IPV4))
        {
            IPv4Header *pIpHeader = (IPv4Header *) RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen);
            TCPHeader *pTCPHeader = (TCPHeader *) RtlOffsetToPointer(pIpHeader, packetInfo->L3HdrLen);

            sgBuff[0].chunkPtr = RtlOffsetToPointer(pIpHeader, FIELD_OFFSET(IPv4Header, ip_src));
            sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv4Header, ip_src) + RTL_FIELD_SIZE(IPv4Header, ip_dest);
            sgBuff[1].chunkPtr = RtlOffsetToPointer(pTCPHeader, FIELD_OFFSET(TCPHeader, tcp_src));
            sgBuff[1].chunkLen = RTL_FIELD_SIZE(TCPHeader, tcp_src) + RTL_FIELD_SIZE(TCPHeader, tcp_dest);

            packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 2, &RSSParameters->ActiveHashingSettings.HashSecretKey[0]);
            packetInfo->RSSHash.Type = NDIS_HASH_TCP_IPV4;
            packetInfo->RSSHash.Function = NdisHashFunctionToeplitz;
            return;
        }

        if(hashTypes & NDIS_HASH_IPV4)
        {
            sgBuff[0].chunkPtr = RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen + FIELD_OFFSET(IPv4Header, ip_src));
            sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv4Header, ip_src) + RTL_FIELD_SIZE(IPv4Header, ip_dest);

            packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 1, RSSParameters->ActiveHashingSettings.HashSecretKey);
            packetInfo->RSSHash.Type = NDIS_HASH_IPV4;
            packetInfo->RSSHash.Function = NdisHashFunctionToeplitz;
            return;
        }
    }
    else if(packetInfo->isIP6)
    {
        if(packetInfo->isTCP)
        {
            if(hashTypes & (NDIS_HASH_TCP_IPV6 | NDIS_HASH_TCP_IPV6_EX))
            {
                IPv6Header *pIpHeader =  (IPv6Header *) RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen);
                TCPHeader  *pTCPHeader = (TCPHeader *) RtlOffsetToPointer(pIpHeader, packetInfo->L3HdrLen);

                sgBuff[0].chunkPtr = (PCHAR) GetIP6SrcAddrForHash(dataBuffer, packetInfo, hashTypes);
                sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_src_address);
                sgBuff[1].chunkPtr = (PCHAR) GetIP6DstAddrForHash(dataBuffer, packetInfo, hashTypes);
                sgBuff[1].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_dst_address);
                sgBuff[2].chunkPtr = RtlOffsetToPointer(pTCPHeader, FIELD_OFFSET(TCPHeader, tcp_src));
                sgBuff[2].chunkLen = RTL_FIELD_SIZE(TCPHeader, tcp_src) + RTL_FIELD_SIZE(TCPHeader, tcp_dest);

                packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 3, RSSParameters->ActiveHashingSettings.HashSecretKey);
                packetInfo->RSSHash.Type = (hashTypes & NDIS_HASH_TCP_IPV6_EX) ? NDIS_HASH_TCP_IPV6_EX : NDIS_HASH_TCP_IPV6;
                packetInfo->RSSHash.Function = NdisHashFunctionToeplitz;
                return;
            }
        }

        if(hashTypes & (NDIS_HASH_IPV6 | NDIS_HASH_IPV6_EX))
        {
            sgBuff[0].chunkPtr = (PCHAR) GetIP6SrcAddrForHash(dataBuffer, packetInfo, hashTypes);
            sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_src_address);
            sgBuff[1].chunkPtr = (PCHAR) GetIP6DstAddrForHash(dataBuffer, packetInfo, hashTypes);
            sgBuff[1].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_dst_address);

            packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 2, RSSParameters->ActiveHashingSettings.HashSecretKey);
            packetInfo->RSSHash.Type = (hashTypes & NDIS_HASH_IPV6_EX) ? NDIS_HASH_IPV6_EX : NDIS_HASH_IPV6;
            packetInfo->RSSHash.Function = NdisHashFunctionToeplitz;
            return;
        }

        if(hashTypes & NDIS_HASH_IPV6)
        {
            IPv6Header *pIpHeader = (IPv6Header *) RtlOffsetToPointer(dataBuffer, packetInfo->L2HdrLen);

            sgBuff[0].chunkPtr = RtlOffsetToPointer(pIpHeader, FIELD_OFFSET(IPv6Header, ip6_src_address));
            sgBuff[0].chunkLen = RTL_FIELD_SIZE(IPv6Header, ip6_src_address) + RTL_FIELD_SIZE(IPv6Header, ip6_dst_address);

            packetInfo->RSSHash.Value = ToeplitsHash(sgBuff, 2, RSSParameters->ActiveHashingSettings.HashSecretKey);
            packetInfo->RSSHash.Type = NDIS_HASH_IPV6;
            packetInfo->RSSHash.Function = NdisHashFunctionToeplitz;
            return;
        }
    }

    packetInfo->RSSHash.Value = 0;
    packetInfo->RSSHash.Type = 0;
    packetInfo->RSSHash.Function = 0;
}
Пример #5
0
NTSTATUS ModifySelfSizeOfImage(LPWSTR ExeFullPath, LPWSTR CommandLine, ULONG SizeOfImage)
{
    BOOL                        Result;
    ULONG                       Length;
    PVOID                       FakeCPInfoBuffer;
    WCHAR                       CmdFullPath[MAX_NTPATH];
    PWCHAR                      CmdLineBuffer;
    NTSTATUS                    Status;
    PLDR_MODULE                 LdrModule;
    PIMAGE_DOS_HEADER           DosHeader;
    PIMAGE_NT_HEADERS           NtHeader;
    PIMAGE_SECTION_HEADER       SectionHeader;
    FAKE_CREATE_PROCESS_INFO   *fcpi;
    PROCESS_INFORMATION         ProcessInformation;
    CONTEXT                     Context;
    NtFileDisk                 file;
    UNICODE_STRING              ExeNtPath, *ProcessCommandLine;

    UNREFERENCED_PARAMETER(CommandLine);

    LdrModule = Nt_FindLdrModuleByName(NULL);

    DosHeader   = (PIMAGE_DOS_HEADER)&__ImageBase;
    NtHeader    = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);

    fcpi = (FAKE_CREATE_PROCESS_INFO *)AllocStack(0x2000);
    fcpi->PeHeaderSize = (ULONG_PTR)(IMAGE_FIRST_SECTION(NtHeader) + NtHeader->FileHeader.NumberOfSections) - (ULONG_PTR)DosHeader;

    Status = file.Open(LdrModule->FullDllName.Buffer);
    if (!NT_SUCCESS(Status))
        return Status;

    Status = file.Read(fcpi->PeHeader, fcpi->PeHeaderSize);
    if (!NT_SUCCESS(Status))
        return Status;

    CmdLineBuffer = (PWCHAR)((ULONG_PTR)fcpi->PeHeader + fcpi->PeHeaderSize);

    fcpi->CommandLine.Buffer        = CmdLineBuffer;
    fcpi->CommandLine.Length        = (USHORT)(StrLengthW(ExeFullPath) * sizeof(WCHAR));

    ProcessCommandLine = &Nt_CurrentPeb()->ProcessParameters->CommandLine;
    CopyMemory(CmdLineBuffer, ProcessCommandLine->Buffer, ProcessCommandLine->Length);
    *(PULONG_PTR)&CmdLineBuffer += ProcessCommandLine->Length;
    CmdLineBuffer[0] = 0;

    fcpi->CommandLine.Length        = ProcessCommandLine->Length;
    fcpi->CommandLine.MaximumLength = fcpi->CommandLine.Length + sizeof(WCHAR);

    ++CmdLineBuffer;
    CmdLineBuffer = (PWCHAR)ROUND_UP((ULONG_PTR)CmdLineBuffer, 16);

    RtlDosPathNameToNtPathName_U(LdrModule->FullDllName.Buffer, &ExeNtPath, NULL, NULL);

    fcpi->ExeNtPath.Buffer = CmdLineBuffer;
    CopyMemory(CmdLineBuffer, ExeNtPath.Buffer, ExeNtPath.Length);
    *(PULONG_PTR)&CmdLineBuffer += ExeNtPath.Length;
    CmdLineBuffer[0] = 0;

    fcpi->ExeNtPath.Length        = ExeNtPath.Length;
    fcpi->ExeNtPath.MaximumLength = fcpi->ExeNtPath.Length + sizeof(WCHAR);

    *CmdLineBuffer++ = 0;

    RtlFreeUnicodeString(&ExeNtPath);

    DosHeader       = (PIMAGE_DOS_HEADER)fcpi->PeHeader;
    NtHeader        = (PIMAGE_NT_HEADERS)((ULONG_PTR)DosHeader + DosHeader->e_lfanew);
    SectionHeader   = IMAGE_FIRST_SECTION(NtHeader);

    SectionHeader   += NtHeader->FileHeader.NumberOfSections - 1;
    SizeOfImage     -= LdrModule->SizeOfImage;
    SizeOfImage      = ROUND_UP(SizeOfImage, MEMORY_PAGE_SIZE);

    SectionHeader->Misc.VirtualSize = ROUND_UP(SectionHeader->Misc.VirtualSize, MEMORY_PAGE_SIZE) + SizeOfImage;

    if (NtHeader->FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage))
        NtHeader->OptionalHeader.SizeOfImage += SizeOfImage;

    Length = Nt_GetSystemDirectory(CmdFullPath, countof(CmdFullPath));
    StrCopyW(CmdFullPath + Length, L"cmd.exe");

    ProcessInformation.hProcess = NtCurrentProcess();
    ProcessInformation.hThread  = NtCurrentThread();

#if 1
    Result = Nt_CreateProcess(NULL, CmdFullPath, NULL, CREATE_SUSPENDED, NULL, &ProcessInformation);
    if (!Result)
        return STATUS_UNSUCCESSFUL;
#endif

    FakeCPInfoBuffer = NULL;
    LOOP_ONCE
    {
        ULONG_PTR Offset;

        Status = NtDuplicateObject(
                    NtCurrentProcess(),
                    NtCurrentProcess(),
                    ProcessInformation.hProcess,
                    &fcpi->ProcessHandle,
                    0,
                    0,
                    DUPLICATE_SAME_ACCESS
                 );
        if (!NT_SUCCESS(Status))
            break;
/*
        Status = NtDuplicateObject(
                    NtCurrentProcess(),
                    file,
                    ProcessInformation.hProcess,
                    &fcpi->FileHandle,
                    0,
                    0,
                    DUPLICATE_SAME_ACCESS
                 );
        if (!NT_SUCCESS(Status))
            break;
*/
        Status = Nt_AllocateMemory(ProcessInformation.hProcess, &FakeCPInfoBuffer, MEMORY_PAGE_SIZE);
        if (!NT_SUCCESS(Status))
            break;

        fcpi->CreateProcessInternalW    = CreateProcessInternalW;
        fcpi->NtTerminateProcess        = NtTerminateProcess;
        fcpi->LdrShutdownProcess        = LdrShutdownProcess;
        fcpi->NtCreateFile              = NtCreateFile;
        fcpi->NtWriteFile               = NtWriteFile;
        fcpi->NtClose                   = NtClose;
        fcpi->NtWaitForSingleObject     = NtWaitForSingleObject;
        fcpi->InitialDirectory.Buffer   = NULL;

        Offset = (ULONG_PTR)FakeCPInfoBuffer - (ULONG_PTR)fcpi;
        *(PULONG_PTR)&fcpi->CommandLine.Buffer += Offset;
        *(PULONG_PTR)&fcpi->ExeNtPath.Buffer   += Offset;

        Status = Nt_WriteMemory(
                    ProcessInformation.hProcess,
                    FakeCPInfoBuffer,
                    fcpi,
                    (ULONG_PTR)CmdLineBuffer - (ULONG_PTR)fcpi,
                    &Length
                );
        if (!NT_SUCCESS(Status))
            break;

        Context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER;
        Status = NtGetContextThread(ProcessInformation.hThread, &Context);
        if (!NT_SUCCESS(Status))
            break;

        Context.Eip = (ULONG_PTR)FakeCPInfoBuffer + Length;
        Context.Eip = ROUND_UP(Context.Eip, 16);
        Context.Ecx = (ULONG_PTR)FakeCPInfoBuffer;

        Status = Nt_WriteMemory(
                    ProcessInformation.hProcess,
                    (PVOID)Context.Eip,
                    ModifySizeOfImage,
                    (ULONG_PTR)ModifySizeOfImageEnd - (ULONG_PTR)ModifySizeOfImage,
                    &Length
                );
        if (!NT_SUCCESS(Status))
            break;

#if 1
        Status = NtSetContextThread(ProcessInformation.hThread, &Context);
        if (!NT_SUCCESS(Status))
            break;

        Status = NtResumeThread(ProcessInformation.hThread, NULL);
#else
        INLINE_ASM jmp Context.Eip;
#endif
    }

    if (!NT_SUCCESS(Status))
    {
        if (FakeCPInfoBuffer != NULL)
            Nt_FreeMemory(ProcessInformation.hProcess, FakeCPInfoBuffer);

        NtTerminateProcess(ProcessInformation.hProcess, 0);
    }

    NtClose(ProcessInformation.hProcess);
    NtClose(ProcessInformation.hThread);

    return Status;
}
Пример #6
0
NTSTATUS GetExeImageSize(LPWSTR ExeFullPath, PULONG SizeOfImage)
{
    ULONG                   Size;
    NTSTATUS                Status;
    NtFileDisk             file;
    IMAGE_DOS_HEADER        DosHeader;
    IMAGE_NT_HEADERS        NtHeader;
    PIMAGE_OPTIONAL_HEADER  OptionalHeader;
    PIMAGE_SECTION_HEADER   SectionHeader;

    Status = file.Open(ExeFullPath);
    if (!NT_SUCCESS(Status))
        return Status;

    Status = file.Read(&DosHeader, sizeof(DosHeader));
    if (!NT_SUCCESS(Status))
        return Status;

    if (DosHeader.e_magic != IMAGE_DOS_SIGNATURE)
        return STATUS_INVALID_IMAGE_WIN_32;

    Status = file.Seek(DosHeader.e_lfanew, FILE_BEGIN);
    if (!NT_SUCCESS(Status))
        return Status;

    Status = file.Read(&NtHeader, sizeof(NtHeader) - sizeof(NtHeader.OptionalHeader));
    if (!NT_SUCCESS(Status))
        return Status;

    if (NtHeader.Signature != IMAGE_NT_SIGNATURE)
        return STATUS_INVALID_IMAGE_WIN_32;

    if (NtHeader.FileHeader.SizeOfOptionalHeader > FIELD_OFFSET(IMAGE_OPTIONAL_HEADER, SizeOfImage) + RTL_FIELD_SIZE(IMAGE_OPTIONAL_HEADER, SizeOfImage))
    {
        OptionalHeader = (PIMAGE_OPTIONAL_HEADER)AllocStack(NtHeader.FileHeader.SizeOfOptionalHeader);
        Status = file.Read(OptionalHeader, NtHeader.FileHeader.SizeOfOptionalHeader);
        if (!NT_SUCCESS(Status))
            return Status;

        *SizeOfImage = OptionalHeader->SizeOfImage;
        return STATUS_SUCCESS;
    }

    SectionHeader = (PIMAGE_SECTION_HEADER)AllocStack(NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader));
    Status = file.Read(SectionHeader, NtHeader.FileHeader.NumberOfSections * sizeof(*SectionHeader));
    if (!NT_SUCCESS(Status))
        return Status;

    Size = 0;
    for (ULONG NumberOfSections = NtHeader.FileHeader.NumberOfSections; NumberOfSections; --NumberOfSections)
    {
        Size += SectionHeader->Misc.VirtualSize;
        ++SectionHeader;
    }

    Size += ROUND_UP(file.GetCurrentPos(), MEMORY_PAGE_SIZE);
    *SizeOfImage = Size;

    return STATUS_SUCCESS;
}
Пример #7
0
// PENUM_BOOT_ENTRIES_ROUTINE
static NTSTATUS
NTAPI
EnumerateInstallations(
    IN BOOT_STORE_TYPE Type,
    IN PBOOT_STORE_ENTRY BootEntry,
    IN PVOID Parameter OPTIONAL)
{
    PENUM_INSTALLS_DATA Data = (PENUM_INSTALLS_DATA)Parameter;
    PNTOS_OPTIONS Options = (PNTOS_OPTIONS)&BootEntry->OsOptions;
    PNTOS_INSTALLATION NtOsInstall;

    ULONG DiskNumber = 0, PartitionNumber = 0;
    PCWSTR PathComponent = NULL;
    PDISKENTRY DiskEntry = NULL;
    PPARTENTRY PartEntry = NULL;

    UNICODE_STRING SystemRootPath;
    WCHAR SystemRoot[MAX_PATH];

    USHORT Machine;
    UNICODE_STRING VendorName;
    WCHAR VendorNameBuffer[MAX_PATH];


    /* We have a boot entry */

    /* Check for supported boot type "Windows2003" */
    if (BootEntry->OsOptionsLength < sizeof(NTOS_OPTIONS) ||
        RtlCompareMemory(&BootEntry->OsOptions /* Signature */,
                         NTOS_OPTIONS_SIGNATURE,
                         RTL_FIELD_SIZE(NTOS_OPTIONS, Signature)) !=
                         RTL_FIELD_SIZE(NTOS_OPTIONS, Signature))
    {
        /* This is not a ReactOS entry */
        // DPRINT("    An installation '%S' of unsupported type '%S'\n",
               // BootEntry->FriendlyName, BootEntry->Version ? BootEntry->Version : L"n/a");
        DPRINT("    An installation '%S' of unsupported type %lu\n",
               BootEntry->FriendlyName, BootEntry->OsOptionsLength);
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

    /* BootType is Windows2003, now check OsLoadPath */
    if (!Options->OsLoadPath || !*Options->OsLoadPath)
    {
        /* Certainly not a ReactOS installation */
        DPRINT1("    A Win2k3 install '%S' without an ARC path?!\n", BootEntry->FriendlyName);
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

    DPRINT("    Found a candidate Win2k3 install '%S' with ARC path '%S'\n",
           BootEntry->FriendlyName, Options->OsLoadPath);
    // DPRINT("    Found a Win2k3 install '%S' with ARC path '%S'\n",
           // BootEntry->FriendlyName, Options->OsLoadPath);

    // TODO: Normalize the ARC path.

    /*
     * Check whether we already have an installation with this ARC path.
     * If this is the case, stop there.
     */
    NtOsInstall = FindExistingNTOSInstall(Data->List, Options->OsLoadPath, NULL);
    if (NtOsInstall)
    {
        DPRINT("    An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n",
               NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemArcPath);
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

    /*
     * Convert the ARC path into an NT path, from which we will deduce
     * the real disk drive & partition on which the candidate installation
     * resides, as well verifying whether it is indeed an NTOS installation.
     */
    RtlInitEmptyUnicodeString(&SystemRootPath, SystemRoot, sizeof(SystemRoot));
    if (!ArcPathToNtPath(&SystemRootPath, Options->OsLoadPath, Data->PartList))
    {
        DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", Options->OsLoadPath);
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

    DPRINT("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n",
           Options->OsLoadPath, &SystemRootPath);

    /*
     * Check whether we already have an installation with this NT path.
     * If this is the case, stop there.
     */
    NtOsInstall = FindExistingNTOSInstall(Data->List, NULL /*Options->OsLoadPath*/, &SystemRootPath);
    if (NtOsInstall)
    {
        DPRINT1("    An NTOS installation with name \"%S\" from vendor \"%S\" already exists in SystemRoot '%wZ'\n",
                NtOsInstall->InstallationName, NtOsInstall->VendorName, &NtOsInstall->SystemNtPath);
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

    DPRINT("EnumerateInstallations: SystemRootPath: '%wZ'\n", &SystemRootPath);

    /* Check if this is a valid NTOS installation; stop there if it isn't one */
    RtlInitEmptyUnicodeString(&VendorName, VendorNameBuffer, sizeof(VendorNameBuffer));
    if (!IsValidNTOSInstallation(&SystemRootPath, &Machine, &VendorName))
    {
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

    DPRINT("Found a valid NTOS installation in SystemRoot ARC path '%S', NT path '%wZ'\n",
           Options->OsLoadPath, &SystemRootPath);

    /* From the NT path, compute the disk, partition and path components */
    if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
    {
        DPRINT("SystemRootPath = '%wZ' points to disk #%d, partition #%d, path '%S'\n",
               &SystemRootPath, DiskNumber, PartitionNumber, PathComponent);

        /* Retrieve the corresponding disk and partition */
        if (!GetDiskOrPartition(Data->PartList, DiskNumber, PartitionNumber, &DiskEntry, &PartEntry))
        {
            DPRINT1("GetDiskOrPartition(disk #%d, partition #%d) failed\n",
                    DiskNumber, PartitionNumber);
        }
    }
    else
    {
        DPRINT1("NtPathToDiskPartComponents(%wZ) failed\n", &SystemRootPath);
    }

    /* Add the discovered NTOS installation into the list */
    AddNTOSInstallation(Data->List,
                        BootEntry->FriendlyName,
                        Machine,
                        VendorName.Buffer, // FIXME: What if it's not NULL-terminated?
                        Options->OsLoadPath,
                        &SystemRootPath, PathComponent,
                        DiskNumber, PartitionNumber, PartEntry);

    /* Continue the enumeration */
    return STATUS_SUCCESS;
}
Пример #8
0
 */

#include "precomp.h"

typedef struct _MINIMUM_SIZE_TABLE
{
    DWORD dwField;
    WORD wSize;
}
MINIMUM_SIZE_TABLE, *PMINIMUM_SIZE_TABLE;

/**
 * Minimum required DEVMODEA structure size based on the used fields. Must be in descending order!
 */
static MINIMUM_SIZE_TABLE MinimumSizeA[] = {
    { DM_PANNINGHEIGHT, FIELD_OFFSET(DEVMODEA, dmPanningHeight) + RTL_FIELD_SIZE(DEVMODEA, dmPanningHeight) },
    { DM_PANNINGWIDTH, FIELD_OFFSET(DEVMODEA, dmPanningWidth) + RTL_FIELD_SIZE(DEVMODEA, dmPanningWidth) },
    { DM_DITHERTYPE, FIELD_OFFSET(DEVMODEA, dmDitherType) + RTL_FIELD_SIZE(DEVMODEA, dmDitherType) },
    { DM_MEDIATYPE, FIELD_OFFSET(DEVMODEA, dmMediaType) + RTL_FIELD_SIZE(DEVMODEA, dmMediaType) },
    { DM_ICMINTENT, FIELD_OFFSET(DEVMODEA, dmICMIntent) + RTL_FIELD_SIZE(DEVMODEA, dmICMIntent) },
    { DM_ICMMETHOD, FIELD_OFFSET(DEVMODEA, dmICMMethod) + RTL_FIELD_SIZE(DEVMODEA, dmICMMethod) },
    { DM_DISPLAYFREQUENCY, FIELD_OFFSET(DEVMODEA, dmDisplayFrequency) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayFrequency) },
    { DM_NUP, FIELD_OFFSET(DEVMODEA, dmNup) + RTL_FIELD_SIZE(DEVMODEA, dmNup) },
    { DM_DISPLAYFLAGS, FIELD_OFFSET(DEVMODEA, dmDisplayFlags) + RTL_FIELD_SIZE(DEVMODEA, dmDisplayFlags) },
    { DM_PELSHEIGHT, FIELD_OFFSET(DEVMODEA, dmPelsHeight) + RTL_FIELD_SIZE(DEVMODEA, dmPelsHeight) },
    { DM_PELSWIDTH, FIELD_OFFSET(DEVMODEA, dmPelsWidth) + RTL_FIELD_SIZE(DEVMODEA, dmPelsWidth) },
    { DM_BITSPERPEL, FIELD_OFFSET(DEVMODEA, dmBitsPerPel) + RTL_FIELD_SIZE(DEVMODEA, dmBitsPerPel) },
    { DM_LOGPIXELS, FIELD_OFFSET(DEVMODEA, dmLogPixels) + RTL_FIELD_SIZE(DEVMODEA, dmLogPixels) },
    { DM_FORMNAME, FIELD_OFFSET(DEVMODEA, dmFormName) + RTL_FIELD_SIZE(DEVMODEA, dmFormName) },
    { DM_COLLATE, FIELD_OFFSET(DEVMODEA, dmCollate) + RTL_FIELD_SIZE(DEVMODEA, dmCollate) },
    { DM_TTOPTION, FIELD_OFFSET(DEVMODEA, dmTTOption) + RTL_FIELD_SIZE(DEVMODEA, dmTTOption) },
Пример #9
0
DWORD
WINAPI
DECLSPEC_HOTPATCH
GetAdaptersAddresses(
    _In_ ULONG Family,
    _In_ ULONG Flags,
    _In_ PVOID Reserved,
    _Inout_ PIP_ADAPTER_ADDRESSES pAdapterAddresses,
    _Inout_ PULONG pOutBufLen)
{
    NTSTATUS Status;
    HANDLE TcpFile;
    TDIEntityID* InterfacesList;
    ULONG InterfacesCount;
    ULONG AdaptersCount = 0;
    ULONG i;
    ULONG TotalSize = 0, RemainingSize;
    BYTE* Ptr = (BYTE*)pAdapterAddresses;
    DWORD MIN_SIZE = 15 * 1024;
    PIP_ADAPTER_ADDRESSES PreviousAA = NULL;

    FIXME("GetAdaptersAddresses - Semi Stub: Family %u, Flags 0x%08x, Reserved %p, pAdapterAddress %p, pOutBufLen %p.\n",
        Family, Flags, Reserved, pAdapterAddresses, pOutBufLen);

    if (!pOutBufLen)
        return ERROR_INVALID_PARAMETER;

    // FIXME: the exact needed size should be computed first, BEFORE doing any write to the output buffer.
    // As suggested by MSDN, require a 15 KB buffer, which allows to React properly to length checks.
    if(!Ptr || *pOutBufLen < MIN_SIZE)
    {
        *pOutBufLen = MIN_SIZE;
        return ERROR_BUFFER_OVERFLOW;
    }

    switch(Family)
    {
        case AF_INET:
            break;
        case AF_INET6:
            /* One day maybe... */
            FIXME("IPv6 is not supported in ReactOS!\n");
            /* We got nothing to say in this case */
            return ERROR_NO_DATA;
            break;
        case AF_UNSPEC:
            WARN("IPv6 addresses ignored, IPv4 only\n");
            Family = AF_INET;
            break;
        default:
            ERR("Invalid family 0x%x\n", Family);
            return ERROR_INVALID_PARAMETER;
            break;
    }

    RemainingSize = *pOutBufLen;
    if (Ptr)
        ZeroMemory(Ptr, RemainingSize);

    /* open the tcpip driver */
    Status = openTcpFile(&TcpFile, FILE_READ_DATA);
    if (!NT_SUCCESS(Status))
    {
        ERR("Could not open handle to tcpip.sys. Status %08x\n", Status);
        return RtlNtStatusToDosError(Status);
    }

    /* Get the interfaces list */
    Status = GetInterfacesList(TcpFile, &InterfacesList, &InterfacesCount);
    if (!NT_SUCCESS(Status))
    {
        ERR("Could not get adapters list. Status %08x\n", Status);
        NtClose(TcpFile);
        return RtlNtStatusToDosError(Status);
    }

    /* Let's see if we got any adapter. */
    for (i = 0; i < InterfacesCount; i++)
    {
        PIP_ADAPTER_ADDRESSES CurrentAA = (PIP_ADAPTER_ADDRESSES)Ptr;
        ULONG CurrentAASize = 0;

        if (InterfacesList[i].tei_entity == IF_ENTITY)
        {
            BYTE EntryBuffer[FIELD_OFFSET(IFEntry, if_descr) +
                             RTL_FIELD_SIZE(IFEntry, if_descr[0]) * (MAX_ADAPTER_DESCRIPTION_LENGTH + 1)];
            IFEntry* Entry = (IFEntry*)EntryBuffer;

            /* Remember we got one */
            AdaptersCount++;

            /* Set the pointer to this instance in the previous one*/
            if(PreviousAA)
                PreviousAA->Next = CurrentAA;

            /* Of course we need some space for the base structure. */
            CurrentAASize = sizeof(IP_ADAPTER_ADDRESSES);

            /* Get the entry */
            Status = GetInterfaceEntry(TcpFile, InterfacesList[i], Entry);
            if (!NT_SUCCESS(Status))
                goto Error;

            TRACE("Got entity %*s, index %u.\n",
                Entry->if_descrlen, &Entry->if_descr[0], Entry->if_index);

            /* Add the adapter name */
            CurrentAASize += Entry->if_descrlen + sizeof(CHAR);

            /* Add the DNS suffix */
            CurrentAASize += sizeof(WCHAR);

            /* Add the description. */
            CurrentAASize += sizeof(WCHAR);

            if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
            {
                /* Just an empty string for now. */
                FIXME("Should get adapter friendly name.\n");
                CurrentAASize += sizeof(WCHAR);
            }

            if (!(Flags & GAA_FLAG_SKIP_DNS_SERVER))
            {
                /* Enumerate the name servers */
                HKEY InterfaceKey;
                CHAR KeyName[256];

                snprintf(KeyName, 256,
                    "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s",
                    Entry->if_descrlen, &Entry->if_descr[0]);

                if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &InterfaceKey) != ERROR_SUCCESS)
                {
                    ERR("Failed opening interface key for interface %*s\n", Entry->if_descrlen, &Entry->if_descr[0]);
                    Flags |= GAA_FLAG_SKIP_DNS_SERVER;
                }
                else
                {
                    EnumNameServers(InterfaceKey, NULL, &CurrentAASize, EnumerateServerNameSize);
                    RegCloseKey(InterfaceKey);
                }
            }

            /* This is part of what we will need */
            TotalSize += CurrentAASize;

            /* Fill in the data */
            if ((CurrentAA) && (RemainingSize >= CurrentAASize))
            {
                CurrentAA->Length = sizeof(IP_ADAPTER_ADDRESSES);
                CurrentAA->IfIndex = Entry->if_index;
                CopyMemory(CurrentAA->PhysicalAddress, Entry->if_physaddr, Entry->if_physaddrlen);
                CurrentAA->PhysicalAddressLength = Entry->if_physaddrlen;
                CurrentAA->Flags = 0; // FIXME!
                CurrentAA->Mtu = Entry->if_mtu;
                CurrentAA->IfType = Entry->if_type;
                CurrentAA->OperStatus = Entry->if_operstatus;
                /* Next items */
                Ptr = (BYTE*)(CurrentAA + 1);

                /* Now fill in the name */
                CopyMemory(Ptr, &Entry->if_descr[0], Entry->if_descrlen);
                CurrentAA->AdapterName = (PCHAR)Ptr;
                CurrentAA->AdapterName[Entry->if_descrlen] = '\0';
                /* Next items */
                Ptr = (BYTE*)(CurrentAA->AdapterName + Entry->if_descrlen + 1);

                /* The DNS suffix */
                CurrentAA->DnsSuffix = (PWCHAR)Ptr;
                CurrentAA->DnsSuffix[0] = L'\0';
                /* Next items */
                Ptr = (BYTE*)(CurrentAA->DnsSuffix + 1);

                /* The description */
                CurrentAA->Description = (PWCHAR)Ptr;
                CurrentAA->Description[0] = L'\0';
                /* Next items */
                Ptr = (BYTE*)(CurrentAA->Description + 1);

                /* The friendly name */
                if (!(Flags & GAA_FLAG_SKIP_FRIENDLY_NAME))
                {
                    CurrentAA->FriendlyName = (PWCHAR)Ptr;
                    CurrentAA->FriendlyName[0] = L'\0';
                    /* Next items */
                    Ptr = (BYTE*)(CurrentAA->FriendlyName + 1);
                }

                /* The DNS Servers */
                if (!(Flags & GAA_FLAG_SKIP_DNS_SERVER))
                {
                    /* Enumerate the name servers */
                    HKEY InterfaceKey;
                    CHAR KeyName[256];

                    snprintf(KeyName, 256,
                        "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\%*s",
                        Entry->if_descrlen, &Entry->if_descr[0]);

                    if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &InterfaceKey) != ERROR_SUCCESS)
                    {
                        ERR("Failed opening interface key for interface %*s\n", Entry->if_descrlen, &Entry->if_descr[0]);
                    }
                    else
                    {
                        PIP_ADAPTER_DNS_SERVER_ADDRESS* ServerAddressPtr;

                        CurrentAA->FirstDnsServerAddress = (PIP_ADAPTER_DNS_SERVER_ADDRESS)Ptr;
                        ServerAddressPtr = &CurrentAA->FirstDnsServerAddress;

                        EnumNameServers(InterfaceKey, NULL, &ServerAddressPtr, EnumerateServerName);
                        RegCloseKey(InterfaceKey);

                        /* Set the last entry in the list as having NULL next member */
                        Ptr = (BYTE*)*ServerAddressPtr;
                        *ServerAddressPtr = NULL;
                    }
                }

                /* We're done for this interface */
                PreviousAA = CurrentAA;
                RemainingSize -= CurrentAASize;
            }
        }
    }

    if (AdaptersCount == 0)
    {
        /* Uh? Not even localhost ?! */
        ERR("No Adapters found!\n");
        *pOutBufLen = 0;
        return ERROR_NO_DATA;
    }

    /* See if we have anything to add */
    // FIXME: Anycast and multicast
    if ((Flags & (GAA_FLAG_SKIP_UNICAST | GAA_FLAG_INCLUDE_PREFIX)) == GAA_FLAG_SKIP_UNICAST)
        goto Success;

    /* Now fill in the addresses */
    for (i = 0; i < InterfacesCount; i++)
    {
        /* Look for network layers */
        if ((InterfacesList[i].tei_entity == CL_NL_ENTITY)
                || (InterfacesList[i].tei_entity == CO_NL_ENTITY))
        {
            IPSNMPInfo SnmpInfo;
            PIP_ADAPTER_ADDRESSES CurrentAA = NULL;
            IPAddrEntry* AddrEntries;
            ULONG j;

            /* Get its SNMP info */
            Status = GetSnmpInfo(TcpFile, InterfacesList[i], &SnmpInfo);
            if (!NT_SUCCESS(Status))
                goto Error;

            if (SnmpInfo.ipsi_numaddr == 0)
                continue;

            /* Allocate the address entry array and get them */
            AddrEntries = HeapAlloc(GetProcessHeap(),
                HEAP_ZERO_MEMORY,
                SnmpInfo.ipsi_numaddr * sizeof(AddrEntries[0]));
            if (!AddrEntries)
            {
                Status = STATUS_NO_MEMORY;
                goto Error;
            }
            Status = GetAddrEntries(TcpFile, InterfacesList[i], AddrEntries, SnmpInfo.ipsi_numaddr);
            if (!NT_SUCCESS(Status))
            {
                HeapFree(GetProcessHeap(), 0, AddrEntries);
                goto Error;
            }

            for (j = 0; j < SnmpInfo.ipsi_numaddr; j++)
            {
                /* Find the adapters struct for this address. */
                if (pAdapterAddresses)
                {
                    CurrentAA = pAdapterAddresses;
                    while (CurrentAA)
                    {
                        if (CurrentAA->IfIndex == AddrEntries[j].iae_index)
                            break;

                        CurrentAA = CurrentAA->Next;
                    }

                    if (!CurrentAA)
                    {
                        ERR("Got address for interface %u but no adapter was found for it.\n", AddrEntries[j].iae_index);
                        /* Go to the next address */
                        continue;
                    }
                }

                ERR("address is 0x%08x, mask is 0x%08x\n", AddrEntries[j].iae_addr, AddrEntries[j].iae_mask);

                //FIXME: For now reactos only supports unicast addresses
                if (!(Flags & GAA_FLAG_SKIP_UNICAST))
                {
                    ULONG Size = sizeof(IP_ADAPTER_UNICAST_ADDRESS) + sizeof(SOCKADDR);

                    if (Ptr && (RemainingSize >= Size))
                    {
                        PIP_ADAPTER_UNICAST_ADDRESS UnicastAddress = (PIP_ADAPTER_UNICAST_ADDRESS)Ptr;

                        /* Fill in the structure */
                        UnicastAddress->Length = sizeof(IP_ADAPTER_UNICAST_ADDRESS);
                        UnicastAddress->Next = CurrentAA->FirstUnicastAddress;

                        // FIXME: Put meaningful value here
                        UnicastAddress->Flags = 0;
                        UnicastAddress->PrefixOrigin = IpPrefixOriginOther;
                        UnicastAddress->SuffixOrigin = IpSuffixOriginOther;
                        UnicastAddress->DadState = IpDadStatePreferred;
                        UnicastAddress->ValidLifetime = 0xFFFFFFFF;
                        UnicastAddress->PreferredLifetime = 0xFFFFFFFF;

                        /* Set the address */
                        //FIXME: ipv4 only (again...)
                        UnicastAddress->Address.lpSockaddr = (LPSOCKADDR)(UnicastAddress + 1);
                        UnicastAddress->Address.iSockaddrLength = sizeof(AddrEntries[j].iae_addr);
                        UnicastAddress->Address.lpSockaddr->sa_family = AF_INET;
                        memcpy(UnicastAddress->Address.lpSockaddr->sa_data, &AddrEntries[j].iae_addr, sizeof(AddrEntries[j].iae_addr));

                        CurrentAA->FirstUnicastAddress = UnicastAddress;
                        Ptr += Size;
                        RemainingSize -= Size;
                    }

                    TotalSize += Size;
                }

                if (Flags & GAA_FLAG_INCLUDE_PREFIX)
                {
                    ULONG Size = sizeof(IP_ADAPTER_PREFIX) + sizeof(SOCKADDR);

                    if (Ptr && (RemainingSize >= Size))
                    {
                        PIP_ADAPTER_PREFIX Prefix = (PIP_ADAPTER_PREFIX)Ptr;

                        /* Fill in the structure */
                        Prefix->Length = sizeof(IP_ADAPTER_PREFIX);
                        Prefix->Next = CurrentAA->FirstPrefix;

                        /* Set the address */
                        //FIXME: ipv4 only (again...)
                        Prefix->Address.lpSockaddr = (LPSOCKADDR)(Prefix + 1);
                        Prefix->Address.iSockaddrLength = sizeof(AddrEntries[j].iae_mask);
                        Prefix->Address.lpSockaddr->sa_family = AF_INET;
                        memcpy(Prefix->Address.lpSockaddr->sa_data, &AddrEntries[j].iae_mask, sizeof(AddrEntries[j].iae_mask));

                        /* Compute the prefix size */
                        _BitScanReverse(&Prefix->PrefixLength, AddrEntries[j].iae_mask);

                        CurrentAA->FirstPrefix = Prefix;
                        Ptr += Size;
                        RemainingSize -= Size;
                    }

                    TotalSize += Size;
                }
            }

            HeapFree(GetProcessHeap(), 0, AddrEntries);
        }
    }

Success:
    /* We're done */
    HeapFree(GetProcessHeap(), 0, InterfacesList);
    NtClose(TcpFile);
    *pOutBufLen = TotalSize;
    TRACE("TotalSize: %x\n", *pOutBufLen);
    return ERROR_SUCCESS;

Error:
    ERR("Failed! Status 0x%08x\n", Status);
    *pOutBufLen = 0;
    HeapFree(GetProcessHeap(), 0, InterfacesList);
    NtClose(TcpFile);
    return RtlNtStatusToDosError(Status);
}