Kako pristupati čvrstim diskovima

Teme koje se tiču programiranja

Moderator: Urednik

Post Reply

Poznata ličnost
Poznata ličnost
offline
User avatar

Posts: 81
Joined: 03 Apr 2012, 19:18

Post Napisano: 27 Dec 2012, 22:38


Zdravo svima. Da ne bi u startu bio pogrešno shvaćen, ovo što ću vas pitati ima za cilj prosto da savladam programiranje i nešto malo više oko hardvera. Hteo sam da u windows-u i linux-u napravim gui aplikaciju koja bi imala jedan list box, dva dugmeta, jedan progres bar i combobox. Cela ta aplikacija bi imala za cilj da pristupi svakom čvrstom disku, izborom čvrstog diska preko combobox, pritiskon da dugme pretraga izrši se pretraga, kompletna pretraga se ispiše u list box i kada pritisnemo na dugme briši da u svakom sektoru upiše nule bez obzira na to da li imali particije ili u kom je formatu hard disk itd. E sad mene zanima na koje sve načine mogu da pristupim čvrstom disku nevezano kako je povezan(da li preko usb ili sata ili ata)? Voleo bi da me uputiti kroz razne forume, knjige, skripte itd. U napred hvala na bilo kakvom odgovoru.

P.S. Ovo pitanje ima za cilj malo i edukacije da ljudi koji žele da znaju nešto više o memorijama mogu da saznaju.



Administrator
Administrator
offline
User avatar

Posts: 4041
Joined: 04 Feb 2011, 20:32
Location: Beograd
Contact:

Post Napisano: 28 Dec 2012, 03:02


U Unixu su svi uređaji datoteke. Znači, koristio bi standardni API za pristup datotekama za upis na particije skladišnog uređaja.

E sad... To postavlja pitanje kako doći do liste skladišnih uređaja/particija.

Funkcije i definicije u <fstab.h> nam daju pristup /etc/fstab. Naravno u /etc/fstab se ne moraju nalaziti sve particije na dostupnim skladišnim uređajima ili može sadržati i neke virtualne sisteme datoteka (napr: proc i sysfs). Nešto o tome ima i u:

Code: Select all

man 5 fstab
Za dobijanje liste skladišnih uređaja/particija bi koristio proc (/proc) sistem datoteka. Lista svih partcija se nalazi u:

Code: Select all

/proc/partitions
Za više informacija o proc sistemu datoteka možeš pogledati i:

Code: Select all

man 5 proc



Administrator
Administrator
offline
User avatar

Posts: 4041
Joined: 04 Feb 2011, 20:32
Location: Beograd
Contact:

Post Napisano: 28 Dec 2012, 06:12


bocke wrote:Za dobijanje liste skladišnih uređaja/particija bi koristio proc (/proc) sistem datoteka. Lista svih partcija se nalazi u:

Code: Select all

/proc/partitions
Jednostavan primer parsiranja /proc/partitions:

Code: Select all

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

int main(void)
{
	typedef struct {
		unsigned short int major;
		unsigned short int minor;
		unsigned int blocks;
		char device[8];
	} fslist;

	fslist mydisks[32];

	int c = 0, d = 0, i = 0, n = 0, devicelen = 0;
	
	FILE *procfile;
	char *filename = "/proc/partitions";

	if (! (procfile = fopen(filename, "r"))){
		perror(strerror(errno));
		exit (-1);
	}
	else
	{
		// Preskoči prve dve linije
		for (i=0; i<2; i++){while ((c = fgetc(procfile)) != '\n');}

		char buff[256];
		char **temp;
		temp = malloc(1024 * sizeof(char));
		while((fgets(buff, 256, procfile)) != NULL){
			c = 0;
			temp[c] = strtok(buff, " ");
			while(temp[c] != NULL){
				if (c == 0) mydisks[n].major = atoi(temp[c]);
				if (c == 1) mydisks[n].minor = atoi(temp[c]);
				if (c == 2) mydisks[n].blocks = atoi(temp[c]);
				if (c == 3) {
					strncpy(mydisks[n].device, temp[c], 8);
					devicelen = strlen(mydisks[n].device);
					mydisks[n].device[devicelen - 1]  = '\0';
#ifdef DEBUG
					printf("%d, %d, %s\n", n, c, mydisks[n].device);
#endif
				}

				c++; 
				temp[c] = strtok(NULL, " ");
			}
			n++;

		}
		free(temp);

		for (d = 0; d < n; d++)
		{
			printf("Skladišni uređaj br %d:\n", d);
			printf("\t Oznaka: %s\n", mydisks[d].device);
			printf("\t Blokovi: %d\n", mydisks[d].blocks);
			printf("\t Čvor uređaja: %d %d\n", mydisks[d].major, mydisks[d].minor);
		}

	}

	fclose(procfile);

	return 0;
}
Izlaz programa:
procfs.png
procfs.png (9.73 KiB) Viewed 1540 times
Uporedi izlaz programa sa sadržajem /proc/partitons. Naravno, ovo se možda može i pametnije uraditi, ali ovo radi sasvim ok. :)

Evo ga i kompajlirani program (32-bitni):
procfs.gz
(2.41 KiB) Downloaded 154 times
Edit

Dao sam primer u C-u zato što sam najbolje upoznat s njim. Program takođe možeš napisati i u C++ ili nekom od popularnih skript jezika (koji su verovatno jednostavniji za ovakve stvari od C-a) kao što su Perl, Python ili Ruby.

U C-u se ovo verovatno isto može olakšati korišćenjem neke eksterne biblioteke. Ili otežati korišćenjem neke biblioteke sa funkcijama regularnih izraza. :)

Edit 2

Ako praviš gtk aplikaciju, logično je da baciš pogled na potencijalno korisne funkcije koje sadrži glib.



Administrator
Administrator
offline
User avatar

Posts: 4041
Joined: 04 Feb 2011, 20:32
Location: Beograd
Contact:

Post Napisano: 28 Dec 2012, 08:39


Evo ti i primer, recimo, malog programa za backup MBR-a zasnovanog na gornjem kodu:

Code: Select all

/* 
 * DESCRIPTION: Small & stupid program to save mbr
 * AUTHOR: Bojan Popovic, 2012
 * LICENSE: CC-BY-SA
 * Use at your own risk, no warranty in any (legal or non-legal) form.
 */

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>
#include <errno.h>

int main(void)
{
	typedef struct {
		unsigned short int major;
		unsigned short int minor;
		unsigned int blocks;
		char device[8];
	} fslist;

	fslist mydisks[32];

	int c = 0, d = 0, i = 0, n = 0, devicelen = 0;
	
	FILE *procfile;
	char *filename = "/proc/partitions";
	char disks[32][16];

	if (! (procfile = fopen(filename, "r"))){
		perror(strerror(errno));
		exit (-1);
	}
	else
	{
		// Skip first two lines
		for (i=0; i<2; i++){while ((c = fgetc(procfile)) != '\n');}

		char buff[256];
		char **temp;
		temp = malloc(1024 * sizeof(char));
		while((fgets(buff, 256, procfile)) != NULL){
			c = 0;
			temp[c] = strtok(buff, " ");
			while(temp[c] != NULL){
				if (c == 0) mydisks[n].major = atoi(temp[c]);
				if (c == 1) mydisks[n].minor = atoi(temp[c]);
				if (c == 2) mydisks[n].blocks = atoi(temp[c]);
				if (c == 3) {
					strncpy(mydisks[n].device, temp[c], 8);
					devicelen = strlen(mydisks[n].device);
					mydisks[n].device[devicelen - 1]  = '\0';
#ifdef DEBUG
					printf("%d, %d, %s\n", n, c, mydisks[n].device);
#endif
				}

				c++; 
				temp[c] = strtok(NULL, " ");
			}
			n++;

		}
		free(temp);

		int e = 0;
		for (d = 0; d < n; d++)
		{
			int len = strlen(mydisks[d].device);
			if (isalpha(mydisks[d].device[len - 1]))
			{
				snprintf(disks[e], 10, "/dev/%s", mydisks[d].device);
				e++;
			}
		}

		puts("Pronađeni su sledeći diskovi:\n");
		for (d = 0; d < e; d++){
			printf("    %d) %s \n", d, disks[d]);
		}

		puts("\nUnesi broj diska čiji MBR želiš da sačuvaš:");
		int izbor;
		izbor = getc(stdin) - 48;

		if (izbor >= e){
			puts("Uneli ste neispravan broj!");
			exit(-1);
		}

		FILE *mbr;
		FILE *out;
		char *izlaz = "mbr.backup";
		mbr = fopen(disks[izbor], "r");

		if (mbr == NULL){
			perror(strerror(errno));
			exit( -1);
		}
		else
		{
			if ((out = fopen(izlaz, "w"))){
				uint16_t d = 0;
				while(d < (512))
				{
					fputc(fgetc(mbr), out);
					d++;
				}
			}
			else
			{
				perror(strerror(errno));
				exit(-1);
			}
				
		}
		
		fclose(mbr);
		fclose(out);
	}

	fclose(procfile);

	return 0;
}
Btw, ne preporučujem njegovo korišćenje. Nije detaljnije istestiran i vrlo je rudimentaran. Ali kod mene radi i pokazuje princip direktnog čitanja disk uređaja. Naravno, da bi se ovo pokrenulo, moraš biti root. Postaviću i primer izvršavanja kasnije.

Edit

Stiže slika:
mbrbackup.png


Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest