OpenXDK can be extended to work with oz_paulb's LBA48.
Need to patch OpenXDK to support NtDeviceIoControlFile.
xboxkrnl.exe.def
CODE
NtDeviceIoControlFile@40 @ 196 NONAME
types.h
CODE
typedef VOID (*PIO_APC_ROUTINE) (PVOID ApcContext,PIO_STATUS_BLOCK IoStatusBlock,ULONG Reserved);
nt.h
CODE
XBSYSAPI EXPORTNUM(196) NTSTATUS NTAPI NtDeviceIoControlFile
(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN ULONG IoControlCode,
IN PVOID InputBuffer OPTIONAL,
IN ULONG InputBufferLength,
OUT PVOID OutputBuffer OPTIONAL,
IN ULONG OutputBufferLength
)
{
return STATUS_SUCCESS;
}
The sample program can read the xbpartitioner style partition table but that's about it. I cannot figure out why it cannot read the individual partition tables and their cluster sizes.
CODE
#include
#include
#include
#include
#include
#include
#include "string.h"
#include "stdio.h"
#include
#include "partition.h"
#include "fatx.h"
unsigned int
read_lba48_info(XboxPartitionTable *p_table, XboxPartitionTable **p_table_add, DWORD *total_sectors, DWORD *version)
{
ANSI_STRING a_file;
OBJECT_ATTRIBUTES obj_attr;
IO_STATUS_BLOCK io_stat_block;
HANDLE handle;
unsigned int stat;
unsigned int lba48_ioctl_cmd_in_buf[100];
unsigned int lba48_ioctl_cmd_out_buf[100];
unsigned int geom_ioctl_cmd_in_buf[100];
unsigned int partition_table_addr;
// char pt[256];
RtlInitAnsiString (&a_file,"\\Device\\Harddisk0\\Partition0");
/*strcpy (pt,);
ANSI_STRING DeviceName =
{
strlen(pt),
strlen(pt) + 1,
(char *)pt
};*/
memset(p_table, 0, sizeof(XboxPartitionTable));
obj_attr.RootDirectory = NULL;
obj_attr.ObjectName = &a_file;
obj_attr.Attributes = OBJ_CASE_INSENSITIVE;
stat = NtOpenFile(&handle, (GENERIC_READ), &obj_attr, &io_stat_block, FILE_SHARE_READ, FILE_SYNCHRONOUS_IO_ALERT | FILE_NO_INTERMEDIATE_BUFFERING);
if (stat != STATUS_SUCCESS) {
debugPrint ("Fail at NtOpenFile\n");
return stat;
}
else
{
//////////////////// lba48 ////////////////////
if (stat == STATUS_SUCCESS)
{
memset(lba48_ioctl_cmd_in_buf, 0, sizeof(lba48_ioctl_cmd_in_buf));
lba48_ioctl_cmd_in_buf[0] = IOCTL_SUBCMD_GET_INFO;
memset(lba48_ioctl_cmd_out_buf, 0, sizeof(lba48_ioctl_cmd_out_buf));
stat = NtDeviceIoControlFile(handle, 0, 0, 0, &io_stat_block,
IOCTL_CMD_LBA48_ACCESS,
lba48_ioctl_cmd_in_buf, sizeof(lba48_ioctl_cmd_in_buf),
lba48_ioctl_cmd_out_buf, sizeof(lba48_ioctl_cmd_out_buf));
}
else
debugPrint ("Fail After NtDeviceIoControlFile\n");
//////////////////////////////////////////////
if ((lba48_ioctl_cmd_out_buf[LBA48_GET_INFO_MAGIC1_IDX] != LBA48_GET_INFO_MAGIC1_VAL) ||
(lba48_ioctl_cmd_out_buf[LBA48_GET_INFO_MAGIC2_IDX] != LBA48_GET_INFO_MAGIC2_VAL)) {
debugPrint ("Fail After Get Info Magic\n");
return 0;
}
// this way is compatible with Paul's lba48 patched kernels
partition_table_addr = lba48_ioctl_cmd_out_buf[LBA48_GET_INFO_LOWCODE_BASE_IDX];
partition_table_addr += lba48_ioctl_cmd_out_buf[LBA48_GET_INFO_PART_TABLE_OFS_IDX];
*version = lba48_ioctl_cmd_out_buf[LBA48_GET_INFO_PATCHCODE_VERSION_IDX];
if (*version == 2)
partition_table_addr += 0x200;
*p_table_add = (XboxPartitionTable *) partition_table_addr;
memcpy(p_table, (void *) partition_table_addr, sizeof(XboxPartitionTable));
NtClose(handle);
//if (stat != STATUS_SUCCESS) {
// return stat;
//}
return STATUS_SUCCESS;
}
}
unsigned int
get_clustersize(ANSI_STRING DeviceName)
{
int j;
HANDLE hDisk;
NTSTATUS status;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER RWOffset;
FATX_SUPERBLOCK * fsb;
char part[18];
char po[3];
char dis[255];
ObjectAttributes.RootDirectory = 0;
ObjectAttributes.ObjectName = &DeviceName;
ObjectAttributes.Attributes = OBJ_CASE_INSENSITIVE;
RWOffset.u.LowPart=0;
//fsb = malloc(sizeof(FATX_SUPERBLOCK));
status = NtOpenFile(&hDisk, GENERIC_READ | GENERIC_WRITE, &ObjectAttributes, &IoStatusBlock, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_SYNCHRONOUS_IO_ALERT);
if (NT_SUCCESS(status)){
status = NtReadFile(hDisk, NULL, NULL, NULL, &IoStatusBlock, part , 4, &RWOffset);
if (!NT_SUCCESS(status))
sprintf (dis,"here %X %X %X %X\n",part[0],part[1],part[2],part[3]);
debugPrint (dis);
return 2;
}
else
return 0;
NtClose(hDisk);
//if (fsb!=NULL)
// {
sprintf (dis,"here %X %X %X %X\n",part[0],part[1],part[2],part[3]);
debugPrint (dis);
// free(fsb);
// }
return 1;
}
void XBoxStartup(void)
{
int i,done=0;
XboxPartitionTable pt,*ptaddr;
DWORD totalSectors,ver;
char display[255];
XInput_Init();
int cluster_size;
ANSI_STRING partition_str[14];
char partStr[][32] = {
"\\Device\\Harddisk0\\Partition1",
"\\Device\\Harddisk0\\Partition2",
"\\Device\\Harddisk0\\Partition3",
"\\Device\\Harddisk0\\Partition4",
"\\Device\\Harddisk0\\Partition5",
"\\Device\\Harddisk0\\Partition6",
"\\Device\\Harddisk0\\Partition7",
"\\Device\\Harddisk0\\Partition8",
"\\Device\\Harddisk0\\Partition9",
"\\Device\\Harddisk0\\Partition10",
"\\Device\\Harddisk0\\Partition11",
"\\Device\\Harddisk0\\Partition12",
"\\Device\\Harddisk0\\Partition13",
"\\Device\\Harddisk0\\Partition14"
};
for (i =0; i < 14; i++)
RtlInitAnsiString(&partition_str, partStr);
debugPrint("List Partitions\n");
if ((read_lba48_info(&pt,&ptaddr,&totalSectors,&ver)==STATUS_SUCCESS))
{
for (i=0;i<14;i++)
{
if (pt.TableEntries.Flags & PE_PARTFLAGS_IN_USE
)
{
cluster_size = get_clustersize(partition_str);
if (cluster_size !=0)
{
if ((pt.TableEntries.LBASize>=LBASIZE_512GB && cluster_size<64)||
(pt.TableEntries.LBASize>=LBASIZE_256GB && cluster_size<32))
sprintf(display, "partition %d start %ld size %ld ERR\n", i,pt.TableEntries.LBAStart,pt.TableEntries.LBASize*512);
else
sprintf(display, "partition %d start %ld size %ld %dK\n", i,pt.TableEntries.LBAStart,pt.TableEntries.LBASize*512,cluster_size);
}
else sprintf (display,"\n");
debugPrint (display);
}
}
}
else
{
debugPrint("Error LBA48\n");
}
debugPrint("Press B to stop program\n");
while(!done)
{
XInput_GetEvents();
for(i=0; i<4; i++)
{
if(g_Pads.PressedButtons.ucAnalogButtons[XPAD_B]) done=1;
}
};
debugPrint("Bye\n");
XInput_Quit();
XSleep(3000);
XReboot();
}