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 ...
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. –
Aslında, siz değilsiniz:/Bunu özledim .... Şimdi yeniden derleme ... Bir saniye içinde. – user3399848
*** *** 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