Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Sektoreiden lukeminen levyltä (Windows)

ErroR++ [26.05.2012 19:35:18]

#

Moi!

Millä tavalla voi lukea sektoreita levyltä ja mahdollisesti kirjoittaakin? Olen yrittänyt tällä koodinpätkällä (hieman muuteltuna), mutta se väittää että levyn \\.\PhysicalDrive0 ensimmäinen sektori olisi jotakin ÙrÉNTFS! Sama tulee levystä \\.\C: (nehän on samat levyt). CD- ja DVD-levyistä se ei tulosta mitään, vaikka ne olisivatkin alustettuja ja jopa boottaavia. Virheellisistä levyistä se tulostaa vain x☺>.

reino [26.05.2012 21:07:21]

#

Se on aivan normaalia. Voit tallentaa syötteen tiedostoon ja lukea sitä heksaeditorilla. Kiinnostaa vaan mihin tarkoitukseen tarvitset tuota sektorien lukua. Voisit myös koittaa vaika windd ohjelmaa jos tarkoitus on muuten vaan lukea ja kirjoittaa sektoreita.

EDIT: Mistä tiedät, että sen sektorin ei pitäisi olla jotakin tuollaista?

Metabolix [26.05.2012 23:00:38]

#

Olet löytänyt aika ruman mallikoodin. Koodin laadusta kertovat mm. huono sisennys, muistivuoto ja lukuisat muut virheet. Eikö levyn avaaminen onnistu tavallisilla keinoilla (fopen, std::ifstream)?

Jos ohjelmasi tulostaa virheellisistä levyistä yhtään mitään, siinä on selvästi virhe. Itse asiassa virhe on jo löytämässäsi mallikoodissa: vaikka ReadSect palauttaa joissain (mutta ei kaikissa) virhetilanteissa virhekoodin, main-funktiossa ei tarkisteta tilannetta vaan jatketaan aina, kuin lukeminen olisi onnistunut. Ohjelman pitäisi antaa virheilmoitus ja vaikka sulkeutua eikä tulostaa mitään satunnaista tulosta.

Sektori on tavallaan hieman historiallinen termi, ja ainakaan sitä ei useinkaan kannata soveltaa tiedostojärjestelmiin, jotka usein käyttävät jotain toista blokkikokoa.

Perinteisesti sektorin pituus on kuitenkin 512 tavua, joten tuossa ei varmasti ole koko sektori. Datan tulostus tekstinä on yleensä järjetöntä, koska tulos riippuu merkistöstä. Toisaalta seassa voi toki olla kohtia, jotka oikeasti ovatkin tekstiä.

Kokeilin Linuxissa näin:

qemu-img create -f raw levykuva 1G
mkfs.ntfs -F levykuva
hexdump -C levykuva | head $((512 / 16))

Viimeisen rivin tulos (eli ensimmäisen sektorin sisältö):

00000000  eb 52 90 4e 54 46 53 20  20 20 20 00 02 08 00 00  |.R.NTFS    .....|
00000010  00 00 00 00 00 f8 00 00  00 00 00 00 00 00 00 00  |................|
00000020  00 00 00 00 80 00 80 00  ff ff 1f 00 00 00 00 00  |................|
00000030  04 00 00 00 00 00 00 00  ff ff 01 00 00 00 00 00  |................|
00000040  f6 00 00 00 01 00 00 00  11 8d a7 46 2c 34 ac 01  |...........F,4..|
00000050  00 00 00 00 fa 33 c0 8e  d0 bc 00 7c fb 68 c0 07  |.....3.....|.h..|
00000060  1f 1e 68 66 00 cb 88 16  0e 00 66 81 3e 03 00 4e  |..hf......f.>..N|
00000070  54 46 53 75 15 b4 41 bb  aa 55 cd 13 72 0c 81 fb  |TFSu..A..U..r...|
00000080  55 aa 75 06 f7 c1 01 00  75 03 e9 d2 00 1e 83 ec  |U.u.....u.......|
00000090  18 68 1a 00 b4 48 8a 16  0e 00 8b f4 16 1f cd 13  |.h...H..........|
000000a0  9f 83 c4 18 9e 58 1f 72  e1 3b 06 0b 00 75 db a3  |.....X.r.;...u..|
000000b0  0f 00 c1 2e 0f 00 04 1e  5a 33 db b9 00 20 2b c8  |........Z3... +.|
000000c0  66 ff 06 11 00 03 16 0f  00 8e c2 ff 06 16 00 e8  |f...............|
000000d0  40 00 2b c8 77 ef b8 00  bb cd 1a 66 23 c0 75 2d  |@.+.w......f#.u-|
000000e0  66 81 fb 54 43 50 41 75  24 81 f9 02 01 72 1e 16  |f..TCPAu$....r..|
000000f0  68 07 bb 16 68 70 0e 16  68 09 00 66 53 66 53 66  |h...hp..h..fSfSf|
00000100  55 16 16 16 68 b8 01 66  61 0e 07 cd 1a e9 6a 01  |U...h..fa.....j.|
00000110  90 90 66 60 1e 06 66 a1  11 00 66 03 06 1c 00 1e  |..f`..f...f.....|
00000120  66 68 00 00 00 00 66 50  06 53 68 01 00 68 10 00  |fh....fP.Sh..h..|
00000130  b4 42 8a 16 0e 00 16 1f  8b f4 cd 13 66 59 5b 5a  |.B..........fY[Z|
00000140  66 59 66 59 1f 0f 82 16  00 66 ff 06 11 00 03 16  |fYfY.....f......|
00000150  0f 00 8e c2 ff 0e 16 00  75 bc 07 1f 66 61 c3 a0  |........u...fa..|
00000160  f8 01 e8 08 00 a0 fb 01  e8 02 00 eb fe b4 01 8b  |................|
00000170  f0 ac 3c 00 74 09 b4 0e  bb 07 00 cd 10 eb f2 c3  |..<.t...........|
00000180  0d 0a 41 20 64 69 73 6b  20 72 65 61 64 20 65 72  |..A disk read er|
00000190  72 6f 72 20 6f 63 63 75  72 72 65 64 00 0d 0a 42  |ror occurred...B|
000001a0  4f 4f 54 4d 47 52 20 69  73 20 6d 69 73 73 69 6e  |OOTMGR is missin|
000001b0  67 00 0d 0a 42 4f 4f 54  4d 47 52 20 69 73 20 63  |g...BOOTMGR is c|
000001c0  6f 6d 70 72 65 73 73 65  64 00 0d 0a 50 72 65 73  |ompressed...Pres|
000001d0  73 20 43 74 72 6c 2b 41  6c 74 2b 44 65 6c 20 74  |s Ctrl+Alt+Del t|
000001e0  6f 20 72 65 73 74 61 72  74 0d 0a 00 00 00 00 00  |o restart.......|
000001f0  00 00 00 00 00 00 00 00  80 9d b2 ca 00 00 55 aa  |..............U.|

Heksadesimaalimuotoisen tulostuksen voi tehdä tulostamalla merkit yksitellen printf-funktion formaatilla %02x. Lisäksi tarvitaan tietenkin sopivia for-silmukoita ja oikeaan kohtaan välit ja rivinvaihdot.

ErroR++ [27.05.2012 11:36:02]

#

reino kirjoitti:

Se on aivan normaalia. Voit tallentaa syötteen tiedostoon ja lukea sitä heksaeditorilla.
...
EDIT: Mistä tiedät, että sen sektorin ei pitäisi olla jotakin tuollaista?

Tallensin myös datan, mutta sen pituus ei ollut kuin se 7 tavua (ÙRÉNTFS, kuten hexdumpin tulosteestakin näkyy).

Metabolix kirjoitti:

Olet löytänyt aika ruman mallikoodin. Koodin laadusta kertovat mm. huono sisennys, muistivuoto ja lukuisat muut virheet. Eikö levyn avaaminen onnistu tavallisilla keinoilla (fopen, std::ifstream)?

Olihan se aika ruma koodi, mutta lisäsin sisennykset ja muuta mukavaa. Täytyy kokeilla standardikirjaston keinoja.

Metabolix [27.05.2012 11:47:14]

#

Varmaan yritit tallentaa datan tekstinä, jolloin se tietenkin "loppuu" ensimmäiseen nollatavuun. On hölmöä väittää, että datan pituus olisi 7 tavua, kun koodistakin näkee, että datalle on varattu tilaa 512 tavua ja sen verran myös tiedostosta luetaan. Voit kirjoittaa binaaridataa esimerkiksi fwrite-funktiolla.

ErroR++ kirjoitti:

Olihan se aika ruma koodi, mutta lisäsin sisennykset ja muuta mukavaa.

Sisennysten lisääminen ei valitettavasti muuta sitä tosiseikkaa, että koodi on muutenkin huonosti tehty. Sitä et varmaan osannut korjata. Mainitsin sisennykset vain, koska ne ovat yksi varoittava merkki siitä, että koko koodi on huono: hyvät koodarit käytännössä aina myös sisentävät kunnolla.

ErroR++ [27.05.2012 12:06:48]

#

Helkkari sentään! Tein standardikirjaston funktioilla ja vähän kyllä ihmettelin kun kuulu vaan kiintolevyn kitinää ja rahinaa eikä loppua näkynyt. Sitten painoin Ctrl+C ja katsoin tiedostoa, mihin kaikki oli tullut. Muistio latas tiedostoa lähes kolme sekuntia, ja sitten älysin että olin tehnyt sinne vahinggossa loputtoman luupin ;D

Kiitos paljon!

Metabolix kirjoitti:

Sisennysten lisääminen ei valitettavasti muuta sitä tosiseikkaa, että koodi on muutenkin huonosti tehty. Sitä et varmaan osannut korjata.

En. Ihmettelin, kun tuli aina virheilmoituksia.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta