예제 #1
0
// PENUM_BOOT_ENTRIES_ROUTINE
static NTSTATUS
NTAPI
EnumerateInstallations(
    IN NTOS_BOOT_LOADER_TYPE Type,
    IN PNTOS_BOOT_ENTRY BootEntry,
    IN PVOID Parameter OPTIONAL)
{
    PENUM_INSTALLS_DATA Data = (PENUM_INSTALLS_DATA)Parameter;

    PNTOS_INSTALLATION NtOsInstall;
    UNICODE_STRING SystemRootPath;
    WCHAR SystemRoot[MAX_PATH];
    WCHAR InstallNameW[MAX_PATH];

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

    /* We have a boot entry */

    UNICODE_STRING InstallName;
    // /**/RtlInitUnicodeString(&InstallName, BootEntry->FriendlyName);/**/
    InstallName = *BootEntry->FriendlyName;

#if 0
    if (Type == FreeLdr)
    {
        /* Check for supported boot type "Windows2003" */

        // TODO: What to do with "Windows" ; "WindowsNT40" ; "ReactOSSetup" ?
        if ((BootType == NULL) ||
            ( (_wcsicmp(BootType, L"Windows2003") != 0) &&
              (_wcsicmp(BootType, L"\"Windows2003\"") != 0) ))
        {
            /* This is not a ReactOS entry */
            /* Certainly not a ReactOS installation */
            DPRINT1("    A Win2k3 install '%wZ' without an ARC path?!\n", &InstallName);
            /* Continue the enumeration */
            return STATUS_SUCCESS;
        }
    }
#endif

    DPRINT1("    Found a candidate Win2k3 install '%wZ' with ARC path '%S'\n",
            &InstallName, BootEntry->OsLoadPath);
    // DPRINT1("    Found a Win2k3 install '%wZ' with ARC path '%S'\n",
            // &InstallName, BootEntry->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, BootEntry->OsLoadPath, NULL);
    if (NtOsInstall)
    {
        DPRINT1("    An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
                NtOsInstall->InstallationName, &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, BootEntry->OsLoadPath, Data->PartList))
    {
        DPRINT1("ArcPathToNtPath(%S) failed, skip the installation.\n", BootEntry->OsLoadPath);
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

    DPRINT1("ArcPathToNtPath() succeeded: '%S' --> '%wZ'\n",
            BootEntry->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 /*BootEntry->OsLoadPath*/, &SystemRootPath);
    if (NtOsInstall)
    {
        DPRINT1("    An NTOS installation with name \"%S\" already exists in SystemRoot '%wZ'\n",
                NtOsInstall->InstallationName, &NtOsInstall->SystemNtPath);
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

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

    /* Check if this is a valid NTOS installation; stop there if it isn't one */
    if (!IsValidNTOSInstallation_UStr(&SystemRootPath))
    {
        /* Continue the enumeration */
        return STATUS_SUCCESS;
    }

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

    /* From the NT path, compute the disk, partition and path components */
    if (NtPathToDiskPartComponents(SystemRootPath.Buffer, &DiskNumber, &PartitionNumber, &PathComponent))
    {
        DPRINT1("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 */
    if (PartEntry && PartEntry->DriveLetter)
    {
        /* We have retrieved a partition that is mounted */
        StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%C:%s  \"%wZ\"",
                         PartEntry->DriveLetter, PathComponent, &InstallName);
    }
    else
    {
        /* We failed somewhere, just show the NT path */
        StringCchPrintfW(InstallNameW, ARRAYSIZE(InstallNameW), L"%wZ  \"%wZ\"",
                         &SystemRootPath, &InstallName);
    }
    AddNTOSInstallation(Data->List, BootEntry->OsLoadPath,
                        &SystemRootPath, PathComponent,
                        DiskNumber, PartitionNumber, PartEntry,
                        InstallNameW);

    /* Continue the enumeration */
    return STATUS_SUCCESS;
}
예제 #2
0
static PNTOS_INSTALLATION
AddNTOSInstallation(
    IN PGENERIC_LIST List,
    IN PCWSTR SystemRootArcPath,
    IN PUNICODE_STRING SystemRootNtPath, // or PCWSTR ?
    IN PCWSTR PathComponent,    // Pointer inside SystemRootNtPath buffer
    IN ULONG DiskNumber,
    IN ULONG PartitionNumber,
    IN PPARTENTRY PartEntry OPTIONAL,
    IN PCWSTR InstallationName)
{
    PNTOS_INSTALLATION NtOsInstall;
    SIZE_T ArcPathLength, NtPathLength;
    CHAR InstallNameA[MAX_PATH];

    /* Is there already any installation with these settings? */
    NtOsInstall = FindExistingNTOSInstall(List, SystemRootArcPath, SystemRootNtPath);
    if (NtOsInstall)
    {
        DPRINT1("An NTOS installation with name \"%S\" already exists on disk #%d, partition #%d, in SystemRoot '%wZ'\n",
                NtOsInstall->InstallationName, NtOsInstall->DiskNumber, NtOsInstall->PartitionNumber, &NtOsInstall->SystemNtPath);
        //
        // NOTE: We may use its "IsDefault" attribute, and only keep the entries that have IsDefault == TRUE...
        // Setting IsDefault to TRUE would imply searching for the "Default" entry in the loader configuration file.
        //
        return NtOsInstall;
    }

    ArcPathLength = (wcslen(SystemRootArcPath) + 1) * sizeof(WCHAR);
    // NtPathLength  = ROUND_UP(SystemRootNtPath->Length + sizeof(UNICODE_NULL), sizeof(WCHAR));
    NtPathLength  = SystemRootNtPath->Length + sizeof(UNICODE_NULL);

    /* None was found, so add a new one */
    NtOsInstall = RtlAllocateHeap(ProcessHeap, HEAP_ZERO_MEMORY,
                                  sizeof(*NtOsInstall) +
                                  ArcPathLength + NtPathLength);
    if (!NtOsInstall)
        return NULL;

    NtOsInstall->DiskNumber = DiskNumber;
    NtOsInstall->PartitionNumber = PartitionNumber;
    NtOsInstall->PartEntry = PartEntry;

    RtlInitEmptyUnicodeString(&NtOsInstall->SystemArcPath,
                              (PWCHAR)(NtOsInstall + 1),
                              ArcPathLength);
    RtlCopyMemory(NtOsInstall->SystemArcPath.Buffer, SystemRootArcPath, ArcPathLength);
    NtOsInstall->SystemArcPath.Length = ArcPathLength - sizeof(UNICODE_NULL);

    RtlInitEmptyUnicodeString(&NtOsInstall->SystemNtPath,
                              (PWCHAR)((ULONG_PTR)(NtOsInstall + 1) + ArcPathLength),
                              NtPathLength);
    RtlCopyUnicodeString(&NtOsInstall->SystemNtPath, SystemRootNtPath);
    NtOsInstall->PathComponent = NtOsInstall->SystemNtPath.Buffer +
                                    (PathComponent - SystemRootNtPath->Buffer);

    StringCchCopyW(NtOsInstall->InstallationName, ARRAYSIZE(NtOsInstall->InstallationName), InstallationName);

    // Having the GENERIC_LIST storing the display item string plainly sucks...
    StringCchPrintfA(InstallNameA, ARRAYSIZE(InstallNameA), "%S", InstallationName);
    AppendGenericListEntry(List, InstallNameA, NtOsInstall, FALSE);

    return NtOsInstall;
}
예제 #3
0
파일: osdetect.c 프로젝트: Moteesh/reactos
// 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;
}