Archive:USB Mass Storage support in XBMC for Xbox - Developers discussion: Difference between revisions

From Official Kodi Wiki
Jump to navigation Jump to search
>Gamester17
No edit summary
({{xbmc4xbox}})
Line 1: Line 1:
'''Note!''' Non-developers can also help with the [[USB Mass Storage support in XBMC for Xbox|USB Mass Storage support in XBMC article (link)]].<br><br>
{{xbmc4xbox}}
==FAT12/FAT16/VFAT/FAT32 on USB Mass Storage devices==
XBMC still rely on the Xbox BIOS kernel USB driver to handle the USB subsystem stuff, including drive detection, etc.. XBMC then uses a ported version of dosfs to enable FAT12/FAT16/VFAT/FAT32 reading from USB Mass Storage devices,  is read the drive directly (ie not via the usual XDK stuff) which we then feed through a simple filesystem layer (based on dosfs).
<br><br>
* IoSynchronousDeviceIoControlRequest does not return a success on USB HDD<br>
* Kernel will report a: ''"WRN[MU]: The logical block configuration of an MU is outside supported parameter ranges."''<br>
<br>
So what can we do to detect a USB HDD Drive?<br>
I tried to use some code from undocumented source to made a test:
I think we can ackt like the kernel and can controll the USB our self to support also USB HDD's<br>
i really just played with the code nothing else.. <br>
 
<br>
<code>
bool CMemoryUnitManager::MountFatDevice(unsigned long port, unsigned long slot)
{
#define WRITE_SIZE      (4096*256)  //1MB write size
  #define TEST_BUFFER_SIZE (4096*32)    //128KB
  #define TRANSFER_SIZE    4096
  #define MU_MEDIA_OFFSET  4096*8
  #define EXTRA_SIZE 4096
  #define SECTOR_MASK 0xFFFFFF000
 
  PARTITION_INFORMATION pi;
  ULONG tryCount = 0;
  //CHAR                  name[64];
//  HRESULT                hr;
  //HANDLE                  hFile;
  PUCHAR buffer,buffer2;
  UCHAR pattern[4] = {1,2,3,4};
  ULONG i;
  HANDLE hVolume;
  OBJECT_ATTRIBUTES oa;
  IO_STATUS_BLOCK statusBlock;
  //DISK_GEOMETRY diskGeometry;
 
  NTSTATUS Status;
PDEVICE_OBJECT DeviceObject;
 
  CHAR oszDeviceObjectBuffer[64];
  //OBJECT_STRING DeviceName;
  OBJECT_STRING objName;
  ULONG  totalErrorCount = 0;
  ULONG  localErrorCount = 0;
  ULONGLONG bytesPerSecond = 0;
 
  objName.Length = 1024;
  objName.MaximumLength = sizeof(oszDeviceObjectBuffer)-1;
  objName.Buffer = oszDeviceObjectBuffer;
//DeviceName.Length = 0;
//DeviceName.MaximumLength = sizeof(szDeviceName)/sizeof(CHAR)-2;
//DeviceName.Buffer = szDeviceName;
 
  CLog::Log(LOGDEBUG, __FUNCTION__" Creating MU device (port %i, slot %i)", port, slot);
  Status = MU_CreateDeviceObject(port, slot, &objName);
  if(!NT_SUCCESS(Status))
  {
    CLog::Log(LOGDEBUG, __FUNCTION__"Could not create device object for MU, status = 0x%0.8x");
    //return false;
  }
 
  buffer =  (PUCHAR) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, TEST_BUFFER_SIZE+EXTRA_SIZE);
  buffer2 =  (PUCHAR) LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, TEST_BUFFER_SIZE+EXTRA_SIZE);
 
  buffer = (PUCHAR)((ULONG) buffer & SECTOR_MASK);
  buffer += EXTRA_SIZE;
 
  buffer2 = (PUCHAR)((ULONG) buffer2 & SECTOR_MASK);
  buffer2 += EXTRA_SIZE;
 
  for (i=0;i<TEST_BUFFER_SIZE/sizeof(ULONG);i++)
  {
    *((PULONG)buffer+i) = i;
  }
 
  CLog::Log(LOGDEBUG, __FUNCTION__"MUTEST: LowLevelTest: Test buffer 1 at %x, 2 at %x",buffer,buffer2);
 
  InitializeObjectAttributes(&oa, (POBJECT_STRING) &objName, OBJ_CASE_INSENSITIVE, NULL, NULL);
 
  CLog::Log(LOGDEBUG, __FUNCTION__"MUTEST: LowLevelTest: Opening volume");
     
  Status = NtOpenFile(&hVolume,
                        SYNCHRONIZE | GENERIC_ALL,
                        &oa,
                        &statusBlock,
                        FILE_SHARE_READ | FILE_SHARE_WRITE,
                        FILE_NO_INTERMEDIATE_BUFFERING | FILE_SYNCHRONOUS_IO_ALERT);
     
  Status = NtDeviceIoControlFile(hVolume,0,NULL,NULL,&statusBlock,IOCTL_DISK_GET_PARTITION_INFO,NULL,0,&pi,
                                          sizeof(pi));
//if (!NT_SUCCESS(Status))
//{
    CLog::Log(LOGDEBUG, __FUNCTION__" Getting MU device (port %i, slot %i)", port, slot);
DeviceObject = MU_GetExistingDeviceObject(port, slot);
    CLog::Log(LOGDEBUG, __FUNCTION__" Reading MU partition info (port %i, slot %i)", port, slot);
 
    Status = IoSynchronousDeviceIoControlRequest(IOCTL_DISK_GET_PARTITION_INFO,
            DeviceObject, NULL, 0, &pi,
            sizeof(pi), NULL, FALSE);
    if (!NT_SUCCESS(Status))
    {
      CLog::Log(LOGDEBUG, __FUNCTION__" !! FAILED !! Reading MU partition info (port %i, slot %i)", port, slot);
      //return false;
 
      // IOCTL_DISK_GET_DRIVE_GEOMETRY
      // IOCTL_DISK_GET_PARTITION_INFO
      // IOCTL_DISK_VERIFY
    }
 
    uint8_t sector[SECTOR_SIZE];
    uint8_t unit = m_fatUnits.size();
 
    CFatDevice *fatDevice = new CFatDevice(port, slot, DeviceObject);
    m_fatUnits.push_back(fatDevice);
 
    // TEST: Dump first 32k of image to make sure we're reading valid data (yuck!)
    DumpImage("Z:\\image.bin", unit, 64);
 
    CLog::Log(LOGDEBUG, __FUNCTION__" Reading first sector to determine type");
    uint32_t lbrSector = 0;
    int ret = CheckFirstSectorForLBR(unit);
    if (ret)
    {
      CLog::Log(LOGDEBUG, __FUNCTION__" First sector failed LBR test (%i)", ret);
      // read the MBR
    uint32_t psize;
    uint8_t pactive, ptype;
      // 0 is the partition number
      lbrSector = DFS_GetPtnStart(unit, sector, 0, &pactive, &ptype, &psize);
      if (lbrSector == 0xFFFFFFFF)
      { // fail
        CLog::Log(LOGDEBUG, __FUNCTION__" No MBR found - assuming none exists");
        lbrSector = 0;
      }
      else
      {
        CLog::Log(LOGDEBUG, __FUNCTION__" Partition 0 start sector 0x%-08.8lX active %-02.2hX type %-02.2hX size %-08.8lX\n", lbrSector, pactive, ptype, psize);
      }
    }
    if (DFS_GetVolInfo(unit, sector, lbrSector, fatDevice->GetVolume()))
    {
      CLog::Log(LOGDEBUG, __FUNCTION__" Error getting volume information\n");
      UnMountFatDevice(port, slot);
      return false;
    }
 
    fatDevice->ReadVolumeName();
    fatDevice->LogInfo();
    return true;
//}
  //return false;
}
 
</code>
<br><br>
 
===The 4GB limit===
XBMC rely on the Xbox BIOS kernel USB driver to handle the USB subsystem stuff, including drive detection etc. One limitation with this is this it can't support memory-cars/harddrives larger than 4GB. This is Xbox BIOS kernel limitation. Only way around it that we see would be to completely rewriting the USB driver (practically writting a USB stack for the Xbox from scratch), which no one of Team-XBMC developers have the experience, skill or time to do, (plus it'd be a hell of a lot of work).<br>
 
 
 
[[category:Inner Workings]]
[[category:Development]]
[[category:Inner Workings]]
[[category:Xbox]]
[[category:To-Do]]

Revision as of 11:14, 9 September 2011

Attention.png XBMC for XBOX is not supported by xbmc anymore. Please check for updates on the related page at the xbmc4xbox wiki.