|
[ Eurora3D Team @ 24.05.2008. 13:53 ] @
| Dali neko ima neki kod koji moze da ocita vrednosti trenutno selektovanih fajlova u Exploreru i na Desktopu.
Kod koji sam napravio radi kada se ocitava ListView kontrola u lokalnom programu. Kada prosledim hWnd desktop ListView-a koji pokazuje ikonice na ekranu (window classa mu je SysListView32) popunjava buffer znakovima kao "EEEEE". Jedina razlika kada ova fn radi/neradi je sto je ListView window u drugom pocesu i mozda u unicode konvenciji. Dali je problem u privilegijama procesa ili u unicodu ?
Nije problem da nadjem desktop window i ListView koji pokazuje ikonice. Isto nije problem ni da nadjem aktivni Explorer window i njegov ListView handler. Jedini problem je da ocitam vrednosti.
Svaki kod koji radi mi zavrsava posao (samo da vidim princip) ... jedino da nije .NET ili drugi framework zato sto mi treba funkcija u cistom WinApi-u.
Ovo je funkcija koju sam napravio za ovo. Ulazni parametar je window handler ListView-a
Code:
BOOL ReadDesktopSelection(HWND hwnd) // int DeskNo ; char* DeskText // spoljnje
{
LONG ret,len;
LV_ITEM lvi;
char buffer [MAX_PATH];
ret = SendMessage(hwnd, LVM_GETSELECTEDCOUNT, 0, 0);
if(ret < 1)
return FALSE;
DeskNo=ret;
DeskText=new char [ret*MAX_PATH];
DeskText[0]=0;
/*
//ITEM
ret=SendMessage(hwnd, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
while(ret!=-1)
{
lvi.iItem = (int)ret;
lvi.iSubItem = 0;
lvi.mask = LVIF_TEXT;
lvi.pszText = &buffer[0];
lvi.cchTextMax = MAX_PATH;
len = SendMessage(hwnd, LVM_GETITEM, 0, (LPARAM)(LV_ITEM FAR *)&lvi);
lstrcat(DeskText,buffer);
lstrcat(DeskText,",");
ret=SendMessage(hwnd, LVM_GETNEXTITEM, ret, LVNI_SELECTED);
}
*/
//ONLY TEXT
ret=SendMessage(hwnd, LVM_GETNEXTITEM, -1, LVNI_SELECTED);
while(ret!=-1)
{
// lvi.iItem = (int)ret;
lvi.iSubItem = 0;
// lvi.mask = LVIF_TEXT;
lvi.pszText = &buffer[0];
lvi.cchTextMax = MAX_PATH;
len = SendMessage(hwnd, LVM_GETITEMTEXT, (WPARAM)ret, (LPARAM)(LV_ITEM FAR *)&lvi);
lstrcat(DeskText,buffer);
lstrcat(DeskText,",");
ret=SendMessage(hwnd, LVM_GETNEXTITEM, ret, LVNI_SELECTED);
}
//
if(lstrlen(DeskText)>0)
DeskText[lstrlen(DeskText)-1]=0; // sklanjam zadnji zarez
::MessageBox(0, DeskText ,"SelectedItems",MB_OK);
return TRUE;
}
|
[ deerbeer @ 24.05.2008. 15:52 ] @
Moras da napravis ATL COM komponentu kao DLL i da implementiras IShellExtInit interfejs ( pogledaj Initialize metod )....
i ako hoces jos da handlujes desni klik u exploreru onda implementiras IContextMenu inteface
Code:
class ATL_NO_VTABLE CResizeShellExt :
public CComObjectRootEx<CComSingleThreadModel>,
public CComCoClass<CResizeShellExt, &CLSID_ResizeShellExtPro>,
public IDispatchImpl<IResizeShellExtPro, &IID_IResizeShellExtPro, &LIBID_SHELLRESIZEProLib>,
public IShellExtInit,
public IContextMenu
{
public:
CResizeShellExt();
~CResizeShellExt() ;
DECLARE_REGISTRY_RESOURCEID(IDR_RESIZESHELLEXT)
DECLARE_PROTECT_FINAL_CONSTRUCT()
BEGIN_COM_MAP(CResizeShellExt)
COM_INTERFACE_ENTRY(IResizeShellExtPro)
COM_INTERFACE_ENTRY(IDispatch)
COM_INTERFACE_ENTRY(IShellExtInit)
COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
END_COM_MAP()
// IResizeShellExt
public:
// IShellExtInit
STDMETHOD(Initialize)(LPCITEMIDLIST, LPDATAOBJECT, HKEY);
// IContextMenu metode
STDMETHOD(GetCommandString)(UINT_PTR, UINT, UINT*, LPSTR, UINT);
STDMETHOD(InvokeCommand)(LPCMINVOKECOMMANDINFO);
STDMETHOD(QueryContextMenu)(HMENU, UINT, UINT, UINT, UINT);
};
HRESULT CResizeShellExt::Initialize ( LPCITEMIDLIST pidlFolder,
LPDATAOBJECT pDataObj,
HKEY hProgID )
{
TCHAR szFile [MAX_PATH];
UINT uNumFiles;
HDROP hdrop;
FORMATETC etc = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
STGMEDIUM stg = { TYMED_HGLOBAL };
//HINSTANCE hinst;
// HRESULT (STDAPICALLTYPE* pfn)();
if (FAILED( pDataObj->GetData ( &etc, &stg )))
return E_INVALIDARG;
hdrop = (HDROP) GlobalLock ( stg.hGlobal );
if (NULL == hdrop)
{
ReleaseStgMedium ( &stg );
return E_INVALIDARG;
}
// Koliko fajlova ima selektovanih
uNumFiles = DragQueryFile ( hdrop, 0xFFFFFFFF, NULL, 0 );
for ( UINT uFile = 0; uFile < uNumFiles; uFile++ )
{
// u petlji uzimas sledece fajlove i smestas ih u neku listu
if ( 0 == DragQueryFile ( hdrop, uFile, szFile, MAX_PATH ))
continue;
}
GlobalUnlock stg.hGlobal );
ReleaseStgMedium ( &stg );
return S_OK ;
}
E sad ne znam koliko ce ti ovakav pristup biti koristan u tvom programu
Ovakva komponenta tj. dll mora da se registruje pod Admin nalogom sa regsvr32.exe
Ako ti ovo ne odgovara onda pogledaj na : http://msdn.microsoft.com/en-us/library/aa457128.aspx
[ Eurora3D Team @ 24.05.2008. 16:14 ] @
Hvala za kod ... nisam ga jos probao u programu ... u svakom slucaju sto vise resenja to bolje
U principu cilj ovoga sto trebam da uradim je da sastavim kod koji ce da koriste drugi programeri a ne korisnici , tako da bi sve tebalo da bude na jednom mestu u obliku koda i da moze lako da se ubaci u VC++ projekat. Tako da ne mogu da racunam na nikakvu spoljnu komponentu nego samo na mehanizme koje ima windows (moze i ovaj COM interface koji si ti postavio samo ako uspem da ga doteram da radi ono sto mi treba)
[ deerbeer @ 24.05.2008. 16:22 ] @
Pretpostavljao sam da ti ovaj primer nije zgodan ..
al mozes da koristis takvu komponentu pa da onda prosledjujes listu fajlova
nekom programu (koji razvijaju drugi programeri )
kroz argumente komande linije ili da koristis sistemsku poruku WM_COPYDATA za transfer tih fajlova u druge programe ..
Jedino sto treba da se uradi je da programer registruje komponentu i ne mora da je ubacuje u solution ...
Ne znam da li jos postoji mehanizama za pristup selektovanim fajlovima ..
al pogledaj na onom linku sto sam ti poslao ...
[ deerbeer @ 24.05.2008. 20:13 ] @
Upss...ono gore je link sa shell api funkcije u embedd sistemima ...
a evo ga pravi http://msdn.microsoft.com/en-us/library/bb776426(VS.85).aspx
Tamo su i funkcije iz primera koji sam poslao DraqQueryFiles ,IShellExtInit ..itd ..
al ne vidim jos nijednu funkciju za dobijanje selektovanih fajlova (ima ih dosta mozda sam nesto ispustio)
Pravljenje ovakvih ekstenzija (plug-inova) koji rade pod explorer.exe -om
povlaci za sobom da moras da imas DLL na sistemu da bi kontrolisao tako nesto (kroz IShellExtInt interfejs)
Slicno pravilo vazi i za pravljenje system-wide MouseHook DLL-a koji sluzi da bi hvatali koordinate misa na desktopu.
[ Eurora3D Team @ 24.05.2008. 20:33 ] @
I ja tazim po netu ... ima raznih pistupa al nijedan nije bas kompletno resenje (by the way nisam rekao da mi treba i iscitavanje trenutnog URL-a iz browsera :) ... al ajde bar ovo da resim)
Hvala na trudu .. saljem ti kod ako napravim nesto :)
Uspeo sam da ocitam desktop sa onom mojom fn gore tako sto sam je stavio u dll i onda dll injectovao u explorer nekom open source injec bibliotekom (znaci izvodila se iz explorera).
Naravno dalako od toga da mogu da to dam programerima kao resenje za ove stvari :)
[ deerbeer @ 25.05.2008. 11:14 ] @
Citat: @Eurora3D Team
by the way nisam rekao da mi treba i iscitavanje trenutnog URL-a iz browsera :) ... al ajde bar ovo da resim)
Iz ActiveX WebBrowser-a ili obicnog IExplorer prozora kao zasebne instance ?
Ako samo hoces da iscitas iz vec postojece instance IExplorer prozora
onda koristi WIN32 API funkcije FindWindowEx ,EnumChildWindows za enumerisanje child prozora.
Pa kad nadjes addres bar (EDit control) tj. njegov "HWND" sa ovom funkcijom
Posalji poruku za dobijanje texta sa istog (WM_GETTEXT)
[Ovu poruku je menjao deerbeer dana 25.05.2008. u 12:24 GMT+1]
[ Eurora3D Team @ 31.05.2008. 20:06 ] @
@deerbeer
Uspeo sam da zavrsim ovo sto sam hteo pa stavljam ovde kao sto sam i rekao.
Bilo je malo problema jer neke stvari ne rade isto na XP - u i Visti pa sam se ovih dana nacitao kojekakve dokumentacije i sl.
Ovu zadnju verziju nisam probao na Visti (ako neko proba i nesto ne radi neka kaze).
Trebalo bi da program radi i na starijim OS.
Svi stringovi su fiksni ... nisam hteo da se bavim optimalizacijom memorije tako da je sve fiksno. A i inace sve ostalo osim glavne funkcije koja radi ovo sto treba je pisano na brzinu.
Inace u kodu ima nekoliko advanced tehnika pa preporucujem da se pogleda... a inace je cist win api.
Project fajl je za VC++6
Vidim da se i ti dosta rezumes u win api ...
Ovde mozes da nadjes kako se ocitava SysListView32 u drugom procesu itd.
Pozdrav
http://eurora3d.com/es/SelectedFilesSrc.zip
[ deerbeer @ 01.06.2008. 01:00 ] @
E super ... znaci ipak moze da se uradi preko standardnog WIN32 api-ija i Shell funkcija ....
Kljucna stvar koliko mi se cini je funkcija SendMessageRemote
i funkcije :
Code:
GetWindowThreadProcessId
OpenProcess
....
WriteProcessMemory( hProcHnd, pLVI, &lvitem, sizeof( LVITEM ), &copied );
ret=SendMessage( hWnd, LVM_GETITEMTEXT, wParam, (LPARAM)pLVI );
ReadProcessMemory( hProcHnd, pBuffer, (LPVOID)buffer, MAX_PATH, &copied );
Ovo je onaj deo sto si rekao da radis inject u explorer-ov proces da bi procitao sa ListView kontrole selektovani fajl.
Evo da se nadovezem malo na kod ako ti treba citanje bitmapa (ili thumbnail-ova) iz explorer fajlova.
proizvoljnih dimenzija .Metod je veoma brz jer cita keshiranu bitmapu iz thumbs.db - hidden fajla.
Radi pod XP-om i pod Vistom .
Code:
LPCTSTR lsFile = _T("putanja do neke slike (jpg,bmp,png , itd.....)") ;
HRESULT hr ;
SIZE prgSize ;
prgSize.cx = 160 ; //zeljene dimenzije bitmape
prgSize.cy = 120;
DWORD dwRecClrDepth = 3 ;
CoInitialize(NULL) ;
IShellFolder* pShell = 0 ;
ULONG nItems = 1 ;
hr = SHGetDesktopFolder(&pShell) ;
CString strpath = CFileOptions::GetFullPath(lpsFile) ; // funkcija koja vraca samo putanju bez imena fajla
CString strFile = CFileOptions::GetFileExt(lpsFile) ; // funkcija koja vraca samo ime fajla ...
LPCSTR path = (LPCSTR)strpath ;
LPCSTR file = (LPCSTR)strFile ;
LPITEMIDLIST pidl = NULL;
OLECHAR olePath[MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,path, -1, olePath, MAX_PATH);
hr = pShell->ParseDisplayName(NULL, NULL,olePath, NULL, &pidl, NULL);
if (hr != S_OK)
{
TRACE(_T("ParseDisplayName failed \r\n")) ;
return NULL;
}
LPSHELLFOLDER psfFolder = NULL;
hr = pShell->BindToObject(pidl,NULL,IID_IShellFolder,(void**)&psfFolder) ;
if (hr != S_OK)
{
TRACE(_T("BindToObject failed \r\n")) ;
return NULL;
}
OLECHAR oleFile[MAX_PATH];
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,file, -1, oleFile, MAX_PATH);
psfFolder->ParseDisplayName(NULL,NULL,oleFile,NULL,&pidl,NULL) ;
if (hr != S_OK)
{
TRACE(_T("ParseDisplayName failed \r\n")) ;
return NULL;
}
IExtractImage* pIExtract = NULL;
LPCITEMIDLIST pidlExtract = pidl ;
hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlExtract, IID_IExtractImage, NULL, (void**)&pIExtract);
if(NULL == pIExtract)
return NULL;
OLECHAR wszPathBuffer[MAX_PATH];
DWORD dwPriority = 0;
DWORD dwFlags = IEIFLAG_SCREEN;
HBITMAP hBmpImage = NULL;
hr = pIExtract->GetLocation(wszPathBuffer, MAX_PATH, &dwPriority,&prgSize, dwRecClrDepth, &dwFlags);
if(NOERROR == hr)
hr = pIExtract->Extract(&hBmpImage);
pIExtract->Release();
return hBmpImage; // bitmapa dimenzija 160x120
[ Eurora3D Team @ 01.06.2008. 12:09 ] @
Hvala za fn...
Valjda ce neko da se okoristi od ovih nasih tekstova :)
Jeste, ono za inject je tacno. Cisto radi objasnjenja da napisem ... nije stvar u tome da se injectuje zbog nekih sigurnosnih stvari ili sl. U nekoj dokumentaciji sam nasao da se za messages ispod neke (WM_USER 1024) vrednosti za kopiranje memorije (izmedju procesa) brine windows , npr kod WM_GETTEXT a za one iznad te vrednosti (za LVM_GETITEMTEXT npr.) moramo sami da se pobrinemo. Isto taj buffer treba da bude alociran u procesu kojem window pripada, znaci ovde za nas to je drugi proces, i da ga prekopiramo kada se SendMessage izvrsi.
[ deerbeer @ 01.06.2008. 13:39 ] @
Citat: @Eurora3D Team
Hvala za fn...
Valjda ce neko da se okoristi od ovih nasih tekstova :)
Pa koga interesuje WIN32 api i ko voli da zaviri malo ispod haube windows-a sigurno ce mu biti od neke koristi ..
Citat: @Eurora3D Team
Jeste, ono za inject je tacno. Cisto radi objasnjenja da napisem ... nije stvar u tome da se injectuje zbog nekih sigurnosnih stvari ili sl. U nekoj dokumentaciji sam nasao da se za messages ispod neke (WM_USER 1024) vrednosti za kopiranje memorije (izmedju procesa) brine windows , npr kod WM_GETTEXT a za one iznad te vrednosti (za LVM_GETITEMTEXT npr.) moramo sami da se pobrinemo. Isto taj buffer treba da bude alociran u procesu kojem window pripada, znaci ovde za nas to je drugi proces, i da ga prekopiramo kada se SendMessage izvrsi.
Meni se to cinilo kao problem jer MS valjda nije toliko hteo da "otvori" svoj Shell Api bas iz security razloga ...
Probacu sutra kad dodjem na posao da li radi na Visti ...
Pozz!!!
EDIT:
Radi na Visti ...
[Ovu poruku je menjao deerbeer dana 02.06.2008. u 12:04 GMT+1]
[ Eurora3D Team @ 02.06.2008. 20:35 ] @
[ deerbeer @ 02.06.2008. 20:38 ] @
Hehe ... nema na cemu :)
Copyright (C) 2001-2025 by www.elitesecurity.org. All rights reserved.
|