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

📄 arcname.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
     * check for ntoskrnl.exe, which is just as good.
     *
     * The signature code stays however, because eventually FreeLDR will work
     * like NTLDR, and, conversly, we do want to be able to be booted by NTLDR.
     */
    if (IopApplyRosCdromArcHack(DiskNumber))
    {
        /* This is the boot CD-ROM, build the ARC name */
        sprintf(ArcBuffer, "\\ArcName\\%s", KeLoaderBlock->ArcBootDeviceName);

        /* Convert it to Unicode */
        RtlInitAnsiString(&TempString, ArcBuffer);
        Status = RtlAnsiStringToUnicodeString(&ArcName, &TempString, TRUE);
        if (!NT_SUCCESS(Status)) return FALSE;

        /* Create the symbolic link and free the strings */
        IoAssignArcName(&ArcName, &DeviceName);
        RtlFreeUnicodeString(&ArcName);
        RtlFreeUnicodeString(&DeviceName);

        /* Let caller know that we've found the boot CD */
        return TRUE;
    }

    /* No boot CD found */
    return FALSE;
}

NTSTATUS
INIT_FUNCTION
NTAPI
IopCreateArcNames(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
{
    PCONFIGURATION_INFORMATION ConfigInfo = IoGetConfigurationInformation();
    PARC_DISK_INFORMATION ArcDiskInfo = LoaderBlock->ArcDiskInformation;
    CHAR Buffer[128];
    ANSI_STRING ArcBootString, ArcSystemString, ArcString;
    UNICODE_STRING ArcName, BootPath, DeviceName;
    BOOLEAN SingleDisk;
    ULONG i, j, Length;
    PDEVICE_OBJECT DeviceObject;
    ULONG Signature, Checksum, PartitionCount;
    PLIST_ENTRY NextEntry;
    PARC_DISK_SIGNATURE ArcDiskEntry;
    NTSTATUS Status;
    BOOLEAN FoundBoot = FALSE;
    PULONG PartitionBuffer;

    /* Check if we only have one disk on the machine */
    SingleDisk = ArcDiskInfo->DiskSignatureListHead.Flink->Flink ==
                 (&ArcDiskInfo->DiskSignatureListHead);

    /* Create the global HAL partition name */
    sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcHalDeviceName);
    RtlInitAnsiString(&ArcString, Buffer);
    RtlAnsiStringToUnicodeString(&IoArcHalDeviceName, &ArcString, TRUE);

    /* Create the global system partition name */
    sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
    RtlInitAnsiString(&ArcString, Buffer);
    RtlAnsiStringToUnicodeString(&IoArcBootDeviceName, &ArcString, TRUE);

    /* Allocate memory for the string */
    Length = strlen(LoaderBlock->ArcBootDeviceName) + sizeof(ANSI_NULL);
    IoLoaderArcBootDeviceName = ExAllocatePoolWithTag(PagedPool,
                                                      Length,
                                                      TAG_IO);
    if (IoLoaderArcBootDeviceName)
    {
        /* Copy the name */
        RtlCopyMemory(IoLoaderArcBootDeviceName,
                      LoaderBlock->ArcBootDeviceName,
                      Length);
    }

    /* Check if we only found a disk, but we're booting from CD-ROM */
    if ((SingleDisk) && strstr(LoaderBlock->ArcBootDeviceName, "cdrom"))
    {
        /* Then disable single-disk mode, since there's a CD drive out there */
        SingleDisk = FALSE;
    }

    /* Build the boot strings */
    RtlInitAnsiString(&ArcBootString, LoaderBlock->ArcBootDeviceName);
    RtlInitAnsiString(&ArcSystemString, LoaderBlock->ArcHalDeviceName);

    /* Loop every detected disk */
    for (i = 0; i < ConfigInfo->DiskCount; i++)
    {
        /* Get information about the disk */
        if (!IopGetDiskInformation(i,
                                   &Checksum,
                                   &Signature,
                                   &PartitionCount,
                                   &DeviceObject))
        {
            /* Skip this disk */
            continue;
        }

        /* Loop ARC disks */
        for (NextEntry = ArcDiskInfo->DiskSignatureListHead.Flink;
             NextEntry != &ArcDiskInfo->DiskSignatureListHead;
             NextEntry = NextEntry->Flink)
        {
            /* Get the current ARC disk signature entry */
            ArcDiskEntry = CONTAINING_RECORD(NextEntry,
                                             ARC_DISK_SIGNATURE,
                                             ListEntry);

            /*
             * Now check if the signature and checksum match, unless this is
             * the only disk that was in the ARC list, and also in the device
             * tree, in which case the check is bypassed and we accept the disk
             */
            if (((SingleDisk) && (ConfigInfo->DiskCount == 1)) ||
                ((Checksum == ArcDiskEntry->CheckSum) &&
                 (Signature == ArcDiskEntry->Signature)))
            {
                /* Build the NT Device Name */
                sprintf(Buffer, "\\Device\\Harddisk%lu\\Partition0", i);

                /* Convert it to Unicode */
                RtlInitAnsiString(&ArcString, Buffer);
                Status = RtlAnsiStringToUnicodeString(&DeviceName,
                                                      &ArcString,
                                                      TRUE);
                if (!NT_SUCCESS(Status)) continue;

                /* Build the ARC Device Name */
                sprintf(Buffer, "\\ArcName\\%s", ArcDiskEntry->ArcName);

                /* Convert it to Unicode */
                RtlInitAnsiString(&ArcString, Buffer);
                Status = RtlAnsiStringToUnicodeString(&ArcName,
                                                      &ArcString,
                                                      TRUE);
                if (!NT_SUCCESS(Status)) continue;

                /* Create the symbolic link and free the strings */
                IoAssignArcName(&ArcName, &DeviceName);
                RtlFreeUnicodeString(&ArcName);
                RtlFreeUnicodeString(&DeviceName);

                /* Loop all the partitions */
                for (j = 0; j < PartitionCount; j++)
                {
                    /* Build the partition device name */
                    sprintf(Buffer,
                            "\\Device\\Harddisk%lu\\Partition%lu",
                            i,
                            j + 1);

                    /* Convert it to Unicode */
                    RtlInitAnsiString(&ArcString, Buffer);
                    Status = RtlAnsiStringToUnicodeString(&DeviceName,
                                                          &ArcString,
                                                          TRUE);
                    if (!NT_SUCCESS(Status)) continue;

                    /* Build the partial ARC name for this partition */
                    sprintf(Buffer,
                            "%spartition(%lu)",
                            ArcDiskEntry->ArcName,
                            j + 1);
                    RtlInitAnsiString(&ArcString, Buffer);

                    /* Check if this is the boot device */
                    if (RtlEqualString(&ArcString, &ArcBootString, TRUE))
                    {
                        /* Remember that we found a Hard Disk Boot Device */
                        FoundBoot = TRUE;
                    }

                    /* Check if it's the system boot partition */
                    if (RtlEqualString(&ArcString, &ArcSystemString, TRUE))
                    {
                        /* It is, create a Unicode string for it */
                        RtlInitAnsiString(&ArcString,
                                          LoaderBlock->NtHalPathName);
                        Status = RtlAnsiStringToUnicodeString(&BootPath,
                                                              &ArcString,
                                                              TRUE);
                        if (NT_SUCCESS(Status))
                        {
                            /* FIXME: Save in registry */

                            /* Free the string now */
                            RtlFreeUnicodeString(&BootPath);
                        }
                    }

                    /* Build the full ARC name */
                    sprintf(Buffer,
                            "\\ArcName\\%spartition(%lu)",
                            ArcDiskEntry->ArcName,
                            j + 1);

                    /* Convert it to Unicode */
                    RtlInitAnsiString(&ArcString, Buffer);
                    Status = RtlAnsiStringToUnicodeString(&ArcName,
                                                          &ArcString,
                                                          TRUE);
                    if (!NT_SUCCESS(Status)) continue;

                    /* Create the symbolic link and free the strings */
                    IoAssignArcName(&ArcName, &DeviceName);
                    RtlFreeUnicodeString(&ArcName);
                    RtlFreeUnicodeString(&DeviceName);
                }
            }
        }
    }

    /* Check if we didn't find the boot disk */
    if (!FoundBoot)
    {
        /* Allocate a buffer for the CD-ROM MBR */
        PartitionBuffer = ExAllocatePoolWithTag(NonPagedPool, 2048, TAG_IO);
        if (!PartitionBuffer) return STATUS_INSUFFICIENT_RESOURCES;

        /* Loop every CD-ROM */
        for (i = 0; i < ConfigInfo->CdRomCount; i++)
        {
            /* Give it an ARC name */
            if (IopAssignArcNamesToCdrom(PartitionBuffer, i)) break;
        }

        /* Free the buffer */
        ExFreePool(PartitionBuffer);
    }

    /* Return success */
    return STATUS_SUCCESS;
}

NTSTATUS
NTAPI
IopReassignSystemRoot(IN PLOADER_PARAMETER_BLOCK LoaderBlock,
                      OUT PANSI_STRING NtBootPath)
{
    OBJECT_ATTRIBUTES ObjectAttributes;
    NTSTATUS Status;
    CHAR Buffer[256], AnsiBuffer[256];
    WCHAR ArcNameBuffer[64];
    ANSI_STRING TargetString, ArcString, TempString;
    UNICODE_STRING LinkName, TargetName, ArcName;
    HANDLE LinkHandle;

    /* Create the Unicode name for the current ARC boot device */
    sprintf(Buffer, "\\ArcName\\%s", LoaderBlock->ArcBootDeviceName);
    RtlInitAnsiString(&TargetString, Buffer);
    Status = RtlAnsiStringToUnicodeString(&TargetName, &TargetString, TRUE);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Initialize the attributes and open the link */
    InitializeObjectAttributes(&ObjectAttributes,
                               &TargetName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenSymbolicLinkObject(&LinkHandle,
                                      SYMBOLIC_LINK_ALL_ACCESS,
                                      &ObjectAttributes);
    if (!NT_SUCCESS(Status))
    {
        /* We failed, free the string */
        RtlFreeUnicodeString(&TargetName);
        return FALSE;
    }

    /* Query the current \\SystemRoot */
    ArcName.Buffer = ArcNameBuffer;
    ArcName.Length = 0;
    ArcName.MaximumLength = sizeof(ArcNameBuffer);
    Status = NtQuerySymbolicLinkObject(LinkHandle, &ArcName, NULL);
    if (!NT_SUCCESS(Status))
    {
        /* We failed, free the string */
        RtlFreeUnicodeString(&TargetName);
        return FALSE;
    }

    /* Convert it to Ansi */
    ArcString.Buffer = AnsiBuffer;
    ArcString.Length = 0;
    ArcString.MaximumLength = sizeof(AnsiBuffer);
    Status = RtlUnicodeStringToAnsiString(&ArcString, &ArcName, FALSE);
    AnsiBuffer[ArcString.Length] = ANSI_NULL;

    /* Close the link handle and free the name */
    ObCloseHandle(LinkHandle, KernelMode);
    RtlFreeUnicodeString(&TargetName);

    /* Setup the system root name again */
    RtlInitAnsiString(&TempString, "\\SystemRoot");
    Status = RtlAnsiStringToUnicodeString(&LinkName, &TempString, TRUE);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Open the symbolic link for it */
    InitializeObjectAttributes(&ObjectAttributes,
                               &LinkName,
                               OBJ_CASE_INSENSITIVE,
                               NULL,
                               NULL);
    Status = NtOpenSymbolicLinkObject(&LinkHandle,
                                      SYMBOLIC_LINK_ALL_ACCESS,
                                      &ObjectAttributes);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Destroy it */
    NtMakeTemporaryObject(LinkHandle);
    ObCloseHandle(LinkHandle, KernelMode);

    /* Now create the new name for it */
    sprintf(Buffer, "%s%s", ArcString.Buffer, LoaderBlock->NtBootPathName);

    /* Copy it into the passed parameter and null-terminate it */
    RtlCopyString(NtBootPath, &ArcString);
    Buffer[strlen(Buffer) - 1] = ANSI_NULL;

    /* Setup the Unicode-name for the new symbolic link value */
    RtlInitAnsiString(&TargetString, Buffer);
    InitializeObjectAttributes(&ObjectAttributes,
                               &LinkName,
                               OBJ_CASE_INSENSITIVE | OBJ_PERMANENT,
                               NULL,
                               NULL);
    Status = RtlAnsiStringToUnicodeString(&ArcName, &TargetString, TRUE);
    if (!NT_SUCCESS(Status)) return FALSE;

    /* Create it */
    Status = NtCreateSymbolicLinkObject(&LinkHandle,
                                        SYMBOLIC_LINK_ALL_ACCESS,
                                        &ObjectAttributes,
                                        &ArcName);

    /* Free all the strings and close the handle and return success */
    RtlFreeUnicodeString(&ArcName);
    RtlFreeUnicodeString(&LinkName);
    ObCloseHandle(LinkHandle, KernelMode);
    return TRUE;
}

/* EOF */

⌨️ 快捷键说明

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