Dobry wieczór,
jestem tutaj nowy, początkujący :-) i chciałbym się przywitać !
Do rzeczy:
piszę sobie taki prosty program poszukujący sektory na dysku mające sygnaturkę "NTFS " (wiadomo, chodzi o sektory z BB) i mam problem.
Samo przeszukiwanie polega na zmianie wskaźnika pozycji w pliku i poruszanie się po cylindrach.
.....|Sektor 254|Sektor 255|>>>(CYLINDER m-1/255/63)<<<|>>>(CYLINDER m/0/1)<<<|Sektor 0|Sektor 1|.....
(E MATKO, ma być .....|sektor 62|sektor 63| ..... )
(tak to wygląda, a przynajmniej myślę że mój programik odpowiada temu wyżej :-) )
I teraz :
mimo deklaracji zmiennej typu uint64_t zawierającej aktualną pozycje w pliku wartość ta nie przekracza uint32_t !! następuje przepełnienie (chyba) i programik startuje ze zmienna od nowa.
Próbowałem już sztuczek z
#define _FILE_OFFSET_BITS 64 oraz #define _LARGEFILE64_SOURCE
i bawiłem się funkcjami lseek64,open64,fopen64(?),fseeko64(?), a ze zmiennymi off_t i off64_t wyprawiałem cuda na kiju :-) no ale nic nie pomogło.
Sprawdzone na Ubuntu 11.04 32bit i 64bit oraz w kazdej wersji tegoz systemu wartosc zmiennej start_sector w programie gdb zawsze miała 4 bajty, np.
(gdb) print &start_sector
$2 = (uint64_t *) 0x7fffffffe1d8
(gdb) x/4x &start_sector-1
0x7fffffffe1d0: 0x00603130 0x00000000 0xec0ffc00 0x00000000
(gdb)
( 0xec0ffc00 ma być wartością pierwszego przesunięcia pliku pod CHS 2048/255/63 )
Proszę o jakąś radę, albo podpowiedź. NIE LICZĘ NA GOTOWCA :-)
#define _FILE_OFFSET_BITS 64
#define _LARGEFILE64_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
// from ntfs-3g - 2011.4.12
// : types.h
typedef uint8_t u8; /* Unsigned types of an exact size */
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef int8_t s8; /* Signed types of an exact size */
typedef int16_t s16;
typedef int32_t s32;
typedef int64_t s64;
typedef u16 le16;
typedef u32 le32;
typedef u64 le64;
typedef u16 sle16;
typedef u32 sle32;
typedef u64 sle64;
typedef u16 ntfschar;
typedef s64 VCN;
typedef sle64 leVCN;
typedef s64 LCN;
typedef sle64 leLCN;
typedef s64 LSN;
typedef sle64 leLSN;
// END : types.h
// : endians.h
#define __le16_to_cpu(x) (x)
#define __le32_to_cpu(x) (x)
#define __le64_to_cpu(x) (x)
#define __cpu_to_le16(x) (x)
#define __cpu_to_le32(x) (x)
#define __cpu_to_le64(x) (x)
#define __constant_le16_to_cpu(x) (x)
#define __constant_le32_to_cpu(x) (x)
#define __constant_le64_to_cpu(x) (x)
#define __constant_cpu_to_le16(x) (x)
#define __constant_cpu_to_le32(x) (x)
#define __constant_cpu_to_le64(x) (x)
// END : endians.h
// : layout.h
//#define magicNTFS __constant_cpu_to_le64(0x202020205346544e) /* "NTFS " */
unsigned long long int magicNTFS = 0x4e54465320202020;
unsigned int NTFS_SB_MAGIC = 0x5346544e; /* 'NTFS' */
unsigned short SECTOR_MARKER = 0xaa55;
typedef struct {
u16 bytes_per_sector; /* Size of a sector in bytes. */
u8 sectors_per_cluster; /* Size of a cluster in sectors. */
u16 reserved_sectors; /* zero */
u8 fats; /* zero */
u16 root_entries; /* zero */
u16 sectors; /* zero */
u8 media_type; /* 0xf8 = hard disk */
u16 sectors_per_fat; /* zero */
/*0x0d*/u16 sectors_per_track; /* Required to boot Windows. */
/*0x0f*/u16 heads; /* Required to boot Windows. */
/*0x11*/u32 hidden_sectors; /* Offset to the start of the partition
relative to the disk in sectors.
Required to boot Windows. */
/*0x15*/u32 large_sectors; /* zero */
/* sizeof() = 25 (0x19) bytes */
} __attribute__((__packed__)) BIOS_PARAMETER_BLOCK;
typedef struct {
u8 jump[3]; /* Irrelevant (jump to boot up code).*/
u64 oem_id; /* Magic "NTFS ". */
/*0x0b*/BIOS_PARAMETER_BLOCK bpb; /* See BIOS_PARAMETER_BLOCK. */
u8 physical_drive; /* 0x00 floppy, 0x80 hard disk */
u8 current_head; /* zero */
u8 extended_boot_signature; /* 0x80 */
u8 reserved2; /* zero */
/*0x28*/s64 number_of_sectors; /* Number of sectors in volume. Gives
maximum volume size of 2^63 sectors.
Assuming standard sector size of 512
bytes, the maximum byte size is
approx. 4.7x10^21 bytes. (-; */
s64 mft_lcn; /* Cluster location of mft data. */
s64 mftmirr_lcn; /* Cluster location of copy of mft. */
s8 clusters_per_mft_record; /* Mft record size in clusters. */
u8 reserved0[3]; /* zero */
s8 clusters_per_index_record; /* Index block size in clusters. */
u8 reserved1[3]; /* zero */
u64 volume_serial_number; /* Irrelevant (serial number). */
u32 checksum; /* Boot sector checksum. */
/*0x54*/u8 bootstrap[426]; /* Irrelevant (boot up code). */
u16 end_of_sector_marker; /* End of bootsector magic. Always is
0xaa55 in little endian. */
/* sizeof() = 512 (0x200) bytes */
} __attribute__((__packed__)) NTFS_BOOT_SECTOR;
// END : layout.h
// END : from ntfs-3g - 2011.4.12
// : DEFINES
int verbose = 1;
#define DEV "/dev/"
#define CYLINDERS 0
#define HEADS 255
#define SECTORS 63
#define SSIZE 512
#define NSEC 4
#define HALF_NSEC (NSEC/2)
#define CYLINDER_LBA 1 * HEADS * SECTORS
#define CYLINDER_BYTES CYLINDER_LBA * SSIZE
#define SOF(type,name) \
type name; \
if(verbose==1) \
{ \
printf("%d: sizeof(", __LINE__); \
printf("%s %s", #type, #name); \
printf(") == %d\n",sizeof(name)); \
}
struct harddg {
unsigned int c;
unsigned char h;
unsigned char s;
} harddg;
void fill_geometry(char *, struct harddg *);
// END : DEFINES
// : FUNCTIONS
void fill_geometry(char *device, struct harddg *g) {
char *LSTR = "/sys/block/";
char *RSTR = "/size";
//char *devpath = strcat(DEV, device);
//char *stok = strtok(devpath, "/");
uint64_t size = 0;
char *path = (char *)calloc(1,128);
char *pp = path;
pp = strcpy(pp, LSTR);
pp += strlen(pp);
pp = strcpy(pp, device);
pp += (strlen(pp));
pp = strcpy(pp, RSTR);
char *buf = (char *)calloc(1,64);
printf("fill_geometry: path %s\n",path);
if(strstr(path,device)) {
FILE *p = fopen(path,"rt");
if(p) {
fread((char *)buf, 64, 1, p);
if(buf) {
size = strtoull(buf,NULL,0); // ???
uint32_t cylinders = size / HEADS / SECTORS;
g->c = cylinders;
g->h = HEADS;
g->s = SECTORS;
fclose(p);
//return size;
} else {
printf("fill_geometry: %s not readed\n",path);
fclose(p);
//return 0;
}
} else {
printf("fill_geometry: %s not opened\n",path);
//return 0;
}
} else {
printf("fill_geometry: string %s error\n",device);
//return 0;
}
}
// END : FUNCTIONS
int main(int argc, char *argt[]) {
if(argc<2) {
printf("%s: use eg. %s sda\n",argt[0],argt[0]);
return 1;
}
char *progname = argt[0];
char *device = argt[1];
char *devpath = (char *)calloc(1,10);
devpath = strcpy(devpath, DEV);
devpath = strcat(devpath, device);
if(argc==2 && device && (strlen(device)==3 || strlen(device)==4)) {
struct harddg *hdg = (struct harddg *)calloc(1,sizeof(struct harddg));
fill_geometry(device, hdg);
//if(!size) {
// printf("%s: fill_geometry error\n", progname);
// return 1;
//}
int devicef = open64(devpath, O_LARGEFILE | O_RDONLY, "rb");
//FILE *devicef = fopen(devpath, "rb");
if(!devicef) {
printf("%s: device %s not opened\n", progname, device);
return 1;
}
//fseek(devicef,0L,SEEK_SET);
unsigned int start_cylinder = 2048;
unsigned int end_cylinder = hdg->c;
SOF(uint64_t,start_sector);//= (start_cylinder * HEADS * SECTORS * SSIZE) - (SSIZE * HALF_NSEC);
//fseek(devicef, start_sector, SEEK_SET);
int nsec = 0;
for( ; start_cylinder<end_cylinder+1; start_cylinder++) {
start_sector = (start_cylinder * HEADS * SECTORS * SSIZE) - (SSIZE * HALF_NSEC);
if(lseek64(devicef, start_sector, SEEK_SET)<0) {
printf("%s: Error seek not set\n", progname);
//fclose(devicef);
close(devicef);
return 1;
}
char *buffer = (char *)calloc(SSIZE*NSEC,1);
//size_t readed = fread(buffer, 1, SSIZE*NSEC, devicef);
size_t readed = read(devicef, buffer, 1 * SSIZE*NSEC);
if(!(start_cylinder%1024))
printf("%s:\tCYLINDER: %d\n",progname,start_cylinder);
if(!(start_sector%(1*1024*1024)))
printf("%s:\t\tOFFSET: %lu\n",progname,start_sector);
for(nsec = 0; nsec < NSEC; nsec++) {
NTFS_BOOT_SECTOR *ntfs_bs = (NTFS_BOOT_SECTOR *)&buffer[nsec*SSIZE];
if(ntfs_bs->oem_id==magicNTFS)
{
printf("%s: MAGICNTFS found on \
%u/%d cylinder\n", progname, start_cylinder, nsec);
}
}
free(buffer);
//start_sector = (start_cylinder * HEADS * SECTORS * SSIZE) - (SSIZE * HALF_NSEC);
//fseek(devicef, start_sector, SEEK_SET);
}
close(devicef);
} else {
printf("%s: bad arguments\n", progname);
}
}