Gizli Desktoplar

Bu başlık kilitlidir. Yeni mesajlar gönderilemez veya mevcut mesajlar düzenlenemez.
Banned
06-11-2004, 00:24   |  #1  
OP Banlandı
Teşekkür Sayısı: 0
366 mesaj
Kayıt Tarihi:Kayıt: Kas 2004

Ön Şart : Win32, Visual C++

Keywords : Private Desktop

Telif : Yazının ingilizce ve daha komplex halini : Dr Dobb’s Journal Ocak 2003 sayısında bulabilirsiniz.

Not : Yazıda geçen Windows 2000 işletim sistemi ile W2k uyumlu tüm işletim sistemleri kastedilmiştir : W2k, WinXp, Win2003 vs.

Bundan 3 yıl kadar önce, linux u bilgisayarıma kurup denemek istemiştim. Daha öncesinde sıkı bir Windows NT kullanıcı olarak ilk dikkatimi çeken nokta, görev çubuğunda bulunan, şu an sayısını hatırlamadığım dikdörtgen şekillerdi. Bunları her tıkladığımda yeni bir desktop alanına geçiyordu. Ne işe yarar anlamamıştım ama epey eğlenceli gelmişti. Bir ekranda işteyken kaytarmak amacıyla çeşitli web siteleri açılabilir, diğer ekranda ise, o an işle ilgili ekranlar açılabilir, ve ani bir baskında bunlar hemen değiştirilebilirdi.

Acaba Windows işletim sistemlerinde böyle birşey varmı ?

Windows 2000 ve sonrasında var diyebiliriz. ( aslında öncesinde de vardı ama hiç oralara girmeyelim, Win 9X ve Me yoktu  )

Yani birden fazla desktop alanı yaratip, her desktopta, ilgili bir programı koşturup, bunlar arasında gidip gelebiliriz.

Peki nasıl yaparız bu işlemi ? Tehlikeleri nelerdir ? Desktop mu o nedir ?

Öncelikle ne işe yarar ? Bir kiosk uygulamasında oldukça işe yarar. Desktop alanında sadece sizin çalıştıracağınız uygulamar gözükür. Bomboş bir desktop ve full-screen çalışan bir internet explorer ile, güzel bir kiosk uygulaması yazılabilir.

Desktop nedir ?
Desktop aslında bir penceredir. Diğer tüm penceleri de kapsayan bir penceredir. Küme işlemlerinde hatırlarsanız, kendisini evrensel küme olarak tanımlayabilirsiniz.

( Win32 bilenlere not : Hatta, GetDC(NULL) derseniz, desktopun handle değerini alarak, tüm işlemlerinizi desktop üzerinde yapabilirsiniz )

Fakat farklı olan durum, birden fazla evrensel kümeniz olabilir J sadece aynı anda bir tanesi ekranda gösterilebilir. Diğer desktoplar arka alanda gizli ( yazımızın başlığı J ) olarak dururlar.

Tipik olarak Windows 2000 açıldığında, hali hazırda 3 adet desktop yaratılır.

Winlogon alanı : Ctrl+Alt+Del tuşlarına bastığınızda veya konfigurasyonunuza göre açılışta hemen gözüken alandır.  Dikkat ederseniz bu desktopta arka alan boştur, önde ise Windows Security isminde bir dialog penceresi bulunur.
Varsayılan alan : sisteme giriş yaptığınızda gördüğünüz alandır. Görev çubuğu, ağ komşuları, bilgisayarım, çöp kutusunu falan görürsünüz. Genelde tüm uygulamarda bu alanda çalışır.
Terminal servisleri için açılan ekran ki yazımızda hiç değinmeyeceğiz.

Bir uygulama yazarken, yazdığınız uygulamanın varsayılan alanda çalıştığını varsaymamanız gerekmektedir. Başka bir uygulama, yeni bir desktop alanı açıp, sizin uygulamanızı orada çalıştırabilir.  Ama illaki varsayılan alanda çalışacak benim uygulamam diyorsanız , OpenDesktop apisi ile varsayılan alanı açmalısınız. Buna ilişkin örneği ileride göreceğiz.

Yeni bir desktop açmak için CreateDesktop(), desktoplar arası geçiş için SwitchDesktop() kullanmalısınız.  Bunlara ait örnekleri daha sonra göreceğiz.

CreateDesktop apisini kullanırken, yaratacağınız desktop a bir isim verirsiniz. Dikkat etmeniz gereken nokta, bu ismin “Default”,”Winlogon”,”Disconnect” olmamasıdır. Bunlar zaten yukarıda bahsedildiği gibi kullanılmaktadır. Dikkat etmeniz gereken başka bir nokta ise, verdiğiniz ismin, sistem bazında global olmasıdır. Yani başka bir uygulamada aynı ismi verirse karışıklık çıkacaktır . Yani bir uygulama bir desktop yaratırken, diğer bir uygulamada sadece ilk başta verilen ismi kullanarak o desktop alanını açıp kullanabilir. Tabii Winnt ve üstündeki tüm işletim sistemlerinde desktelenen security özellikleri ile bu engellenebilir, yani desktop u sadece yaratan kullanabilir.

Eğer yaratılan bir desktopu hiçbir process kullanmazsa, bu desktop yok edilir.  Fakat, bir process desktop yarattıktan sonra , hiçbir işlem yapmasada, desktop var olmayı sürdürür, çünkü, process bir thread yarattığında, thread , o desktopu kullanacaktır. Bu sebepten dolayı, desktop ile işimiz bittiğinde CloseDesktop() apisini kullanmalıyız.

Bu arada, o anda aktif olan desktopu anlamak için GetThreadDesktop() apisini kullanmalısınız.

Hep laf hep laf J şimdi bir örnek yapalım ama örnek öncesi son kez kullanacağımız apileri parametreleri ile inceleyelim.

·        HDESK GetThreadDesktop(DWORD dwThreadID) dwThreadID ile id numarasını verdiğiniz thread’in, aktik olan desktop’unun handle numarasını döner. O anda aktif olaran thread’in id numarasını ise GetCurrentThreadId ile alabilirsiniz.Hata olursa handle değeri olarak sistem NULL döner.

·        Void OpenInputDesktop(DWORD dwFlags,BOOL bInherit,ACCESS_MASK acess)

Bu api o anda giriş için kullanılan desktopu açar. Dikkat edilmesi gereken bir nokta, çıkış desktopu ile giriş desktopu farklı olabilir. Biz bu api ile giriş desktopunu aktif hale getiriyoruz. Parametreleri inceleyelim : dwFlags , sıfır olarak girebilirsiniz, alabileceği diğer parametre oldukça alt seviye bir programlama içindir.  BInherit değeri, bir başka process’in desktopun handle değerini kullanıp kullanmayacağını belirdir. Aslında bu security ile ilgili kısım ( nerdeyse çoğu apide göreceğiniz, security attributes değeri ve bInherit  değerleri başlı başına bir konu olarak işlenebilir ). Son parametremizle açtığımız bu desktop alanla ne yapacağımızı sisteme anlatırız. Detaylar için msdn e bakabilirsiniz, ama biz desktop değiştireceğiz ve desktop değiştirmek için gerekli değer : DESKTOP_SWITCHDESKTOP

·        HDESK CreateDesktop(lpszDesktop,lpszDevice,pDevMode,dwFlags,dwAccess,lpsa) İsminden anlaşılabileceği gibi bu api ile bir desktop alanı yaratıyoruz. Geriye dönüş değeri yaratılan desktop’un handle değeridir. İlk parametremiz, yaratacağımız desktop alanın adı. Bu ad sistem bazında globaldır, büüyk küçük harf önemlidir ve farklılık yaratır.  2. ve 3. parametre işletim sistemine aittir, biz buralar NULL değerini girmeliyiz. 4. parametre yani flags a sıfır değerini girebilirsiniz, diğer alabilecğei değerler alt seviye programlama ile ilgilidir , biz o kadar alta inmeyeceğiz. Access parametresi olarak, kolaylık açısından ( zaten hep bu kolaylıklar yüzünden yazılımlar patlar J )tüm haklar anlamına gelen GENERIC_ALL yazacağız. Diğer ayrıntılar için msdn den bakabilirsiniz. Son parametreye NULL değerni girebilirsiniz.

·        BOOL SetThreadDesktop(HDESK) Bu api sayesinde, thread’in desktopunu değiştirebiliriz. Parametre olarak yeni alanın handle numarasını alır. Burada dikkat edilmesi gereken bir nokta, eğer threadimizin bulunduğumuuz desktop üzerinde bir objesi varsa ( pencere gibi ), yeni bir desktop alanına geçemeyiz. Bu apiyi çağırmak hemen desktopu değiştirmez, sadece yeni yaratılacak, pencere vs nin bu desktopta yaratılmasını sağlar ama desktop hala visible değildir.

·        BOOL SwitchDesktop(HDESK)  Artık arkada gizli kalmış desktop alanını görünür hale getiren apidir.

Şimdi kodumuzu yayınlayalım J

#include<windows.h>

// Dr Dobb's Journal

int WINAPI WinMain(HINSTANCE hInst,HINSTANCE hPrev,LPSTR lpCmd,int nShow)

{

          //once varsayilan desktopun handle ini saklayalim

          HDESK hdeskOriginalThread = GetThreadDesktop(GetCurrentThreadId());

          //varsayılan input desktopunun handleini alalım

          HDESK hdeskOriginalInput = OpenInputDesktop(0,FALSE,DESKTOP_SWITCHDESKTOP);

          //ceviz_desktop isminde yeni bir desktop yarattık

          HDESK hdeskNewDesktop = CreateDesktop("CEVIZ_DESKTOP",NULL,NULL,

                                0,GENERIC_ALL,NULL);

          //artık desktopumuz ceviz_desktop

          SetThreadDesktop(hdeskNewDesktop);

          // şimdi de visible yapalim

          SwitchDesktop(hdeskNewDesktop);

          // bu mesaj yeni desktop ta çıkacak

          MessageBox(NULL,"Bu mesaj, CEVIZ_DESKTOP ta görüntüleniyor. Arka Plana Dikkat",

                                "CEVIZ_DESKTOP",MB_OK);

         

          //eski haline getirelim, eğer eski haline getirmezsek, default desktopa reboot edilene dek

          //dönemeyiz

          SwitchDesktop(hdeskOriginalInput);

          SetThreadDesktop(hdeskOriginalThread);

                                

          CloseDesktop(hdeskNewDesktop);

          return 0;

}

Şimdi biraz yorumlar yapıp yazıyı bitiricem. Eğer yazının devam etmesini istiyorsanız ceviz.net forumunda bunu belirtin. Daha önceki yazılarda olduğu gibi yoksa bu da ilgi görülmediği varsayılıp burada bırakılacaktır.

Eğer uygulamanız default desktopta çalışmak için ayarlanırsa bazı problemler çıkabilir.

Mesela yukaridaki programı çalıştırın, ekranda messagebox varken, ctrl+alt+del tuşlarına basarak, Winlogon desktopuna geçin, ve task manager’I çağırın. Eee hani nerde task manager ?

Task manager default desktop ta açıldı, inanmazsanız, messageboxta ok e basıp tekrar default desktop a düşün ve task manager a bakın.

Uygulamalarınızda buna dikkat etmelisiniz, bundan başka, eğer bir desktop yarattıysanız ve o desktop alanına switch ettiyseniz, ve programınız sonsuz döngüye girerse tek çare reboottur J

Aslında yazının devamı  için istek gelirse, bunun başka bir yolunuda göstericem.

Kolay Gelsin.