I want to get notified when the user inserts a new disk, I'm thinking specially of USB sticks and things like that. I know the FindFirstChangeNotification API, but the MSDN doesn't tell me how I should check for new drives.

The only thing I can think of is polling every n seconds, but I don't think that that'll be the way to go.

Thanks in advance!
Posted on 2004-12-16 10:19:52 by lifewire
Hi
.386

.model flat, stdcall
option casemap :none

include windows.inc
include user32.inc
include kernel32.inc
include gdi32.inc

includelib user32.lib
includelib kernel32.lib
includelib gdi32.lib

DBT_DEVICEARRIVAL = 8000h
DBT_DEVICEREMOVECOMPLETE = 8004h
DBT_DEVTYP_VOLUME = 2

DEV_BROADCAST_HDR struc
dbch_size DWORD ?
dbch_devicetype DWORD ?
dbch_reserved DWORD ?
DEV_BROADCAST_HDR ends

DEV_BROADCAST_VOLUME struc
dbcv_size DWORD ?
dbcv_devicetype DWORD ?
dbcv_reserved DWORD ?
dbcv_unitmask DWORD ?
dbcv_flags WORD ?
WORD ? ; __alignmentDummy
DEV_BROADCAST_VOLUME ends

.const
szClsName db 'p2mDiskArriveRemoveDetectClass',0
szAppName db 'Disk arrive/remove detect',0
szArrived db 'Arrived', 0
szRemoved db 'Removed', 0

.code

;---------------------------------------------------------;
align 4
DriveFromMask proc dwMask:DWORD
mov ecx,dwMask
xor eax,eax
mov al,'A'
.while (al <= 'Z') && (ecx != 0)
.break .if (ecx & 1)
shr ecx,1
inc al
.endw
.if al > 'Z'
xor al,al
.else
mov ah,':'
.endif
ret
DriveFromMask endp

;---------------------------------------------------------;
align 4
wndproc proc uses ebx edi esi, hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
local buf:dword

.if uMsg == WM_DEVICECHANGE
mov eax,lParam
.if eax != 0
mov eax,(DEV_BROADCAST_HDR ptr [eax]).dbch_devicetype
.if (wParam == DBT_DEVICEARRIVAL) && (eax == DBT_DEVTYP_VOLUME)
mov eax,lParam
invoke DriveFromMask, (DEV_BROADCAST_VOLUME ptr [eax]).dbcv_unitmask
.if eax != 0
mov buf,eax
invoke MessageBox, hWnd, addr buf, offset szArrived, MB_OK
.endif
.elseif (wParam == DBT_DEVICEREMOVECOMPLETE) && (eax == DBT_DEVTYP_VOLUME)
mov eax,lParam
invoke DriveFromMask, (DEV_BROADCAST_VOLUME ptr [eax]).dbcv_unitmask
.if eax != 0
mov buf,eax
invoke MessageBox, hWnd, addr buf, offset szRemoved, MB_OK
.endif
.endif
.endif
invoke DefWindowProc, hWnd, uMsg, wParam, lParam

.elseif uMsg == WM_DESTROY
invoke PostQuitMessage, NULL
xor eax,eax

.else
invoke DefWindowProc, hWnd, uMsg, wParam, lParam
.endif

ret
wndproc endp

;---------------------------------------------------------;
align 4
main proc
local wc:WNDCLASS
local msg:MSG

invoke RtlZeroMemory, addr wc, sizeof wc

mov wc.style,CS_HREDRAW or CS_VREDRAW
mov wc.lpfnWndProc,offset wndproc
invoke GetModuleHandle, NULL
mov wc.hInstance,eax
invoke LoadIcon, NULL, IDI_APPLICATION
mov wc.hIcon,eax
invoke LoadCursor, NULL, IDC_ARROW
mov wc.hCursor,eax
mov wc.hbrBackground,COLOR_APPWORKSPACE+1
mov wc.lpszClassName,offset szClsName

invoke RegisterClass, addr wc
.if eax != 0

invoke CreateWindowEx, NULL, addr szClsName, addr szAppName,\
WS_OVERLAPPEDWINDOW,
10, 10, 250, 80,\
NULL, NULL, wc.hInstance, NULL
.if eax != NULL

push eax
push SW_SHOWNORMAL
push eax
call ShowWindow
call UpdateWindow

.while TRUE
invoke GetMessage, addr msg, NULL, 0, 0
.break .if (!eax)
invoke TranslateMessage, addr msg
invoke DispatchMessage, addr msg
.endw
.endif
.endif

ret
main endp

;---------------------------------------------------------;
align 4
start:
invoke main
invoke ExitProcess, 0

end start
For detect USB or not USB need use DeviceIoControl + IOCTL_STORAGE_QUERY_PROPERTY. If need i post code later.
Posted on 2004-12-19 22:45:30 by P2M
great, thanks! i didn't know about the WM_DEVICECHANGE, very interesting!
Posted on 2004-12-20 07:34:26 by lifewire