dbch_devicetypeが、DBT_DEVTYP_HANDLEの時、DEV_BROADCAST_HDRポインタをDEV_BROADCAST_HANDLEポインタにキャストできる。
DEV_BROADCAST_HANDLE (dbt.h) - Win32 apps | Microsoft Learn
デバイスを削除する要求の処理 - Win32 apps | Microsoft Learn
これは、USBデバイスを取り出す要求が来た時に、処理をしなければならない場合などに使う。
DEV_BROADCAST_HANDLE.cppで、
デバイス通知登録をする位置を変更。DBT_DEVICEARRIVALのDBT_DEVTYP_VOLUMEで、pDBV->dbcv_unitmaskから、ドライブレターを取得。CreateFileで、そのドライブのルートディレクトリを開く。
(ディレクトリを開くには、CreateFileの第6引数にFILE_FLAG_BACKUP_SEMANTICSを指定)
DEV_BROADCAST_HANDLE のdbch_handleに、ディレクトリハンドルをセットし、RegisterDeviceNotificationでDEV_BROADCAST_HANDLEを登録。
これで、今まで呼ばれなかった新たなDBT_XXX系のイベントが来る。
ただし、ハンドルを開きっぱなしは良くないし、このままだと取り出し操作した時に使用中のエラーが発生する。
今回は、デバイス通知登録直後にCloseHandleでディレクトリハンドルを閉じている。これで取り出しに成功する。
DBT_DEVICEREMOVECOMPLETEには、DBT_DEVTYP_VOLUMEの場合と、DBT_DEVTYP_HANDLEの場合と、両方が来る。
どちらが先に来てもいいように、先に来た時に通知登録を解除し、そこで通知ハンドルをNULLにしておく。後から来たらNULLなので何もしない。
挿した時に、
![Dドライブのルートディレクトリのハンドルをセットしてデバイス通知登録](https://cdn-ak.f.st-hatena.com/images/fotolife/B/BG1/20230601/20230601115329.png)
Dドライブのルートディレクトリのハンドルをセットしてデバイス通知登録。
取り出し操作で、
![取り出し成功](https://cdn-ak.f.st-hatena.com/images/fotolife/B/BG1/20230601/20230601115510.png)
取り出し成功。
そして、DBT_DEVTYP_HANDLEに来てる。
ここで通知解除。
さらに、"Other"というのが出ているが、これが新たなDBT_XXX系のイベント。
本来、CloseHandleは、この新たなDBT_XXX系イベントで行うものである。