Cum as putea monitoriza discurile ?

Intrebari legate de programarea cu biblioteci precum MFC, ATL, WTL si GDI+.
mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Cum as putea monitoriza discurile ?

Post by mesajflaviu » 06 Dec 2010, 10:04

Cum as putea monitoriza cu ajutorul unui program MFC discurile nou aparute , exact ca in Windows Explorer ? De exemplu , daca introduc un stick USB in PC , sau eventual , daca scot un stick sau cade un disc de retea ?



User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Cum as putea monitoriza discurile ?

Post by Marius Bancila » 06 Dec 2010, 11:32

Teoretic ar trebui sa prinzi mesajul WM_CHANGEDEVICE. Treaba e ca nu-l gasesc documentat niciunde. Chiar is MSDN-ul nu gaseste decat acest articol: http://www.codeproject.com/KB/dotnet/de ... nitor.aspx.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: Cum as putea monitoriza discurile ?

Post by cristianamarie » 06 Dec 2010, 22:29

Marius Bancila wrote:Teoretic ar trebui sa prinzi mesajul WM_CHANGEDEVICE. Treaba e ca nu-l gasesc documentat niciunde. Chiar is MSDN-ul nu gaseste decat acest articol: http://www.codeproject.com/KB/dotnet/de ... nitor.aspx.
E WM_DEVICECHANGE, cu wParam == DBT_DEVICEARRIVAL (poate si DBT_DEVNODES_CHANGED). Sau cu RegisterDeviceNotification.
Te uiti la lParam (DEV_BROADCAST_HDR) sa aiba tipul DBT_DEVTYP_VOLUME, si faci cast la DEV_BROADCAST_VOLUME.
dbcv_unitmask iti spune care e drive letter (0=A, 1=B etc).

Ca sa iei volume info, DeviceIoControl pe handle-ul de la CreateFile cu \\.\X (X = drive letter) si un control code gen IOCTL_DISK_GET_PARTITION_INFO_EX (sa iei partitiile), GetVolumeInformation pentru disk si serial number, volume info, file system etc. Depinde ce vrei.

Aici ai un sample.
Last edited by cristianamarie on 06 Dec 2010, 22:32, edited 1 time in total.
Nuclear launch detected

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: Cum as putea monitoriza discurile ?

Post by cristianamarie » 06 Dec 2010, 22:32

Poti lua si direct de la shell cu SHChangeNotifyRegister. Probabil de ce ai nevoie e notificarea SHCNE_DRIVEADD, si in dwItem1 ai drive root. Poate fi SHCNF_IDLIST sau SHCNF_PATH.
Nuclear launch detected

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: Cum as putea monitoriza discurile ?

Post by cristianamarie » 06 Dec 2010, 22:34

cristianamarie wrote:Poti lua si direct de la shell cu SHChangeNotifyRegister. Probabil de ce ai nevoie e notificarea SHCNE_DRIVEADD, si in dwItem1 ai drive root. Poate fi SHCNF_IDLIST sau SHCNF_PATH.
Sau SHCNE_MEDIAINSERTED.
Nuclear launch detected

User avatar
Marius Bancila
Fondator
Fondator
Posts: 2344
Joined: 11 Jul 2007, 11:45
Judet: Timiş
Location: Timisoara
Contact:

Re: Cum as putea monitoriza discurile ?

Post by Marius Bancila » 07 Dec 2010, 00:40

Ah, da, asta era, WM_DEVICECHANGE. Doar stiam ca citisem de mai multe ori in trecut despre mesajul asta; nu puteam intelege azi de ce nu gaseam nimic.
Marius Bancila
Fondator Codexpert, Microsoft MVP VC++
Site personal | Blog

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: Cum as putea monitoriza discurile ?

Post by cristianamarie » 07 Dec 2010, 09:09

Din categoria "de cite ori ati scris SLEECT in loc de SELECT" ? :)
Nuclear launch detected

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Cum as putea monitoriza discurile ?

Post by mesajflaviu » 07 Dec 2010, 09:30

Multumesc tuturor , o sa incerc acel exemplu .

User avatar
Andreas
Membru
Membru
Posts: 117
Joined: 09 Nov 2008, 12:13
Judet: Timiş
Location: Timisoara

Re: Cum as putea monitoriza discurile ?

Post by Andreas » 08 Dec 2010, 14:09

ma gandesc ca s-ar putea scrie un monitor pentru discurile logice dintr-un sistem folosind WMI:WMI Start Page
chiar zilele trecute am avut nevoie sa afisez intr-o aplicatie C# ceva date despre hw local, si am fost surprins placut sa constat ce mult s-au inlesnit lucrurile in .NET. Un exemplu ar fi:aici
Daca nu ai constrangeri legate de dependintele aplicatiei, eu as incerca sa scriu un monitor pentru discurile logice impachetat intr-un dll C++/CLI, adaptand codul C# din exemplu de mai sus. Asta ca sa nu "convertesc" toata aplicatia la CLR.

Altfel, daca ramai doar pe C++ nativ trebuie sa te joci doar cu WMI, Win32_LogicalDisk, exemple gasindu-se chiar in MSDN. Daca nu doresti sa faci monitorul un loop intr-un thread, ai posibilitatea inclusiv sa primesti evenimente de la WMI in urma carora sa faci query despre logical disks:Example: Receiving Event Notifications Through WMI

User avatar
cristianamarie
Membru++
Membru++
Posts: 480
Joined: 12 Mar 2009, 18:47
Judet: Iaşi
Location: Iasi

Re: Cum as putea monitoriza discurile ?

Post by cristianamarie » 09 Dec 2010, 12:08

Andreas wrote:ma gandesc ca s-ar putea scrie un monitor pentru discurile logice dintr-un sistem folosind WMI:WMI Start Page
chiar zilele trecute am avut nevoie sa afisez intr-o aplicatie C# ceva date despre hw local, si am fost surprins placut sa constat ce mult s-au inlesnit lucrurile in .NET. Un exemplu ar fi:aici
Daca nu ai constrangeri legate de dependintele aplicatiei, eu as incerca sa scriu un monitor pentru discurile logice impachetat intr-un dll C++/CLI, adaptand codul C# din exemplu de mai sus. Asta ca sa nu "convertesc" toata aplicatia la CLR.

Altfel, daca ramai doar pe C++ nativ trebuie sa te joci doar cu WMI, Win32_LogicalDisk, exemple gasindu-se chiar in MSDN. Daca nu doresti sa faci monitorul un loop intr-un thread, ai posibilitatea inclusiv sa primesti evenimente de la WMI in urma carora sa faci query despre logical disks:Example: Receiving Event Notifications Through WMI
Probabil o sa trebuiasca dintr-un service si asta sa notifice aplicatia client. Marea problema e CoInitializeSecurity. Pe Vista am patit destule sa primesc S_OK dar return data empty cu user admin dar nu elevat (!!). Cu runas admin primeam datele corecte.
Nuclear launch detected

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Cum as putea monitoriza discurile ?

Post by mesajflaviu » 14 Dec 2010, 22:54

cristianamarie wrote:
Marius Bancila wrote:Teoretic ar trebui sa prinzi mesajul WM_CHANGEDEVICE. Treaba e ca nu-l gasesc documentat niciunde. Chiar is MSDN-ul nu gaseste decat acest articol: http://www.codeproject.com/KB/dotnet/de ... nitor.aspx.
E WM_DEVICECHANGE, cu wParam == DBT_DEVICEARRIVAL (poate si DBT_DEVNODES_CHANGED). Sau cu RegisterDeviceNotification.
Te uiti la lParam (DEV_BROADCAST_HDR) sa aiba tipul DBT_DEVTYP_VOLUME, si faci cast la DEV_BROADCAST_VOLUME.
dbcv_unitmask iti spune care e drive letter (0=A, 1=B etc).

Ca sa iei volume info, DeviceIoControl pe handle-ul de la CreateFile cu \\.\X (X = drive letter) si un control code gen IOCTL_DISK_GET_PARTITION_INFO_EX (sa iei partitiile), GetVolumeInformation pentru disk si serial number, volume info, file system etc. Depinde ce vrei.

Aici ai un sample.
Am incercat acel exemplu ... dar nu merge ...aplicatia nu prinde WM_DEVICECHANGE :

Code: Select all

ON_MESSAGE(WM_DEVICECHANGE,OnMyDeviceChange)

Code: Select all

void CDeviceChangeView::OnMyDeviceChange(HWND hwnd, WPARAM wParam, LPARAM lParam)
{
                MessageBox("A");
}
.. fara nici un rezultat ...

Viorel
Microsoft MVP
Microsoft MVP
Posts: 293
Joined: 13 Jul 2007, 12:26

Re: Cum as putea monitoriza discurile ?

Post by Viorel » 14 Dec 2010, 23:14

Încearcă să interceptezi mesajul în fereastra principală a aplicaţiei.

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Cum as putea monitoriza discurile ?

Post by Ovidiu Cucu » 15 Dec 2010, 16:35

In primul rand, prinde mesajul in fereastra principla (CMainFrame), asa cum a zis Viorel.
Banui ca ai putea sa-l prinzi si in alta daca folosesti functia RegisterDeviceNotification care este cam "peste mana" pentru ceea ce vrei tu.

In al dolea rand, ai grija cum mapezi.
Daca folosesti macro-ul ON_WM_DEVICECHANGE() atunci prototipul corect este ca cel din documentatia lui CWnd::OnDeviceChange

Code: Select all

BOOL CMainFrame:OnDeviceChange(UINT nEventType, DWORD dwData)
Si in general, daca folosesti macro-ul ON_MESSAGE(WM_XYZ, OnXyz) atunci prototipul corect al handler-ului este

Code: Select all

LRESULT CMainFrame::OnXyz(WPARAM wParam, LPARAM lParam)
In versiuni mai noi de MFC, compilatorul iti da peste mana cum vede ca ai mapat gresit.
E posibil ca VS6.0 sa-ti permita mici "variatiuni", s-ar putea chiar sa functioneze in buid-ul DEBUG, dar in RELEASE vei avea probeme.
Bagi un bug din seria "merge in debug, in release crapa", destul de nashpa de gasit.

mesajflaviu
Membru++
Membru++
Posts: 687
Joined: 10 Sep 2008, 21:40
Judet: Cluj

Re: Cum as putea monitoriza discurile ?

Post by mesajflaviu » 15 Dec 2010, 21:27

Sa incerc sa prind acest mesaj in MainFrame am incercat deja , insa fara rezultat .
Mai important , am invatat ceva : desi foloseam regula denumirii metodelor dupa cum a zis Ovidiu ( desi in cazul asta m-am inspirat dupa un exemplu de pe net ) , nu stiam ca poate da erori la Release . In trecut , am dedus de aici ca nu conteaza daca numele metodei difera de numele mesajului ...

User avatar
Ovidiu Cucu
Fondator
Fondator
Posts: 3778
Joined: 11 Jul 2007, 16:10
Judet: Iaşi
Location: Iasi
Contact:

Re: Cum as putea monitoriza discurile ?

Post by Ovidiu Cucu » 15 Dec 2010, 23:35

NU ma refeream la nume (poti sa-i zici si Rantampax :)) ci la semnatura.
Adica, handler-ul mapat cu ON_MESSAGE trebuie sa aiba doi parametri de tip WPARAM si LPARAM si sa intoarca LRESULT.
Tu pusesesi:

Code: Select all

ON_MESSAGE(WM_DEVICECHANGE,OnMyDeviceChange)
//...
void CDeviceChangeView::OnMyDeviceChange(HWND hwnd, WPARAM wParam, LPARAM lParam)
Vezi Incorrect Function Signatures May Cause Problems in Release

Post Reply