⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dir.c

📁 EM85XX读NTFS修正代码包
💻 C
📖 第 1 页 / 共 3 页
字号:
 *   011     5      23           54 *   0111    6      55           119 *   More values are hopefully not needed, as the file position has currently *   64 bits in total. *//* Find an entry in the directory. Return 0 if not found, otherwise copy the * entry to the result buffer. */int ntfs_getdir(ntfs_iterate_s *walk){	int length = walk->dir->vol->mft_record_size;	int retval, error;	/* Start at the index root. */	char *root = ntfs_malloc(length);	ntfs_io io;	if (!root)		return -ENOMEM;	io.fn_put = ntfs_put;	io.param = root;	io.size = length;	error = ntfs_read_attr(walk->dir, walk->dir->vol->at_index_root, I30,			       0, &io);	if (error) {		ntfs_error("Not a directory\n");		return 0;	}	walk->block = -1;	/* FIXME: Move these to walk. */	walk->dir->u.index.recordsize = NTFS_GETU32(root + 0x8);	walk->dir->u.index.clusters_per_record = NTFS_GETU32(root + 0xC);	/* FIXME: Consistency check. */	/* Skip header. */	retval = ntfs_getdir_iterate(walk, root, root + 0x20);	ntfs_free(root);	return retval;}/* Find an entry in the directory by its position stack. Iteration starts * if the stack is 0, in which case the position is set to the first item * in the directory. If the position is nonzero, return the item at the * position and change the position to the next item. The position is -1 * if there are no more items. */int ntfs_getdir_byposition(ntfs_iterate_s *walk){	walk->type = BY_POSITION;	return ntfs_getdir(walk);}/* Find an entry in the directory by its name. Return 0 if not found. */int ntfs_getdir_byname(ntfs_iterate_s *walk){	walk->type = BY_NAME;	return ntfs_getdir(walk);}int ntfs_getdir_unsorted(ntfs_inode *ino, u32 *p_high, u32 *p_low,		int (*cb)(ntfs_u8 *, void *), void *param){	s64 ib_ofs;	char *buf = 0, *entry = 0;	ntfs_attribute *attr;	ntfs_volume *vol;	int byte, bit, err = 0;	u32 start, finish, ibs, max_size;	ntfs_io io;	u8 ibs_bits;	if (!ino) {		ntfs_error("%s(): No inode! Returning -EINVAL.\n",__FUNCTION__);		return -EINVAL;	}	vol = ino->vol;	if (!vol) {		ntfs_error("%s(): Inode 0x%lx has no volume. Returning "			    "-EINVAL.\n", __FUNCTION__, ino->i_number);		return -EINVAL;	}	ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 1: Entering for inode 0x%lx, "			"p_high = 0x%x, p_low = 0x%x.\n", __FUNCTION__,			ino->i_number, *p_high, *p_low);	if (!*p_high) {		/* We are still in the index root. */		buf = ntfs_malloc(io.size = vol->mft_record_size);		if (!buf)			return -ENOMEM;		io.fn_put = ntfs_put;		io.param = buf;		err = ntfs_read_attr(ino, vol->at_index_root, I30, 0, &io);		if (err || !io.size)			goto read_err_ret;		ino->u.index.recordsize = ibs = NTFS_GETU32(buf + 0x8);		ino->u.index.clusters_per_record = NTFS_GETU32(buf + 0xC);		entry = buf + 0x20;		ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 2: In index root.\n",				__FUNCTION__);		ibs_bits = ffs(ibs) - 1;		/* Compensate for faked "." and "..". */		start = 2;	} else { /* We are in an index record. */		io.size = ibs = ino->u.index.recordsize;		buf = ntfs_malloc(ibs);		if (!buf)			return -ENOMEM;		ibs_bits = ffs(ibs) - 1;		io.fn_put = ntfs_put;		io.param = buf;		/*		 * 0 is index root, index allocation starts at 1 and works in		 * units of index block size (ibs).		 */		ib_ofs = (s64)(*p_high - 1) << ibs_bits;		err = ntfs_read_attr(ino, vol->at_index_allocation, I30, ib_ofs,				&io);		if (err || io.size != ibs)			goto read_err_ret;		if (!ntfs_check_index_record(ino, buf)) {			ntfs_error("%s(): Index block 0x%x is not an index "					"record. Returning -ENOTDIR.\n",					 __FUNCTION__, *p_high - 1);			ntfs_free(buf);			return -ENOTDIR;		}		entry = buf + 0x18 + NTFS_GETU16(buf + 0x18);		ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 3: In index "				"allocation.\n", __FUNCTION__);		start = 0;	}	/* Process the entries. */	finish = *p_low;	for (; entry < (buf + ibs) && ntfs_entry_is_used(entry);			entry += NTFS_GETU16(entry + 8)) {		if (start < finish) {			/* Skip entries that were already processed. */			ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 4: Skipping "					"already processed entry p_high 0x%x, "					"p_low 0x%x.\n", __FUNCTION__, *p_high,					start);			start++;			continue;		}		ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 5: Processing entry "				"p_high 0x%x, p_low 0x%x.\n", __FUNCTION__,				*p_high, *p_low);		if ((err = cb(entry, param))) {			/* filldir signalled us to stop. */			ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 6: cb returned "					"%i, returning 0, p_high 0x%x, "					"p_low 0x%x.\n", __FUNCTION__, err,					*p_high, *p_low);			ntfs_free(buf);			return 0;		}		++*p_low;	}	ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 7: After processing entries, "			"p_high 0x%x, p_low 0x%x.\n", __FUNCTION__, *p_high,			*p_low);	/* We have to locate the next record. */	ntfs_free(buf);	buf = 0;	*p_low = 0;	attr = ntfs_find_attr(ino, vol->at_bitmap, I30);	if (!attr) {		/* Directory does not have index bitmap and index allocation. */		*p_high = 0x7fff;		ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 8: No index allocation. "				"Returning 0, p_high 0x7fff, p_low 0x0.\n",				__FUNCTION__);		return 0;	}	max_size = attr->size;	if (max_size > 0x7fff >> 3) {		ntfs_error("%s(): Directory too large. Visible "				"length is truncated.\n", __FUNCTION__);		max_size = 0x7fff >> 3;	}	buf = ntfs_malloc(max_size);	if (!buf)		return -ENOMEM;	io.param = buf;	io.size = max_size;	err = ntfs_read_attr(ino, vol->at_bitmap, I30, 0, &io);	if (err || io.size != max_size)		goto read_err_ret;	attr = ntfs_find_attr(ino, vol->at_index_allocation, I30);	if (!attr) {		ntfs_free(buf);		ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 9: Find attr failed. "				"Returning -EIO.\n", __FUNCTION__);		return -EIO;	}	if (attr->resident) {		ntfs_free(buf);		ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 9.5: IA is resident. Not"				" allowed. Returning EINVAL.\n", __FUNCTION__);		return -EINVAL;	}	/* Loop while going through non-allocated index records. */	max_size <<= 3;	while (1) {		if (++*p_high >= 0x7fff) {			ntfs_error("%s(): Unsorted 10: Directory "					"inode 0x%lx overflowed the maximum "					"number of index allocation buffers "					"the driver can cope with. Pretending "					"to be at end of directory.\n",					__FUNCTION__, ino->i_number);			goto fake_eod;		}		if (*p_high > max_size || (s64)*p_high << ibs_bits >				attr->initialized) {fake_eod:			/* No more index records. */			*p_high = 0x7fff;			*p_low = 0;			ntfs_free(buf);			ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 10.5: No more "					"index records. Returning 0, p_high "					"0x7fff, p_low 0.\n", __FUNCTION__);			return 0;		}		byte = (ntfs_cluster_t)(*p_high - 1);		bit = 1 << (byte & 7);		byte >>= 3;		if ((buf[byte] & bit))			break;	};	ntfs_debug(DEBUG_DIR3, "%s(): Unsorted 11: Done. Returning 0, p_high "			"0x%x, p_low 0x%x.\n", __FUNCTION__, *p_high, *p_low);	ntfs_free(buf);	return 0;read_err_ret:	if (!err)		err = -EIO;	ntfs_error("%s(): Read failed. Returning error code %i.\n",			__FUNCTION__, err);	ntfs_free(buf);	return err;}int ntfs_dir_add(ntfs_inode *dir, ntfs_inode *new, ntfs_attribute *name){	ntfs_iterate_s walk;	int nsize, esize;	ntfs_u8* entry, *ndata;	int error;	walk.type = DIR_INSERT;	walk.dir = dir;	walk.u.flags = 0;	nsize = name->size;	ndata = name->d.data;	walk.name = (ntfs_u16*)(ndata + 0x42);	walk.namelen = NTFS_GETU8(ndata + 0x40);	walk.new_entry_size = esize = (nsize + 0x10 + 7) & ~7;	walk.new_entry = entry = ntfs_malloc(esize);	if (!entry)		return -ENOMEM;	NTFS_PUTINUM(entry, new);	NTFS_PUTU16(entry + 0x8, esize); /* Size of entry. */	NTFS_PUTU16(entry + 0xA, nsize); /* Size of original name attribute. */	NTFS_PUTU16(entry + 0xC, 0);     /* Flags. */	NTFS_PUTU16(entry + 0xE, 0);	 /* Reserved. */	ntfs_memcpy(entry + 0x10, ndata, nsize);	ntfs_bzero(entry + 0x10 + nsize, esize - 0x10 - nsize);	error = ntfs_getdir(&walk);	if (walk.new_entry)		ntfs_free(walk.new_entry);	return error;}#if 0int ntfs_dir_add1(ntfs_inode *dir, const char* name, int namelen,		  ntfs_inode *ino){	ntfs_iterate_s walk;	int error;	int nsize;	char *entry;	ntfs_attribute *name_attr;	error = ntfs_decodeuni(dir->vol, name, namelen, &walk.name,			       &walk.namelen);	if (error)		return error;	/* FIXME: Set flags. */	walk.type = DIR_INSERT;	walk.dir = dir;	/* walk.new = ino; */	/* Prepare new entry. */	/* Round up to a multiple of 8. */	walk.new_entry_size = nsize = ((0x52 + 2 * walk.namelen + 7) / 8) * 8;	walk.new_entry = entry = ntfs_malloc(nsize);	if (!entry)		return -ENOMEM;	ntfs_bzero(entry, nsize);	NTFS_PUTINUM(entry, ino);	NTFS_PUTU16(entry + 8, nsize);	NTFS_PUTU16(entry + 0xA, 0x42 + 2 * namelen); /* FIXME: Size of name 						       * attribute. */	NTFS_PUTU32(entry + 0xC, 0); /* FIXME: D-F? */	name_attr = ntfs_find_attr(ino, vol->at_file_name, 0);						    /* FIXME: multiple names */	if (!name_attr || !name_attr->resident)		return -EIDRM;	/* Directory, file stamps, sizes, filename. */	ntfs_memcpy(entry + 0x10, name_attr->d.data, 0x42 + 2 * namelen);	error = ntfs_getdir(&walk);	ntfs_free(walk.name);	return error;}#endif/* Fills out and creates an INDEX_ROOT attribute. */int ntfs_add_index_root(ntfs_inode *ino, int type){	ntfs_attribute *da;	ntfs_u8 data[0x30]; /* 0x20 header, 0x10 last entry. */	char name[10];	NTFS_PUTU32(data, type);	/* Collation rule. 1 == COLLATION_FILENAME */	NTFS_PUTU32(data + 4, 1);	NTFS_PUTU32(data + 8, ino->vol->index_record_size);	NTFS_PUTU32(data + 0xC, ino->vol->index_clusters_per_record);	/* Byte offset to first INDEX_ENTRY. */	NTFS_PUTU32(data + 0x10, 0x10);	/* Size of entries, including header. */	NTFS_PUTU32(data + 0x14, 0x20);	NTFS_PUTU32(data + 0x18, 0x20);	/* No index allocation, yet. */	NTFS_PUTU32(data + 0x1C, 0);	/* Add last entry. */	/* Indexed MFT record. */	NTFS_PUTU64(data + 0x20, 0);	/* Size of entry. */	NTFS_PUTU32(data + 0x28, 0x10);	/* Flags: Last entry, no child nodes. */	NTFS_PUTU32(data + 0x2C, 2);	/* Compute name. */	ntfs_indexname(name, type);	return ntfs_create_attr(ino, ino->vol->at_index_root, name,				data, sizeof(data), &da);}int ntfs_mkdir(ntfs_inode *dir, const char *name, int namelen,	       ntfs_inode *result){	int error;		error = ntfs_alloc_inode(dir, result, name, namelen, NTFS_AFLAG_DIR);	if (error)		goto out;	error = ntfs_add_index_root(result, 0x30);	if (error)		goto out;	/* Set directory bit. */	result->attr[0x16] |= 2;	error = ntfs_update_inode(dir);	if (error)		goto out;	error = ntfs_update_inode(result);	if (error)		goto out; out:	return error;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -