📄 fsys_ntfs.c.org
字号:
} } /* flush destination */ dcoff += dclen; dclen = 0; while (dcrem && dclen < DECOMP_DEST_BUFFER_SIZE && dcslen >= 2 && (head = compressed_block_size (dcsptr)) <= dcslen) { size = decompress_block (dcdbuf + dclen, dcsptr); if (dcrem >= 0x1000 && size != 0x1000) { errnum = ERR_FSYS_CORRUPT; return ret; } dcrem -= size; dclen += size; dcsptr += head; dcslen -= head; } continue; } dclen = dcrem = 0;#ifdef DEBUG_NTFSprintf("get next 16 clusters\n");#endif switch (get_16_cluster (cmft, vcn)) { case 0:#ifdef DEBUG_NTFSprintf("sparse\n");#endif /* sparse */ size = 16 * clustersize - off; if (size > len) size = len;#ifndef STAGE1_5 memset (buf, 0, size);#endif filepos += size; len -= size; /* len always >= 0 */ ret += size; buf += size; break; case 16:#ifdef DEBUG_NTFSprintf("uncompressed\n");#endif /* uncompressed */ index16 = off / clustersize; off %= clustersize; while (index16 < 16) { size = clustersize - off; if (size > len) size = len; if (! devread (cluster16[index16] * (clustersize >> 9) + (off >> 9), off & 0x1ff, size, buf)) return ret; filepos += size; len -= size; /* len always >= 0 */ ret += size; if (len == 0) return ret; off = 0; buf += size; index16++; } break; default:#ifdef DEBUG_NTFSprintf("compressed\n");#endif index16 = 0; dcvcn = vcn; dcoff = vcn * clustersize; dcrem = cmft->attr_inited - dcoff; if (dcrem > 16 * clustersize) dcrem = 16 * clustersize; dcsptr = dcsbuf; dcslen = 0; } } if (len0) {#ifdef DEBUG_NTFSprintf("reading uninitialized data 3\n");#endif memset (buf, 0, len0); filepos += len0; ret += len0; }#else errnum = ERR_FSYS_CORRUPT; #endif /*NO_NTFS_DECOMPRESSION*/#endif /*STAGE1_5*/ return ret;}int ntfs_mount (void){#define sb ((char *)FSYS_BUF) unsigned long mft_record; unsigned long spc; /* sectors per cluster */ if (((current_drive & 0x80) || (current_slice != 0)) && (current_slice != /*PC_SLICE_TYPE_NTFS*/7) && (current_slice != /*PC_SLICE_TYPE_NTFS*/0x17)) return 0; if (! devread (0, 0, 512, (char *) FSYS_BUF)) return 0; /* Cannot read superblock */ //if (sb[3] != 'N' || sb[4] != 'T' || sb[5] != 'F' || sb[6] != 'S') if (*(long *)(sb + 3) != 0x5346544E) /* "NTFS" */ return 0; blocksize = *(unsigned short *)(sb + 0xb); spc = *(unsigned char *)(sb + 0xd); clustersize = spc * blocksize; mft_record_size = (long)(*(char *)(sb + 0x40)); /* XXX: signed value */ index_record_size = *(char *)(sb + 0x44); /* XXX */ if (((long)mft_record_size) > 0) mft_record_size *= clustersize; else if (((long)mft_record_size) < 0) mft_record_size = (1 << (-mft_record_size)); else return 0; index_record_size *= clustersize; mft_record = *(unsigned long *)(sb + 0x30); /* only support 32 bit */ spc = clustersize >> 9; /* clustersize / 512 */ if (mft_record_size > MAX_MFT_RECORD_SIZE || index_record_size > MAX_INDEX_RECORD_SIZE) { /* only support 1k MFT record, 4k INDEX record */ return 0; }#ifdef DEBUG_NTFS printf("spc=%x mft_record=%x:%x\n", spc, *(long long *)(sb+0x30));#endif if (! devread (mft_record * spc, 0, mft_record_size, mmft->mft)) return 0; /* Cannot read superblock */ if (! fixup_record (mmft->mft, "FILE", mft_record_size)) return 0;#ifndef NO_ALTERNATE_DATASTREAM is_ads_completion = 0;#endif if (! search_attribute (mmft, at_data, NONAME)) return 0; *mft_run = mmft->runl; *path_ino = FILE_ROOT; return 1;#undef sb}intntfs_dir (char *dirname){ char *rest, ch; unsigned long namelen; unsigned long depth = 0; unsigned long flag = 0; unsigned long record_offset; unsigned long my_index_record_size; unsigned char *index_entry = 0, *entry, *index_end; unsigned long i; int chk_sfn = 1; /* main loop to find desired directory entry */loop:#ifdef DEBUG_NTFS printf("dirname=%s\n", dirname);#endif if (! read_mft_record (path_ino[depth], cmft->mft, 0)) {#ifdef DEBUG_NTFS printf("MFT error 1\n");#endif errnum = ERR_FSYS_CORRUPT; return 0; } /* if we have a real file (and we're not just printing possibilities), then this is where we want to exit */ if (! *dirname || isspace (*dirname) || *dirname == ':') {#ifndef STAGE1_5#ifndef NO_ALTERNATE_DATASTREAM if (*dirname == ':' && print_possibilities) { char *tmp; /* preparing ADS name completion */ for (tmp = dirname; *tmp != '/'; tmp--); for (tmp++, rest = fnbuf; *tmp && ! isspace (*tmp); *(rest++) = *(tmp++)) if (*tmp == ':') dirname = rest; *(rest++) = '\0'; is_ads_completion = 1; search_attribute (cmft, at_data, dirname + 1); is_ads_completion = 0; if (errnum == 0) { if (print_possibilities < 0) return 1; errnum = ERR_FILE_NOT_FOUND; } return 0; }#endif#endif if (*dirname == ':') dirname++; for (rest = dirname; (ch = *rest) && ! isspace (ch); rest++); *rest = 0;#ifdef DEBUG_NTFS printf("got file: search at_data\n");#endif if (! search_attribute (cmft, at_data, dirname)) { errnum = ((*(dirname - 1) == ':') ? ERR_FILE_NOT_FOUND : ERR_BAD_FILETYPE); *rest = ch; return 0; } *rest = ch; filemax = cmft->attr_size;#ifdef DEBUG_NTFS printf("filemax=%x\n", filemax);#endif return 1; } if (depth >= (MAX_DIR_DEPTH - 1)) { errnum = ERR_FSYS_CORRUPT; return 0; } /* continue with the file/directory name interpretation */ while (*dirname == '/') dirname++; for (rest = dirname; (ch = *rest) && ! isspace (ch) && ch != '/' && ch != ':'; rest++); *rest = 0; if (! search_attribute (cmft, at_index_root, "$I30")) { errnum = ERR_BAD_FILETYPE; return 0; } read_attribute (cmft, 0, fnbuf, 16, 0); my_index_record_size = *(unsigned long *)(fnbuf + 8); if (my_index_record_size > MAX_INDEX_RECORD_SIZE) { errnum = ERR_FSYS_CORRUPT; return 0; }#ifdef DEBUG_NTFS printf("index_record_size=%x\n", my_index_record_size);#endif if (cmft->attr_size > MAX_INDEX_RECORD_SIZE) { errnum = ERR_FSYS_CORRUPT; return 0; } read_attribute (cmft, 0, index_data, cmft->attr_size, 0); index_end = (unsigned char *)(index_data + cmft->attr_size); index_entry = (unsigned char *)(index_data + 0x20); record_offset = -1;//#ifndef STAGE1_5// if (print_possibilities && ch != '/' && ch != ':' && !*dirname)// {// print_possibilities = -print_possibilities;// /* fake '.' for empty directory */// print_a_completion (".");// }//#endif if (search_attribute (cmft, at_bitmap, "$I30")) { if (cmft->attr_size > MAX_INDEX_BITMAP_SIZE) { errnum = ERR_FSYS_CORRUPT; return 0; } read_attribute (cmft, 0, (char *)bitmap_data, cmft->attr_size, 0); if (search_attribute (cmft, at_index_allocation, "$I30") == 0) { errnum = ERR_FSYS_CORRUPT; return 0; } for (record_offset = 0; record_offset * my_index_record_size < cmft->attr_size; record_offset++) { unsigned long bit = (1 << (record_offset & 3)); unsigned long byte = (record_offset >> 3);#ifdef DEBUG_NTFS printf("record_offset=%x\n", record_offset);#endif if ((bitmap_data[byte] & bit)) break; } if (record_offset * my_index_record_size >= cmft->attr_size) record_offset = -1; } do { entry = index_entry; index_entry += *(unsigned short *)(entry + 8); if (entry + 0x50 >= index_entry || entry >= index_end || index_entry >= index_end || (entry[0x12] & 2)) { if ((long)record_offset == -1 || ! read_attribute (cmft, record_offset * my_index_record_size, index_data, my_index_record_size, 0)) { if (errnum == 0) {#ifndef STAGE1_5 if (print_possibilities < 0) {#if 0 putchar ('\n');#endif return 1; }#endif errnum = ERR_FILE_NOT_FOUND; } *rest = ch; return 0; } if (! fixup_record (index_data, "INDX", my_index_record_size)) {#ifdef DEBUG_NTFS printf("index error\n");#endif errnum = ERR_FSYS_CORRUPT; return 0; } entry = (unsigned char *)(index_data + 0x18 + (*(unsigned short *)(index_data + 0x18))); index_entry = entry + (*(unsigned short *)(entry + 8)); index_end = (unsigned char *)(index_data + my_index_record_size - 0x52); for (record_offset++; record_offset * my_index_record_size < cmft->attr_size; record_offset++) { unsigned long bit = (1 << (record_offset & 3)); unsigned long byte = (record_offset >> 3); if ((bitmap_data[byte] & bit)) break; } if (record_offset * my_index_record_size >= cmft->attr_size) record_offset = -1;#ifdef DEBUG_NTFS printf("record_offset=%x\n", record_offset);#endif } flag = entry[0x51]; if ((long)(path_ino[depth + 1] = (*(unsigned long *)entry)) < 16)// if (path_ino[depth + 1] < 16) continue; namelen = entry[0x50]; //if(index_data[0x48]&2) printf("hidden file\n");#ifndef STAGE1_5 /* skip short file name */ if (flag == 2 && print_possibilities && ch != '/' && ch != ':') continue;#endif for (i = 0, entry += 0x52; i < namelen; i++, entry += 2) { unsigned long c = *(unsigned short *)entry; if (c == ' '|| c >= 0x100) fnbuf[i] = '_'; else fnbuf[i] = c; } fnbuf[namelen] = 0;#ifdef DEBUG_NTFS printf("FLAG: %d NAME: %s inum=%d\n", flag,fnbuf,path_ino[depth+1]);#endif //uncntrl(fnbuf); chk_sfn = substring (dirname, fnbuf, 1);#ifndef STAGE1_5 if (print_possibilities && ch != '/' && ch != ':' && (! *dirname || chk_sfn <= 0)) { if (print_possibilities > 0) print_possibilities = -print_possibilities; print_a_completion (fnbuf); }#endif /* STAGE1_5 */ } while (chk_sfn != 0 || (print_possibilities && ch != '/' && ch != ':')); *(dirname = rest) = ch; depth++; /* go back to main loop at top of function */ goto loop;}#ifdef DEBUG_NTFSint dump_block(char *msg, char *buf, unsigned long size){ unsigned long l = (size+15)/16; unsigned long off; unsigned long i, j; int c; printf("----- %s -----\n", msg); for( i = 0, off = 0; i < l; i++, off+=16) { if(off<16) printf("000%x:", off); else if(off<256) printf("00%x:", off); else printf("0%x:", off); for(j=0;j<16;j++) { c = buf[off+j]&0xff; if( c >= 16 ) printf("%c%x",j==8?'-':' ',c); else printf("%c0%x",j==8?'-':' ',c); } printf(" "); for(j=0;j<16;j++) { char c = buf[off+j]; printf("%c",c<' '||c>='\x7f'?'.':c); } printf("\n"); }}/*#endif*/#endif /* FSYS_NTFS */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -