2010-02-02 23 views
7

मैं कैसे पता लगा सकता हूं कि एक हटाने योग्य डिस्क ड्राइव (डी) सिस्टम से जुड़ा हुआ है? माउंट पथ (लिनक्स के लिए) और ड्राइव अक्षर (विंडोज़ के लिए) कैसे प्राप्त करें?हटाने योग्य ड्राइव का पता लगाएं (जैसे यूएसबी फ्लैश ड्राइव) सी/सी ++

संपादित करें: क्या वर्तमान में जुड़े उपकरणों का पता लगाने का कोई तरीका है?

उत्तर

4

Windows के लिए, एपीआई RegisterDeviceNotification तुम्हें पता है जब एक USB डिवाइस जोड़ा जाता है करने देगा। वॉल्यूम के बारे में जानकारी DEV_BROADCAST_VOLUME structure में दी गई है। dbcv_unitmask ड्राइव अक्षर देता है।

+1

क्या आप एक उदाहरण सुझा सकते हैं? –

+2

http://msdn.microsoft.com/en-us/library/aa363215(VS.85).aspx –

+0

धन्यवाद, मैं कोशिश करूँगा। –

1

आप शैल से परिवर्तन अधिसूचनाएं (ड्राइव/हटाए गए ड्राइव के लिए) प्राप्त कर सकते हैं। आप documenattion के रूप में उपयोग करने के लिए इस डेल्फी कोड का उपयोग कर सकते हैं:

unit UnitChangeNotify; 

interface 

uses 
    Windows, Messages, SysUtils, Classes, ShlObj, Types; 

type 
    SHChangeNotifyEntry = record 
     pidlPath  : PItemIDList; 
     bWatchSubtree : Boolean; 
    end; 

    TChangeEventType = (
     cnAssocchanged, 
     cnAttributes, 
     cnCreate, 
     cnDelete, 
     cnDriveAdd, 
     cnDriveAddGui, 
     cnDriveRemoved, 
     cnMediaInserted, 
     cnMediaRemoved, 
     cnMkdir, 
     cnNetShare, 
     cnNetUnshare, 
     cnRenameFolder, 
     cnRenameItem, 
     cnRmdir, 
     cnServerDisconnect, 
     cnUpdateDir, 
     cnUpdateImage, 
     cnUpdateItem); 

    TChangeNotifyEvent = procedure(Sender: TObject; Event: TChangeEventType; const Paths: TStringDynArray) of object; 

    TChangeNotify = class(TComponent) 
    private 
     FHWnd:    HWND; 
     FRegID:   THandle; 
     FEntry:   SHChangeNotifyEntry; 
     FOnChange:   TChangeNotifyEvent; 
     function GetActive  (): Boolean; 
     procedure SetActive   (const Value: Boolean); 
     procedure WndProc   (var Msg: TMessage); 
     procedure DoEvent   (Event: TChangeEventType; const Paths: TStringDynArray); virtual; 
    public 
     constructor Create   (Aowner: TComponent); override; 
     destructor Destroy;   override; 
     property Active:   Boolean   read GetActive write SetActive; 
     property OnChange:   TChangeNotifyEvent read FOnChange write FOnChange; 
    end; 

const 
    SHCNF_ACCEPT_INTERRUPTS  = $0001; 
    SHCNF_ACCEPT_NON_INTERRUPTS = $0002; 
    SHCNF_NO_PROXY    = $8000; 

function SHChangeNotifyRegister( hWnd: HWND; fSources: Integer; wEventMask: DWORD; uMsg: UINT; cItems: integer; const Items: SHChangeNotifyEntry): THandle; stdcall; 
function SHChangeNotifyDeregister(hRegID: THandle) : BOOL; stdcall; 
function SHILCreateFromPath(  Path: Pointer; PIDL: PItemIDList; var Attributes: ULONG): HResult; stdcall; 

implementation 

const Shell32DLL = 'shell32.dll'; 

function SHChangeNotifyRegister; external Shell32DLL index 2; 
function SHChangeNotifyDeregister; external Shell32DLL index 4; 
function SHILCreateFromPath;  external Shell32DLL index 28; 

{ TChangeNotify } 

constructor TChangeNotify.Create(Aowner: TComponent); 
begin 
    inherited Create(AOwner); 
end; 

destructor TChangeNotify.Destroy; 
begin 
    Active := False; 
    inherited Destroy; 
end; 

procedure TChangeNotify.DoEvent(Event: TChangeEventType; const Paths: TStringDynArray); 
begin 
    if Assigned(FOnChange) then FOnChange(Self, Event, Paths); 
end; 

function TChangeNotify.GetActive(): Boolean; 
begin 
    Result := FHWnd <> 0; 
end; 

procedure TChangeNotify.SetActive(const Value: Boolean); 
begin 
    if Value = GetActive() then Exit; 
    if Value then begin 
     FHWnd := AllocateHWnd(WndProc); 
     FEntry.pidlPath  := nil; 
     FEntry.bWatchSubtree := True; 
     FRegID := SHChangeNotifyRegister(FHWnd, SHCNF_ACCEPT_INTERRUPTS or SHCNF_ACCEPT_NON_INTERRUPTS, 
              SHCNE_ALLEVENTS, WM_USER, 1, FEntry); 
     if FRegID = 0 then begin 
      DeallocateHWnd(FHWnd); 
      FHWnd := 0; 
      RaiseLastOSError(); 
     end; 
    end else begin 
     SHChangeNotifyDeregister(FRegID); 
     FRegID := 0; 
     DeallocateHWnd(FHWnd); 
     FHWnd := 0; 
    end; 
end; 

procedure TChangeNotify.WndProc(var Msg: TMessage); 
type 
    PPITEMIDLIST = ^PITEMIDLIST; 
var 
    Event: TChangeEventType; 
    i:  Integer; 
    Paths: TStringDynArray; 
    P:  PPITEMIDLIST; 
const 
    EventBits: array [ TChangeEventType ] of DWORD = (
     SHCNE_ASSOCCHANGED, 
     SHCNE_ATTRIBUTES, 
     SHCNE_CREATE, 
     SHCNE_DELETE, 
     SHCNE_DRIVEADD, 
     SHCNE_DRIVEADDGUI, 
     SHCNE_DRIVEREMOVED, 
     SHCNE_MEDIAINSERTED, 
     SHCNE_MEDIAREMOVED, 
     SHCNE_MKDIR, 
     SHCNE_NETSHARE, 
     SHCNE_NETUNSHARE, 
     SHCNE_RENAMEFOLDER, 
     SHCNE_RENAMEITEM, 
     SHCNE_RMDIR, 
     SHCNE_SERVERDISCONNECT, 
     SHCNE_UPDATEDIR, 
     SHCNE_UPDATEIMAGE, 
     SHCNE_UPDATEITEM); 
    EventPIDLCount: array [ TChangeEventType ] of Integer = (
     2, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     1, 
     2, 
     2, 
     1, 
     1, 
     1, 
     1, 
     1); 
begin 
    case Msg.Msg of 
     WM_USER: begin 
      // lParam = eventmask 
      // wParam = array of PIDLs with 
      for Event := Low(Event) to High(Event) do begin 
       if EventBits[ Event ] and msg.LParam = EventBits[ Event ] then begin 
        SetLength(Paths, EventPIDLCount[ Event ]); 
        P := PPITEMIDLIST(Msg.WParam); 
        for i := 0 to High(Paths) do begin 
         SetLength(Paths[ i ], MAX_PATH); 
         if not SHGetPathFromIDList(P^, PChar(Paths[ i ])) then Paths[ i ] := '' else Paths[ i ] := PChar(Paths[ i ]); 
         Inc(P); 
        end; 
        DoEvent(Event, Paths); 
        Break; 
       end; 
      end; 
     end; 
    end; 
    DefaultHandler(Msg); 
end; 

end. 
संबंधित मुद्दे