Make(delphi) Add(MainForm,9667040,154,133) { Left=20 Top=105 Width=378 Height=90 Caption="Eject Removable" } Add(FormatStr,7872013,329,210) { DataCount=1 Mask="Устройство %1: может быть извлечено" link(onFString,15888370:doWork2,[]) } Add(Message,1813617,483,210) { } Add(IndexToChanel,6464938,329,252) { Count=9 link(onEvent5,11962906:doData,[]) link(onEvent9,16744231:doData,[(371,314)(371,335)]) } Add(DoData,11962906,399,280) { Data=String(Устройство не может быть извлечено) link(onEventData,8192225:doWork2,[]) } Add(HubEx,15888370,448,203) { link(onEvent,1813617:doMessage,[]) } Add(InlineCode,13151070,252,210) { WorkPoints=#12:DeviceRemove| EventPoints=#22:onDeviceRemoveComplete|7:onError| DataPoints=#5:Drive| Code=#15:unit HiAsmUnit;|0:|9:interface|0:|29:uses Windows,kol,Share,Debug;|0:|4:type|23: TGUID = System.TGUID;|2: |5:const|81: GUID_DEVINTERFACE_VOLUME: TGUID = '{53f5630d-b6bf-11d0-94f2-00a0c91efb8b}';|81: GUID_DEVINTERFACE_USB_DEVICE: TGUID = '{A5DCBF10-6530-11D2-901F-00C04FB951ED}';|2: |5:const|25: ANYSIZE_ARRAY = 1;|38: CfgMgrDllName = 'cfgmgr32.dll';|38: SetupApiModuleName = 'SETUPAPI.DLL';|0:|5:const|36: DIGCF_PRESENT = $00000002;|36: DIGCF_DEVICEINTERFACE = $00000010;|0:|4:type|22: RETURN_TYPE = DWORD;|26: CONFIGRET = RETURN_TYPE;|21: HDEVINFO = THandle;|22: ULONG_PTR = ^ ULONG;|22: PDEVINST = ^DEVINST;|18: DEVINST = DWORD;|21: DI_FUNCTION = UINT;|26: DEVINSTID_A = PAnsiChar;|34: PPNP_VETO_TYPE = ^PNP_VETO_TYPE;|24: PNP_VETO_TYPE = DWORD;|0:|4:type|35: PSPDevInfoData = ^TSPDevInfoData;|33: SP_DEVINFO_DATA = packed record|18: cbSize: DWORD;|21: ClassGuid: TGUID;|37: DevInst: DWORD; // DEVINST handle|24: Reserved: ULONG_PTR;|6: end;|35: TSPDevInfoData = SP_DEVINFO_DATA;|0:|4:type|64: PSPDeviceInterfaceDetailData = ^TSPDeviceInterfaceDetailData;|52: SP_DEVICE_INTERFACE_DETAIL_DATA_A = packed record|19: cbSize: DWORD;|58: DevicePath: array [0..ANYSIZE_ARRAY - 1] of AnsiChar;|7: end;|68: TSPDeviceInterfaceDetailData = SP_DEVICE_INTERFACE_DETAIL_DATA_A;|0:|4:type|52: PSPDeviceInterfaceData = ^TSPDeviceInterfaceData;|43: SP_DEVICE_INTERFACE_DATA = packed record|19: cbSize: DWORD;|31: InterfaceClassGuid: TGUID;|18: Flags: DWORD;|21: Reserved: DWORD;|7: end;|53: TSPDeviceInterfaceData = SP_DEVICE_INTERFACE_DATA;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|0:|9: public|22: Drive : THI_Event;|38: onDeviceRemoveComplete: THI_Event;|23: onError: THI_Event;|56: procedure DeviceRemove(var _Data:TData; Index:word);|0:|5: end;|0:|14:implementation|0:|80://--------------------------- API - function -----------------------------------|0:|72:function CM_Get_Parent(var dnDevInstParent: DEVINST; dnDevInst: DEVINST;|90: ulFlags: ULONG): CONFIGRET; stdcall; external CfgMgrDllName name 'CM_Get_Parent';|0:|79:function CM_Request_Device_Eject(dnDevInst: DEVINST; pVetoType: PPNP_VETO_TYPE;|90: pszVetoName: PAnsiChar; ulNameLength: ULONG; ulFlags: ULONG): CONFIGRET; stdcall;|69: external SetupApiModuleName name 'CM_Request_Device_EjectA';|0:|68:function CM_Get_Device_ID_Size(var ulLen: ULONG; dnDevInst: DEVINST;|98: ulFlags: ULONG): CONFIGRET; stdcall; external CfgMgrDllName name 'CM_Get_Device_ID_Size';|0:|64:function CM_Get_Device_ID(dnDevInst: DEVINST; Buffer: PAnsiChar;|112: BufferLen: ULONG; ulFlags: ULONG): CONFIGRET; stdcall; external CfgMgrDllName name 'CM_Get_Device_IDA';|0:|75:function SetupDiGetClassDevs(ClassGuid: PGUID; const Enumerator: PAnsiChar;|117: hwndParent: HWND; Flags: DWORD): HDEVINFO; stdcall; external SetupApiModuleName name 'SetupDiGetClassDevsA';|0:|75:function SetupDiEnumDeviceInfo(DeviceInfoSet: HDEVINFO; MemberIndex: DWORD;|118: var DeviceInfoData: TSPDevInfoData): BOOL; stdcall; external SetupApiModuleName name 'SetupDiEnumDeviceInfo';|0:|78:function SetupDiDestroyDeviceInfoList(DeviceInfoSet: HDEVINFO): BOOL; stdcall;|73: external SetupApiModuleName name 'SetupDiDestroyDeviceInfoList';|0:|65:function SetupDiGetDeviceInterfaceDetail(DeviceInfoSet: HDEVINFO;|53: DeviceInterfaceData: PSPDeviceInterfaceData;|65: DeviceInterfaceDetailData: PSPDeviceInterfaceDetailData;|71: DeviceInterfaceDetailDataSize: DWORD; var RequiredSize: DWORD;|121: Device: PSPDevInfoData): LongBool; stdcall; external SetupApiModuleName name 'SetupDiGetDeviceInterfaceDetailA';|0:|61:function SetupDiEnumDeviceInterfaces(DeviceInfoSet: HDEVINFO;|73: DeviceInfoData: PSPDevInfoData; const InterfaceClassGuid: TGUID;|161: MemberIndex: DWORD; var DeviceInterfaceData: TSPDeviceInterfaceData): LongBool; stdcall; external SetupApiModuleName name 'SetupDiEnumDeviceInterfaces';|0:|125:function GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint: LPCSTR; lpszVolumeName: LPSTR; cchBufferLength: DWORD): BOOL;|83: stdcall; external 'Kernel32.dll' name 'GetVolumeNameForVolumeMountPointA';|0:|80://------------------------------------------------------------------------------|0:|49:function _IsUSBDevice(DevInst: DEVINST): boolean;|19:var IDLen: DWORD;|16: ID: PChar;|5:begin|18: Result:= false;|79: if (CM_Get_Device_ID_Size(IDLen, DevInst, 0) <> 0) or (IDLen = 0) then exit;|14: inc(IDLen);|25: ID:= GetMemory(IDLen);|27: if (ID = nil) then exit;|43: CM_Get_Device_ID(DevInst, ID, IDLen, 0);|108: if (CM_Get_Device_ID(DevInst, ID, IDLen, 0) <> 0) or (not CompareMem(ID, PChar('USBSTOR'), 7)) then begin|21: FreeMemory(ID);|11: exit;|7: end;|18: FreeMemory(ID);|17: Result:= true;|4:end;|0:|40:function RemoveDrive(Letter:Char): Byte;|32:var DrivesPnPHandle: HDEVINFO;|31: DevInfo: SP_DEVINFO_DATA;|50: DeviceInterfaceData: TSPDeviceInterfaceData;|66: FunctionClassDeviceData: PSPDeviceInterfaceDetailData; |21: inst : DEVINST;|43: VetoName: array[0..MAX_PATH] of char;|20: Devn: Integer;|27: BytesReturned: DWORD;|24: Success: LongBool;|39: VolumePath, nVolumePath: string; |0:|72: function GetVolumeNameForVolumeMountPointString(Name: string): string;|44: var Volume: array [0..MAX_PATH] of Char;|7: begin|44: FillChar(Volume[0], SizeOf(Volume), 0);|79: GetVolumeNameForVolumeMountPoint(PChar(Name), @Volume[0], SizeOf(Volume));|22: Result := Volume;|6: end;|2: |5:begin|15: Result := 2;|72: VolumePath := GetVolumeNameForVolumeMountPointString(Letter + ':\'); |0:|37: DevInfo.cbSize := sizeof(DevInfo);|117: DrivesPnPHandle := SetupDiGetClassDevs(@GUID_DEVINTERFACE_VOLUME, nil, 0, DIGCF_PRESENT or DIGCF_DEVICEINTERFACE);|55: if DrivesPnPHandle = INVALID_HANDLE_VALUE then exit;|0:|12: Devn:= 0;|0:|73: while (SetupDiEnumDeviceInfo(DrivesPnPHandle, Devn, DevInfo)) do begin|67: DeviceInterfaceData.cbSize := SizeOf(DeviceInterfaceData);|125: Success := SetupDiEnumDeviceInterfaces(DrivesPnPHandle, @DevInfo, GUID_DEVINTERFACE_VOLUME, 0, DeviceInterfaceData);|30: if Success then begin|32: BytesReturned := 0;|116: SetupDiGetDeviceInterfaceDetail(DrivesPnPHandle, @DeviceInterfaceData, nil, 0, BytesReturned, @DevInfo);|93: if (BytesReturned <> 0) and (GetLastError = ERROR_INSUFFICIENT_BUFFER) then begin|66: FunctionClassDeviceData := AllocMem(BytesReturned);|18: TRY|54: FunctionClassDeviceData.cbSize := 5;|167: if SetupDiGetDeviceInterfaceDetail(DrivesPnPHandle, @DeviceInterfaceData, FunctionClassDeviceData, BytesReturned, BytesReturned, @DevInfo) then begin|125: nVolumePath := GetVolumeNameForVolumeMountPointString(PChar(@FunctionClassDeviceData.DevicePath) + '\');|60: if VolumePath = nVolumePath then begin|48: Inst := DevInfo.DevInst;|53: CM_Get_Parent(Inst, Inst, 0);|56: if _IsUSBDevice(Inst) then begin|56: CM_Get_Parent(Inst, Inst, 0);|68: FillChar(VetoName, Length(VetoName), #0);|86: CM_Request_Device_Eject(Inst, nil, @VetoName, MAX_PATH, 0);|48: if VetoName = '' then|41: Result := 0|31: else|42: Result := 4;|32: end else|72: Result := 8; |70: SetupDiDestroyDeviceInfoList(DrivesPnPHandle);|29: exit;|29: end; |22: end;|22: FINALLY|51: FreeMem(FunctionClassDeviceData);|23: END; |16: end;|13: end;|16: inc(Devn);|7: end;|49: SetupDiDestroyDeviceInfoList(DrivesPnPHandle);|4:end;|0:|35:procedure THiAsmClass.DeviceRemove;|16:var err: Byte;|26: DriveLetter: String;|5:begin|39: DriveLetter := ToStringEvent(Drive);|83: if (Length(DriveLetter)>0) and (DriveLetter[1] in ['A'..'z']) then // Синтаксис |76:// if GetDriveType(PChar(DriveLetter[1]+ ':\')) <> DRIVE_REMOVABLE then|19:// err := 8|12:// else|40: err := RemoveDrive(DriveLetter[1])|15: else err:=1;|0:|16: if err=0 then|57: _hi_OnEvent(onDeviceRemoveComplete, DriveLetter[1])|7: else|36: _hi_OnEvent(onError, err); |4:end;|0:|4:end.| link(onDeviceRemoveComplete,7872013:doString,[]) link(onError,6464938:doEvent,[(306,223)(306,258)]) link(Drive,13235457:Var2,[]) } Add(DoData,16744231,399,329) { Data=String(Это не съемный диск) link(onEventData,8192225:doWork3,[(452,335)]) } Add(HubEx,8192225,448,273) { Angle=3 link(onEvent,15888370:doWork3,[]) } Add(DriveBox,14435899,252,133) { Left=20 Top=15 Width=270 Height=21 } Add(Message,6719040,203,203) { Message="Выгрузить диск ?" Type=2 Point(onYES) link(Caption,13235457:Var1,[(216,184)]) link(onYES,13151070:DeviceRemove,[]) } Add(Button,12916552,154,203) { Left=295 Top=15 Font=[MS Sans Serif,8,1,0,1] TabOrder=-1 Caption="DisCard" link(onClick,6719040:doMessage,[]) } Add(GetDataEx,13235457,245,175) { link(Data,14435899:Disk,[]) }