首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >根据GetLastError,直接写入磁盘会导致错误代码5

根据GetLastError,直接写入磁盘会导致错误代码5
EN

Stack Overflow用户
提问于 2018-10-22 09:10:34
回答 1查看 389关注 0票数 1

我正尝试在Windows中直接写入U盘。我使用CreateFile函数创建了一个磁盘句柄,并使用WriteFile函数尝试写入文件。WriteFile函数失败,状态代码为5(根据GetLastError)。我尝试使用FSCTL_DISMOUNT_VOLUME锁定磁盘卷,但该卷被隐藏,因此我无法获取其卷号。

代码:

代码语言:javascript
复制
    u8 Disk::Init()
    {
        char fn[24] = { 0 };
        sprintf(fn, "\\\\.\\PhysicalDrive%d", (int)m_nDiskNum);
        m_hDisk = CreateFileA(fn, GENERIC_WRITE | GENERIC_READ,
            FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
            OPEN_EXISTING,
            FILE_FLAG_WRITE_THROUGH | FILE_FLAG_NO_BUFFERING, 0);

        if (INVALID_HANDLE_VALUE == m_hDisk)
        {
            return (FAIL);
        }

        //m_DiskInfo.Init();
        return Lock();
    }

    u8 Disk::Lock()
    {
        STORAGE_DEVICE_NUMBER d1;
        DWORD nr;
        char dn[8], c;

        if (!DeviceIoControl((HANDLE)m_hDisk, IOCTL_STORAGE_GET_DEVICE_NUMBER,
            NULL, 0, &d1, sizeof(d1), &nr, 0))
        {
            return (FAIL);
        }

        strcpy(dn, "\\\\.\\A:");

        // some volume is hided, so I cannot get its letter
        for (c = 'C'; c < 'Z'; c++)
        {
            HANDLE hd;
            STORAGE_DEVICE_NUMBER d2;

            dn[4] = c;
            hd = CreateFileA(dn, GENERIC_READ | GENERIC_WRITE,
                FILE_SHARE_READ | FILE_SHARE_WRITE,
                NULL, OPEN_EXISTING, 0, 0);

            if (hd == INVALID_HANDLE_VALUE)
            {
                continue;
            }

            if ((!DeviceIoControl(hd, IOCTL_STORAGE_GET_DEVICE_NUMBER,
                NULL, 0, &d2, sizeof(d2), &nr, 0)) ||
                (d1.DeviceType != d2.DeviceType) ||
                (d1.DeviceNumber != d2.DeviceNumber))
            {
                CloseHandle(hd);
                continue;
            }

            if (!DeviceIoControl(hd, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0,
                &nr, 0))
            {
                CloseHandle(hd);
                return (FAIL);
            }

            m_LockedVolums.push_back(hd);
        }

        return (SUCC);
    }

    u8 Disk::UnLock()
    {
        for (auto it : m_LockedVolums)
        {
            CloseHandle(it);
        }

        m_LockedVolums.clear();
        return (SUCC);
    }

    u8 Disk::WriteSector(_Out_opt_ u8 * cBuf, int nStartSec, int nSecCont/* = 1*/)
    {
        if (Seek(nStartSec))
        {
            return(FAIL);
        }

        unsigned long nWrited;

        if ((!WriteFile((HANDLE)m_hDisk, cBuf, nSecCont * m_nBytePerSec, &nWrited, NULL))
            || (nSecCont * m_nBytePerSec != (int)nWrited))
        {
            return(FAIL);
        }

        return(SUCC);
    }
EN

Stack Overflow用户

发布于 2018-10-22 21:37:53

FSCTL_DISMOUNT_VOLUME IO控制会卸载文件系统,但我不认为它会锁定文件系统进行写入。之后使用FSCTL_LOCK_VOLUME (或者,如果卷没有Windows可读的文件系统,因此没有挂载)来请求写访问权限。

附注:我认为你需要你的应用程序运行提升才能使用该API。

票数 0
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52921265

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档