📄 fsys_ntfs.c.org
字号:
#endif /* corrupt */ errnum = ERR_FSYS_CORRUPT; mftr->attr_list_size = 0; mftr->attr_len = 0; mftr->attr_list = NULL; return 0; } mftr->attr_list_len += len; mftr->attr_list_off += len; goto again; }#endif mftr->attr_list = NULL; return 0;}#endifstatic intsearch_attribute (MFTR *mftr, unsigned long type, char *name){#ifdef DEBUG_NTFS printf("searching attribute %x <%s>\n", type, name);#endif mftr->attr_type = type; mftr->attr_name = name; mftr->attr_list = NULL; mftr->attr_list_len = 0; mftr->attr_list_size = 0; mftr->attr_list_off = 0; dcrem = dclen = 0;#ifndef NO_ATTRIBUTE_LIST if (find_attribute (mftr->mft, at_attribute_list, NONAME, &mftr->attr_list, &mftr->attr_list_size, &mftr->attr_list_len, &mftr->attr_list_off)) { if (mftr->attr_list_off&ATTR_RESIDENT) { /* resident at_attribute_list */ mftr->attr_list_size = 0;#ifdef DEBUG_NTFS printf("resident attribute_list len=%x\n", mftr->attr_list_len);#endif } else {#ifdef DEBUG_NTFS printf("non-resident attribute_list len=%x size=%x\n", mftr->attr_list_len, mftr->attr_list_size);#endif#ifndef NO_NON_RESIDENT_ATTRIBUTE_LIST init_run_list(mftr->attr_list, mftr->attr_list_len, &mftr->attr_list_runl, NULL); if (get_next_run (&mftr->attr_list_runl) == 0 || mftr->attr_list_runl.cnum == 0) mftr->attr_list_size = 0;#endif mftr->attr_list = NULL; mftr->attr_list_len = 0; } }#endif if (find_attribute (mftr->mft, type, name, &mftr->attr, &mftr->attr_size, &mftr->attr_len, &mftr->attr_flag)#ifndef NO_ATTRIBUTE_LIST || get_next_attribute_list (mftr, &mftr->attr_size)#endif ) {#ifndef NO_ATTRIBUTE_LIST if (! (mftr->attr_flag & ATTR_RESIDENT)) { init_run_list (mftr->attr, mftr->attr_len, &mftr->runl, (unsigned long *)&mftr->attr_inited); if (mftr->attr_inited > mftr->attr_size) mftr->attr_inited = mftr->attr_size; if (get_next_run (&mftr->runl) == 0) { mftr->attr_flag |= ATTR_RESIDENT; mftr->attr_len = 0; } } else mftr->attr_inited = mftr->attr_size;#endif return 1; } mftr->attr_type = 0; return 0;}static intget_run (RUNL *rl, unsigned long vcn, unsigned long *clp, unsigned long *lenp){ if (rl->evcn < vcn) return 0; if (rl->vcn > vcn) { rewind_run_list(rl); get_next_run(rl); } while (rl->vcn + rl->clen <= vcn) { if (get_next_run (rl) == 0) return 0; } if (clp) *clp = rl->cnum == 0 ? 0 : rl->cnum + vcn - rl->vcn; if (lenp) *lenp = rl->clen - vcn + rl->vcn; return 1;}static intsearch_run (MFTR *mftr, unsigned long vcn){ if (mftr->attr == NULL && ! search_attribute (mftr, mftr->attr_type, mftr->attr_name)) return 0; if (mftr->runl.svcn > vcn) search_attribute (mftr, mftr->attr_type, mftr->attr_name);#ifdef NO_ATTRIBUTE_LIST if (mftr->runl.evcn < vcn) return 0;#else while (mftr->runl.evcn < vcn) { if (get_next_attribute_list (mftr, NULL) == 0) { mftr->attr = NULL; return 0; } init_run_list (mftr->attr, mftr->attr_len, &mftr->runl, NULL); if (get_next_run (&mftr->runl) == 0) { mftr->attr = NULL; return 0; } }#endif return 1;}static unsigned longread_attribute (MFTR *mftr, unsigned long offset, char *buf, unsigned long len, RUNL *from_rl){ unsigned long vcn; unsigned long cnum, clen; unsigned long done = 0; unsigned long n; RUNL *rl; if (! from_rl && (mftr->attr_flag & ATTR_RESIDENT)) { /* resident attribute */ if (offset > mftr->attr_len) return 0; if (offset + len > mftr->attr_len) len = mftr->attr_len - offset; memmove (buf, mftr->attr + offset, len); return len; } vcn = offset / clustersize; offset %= clustersize; while (len > 0) { if (from_rl) rl = from_rl; else if (search_run (mftr, vcn) == 0) break; else rl = &mftr->runl; if (get_run (rl, vcn, &cnum, &clen) == 0) break; if (cnum == 0 && from_rl) break; n = clen * clustersize - offset; if (n > len) n = len; if (cnum == 0) { memset (buf, 0, n); } else if (! devread (cnum * (clustersize >> 9) + (offset >> 9), offset & 0x1ff, n, buf)) break; buf += n; vcn += (offset + n) / clustersize; done += n; offset = 0; len -= n; /* len always >= 0 */ } return done;}static int read_mft_record (unsigned long mftno, char *mft, unsigned long self){#ifdef DEBUG_NTFS printf("Reading MFT record: mftno=%d\n", mftno);#endif if (read_attribute (mmft, mftno * mft_record_size, mft, mft_record_size, self ? mft_run : NULL) != mft_record_size) return 0; if (! fixup_record (mft, "FILE", mft_record_size)) return 0; return 1;}#ifndef NO_NTFS_DECOMPRESSIONstatic unsigned long get_16_cluster (MFTR *mftr, unsigned long vcn){ unsigned long n = 0, cnum, clen; while (n < 16 && search_run (mftr, vcn) && get_run (&mftr->runl, vcn, &cnum, &clen) && cnum) { if (clen > 16 - n) clen = 16 - n; vcn += clen; while (clen--) cluster16[n++] = cnum++; } cluster16[n] = 0; return n;}static inline unsigned long compressed_block_size (unsigned char *src){ return 3 + (*(unsigned short *)src & 0xfff);}static unsigned long decompress_block (unsigned char *dest, unsigned char *src){ unsigned long head; unsigned long copied=0; unsigned char *last; unsigned long bits; unsigned long tag=0; /* high bit indicates that compression was performed */ if (! (*(unsigned short *)src & 0x8000)) { memmove (dest, src + 2, 0x1000); return 0x1000; } if ((head = *(unsigned short *)src & 0xFFF) == 0) /* block is not used */ return 0; src += 2; last = src + head; bits = 0; while (src <= last) { if (copied > 4096) {#ifdef DEBUG_NTFS printf("decompress error 1\n");#endif errnum = ERR_FSYS_CORRUPT; return 0; } if (! bits) { tag = *(unsigned char *)src; bits = 8; src++; if (src > last) break; } if (tag & 1) { unsigned long i, len, delta, code, lmask, dshift; code = *(unsigned short *)src; src += 2; if (! copied) {#ifdef DEBUG_NTFS printf("decompress error 2\n");#endif errnum = ERR_FSYS_CORRUPT; return 0; } for (i = copied - 1, lmask = 0xFFF, dshift = 12; i >= 0x10; i >>= 1) { lmask >>= 1; dshift--; } delta = code >> dshift; len = (code & lmask) + 3; for (i = 0; i < len; i++) { dest[copied] = dest[copied - delta - 1]; copied++; } } else dest[copied++] = *(unsigned char *)src++; tag >>= 1; bits--; } return copied;}#endifunsigned longntfs_read(char *buf, unsigned long len){ unsigned long ret;#ifdef STAGE1_5/* stage2 can't be resident/compressed/encrypted files, * but does sparse flag, cause stage2 never sparsed */ if ((cmft->attr_flag & ~ATTR_SPARSE) != ATTR_NORMAL) return 0; disk_read_func = disk_read_hook; ret = read_attribute (cmft, filepos, buf, len, 0); disk_read_func = NULL; filepos += ret;#else/*#ifndef NO_NTFS_DECOMPRESSION*/ //int off; //int vcn; //int size; unsigned long len0 = 0;/*endif*/ if (len <= 0 || filepos >= cmft->attr_size || (cmft->attr_flag & ATTR_ENCRYPTED)) return 0; if (filepos + len > cmft->attr_size) len = cmft->attr_size - filepos;#if 0 if(filepos >= cmft->attr_inited) {#ifdef DEBUG_NTFSprintf("reading uninitialized data 1\n");#endif memset(buf, 0, len); return len; } else if(filepos+len > cmft->attr_inited) { len0 = len; len = cmft->attr_inited - filepos; len0 -= len; } else len0 = 0;#endif#ifdef DEBUG_NTFSprintf("read filepos=%x filemax=%x inited=%x len=%x len0=%x\n",filepos,filemax,cmft->attr_inited,len,len0);#endif if ((cmft->attr_flag & (ATTR_COMPRESSED | ATTR_RESIDENT)) != ATTR_COMPRESSED) { if (cmft->attr_flag == ATTR_NORMAL) //if((cmft->attr_flag | ATTR_RESIDENT) == ATTR_RESIDENT) disk_read_func = disk_read_hook; ret = read_attribute (cmft, filepos, buf, len, 0); if (cmft->attr_flag == ATTR_NORMAL) //if((cmft->attr_flag | ATTR_RESIDENT) == ATTR_RESIDENT) disk_read_func = NULL; filepos += ret; if(ret == len && len0) { memset (buf + len, 0, len0); filepos += len0; ret += len0; } return ret; } ret = 0;#ifndef NO_NTFS_DECOMPRESSION /* NTFS don't support compression if cluster size > 4k */ if (clustersize > 4096) { errnum = ERR_FSYS_CORRUPT; return 0; } while (len > 0) {#ifdef DEBUG_NTFSprintf("Reading filepos=%x len=%x\n", filepos, len);#endif if (filepos >= dcoff && filepos < (dcoff + dclen)) {#ifdef DEBUG_NTFSprintf("decompress cache %x+%x\n", dcoff, dclen);#endif size = dcoff + dclen - filepos; if (size > len) size = len; memmove (buf, dcdbuf + filepos - dcoff, size); filepos += size; len -= size; /* len always >= 0 */ ret += size; buf += size; if (len == 0) { if (len0) {#ifdef DEBUG_NTFSprintf("reading uninitialized data 2\n");#endif memset (buf, 0, len0); filepos += len0; ret += len0; } return ret; } } vcn = filepos / clustersize / 16; vcn *= 16; off = filepos % (16 * clustersize); if (dcvcn != vcn || filepos < dcoff) dcrem = 0;#ifdef DEBUG_NTFSprintf("vcn %x off %x dcrem %x\n", vcn, off, dcrem);#endif if (dcrem) { unsigned long head; /* reading source */ if (dcslen < 2 || compressed_block_size (dcsptr) > dcslen) { if (cluster16[index16] == 0) { errnum = ERR_FSYS_CORRUPT; return ret; } if (dcslen) memmove (dcsbuf, dcsptr, dcslen); dcsptr = dcsbuf; while ((dcslen + clustersize) < DECOMP_SOURCE_BUFFER_SIZE) { if (cluster16[index16] == 0) break;#ifdef DEBUG_NTFSprintf("reading dcslen=%x cluster %x\n", dcslen, cluster16[index16]);#endif if (! devread (cluster16[index16] * (clustersize >> 9), 0, clustersize, dcsbuf + dcslen)) return ret; dcslen += clustersize; index16++;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -