Makale Özeti

Bu yazımızda C# ile Registry (Kayıt Defteri) üzerinden USB depolama aygıtlarına erişimi düzenleyen bir program nasıl geliştirilir adım adım anlatmaya çalışacağız. Daha kolay anlaşılabilmesi için anlatımları mümkün mertebe basit seviyede tutmaya çalışacağım.

Makale

C# ile Registry Üzerinden USB Depolama Aygıtlarına Erişimi Düzenlemek

Bu yazımızda C# ile Registry (Kayıt Defteri) üzerinden USB depolama aygıtlarına erişimi düzenleyen bir program nasıl geliştirilir adım adım anlatmaya çalışacağız. Daha kolay anlaşılabilmesi için anlatımları mümkün mertebe basit seviyede tutmaya çalışacağım. Öncelikle kısaca Registry den bahsedelim. Registry Windows işletim sisteminin ve işletim sistemine yüklü bulunan uygulamaların gerekli bilgilerinin (yazılım ayarları, kısıtlamalar, dosya ilişkileri vs.) tutulduğu bir veritabanıdır. Tasarlanan programların kullanıcılar tarafından benimsenebilmesi için kullanıcıya bir takım ayarlamalar yapma ve bu ayarları daha sonraki kullanımlar için saklı tutma gibi özellikler sunmalıdır. Eskiden ( hatta halen) bu yapılandırma bilgileri programla beraber gelen INI (initialization file = başlangıç dosyası) dosyalarında tutulurdu. Bu INI dosyalarından kurtulmak ve yapılandırma kayıtlarını daha düzenli bir şekilde tutmak için Registry ( Kayıt Defteri) geliştirildi.

Kayıt Defterine ulaşmak için “Başlat” menüsünden “Çalıştır” ı seçip gelen ara yüzdeki metin alanına “regedit” yazıp tamam tuşuna basmanız yeterlidir. Örneğin şu an aktif olan kulacının oturum açması esnasında otomatik olarak devreye giren programları görmek için “HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run” anahtarına gelmeniz yeterli. Sağdaki alanda oturum yapıldıktan sonra devreye giren programların listesini göreceksiniz. Devreye girmesini istemediğiniz programın kaydını silmeniz yeterli.

Bu kadar registry bilgisinden sonra programa geçebiliriz. Daha fazla bilgi için Google da arama yapmanız yeterli.Visual Studio 2005/2008 Geliştirme Ortamı dosya menüsünden Yeni > Proje yi seçin ( File > New > Project ). Proje türlerinden ( Project Types) Visual C# ı, şablonlardan (Templates) Windows Application ı seçiyoruz. Uygun bir proje ismi yazıp tamam dedikten geliştirme ortam ara yüzü boş bir form nesnesi ile açılacaktır. Aşağıdaki gibi bir form tasarlayıp gerekli kodlamaları yapacağız.

Şimdilik amacımız USB Depolama aygıtları üzerinde kısıtlamalar yapabilecek bir yazılım geliştirmek. USB Depolama aygıtlarına veri yazmayı engelleyip bu aygıtları “sadece okunabilir” modunda kullanılmasına izin vermek için HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\StorageDevicePolicies< anahtarı altında WriteProtect isimli bir DWORD Değeri oluşturulup değer olarak 1 atanması gerekiyor ( 0 = Okuma ve Yazma, 1=Sadece Okunabilir). USB Depolama aygıtlarının hiç yüklenmemesini istiyorsak HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\USBSTOR anahtarı altında değer verisi 3 olan Start adlı DWORD değerinin değer verisini 4 yapmalıyız.

Kodlamaya geçmek için form üzerinde boş bir alana çift tıklamamız yeterli. Otomatik olarak bu form yüklendiğinde işlenecek komutları yazabileceğimiz satıra yönlendirileceğiz.

Bizim amacımız Registry üzerinde çalışmak olduğu için öncelikle Registry ile alakalı isim uzayını kullanabilmek için kod sayfasının başına aşağıdaki satırı ekliyoruz.

using Microsoft.Win32;

Programımız açıldığında mevcut yapılandırmanın programımız tarafından algılanması için USB_getStatus()adında bir fonksiyon tanımlayıp bu fonksiyonu formun yükleniş olayına (Form Load) ekliyoruz. USB_getStatus() fonksiyonunun gövdesine aşağıdaki kodları yazmaya başlıyoruz:

RegistryKey key;

try

{

key = Registry.LocalMachine.OpenSubKey

("SYSTEM\\CurrentControlSet\\Control\\StorageDevicePolicies");

 

      if (System.Convert.ToInt16(key.GetValue("WriteProtect", null)) == 1)

            USB_radio_ReadOnly.Checked = true;

      else

            USB_radio_FullAccess.Checked = true;

}

catch (NullReferenceException )

{

key = Registry.LocalMachine.OpenSubKey

            ("SYSTEM\\CurrentControlSet\\Control", true);

      key.CreateSubKey("StorageDevicePolicies");

      key.Close();

}

catch( Exception ) {}

 

Burada key adında yeni bir anahtar nesnesi oluşturup bu anahtar nesnesi ile CurrentControlSet\Control\StorageDevicePolicies alt anahtarını açmaya çalışıyoruz. Bu anahtardaki WiteProtect değerini okumaya çalışıyoruz, GetValue() fonksiyonu geriye object türünden bir nesne dönderdiği için System.Convert.ToInt16() fonksiyonu ile tam sayıya ( integer) döşümü sağlıyoruz. Eğer bu alt anahtar mevcut değilse NullReferenceException hatası verileceğinden dolayı bu hatayı yakalayıp anahtarı kendimiz oluşturuyoruz.

 

Aynı nesne ile SYSTEM\CurrentControlSet\Services\UsbStor alt anahtarına erişmeye çalışıp buradaki Start değerini okuyoruz. Yine aynı şekilde anahtarın mevcut olmaması durumunda verilen hatayı yakalayıp anahtarı kendimiz oluşturarak varsayılan değerleri atıyoruz:

 

try

{

key = Registry.LocalMachine.OpenSubKey

            ("SYSTEM\\CurrentControlSet\\Services\\UsbStor");

 

      if (System.Convert.ToInt16(key.GetValue("Start", null)) == 4)

      {

            USB_radio_Disabled.Checked = true;

            return;

}

}

 

catch ( NullReferenceException )

{

key = Registry.LocalMachine.OpenSubKey

            ("SYSTEM\\CurrentControlSet\\Services", true);

key.CreateSubKey("USBSTOR");

key = Registry.LocalMachine.OpenSubKey

            ("SYSTEM\\CurrentControlSet\\Services\\UsbStor", true);

 

key.SetValue("Type", 1, RegistryValueKind.DWord);

      key.SetValue("Start", 3, RegistryValueKind.DWord);

      key.SetValue

("ImagePath", "system32\\drivers\\usbstor.sys", RegistryValueKind.ExpandString);

key.SetValue("ErrorControl", 1, RegistryValueKind.DWord);

      key.SetValue

("DisplayName", "USB Mass Storage Driver", RegistryValueKind.String);

 

key.Close();

}

           

catch( Exception ) {}

 

Uygulamamızda 3 ana özelliğe ihtiyacımız olacak,

1- USB depolama aygıtlarına erişim modunu belirleme

2- Kayıt Defteri Düzenleyicisine erişimi belirleme

3- Ayarlara yetkisiz erişimi parola aracılığı kısıtlamak

Her ne kadar ayarlara erişimi parola belirlemek suretiyle kısıtlasak da, kullanıcıların doğrudan Kayıt Düzenleyicisi aracılığı ile yaptığımız ayaralamaları değiştirebilme imkanı bulunmakta. İkinci özelliğe bu imkanı ortadan kaldırmak için ihtiyaç duyuyoruz.

 

Yazma korumasını aktifleştirmek için aşağıdaki işlevi tanımlıyoruz:

 

void USB_enableWriteProtect()

{

RegistryKey key = Registry.LocalMachine.OpenSubKey

      ("SYSTEM\\CurrentControlSet\\Control\\StorageDevicePolicies", true);

      if (key == null)

      {

            Registry.LocalMachine.CreateSubKey

("SYSTEM\\CurrentControlSet\\Control\\StorageDevicePolicies",      RegistryKeyPermissionCheck.ReadWriteSubTree);

           key = Registry.LocalMachine.OpenSubKey

("SYSTEM\\CurrentControlSet\\Control\\StorageDevicePolicies", true);

key.SetValue("WriteProtect", 1, RegistryValueKind.DWord);

      }

else if (key.GetValue("WriteProtect") != (object)(1))

      {

key.SetValue("WriteProtect", 1, RegistryValueKind.DWord);

}

}

 

Dikkat etmenizi istediğim birkaç nokta var. Daha önceki örneklerden farklı olarak “OpenSubKey()” fonksiyonuna “true” boolean değeri eklemek suretiyle alt anahtarı yazma modunda açtık. if()  şartı ile alt-anahtarın mevcut olup olmadığını kontrol ediyoruz, mevcut değil ise “CreateSubKey()” işlevi ile oluşturuyoruz. İhtimal dahiline alınması gereken bir durum daha var; alt anahtar mevcut olabilir ama bu anahtar altında “WriteProtect” isminde bir değer bulunmayabilir, fonksiyonun son kısmında bu ihtimali çözümlüyoruz.

 

Yazma korumasını pasifleştirmek için ise aşağıdaki işlevi yazıyoruz:

 

void USB_disableWriteProtect()

{

RegistryKey key = Registry.LocalMachine.OpenSubKey

          ("SYSTEM\\CurrentControlSet\\Control\\StorageDevicePolicies",true);

if (key != null)

      {

            key.SetValue("WriteProtect", 0, RegistryValueKind.DWord);

}

      key.Close();

}

 

Benzer bir şekilde USB Depolama aygıtlarının kullanımını tamamen engellemek için aşağıdaki fonksiyonu tanımlıyoruz:

 

void USB_disableAllStorageDevices()

{

RegistryKey key = Registry.LocalMachine.OpenSubKey

                ("SYSTEM\\CurrentControlSet\\Services\\UsbStor",true);

if (key != null)

      {

key.SetValue("Start", 4, RegistryValueKind.DWord);

}

      key.Close();

}

 

USB Depolama aygıtlarının kullanımına izin vermek için ise şu fonksiyonu tanımlıyoruz:

 

void USB_enableAllStorageDevices()

{

RegistryKey key = Registry.LocalMachine.OpenSubKey

                ("SYSTEM\\CurrentControlSet\\Services\\UsbStor", true);

      if (key != null)

      {

            key.SetValue("Start", 3, RegistryValueKind.DWord);

      }

      key.Close();

}

 

Kayıt Düzenleyiciye erişimi engellemek için şu fonksiyonu tanımlıyoruz:

 

private void REG_DisableRegedit()

{

RegistryKey key =

Registry.CurrentUser.OpenSubKey

("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", true);

key.SetValue("DisableRegistryTools", 1, RegistryValueKind.DWord);

      key.Close();

}

 

Kayıt Düzenleyiciyi kullanıma açmak için ise aşağıdaki fonksiyonu tanımlıyoruz:

 

private void REG_EnableRegedit()

{

RegistryKey key =

Registry.CurrentUser.OpenSubKey

("Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System", true);

key.SetValue("DisableRegistryTools", 0, RegistryValueKind.DWord);

      key.Close();

}

 

Programımızın son kısmında “Apply” (=Uygula)  tuşuna tıklandığında gerekli işlevlerin yapılmasını sağlayacak kodları yazmamız gerek. İlk öncelikle yanlış tıklamaların olma ihtimalini göz önünde tutarak bir mesaj kutusu aracılığıyla kullanıcıya değişiklerin gerçekten uygulanmasını istiyor mu diye soruyoruz. Sonuç evet ise if() şartları aracılığı ile hangi değişikliklerin talep edildiğini kontrol ediyoruz buna bağlı olarak daha önceden hazırladığımız fonksiyonları çağırıyoruz.  Eğer herhangi bir parola belirlenmişse kullanıcıdan parolayı girmesini istiyoruz. Son olarak kullanıcıya değişikliklerin etkinleşmesi için bilgisayarın yeniden başlatılmasının gerektiğini hatırlatıyoruz.

 

private void btnApply_Click(object sender, EventArgs e)

{

DialogResult resultApplyChanges

= MessageBox.Show("Apply changes?", "Confirm",

MessageBoxButtons.YesNo, MessageBoxIcon.Question);

           

if (resultApplyChanges == DialogResult.Yes)

      {

            if (Program.isPwdEnabled)

            {

                  frmPasswordCheck frmPwdCheck = new frmPasswordCheck();

                  frmPwdCheck.ShowDialog();

 

if (frmPwdCheck.DialogResult != DialogResult.OK)

                        return;

}

            if (USB_radio_Disabled.Checked == true)

            {

                  USB_disableAllStorageDevices();

}

            else if (USB_radio_ReadOnly.Checked == true)

            {

                  USB_enableAllStorageDevices();

                 USB_enableWriteProtect();

}

            else

            {

                  USB_enableAllStorageDevices();

                  USB_disableWriteProtect();

}

 

            if (REG_cbox_DisableRegistry.Checked == true)

            {

                  REG_DisableRegedit();

}

           else

            {

                  REG_EnableRegedit();

            }

            MessageBox.Show

                  ("In order to enable new setting please" +

                    " reconnect your USB storage devices" +

                    " or restart your computer", "Information",

                    MessageBoxButtons.OK, MessageBoxIcon.Information);

}

}

Bu yazıda, C# ile registry ayarlarında düzenlemelerin nasıl yapıldığını,  USB Depolama aygıtlarına erişimi nasıl kısıtlayabileceğimizi öğrendik.  Aslında bu programı lisans öğrenimimim son yılında, 2007de, hazırlamıştım ve bu makaleyi o zaman kaleme almıştım. Çeşitli sebeplerden dolayı o zaman yayınlamadım, sadece birkaç arkadaşa gönderdim. Geçenlerde ağabeyim benden bu tür bir program hazırlamamı rica edince programı ve yazdığım makaleyi gözden geçirip yayınlamaya karar verdim.

 

Programın kullanılabilir haline ve kaynak kodlarına http://www.codeproject.com/KB/cs/usb_lock.aspx  adresinden ulaşabilirsiniz. Bir sonraki makalede görüşmek dileğiyle…

 

Özcan İLİKHAN

 

Bilgisayar Mühendisi

http://knol.google.com/k/ozcan-ilikhan