2014-09-08 7 views
5

में बड़ी ड्राइव संरचना जानकारी प्राप्त करना मैंने एक निर्देशिका सूचना उपयोगिता लिखी और (क्योंकि मैं, और जिन लोगों को मैंने & संग्रहित विंटेज हार्डवेयर का संग्रह करने के लिए लिखा था,) ने इसे डॉस और विंडोज 9एक्स के साथ-साथ विंडोज के साथ संगत बना दिया एक्सपी/विस्टा/7/8 64-बिट (क्योंकि हम उन लोगों का भी उपयोग करते हैं।) जिस समस्या में मैंने भाग लिया वह विंडोज 9एक्स और एफएटी 32 ड्राइव के साथ था। जब तक विंडोज 9एक्स वास्तव में लोड किया गया था तब तक मैं इसे काम करने में कामयाब रहा, लेकिन अगर मैं केवल कमांड प्रॉम्प्ट पर बूट करता हूं, या एमएस-डॉस मोड में पुनरारंभ करता हूं तो मैं विंडोज एपीआई तक पहुंच खो देता हूं जिसने मुझे बड़े ड्राइव डेटा और इसे प्राप्त करने की अनुमति दी मेरे पास डॉस रूटीन पर वापस डिफॉल्ट किया गया है। ये 2 जीबी सीमा दिनचर्या तक ही सीमित हैं। यह जांचने के लिए कि डॉस 7.x प्रोग्राम (मुख्य रूप से chkdsk,) कैसे संभालते हैं (क्योंकि उन्हें सही ड्राइव आकार की रिपोर्ट करने में कोई समस्या नहीं है) ऐसा लगता है कि वे ऐसा करने के लिए डॉस इंटरप्ट्स (मुख्य रूप से INT 21h,) का उपयोग करते हैं। सोच रहा है, कोई समस्या नहीं, मैं एक त्वरित संस्करण जांच करूँगा, और यदि यह डॉस 7 या उच्चतर है तो मैं ड्राइव संरचना प्राप्त करने के लिए एक त्वरित असेंबली रूटिंग चलाऊंगा और कुल & इस तरह की खाली जगह की गणना करूंगा। केवल, दिनचर्या (हालांकि यह कोई त्रुटि नहीं लौटाती है), मेरे बफर को किसी भी चीज़ से भरती नहीं है।डॉस 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; 
} 

पिछले सा गया था मुझे यह पता लगाने की क्या गलत हो रहा था की कोशिश कर रहा है कि:

यहाँ कोड है। मुझे अजीब परिणाम मिल रहे थे, और एक पैटर्न का पता नहीं लगा सका। मूल रूप से, मैं बफर को साफ़ करने के बारे में चिंतित नहीं था क्योंकि आईएनटी कॉल इसे अपने स्वयं के मूल्यों से भरना चाहिए था (पहले 2 बाइट्स को छोड़कर, जिसे ईडीबी डेटा बफर आकार से भरा जाना चाहिए।) इतने स्पष्ट रूप से प्राप्त करने के बाद यादृच्छिक परिणाम, मैंने शुरुआत में लूप में शून्य के साथ बफर भरने के लिए जोड़ा, फिर बफर आकार में जोड़ें। परिणाम उस बिंदु पर यादृच्छिक होने से रोकते थे, वे हमेशा सभी शून्य थे, जिसका अर्थ है कि आईएनटी कॉल बफर भर नहीं रहा है। विभिन्न परीक्षणों के साथ, मैंने पुष्टि की है कि hes & एचडीआई को बफर पते के सेगमेंट और ऑफ़सेट को सही तरीके से असाइन किया जा रहा है। मैंने बफर पते के बजाय सूचक पते पर & di भी कोशिश की है। मैंने नहीं सोचा था कि यह सबकुछ काम करेगा जैसा मैंने पढ़ा था, इसे पते पर सेट करने के लिए कहा था, लेकिन सूचक के लिए नहीं, लेकिन मैं जो कुछ भी सोच सकता था उसकी कोशिश कर रहा था। सभी मामलों में, बफर कुछ भी भर नहीं रहा है।

जैसा कि आप शायद बता सकते हैं, यह केवल एक परीक्षण कार्यक्रम है जिसे मैं अपने मुख्य कार्यक्रम में जोड़ने से पहले सटीक प्रक्रिया को समझने के लिए लिख रहा हूं (जो इस मुद्दे को छोड़कर ठीक काम करता है।) एफपी_ लाइनें बस हैं मैक्रोज़ जिन्हें ऑफ़सेट के लिए (हस्ताक्षर किए गए लंबे) (x & 0xffff0000) >> सेगमेंट के लिए 16 और (हस्ताक्षर किए गए लंबे) (x & 0x0000ffff) के रूप में वर्णित किया जा सकता है। आम तौर पर आप पॉइंटर (& drivedata,) पास करेंगे, लेकिन drivedata पहले से ही एक सूचक है।

वास्तविक उत्पादन:

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 

तो, मुझे याद आ रही? Chkdsk की तरह, मैं पहले ड्राइव को लॉक कर रहा हूं और कॉल के बाद इसे अनलॉक कर रहा हूं (हालांकि मुझे आवश्यकता के बारे में निश्चित नहीं है।) मैं इसे सही तरीके से कैसे काम कर सकता हूं? वैकल्पिक रूप से, क्या INT 21h का उपयोग करने से ड्राइव संरचना (क्लस्टर, प्रति क्लस्टर प्रति क्षेत्र, बाइट प्रति क्षेत्र) प्राप्त करने का एक बेहतर तरीका है? खोजों में जो कुछ भी मुझे मिलता है, वह केवल मुझे विंडोज एपीआई फ़ंक्शंस पर इंगित करता है, जिसे उपयोगकर्ता को एक्सेस कमांड इत्यादि के लिए बूट करने की सुविधा नहीं होगी ...

+1

क्या मैं आपका कोड गलत पढ़ रहा हूं? ऐसा लगता है कि आप ड्राइव को लॉक करने में सफल होते हैं, तो आप डेटा को पढ़ने के लिए कोड को छोड़ देते हैं। यह विफल हो रहा है, शायद 1) एसआई को 0xF1A6 सेट करना। 2) डीएल को 0x80 पर सेट करना। 3) एक बड़ा बफर (256?) का उपयोग करना। –

+1

दरअसल, आप नहीं हैं:/मुझे याद आया .... अब पुन: संकलित ... एक सेकेंड में वापस। – user3399848

+1

*** श्वास *** हाँ, मैं विफलता पर छोड़ने की बजाए सफलता पर अपना कोड छोड़ रहा था। Jcc को jnc opcode बदल दिया, और एक नए लेबल में जोड़ा गया (अच्छे/खराब ध्वज को उचित रूप से बदलने के लिए।) मेरा बुरा। खैर, अब मुझे डेटा मिल रहा है, हालांकि संख्याएं प्रतीत होती हैं। अब कुछ और परीक्षण करने जा रहे हैं :) धन्यवाद – user3399848

उत्तर

1

वाह, पुराने स्कूल के डॉस का उपयोग करके वाह! पंच कार्ड का उपयोग करने के रूप में पुराने स्कूल के रूप में नहीं, लेकिन अभी भी ...

जाहिर है, FreeDOS में FAT 32 support है। आप इसे उन मशीनों पर स्थापित करने का प्रयास कर सकते हैं जिनके पास विंडोज 95 भी स्थापित नहीं है।

+3

जो लोग विंटेज सिस्टम बनाते हैं वे उस ओएस के साथ चिपकते हैं जो उस समय उपयोग में था। मेरा छोटा कार्यक्रम डॉस 3 पर काम करता है + (वास्तव में जब तक मैं स्थापित करने और परीक्षण करने के लिए तैयार था, यह आगे बढ़ सकता है।) यह आधुनिक प्रणालियों पर भी काम करता है (उदाहरण के लिए मेरा विंडोज 7 64-बिट।) एकमात्र हिचकी, डॉस 7 (विंडोज 9एक्स है) कमांड प्रॉम्प्ट पर बूट किया गया।) यही वह है जो मैं अब काम करने की कोशिश कर रहा हूं, डॉस 7. बस एक एफवाईआई, जब उन्होंने कीबोर्ड का आविष्कार किया तो मैं वास्तव में खुश था, पंच कार्ड एक वास्तविक पिटा थे। – user3399848

+0

वाह, आपको * निश्चित रूप से * जांच करनी चाहिए यह सीपी/एम! – zmbq

1

अपने पुराने शौक के लिए आपको LBA और FAT32 विनिर्देशों के साथ स्वयं को लैस करना चाहिए, Wikipedia: File Allocation Table अच्छे लिंक होने लगते हैं।

एक चीज जो आपको मिल सकती है वह यह है कि उन विरासत प्रणालियों (और उनके लिए लिखे गए सॉफ़्टवेयर) बड़ी डिस्क (डिस्क आकार> 2^(32-1)) को संभाल नहीं सकते थे।

अन्य सामग्री मुझे लगता है कि यह भी बहुत महत्वपूर्ण होगा:

"बेहतर तरीका" है कि सभी मामलों में आप के लिए काम करना चाहिए BIOS उपयोग करने के लिए किया जाएगा पता लगाने के लिए कॉल सभी मूल बातें और फिर अपने कोड में आकार आदि की गणना के लिए एल्गोरिदम दोहराएं। पुराने डॉस दिनों में गैर-माइक्रोसॉफ्ट प्रोग्राम्स के लिए कोई आसानी से पुन: प्रयोज्य एपीआई उपलब्ध नहीं था। जिन कार्यक्रमों को उन्नत चीजों को करने की ज़रूरत थी उन्हें यह जानना था कि इसे खुद से नंगे हड्डी कैसे करें ..

+1

पर मैं अब BIOS कॉल का उपयोग कर रहा हूं, यही वह जगह है जहां मैं समस्या में भाग गया :(मैंने एलबीए और एफएटी 32 पर पढ़ा है। मैंने वह सब किया जब मैं पहली बार छोटी उपयोगिता लिख ​​रहा था। जैसा कि आप ऊपर देख सकते हैं, यह पता चला है कि मेरी समस्याएं मेरी सारी सृष्टि थीं। मुझे खेद है, मैं एक पेशेवर प्रोग्रामर नहीं हूं, सिर्फ शौकिया हूं। मुझे अब ज्यादातर तय कर लिया गया है। पता लगाने के लिए एक मामूली बग (वास्तविक उपयोगिता कोड में) और सीडी-रोम के लिए एक कामकाज और मुझे समाप्त होना चाहिए। – user3399848

संबंधित मुद्दे