Ejemplo n.º 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;
}
Ejemplo n.º 2
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;
}