본문 바로가기
놀기/Qt

USB 저장 장치 제거하기 (How to eject an external drive or USB stick)

by Hi~ 2023. 9. 5.

USB 저장 장치에 파일을 복사하는 프로그램을 만드는데 이왕이면 꺼내기까지 기능까지 같이 넣으면 좋겠다는 생각이 들었다. 일반적인 프로그램에서 되니 OS에서 지원하는 API가 있다는 것이니 검색을 해보았다.

 

https://www.codeproject.com/Articles/13839/How-to-Prepare-a-USB-Drive-for-Safe-Removal

 

How to Prepare a USB Drive for Safe Removal

Shows the link between a drive letter, its disk number, and the disk's device instance

www.codeproject.com

 

구글에서 찾으면 많은 질문과 답변이 있는데 정리된 자료를 찾을 수 있었다. CM_Request_Device_Eject() API를 사용하는 방식이다. 그런데, 동작이 안된다. microSD에 파일을 쓰고 꺼내기를 하려고 하는데 안된다. 뭐가 잘못된 것인지 몰라 포기했었다. 그러다가 다시 코드를 보게 되었다. 이상하게 동작되었다. 알고 보니 USB 저장장치와 microSD의 차이가 있었다. 윈도우즈나 리눅스에서 그냥 같은 "꺼내기" 기능을 사용해서 차이가 없다고 생각했는데, 생각해 보니 당연히 다른 것이다. 어쨌든, 위 게시물은 USB 저장 장치를 꺼낼 때 동작하는 프로그램이었다. 

 

나는 USB 저장 장치와 microSD 둘 다 꺼내고 싶기에 다시 찾아 봤다. 그러다 같은 분이 작성한 게시물을 code project에서 찾았다. DeviceIoControl() API를 사용하여 다음 방식으로 처리한다.

 

FSCTL_LOCK_VOLUME
FSCTL_DISMOUNT_VOLUME
IOCTL_STORAGE_EJECT_MEDIA
FSCTL_UNLOCK_VOLUME

 

https://www.codeproject.com/Articles/259577/How-to-flush-a-storage-volumes-the-file-cache-lock

 

How to flush a storage volume's file cache, lock and dismount it, and eject the media

Demonstrates how to open a storage volume and do some interesting things with it.

www.codeproject.com

 

이 프로그램은 다른 방식으로 "꺼내기"를 수행하는데 USB 저장 장치와 microSD 모두 가능했다. 이것을 쓰면 되겠다고 했는데 또 약간의 장벽이 있었다.

 

원하는 프로그램은 아래와 같이 생겼다. 간단하게 생기긴 했는데 저장장치를 연결하면 인식하고 "eject"를 누르면 목록에서 삭제되는 방식이다. 드라이브 인식은 "Win32 Disk Imager"의 코드를 가져다 썼다. 첫 번째 방식으로 하면 WM_DEVICECHANGE 메시지로 디바이스 추가/삭제 메시지가 뿌려져 확인할 수 있었는데, 두 번째 방식은 이 메시지가 안 온다. 그래서 어쩔 수 없이 인식은 이 메시지를 사용하고 제거했을 때의 처리는 WM_USER 메시지를 하나 만들어서 해결했다. QT로 만들었지만 윈도우즈 메시지를 받을 수 있고 보낼 수 있는 것이 간단해서 무리가 없었다. QT에서 WM_USER 사용방법은 마지막 부분에 추가했다. 그나저나 검색으로 소스코드를 가져다 쓰고 내가 한 것은 하나도 없다. 뭐 요즘 세상 그런 거 아니겠는가. 

 

 

동작은 아래와 같이 된다. 

 

https://youtu.be/oaHca9G5b4U

 

소스코드

 

bmEjectUSBStorage-master.zip
0.01MB

 

 

2023.09.09 - [놀기/Qt] - QT에서 SendMessage() 사용하기

 

QT에서 SendMessage() 사용하기

MFC를 사용하던 시절 SendMessage()를 자주 사용했다. 운영체제에서 보내주는 메시지를 받을 수 있고 다른 프로그램의 핸들을 얻어 메시지를 전달할 수도 있었다. MFC는 Windows를 만든 M$에서 만들었기

busyman.tistory.com

 

댓글