Файл ISO не открывается при использовании службы виртуального диска Windows, код ошибки 50: ERROR_NOT_SUPPORTED

Я пытаюсь загрузить файл ISO в свою программу и смонтировать его с помощью службы виртуального диска Windows 8.1. Перед загрузкой ISO я загружаю файл VHD, в котором находится игра. затем я хочу смонтировать ISO, чтобы игра работала (ISO находится на VHD, но проблема также возникает, когда ISO находится в каталоге программы).

Теперь я не знаю, почему операция «НЕ ПОДДЕРЖИВАЕТСЯ» (код ошибки 50), но я знаю, что окна могут монтировать ISO, потому что, когда я дважды щелкаю по ним, они монтируются проводником Windows (и он, очевидно, использует Служба виртуальных дисков, поскольку в КБ виртуальной службы указано, что подключение ISO поддерживается в Windows 7 и более поздних версиях).

Теперь, как я пытаюсь загрузить файл iso, это:

GUID GUID_TEST = { 12345678 - 1234 - 5678 - 1234 - 000000000000 };

//convert string to wstring
std::wstring s2ws(const std::string& str)
{
    typedef std::codecvt_utf8<wchar_t> convert_typeX;
    std::wstring_convert<convert_typeX, wchar_t> converterX;

    return converterX.from_bytes(str);
}

DWORD OpenISO(const char* isoFilePath, HANDLE *handle)
{
    VIRTUAL_STORAGE_TYPE storageType =
    {
        VIRTUAL_STORAGE_TYPE_DEVICE_ISO,
        GUID_TEST
    };

    OPEN_VIRTUAL_DISK_PARAMETERS parameters =
    {
        OPEN_VIRTUAL_DISK_VERSION_1
    };

    return ::OpenVirtualDisk(
        &storageType,
        s2ws(std::string(isoFilePath)).c_str(),
        VIRTUAL_DISK_ACCESS_READ,
        OPEN_VIRTUAL_DISK_FLAG_NONE,
        &parameters,
        handle);
}

void main()
{
    //load VHD here, do some program setup, etc etc
    //then load iso:

    //makesure VHD is mounted and ready
    UINT dtype = GetDriveTypeA(Config.MountPoint.c_str());
    while (dtype == 1 || dtype == 0)
    {
        dtype = GetDriveTypeA(Config.MountPoint.c_str());
        Sleep(10);
    }
    std::cout << "OK" << std::endl;
    //just a bit more waiting to be sure it is really loaded correctly
    Sleep(2500);
    //now load the iso our game needs to run
    HANDLE  isohandle;
    if (FileExists(Config.ISO_location.c_str()))
    {
        std::cout << "Mounting ISO... " << std::flush;
        if (OpenISO(Config.ISO_location.c_str(), &isohandle) == ERROR_SUCCESS)
        {
            if (AttachVirtualDisk(isohandle, NULL, ATTACH_VIRTUAL_DISK_FLAG_READ_ONLY, 0, 0, NULL) == ERROR_SUCCESS)
            {
                std::cout << "ISO mounted.\r\n";
            }
            else
            {
                std::cout << "ISO NOT mounted (" << GetLastError() << ").\r\n";
            }
        }
        else
        {
            std::cout << "Cannot open ISO file, skipping (" << GetLastError() << ").\r\n";
        }
    }
    //launch the game process here
    //wait til game ends
    //cleanup
    //shutdown
}

Я всегда получаю сообщение «ISO НЕ установлен» (50). При замене GUID_TEST на guid по умолчанию microsoft я получаю ISO NOT примонтирован (0), код ошибки 0 должен указывать на успех, но почему-то ISO не отображается в управлении дисками. Что здесь не так? Почему мой ISO не может быть смонтирован программно, в то время как проводник может?

Признаюсь, я точно не знаю, как смонтировать ISO, но я монтирую VHD следующим образом:

DWORD OpenVDisk(const char* virtualDiskFilePath, HANDLE *handle)
{
    VIRTUAL_STORAGE_TYPE storageType =
    {
        VIRTUAL_STORAGE_TYPE_DEVICE_VHD,
        VIRTUAL_STORAGE_TYPE_VENDOR_MICROSOFT
    };

    OPEN_VIRTUAL_DISK_PARAMETERS parameters =
    {
        OPEN_VIRTUAL_DISK_VERSION_1
    };

    parameters.Version1.RWDepth = 1024;

    return ::OpenVirtualDisk(
        &storageType,
        s2ws(std::string(virtualDiskFilePath)).c_str(),
        VIRTUAL_DISK_ACCESS_ALL,
        OPEN_VIRTUAL_DISK_FLAG_NONE,
        &parameters,
        handle);
}

    //somewhere else
HANDLE  handle;
DWORD   result;
ULONG   bytesUsed;

result = OpenVDisk(Config.VHD_location.c_str(), &handle);
if (result != ERROR_SUCCESS)
{
    std::cout << "Unable to open virtual disk '" << Config.VHD_location << "'" << std::endl;
    return (int)pressanykey("Hit any key to quit the application\r\n");
}
std::cout << "OK" << std::endl;
std::cout << "Attaching Game Disk..." << std::flush;
result = AttachVirtualDisk(handle, NULL, ATTACH_VIRTUAL_DISK_FLAG_NO_DRIVE_LETTER, 0, 0, NULL);
if (result != ERROR_SUCCESS)
{
    std::cout << "Unable to attach virtual disk (did you forget to run this program with administrative rights? -- " << GetLastError() << ")" << std::endl;
    return (int)pressanykey("Hit any key to quit the application\r\n");
}
std::cout << "OK" << std::endl;

и монтаж VHD. Это заставляет меня задуматься, почему этого нет в ISO.


person Gizmo    schedule 15.05.2014    source источник
comment
Вы должны вызвать GetLastError () сразу после неудачного вызова функции, иначе он может быть аннулирован промежуточными вызовами (например, реализацией cout).   -  person Luke    schedule 16.05.2014
comment
та же ошибка, указанная до и после std :: cout   -  person Gizmo    schedule 16.05.2014


Ответы (1)


Решение состоит в том, чтобы убедиться, что установлен флаг ATTACH_VIRTUAL_DISK_FLAG_PERMANENT_LIFETIME, а затем также убедиться, что размер файла ISO кратен 2048 байтам. Теперь это работает.

person Gizmo    schedule 15.05.2014
comment
Вы когда-нибудь пробовали прикреплять файлы ISO в Windows 7? Похоже, что это невозможно, так как это должно быть доступно только в Windows 8 и более поздних версиях. - person bkausbk; 26.10.2015