1 // DBTUtils.inc - small version DBT.pas, only DEVICE CHANGE & Utils.
\r
2 // Used units: ShellApi, MMSystem;
\r
5 WM_DEVICECHANGE = $0219;
\r
8 _DEV_BROADCAST_HDR = record // Device broadcast header
\r
10 dbch_devicetype: DWORD;
\r
11 dbch_reserved: DWORD;
\r
13 DEV_BROADCAST_HDR = _DEV_BROADCAST_HDR;
\r
14 PDEV_BROADCAST_HDR = ^DEV_BROADCAST_HDR;
\r
16 // The following messages are for WM_DEVICECHANGE. The immediate list
\r
17 // is for the wParam. ALL THESE MESSAGES PASS A POINTER TO A STRUCT
\r
18 // STARTING WITH A DWORD SIZE AND HAVING NO POINTER IN THE STRUCT.
\r
21 DBT_DEVICEARRIVAL = $8000; // system detected a new device
\r
22 DBT_DEVICEREMOVECOMPLETE = $8004; // device is gone
\r
24 DBT_DEVTYP_VOLUME = $00000002; // logical volume
\r
26 DBTF_MEDIA = $0001; // media comings and goings
\r
27 DBTF_NET = $0002; // network volume
\r
30 _DEV_BROADCAST_VOLUME = record
\r
32 dbcv_devicetype: DWORD;
\r
33 dbcv_reserved: DWORD;
\r
34 dbcv_unitmask: DWORD;
\r
37 DEV_BROADCAST_VOLUME = _DEV_BROADCAST_VOLUME;
\r
38 PDEV_BROADCAST_VOLUME = ^DEV_BROADCAST_VOLUME;
\r
40 (* Finds the first valid drive letter from a mask of drive letters *)
\r
42 function FirstDriveFromMask(unitmask: Longint): Char;
\r
44 DriveLetter: Shortint;
\r
46 DriveLetter := Byte('a');
\r
47 while (unitmask and 1) = 0 do
\r
49 unitmask := unitmask shr 1;
\r
52 Result := Char(DriveLetter);
\r
55 (* Ãîòîâíîñòü äðàéâà *)
\r
57 function DriveReady(const Drv: Char): Boolean;
\r
61 Result := GetVolumeInformation(PChar(Drv + ':\'), nil, 0, nil,
\r
62 NotUsed, NotUsed, nil, 0);
\r
67 function GetLabelDisk(const Drv: Char; const VolReal: Boolean): string;
\r
69 function DisplayName(const Drv: Char): string;
\r
73 FillChar(SFI, SizeOf(SFI), 0);
\r
74 SHGetFileInfo(PChar(Drv + ':\'), 0, SFI, SizeOf(SFI), SHGFI_DISPLAYNAME);
\r
75 Result := SFI.szDisplayName;
\r
77 // Â Win9x, Me - íåò ìåòêè äèñêà -> #32 + (x:)
\r
78 // Â WinNT 5.x - íåò ìåòêè äèñêà -> Íàçâàíèå óñòðîéñòâà + #32 + (x:)
\r
79 if Pos('(', Result) <> 0 then
\r
80 SetLength(Result, Pos('(', Result) - 2);
\r
85 DriveType, NotUsed: DWORD;
\r
86 Buf: array [0..MAX_PATH - 1] of Char;
\r
89 WinVer := LOBYTE(LOWORD(GetVersion));
\r
90 DriveType := GetDriveType(PChar(Drv + ':\'));
\r
92 if (WinVer <= 4) and (DriveType <> DRIVE_REMOVABLE) or VolReal then
\r
93 begin // Win9x, Me, NT <= 4.0
\r
95 GetVolumeInformation(PChar(Drv + ':\'), Buf, DWORD(SizeOf(Buf)), nil,
\r
96 NotUsed, NotUsed, nil, 0);
\r
99 if VolReal and (WinVer >= 5) and (Result <> '') and
\r
100 (DriveType <> DRIVE_REMOVABLE) then // Win2k, XP è âûøå
\r
101 Result := DisplayName(Drv)
\r
102 else if (Result = '') and (not VolReal) then
\r
103 Result := '<none>';
\r
105 Result := DisplayName(Drv);
\r
108 (* Îæèäàíèå èçìåíåíèÿ ìåòêè äèñêà *)
\r
110 procedure WaitLabelChange(const Drv: Char; const Str: string);
\r
114 if GetLabelDisk(Drv, True) = '' then
\r
116 st1 := TrimLeft(Str);
\r
119 st2 := GetLabelDisk(Drv, FALSE);
\r
122 (* Çàêðûòü øòîðêó CD/DVD *)
\r
124 procedure CloseCD(const Drive: string);
\r
126 OpenParms: MCI_OPEN_PARMS;
\r
128 FillChar(OpenParms, SizeOf(OpenParms), 0);
\r
129 OpenParms.lpstrDeviceType := 'CDAudio';
\r
130 OpenParms.lpstrElementName := PChar(Drive + ':');
\r
131 mciSendCommand(0, MCI_OPEN, MCI_OPEN_TYPE or MCI_OPEN_ELEMENT, Longint(@OpenParms));
\r
132 mciSendCommand(OpenParms.wDeviceID, MCI_SET, MCI_SET_DOOR_CLOSED, 0);
\r
133 mciSendCommand(OpenParms.wDeviceID, MCI_CLOSE, MCI_OPEN_TYPE or MCI_OPEN_ELEMENT, Longint(@OpenParms));
\r
136 (* Èêîíêà äðàéâà *)
\r
138 function DriveIconSysIdx(const Path: string): Integer;
\r
143 SHGetFileInfo(PChar(Path), 0, SFI, SizeOf(SFI), SHGFI_SYSICONINDEX);
\r
144 Result := SFI.iIcon;
\r