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

📄 dir.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
 *   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(__FUNCTION__ "(): No inode! Returning -EINVAL.\n");		return -EINVAL;	}	vol = ino->vol;	if (!vol) {		ntfs_error(__FUNCTION__ "(): Inode 0x%lx has no volume. "				"Returning -EINVAL.\n", ino->i_number);		return -EINVAL;	}	ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 1: Entering for "			"inode 0x%lx, p_high = 0x%x, p_low = 0x%x.\n",			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, __FUNCTION__ "(): Unsorted 2: In index "				"root.\n");		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(__FUNCTION__ "(): Index block 0x%x is not "					"an index record. Returning "					"-ENOTDIR.\n", *p_high - 1);			ntfs_free(buf);			return -ENOTDIR;		}		entry = buf + 0x18 + NTFS_GETU16(buf + 0x18);		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 3: In index "				"allocation.\n");		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, __FUNCTION__ "(): Unsorted 4: "					"Skipping already processed entry "					"p_high 0x%x, p_low 0x%x.\n", *p_high,					start);			start++;			continue;		}		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 5: "				"Processing entry p_high 0x%x, p_low 0x%x.\n",				*p_high, *p_low);		if ((err = cb(entry, param))) {			/* filldir signalled us to stop. */			ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): "					"Unsorted 6: cb returned %i, "					"returning 0, p_high 0x%x, p_low 0x%x."					"\n", *p_high, *p_low);			ntfs_free(buf);			return 0;		}		++*p_low;	}	ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 7: After processing "			"entries, p_high 0x%x, p_low 0x%x.\n", *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, __FUNCTION__ "(): Unsorted 8: No index "				"allocation. Returning 0, p_high 0x7fff, "				"p_low 0x0.\n");		return 0;	}	max_size = attr->size;	if (max_size > 0x7fff >> 3) {		ntfs_error(__FUNCTION__ "(): Directory too large. Visible "				"length is truncated.\n");		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, __FUNCTION__ "(): Unsorted 9: Find "				"attr failed. Returning -EIO.\n");		return -EIO;	}	if (attr->resident) {		ntfs_free(buf);		ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 9.5: IA is "				"resident. Not allowed. Returning EINVAL.\n");		return -EINVAL;	}	/* Loop while going through non-allocated index records. */	max_size <<= 3;	while (1) {		if (++*p_high >= 0x7fff) {			ntfs_error(__FUNCTION__ "(): 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",					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, __FUNCTION__ "(): Unsorted "					"10.5: No more index records. "					"Returning 0, p_high 0x7fff, p_low "					"0.\n");			return 0;		}		byte = (ntfs_cluster_t)(*p_high - 1);		bit = 1 << (byte & 7);		byte >>= 3;		if ((buf[byte] & bit))			break;	};	ntfs_debug(DEBUG_DIR3, __FUNCTION__ "(): Unsorted 11: Done. "			"Returning 0, p_high 0x%x, p_low 0x%x.\n", *p_high,			*p_low);	ntfs_free(buf);	return 0;read_err_ret:	if (!err)		err = -EIO;	ntfs_error(__FUNCTION__ "(): Read failed. Returning error code %i.\n",			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 + -