2014-09-08 32 views
5

Bir dizin bilgisi yardımcı programı yazdım ve (bu yüzden, & eski donanımı kullanmam için bunları yazdığım kişiler), Windows ve Windows 9x ile uyumlu olmasını sağladı XP/Vista/7/8 64-bit (biz de bunları kullanıyoruz çünkü). Çalıştığım sorun Windows 9x ve FAT32 sürücülerindeydi. Windows 9x gerçekten yüklendiği sürece çalışmayı başardım, ancak yalnızca komut istemi için önyükleme yaparsam veya MS-DOS modunda yeniden başlatırsam, büyük sürücü verilerini almamı sağlayan Windows API'ye erişimimi kaybederim. sahip olduğum DOS yordamına geri döndü. Bunlar 2GB limit rutini ile sınırlıdır. DOS 7.x programlarının (chkdsk ağırlıklı olarak) bunun nasıl işlediğini incelemek (doğru sürücü boyutlarını bildirirken herhangi bir sorunu olmadığından), bunu yapmak için DOS kesmelerini (esas olarak INT 21h,) kullanırlar. Düşünme, sorun değil, hızlı sürüm kontrolü yapacağım, ve eğer DOS 7 veya daha yüksekse, sürücü yapısını almak ve toplam & boş alanı bu şekilde hesaplamak için hızlı bir montaj yönlendirmesi yapacağım. Sadece, rutin (bir hata döndürmese de) arabamı hiçbir şeyle doldurmaz. Geçen bit beni yanlış neler olduğunu anlamaya çalışıyordu YaniDOS sürücüde büyük sürücü yapısı bilgileri edinme 7.x

#include <stdio.h> 
#include <dos.h> 

void main(void) { 
    unsigned short hes,hdi,sectors,bytes; 
    unsigned long tclusters,fclusters; 
    unsigned char far *drivedata; 
    char test = '\0'; 
    char display[17] = "ABCDEF"; 
    int count; 

    drivedata = new unsigned char [63]; 

    for (count = 0; count < 63; count++) drivedata[count] = '\0'; 

    drivedata[0] = '\x3d'; 
    drivedata[1] = '\x00'; 

    hes = FP_SEG(drivedata); 
    hdi = FP_OFF(drivedata); 

asm { 
     push ax 
     push es 
     push di 
     push ds 
     push dx 
     push cx 
     mov ax,0x440d 
     mov bx,0x0003 
     mov cx,0x484a 
     int 21h 
     jnc _GOOD 
     mov ax,0x7302 
     mov es,[hes] 
     mov di,[hdi] 
     mov dx,0x0003 
     mov cx,0x003f 
     int 21h 
     jnc _GOOD 
    } 
    test = '\1'; 
_GOOD: 
    asm { 
     mov ax,0x440d 
     mov bl,0x03 
     mov cx,0x486a 
     int 21h 
     pop cx 
     pop dx 
     pop ds 
     pop di 
     pop es 
     pop ax 
    } 

    if (test == '\1') { 
     printf("There was an error.\r\n"); 
     return; 
    } 



    tclusters = (unsigned long) drivedata[48]; 
    tclusters = (tclusters * 256) + (unsigned long)drivedata[47]; 
    tclusters = (tclusters * 256) + (unsigned long)drivedata[46]; 
    tclusters = (tclusters * 256) + (unsigned long)drivedata[45]; 
    ++tclusters; 

    fclusters = (unsigned long)drivedata[36]; 
    fclusters = (fclusters * 256) + (unsigned long)drivedata[35]; 
    fclusters = (fclusters * 256) + (unsigned long)drivedata[34]; 
    fclusters = (fclusters * 257) + (unsigned long)drivedata[33]; 

    bytes = (unsigned int)drivedata[5]; 
    bytes = (bytes * 256) + (unsigned int)drivedata[4]; 

    sectors = (unsigned long)drivedata[6]; 
    ++sectors; 

    printf("Drive C has:\r\n"); 
    printf(" Total Clusters: %u\r\n",tclusters); 
    printf(" Free Clusters: %u\r\n",fclusters); 
    printf("   Sectors: %u\r\n",sectors); 
    printf("   Bytes: %u\r\n",bytes); 

    printf("\r\n"); 
    printf(" | 0 1 2 3 4 5 6 7 8 9 A B C D E F\r\n"); 
    printf("---------------------------------------------------------------------"); 
    for (count = 0; count < 63; count++) { 
     if ((count % 16) == 0) printf("\r\n %c | ",display[(count/16)]); 
     printf("%03u ",drivedata[count]); 
    } 
    printf("\r\n"); 

    return; 
} 

: Burada

kodudur. Garip sonuçlar elde ettim ve bir desen bulamadım. Aslında, INT çağrısının kendi değerleri ile doldurması gerektiği için arabellek temizliği konusunda endişelenmemiştim (EDB veri arabelleği boyutuyla doldurulması gereken ilk 2 bayt hariç). rastgele sonuçlar, tamponun sıfırlar ile doldurmak için başında ekledim, daha sonra tampon boyutunu ekleyin. Sonuçlar o noktada rasgele durdu, hepsi sıfırdı, INT çağrısı arabayı doldurmuyordu. Çeşitli testlerle, hes & hdi'nin arabellek adresinin segmentine ve ofsetine doğru olarak atanacağını doğruladım. Ayrıca tampon adresi yerine işaretçi adresine & di denedim. Okuduğum her şeyin bir işaretçiye değil, adrese değil, düşünmeye çalışacağını düşünürdüm ama düşünebileceğim herşeyi deniyordum. Her durumda, tampon hiçbir şeyle dolu değildir.

Muhtemelen söyleyebildiğiniz gibi, bu sadece ana programıma eklemeden önce tam prosedürü bulmak için yazdığım bir test programıdır (bu sorun sadece bir sorun dışında çalışır.) FP_ satırları sadece (imzasız uzun) (x & 0xffff0000) >> 16 segmenti ve ofset için (imzasız uzun) (x & 0x0000ffff) olarak ifade edilebilecek makrolar. Normalde işaretçiyi (& drivedata,) geçirirsiniz, ancak drivedata zaten bir işaretleyicidir.

gerçek çıktı:

Drive C has: 
    Total Clusters: 1 
    Free Clusters: 0 
      Sectors: 1 
      Bytes: 0 

    | 0 1 2 3 4 5 6 7 8 9 A B C D E F 
--------------------------------------------------------------------- 
0 | 061 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
1 | 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
2 | 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 
3 | 000 000 000 000 000 000 000 000 000 000 000 000 000 000 000 

Peki, ne eksik? Chkdsk gibi, sürücüyü daha önce kilitlerim ve aramadan sonra kilitlerim (gerekliliğinden emin değilim). Bunu doğru şekilde nasıl çalıştırabilirim? Alternatif olarak, INT 21h kullanmadan sürücü yapısını (kümeler, sektör başına küme, sektör başına bayt) almak için daha iyi bir yol var mı? Aramalarda bulduğum her şey, bana sadece komut istemine yönelik bir önyükleme yaparsa, kullanıcının erişemeyeceği Windows API işlevlerine işaret eder ...

+1

Kodunuzu yanlış mı okuyordum? Sürücüyü kilitlemeyi başarırsanız, verileri okumak için kodun üzerinden geçersiniz. Başarısız olabilir, belki 1) SI'nın 0xF1A6'ya ayarlanması. 2) dl’yi 0x80’e ayarlama. 3) Daha büyük bir arabellek (256?) Kullanma. –

+1

Aslında, siz değilsiniz:/Bunu özledim .... Şimdi yeniden derleme ... Bir saniye içinde. – user3399848

+1

*** *** Evet, Başarısızlığı atlamak yerine kodumu başarıya atlıyordum. Jnc opcode'ı jc olarak değiştirdi ve yeni bir etikete ekledi (iyi/hatalı bayrağı uygun şekilde değiştirmek için). Eh, şimdi veri alıyorum, sayılar görünse de. Şimdi biraz daha test yapmak için gidiyor :) Teşekkürler – user3399848

cevap

1

Wow, DOS kullanıyor, bu eski okul! Yumruk kartlarını kullanarak eski okul olarak değil, ama hala ...

Görünüşe göre, FreeDOSFAT 32 support'a sahiptir. Windows 95'in yüklü olmadığı makinelere yüklemeyi deneyebilirsiniz.

+3

Eski sistemler inşa eden insanlar o anda kullanılan işletim sistemi ile uğraşma eğilimindedirler. Benim küçük programım DOS 3'te çalışır. + (gerçekten yüklemek ve test etmek için uğraşırken olduğu kadar geri döndü, daha ileri geri gidebilir.) Ayrıca modern sistemler üzerinde çalışıyor (örneğin Windows 7 64-bit.) Tek hıçkırık DOS 7 (Windows 9x) komut istemine önyükleme.) Şimdi çalışmayı denediğim şey, DOS 7. Sadece bir FYI, klavyeyi icat ettikleri zaman gerçekten çok memnun oldum, kartlar gerçek bir PITA idi. – user3399848

+0

Vay, * kesinlikle * kontrol etmelisin Bu CP/M üzerinde – zmbq

1

Eski hobiniz için LBA ve FAT32 özellikleriyle donatmanız gerekir, Wikipedia: File Allocation Table iyi bağlantılara sahip gibi görünüyor.

Bu eski sistemlerin (ve onlar için yazılmış olan yazılımların) büyük diskleri (disk boyutu> 2^(32-1)) incelikle kullanamadıklarını öğrenebileceğiniz bir şey var. Bence

Diğer malzeme de çok önemli olacaktır:

BIOS kullanmak olacaktır her durumda sizin için çalışması gerektiğini "iyi bir yol" bulmaya çağıran Tüm temelleri ve sonra kendi kodunuzda vb boyutlarını hesaplamak için algoritmaları çoğaltın. Eski DOS günlerinde, Microsoft dışı programlar için kullanılabilir olan yeniden kullanılabilir bir API bulunmuyordu. Gelişmiş şeyler yapmak için gereken programlar kendi başlarına çıplak kemiği nasıl yapılacağını bilmek zorundaydı ..

+1

Şu anda BIOS çağrıları kullanıyorum, yani burada koştu :(LBA ve FAT32'yi okudum. Tüm bunları ben küçük programı yazarken yaptım. Yukarıda gördüğünüz gibi, problemlerimin hepsi benim kendi yaratımımdı. Üzgünüm, profesyonel bir programcı değilim, sadece amatör. Bunu şimdi sabitledim. Izlemek için küçük bir hata (gerçek yardımcı program kodu) ve CD-ROM'lar için bir geçici çözüm ve ben bitmiş olmalıdır. – user3399848