How to fake an Arcpath

D

Dietmar

Hi Slobodan,
some month ago you wrote to me

"I told you simple solution to fix BSOD 7B error. Just make your
additional
driver that will start before 7B check happens and this driver should just

fake ARC path this is 10 times simpler then writing full driver and
specification, and tools, etc."

I still do not understand, how I can do exact this.
I am able now to write simple new drivers, but how can this solve faking
Arcpath?

What is the input string for such a driver, that fakes arcpath? It must be
a kind of device ID
for that special device, you want to boot from alone, which the kernel
knows very early in bootime, but can not translate this information to a
working arcpath? That seems to me strange.

Output string from that wished driver, so I think, is simple the normal
arcpath as in boot.ini.

This is the only thing until now, I cant solve.
I can boot now with one and the same USB Stick
a total unknown Computer with XP(E), doesnt matter what unknown drivers
are on that computer:

It is like the USB Stick is learning from each computer, which means the
Stick gets more and more drivers and until now, they do not disturb each
other. This is a fantastic thing.

Please help or give me a little advice how to solve this problem,

Dietmar

PS: Is the input string for the driver that fakes arcpath the same that
the EWF filter uses? For example:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ewf\Parameters\Protec­t

ed\Volume0]
"VolumeID"="{1EA414D1-6760-4625-8CBE-4F9F85A48E15}"
"Type"=dword:00000001
"ArcName"="multi(0)disk(0)rdisk(0)partition(1)"

and is here standing all what I need with
translation

1EA414D1-6760-4625-8CBE-4F9F85A48E15

to

multi(0)disk(0)rdisk(0)partition(1)

with that wanted driver?
 
D

Dietmar

Hi Slobodan,
I saw with WinObj that the arcpath is missing on one motherboard.

But what could I do then do overcome this?

If I write an own driver that starts before disk.sys and I know the exact
ID number
for that bootdevice how can I give this ID to the starting disk.sys that
disk.sys accepts it as
valid arcpath? ?

And the problem may come from another side:
A bad Bios perhaps changes the order in which I thought it would be ok for
drivers for booting as described in CriticalDeviceDatabase.

The question remains, how to force a device with exact known ID to boot
when Winobj shows no Arcpath. It is not a problem of a missing driver
(because the driver is there but does not start because of an unknown
reason)as always is said for 0x7b.
And I think that indeed an other driver can cause 0x7b, for example
usbccgp or an upper filter or volsnap or ntdetect.com.

I am still thinking that most of this 0x7b BSODS will disappear, if I know
how to write a driver who gives the ID number of the existing bootdevice by
himself as Arcpath to disk.sys.

Nice to hear from you
Dietmar
 
D

Dietmar

Hi Slobodan,

is this the right way?



/* INCLUDES
*****************************************************************/

#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>

/* MACROS
*******************************************************************/

#define FS_VOLUME_BUFFER_SIZE (MAX_PATH +
sizeof(FILE_FS_VOLUME_INFORMATION))

/* FUNCTIONS
****************************************************************/

NTSTATUS INIT_FUNCTION
IoCreateArcNames(VOID)
{
PCONFIGURATION_INFORMATION ConfigInfo;
PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
WCHAR DeviceNameBuffer[80];
WCHAR ArcNameBuffer[80];
UNICODE_STRING DeviceName;
UNICODE_STRING ArcName;
ULONG i, j, k;
NTSTATUS Status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
BOOL IsRemovableMedia;

DPRINT("IoCreateArcNames() called\n");

ConfigInfo = IoGetConfigurationInformation();

/* create ARC names for floppy drives */
DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
for (i = 0; i < ConfigInfo->FloppyCount; i++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\Floppy%lu",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
i);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);
}

/* create ARC names for hard disk drives */
DPRINT("Disk drives: %lu\n", ConfigInfo->DiskCount);
for (i = 0, k = 0; i < ConfigInfo->DiskCount; i++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\Harddisk%lu\\Partition0",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);


Status = IoGetDeviceObjectPointer(&DeviceName,
FILE_READ_DATA,
&FileObject,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
continue;
}
IsRemovableMedia = DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA ?
TRUE : FALSE;
ObDereferenceObject(FileObject);
if (IsRemovableMedia)
{
continue;
}

swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(0)",
k);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);

Status = xHalQueryDriveLayout(&DeviceName,
&LayoutInfo);
if (!NT_SUCCESS(Status))
return(Status);

DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);

for (j = 0;j < LayoutInfo->PartitionCount; j++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
i,
j + 1);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

swprintf(ArcNameBuffer,

L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
k,
j + 1);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);
}

ExFreePool(LayoutInfo);
LayoutInfo = NULL;
k++;
}

/* create ARC names for cdrom drives */
DPRINT("CD-ROM drives: %lu\n", ConfigInfo->CdRomCount);
for (i = 0; i < ConfigInfo->CdRomCount; i++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)cdrom(%lu)",
i);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);
}

DPRINT("IoCreateArcNames() done\n");

return(STATUS_SUCCESS);
}


static NTSTATUS
IopCheckCdromDevices(PULONG DeviceNumber)
{
PCONFIGURATION_INFORMATION ConfigInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DeviceName;
WCHAR DeviceNameBuffer[MAX_PATH];
HANDLE Handle;
ULONG i;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
#if 0
PFILE_FS_VOLUME_INFORMATION FileFsVolume;
USHORT Buffer[FS_VOLUME_BUFFER_SIZE];

FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
#endif

ConfigInfo = IoGetConfigurationInformation();
for (i = 0; i < ConfigInfo->CdRomCount; i++)
{
#if 0
swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu\\",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
if (NT_SUCCESS(Status))
{
Status = ZwQueryVolumeInformationFile(Handle,
&IoStatusBlock,
FileFsVolume,
FS_VOLUME_BUFFER_SIZE,

FileFsVolumeInformation);
DPRINT("ZwQueryVolumeInformationFile() Status %lx\n",
Status);
if (NT_SUCCESS(Status))
{
DPRINT("VolumeLabel: '%S'\n", FileFsVolume->VolumeLabel);
if (_wcsicmp(FileFsVolume->VolumeLabel, L"REACTOS") == 0)
{
ZwClose(Handle);
*DeviceNumber = i;
return(STATUS_SUCCESS);
}
}
ZwClose(Handle);
}
#endif

/*
* Check for 'reactos/ntoskrnl.exe' first...
*/

swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu\\reactos\\ntoskrnl.exe",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
if (NT_SUCCESS(Status))
{
DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i);
ZwClose(Handle);
*DeviceNumber = i;
return(STATUS_SUCCESS);
}

/*
* ...and for 'reactos/system32/ntoskrnl.exe' also.
*/

swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu\\reactos\\system32\\ntoskrnl.exe",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
if (NT_SUCCESS(Status))
{
DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i);
ZwClose(Handle);
*DeviceNumber = i;
return(STATUS_SUCCESS);
}
}

DPRINT("Could not find ntoskrnl.exe\n");
*DeviceNumber = (ULONG)-1;

return(STATUS_UNSUCCESSFUL);
}


NTSTATUS INIT_FUNCTION
IoCreateSystemRootLink(PCHAR ParameterLine)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
UNICODE_STRING DeviceName;
UNICODE_STRING ArcName;
UNICODE_STRING BootPath;
PCHAR ParamBuffer;
PWCHAR ArcNameBuffer;
PCHAR p;
NTSTATUS Status;
ULONG Length;
HANDLE Handle;

/* Create local parameter line copy */
ParamBuffer = ExAllocatePool(PagedPool, 256);
strcpy(ParamBuffer, (char *)ParameterLine);

DPRINT("%s\n", ParamBuffer);
/* Format: <arc_name><path> [options...] */

/* cut options off */
p = strchr(ParamBuffer, ' ');
if (p)
*p = 0;
DPRINT("%s\n", ParamBuffer);

/* extract path */
p = strchr(ParamBuffer, '\\');
if (p)
{
DPRINT("Boot path: %s\n", p);
RtlCreateUnicodeStringFromAsciiz(&BootPath, p);
*p = 0;
}
else
{
DPRINT("Boot path: %s\n", "\\");
RtlCreateUnicodeStringFromAsciiz(&BootPath, "\\");
}
DPRINT("ARC name: %s\n", ParamBuffer);

p = strstr(ParamBuffer, "cdrom");
if (p != NULL)
{
ULONG DeviceNumber;

DPRINT("Booting from CD-ROM!\n");
Status = IopCheckCdromDevices(&DeviceNumber);
if (!NT_SUCCESS(Status))
{
CPRINT("Failed to find setup disk!\n");
return(Status);
}

sprintf(p, "cdrom(%lu)", DeviceNumber);

DPRINT("New ARC name: %s\n", ParamBuffer);

/* Adjust original command line */
p = strstr(ParameterLine, "cdrom");
if (p != NULL);
{
char temp[256];
char *q;

q = strchr(p, ')');
if (q != NULL)
{

q++;
strcpy(temp, q);
sprintf(p, "cdrom(%lu)", DeviceNumber);
strcat(p, temp);
}
}
}

/* Only arc name left - build full arc name */
ArcNameBuffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
swprintf(ArcNameBuffer,
L"\\ArcName\\%S", ParamBuffer);
RtlInitUnicodeString(&ArcName, ArcNameBuffer);
DPRINT("Arc name: %wZ\n", &ArcName);

/* free ParamBuffer */
ExFreePool(ParamBuffer);

/* allocate device name string */
DeviceName.Length = 0;
DeviceName.MaximumLength = 256 * sizeof(WCHAR);
DeviceName.Buffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));

InitializeObjectAttributes(&ObjectAttributes,
&ArcName,
OBJ_OPENLINK,
NULL,
NULL);

Status = ZwOpenSymbolicLinkObject(&Handle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&BootPath);
ExFreePool(DeviceName.Buffer);
CPRINT("ZwOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
&ArcName,
Status);
ExFreePool(ArcName.Buffer);

return(Status);
}
ExFreePool(ArcName.Buffer);

Status = ZwQuerySymbolicLinkObject(Handle,
&DeviceName,
&Length);
ZwClose (Handle);
if (!NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&BootPath);
ExFreePool(DeviceName.Buffer);
CPRINT("ZwQuerySymbolicObject() failed (Status %x)\n",
Status);

return(Status);
}
DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);

RtlAppendUnicodeStringToString(&DeviceName,
&BootPath);

RtlFreeUnicodeString(&BootPath);
DPRINT("DeviceName: %wZ\n", &DeviceName);

/* create the '\SystemRoot' link */
Status = IoCreateSymbolicLink(&LinkName,
&DeviceName);
ExFreePool(DeviceName.Buffer);
if (!NT_SUCCESS(Status))
{
CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
Status);

return(Status);
}

/* Check whether '\SystemRoot'(LinkName) can be opened */
InitializeObjectAttributes(&ObjectAttributes,
&LinkName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
if (!NT_SUCCESS(Status))
{
CPRINT("ZwOpenFile() failed to open '\\SystemRoot' (Status %x)\n",
Status);
return(Status);
}

ZwClose(Handle);

return(STATUS_SUCCESS);
}

/* EOF */



Thanks to a little help

Dietmar
 
S

Slobodan Brcin \(eMVP\)

Hi Dietmar,

Like I said many times before (I think) I can't discuss USB boot topics.
I'm just curious where did you get this code? According to function names this awfully resemble NT kernel code.

Regards,
Slobodan

Dietmar said:
Hi Slobodan,

is this the right way?



/* INCLUDES
*****************************************************************/

#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>

/* MACROS
*******************************************************************/

#define FS_VOLUME_BUFFER_SIZE (MAX_PATH +
sizeof(FILE_FS_VOLUME_INFORMATION))

/* FUNCTIONS
****************************************************************/

NTSTATUS INIT_FUNCTION
IoCreateArcNames(VOID)
{
PCONFIGURATION_INFORMATION ConfigInfo;
PDRIVE_LAYOUT_INFORMATION LayoutInfo = NULL;
WCHAR DeviceNameBuffer[80];
WCHAR ArcNameBuffer[80];
UNICODE_STRING DeviceName;
UNICODE_STRING ArcName;
ULONG i, j, k;
NTSTATUS Status;
PFILE_OBJECT FileObject;
PDEVICE_OBJECT DeviceObject;
BOOL IsRemovableMedia;

DPRINT("IoCreateArcNames() called\n");

ConfigInfo = IoGetConfigurationInformation();

/* create ARC names for floppy drives */
DPRINT("Floppy drives: %lu\n", ConfigInfo->FloppyCount);
for (i = 0; i < ConfigInfo->FloppyCount; i++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\Floppy%lu",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)fdisk(%lu)",
i);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);
}

/* create ARC names for hard disk drives */
DPRINT("Disk drives: %lu\n", ConfigInfo->DiskCount);
for (i = 0, k = 0; i < ConfigInfo->DiskCount; i++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\Harddisk%lu\\Partition0",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);


Status = IoGetDeviceObjectPointer(&DeviceName,
FILE_READ_DATA,
&FileObject,
&DeviceObject);
if (!NT_SUCCESS(Status))
{
continue;
}
IsRemovableMedia = DeviceObject->Characteristics & FILE_REMOVABLE_MEDIA ?
TRUE : FALSE;
ObDereferenceObject(FileObject);
if (IsRemovableMedia)
{
continue;
}

swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(0)",
k);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);

Status = xHalQueryDriveLayout(&DeviceName,
&LayoutInfo);
if (!NT_SUCCESS(Status))
return(Status);

DPRINT("Number of partitions: %u\n", LayoutInfo->PartitionCount);

for (j = 0;j < LayoutInfo->PartitionCount; j++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\Harddisk%lu\\Partition%lu",
i,
j + 1);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

swprintf(ArcNameBuffer,

L"\\ArcName\\multi(0)disk(0)rdisk(%lu)partition(%lu)",
k,
j + 1);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);
}

ExFreePool(LayoutInfo);
LayoutInfo = NULL;
k++;
}

/* create ARC names for cdrom drives */
DPRINT("CD-ROM drives: %lu\n", ConfigInfo->CdRomCount);
for (i = 0; i < ConfigInfo->CdRomCount; i++)
{
swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

swprintf(ArcNameBuffer,
L"\\ArcName\\multi(0)disk(0)cdrom(%lu)",
i);
RtlInitUnicodeString(&ArcName,
ArcNameBuffer);
DPRINT("%wZ ==> %wZ\n",
&ArcName,
&DeviceName);

Status = IoAssignArcName(&ArcName,
&DeviceName);
if (!NT_SUCCESS(Status))
return(Status);
}

DPRINT("IoCreateArcNames() done\n");

return(STATUS_SUCCESS);
}


static NTSTATUS
IopCheckCdromDevices(PULONG DeviceNumber)
{
PCONFIGURATION_INFORMATION ConfigInfo;
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING DeviceName;
WCHAR DeviceNameBuffer[MAX_PATH];
HANDLE Handle;
ULONG i;
NTSTATUS Status;
IO_STATUS_BLOCK IoStatusBlock;
#if 0
PFILE_FS_VOLUME_INFORMATION FileFsVolume;
USHORT Buffer[FS_VOLUME_BUFFER_SIZE];

FileFsVolume = (PFILE_FS_VOLUME_INFORMATION)Buffer;
#endif

ConfigInfo = IoGetConfigurationInformation();
for (i = 0; i < ConfigInfo->CdRomCount; i++)
{
#if 0
swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu\\",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
if (NT_SUCCESS(Status))
{
Status = ZwQueryVolumeInformationFile(Handle,
&IoStatusBlock,
FileFsVolume,
FS_VOLUME_BUFFER_SIZE,

FileFsVolumeInformation);
DPRINT("ZwQueryVolumeInformationFile() Status %lx\n",
Status);
if (NT_SUCCESS(Status))
{
DPRINT("VolumeLabel: '%S'\n", FileFsVolume->VolumeLabel);
if (_wcsicmp(FileFsVolume->VolumeLabel, L"REACTOS") == 0)
{
ZwClose(Handle);
*DeviceNumber = i;
return(STATUS_SUCCESS);
}
}
ZwClose(Handle);
}
#endif

/*
* Check for 'reactos/ntoskrnl.exe' first...
*/

swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu\\reactos\\ntoskrnl.exe",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
if (NT_SUCCESS(Status))
{
DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i);
ZwClose(Handle);
*DeviceNumber = i;
return(STATUS_SUCCESS);
}

/*
* ...and for 'reactos/system32/ntoskrnl.exe' also.
*/

swprintf(DeviceNameBuffer,
L"\\Device\\CdRom%lu\\reactos\\system32\\ntoskrnl.exe",
i);
RtlInitUnicodeString(&DeviceName,
DeviceNameBuffer);

InitializeObjectAttributes(&ObjectAttributes,
&DeviceName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
DPRINT("ZwOpenFile() DeviceNumber %lu Status %lx\n", i, Status);
if (NT_SUCCESS(Status))
{
DPRINT("Found ntoskrnl.exe on Cdrom%lu\n", i);
ZwClose(Handle);
*DeviceNumber = i;
return(STATUS_SUCCESS);
}
}

DPRINT("Could not find ntoskrnl.exe\n");
*DeviceNumber = (ULONG)-1;

return(STATUS_UNSUCCESSFUL);
}


NTSTATUS INIT_FUNCTION
IoCreateSystemRootLink(PCHAR ParameterLine)
{
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING LinkName = RTL_CONSTANT_STRING(L"\\SystemRoot");
UNICODE_STRING DeviceName;
UNICODE_STRING ArcName;
UNICODE_STRING BootPath;
PCHAR ParamBuffer;
PWCHAR ArcNameBuffer;
PCHAR p;
NTSTATUS Status;
ULONG Length;
HANDLE Handle;

/* Create local parameter line copy */
ParamBuffer = ExAllocatePool(PagedPool, 256);
strcpy(ParamBuffer, (char *)ParameterLine);

DPRINT("%s\n", ParamBuffer);
/* Format: <arc_name><path> [options...] */

/* cut options off */
p = strchr(ParamBuffer, ' ');
if (p)
*p = 0;
DPRINT("%s\n", ParamBuffer);

/* extract path */
p = strchr(ParamBuffer, '\\');
if (p)
{
DPRINT("Boot path: %s\n", p);
RtlCreateUnicodeStringFromAsciiz(&BootPath, p);
*p = 0;
}
else
{
DPRINT("Boot path: %s\n", "\\");
RtlCreateUnicodeStringFromAsciiz(&BootPath, "\\");
}
DPRINT("ARC name: %s\n", ParamBuffer);

p = strstr(ParamBuffer, "cdrom");
if (p != NULL)
{
ULONG DeviceNumber;

DPRINT("Booting from CD-ROM!\n");
Status = IopCheckCdromDevices(&DeviceNumber);
if (!NT_SUCCESS(Status))
{
CPRINT("Failed to find setup disk!\n");
return(Status);
}

sprintf(p, "cdrom(%lu)", DeviceNumber);

DPRINT("New ARC name: %s\n", ParamBuffer);

/* Adjust original command line */
p = strstr(ParameterLine, "cdrom");
if (p != NULL);
{
char temp[256];
char *q;

q = strchr(p, ')');
if (q != NULL)
{

q++;
strcpy(temp, q);
sprintf(p, "cdrom(%lu)", DeviceNumber);
strcat(p, temp);
}
}
}

/* Only arc name left - build full arc name */
ArcNameBuffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));
swprintf(ArcNameBuffer,
L"\\ArcName\\%S", ParamBuffer);
RtlInitUnicodeString(&ArcName, ArcNameBuffer);
DPRINT("Arc name: %wZ\n", &ArcName);

/* free ParamBuffer */
ExFreePool(ParamBuffer);

/* allocate device name string */
DeviceName.Length = 0;
DeviceName.MaximumLength = 256 * sizeof(WCHAR);
DeviceName.Buffer = ExAllocatePool(PagedPool, 256 * sizeof(WCHAR));

InitializeObjectAttributes(&ObjectAttributes,
&ArcName,
OBJ_OPENLINK,
NULL,
NULL);

Status = ZwOpenSymbolicLinkObject(&Handle,
SYMBOLIC_LINK_ALL_ACCESS,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&BootPath);
ExFreePool(DeviceName.Buffer);
CPRINT("ZwOpenSymbolicLinkObject() '%wZ' failed (Status %x)\n",
&ArcName,
Status);
ExFreePool(ArcName.Buffer);

return(Status);
}
ExFreePool(ArcName.Buffer);

Status = ZwQuerySymbolicLinkObject(Handle,
&DeviceName,
&Length);
ZwClose (Handle);
if (!NT_SUCCESS(Status))
{
RtlFreeUnicodeString(&BootPath);
ExFreePool(DeviceName.Buffer);
CPRINT("ZwQuerySymbolicObject() failed (Status %x)\n",
Status);

return(Status);
}
DPRINT("Length: %lu DeviceName: %wZ\n", Length, &DeviceName);

RtlAppendUnicodeStringToString(&DeviceName,
&BootPath);

RtlFreeUnicodeString(&BootPath);
DPRINT("DeviceName: %wZ\n", &DeviceName);

/* create the '\SystemRoot' link */
Status = IoCreateSymbolicLink(&LinkName,
&DeviceName);
ExFreePool(DeviceName.Buffer);
if (!NT_SUCCESS(Status))
{
CPRINT("IoCreateSymbolicLink() failed (Status %x)\n",
Status);

return(Status);
}

/* Check whether '\SystemRoot'(LinkName) can be opened */
InitializeObjectAttributes(&ObjectAttributes,
&LinkName,
0,
NULL,
NULL);

Status = ZwOpenFile(&Handle,
FILE_ALL_ACCESS,
&ObjectAttributes,
&IoStatusBlock,
0,
0);
if (!NT_SUCCESS(Status))
{
CPRINT("ZwOpenFile() failed to open '\\SystemRoot' (Status %x)\n",
Status);
return(Status);
}

ZwClose(Handle);

return(STATUS_SUCCESS);
}

/* EOF */



Thanks to a little help

Dietmar
 
D

Dietmar

Hi Slobodan,
I know, that you dont want to talk about USB and
the reason why not.

I can boot now any XP SP1, XP SP2, XPE1, XPE2 from any USB device with a
motherboard, which is not older than 2...3 years.
The new Tutorial(Version 3)from me, how to do this, is nearly ready and
will appear in the german computermagazin c't in about 1 week.

Sean Liming asks me for that and so I will make also a try in English.

The code above with IoCreateArcNames()is from Reactos. This is a clone
from XP, but not from Microsoft and it is free for copying and changing
drivers.

I try to get better and so I am not sure, wether
IoCreateArcNames() will help against 0x7B on USB boot.
As far as I know changes IoCreateArcNames() for example
\Device\HarddiskVolume5 (string in Unicode)
to multi(0)disk(0)rdisk(0)partition(1)(string in Unicode).
But there are two questions remaining to me:
This is useless, if not another function is called, which Bootdevice is
meant with \Device\HarddiskVolume5 .

And the other, more important is the following:
When the time to start for drivers with start=0 entry in registry is over,
there may be a device(here for example an USB Bootdevice) which is not
recogniced until then and that will mean BSOD 0x7B.
So you have to use something, that looks for bootable devices after ALL
drivers and devices are ready, which may be needed for booting.
I think, like Microsoft says and here in the newsgroup also, that the
IoRegisterBootDriverReinitialization routine, which is called by a boot
driver to register the driver's reinitialization routine with the I/O
manager to be called after ALL devices have been enumerated and started,
may be the right one, to "wait".

Nice to hear from you
Dietmar
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top