0

Why I can not write sector at position bigger than 0x1FFF? I am trying to write sector in a SD card. The following code work great for sectors number lower than 0x2000 but fail for any sector bigger than 0x1FFFF returning error code number 5. I don't know why? I don't think this is a duplicate question because I can write sectors in the disk but I can't write sector bigger than 0x1FFF. I am using WinHex and Disk Editor to verify that those sector exist.

#include <windows.h>
#include <stdio.h>

int main()
{
    LPCWSTR device_name = L"\\\\.\\PHYSICALDRIVE2";


    int sector = 0x2000;

    //Open the volume
    HANDLE hDisk = CreateFile(device_name, (GENERIC_READ | GENERIC_WRITE), 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hDisk != INVALID_HANDLE_VALUE) 
    {
        DWORD ol = 0;
        //Lock the volume
        if (DeviceIoControl(hDisk, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &ol, NULL))
        {
            ol = 0;
            //Dismount the volume
            if (DeviceIoControl(hDisk, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &ol, NULL))
            {
                unsigned char buff[512];

                //Set position at desire sector
                int position = sector * 512;
                DWORD readBytes = 0;
                long moveToHigh = 0;
                SetFilePointer(hDisk, position, &moveToHigh, FILE_BEGIN);

                //Read the sector
                if (ReadFile(hDisk, buff, 512, &readBytes, NULL) && readBytes == 512)
                {
                    //Set the write position
                    DWORD writenBytes = 0;
                    moveToHigh = 0;
                    SetFilePointer(hDisk, position, &moveToHigh, FILE_BEGIN);

                    if (WriteFile(hDisk, buff, 512, &writenBytes, NULL) && writenBytes == 512)
                    {
                        printf("OK for Sector %d \r\n", sector);
                    }
                    else
                    {
                        DWORD dwError = GetLastError();
                        printf("Error Code: %d \r\n", dwError);
                    }
                }
            }
        }

        CloseHandle(hDisk);
    }   
}
Deulis
  • 414
  • 4
  • 10
  • 1
    Check `sizeof(long) == sizeof(DWORD)` as `moveToHigh` should be a `DWORD`. Also `SetFilePointerEx` might be simpler to use. – Richard Critten Nov 06 '19 at 19:04
  • @RichardCritten also `SetFilePointer[Ex]` not need at all. need set offset in `ReadFile/WriteFile` call direct – RbMm Nov 06 '19 at 19:29
  • 1
    RbMm is referring to using an `OVERLAPPED` struct to specify the offset when calling `ReadFile()`/`WriteFile()`, then there is no need to use `SetFilePointer/Ex()` – Remy Lebeau Nov 06 '19 at 19:51
  • @Deulis are you sure the sector size on the disk is 512 bytes? How is the disk formatted exactly? – Remy Lebeau Nov 06 '19 at 19:52
  • RbMm and Remy, I have the same result using an OVERLAPPED struct. And yes, the sector size on disk is 512 bytes, I am using WinHex and Disk Editor to double check that. Thanks! – Deulis Nov 06 '19 at 21:20
  • @Deulis - of course result will not change only because you change way how you set offset. i only try to say that api like `SetFilePointerEx` was atavism. about access denied (if it really was access denied - i be call `RtlGetLastNtStatus()` or `NtWriteFile`) - it can be from filesystem, but you dismount volume – RbMm Nov 06 '19 at 22:06

0 Answers0