none
Access raw partition RRS feed

  • Question

  • Hi,

    Since Microsoft has released vs2015 and clang/C2 toolset I am porting some open-source libraries (in my case libblkid) that is used to 
    identify harddisk partitions and I have managed by providing my own implementation of open, read, ... to make it work to detect partitions.
    Very simply when passing "/dev/sdx" I just convert it into \\\\.\\PhysicalDrive%d, devicenumber.

    Now I would like to get further and detect filesystem but to do that I need to access partitions individually but it doesn't seem to be possible.
    I mean in my case I am working with filesystems not natively recognized by Windows and there is no associated volume.

    So I have found an article talking about accessing raw sectors here : http://www.codeproject.com/Articles/28314/Reading-and-Writing-to-Raw-Disk-Sectors
    and I would like to know if it's the way to go or if there is a simpler approach.

    I tried to open the raw disk and then go directly the start of the partition then call ReadFile but it doesn't seem to work:

    To explain how I do my experiments and also introduce my second question here are my harddisks configuration (dmdiag.exe): 

    ******************************************************************************

    ---------- \Device\Harddisk0 ----------

    \Device\Harddisk0\DR0            (Device)
    \Device\Harddisk0\Partition0     (SymbolicLink) -> \Device\Harddisk0\DR0
    \Device\Harddisk0\Partition1     (SymbolicLink) -> \Device\HarddiskVolume1

    ---------- \Device\Harddisk1 ----------

    \Device\Harddisk1\DR1            (Device)
    \Device\Harddisk1\Partition0     (SymbolicLink) -> \Device\Harddisk1\DR1
    \Device\Harddisk1\Partition1     (SymbolicLink) -> \Device\HarddiskVolume2
    \Device\Harddisk1\Partition2     (SymbolicLink) -> \Device\HarddiskVolume3
    \Device\Harddisk1\Partition3     (SymbolicLink) -> \Device\HarddiskVolume4
    \Device\Harddisk1\Partition4     (SymbolicLink) -> \Device\HarddiskVolume5
    \Device\Harddisk1\Partition5     (SymbolicLink) -> \Device\HarddiskVolume6
    \Device\Harddisk1\Partition6     (SymbolicLink) -> \Device\HarddiskVolume7
    \Device\Harddisk1\Partition7     (SymbolicLink) -> \Device\HarddiskVolume8

    ---------- \Device\Harddisk2 ----------

    \Device\Harddisk2\DR5            (Device)
    \Device\Harddisk2\Partition0     (SymbolicLink) -> \Device\Harddisk2\DR5
    \Device\Harddisk2\Partition1     (SymbolicLink) -> \Device\HarddiskVolume12

    *********************************************************************************

    Let's focus now on \Device\Harddisk2 that is actually a USB key with GPT partition table and 2 partitions:

    Partition Name        Partition         Starting   Partition  Part           Part  Partition
                           Partition GUID   Offset (bytes)   Length (bytes)     Sectors    No           Type  Partition

                     EFI System Partition
      d53129ed-9088-4fef-a938-1fd6bca0dc6e           20,480      209,715,200     409,600     0     EFI system          0
                                      USB
      c9d114a6-4743-44b4-89fc-2645d10fb62e      209,735,680   31,247,523,840  61,030,320     1          0

    So I tried this :

    hDevice = CreateFile(deviceInterfaceDetailData->DevicePath,
    				GENERIC_READ,
    				FILE_SHARE_READ | FILE_SHARE_WRITE,
    				NULL,
    				OPEN_EXISTING,
    				0,
    				NULL);
    			CHK(INVALID_HANDLE_VALUE != hDevice,
    				"CreateFile");
    
    			CHK(DeviceIoControl(hDevice,
    				IOCTL_STORAGE_GET_DEVICE_NUMBER,
    				NULL,
    				0,
    				&diskNumber,
    				sizeof(STORAGE_DEVICE_NUMBER),
    				&bytesReturned,
    				NULL),
    				"IOCTL_STORAGE_GET_DEVICE_NUMBER");
    
    			// If we are here it means everything was ok with this drive => get info
    			DiskInfo dskInfo = {0};
    			dskInfo.u32DeviceNumber = diskNumber.DeviceNumber;
    			_tcsncpy(dskInfo.szDevicePath, deviceInterfaceDetailData->DevicePath, MAX_PATH);
    			_tcsncpy(dskInfo.szShortDevicePath, deviceInterfaceDetailData->DevicePath, MAX_PATH);
    			if (diskNumber.DeviceType == FILE_DEVICE_DISK){
    				snprintf(dskInfo.szShortDevicePath, MAX_PATH, "\\\\.\\PhysicalDrive%d", diskNumber.DeviceNumber);
    			}
    			dskInfo.canBePartitioned = (diskNumber.PartitionNumber == 0);
    
    			DWORD dwErr;
    			if (dskInfo.u32DeviceNumber == 2)
    			{
    				DWORD dwPos = SetFilePointer(hDevice, 209735680, NULL, 0);
    				DWORD dwRead;
    				char buff[64];
    				BOOL bRet = ReadFile(hDevice, buff, 64, &dwRead, NULL);
    				dwErr = ::GetLastError();
    			}

    but bRet returns false and lasterror is 87 so could you confirm that it's not possible from user-mode to access this partition ?

    -------------------------------

    I have anothere question related to harddisk and the way it's handled by kernel because as you can see from the dmdiag.exe output I have posted 
    above it seems there is only 1 partition (partition0 being the whole drive from what I undertand):

    \Device\Harddisk2\DR5            (Device)
    \Device\Harddisk2\Partition0     (SymbolicLink) -> \Device\Harddisk2\DR5
    \Device\Harddisk2\Partition1     (SymbolicLink) -> \Device\HarddiskVolume12

    but of course on this usb key there are 2 partitions, so why it doesnt' appear here ?

    I tried to answer this question myself by saying that it's because the second partition is formated in hfs+ (Apple fs) and since
    it's not recognized by windows it doesn't appear.

    BUUUT if I look at l\Device\Harddisk1 that is a  ssd gpt partitioned with 7 partitions and one is hfs+ it appears so I don't understand...

    Could you please explain it to me ?

    So to sum up I would like to be able to allow access through posix functions open read write to partitions and I need some opinion about it.

    Thanks


    Thursday, May 5, 2016 8:24 PM

Answers

  • Yes as a security measure you cannot access a storage device that has mounted partitions.  Also, Windows only allows a single partition on a USB key. 


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Thursday, May 5, 2016 8:35 PM

All replies

  • Yes as a security measure you cannot access a storage device that has mounted partitions.  Also, Windows only allows a single partition on a USB key. 


    Don Burn Windows Driver Consulting Website: http://www.windrvr.com

    Thursday, May 5, 2016 8:35 PM
  • Not sure to understand your answer because I am talking about partitions with filesystem not supported by windows (ext4, hf+, ...)
    so is there any mounted volumes for them ?
    For instance if I look at FSCTL_DISMOUNT_VOLUME msdn I can read:

    To retrieve a volume handle, call CreateFile with the lpFileName parameter set to a string of the following form:
    \\.\X:
    where X is a hard-drive partition letter, floppy disk drive, or CD-ROM drive

    but in my case there is no harddrive partition letter.

    Update:

    I have continued my explorations and I have tried to use NtCreateFile to open partitions:

    HANDLE hFile;
    BOOL bRet;
    char buffer[64];
    
    hFile = KCreateFileW(
    	L"\\Device\\Harddisk1\\Partition6",
    	GENERIC_READ,
    	FILE_SHARE_READ | FILE_SHARE_WRITE,
    	NULL,
    	OPEN_EXISTING,
    	0/*FILE_ATTRIBUTE_NORMAL*/,
    	NULL);
    
    if (hFile != INVALID_HANDLE_VALUE)
    {
    	bRet = KReadFile(hFile, buffer, 64, NULL, NULL);
    }
    
    if (hFile != NULL) CloseHandle(hFile);

    KCreateFileW and KReadFile are my versions of CreateFileW and ReadFile that calls NtCreateFile and NtReadFile internally
    and from what I can see I can open Partition6(hfs+) but as soon as I try to call NtReadFile I get a LastError of 1005
    that is ERROR_UNRECOGNIZED_VOLUME. So for me it's not possible to access raw partitions from user-mode and even from kernel mode
    I suppose I will have to use the undocumented features described in the article of CodeProject.
    I wish I could avoid to developp a driver...


    Friday, May 6, 2016 11:00 AM