If you are as curious as I am, you have probably wondered whether or not it is possible to determine if a memory stick was plugged in or taken out. To answer your question, yes you can! As the saying goes: Curiosity killed the cat. In this case, if you are not careful, curiosity can cause very serious errors, even some bad, unpredictable results. So, if you are careful and do things right, everything will work smoothly, so make sure to follow every step carefully, and double check your progress against mine.
I will cover how to determine whether or not a disk is plugged in or taken out in this article—that is the main topic, but another “thing” I’ve been wondering about was: How can you make the disk Autorun, similar to CD drives, and, how can you run a normal VB 6 program from this disk, without the need of installing it on the client machine? Sound interesting? Well, it’s time to get started.
What Is Needed?
The obvious answer would be: A Lot Of APIs. Now, for the inexperienced VB 6 developer, the Win 32 Application Programming Interface would seem too advanced or too complicated to go into. To put you a bit more at ease, I won’t be shy in mentioning the fact that many a experienced VB 6 developer finds the API just as scary as you! You may think that if experienced developers find APIs scary, they must indeed be extremely difficult. No; with time you will realise that the Win 32 API is extremely huge—there are literally millions of pages written on the various APIs found—and still some of the APIs remain a mystery. In case you haven’t run away in fear for the APIs, you could have a look at these resources about the API.
- Application Programming Interface
- AllAPI.net (Mentalis.org)
- Discovering the API Using Visual Basic 6 and Visual Basic .NET
The Needed APIs
In the sample program, you will be using the following APIs:
API Name | API Description/Use |
---|---|
SetWindowLong | The SetWindowLong function changes an attribute of the specified window. The function also sets the 32-bit (long) value at the specified offset into the extra window memory. |
CallWindowProc | The CallWindowProc function passes message information to the specified window procedure |
GetDriveType | The GetDriveType function determines whether a disk drive is a removable, fixed, CD-ROM, RAM disk, or network drive |
RtlMoveMemory | The RtlMoveMemory routine moves memory either forward or backward, aligned or unaligned, in 4-byte blocks, followed by any remaining bytes |
GetDWord | The GetDWORD method retrieves a DWORD property |
GetWord | GetWORD method retrieves a WORD property |
DeviceIoControl | The DeviceIoControl function sends a control code directly to a specified device driver, causing the corresponding device to perform the corresponding operation. |
CreateFile | The CreateFile function creates or opens the following objects and returns a handle that can be used to access the object: → files → pipes → mailslots → communications resources → disk devices (Windows NT only) → consoles → directories (open only) |
CloseHandle | The CloseHandle function closes an open object handle. |
RegisterDeviceNotification | The RegisterDeviceNotification function registers the device or type of device for which a window will receive notifications |
UnregisterDeviceNotification | The UnregisterDeviceNotification function closes the specified device notification handle |
The Needed API Types
To make all these APIs work properly, you need a couple of API Types, and several API Constants. In the sample program, you will be working with the following API Types:
API Type Name | API Type Description/Usage |
---|---|
DEV_BROADCAST_HDR | The DEV_BROADCAST_HDR structure is a standard header for information related to a device event reported through the WM_DEVICECHANGE message |
DEV_BROADCAST_DEVICEINTERFACE | The DEV_BROADCAST_DEVICEINTERFACE structure contains information about a class of devices |
The Needed API Constants
You will need the following Constants in your sample program:
API Constant Name | API Constant Description/Use |
---|---|
GWL_WNDPROC | Use the GWL_WNDPROC constant to tell the SetWindowLong function that you want to change the address of the target window’s WindowProc function |
WM_DEVICECHANGE | The WM_DEVICECHANGE device message notifies an application of a change to the hardware configuration of a device or the computer |
DBT_DEVICEARRIVAL | The system broadcasts the DBT_DEVICEARRIVAL device event when a device or piece of media has been inserted and becomes available |
DBT_DEVICEREMOVECOMPLETE | The system broadcasts the DBT_DEVICEREMOVECOMPLETE device event when a device or piece of media has been physically removed |
DBT_DEVTYP_VOLUME | The application must check the event to ensure that the type of device arriving is a volume. Logical volume |
DBT_DEVTYP_DEVICEINTERFACE | Device interface class |
IOCTL_STORAGE_EJECT_MEDIA | Causes media to be ejected from a SCSI device |
GENERIC_READ | Read Access |
FILE_SHARE_READ | Subsequent open operations on the object will succeed only if read access is requested |
FILE_SHARE_WRITE | Subsequent open operations on the object will succeed only if write access is requested |
OPEN_EXISTING | Opens the file |
INVALID_HANDLE_VALUE | If the function fails, the return value is INVALID_HANDLE_VALUE |
DEVICE_NOTIFY_WINDOW_HANDLE | Handle to the window or service that will receive device events for the devices specified in the NotificationFilter parameter |
DBT_DEVTYP_DEVICEINTERFACE | Device interface class |
DEVICE_NOTIFY_ALL_INTERFACE_CLASSES | Notifies the recipient of device interface events for all device interface classes |