首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >我试图使用DeviceIoControl IOCTL_STORAGE_EJECT_MEDIA弹出我的CD光盘驱动器,但是获得了错误访问冲突写入位置。

我试图使用DeviceIoControl IOCTL_STORAGE_EJECT_MEDIA弹出我的CD光盘驱动器,但是获得了错误访问冲突写入位置。
EN

Stack Overflow用户
提问于 2021-01-14 04:53:27
回答 1查看 155关注 0票数 0

我试图弹出我的光盘驱动器点击一个按钮。当按下按钮时,CD Rom驱动器以前是正确弹出的,但现在它给了我一个错误:"0xC0000005:访问冲突写入位置0x00000000“。我不知道为什么我会犯这个错误。我的代码如下所示,其中我的光盘驱动器是D-驱动器:

代码语言:javascript
复制
#include <windows.h>
#include <tchar.h>
#include <stdio.h>

#define BUTTON                  3456
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
DWORD dwBytes;
HANDLE hCdRom;

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
    {
        HWND hwndButton = CreateWindow(
            L"BUTTON",  // Predefined class; Unicode assumed 
            L"EJECT",   // Button text 
            WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
            180,         // x position 
            200,        // y position 
            100,        // Button width
            100,        // Button height
            hWnd,     // Parent window
            (HMENU)BUTTON,       // No menu.
            (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
            NULL);      // Pointer not needed.
    }
    
    case WM_COMMAND:
    {
        switch (LOWORD(wParam))
        {
        case BUTTON:
            hCdRom = CreateFile(L"\\\\.\\D:",
                GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

            if (hCdRom == INVALID_HANDLE_VALUE)
            {
                wsprintf(NULL, L"Error: %d", GetLastError());    //Getting error: Exception thrown at 0x746FFA6F (user32.dll) in Project.exe: 0xC0000005: Access violation writing location 0x00000000.
                return 1;
            }

            DeviceIoControl(hCdRom, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwBytes, NULL);

            if (hCdRom == 0)
            {
                wsprintfW(NULL, L"Error: %d", GetLastError());
                return 1;
            }
            MessageBox(NULL, L"Please insert a CD ROM in the CD tray.", L"CD ROM Drive", 0);

            CloseHandle(hCdRom);
    
            break;
        }
    }
}

有没有人遇到这个错误,并知道如何修复它?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-14 05:37:41

因为MessageBox一直处于阻塞状态,所以不调用CloseHandle。当您第二次按下按钮时,CreateFile将再次打开CD驱动器句柄,之前的句柄尚未关闭,访问被拒绝。

您可以简单地删除这一行:

MessageBox(NULL, L"Please insert a CD ROM in the CD tray.", L"CD ROM Drive", 0);

但是正确的方法是添加DefWindowProcA函数,以确保所有消息都被处理。

调用默认窗口过程,为应用程序不处理的任何窗口消息提供默认处理。此函数确保处理每条消息。使用窗口过程接收的相同参数调用DefWindowProc。

像这样修改,

代码语言:javascript
复制
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_CREATE:
    {
        HWND hwndButton = CreateWindow(
            L"BUTTON",  // Predefined class; Unicode assumed 
            L"EJECT",   // Button text 
            WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,  // Styles 
            180,         // x position 
            200,        // y position 
            100,        // Button width
            100,        // Button height
            hWnd,     // Parent window
            (HMENU)BUTTON,       // No menu.
            (HINSTANCE)GetWindowLongPtr(hWnd, GWLP_HINSTANCE),
            NULL);      // Pointer not needed.
    }

    case WM_COMMAND:
    {
        switch (LOWORD(wParam))
        {
        case BUTTON:
            hCdRom = CreateFile(L"\\\\.\\D:",
                GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);

            if (hCdRom == INVALID_HANDLE_VALUE)
            {
                wsprintf(NULL, L"Error: %d", GetLastError());    //Getting error: Exception thrown at 0x746FFA6F (user32.dll) in Project.exe: 0xC0000005: Access violation writing location 0x00000000.
                return 1;
            }

            DeviceIoControl(hCdRom, IOCTL_STORAGE_EJECT_MEDIA, NULL, 0, NULL, 0, &dwBytes, NULL);

            if (hCdRom == 0)
            {
                wsprintfW(NULL, L"Error: %d", GetLastError());
                return 1;
            }
            MessageBox(NULL, L"Please insert a CD ROM in the CD tray.", L"CD ROM Drive", 0);

            CloseHandle(hCdRom);

            break;
        }
    }
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}

更新:

代码语言:javascript
复制
#include <tchar.h>
#include <windows.h>
#include <mmsystem.h> // for MCI functions

// Link to winmm.lib (usually included in project settings)
#pragma comment(lib, "winmm")

void ControlCdTray(TCHAR drive, DWORD command)
{
    // Not used here, only for debug
    MCIERROR mciError = 0;

    // Flags for MCI command
    DWORD mciFlags = MCI_WAIT | MCI_OPEN_SHAREABLE | 
        MCI_OPEN_TYPE | MCI_OPEN_TYPE_ID | MCI_OPEN_ELEMENT;

    // Open drive device and get device ID
    TCHAR elementName[] = { drive };
    MCI_OPEN_PARMS mciOpenParms = { 0 };
    mciOpenParms.lpstrDeviceType = (LPCTSTR)MCI_DEVTYPE_CD_AUDIO;
    mciOpenParms.lpstrElementName = elementName;    
    mciError = mciSendCommand(0, 
        MCI_OPEN, mciFlags, (DWORD_PTR)&mciOpenParms);

    // Eject or close tray using device ID
    MCI_SET_PARMS mciSetParms = { 0 };
    mciFlags = MCI_WAIT | command; // command is sent by caller
    mciError = mciSendCommand(mciOpenParms.wDeviceID, 
        MCI_SET, mciFlags, (DWORD_PTR)&mciSetParms);
    
    // Close device ID
    mciFlags = MCI_WAIT;
    MCI_GENERIC_PARMS mciGenericParms = { 0 };
    mciError = mciSendCommand(mciOpenParms.wDeviceID, 
        MCI_CLOSE, mciFlags, (DWORD_PTR)&mciGenericParms);
}

// Eject drive tray
void EjectCdTray(TCHAR drive)
{
    ControlCdTray(drive, MCI_SET_DOOR_OPEN);
}

// Retract drive tray
void CloseCdTray(TCHAR drive)
{
    ControlCdTray(drive, MCI_SET_DOOR_CLOSED);
}

int _tmain(int argc, _TCHAR* argv[])
{
    EjectCdTray(TEXT('D')); // drive letter hardcoded
    //CloseCdTray(TEXT('D'));

    return 0;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65713609

复制
相关文章

相似问题

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