Bir Kiosk ve CreateDesktop macerası.. | Delphi Programming
Transkript
Bir Kiosk ve CreateDesktop macerası.. | Delphi Programming
Contact Me | Subscribe D e l p h i P r o g r a m m i n g Search Keywords There are only 10 types of people in the world: Those who understand binary, and those who don’t. Home TObject.Create Delphi Hakkında Ziyaretçi Defteri Posted by Tuğrul HELVACI - Mayıs 20, 2009 Comments 17 Bir Kiosk ve CreateDesktop macerası.. Plugin WP FlashTime by horoscop 2009.org requires Flash Player 8 or better currency converter calculator.Plugin creat de horoscop | horoscop saptamanal | horoscop zilic | horoscop | play sonic games Bu yazıma gecenin bu saatinde başladığıma göre büyük ihtimalle yarın işe geç kalacağım. Ama tamamlandığında da bu konuyu 3 gündür makaleleştirememenin verdiği sıkıntıdan da kurtulmuş olacağım. Sanırım bu kafi derecede haz verir bana. Hayatının herhangi bir anında herhangi bir husus hakkında birşeyler karalamış olanlar bilirler ki, bir şeyi biliyor olmak ile anlatabiliyor olmak cidden farklı. Bunlar farklı kaabiliyetler sanıyorum. Ve yine yazmaya gönlü kaymış kişiler bilir ki; bazen bir konuyu layıkı ile anlatamama endişesi “acaba hiç mi yazmasam” düşüncesine hayat verir. Bende böyle gitgeller yaşadım bu makale için ama elimden geldiğince kendi üslubum gereği aklıma gelen tüm detaylara da inerek bir cesaretle ya Allah diyip başlıyorum makaleye. Şimdiden okuyanların gözlerini ve zihinlerini yoracağım için helallik diliyorum. Aslında anlatacaklarım tam bir kiosk uygulaması değil elbette. Ancak bir ucundan dokunuyor. Daha ziyade Unix türevli işletim sistemlerinin popüler KDE, Gnome gibi arayüzlerinde görmeye alıştığımız multi-desktop meselesini anlatmaya çalışacağım. Pek çok kullanıcı bazen muzurluk adına ve bazen de gerçekten işi gereği çoklu masaüstlerine ihtiyaç duyar. İşyerinde çalışırken, başkalarından gizlemek istediği programları başka bir masaüstünde barındırmak Etiketler Absolute Abstract Classes ActionScript Algoritma API Bug Byte Arrays Class Reference CloseHandle COM CreateDesktop CreateEvent CreateMutex CreateProcess CreateRemoteThread CreateSemaphore CreateToolHelp32SnapShot CreateWaitableTimer DeleteCriticalSection delphi 2010 DTS EnterCriticalSection EnumDesktopProc EnumDesktops Flash Function PDFmyURL.com isteyen insanların sayısı gerçekten de az değildir. Hatta irili ufaklı pek çok uygulamada vardır sevgili patron ve müdürlerin gözlerinden sizleri korumak için Bazı yazılımlar ise, muzurluk adına değil de yapmaları icap eden iş gereği başka masaüstlerinde çalışma ihtiyacı hissederler. Kiosk uygulamaları gibi. Bu uygulamalar genelde topluma açık yerlerde herkesin kullanımına sunulduklarından işletim sistemine müdahalenin mümkün mertebe sınırlandırılması gerekir. Bunun için en güzel çözümlerden bir tanesi uygulamanın kendisine has bir masaüstünde çalışmasıdır. Böylelikle bilerek yada bilmeyerek verilecek zararlar minimize edilmiş olur. Tüm bu düşüncelerin ışığında, bir kaç gün evvel kendime ait bir masaüstü nasıl yaparım diye oturdum araştırma yaptım. Başta herşey iyi gidiyordu. İstediğimi yapabilmiştim. İşletim sistemi üzerinde bir masaüstü oluşturabilmiş, o masaüstüne geçebilmiş ve hatta uygulamamı yalnız başına orada çalıştırmayı başarabilmiştim. Buraya kadar herşey gayet iyi idi. Ancak ne oldu ise ondan sonra oldu Programlama sanatına gönül vermiş insanların uzun makaleleri okurken sıkıldıklarını, konudan uzaklaşma eğilimi gösterdiklerini gözlemledim programlama hayatım boyunca. Bu sebeple, kodsal içeriklere başlayarak ilerlemeyi sizlerin sıkılmaması adına tercih ediyorum. Sizlere ilk bahsedeceğim API CreateDesktop API’si olacak: CreateDesktop API’si Win32 Programmers Referance’da aşağıdaki şekilde tanımlanmıştır. 1. 2. 3. 4. 5. 6. 7. 8. HDESK CreateDesktop( LPCTSTR lpszDesktop, // name of the new desktop LPCTSTR lpszDevice, // reserved; must be NULL. LPDEVMODE pDevMode, // reserved; must be NULL DWORD dwFlags, // flags to control interaction with other applications DWORD dwDesiredAccess, // specifies access of returned handle LPSECURITY_ATTRIBUTES lpsa // specifies security attributes of the desktop ); Aynı API’nin Delphi’deki tanımı ise: 1. 2. 3. function CreateDesktop(lpszDesktop, lpszDevice: PChar; pDevmode: PDeviceMode; dwFlags: DWORD; dwDesiredAccess: DWORD; lpsa: PSecurityAttributes): HDESK; stdcall; şeklindedir. Adından anlaşılabileceği gibi bu fonksiyon yeni bir masaüstü oluşturmaktadır. Fonksiyonumuzun birinci parametresi desktop’umuza vereceğimiz isimdir. İkinci ve üçüncü paratemtelerin Nil(Null) olması gerektiği bildirilmektedir yardım dökümanında. dwFlags isimli dördüncü parametre ise çalıştırılacak olan uygulamanın yeni desktopta diğer uygulamalar ile nasıl bir işbirliği yapacağını belirtirmiş. Ancak bunu nasıl yapar, derinlerinde ne gibi ipuçları EnumDesktopProc EnumDesktops Flash Function Pointer GetCurrentProcess GetIconInfo GetKeyState GetLastInputInfo GetProcessMemoryInfo GetStartupInfo GetThreadContext GetTickCount GetTickCount64 Hacking Inheritance InitializeCriticalSection Interface InterlockedCompareExchange InterlockedDecrement InterlockedExchange InterlockedExchangeAdd InterlockedIncrement JavaScript LeaveCriticalSection Method Pointer Module32First Module32Next MSSQL OpenDesktop OpenEvent OpenMutex OpenSemaphore OpenWaitableTimer Operator Overloading Persistance Pointer Procedure Pointer Process Process32First Process32Next Query QueryInterface QueryPerformanceCounter Queue ReleaseMutex ReleaseSemaphore Reqursion ResetEvent ResumeThread RTTI SetEvent SetProcessWorkingSetSize SetThreadContext SetWaitableTimer Smilarity SORT SQL SQL Server Stream SuspendThread Sw itchDesktop TDateTime TerminateProcess TerminateThread Thread TInterfacedObject TValue Untyped Parameters VirtualAllocEx VirtualFreeEx WaitForSingleObject WaitForMultipleObjects Weaver WriteProcessMemory _AddRef _Release WP Cumulus Flash tag cloud by Roy Tanck requires Flash Player 9 or better. Son Yorumlar Yeni Veri Tipleri ve Operator Overloading için Tuğrul HELVACI Yeni Veri Tipleri ve Operator Overloading için Zafer Çelenk Delphi ve Google Maps API için Tuğrul HELVACI Delphi ve Google Maps API için ahmet Ziyaretçi Defteri için Tuğrul HELVACI PDFmyURL.com vardır henüz bilmiyorum. Ancak yardım dosyasında denildiği kadarı ile dwFlags’ın alabileceği değer ya sıfır olabilirmiş yada DF_ALLOWOTHERACCOUNTHOOK olabilirmiş. Biz bu parametre için bu değeri kullanacağız. DF_ALLOWOTHERACCOUNTHOOK sabiti Windows.pas’da 1 değeri ile ifade edilmiştir. dwDesiredAccess isimli parametremiz ise yeni oluşturacağımız desktopumuzun kaabiliyetlerini ifade edecek. Yine yardım dosyasında aşağıdaki değerlere sahip olabileceğini gözlemleyebilirsiniz: 01. 02. 03. 04. 05. 06. 07. 08. 09. DESKTOP_READOBJECTS = 1; DESKTOP_CREATEWINDOW = 2; DESKTOP_CREATEMENU = 4; DESKTOP_HOOKCONTROL = 8; DESKTOP_JOURNALRECORD = $10; DESKTOP_JOURNALPLAYBACK = $20; DESKTOP_ENUMERATE = $40; DESKTOP_WRITEOBJECTS = 128; DESKTOP_SWITCHDESKTOP = $100; Bu parametrenin alabileceği değerler son derece mühim. Yeni oluşturacağınız desktop’un yapabilecekleri bu parametrelerle belirleniyor. Biz desktopumuzun her türlü hakka sahip olmasını isteyeceğiz bu uygulamamızda. O sebeple aşağıdaki gibi bir tanım yapacağız: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. const DESKTOP_ALL = DESKTOP_READOBJECTS or DESKTOP_CREATEWINDOW or DESKTOP_CREATEMENU or DESKTOP_HOOKCONTROL or DESKTOP_JOURNALRECORD or DESKTOP_JOURNALPLAYBACK or DESKTOP_ENUMERATE or DESKTOP_WRITEOBJECTS or DESKTOP_SWITCHDESKTOP; Son parametremiz ise işletim sisteminde tanımlı olan ve genellikle hep nil bıraktığımız güvenlik parametresi. Bu parametre işletim sistemi güvenliği ile ilgili derin güvenlik bilgileri istiyor, açıkçası bu hususta az bir bilgim var o yüzden sizlere bu parametrenin detaylarını anlatamayacağım. Bu parametremizi de Nil(Null) olarak geçeceğiz. Tüm bu bilgilerin ışığında artık desktop’umuzu oluşturan kodumuzu yazabiliriz: 1. 2. 3. 4. 5. 6. 7. var NewDesktop : HDESK; begin NewDesktop := CreateDesktop(PChar('NewDesktop'), nil, nil, DF_ALLOWOTHERACCOUNTHOOK, DESKTOP_ALL, nil); .. .. end; Ziyaretçi Defteri için Tuğrul HELVACI Son Yazılar Yeni Veri Tipleri ve Operator Overloading Interface Nedir, Nerelerde ve Neden Kullanırız ? Derinlemesine Threading..(3) SQL’de Benzerlik Algoritmaları… Full Text Searching… Kategoriler Genel (4) IDE (1) İşletim Sistemi (7) Programlama (43) .Net (3) C# (2) Delphi (43) Grafik (2) Internet (4) Veritabanı (3) Win32 (6) Takvim Temmuz 2010 Pts Sal Çar Per Cum Cts Paz 1 2 3 4 PDFmyURL.com Evet artık işletim sistemi üzerine yeni bir masaüstü daha açtık. Ama tabii ki henüz onu göremiyoruz. Kaç tane masaüstümüz olduğunu da bilmiyoruz şu anda. Bazı arkadaşlarımın, “Nasıl bilmiyoruz ? Bir tane vardı bir de biz oluşturduk etti iki..” dediğinizi duyar gibiyim Yok yok iki tane değil İşletim sistemimizde mevcut birden fazla masaüstü var. Arzu ederseniz daha fazla ilerlemeden önce bu söylemimizin doğruluğunu test edelim. Bu bağlamda hemen Win32 API help’imizi açıyor ve CreateDesktop yazıyoruz. Bu fonksiyonun Group yada See also kısmına baktığımızda EnumDesktops isimli fonksiyonu göreceğiz. Adından da anlaşıldığı gibi bu fonksiyon bize işletim sistemindeki masaüstlerini verecek. Gelin birlikte tanımına bir göz atalım; 1. 2. 3. 4. 5. BOOL EnumDesktops( HWINSTA hwinsta, // handle to window station to enumerate DESKTOPENUMPROC lpEnumFunc, // points to application's callback function LPARAM lParam // 32-bit value to pass to the callback function ); 5 12 19 26 6 13 20 27 7 14 21 28 8 15 22 29 9 16 23 30 10 11 17 18 24 25 31 « Haz Arşivler Haziran 2010 (1) Mayıs 2010 (1) Nisan 2010 (3) Ağustos 2009 (1) Temmuz 2009 (2) Haziran 2009 (7) Mayıs 2009 (32) ve Delphi’deki tanımı ise aşağıdaki gibidir. 1. function EnumDesktops(hwinsta: HWINSTA; lpEnumFunc: TFNDeskTopEnumProc; lParam: LPARAM): BOOL; stdcall; Bu fonksiyonumuzda yine açıklamakta zorlanacağım, henüz tam manası ile hakim olamadığım Window Statiton kavramına bir atıf var. Tanımda gözlemleyebileceğiniz birinci parametrenin tipine dikkat edin: HWINSTA. Yani bir window station tutacağı(handle). Peki Window Station da neyin nesi ? Window Station kendine has bir clipboard’u olan, kendine has global atom tablosu olan, içinde birden fazla masaüstüne sahip olabilen; klavye, mouse ve ekran ile etkileşim kurabildiğiniz bir nevi kapsayıcı güvenlik nesnesi. Bir makina üzerinde birden fazla Window Station olabiliyor. Ama sadece winsta0 olarak adlandırılan birinci Window Station’un interaktiflik özelliği bulunuyor. Bu güvenlik nesnesinin hangi ihtiyaçlara binaen var olduğunu kestirebildiğimi söylesem pek doğru bir kelam etmiş sayılmam. Ancak Terminal server’da her yapılan bağlantının kendi oturumunda(session) bir window station’a sahip olduğunu ve bunun interaktif(kullanıcı ile etkileşimli) olduğunu öğrenmiş bulunuyorum. Bu parametre hakkında ilerleyen zamanlarda kendi öğrenebildiklerim kadarı ile yeni paylaşımlar yapmayı arzuluyorum, ama sanırım bu makalemiz için bu kadarı yeterlidir. Zaten kendisini pek de fazla kullanmayacağız. Biz yine işletim sistemimizde birden fazla olduğunu iddaa ettiğimiz masaüstlerimizin nasıl bulunacağı konusuna yani EnumDesktops‘a geri dönelim isterseniz. Birinci parametresini zor da olsa geçebildiğimiz fonksiyonun ikinci parametresi TFNDeskTopEnumProc türünde ve callback fonksiyon diye adlandırılan bir Bağlantılar Bir Türkçe Sevdalısı.. Delphi Türkiye Forum Gürcan ÖZTÜRK M.Fatih KÜÇÜKKELEPÇE Memik YANIK Kişisel Memik YANIK’ın Günlüğü Nick Hodges Sinan BARAN Zafer Çelenk PDFmyURL.com fonksiyon pointer’dır. Yani bir fonksiyona işaret eden bir işaretçi. Win32 API dökümanında aşağıdaki gibi tanımlanmıştır: 1. 2. 3. 4. BOOL CALLBACK EnumDesktopProc( LPTSTR lpszDesktop, // name of a desktop LPARAM lParam // value specified in EnumDesktops call ); Ziyaretçi Bilgileri Ziyaret: 4 / 12073 Delphi’ye ise aşağıdaki gibi çevireceğiz: 1. function DesktopProc(DesktopName : LPTSTR; Param : LPARAM) : Boolean; stdcall; Metodun Delphi’deki tanımından sizinde gözlemleyebildiğiniz üzere metodun isminin bir önemi yoktur. Yani illa EnumDesktopProc olması lüzumu yoktur. Gerçi okunaklığı arttırmak adına genellikle API yardımındaki isimlendirme notasyonu tercih edilir ancak ben sizin özgür olduğunuzu ifade edebilmek adına farklı bir isimlendirmeye gittim. Üçüncü parametre ise EnumDesktops tarafından DesktopProc’a olduğu gibi geçilecek bir parametredir. EnumDesktops fonksiyonu kısaca, kendisine geçilen ikinci parametredeki DesktopProc fonksiyonunu işletim sistemindeki her desktop nesnesi için bir kere çağıracaktır. Şimdi gelelim bu metodu nasıl kullanacağımıza: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. TDesktop = class private fDesktops : TStrings; public constructor Create; destructor Destroy; override; Beğenilenler Delphi 2010 (Weaver) ve TValue - 14 votes Derinlemesine Threading..(3) - 13 votes Derinlemesine Threading..(2) - 6 votes Derinlemesine Threading..(1) - 6 votes Yeni Veri Tipleri ve Operator Overloading - 4 votes Win32 & .Net(Delphi->C#) - 4 votes Delphi ve Google Maps API - 3 votes TThread.WaitFor Bug.. - 3 votes BITS(Background Intelligent Transfer Service) ile sessiz sedasız download ;) - 3 votes Bir Kiosk ve CreateDesktop macerası.. - 3 votes procedure Refresh; property Desktops : TStrings read fDesktops; end; function DesktopProc(DesktopName : LPTSTR; Param : LPARAM) : Boolean; stdcall; begin TDesktop(Param).Desktops.Add(DesktopName); Result := true; // Burada true döndürmek önemlidir. Desktop arama işleminin devam etmesini sağlar, false döndürülmesi bu metodu çağıran EnumDesktops'un durmasına //ve sonraki desktoplar için DesktopProc'u çağırmamasına neden olur. end; constructor TDesktop.Create; begin Meta Giriş Yazılar RSS Yorumlar RSS WordPress.org Etiketler-Liste PDFmyURL.com 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. inherited Create; fDesktops := TStringList.Create; Refresh; .. .. end; procedure TDesktop.Refresh; begin Desktops.Clear; EnumDesktops(GetProcessWindowStation, @DesktopProc, Integer(Self)); end; .. .. .. procedure TForm1.Button1Click(Sender : TObject); var Desktop : TDesktop; begin Desktop := TDesktop.Create; ListBox1.Items := Desktop.Desktops; // ListBox1 nesnesi TListBox türündedir. Desktop.Free; end; Yukarıdaki kodumuzu çağırdımızda 3 adet desktop’un işletim sistemimizde varsayılan olarak bulunduklarını gözlemleyeceksiniz. Bunlar sırası ile Default, Disconnect ve WinLogon masaüstleridir. Default desktop’u; adından da anlayacağınız gibi hergün kullandığımız masaüstümüzdür. Disconnect desktop’u Terminal server bağlantılarında kullanılan desktop, son olarak da WinLogon desktop’u Win+L, Ctrl+Alt+Del ile geçtimiz kullanıcı girişinin olduğu masaüstümüzdür. Bu masaüstlerinin ilginç ve kısıtlayıcı bazı yanlarından ilerleyen satırlarda bahsedeceğim. Bu arada son verdiğim kod örneğini ileride komple bir sınıf haline getireceğimiz TDesktop sınıfı üzerinden anlatmayı uygun buldum. En son kaldığımız noktada bir desktop create edebilmiştik. Ancak hala o desktop’a geçememiş ve birşeyler görememiştik. Gelin şimdi ekranda görebileceğimiz ve haz duyabileceğimiz desktoplar arası geçişi sağlayan metoda hayat verelim. Bunun için yine bir başka API fonksiyonu olan SwitchDesktop metodunu kullanacağız. Yine herzaman olduğu gibi tanımlarına bir göz gezdirelim: 1. 2. 3. BOOL SwitchDesktop( HDESK hDesktop // handle of desktop to activate ); ve yine herzamanki gibi Delphi tanımımız: 1. function SwitchDesktop(hDesktop: HDESK): BOOL; stdcall; Absolute API Byte Arrays Class Reference COM CreateDesktop CreateProcess CreateRemoteThread CreateToolHelp32SnapShot Function DTS EnumDesktopProc EnumDesktops Pointer GetCurrentProcess GetIconInfo GetKeyState GetLastInputInfo GetProcessMemoryInfo GetStartupInfo Hacking Inheritance Interface JavaScript Method Pointer Module32First Module32Next OpenDesktop Persistance Pointer Procedure Pointer Process Process32First Process32Next RTTI SetProcessWorkingSetSize SQL Server Sw itchDesktop TerminateProcess Reqursion Thread Untyped Parameters VirtualAllocEx WaitForSingleObject VirtualFreeEx WriteProcessMemory Delphi About Auto Select All The Text For TCustomEdit On Mouse Click 29 Haziran 2010 Memory Leak Notification in Delphi - Report Memory Leak on Program Exit 27 Haziran 2010 PCRE Workbench - Regular Expression Test Tool - Source Code Delphi Application 22 Haziran 2010 Deleting Dataset Records In a Loop - Poll Results - Why All Records Are Not Deleted 21 Haziran 2010 Force TListView's Edit Mode using a Keyboard Shortcut 17 Haziran 2010 Implementing On Item Click / Double Click for Delphi's TListView control 16 Haziran 2010 Run Your Delphi Application in Full Screen Implement "F11 - Full Screen" 14 Haziran 2010 PDFmyURL.com Nihayet son derece kısa bir tanıma sahip bir metodumuz oldu. Ancak yine de anlatmakta fayda var kanısındayım. Bu fonksiyon, CreateDesktop yada OpenDesktop API fonksiyonlarından geriye dönen desktop’un tutacağını(handle) kendisine parametre olarak alır ve anında belirtilen masaüstüne geçiş yapar. Bunun bir istisnası, geçiş yapılmak istenilen masaüstünün varsayılan Window Station‘da olmaması durumudur ki bu durumda hata verecektir. Şimdi müsaade ederseniz daha önce tanımına yer verdiğimiz CreateDesktop metodunu ve henüz içeriğini yazmadığımız SwitchDesktop metodunu ilgili sınıfımız TDesktop’a ekleyelim: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. TDesktop = class .. .. procedure CreateDesktop(const Name : String); procedure SwitchDesktop(const Name : String); end; procedure TDesktop.CreateDesktop(const Name : String); var Handle : HDESK; begin Handle := Windows.CreateDesktop(PChar(Name), nil, nil, DF_ALLOWOTHERACCOUNTHOOK, DESKTOP_ALL, nil); if Handle = 0 then raise Exception.Create(Name + ' isimli desktop oluşturulamadı.!'); Desktops.Add(Name); end; procedure TDesktop.SwitchDesktop(const Name : String); var Index : Integer; Handle: HDESK; begin Index := Desktops.IndexOf(Name); if Index = -1 then raise Exception.Create(Name + ' isimli desktop mevcut değil.!'); Handle := OpenDesktop(PChar(Name), DF_ALLOWOTHERACCOUNTHOOK, false, DESKTOP_ALL); if Handle = 0 then raise Exception.Create(Name + ' isimli desktop açılamadı.!'); Windows.SwitchDesktop(Handle); CloseDesktop(Handle); Implement "F11 - Full Screen" 14 Haziran 2010 Displaying Enumerated Properties in a Selectable List - Run-Time Enum Selection in Delphi 10 Haziran 2010 How Do You Delete Dataset Records In a Loop? 08 Haziran 2010 Display Custom Hints for Status Bar Panels 07 Haziran 2010 Sık Ziyaret Edilenler Sayfa: Home (16059) Delphi ve Google Maps API (4132) Delphi ve Google Maps API (1973) Nedir bu Thread’lerden çektiğimiz..! (1444) Delphi & Animated Flash Charts(Fusion Charts) (1174) Delphi & JavaScript Kardeşliği (933) Delphi 2010 (Weaver) ve TValue (918) Derinlemesine Threading..(1) (886) Derinlemesine Threading..(2) (695) Win32 & .Net(Delphi->C#) (617) Kategori: Delphi (613) Bir Kiosk ve CreateDesktop macerası.. (568) Sayfa: Hakkında (563) PDFmyURL.com 34. end; SwitchDesktop metodumuzda öncelikle geçiş yapmak istediğimiz desktop’un var olup olmadığını kontrol ediyor ardından da OpenDesktop metodu vasıtası ile o desktop’un handle’ını elde ediyoruz. Ardından SwitchDesktop’umuzu çalıştırıyoruz ve yeni masaüstümüz karşımızda. Sonrada hafıza kullanımına değer veren bir programcı olduğumuz için OpenDesktop ile hafızada ayırdığımız bir miktar yeri hemen serbest bırakıyoruz. Ancak sakın bu kodu hemen denemeyin. Biraz daha sabır istirham edeceğim sizlerden. Eğer bu kodu hemen bu hali ile denerseniz, benim defalarca yapmış olduğum gibi makinanızı restart etmekten başka bir çareniz kalmaz. İşletim sisteminde oluşturulan her desktop nesnesi kendi etki alanı içinde çalışmaktadır. Diğer desktoplardaki pencerelerle iletişim halinde değildir, onlarla haberleşemez. Alt+Tab çağrılarınız diğer desktop’taki pencereler arasında geçişinizi sağlamaz. Task Manager’ı açma çabalarınız da sonuçsuz kalacaktır. İşletim sisteminin bir bug’u olduğunu düşündüğüm Task Manager’ı açma çabası da aslında karşılıksız kalmaz ama Task Manager maalesef beklediğiniz desktop’da değil Default desktop’ta açılacaktır. Dolayısı ile bu kodu şu hali ile çalıştırmak, makinanızı restart etmeniz gerektiğinin güçlü bir delilidir. Makinamı 7-8 kez restart etmek durumunda kaldıktan sonra TDesktop sınıfına aşağıdaki metodu yazmayı uygun buldum; 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. procedure TDesktop.SwitchDefaultDesktop; var Handle: HDESK; begin Handle := OpenDesktop(PChar('WinSta0\Default'), DF_ALLOWOTHERACCOUNTHOOK, false, DESKTOP_ALL); if Handle = 0 then // Çifte güvenlik. Bazı makinalarda WinSta0\Default isminde olabileceğini okudum, işi şansa bırakmak istemedim. begin Handle := OpenDesktop(PChar('Default'), DF_ALLOWOTHERACCOUNTHOOK, false, DESKTOP_ALL); if Handle = 0 then raise Exception.Create('Default desktop açılamadı.!'); end; Windows.SwitchDesktop(Handle); CloseDesktop(Handle); end; Artık arzu ederseniz ilk denemenizi yapabilirsiniz. Şimdi yazacağımız kod ile restart yapmak zorunda kalmayacaksınız. Buyurun bunca uğraşının sonunda artık desktop’umuzu görelim: 01. 02. 03. 04. 05. 06. 07. procedure TForm1.Button1Click(Sender : TObject); var Desktop : TDesktop; begin Desktop := TDesktop.Create; Desktop.CreateDesktop('Deneme'); Desktop.SwitchDesktop('Deneme'); (563) TThread.WaitFor Bug.. (540) Delphi 2010 (Weaver) ve TValue (530) Oylama.. Sitedeki makaleleri yararlı buluyor musunuz ? Evet, yararlı ama yetersiz. Evet, son derece yararlı. Evet, mükemmel. Hayır, yararlı değil. Hayır, hem yararlı değil, hem de yetersiz. Hayır, rezalet. Vote View Results Delphi'nin hangi sürümünü kullanıyorsunuz ? Delphi 5 yada öncesi Delphi 6 Delphi 7 Delphi 8 Delphi 2005 Delphi 2006 Delphi 2007 PDFmyURL.com 08. 09. 10. 11. Sleep(25000); // 25 sn bekle.. Desktop.SwitchDefaultDesktop; Desktop.Free; end; Kodumuz Deneme isminde bir masaüstü oluşturacak ve ona geçiş yapacak, ardından 25 saniye boyunca siz desktopunuza bakarken varsayılan masaüstünüze geri döneceksiniz. Sizlerin de farkettiği gibi yeni oluşturduğumuz masaüstümüzde hiçbir şey yoktur. Ne masaüstü resmi, ne başlat menüsü, ne masaüstü simgeleri, ne de taskbar. Uygulamamızda orada değil. Şu hali ile bu masaüstü bizim hiç bir işimize yaramıyor. Bizim; yazacağımız uygulamaları yeni desktop’ta çalıştırabilmeye kesinlikle ihtiyacımız var. Aksi taktirde bunca anlatılanın hiç bir ehemmiyeti olmazdı. Arzu ederseniz onu da yapalım. İstediğimiz herhangi bir uygulamayı diğer bir masaüstünde çalıştırabilmek için CreateProcess isimli API metoduna gereksinimimiz olacak. Buyrun tanımına bakalım: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 1. 2. 3. 4. 5. Delphi 2009 Delphi 2010 Vote View Results BOOL CreateProcess( LPCTSTR lpApplicationName, // pointer to name of executable module LPTSTR lpCommandLine, // pointer to command line string LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security attributes LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security attributes BOOL bInheritHandles, // handle inheritance flag DWORD dwCreationFlags, // creation flags LPVOID lpEnvironment, // pointer to new environment block LPCTSTR lpCurrentDirectory, // pointer to current directory name LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATION ); function CreateProcess(lpApplicationName: PChar; lpCommandLine: PChar; lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo; var lpProcessInformation: TProcessInformation): BOOL; stdcall; Görüldüğü gibi pek çok parametresi var. Ben bunlardan birkaçına değinip diğerlerini araştırmayı siz değerli okuyucularıma bırakacağım. Bu parametrelerden en önemlisi lpCommandLine isimli olan peremetredir. Bu parametre çalıştırmak istediğimiz dosyanın path bilgisini yazacağımız yerdir. İkinci ve en can alıcı parametremiz ise lpStartupInfo isimli parametredir. Bu parametre PDFmyURL.com üzerinde biraz durmamız gerekiyor. Herzamanki gibi TStartupInfo türünde olan parametremizin tanımına bir göz gezdirelim: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. _STARTUPINFOA = record cb: DWORD; lpReserved: Pointer; lpDesktop: Pointer; lpTitle: Pointer; dwX: DWORD; dwY: DWORD; dwXSize: DWORD; dwYSize: DWORD; dwXCountChars: DWORD; dwYCountChars: DWORD; dwFillAttribute: DWORD; dwFlags: DWORD; wShowWindow: Word; cbReserved2: Word; lpReserved2: PByte; hStdInput: THandle; hStdOutput: THandle; hStdError: THandle; end; TStartupInfo = _STARTUPINFOA; Gördüğünüz gibi bu bir record. Bu record’un içerisinde uygulamız için hayati derecede öneme sahip olan bir parametre mevcut. O da; pointer türünde tanımlanmış olan lpDesktop. İşte bu bizim desktopumuzun adını geçeceğimiz yerden başkası değil. Bir diğer önemli parametre ise DWord tipli cb isimli parametredir. Bu parametreye de SizeOf(TStartupInfo) gibi bir atama yapacağız. Dilerseniz herhangi bir masaüstünde herhangi bir uygulamanın çalıştırılması becerisine haiz metodumuzu da sınıfımıza ekleyelim: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. procedure TDesktop.ExecuteProgram(const Desktop, ExeName: String); var Index : Integer; StartupInfo : TStartupInfo; ProcessInfo : TProcessInformation; begin Index := Desktops.IndexOf(Desktop); if Index = -1 then raise Exception.Create(Desktop + ' isimli desktop mevcut değil.!'); if not FileExists(ExeName) then raise Exception.Create(ExeName + ' isimli dosya mevcut değil.!'); PDFmyURL.com 14. 15. 16. 17. 18. 19. 20. 21. FillChar(StartupInfo, SizeOf(TStartupInfo), 0); // Recordun içeriğini temizliyoruz.. StartupInfo.cb := SizeOf(TStartupInfo); StartupInfo.lpDesktop := PChar(Desktop); // PChar da bir pointer tipidir. if not CreateProcess(nil, PChar(ExeName), nil, nil, false, NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo) then raise Exception.Create(ExeName + ' isimli uygulama ' + #13#10 + Desktop + ' isimli masaüstünde çalıştırılamadı.!'); end; Şimdi bir önceki örneğimize geri dönelim ve o anda çalışan uygulamamızı diğer masaüstünde de çalıştıralım: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. procedure TForm1.Button1Click(Sender : TObject); var Desktop : TDesktop; begin Desktop := TDesktop.Create; Desktop.CreateDesktop('Deneme'); Desktop.SwitchDesktop('Deneme'); Desktop.ExecuteProgram('Deneme', Application.ExeName); Sleep(25000); // 25 sn bekle.. Desktop.SwitchDefaultDesktop; Desktop.Free; end; Bu kodu deneyince göreceğiniz gibi, yeni bir masaüstünüz olacak ve çalışan uygulamanızın bir kopyası da diğer masaüstünde hazır halde sizi bekliyor olacaktır. Buraya kadar herşey sorunsuz(7-8 defa restart etmeyi saymaz isek) gitti. Herhangi bir mâni ile karşılaşmadık. Bundan sonra tercihlerinize göre yine karşılaşmayabilirsiniz. Ama sizlerde benim gibi hafıza kullanımı konusunda son derece titizseniz o zaman sizleri bazı sorunlar bekliyor. Benim bu makaleyi yazmaktan imtina ettiğim sorunlar. Herne kadar o sorunların hepsini aşsam da izahı son derece zor hususlar. Ancak yine de elimden geldiğince dilim döndüğünce izaha gayret edeyim. Nedir bu sorunlar diye iyice meraklanmış olabilirsiniz. Sizleri daha fazla merakta bırakmadan anlatayım. Şimdi bir senaryo üzerinden hareket edelim. Bu senaryoda yeni oluşturduğumuz masaüstümüzde başlat menüsünü, masaüstü simgelerini ve görev çubuğunu görmek istediğimizi düşünelim. O zaman daha evvel yazdığımız ExecuteProgram metodumuz ile explorer.exe‘nin de ilgili masaüstünde çalıştırılması gerekecektir. Bunu yapmamız kolay, ancak sorun çalıştırmış olduğumuz explorer.exe’nin sonlandırılması sırasında ortaya çıkacak. Zaten varsayılan masaüstümüzde çalışan bir explorer.exe’miz vardı, şimdi ikinci masaüstünde çalışan bir tane daha oldu ve biz hafızayı iktisatlı kullanmak PDFmyURL.com istiyoruz. Dolayısı ile ikinci masaüstü için çalıştırdığımız explorer.exe’nin sonlandırılması gerekli. Bu problem aklımıza daha önce kullanımını anlattığımız TStartupInfo yapısını getiriyor ve araştırmalara başlıyoruz. Acaba çalışan uygulamalardan elde edebileceğimiz TStarupInfo gibi bir yapı var mı ? Bu bağlamda API help’te dolaşırken GetStartupInfo gibi bir metoda rastlıyoruz. Tanımı aşağıdaki gibidir: 1. 2. 3. 1. VOID GetStartupInfo( LPSTARTUPINFO lpStartupInfo structure ); // address of STARTUPINFO procedure GetStartupInfo(var lpStartupInfo: TStartupInfo); stdcall; Ancak incelemelerimiz bu metodun o anda çalışan uygulamanın bilgilerini döndüreceğini söylüyor. Oysaki bizim explorer.exe’nin bilgilerine ihtiyacımız vardı.! İşte bu noktada aslında bir başka makalenin konusu olabilecek kadar derin bir araştırma ve ayrıma gitmemiz gerekiyor. Uzunca bir müddet düşündükten sonra, sonlandırmak istediğimiz explorer.exe’nin hangisi olduğuna karar verilemediği için hafızada çalışır halde bulunan her iki uygulamaya da bulaşan bir dll yazmaya karar verdim. Bu DLL ilgili exe’lere bulaştıktan sonra GetStartupInfo metodunu o exe içinde çalıştırmalı ve sonucu explorer.exe’yi çalıştıran uygulamaya yada diğer masaüstünde hali hazırda çalışan uygulamamızın kopyasına göndermeliydi. Hafızada çalışan uygulamaya bulaşan kodu uzunca bir araştırma sürecinden sonra mantığı ile anlayıp kodlamıştım ancak bu sefer de bulaşan DLL’in bulaştığı kaynaktan silinmesi gerekiyordu. PDFmyURL.com Bu sorun da aşıldıktan sonra, artık hafızaki istediğimiz herhangi bir uygulamaya yüklenebilen ve tekrar silinebilen bir mekanizmaya sahiptik. Artık bu mekanizma bize bulaştığı uygulamaların içinde GetStartupInfo metodundan elde ettiği değerli desktop name bilgisini döndürebilirdi. Bir DLL ile bir EXE’nin birbirleri arasında haberleşme birden fazla yöntem ile sağlanabilir. Bu tarz işlemlere genellikle Interprocess Comminication (IPC) adı verilir. Hafızada paylaşılan bir alana yazılan veriler diğer uygulama tarafından görünür kılınabilir, yada daha basit bir yöntem ile DLL ile EXE arasında mesajlaşma API’leri vasıtası ile(SendMessage, PostMessage) haberleşilebilir. Ancak burada kesinlikle unutulmaması gereken bir şeyi daha önce söylediğim halde yeniden ifade etmekte yarar görüyorum. Birbirinden farklı desktoplardaki uygulamalar, birbirleri ile bu şekillerde kesinlikle haberleşemezler. Bu durum hasıl olduğunda socket haberleşmesi daha genel ve etkin bir çözüm olabilir. Bu vesile ile bende iletişim yöntemi olarak socket haberleşmesini tercih ettim. Böylece hangi desktop’ta olduğunuzdan bağımsız olarak sistemin hatasız çalışmasını garanti altına almış olduk. Sorun üzerinde bunca dönüp dolaştıktan sonra birazda çözüme doğru yol alalım.Şimdi yapmamız gereken 3 şey var. Çalışan uygulamalara bulaşan bir kod yazmak. Çalışan uygulamalara bulaşan kodun temizlik kodunu yazmak Sonlandırmak istediğimiz process’in bulunmasına müteakip çalışacak sonlandırma kodunu yazmak. Sırası ile hepsini yazalım: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. procedure InjectProcess(const RemoteProcessID : Cardinal; const DLLName : String); var RemoteProcessHandle, BytesWritten, ThreadID, RemoteThreadHandle : Cardinal; pDLL : Pointer; begin if not FileExists(DLLName) then raise Exception.Create(InttoStr(RemoteProcessID) + '->' + DLLName + ' bulunamadı.!'); PDFmyURL.com 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. RemoteProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, false, RemoteProcessID); if RemoteProcessHandle <> 0 then begin pDLL := VirtualAllocEx(RemoteProcessHandle, nil, Length(DLLName), MEM_COMMIT, PAGE_EXECUTE_READWRITE); if Assigned(pDLL) then if WriteProcessMemory(RemoteProcessHandle, pDLL, PChar(DLLName), Length(DLLName), BytesWritten) then begin RemoteThreadHandle := CreateRemoteThread(RemoteProcessHandle, nil, 0, GetProcAddress(GetModuleHandle('kernel32.dll'), 'LoadLibraryA'), pDLL, 0, ThreadID); if RemoteThreadHandle <> 0 then begin WaitForSingleObject(RemoteThreadHandle, 2000); CloseHandle(RemoteThreadHandle); end; end; end; // if RemoteProcessHandle <> 0 then if Assigned(pDLL) then VirtualFreeEx(RemoteProcessHandle, pDLL, 0, MEM_RELEASE ); CloseHandle(RemoteProcessHandle); end; Şimdi sıra temizlik kodunda: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. procedure CleanProcess(const RemoteProcessID : Cardinal; const DLLName : String); var SnapshotHandle, RemoteProcessHandle, RemoteThreadHandle, ThreadID : Cardinal; meCurrent : TModuleEntry32; found : Boolean; Module: String; begin if not FileExists(DLLName) then raise Exception.Create(InttoStr(RemoteProcessID) + '->' + DLLName + ' bulunamadı.!'); PDFmyURL.com 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. SnapshotHandle := CreateToolHelp32SnapShot(TH32CS_SNAPMODULE, RemoteProcessID); meCurrent.dwSize := SizeOf(TModuleEntry32); Module32First(SnapshotHandle, meCurrent); found := false; while 1 <> 2 do begin Module := meCurrent.szExePath; if LowerCase(Module) = LowerCase(DLLName) then begin found := true; Break; end; if not Module32Next(SnapshotHandle, meCurrent) then Break; end; if not found then begin CloseHandle(SnapshotHandle); raise Exception.Create('Remote uygulamada istenilen modül bulunamadı.!'); end; RemoteProcessHandle := OpenProcess(PROCESS_ALL_ACCESS, false, RemoteProcessID); if RemoteProcessHandle <> 0 then begin RemoteThreadHandle := CreateRemoteThread(RemoteProcessHandle, nil, 0, GetProcAddress(GetModuleHandle('kernel32.dll'), 'FreeLibrary'), meCurrent.modBaseAddr, 0, ThreadID); if RemoteThreadHandle <> 0 then begin WaitForSingleObject(RemoteThreadHandle, 2000); CloseHandle(RemoteThreadHandle); end; end; CloseHandle(RemoteProcessHandle); CloseHandle(SnapshotHandle); end; Ve nihayet bulunan process’in yok edilmesini sağlayan metodumuz: PDFmyURL.com 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. procedure KillProcess(const ProcessID : Cardinal); var ProcessHandle : Cardinal; begin if ProcessId <> 0 then begin ProcessHandle := OpenProcess(PROCESS_TERMINATE, false, ProcessID); if ProcessHandle <> 0 then begin try TerminateProcess(ProcessHandle, 0); finally CloseHandle(ProcessHandle); end; end; end; end; Daha fazla ilerlemeden önce ne yaptığımız hakkında az çok malümat vermeye çalışalım. Bulaşma kodunda, öncelikle bulaşacağımız process’i OpenProcess ile açıyoruz. Böylelikle bulaşacağımız process’in handle’ını elde etmiş oluyoruz. Hemen ardından VirtualAllocEx ile o process’in kullandığı hafıza bloğunda DLL’imizin path’i ile birlikte adının sığabileceği kadar bir hafıza tahsis ediyoruz. Bu tahsisattan geriye dönen pointer ayrılmış hafıza bölgesini işaret ediyor.Daha sonra WriteProcessMemory ile bulaşacağımız exe’nin ayrılmış olan hafıza bölgesine DLL’imizin adını yazıyoruz. Ve en can alıcı kısım olan CreateRemoteThread metodu vasıtası ile DLL’imizi çalıştırıyoruz. CreateRemoteThread belirtilen process’in belirtilen hafıza bölgesindeki değeri parametre alarak belirtilen metodu çalıştırmakla yükümlüdür. Yani bizim örneğimizde pDLL isimli hafıza bölgesini(ki içinde DLL’imizin adı var) LoadLibraryA metoduna parametre olarak geçecek. Bildiğiniz gibi LoadLibraryA DLL kütüphanelerimizi dinamik olarak yüklemek için kullandığımız Windows API metodudur. Bulaşma işleminin temelinde bu mekanizma yatmaktadır. İlk bakışta karmaşık görünse de , anlamaya çalışarak ilerlediğinizde o derece zor ve karmaşık olmadığını göreceksiniz. Yükleme kodunun tam zıttı olan kodun beni biraz daha uğraştırdığını itiraf etmeliyim. Bu kodda processler içindeki modüllerin hepsini dolaşmak ve kendi modülünüzü(yani DLL’inizi) bulmak ve ardından yine CreateRemoteThread API’sine bu sefer FreeLibrary metodunu geçerek temizlik işlemini yapmanız gerekiyor. Sizlerinde farkedeceği gibi, DLL’imizin yüklenmesi sırasında çalışan bazı kodlar var ve biz henüz bu kodların neye benzedikleri hakkında fikir sahibi değiliz. Arzu ederseniz biraz da DLL’imizin kodlarına göz gezdirelim: 01. 02. 03. 04. 05. 06. 07. library RemoteDLL; uses SysUtils, Classes, Windows, Dialogs, PDFmyURL.com 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. Messages, IdTcpClient; {$R *.res} const LogFile = 'c:\CreateRemoteThread.txt'; procedure Log(const Message : String); begin with TStringList.Create do begin if FileExists(LogFile) then LoadFromFile(LogFile); Add(Message); SaveToFile(LogFile); Free; end; end; procedure EntryPointProc(Reason : Integer); var si : TStartupInfo; p : PChar; str: String; client : TIdTCPClient; begin case Reason of DLL_PROCESS_ATTACH: //1 begin FillChar(si, SizeOf(TStartupInfo), 0); si.cb := SizeOf(TStartupInfo); GetStartupInfo(si); p := si.lpDesktop; str := p; try client := TIdTCPClient.Create(nil); try client.Host := '127.0.0.1'; client.Port := 9999; client.Connect(); client.WriteLn(str + ',' + InttoStr(GetCurrentProcessId())); client.Disconnect; except on E: Exception do Log('Connection Problem:' + E.Message); end; finally client.Disconnect; client.Free; PDFmyURL.com 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. end; Log('DLL_PROCESS_ATTACH:' + str + '/' + TimeToStr(Time) + '/' + InttoStr(GetCurrentProcessId())); end; DLL_THREAD_ATTACH: //2 begin end; DLL_PROCESS_DETACH: //3 begin Log('DLL_PROCESS_DETACH:' + TimeToStr(Time)); end; DLL_THREAD_DETACH: //0 begin end; end; end; begin DLLProc := @EntryPointProc; DLLProc(DLL_PROCESS_ATTACH); end. Görüldüğü gibi DLL’imiz hafızaya yüklenir yüklenmez DLL_PROCESS_ATTACH bölümüne gidiyor ve bir socket bağlantısı vasıtası ile gönderilmesi gereken mesajı gönderiyor. Şimdi sıra TDesktop sınıfımızın CloseRunningProcesses isimli metodunu yazmaya geldi. Buyurun onu da yazıp makalemizin sonlarına doğru ilerleyelim: 01. 02. 03. 04. 05. 06. 07. 08. 09. 10. 11. 12. 13. 14. 15. 16. 17. 18. procedure TDesktop.CloseRunningProcesses(const Desktop: String; Processes: array of String; const InjectDLLFile : String); var Index, iCounter : Integer; ProcessName : String; ProcessList : TStrings; peCurrent : TProcessEntry32; SnapshotHandle : Cardinal; TCPServer : TIdTCPServer; pItem : TProcessItem; begin Index := Desktops.IndexOf(Desktop); if Index = -1 then raise Exception.Create(Desktop + ' isimli desktop mevcut değil.!'); ProcessList := TStringList.Create; PDFmyURL.com 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. TCPServer := TIdTCPServer.Create(nil); try TCPServer.Bindings.Clear; with TCPServer.Bindings.Add do begin IP := '127.0.0.1'; Port := 9999; end; TCPServer.OnExecute := TCPServerExecuteEvent; TCPServer.Active := true; for iCounter := Low(Processes) to High(Processes) do begin ProcessName := Processes[iCounter]; ProcessName := ExtractFileName(ProcessName); // Path şeklinde olmamalı.. ProcessList.Add(ProcessName); end; InjectCount := 0; SnapshotHandle := CreateToolHelp32SnapShot(TH32CS_SNAPPROCESS, 0); peCurrent.dwSize := SizeOf(TProcessEntry32); Process32First(SnapshotHandle, peCurrent); while 1 <> 2 do begin ProcessName := peCurrent.szExeFile; if ProcessList.IndexOf(ProcessName) <> -1 then begin Inc(InjectCount); InjectProcess(peCurrent.th32ProcessID, InjectDLLFile); // Load &amp;amp;amp;amp;amp; Execute DLL CleanProcess (peCurrent.th32ProcessID, InjectDLLFile); // UnLoad DLL end; if not Process32Next(SnapshotHandle, peCurrent) then Break; end; while InjectCount > 0 do Application.ProcessMessages; for iCounter := 0 to KillProcessList.Count - 1 do begin try pItem := TProcessItem(KillProcessList[iCounter]); if pItem <> nil then PDFmyURL.com 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. if pItem.Name = Desktop then KillProcess(pItem.Handle); except end; end; finally ProcessList.Free; TCPServer.Active := false; TCPServer.OnExecute := nil; TCPServer.Free; end; CloseHandle(SnapshotHandle); end; Geriye kalan kodlar pek de ehemmiyetli kodlar değil, çeşitli kontroller, silinmesi istenilen uygulamaların listesini tutan burada anlatmaya değer olmayan kod parçacıkları. Bu sebeple onları anlatma gereği duymuyorum. Ancak kodları daha rahat ve bir bütün halinde inceleyebilmeniz adına ilgili sınıfın pas dosyasını da buraya koyuyorum. Çok uzun bir makale oldu gerçekten, sabırla okuyabilenlere teşekkür ederim. Saygılar, sevgiler.. Not: CleanProcess metodunu explorer.exe ve diğer şüphelendiğiniz processler için çalıştırabilirsiniz. Benim explorer.exe ile ilgili testlerim sırasında FlashGet programının bir DLL’inin explorer.exe içerisinde yüklü olduğunu gördüm. Bu normal mi değil mi tam emin olmamakla birlikte yine de şüphe çekici.. [Translate] 17 Comments Özkan Danacı on Mayıs 22nd, 2009 Okuyorum.. Okuyorum.. hala Okuyorum.. PDFmyURL.com Tuğrul HELVACI on Mayıs 22nd, 2009 Olcay DAĞLI on Mayıs 23rd, 2009 Sanırım biraz uzun yazmışım Uzun uğraşılar sonucu elde etmiş olduğun böylesi bir bilgiyi daha zor ve uzun bir uğraşı ile yazıya döküp anlatabildiğin için tebrik ederim hocam… Yanlız bir şey belirteyim makale o kadar uzun gelmiyor okuyunca, zira gayet akıcı yazmışsın, eline sağlık hocam Veli BOZATLI on Haziran 1st, 2009 Tuğrul HELVACI Sanal alemde gerçekten böyle yararlı ve değerli (araştırılması, oluşturulması, yazılması vs. zor) bilgileri paylaşan kişilerin olduğunu görmek beni çok mutlu ediyor. Elimizden sadece bir kuru teşekkür etmek geliyor : Hiçbir karşılık beklemeksizin bilgilerini paylaşanlardan Allah razı olsun… Allah, “Allah razı olsun” diyenden de demiyenden de razı olsun.. on Haziran 1st, 2009 Numan on Haziran 26th, 2009 M akaleyi henüz okumadım ama hemen teşekkür etmek istedim. Ben Delphi de yeniyim, CreateDesktop olayını visual basic de kullanıyordum, ancak bunu Delphi ye bir çırpıda dönüştürmek şu an benim için çok zor bir olaydı. Bu makaleyi henüz okumadım ancak olayı bildiğimden dolayı bunun bana çok faydalı olacağından emin gibiyim, şimdiden teşekkürler aro. PDFmyURL.com Tuğrul HELVACI Allah cümlemizden razı olsun. on Haziran 26th, 2009 Soylu OItu KAYA on Ağustos 1st, 2009 Açıkcası çok güzel açıklamalar ve farklı bir yaklaşım. Programlama konusunda bu tarz makaleleri okurken bazen bir satırın açıklamasını gördüğümde o satırdaki komutun araştırmasına giriyorum ve bir bakıyorum 6 gün geçmiş ve ben o satırlardaki tüm komutları en detaylı şekilde öğrenmişim. Tabiki bunu kendi yazılımıma adapte etme aşamasına gelince iş biraz farklılaşıyor kendi yazılımımda 5 satır kodu kullanıyorum öğrendiğim 500 sayfa açıklama gereksiz kalıyor Biraz düşündüm ve dedim ki kendi kendime bu arkadaş bu kadar yazmış bunun proje dosyasını yada pas dosyasını niye koymamış sonralarda fark ettim ki en altta 1 satırcık yere ” ilgili sınıfın pas dosyasını da buraya koyuyorum.” ibaresi ile pas dosyasını koymuş tebrikler. Proje dosyalarından inceleme yapmak bazen çok daha seri oluyor. Her komuta her yerde ihtiyaç olmayabiliyor. Çalışmalarında başarılar. Bora ÇAYIR on Ağustos 28th, 2009 İsmail Aktaş (SHURZAN) on Ekim 24th, 2009 Delphiyle ilgili hereşeye varım siteyi bugün keşfettim konular guzel M erhaba Tuğrul, Yazmış olduğun makleyi ve bu sayfanı, Kendi projemde geliştimek istediğim bir çalışmaya ait başka bir win32 API hakkında bilgi ararken rastgeldim, doğrusu konuya hakim ve akıcı bir uslupta ayrıntılara girmişsin ki çok başarılı eline sağlık. Ben C++ yazılım dilinde BDS 2006 ortamında proje geliştiriyorum. Her ne kadar Delphi’ci değilsem de okuyabiliyorum. PDFmyURL.com Windows XP için çeşitili ayar ve düzenlemeler yapan Shurzanop 2.0 için makalenizde geçen çalışmayı da uygulamak istiyorum. Eğer bir mahsuru yoksa kodlamayı C++ dili ile geliştirip kullanacağım. Bu makaleniz için teşekkürler, başka makalelerde bekliyoruz. Tuğrul HELVACI on Ekim 26th, 2009 mkysoft M erhaba İsmail bey, elbette gönlünüzce kullanabilirsiniz. Çalışmalarınızda başarılar dilerim. Çok güzel bir makale olmuş, teşekkür ederim. on Ekim 31st, 2009 mesut on Mart 11th, 2010 Tuğrul HELVACI on Mart 16th, 2010 hocam çok teşekkür ederim çok güzle bir makale olmuş. benim ufak bir sorum var . ben TM emoryStream nesnesi ile şifrelediğim bir dosyayı ram da çalıştırmak istiyorum yani bir yere kopyalanıp oradan çalışmasını istemiyorum.şifrelenmiş dosyayı direk çalıştıracak. makalenizde writeproccesmemory komutunu ksıa analtmışsınız acaba bu komutu kulalnarak direk ram da çalıştırabilirmiyim veya hangi kodu kullanmalıyım teşekkür ederim.. ayrıetten msn desteğiniz olursa sevinirim. M esut bey, WriteProcessM emory ile ilgili daha detaylı bilgi paylaşımı virüs ve trojan yapımcılarının işine yarar ve onların ilgi alanıdır genellikle. Zaten konuyu izah edebilmek adına biraz da olsa zararlı olabilecek içeriklere girdik, daha detaylarına girmeyelim PDFmyURL.com Mehmet Erdem Korkmaz Güzel bir çalışma olmuş. Emeğine sağlık. Bana yol gösterici olmasına rağmen hala yapmayı başaramadığım bir meseleyi sormak isterim. on Mart 17th, 2010 Benim yapmak istediğim şey winlogon ekranına geçilse bile o ekranın görüntüsünü alabilmek. Bunu bir türlü başaramadım. MURAT on Haziran 7th, 2010 Tuğrul HELVACI Helal olsun kardeş, Harika olmuş baya uğraşmıssın eline sağlık. Teşekkür ederim, sağolun. on Haziran 7th, 2010 Share your comment Name (required) Mail (required) Website PDFmyURL.com Son Yorumlar Yeni Eklenenler Linkler Yorumunuza teşekkürler. Aslında operatör aşırı yüklemenin sınıflarda pek bir avantaj... by Tuğrul HELVACI Yeni Veri Tipleri ve Operator Overloading Bir Türkçe Sevdalısı.. - Taha EKREM Interface Nedir, Nerelerde ve Neden Kullanırız ? Delphi Türkiye Forum Merhaba, Ben ilk olarak merakımdan dolayı uğraştığım C++ dilinde görmüştüm Operatör... by Zafer Çelenk Derinlemesine Threading..(3) Gürcan ÖZTÜRK - Gürcan ÖZTÜRK SQL’de Benzerlik Algoritmaları… M.Fatih KÜÇÜKKELEPÇE Full Text Searching… Memik YANIK Kişisel Delphi 2010 (Weaver) ve TValue Memik YANIK’ın Günlüğü Derinlemesine Threading..(2) Nick Hodges Merhaba, makaleyi yazdığım zaman kodlarda bir sorun yoktu. Belki Google Maps'de bir şeyler... by Tuğrul HELVACI Merhaba Kodlarda bir sorun mu var? yoksa ggogle bu hizmeti durdurdu mu? Sadece boş bir... by ahmet Programcı arkadaşların daha fazla takıldığı bir yerde yazsa idiniz mesajınızı daha... by Tuğrul HELVACI Sinan BARAN Tuğrul Bey Yeri Burasımıdır Bilmiyorum O nedenle hata ediyorsam özür dilerm bir iş ilanı... by geyikben Teşekkürler ;) by Tuğrul HELVACI Copyright © 2009 Delphi Programming Pow ered by WordPress | Increase Traffic w ith TrafficWhirl. PDFmyURL.com
Benzer belgeler
Her türlü veritipini kıyaslamak için.. | Delphi Programming
kadar uğraşmaya..” Doğru haklısınız, peki o zaman örneklere devam edelim
İndirmek için tıklayın
Window Station da neyin nesi ? Window Station kendine has bir clipboard’u olan, kendine has
global atom tablosu olan, içinde birden fazla masaüstüne sahip olabilen; klavye, mouse ve
ekran ile etkil...