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

📄 storage.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
	(LPDWORD)&hres
    )) {
	ERR("CallTo16 ILockBytes16::WriteAt() failed, hres %x\n",hres);
	return FALSE;
    }
    UnMapLS(args[3]);
    return TRUE;
}

/******************************************************************************
 * STORAGE_put_big_block [INTERNAL]
 */
static BOOL
STORAGE_put_big_block(stream_access16 *str,int n,BYTE *block)
{
    DWORD result;

    assert(n>=-1);
    if (str->hf) {
	if ((SetFilePointer( str->hf, (n+1)*BIGSIZE, NULL,
			     SEEK_SET ) == INVALID_SET_FILE_POINTER) && GetLastError())
	{
            WARN("seek failed (%d)\n",GetLastError());
	    return FALSE;
	}
	if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE)
	{
            WARN(" write failed (%d)\n",GetLastError());
	    return FALSE;
	}
	return TRUE;
    } else {
	_ilockbytes16_writeat(str->lockbytes, (n+1)*BIGSIZE, BIGSIZE, block);
	return TRUE;
    }
}

/******************************************************************************
 * STORAGE_get_next_big_blocknr [INTERNAL]
 */
static int
STORAGE_get_next_big_blocknr(stream_access16 *str,int blocknr) {
	INT	bbs[BIGSIZE/sizeof(INT)];
	struct	storage_header	sth;

	READ_HEADER(str);

	assert(blocknr>>7<sth.num_of_bbd_blocks);
	if (sth.bbd_list[blocknr>>7]==0xffffffff)
		return -5;
	if (!STORAGE_get_big_block(str,sth.bbd_list[blocknr>>7],(LPBYTE)bbs))
		return -5;
	assert(bbs[blocknr&0x7f]!=STORAGE_CHAINENTRY_FREE);
	return bbs[blocknr&0x7f];
}

/******************************************************************************
 * STORAGE_get_nth_next_big_blocknr [INTERNAL]
 */
static int
STORAGE_get_nth_next_big_blocknr(stream_access16 *str,int blocknr,int nr) {
	INT	bbs[BIGSIZE/sizeof(INT)];
	int	lastblock = -1;
	struct storage_header sth;

	TRACE("(blocknr=%d, nr=%d)\n", blocknr, nr);
	READ_HEADER(str);

	assert(blocknr>=0);
	while (nr--) {
		assert((blocknr>>7)<sth.num_of_bbd_blocks);
		assert(sth.bbd_list[blocknr>>7]!=0xffffffff);

		/* simple caching... */
		if (lastblock!=sth.bbd_list[blocknr>>7]) {
			BOOL ret = STORAGE_get_big_block(str,sth.bbd_list[blocknr>>7],(LPBYTE)bbs);
			assert(ret);
			lastblock = sth.bbd_list[blocknr>>7];
		}
		blocknr = bbs[blocknr&0x7f];
	}
	return blocknr;
}

/******************************************************************************
 *		STORAGE_get_root_pps_entry	[Internal]
 */
static BOOL
STORAGE_get_root_pps_entry(stream_access16* str,struct storage_pps_entry *pstde) {
	int	blocknr,i;
	BYTE	block[BIGSIZE];
	struct storage_pps_entry	*stde=(struct storage_pps_entry*)block;
	struct storage_header sth;

	READ_HEADER(str);
	blocknr = sth.root_startblock;
	TRACE("startblock is %d\n", blocknr);
	while (blocknr>=0) {
		BOOL ret = STORAGE_get_big_block(str,blocknr,block);
		assert(ret);
		for (i=0;i<4;i++) {
			if (!stde[i].pps_sizeofname)
				continue;
			if (stde[i].pps_type==5) {
				*pstde=stde[i];
				return TRUE;
			}
		}
		blocknr=STORAGE_get_next_big_blocknr(str,blocknr);
		TRACE("next block is %d\n", blocknr);
	}
	return FALSE;
}

/******************************************************************************
 * STORAGE_get_small_block [INTERNAL]
 */
static BOOL
STORAGE_get_small_block(stream_access16 *str,int blocknr,BYTE *sblock) {
	BYTE				block[BIGSIZE];
	int				bigblocknr;
	struct storage_pps_entry	root;
	BOOL ret;

	TRACE("(blocknr=%d)\n", blocknr);
	assert(blocknr>=0);
	ret = STORAGE_get_root_pps_entry(str,&root);
	assert(ret);
	bigblocknr = STORAGE_get_nth_next_big_blocknr(str,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK);
	assert(bigblocknr>=0);
	ret = STORAGE_get_big_block(str,bigblocknr,block);
	assert(ret);

	memcpy(sblock,((LPBYTE)block)+SMALLSIZE*(blocknr&(SMALLBLOCKS_PER_BIGBLOCK-1)),SMALLSIZE);
	return TRUE;
}

/******************************************************************************
 * STORAGE_put_small_block [INTERNAL]
 */
static BOOL
STORAGE_put_small_block(stream_access16 *str,int blocknr,const BYTE *sblock) {
	BYTE				block[BIGSIZE];
	int				bigblocknr;
	struct storage_pps_entry	root;
	BOOL ret;

	assert(blocknr>=0);
	TRACE("(blocknr=%d)\n", blocknr);

	ret = STORAGE_get_root_pps_entry(str,&root);
	assert(ret);
	bigblocknr = STORAGE_get_nth_next_big_blocknr(str,root.pps_sb,blocknr/SMALLBLOCKS_PER_BIGBLOCK);
	assert(bigblocknr>=0);
	ret = STORAGE_get_big_block(str,bigblocknr,block);
	assert(ret);

	memcpy(((LPBYTE)block)+SMALLSIZE*(blocknr&(SMALLBLOCKS_PER_BIGBLOCK-1)),sblock,SMALLSIZE);
	ret = STORAGE_put_big_block(str,bigblocknr,block);
	assert(ret);
	return TRUE;
}

/******************************************************************************
 * STORAGE_get_next_small_blocknr [INTERNAL]
 */
static int
STORAGE_get_next_small_blocknr(stream_access16 *str,int blocknr) {
	BYTE				block[BIGSIZE];
	LPINT				sbd = (LPINT)block;
	int				bigblocknr;
	struct storage_header		sth;
	BOOL ret;

	TRACE("(blocknr=%d)\n", blocknr);
	READ_HEADER(str);
	assert(blocknr>=0);
	bigblocknr = STORAGE_get_nth_next_big_blocknr(str,sth.sbd_startblock,blocknr/128);
	assert(bigblocknr>=0);
	ret = STORAGE_get_big_block(str,bigblocknr,block);
	assert(ret);
	assert(sbd[blocknr & 127]!=STORAGE_CHAINENTRY_FREE);
	return sbd[blocknr & (128-1)];
}

/******************************************************************************
 * STORAGE_get_nth_next_small_blocknr [INTERNAL]
 */
static int
STORAGE_get_nth_next_small_blocknr(stream_access16*str,int blocknr,int nr) {
	int	lastblocknr=-1;
	BYTE	block[BIGSIZE];
	LPINT	sbd = (LPINT)block;
	struct storage_header sth;
	BOOL ret;

	TRACE("(blocknr=%d, nr=%d)\n", blocknr, nr);
	READ_HEADER(str);
	assert(blocknr>=0);
	while ((nr--) && (blocknr>=0)) {
		if (lastblocknr/128!=blocknr/128) {
			int	bigblocknr;
			bigblocknr = STORAGE_get_nth_next_big_blocknr(str,sth.sbd_startblock,blocknr/128);
			assert(bigblocknr>=0);
			ret = STORAGE_get_big_block(str,bigblocknr,block);
			assert(ret);
			lastblocknr = blocknr;
		}
		assert(lastblocknr>=0);
		lastblocknr=blocknr;
		blocknr=sbd[blocknr & (128-1)];
		assert(blocknr!=STORAGE_CHAINENTRY_FREE);
	}
	return blocknr;
}

/******************************************************************************
 * STORAGE_get_pps_entry [INTERNAL]
 */
static int
STORAGE_get_pps_entry(stream_access16*str,int n,struct storage_pps_entry *pstde) {
	int	blocknr;
	BYTE	block[BIGSIZE];
	struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3));
	struct storage_header sth;
	BOOL ret;

	TRACE("(n=%d)\n", n);
	READ_HEADER(str);
	/* we have 4 pps entries per big block */
	blocknr = STORAGE_get_nth_next_big_blocknr(str,sth.root_startblock,n/4);
	assert(blocknr>=0);
	ret = STORAGE_get_big_block(str,blocknr,block);
	assert(ret);

	*pstde=*stde;
	return 1;
}

/******************************************************************************
 *		STORAGE_put_pps_entry	[Internal]
 */
static int
STORAGE_put_pps_entry(stream_access16*str,int n,const struct storage_pps_entry *pstde) {
	int	blocknr;
	BYTE	block[BIGSIZE];
	struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3));
	struct storage_header sth;
	BOOL ret;

	TRACE("(n=%d)\n", n);
	READ_HEADER(str);
	/* we have 4 pps entries per big block */
	blocknr = STORAGE_get_nth_next_big_blocknr(str,sth.root_startblock,n/4);
	assert(blocknr>=0);
	ret = STORAGE_get_big_block(str,blocknr,block);
	assert(ret);
	*stde=*pstde;
	ret = STORAGE_put_big_block(str,blocknr,block);
	assert(ret);
	return 1;
}

/******************************************************************************
 *		STORAGE_look_for_named_pps	[Internal]
 */
static int
STORAGE_look_for_named_pps(stream_access16*str,int n,LPOLESTR name) {
	struct storage_pps_entry	stde;
	int				ret;

	TRACE("(n=%d,name=%s)\n", n, debugstr_w(name));
	if (n==-1)
		return -1;
	if (1!=STORAGE_get_pps_entry(str,n,&stde))
		return -1;

	if (!lstrcmpW(name,stde.pps_rawname))
		return n;
	if (stde.pps_prev != -1) {
		ret=STORAGE_look_for_named_pps(str,stde.pps_prev,name);
		if (ret!=-1)
			return ret;
	}
	if (stde.pps_next != -1) {
		ret=STORAGE_look_for_named_pps(str,stde.pps_next,name);
		if (ret!=-1)
			return ret;
	}
	return -1;
}

/******************************************************************************
 *		STORAGE_dump_pps_entry	[Internal]
 *
 * FIXME
 *    Function is unused
 */
void
STORAGE_dump_pps_entry(struct storage_pps_entry *stde) {
    char	name[33];

    WideCharToMultiByte( CP_ACP, 0, stde->pps_rawname, -1, name, sizeof(name), NULL, NULL);
	if (!stde->pps_sizeofname)
		return;
	DPRINTF("name: %s\n",name);
	DPRINTF("type: %d\n",stde->pps_type);
	DPRINTF("prev pps: %d\n",stde->pps_prev);
	DPRINTF("next pps: %d\n",stde->pps_next);
	DPRINTF("dir pps: %d\n",stde->pps_dir);
	DPRINTF("guid: %s\n",debugstr_guid(&(stde->pps_guid)));
	if (stde->pps_type !=2) {
		time_t	t;
                DWORD dw;
		RtlTimeToSecondsSince1970((LARGE_INTEGER *)&(stde->pps_ft1),&dw);
                t = dw;
		DPRINTF("ts1: %s\n",ctime(&t));
		RtlTimeToSecondsSince1970((LARGE_INTEGER *)&(stde->pps_ft2),&dw);
                t = dw;
		DPRINTF("ts2: %s\n",ctime(&t));
	}
	DPRINTF("startblock: %d\n",stde->pps_sb);
	DPRINTF("size: %d\n",stde->pps_size);
}

/******************************************************************************
 * STORAGE_init_storage [INTERNAL]
 */
static BOOL
STORAGE_init_storage(stream_access16 *str) {
	BYTE	block[BIGSIZE];
	LPDWORD	bbs;
	struct storage_header *sth;
	struct storage_pps_entry *stde;
        DWORD result;

	if (str->hf)
	    SetFilePointer( str->hf, 0, NULL, SEEK_SET );
	/* block -1 is the storage header */
	sth = (struct storage_header*)block;
	memcpy(sth->magic,STORAGE_magic,8);
	memset(sth->unknown1,0,sizeof(sth->unknown1));
	memset(sth->unknown2,0,sizeof(sth->unknown2));
	memset(sth->unknown3,0,sizeof(sth->unknown3));
	sth->num_of_bbd_blocks	= 1;
	sth->root_startblock	= 1;
	sth->sbd_startblock	= 0xffffffff;
	memset(sth->bbd_list,0xff,sizeof(sth->bbd_list));
	sth->bbd_list[0]	= 0;
	if (str->hf) {
	    if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE) return FALSE;
	} else {
	    if (!_ilockbytes16_writeat(str->lockbytes, 0, BIGSIZE, block)) return FALSE;
	}
	/* block 0 is the big block directory */
	bbs=(LPDWORD)block;
	memset(block,0xff,sizeof(block)); /* mark all blocks as free */
	bbs[0]=STORAGE_CHAINENTRY_ENDOFCHAIN; /* for this block */
	bbs[1]=STORAGE_CHAINENTRY_ENDOFCHAIN; /* for directory entry */
	if (str->hf) {
	    if (!WriteFile( str->hf, block, BIGSIZE, &result, NULL ) || result != BIGSIZE) return FALSE;
	} else {
	    if (!_ilockbytes16_writeat(str->lockbytes, BIGSIZE, BIGSIZE, block)) return FALSE;
	}
	/* block 1 is the root directory entry */
	memset(block,0x00,sizeof(block));
	stde = (struct storage_pps_entry*)block;
        MultiByteToWideChar( CP_ACP, 0, "RootEntry", -1, stde->pps_rawname,
                             sizeof(stde->pps_rawname)/sizeof(WCHAR));
	stde->pps_sizeofname	= (strlenW(stde->pps_rawname)+1) * sizeof(WCHAR);
	stde->pps_type		= 5;
	stde->pps_dir		= -1;
	stde->pps_next		= -1;
	stde->pps_prev		= -1;
	stde->pps_sb		= 0xffffffff;
	stde->pps_size		= 0;
	if (str->hf) {
	    return (WriteFile( str->hf, block, BIGSIZE, &result, NULL ) && result == BIGSIZE);
	} else {
	    return _ilockbytes16_writeat(str->lockbytes, BIGSIZE, BIGSIZE, block);
	}
}

/******************************************************************************
 *		STORAGE_set_big_chain	[Internal]
 */
static BOOL
STORAGE_set_big_chain(stream_access16*str,int blocknr,INT type) {
	BYTE	block[BIGSIZE];
	LPINT	bbd = (LPINT)block;
	int	nextblocknr,bigblocknr;
	struct storage_header sth;
	BOOL ret;

	READ_HEADER(str);
	assert(blocknr!=type);
	while (blocknr>=0) {
		bigblocknr = sth.bbd_list[blocknr/128];
		assert(bigblocknr>=0);
		ret = STORAGE_get_big_block(str,bigblocknr,block);
		assert(ret);

		nextblocknr = bbd[blocknr&(128-1)];
		bbd[blocknr&(128-1)] = type;
		if (type>=0)
			return TRUE;
		ret = STORAGE_put_big_block(str,bigblocknr,block);
		assert(ret);
		type = STORAGE_CHAINENTRY_FREE;
		blocknr = nextblocknr;
	}
	return TRUE;
}

⌨️ 快捷键说明

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