📄 storage.c
字号:
(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 + -