montowanie obrazów płyt

0

Programów do montowania obrazków iso etc jest sporo, z prostych i portable to np. PortableWinCDEmu
Czy trudno napisać taki program? To zadanie dla bardzo zaawansowanych osób? Czy są jakieś biblioteki gotowe (do mp3 jest BASS.dll, może do iso też coś jest?). Chodzi o samo zamontowanie obrazu iso, tak by odczytać z niego dane.

0

Jaki język programowania?? :)

0

Skoro o to pytasz, nawet nie masz po co zaczynać...
Zacznij może od napisania programu do wypakowywania iso, a potem pogadamy.

0

@Patryk27: Nie zauważyłem tego tagu. :) @nowe: najpierw musisz tą aplikacje zaplanować jak ma wyglądać i co robić ma, jedna funkcja nie wystarczy tutaj :P

1
nowe napisał(a):

Programów do montowania obrazków iso etc jest sporo, z prostych i portable to np. PortableWinCDEmu
Czy trudno napisać taki program? To zadanie dla bardzo zaawansowanych osób? Czy są jakieś biblioteki gotowe (do mp3 jest BASS.dll, może do iso też coś jest?). Chodzi o samo zamontowanie obrazu iso, tak by odczytać z niego dane.

To może od razu zapytaj, czy trudno się tworzy OS, przeglądarkę, sniffer, program do puszczania bąków czy o cokolwiek innego. Ciągle masz tego typu pytania. Co nimi chcesz osiągnąć? Sądzisz że tutaj wszyscy wiedzą coś o tych programach? Naprawdę?
Daruj sobie takie beznadziejne pytania, pytasz bez sensu, ciągle masz pomysł na program którego nie umiesz napisać. Bardziej byś zaimponował gdybyś jakiś program napisał bez pytania o gotowca na forum.
Mam dość twoich pytań na tematy na które tutaj na pewno nie znajdziesz odpowiedzi oczywiście przedzielanych zaawansowanymi pytaniami w stylu "jak używać procedur z unit2 w unit1" albo "czy warto czyścić memo przy prowadzeniu logów?". Naucz się podstaw, przestań liczyć na to że o wszystko zapytasz na forum i jak chcesz to sobie napisz taki program. Po prostu jak ogarniesz podstawy to się skup na jakimś temacie (np. jak ja teraz na budowie plików PE EXE) a wyniki przyjdą.

0

@-123oho
pytać nikt mi nie zabroni, a tak to na przyszłość będę wiedział, czy są dllki jakieś, czy coś do danej rzeczy i czy hardkorowe to. I mówisz tak jakbym miał zamiar wydawać 2000 programów w necie dla tysięcy ludzi, a w rzeczywistości wszystko co robię to głównie dla siebie jak np:

  • odtwarzacz mp3 z bass.dll po swojemu, taki który mi odpowiada
  • programy do wysyłania zdjęć na hostingi, w tym monitorowanie schowka, czy obrazek jest + autowysyłanie, drag and drop obrazków i wysyłanie w kolejce
  • pobieranie plików, też dllka
  • wysyłanie plików na dany serwis
  • rss
  • wyciąganie linków z serwisów typu adf.ly i z generatorów
  • program wysyłający coś do mojego skryptu php (+mysql)
  • kilka programów z logowaniem na kilka serwisów, pobieraniem pewnych rzeczy ze strony
  • bateria w notebooku
  • inne programiki

robię to tylko dla siebie. Pytać będę na forum o to co mi się podoba i nie oznacza to wcale, że mam w planach pisać dany program. A swoje posty nic nie wnoszące do tematu schowaj dla siebie, bo nie pomagasz. Żalić możesz się o księdza w kościele lub u znajomych, albo rodzinie.

@Docent (log off)
wygląd mnie nie interesuje ani nic. Chodziło tylko o zwykłe otworzenie pliku ISO by np. dało radę z niego zainstalować coś. To wszystko.

0

Btw - skąd uczysz się o PE (jakiś kurs, książka)? Także planowałem zacząć się tego w najbliższym czasie uczyć, ale jakoś coś mnie ciągle powstrzymuje :P

Polecę tutaj tutoriale "Iczelion" których używałem m.in. przy pisaniu szyfratora relokacji. Możesz mieć problemy żeby je znaleźć, bo nie są już hostowane na oryginalnej stronie, nie mniej gdzieś się po internecie krążą (google keywords: Iczelion PE tutorial).
Poza tym gynvael pisał swój prosty szyfrator sekcji .text pliku, to tam zacząłem przygodę, portując jego prosty system ładowania plików PE na FPC (można znaleźć jako MyPE w moim programie do szyfrowania relokacji - powinno się nadać na początek, sam używam nieco bardziej zaawansowanej wersji tego modułu).
Generalnie odradzę dokumentację M$ na temat PE, bo opisuje ona dużo rzeczy które w rzeczywistości nie mają miejsca.
No i oczywiście jest masa niesprecyzowanych rzeczy które w googlach można znaleźć jak się umie szukać.

--A teraz on-topic --

robię to tylko dla siebie.

To po cholerę nas w to mieszasz. Nie obchodzi mnie to czym się zajmujesz, serio. Zwłaszcza że każdy głupi umie wkleić gotowca z googlów/forum do programiku.

A swoje posty nic nie wnoszące do tematu schowaj dla siebie, bo nie pomagasz.

Ja ci pomagam odkryć fakt, że te forum ci nie pomoże.
Ciekaw jestem CZEGO od nas oczekujesz? Może wykładu na temat plików ISO? Albo jak napisać Emulator CDromów? :)

a tak to na przyszłość będę wiedział, (1) czy są dllki jakieś, (2) czy coś do danej rzeczy i (3) czy hardkorowe to.

(1) www.google.pl
(2) a po polsku?
(3) TBrain.active=false...

I mówisz tak jakbym miał zamiar wydawać 2000 programów w necie dla tysięcy ludzi, a w rzeczywistości wszystko co robię to głównie dla siebie

Jakie to ma znaczenie? I dlaczego uważasz że tak mówię?

Żalić możesz się o księdza w kościele lub u znajomych, albo rodzinie.

Żalenie<>Krytyka.
Zabronisz mi się żalić? Będę się żalić ile mi się podoba!!!

1

Koledzy - dajcie spokój - nie ma sensu żreć się o byle co;

@nowe - dlaczego najpierw nie przejrzysz sieci w poszukiwaniu inforamcji na temat tego formatu? Przeczytaj jakikolwiek na początek, choćby ten:

Wikipedia - ISO (obraz) napisał(a)

Obraz ISO to format zapisu danych dysków optycznych. Korzysta on z międzynarodowych standardów ISO. Najpopularniejszym typem obrazów są pliki .iso (Windows) lub .cdr (Mac OS X). Nazwa ISO została zaczerpnięta z ISO 9660 – standardu zapisu danych na płytach CD.

Tak jak inne archiwa danych, obraz ISO zawiera wszystkie dane z archiwizowanej płyty CD/DVD. Są one przechowywane w nieskompresowanym formacie. Do danych są także załączone metadane systemu plików, w tym także kod rozruchowy, struktury oraz atrybuty. ISO stanowi niezależne archiwum danych (tak jak ZIP lub RAR) – łączy pliki w jeden spójny format.

Dzięki niezawodności formatu oraz łatwości jego odtworzenia, ISO stał się jednym z najpopularniejszych sposobów rozprzestrzeniania informacji przez internet.

  • Plik obrazu można przechowywać na dysku twardym i emulować napęd z dana płytą, uzyskując identyczną funkcjonalność jak przy używaniu fizycznego nośnika. Jest to przydatne, gdy płyty używa się często, zmniejsza to zużycie napędu oraz płyt.
  • Pliki obrazu ułatwiają wymianę plików w sieci. W ten sposób na przykład rozprowadzane jest wiele dystrybucji systemu operacyjnego Linux
  • Łatwość zastosowania sektora rozruchowego

Tak więc czytając taki opis powinieneś wiedzieć, że format ten jest typem samodzielnego archiwum, którego przygotowanie na pierwszy rzut oka wydaje się trudne; Pisałeś kiedyś jakikolwiek program tworzący jakiekolwiek archiwa...? Mi się wydaje, że nie; Gdybyś posiadał taką wiedzę, to Twój poziom byłby na tyle wysoki, że nie napisałbyś tego tematu w dziale dla kompletnych laików; Poza tym napisałbyś coś sam i pokazał niedziałający kod, który ktoś pomógłby Ci zdebagować;

Więc nie dziw się, że doświadczysz krytycznych opinii na temat całego tego przedsięwzięcia;

Zapytasz, czy hardkorowe to? Odpowiem: owszem;

6

Ave!

Wstęp

zadane pytanie napisał(a)

Programów do montowania obrazków iso etc jest sporo, z prostych i portable to np. PortableWinCDEmu
Czy trudno napisać taki program? To zadanie dla bardzo zaawansowanych osób?

To pytanie okazało się na tyle ciekawe, że postanowiłem się trochę zagłębić w temat.
Zawsze lubiłem parsowanie i analizowanie różnych formatów plików a jako że z .iso nigdy nie miałem styczności, więc stwierdziłem że może warto coś z tym zrobić.

Okazuje się że format .iso jest dość kiepsko udokumentowany - tzn. jest udokumentowany całkiem nieźle, ale tylko w tekstach rodzaju oficjalna specyfikacja (która jest bardzo precyzyjna) - którą można znaleźć tutaj: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-119.pdf
Podjąłem więc trud zmierzenia się z tym dokumentem, napisanego stylem podobnym do książki telefonicznej i standardu C++. To co zrobiłem, planuję opisać tutaj tworząc przy okazji przypadkowo najlepszy polskojęzyczny opis tego formatu (bo jedyny).

Format ISO

Ok, więc co w takim pliku siedzi? Jest to dość ciekawy format, bo nazwa w tym przypadku nie kłamie - to naprawdę 'obraz płyty', czyli kopia bajt-po-bajcie tego co by się znalazło na płycie o identycznej zawartości (dygresja: z pominięciem tego, że na płyta CD dane są kodowane, logiczna sekwencja bajtów jest dzielona na bity inaczej niż wynikałoby to z ich reprezentacji NKB - z tego co pamiętam, kodowanie jest 8 logicznych do 13 fizycznych bitów, ale czytałem o tym dawno a hardware mnie nigdy nie interesowało specjalnie).

Jakie są tego praktyczne implikacje - na przykład dane na płycie CD są podzielone na sektory - podobnie dane w pliku są logicznie podzielone na sektory, i większość struktur danych musi się zaczynać na początku danego sektora - jest to oczywiście spowodowane tym że odtwarzacze CD operują na sektorach właśnie. Takie sektory mają po 0x800 (2048) bajtów.

Co dalej - na początku płyty zgodnej ze standardem (jak mówiłem, obraz płyty wygląda dokładnie tak samo jak dane na płycie, czyli sposób zapisywania danych również) jest 16 sektorów (0x8000 bajtów) ignorowanych - to oznacza, że pierwsze 32000 bajtów każdego pliku ISO to najczęściej zera...
Dygresja 2: Celem tego było pozwolenie na tworzenie płyt zgodnych z różnymi standardami jednocześnie - można w tych pierwszych 32000 bajtach nagrać nagłówki płyty zapisanej w jakimś innym formacie, w ten sposób płyta będzie mogła być rozpoznawana przez dwa czytniki obsługujące zupełnie inne standardy. Z tego co wiem, jest to wykorzystywane np. na płytach CD-Audio.

Po sekcji ignorowanej, znajduje się sekwencja Volume Descriptors (deskryptorów dysku?).
W obecnej (i jedynej) wersji standardu, jest 5 różnych deskryptorów:

  • Primary Volume Descriptor
  • Supplementary Volume Descriptor
  • Volume Partition Descriptor
  • Boot Record
  • Volume Descriptor Set Terminator

Z czego ja się interesowałem właściwie tylko Primary Volume Descriptorem (nie będę systemu bootował z tego, w pozostałych dwóch nie ma wiele ciekawego zazwyczaj).

Tak, a teraz przyznam się do czegoś w tajemnicy - tak naprawdę nie tylko czytałem dokumentację, napisałem nawet własny 'wypakowywać' plików ISO (w C99). Żeby się do czegoś przydał, będę wrzucał praktykę, tzn. fragmenty kodu w miejscach gdzie mówię o teorii, tzn. tym jak dane są zapisane. (komentarze dopisywane na bieżąco, po polsku)

No więc, żeby odczytać deskryptory, czytamy i analizujemy po kolei deskryptory jak leci, aż trafimy na Volume Descriptor Set Terminator.

void iso_inspect_descriptors(FILE *image) {
    struct volume_descriptor_generic_t generic_desc; // struktura mogąca przechowywać dowolny deskryptor - o wielkości sektora, bo tyle zajmuje każdy deskryptor (tzn. dane na końcu są ignorowane, ale między deskryptorami jest zawsze przerwa jednego sektora)
    
    fseek(image, ignored_sectors * sector_size, SEEK_SET); // omiń ignorowane sektory
    do  {
        fread(&generic_desc, sizeof(generic_desc), 1, image); // przeczytaj kolejny deskryptor
        iso_dump_descriptor(image, &generic_desc); // wykonaj analiza deskryptora
    } while(generic_desc.volume_data.type != vt_end); // jeśli to koniec, skończ.
}

Same typy deskryptorów są opisywane kolejnymi liczbami:

enum volume_type {
    vt_boot_descriptor,
    vt_primary_descriptor,
    vt_supplementart_descriptor,
    vt_partition_descriptor,
    vt_end = 0xFF
};

Jak wygląda funkcja iso_dump_descriptor (parsująca deskryptor i wykonująca różne działania w zależności od typu)?
Zacznijmy od tego że wszystkie deskryptory zaczynają się tak samo, taką oto strukturą:

struct volume_descriptor_common_t {
    uint8_t type;
    char magic[5]; // -> musi być <- `CD001`
    uint8_t version; // musi być 1, chyba że wyjdzie nowy standard z wersją 2
};

I po polu type rozpoznajemy jaki to deskryptor mamy przed sobą. Ja wyróżniam dwa typy:

void iso_dump_descriptor(FILE *image, struct volume_descriptor_generic_t *desc) {
    struct volume_descriptor_common_t common = desc->volume_data;
    printf("\nFound Descriptor <type=%X> <magic=%.5s> <version=%X>\n",
            common.type, common.magic, common.version); // informacje wspólne dla każdego typu deskryptora

    isetstr("    "); // takie tam małe API do łatwego indentowania wypisywanego tekstu, nie ma co go tu wklejać. Zmień sposób wcinania na 4 spacje.
    iindent(); // zwiększ poziom wcięcia
    if (common.type == vt_primary_descriptor) { 
        iso_dump_primary_descriptor(image, (struct primary_descriptor_t*)desc); // znany typ - primary descriptor
    } else if (common.type == vt_boot_descriptor) {
        iso_dump_boot_descriptor(image, (struct boot_descriptor_t*)desc); // znany typ - boot descriptor
    }
    iundent(); // zmniejsz poziom wcięcia
}

Żeby coś dalej mówić, trzeba podać jak wyglądają na płycie boot_descriptor_t i primary_descriptor_t. Oto i one (z komentarzami do ciekawszych pól):

struct boot_descriptor_t {
    struct volume_descriptor_common_t volume_data; // część wspólna wszystkich deskryptorów
    char boot_system_id[32];
    char boot_id[32];
    char boot_system_use[1976];
};

struct primary_descriptor_t {
    struct volume_descriptor_common_t volume_data; // część wspólna wszystkich deskryptorów
    uint8_t RESERVED(0); // nic 
    char system_id[32];
    char volume_id[32];
    char RESERVED(1)[8]; // nic
    uint64_t volume_space_size;
    char RESERVED(2)[32]; // nic
    uint32_t volume_set_size;
    uint32_t volume_seq_number;
    uint16_t logical_block_size_le;
    uint16_t logical_block_size_be;
    uint64_t path_table_size;
    uint32_t path_table_l_occurence;
    uint32_t path_table_l_optional_occurence;
    uint32_t path_table_m_occurence;
    uint32_t path_table_m_optional_occurence;
    struct directory_record_t root_directory; // that's it, deskryptor `korzenia dysku` - o tym później
    char ignored_rest[]; // tu jeszcze trochę pól, ale nas nie interesują
};

Jak już mówiłem, systemu z tego nie bootujemy, czyli do boot_descriptora tylko trochę informacji wypisujemy:

void iso_dump_boot_descriptor(FILE *image, struct boot_descriptor_t *desc) {
    UNUSED(image);

    iprintf("Known Type: Boot Descriptor\n");
    iprintf("Boot System ID: %.32s\n", desc->boot_system_id);
    iprintf("Boot ID: %.32s\n", desc->boot_id);
}

Za to primary_descriptor jest dużo ciekawszy - bo zawiera deskryptor (chyba nadużywam tego słowa) root_directory - czyli korzeń systemu plików. Więc dzięki temu możemy odczytać - i zapisać na dysk - całe drzewo katalogów!

No ale trochę na ekran też ląduje:

void iso_dump_primary_descriptor(FILE *image, struct primary_descriptor_t *desc) {
    iprintf("Known Type: Primary Descriptor\n");
    iprintf("System ID: %.32s\n", desc->system_id);
    iprintf("Volume ID: %.32s\n", desc->volume_id);
    iprintf("Logical Block Size: %x\n", desc->logical_block_size_le);
    iprintf("Filesystem Dump\n");

    iso_dump_record(image, "Root", &desc->root_directory, true); // przejdź przez cały system plików! Tzn. przejdź po wszystkich dzieciach korzenia. "Root" to nazwa folderu do którego idzie odczytane drzewo katalogów.
}

Dobra, czyli znowu kolejna funkcja niewiele robi i kieruje nas do innej (tym razem iso_dump_record) - i znowu, żeby dalej analizować, trzeba wiedzieć co się kryje pod root_directory. Taka oto struktura:

struct directory_record_t {
    uint8_t length; // długość w bajtach rekordu (tak, może mieć różną długość)
    uint8_t ext_attrib_length;
    uint32_t extent_le; // 'extent', czyli sektor w którym są dane
    uint32_t extent_be; // to co powyżej, tylko w big endian.
    uint32_t data_length_le; // ilość danych
    uint32_t data_length_be; // to co powyżej, tylko w big endian.
    struct date_time_t recording_time;
    uint8_t flags; // flagi dla pliku, jedyna którą się interesowałem to ta mówiąca czy plik 
    uint8_t file_unit_size;
    uint8_t interleave_gap_size;
    uint32_t volume_seq_number;
    uint8_t file_id_length; // długość id rekordu
    char file_id[]; // reszta bajtów to id rekordu - czyli jego nazwa...
};

A to, swoją drogą, flagi możliwe dla pliku:

enum dir_flags {
    df_hidden = 0x01,
    df_directory = 0x02,
    df_associated = 0x04,
    df_format_specified = 0x08,
    df_permissions_specified = 0x10,
    df_continue = 0x80
};

No więc w końcu to iso_dump_record - kod jest dość prosty do zrozumienia, więc zostaje podany jako tłumaczenie:

void iso_dump_record(FILE *image, const char *relpath, const struct directory_record_t *current, bool recursive) {
    const char *name = record_get_hr_name(current); // pobierz human-readable nazwę rekordu
    bool is_dir = current->flags & df_directory; // czy rekord jest folderem?

    iprintf("- %s%s%s\n", 
            is_dir ? "[" : "",
            name,
            is_dir ? "]" : ""); // wypisz nazwę pliku na ekran, jeśli jest folderem to [otocz nawiasami].

    if (recursive) { // jeśli zawartość rekordu ma być przetwarzana rekurencyjnie
        iindent(); // zwiększ poziom indentacji
        const char *childpath = path_combine(relpath, name); // połącz ścieżkę do folderu z kolejną nazwą

        if (is_dir) {
            iso_dump_record_list(image, childpath, current->extent_le, current->data_length_le);  // jeśli jest folderem, przetwórz wszystkie pliki
        } else {
            iso_dump_file(image, childpath, current->extent_le, current->data_length_le); // jeśli jest plikiem, przetwórz go (w moim przypadku - zapisz na dysk)
        }

        path_free(childpath); // zwolnij ścieżkę
        iundent(); // zmniejsz poziom indentacji
    }

    record_free_hr_name(name); // no i zwolnij nazwę pliku.
}

No i teraz zostały dwie (ciekawe) funkcje do omówienia - iso_dump_record_list i iso_fump_file.
Może najpierw record_list, bo jest trudniejsza trochę.

Otóż rekordy są zapisane konsekutywnie (no, jeden po drugim) w pamięci. I zawsze zaczynają się na początku sektora. Czyli po prostu zaczynamy czytać od początku sektora (może o tym nie wspomniałem jawnie wcześniej - pozycje rekordów są podane jako sektor w którym rekord się zaczyna, nie jako offset od początku pliku), i czytamy aż skończymy. Z tym skończeniem był spory problem, bo nie do końca wiem jak sprawdzić czy rekord jest ostatni (czytaj - nie ma takiego pola). Standard za to wymaga żeby wszystkie bajty w sektorze za rekordem były zerami, więc poradziłem sobie sprawdzając czy długość (pierwsze pole struktury) następnego rekordu jest zerem (nigdy nie prawda dla normalnego rekordu) - działa, ale czy to sposób jaki wymyślili twórcy formatu - nie wiem :]

No to tą serię sektorów jedziemy tak:

void iso_dump_record_list(FILE *image, const char *relpath, int sector, size_t data_size) {
    uint8_t *const sector_data = malloc(data_size); // zaalokuj dane (no na stosie to się ich dużo nie zmieści, szczególnie że wołamy rekurencyjnie)
    fread_at(sector_data, sector * sector_size, data_size, image); // wczytaj rekordy z pliku
    
    mkdir(relpath); // tworzymy folder. Tak, niezbyt przenośne, ale nie da się tego zrobić przenośnie w czystym, standardowym C.

    uint8_t *current_record_ptr = sector_data; // trochę kombinowania ze wskaźnikami tu jest... Wskaźnik na początek kolejnego rekordu.
    struct directory_record_t *current = (struct directory_record_t*)current_record_ptr; // kolejny rekord

    for(int ndx = 0; current->length != 0; ndx++) {
        iso_dump_record(image, relpath, current, ndx > 1); // dump obecnego rekordu - ta funkcja już była

        current_record_ptr += current->length; // no i zwiększamy wskaźnik do kolejnego rekordu o length bajtów...
        current = (struct directory_record_t*)current_record_ptr;
    }

    free(sector_data); // jeszcze zwalniamy dane.
}

Już prawie koniec. Jeszcze trzeba jakoś przetwarzać pliki - robimy to po prostu tak (czytamy z pliku iso, zapisujemy do nowego):

void iso_dump_file(FILE *image, const char *relpath, int sector, size_t data_size) {
    FILE *newf = fopen(relpath, "wb");

    uint8_t *const file_data = malloc(data_size);
    fread_at(file_data, sector * sector_size, data_size, image);

    fwrite(file_data, data_size, 1, newf); 

    fclose(newf);
}

Podsumowanie

Ok, bo 'trochę' sporo tego tekstu wyszło, trzeba by jakoś podsumować.

Tak więc zgadza się, parsowanie .iso nie jest bardzo prostą rzeczą, ale nie jest to coś czego się nie da zrobić samodzielnie jeśli ktoś chce.
Ale to dopiero początek, jeśli chcesz samodzielnie montować takie pliki to przed tobą jeszcze pewnie 3x tyle roboty...
Chyba że wykorzystasz do tego gotowy program/bibliotekę, ale to oczywiście zbyt lamerskie.

Oczywiście nie ręczę za zawsze-poprawność tego kodu, przede wszystkim rzeczą której na pewno nie zaimplementowałem jest tzw. path-table - dodatkowa struktura która trzyma m.in poprawne nazwy plików. Obecnie nazwy plików tworzone są nieco uszkodzone, tzn. zamiast index.html jest INDEX.HTML, albo zamiast lost+found jest LOST_FOUND (patologiczny przypadek, plus w nazwie pliku). Stwierdziłem że nie chce mi się z tym bawić, więc pozostawiam jako ćwiczenie dla czytelnika ;P

Ach, tak, wiem że nie do końca o to było pytanie... No ale skoro już odpowiedziałem to trudno, niech zostanie.

Any Questions? ;]

Wklejka na pastebin z kompletnym kodem:
http://pastebin.com/9Firwwbs

Edit: łee, ale brzydkie to kolorowanie C na forum, w porównaniu z VIM-em :/

Edit 2: wynik działania na obrazie z DSL:

D:\Projects\C\IsoRead>gcc iso.c -std=c99 -Wall -Wextra

D:\Projects\C\IsoRead>a

Found Descriptor <type=1> <magic=CD001> <version=1>
    Known Type: Primary Descriptor
    System ID: LINUX
    Volume ID: KNOPPIX
    Logical Block Size: 800
    Filesystem Dump
    - [.]
        - [.]
        - [..]
        - [BOOT]
            - [.]
            - [..]
            - [ISOLINUX]
                - [.]
                - [..]
                - BOOT.CAT
                - BOOT.MSG
                - F2
                - F3
                - GERMAN.KBD
                - ISOLINUX.BIN
                - ISOLINUX.CFG
                - LINUX24
                - LOGO.16
                - MINIRT24.GZ
        - INDEX.HTML
        - [KNOPPIX]
            - [.]
            - [..]
            - KNOPPIX
        - [LOST_FOUND]
            - [.]
            - [..]

Found Descriptor <type=0> <magic=CD001> <version=1>
    Known Type: Boot Descriptor
    Boot System ID: EL TORITO SPECIFICATION
    Boot ID:

Found Descriptor <type=2> <magic=CD001> <version=1>

Found Descriptor <type=FF> <magic=CD001> <version=1> 

1 użytkowników online, w tym zalogowanych: 0, gości: 1