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

📄 dir.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
		NTFS_PUTU32(prev + 8, 0x18);		NTFS_PUTU32(prev + 0xC, 3);		NTFS_PUTU64(prev + 0x10, oldblock);		othersize += 0x18;	}	/* Write back original block. */	error = ntfs_index_writeback(walk, start, walk->block, othersize); out:	if (newbuf)		ntfs_free(newbuf);	if (middle)		ntfs_free(middle);	return error;}static int ntfs_dir_insert(ntfs_iterate_s *walk, char *start, char* entry){	int blocksize, usedsize, error, offset;	int do_split = 0;	offset = entry - start;	if (walk->block == -1) { /* index root */		blocksize = walk->dir->vol->mft_record_size;		usedsize = NTFS_GETU16(start + 0x14) + 0x10;	} else {		blocksize = walk->dir->u.index.recordsize;		usedsize = NTFS_GETU16(start + 0x1C) + 0x18;	}	if (usedsize + walk->new_entry_size > blocksize) {		char* s1 = ntfs_malloc(blocksize + walk->new_entry_size);		if (!s1)			return -ENOMEM;		ntfs_memcpy(s1, start, usedsize);		do_split = 1;		/* Adjust entry to s1. */		entry = s1 + (entry - start);		start = s1;	}	ntfs_memmove(entry + walk->new_entry_size, entry, usedsize - offset);	ntfs_memcpy(entry, walk->new_entry, walk->new_entry_size);	usedsize += walk->new_entry_size;	ntfs_free(walk->new_entry);	walk->new_entry = 0;	if (do_split) {		error = ntfs_split_record(walk, start, blocksize, usedsize);		ntfs_free(start);	} else {		error = ntfs_index_writeback(walk, start, walk->block,usedsize);		if (error)			return error;	}	return 0;}/* Try to split INDEX_ROOT attributes. Return -E2BIG if nothing changed. */int ntfs_split_indexroot(ntfs_inode *ino){	ntfs_attribute *ra;	ntfs_u8 *root = 0, *index = 0;	ntfs_io io;	int error, off, i, bsize, isize;	ntfs_iterate_s walk;	ra = ntfs_find_attr(ino, ino->vol->at_index_root, I30);	if (!ra)		return -ENOTDIR;	bsize = ino->vol->mft_record_size;	root = ntfs_malloc(bsize);	if (!root)		return -E2BIG;	io.fn_put = ntfs_put;	io.param = root;	io.size = bsize;	error = ntfs_read_attr(ino, ino->vol->at_index_root, I30, 0, &io);	if (error)		goto out;	off = 0x20;	/* Count number of entries. */	for (i = 0; ntfs_entry_is_used(root + off); i++)		off += NTFS_GETU16(root + off + 8);	if (i <= 2) {		/* We don't split small index roots. */		error = -E2BIG;		goto out;	}	index = ntfs_malloc(ino->vol->index_record_size);	if (!index) {		error = -ENOMEM;		goto out;	}	walk.dir = ino;	walk.block = -1;	walk.result = walk.new_entry = 0;	walk.name = 0;	error = ntfs_allocate_index_block(&walk);	if (error)		goto out;	/* Write old root to new index block. */	io.param = index;	io.size = ino->vol->index_record_size;	error = ntfs_read_attr(ino, ino->vol->at_index_allocation, I30,		(__s64)walk.newblock << ino->vol->cluster_size_bits, &io);	if (error)		goto out;	isize = NTFS_GETU16(root + 0x18) - 0x10;	ntfs_memcpy(index + NTFS_GETU16(index + 0x18) + 0x18, root+0x20, isize);	/* Copy flags. */	NTFS_PUTU32(index + 0x24, NTFS_GETU32(root + 0x1C));	error = ntfs_index_writeback(&walk, index, walk.newblock, 				     isize + NTFS_GETU16(index + 0x18) + 0x18);	if (error)		goto out;	/* Mark root as split. */	NTFS_PUTU32(root + 0x1C, 1);	/* Truncate index root. */	NTFS_PUTU64(root + 0x20, 0);	NTFS_PUTU32(root + 0x28, 0x18);	NTFS_PUTU32(root + 0x2C, 3);	NTFS_PUTU64(root + 0x30, walk.newblock);	error = ntfs_index_writeback(&walk, root, -1, 0x38); out:	ntfs_free(root);	ntfs_free(index);	return error;}/* The entry has been found. Copy the result in the caller's buffer */static int ntfs_copyresult(char *dest, char *source){	int length = NTFS_GETU16(source + 8);	ntfs_memcpy(dest, source, length);	return 1;}/* Use $UpCase some day. */static inline unsigned short ntfs_my_toupper(ntfs_volume *vol, ntfs_u16 x){	/* We should read any pending rest of $UpCase here. */	if (x >= vol->upcase_length)		return x;	return vol->upcase[x];}/* Everything passed in walk and entry. */static int ntfs_my_strcmp(ntfs_iterate_s *walk, const unsigned char *entry){	int lu = *(entry + 0x50);	int i;	ntfs_u16* name = (ntfs_u16*)(entry + 0x52);	ntfs_volume *vol = walk->dir->vol;	for (i = 0; i < lu && i < walk->namelen; i++)		if (ntfs_my_toupper(vol, NTFS_GETU16(name + i)) != 			     ntfs_my_toupper(vol, NTFS_GETU16(walk->name + i)))			break;	if (i == lu && i == walk->namelen)		return 0;	if (i == lu)		return 1;	if (i == walk->namelen)		return -1;	if (ntfs_my_toupper(vol, NTFS_GETU16(name + i)) < 			    ntfs_my_toupper(vol, NTFS_GETU16(walk->name + i)))		return 1;	return -1;}/* Necessary forward declaration. */static int ntfs_getdir_iterate(ntfs_iterate_s *walk, char *start, char *entry);/* Parse a block of entries. Load the block, fix it up, and iterate over the * entries. The block is given as virtual cluster number. */static int ntfs_getdir_record(ntfs_iterate_s *walk, int block){	int length = walk->dir->u.index.recordsize;	char *record = (char*)ntfs_malloc(length);	char *offset;	int retval,error;	int oldblock;	ntfs_io io;	if (!record)		return -ENOMEM;	io.fn_put = ntfs_put;	io.param = record;	io.size = length;	/* Read the block from the index allocation attribute. */	error = ntfs_read_attr(walk->dir, walk->dir->vol->at_index_allocation,		I30, (__s64)block << walk->dir->vol->cluster_size_bits, &io);	if (error || io.size != length) {		ntfs_error("read failed\n");		ntfs_free(record);		return 0;	}	if (!ntfs_check_index_record(walk->dir, record)) {		ntfs_error("%x is not an index record\n", block);		ntfs_free(record);		return 0;	}	offset = record + NTFS_GETU16(record + 0x18) + 0x18;	oldblock = walk->block;	walk->block = block;	retval = ntfs_getdir_iterate(walk, record, offset);	walk->block = oldblock;	ntfs_free(record);	return retval;}/* Go down to the next block of entries. These collate before the current * entry. */static int ntfs_descend(ntfs_iterate_s *walk, ntfs_u8 *start, ntfs_u8 *entry){	int length = NTFS_GETU16(entry + 8);	int nextblock = NTFS_GETU32(entry + length - 8);	int error;	if (!ntfs_entry_has_subnodes(entry)) {		ntfs_error("illegal ntfs_descend call\n");		return 0;	}	error = ntfs_getdir_record(walk, nextblock);	if (!error && walk->type == DIR_INSERT && 	    (walk->u.flags & ITERATE_SPLIT_DONE)) {		/* Split has occurred. Adjust entry, insert new_entry. */		NTFS_PUTU32(entry + length - 8, walk->newblock);		/* Reset flags, as the current block might be split again. */		walk->u.flags &= ~ITERATE_SPLIT_DONE;		error = ntfs_dir_insert(walk, start, entry);	}	return error;}static int ntfs_getdir_iterate_byposition(ntfs_iterate_s *walk, char* start,					  char *entry){	int retval = 0;	int curpos = 0, destpos = 0;	int length;	if (walk->u.pos != 0) {		if (ntfs_is_top(walk->u.pos))			return 0;		destpos = ntfs_pop(&walk->u.pos);	}	while (1) {		if (walk->u.pos == 0) {			if (ntfs_entry_has_subnodes(entry))				ntfs_descend(walk, start, entry);			else				walk->u.pos = ntfs_top();			if (ntfs_is_top(walk->u.pos) && 			    !ntfs_entry_is_used(entry))				return 1;			walk->u.pos = ntfs_push(walk->u.pos, curpos);			return 1;		}		if (curpos == destpos) {			if (!ntfs_is_top(walk->u.pos) && 			    ntfs_entry_has_subnodes(entry)) {				retval = ntfs_descend(walk, start, entry);				if (retval) {					walk->u.pos = ntfs_push(walk->u.pos,								curpos);					return retval;				}				if (!ntfs_entry_is_used(entry))					return 0;				walk->u.pos = 0;			}			if (ntfs_entry_is_used(entry)) {				retval = ntfs_copyresult(walk->result, entry);				walk->u.pos = 0;			} else {				walk->u.pos = ntfs_top();				return 0;			}		}		curpos++;		if (!ntfs_entry_is_used(entry))			break;		length = NTFS_GETU16(entry + 8);		if (!length) {			ntfs_error("infinite loop\n");			break;		}		entry += length;	}	return -1;}	/* Iterate over a list of entries, either from an index block, or from the * index root. * If searching BY_POSITION, pop the top index from the position. If the * position stack is empty then, return the item at the index and set the * position to the next entry. If the position stack is not empty,  * recursively proceed for subnodes. If the entry at the position is the * 'end of dir' entry, return 'not found' and the empty stack. * If searching BY_NAME, walk through the items until found or until * one item is collated after the requested item. In the former case, return * the result. In the latter case, recursively proceed to the subnodes. * If 'end of dir' is reached, the name is not in the directory */static int ntfs_getdir_iterate(ntfs_iterate_s *walk, char *start, char *entry){	int length;	int cmp;	if (walk->type == BY_POSITION)		return ntfs_getdir_iterate_byposition(walk, start, entry);	do {		/* If the current entry is a real one, compare with the		 * requested item. If the current entry is the last item, it		 * is always larger than the requested item. */		cmp = ntfs_entry_is_used(entry) ? 						ntfs_my_strcmp(walk,entry) : -1;		switch (walk->type) {		case BY_NAME:			switch (cmp) {			case -1:				return ntfs_entry_has_subnodes(entry) ?					ntfs_descend(walk, start, entry) : 0;			case  0:				return ntfs_copyresult(walk->result, entry);			case  1:				break;			}			break;		case DIR_INSERT:			switch (cmp) {			case -1:				return ntfs_entry_has_subnodes(entry) ?					ntfs_descend(walk, start, entry) :					ntfs_dir_insert(walk, start, entry);			case  0:				return -EEXIST;			case  1:				break;			}			break;		default:			ntfs_error("TODO\n"); /* FIXME: ? */		}		if (!ntfs_entry_is_used(entry))			break;		length = NTFS_GETU16(entry + 8);		if (!length) {			ntfs_error("infinite loop\n");			break;		}		entry += length;	} while (1);	return 0;}/*  Tree walking is done using position numbers. The following numbers have a *  special meaning: *       0   start (.) *      -1   no more entries *      -2   .. *  All other numbers encode sequences of indices. The sequence a, b, c is  *  encoded as <stop><c><b><a>, where <foo> is the encoding of foo. The *  first few integers are encoded as follows: *      0:    0000    1:    0010    2:    0100    3:    0110 *      4:    1000    5:    1010    6:    1100 stop:    1110 *      7:  000001    8:  000101    9:  001001   10:  001101 *  The least significant bits give the width of this encoding, the other bits *  encode the value, starting from the first value of the interval. *   tag     width  first value  last value *   0       3      0            6 *   01      4      7            22 *   011     5      23           54 *   0111    6      55           119

⌨️ 快捷键说明

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