mirror of
https://github.com/reactos/reactos.git
synced 2025-06-14 16:08:31 +00:00
Git conversion: Make reactos the root directory, move rosapps, rostests, wallpapers into modules, and delete rossubsys.
This commit is contained in:
parent
b94e2d8ca0
commit
c2c66aff7d
24198 changed files with 0 additions and 37285 deletions
695
sdk/lib/fslib/ext2lib/Inode.c
Normal file
695
sdk/lib/fslib/ext2lib/Inode.c
Normal file
|
@ -0,0 +1,695 @@
|
|||
/*
|
||||
* PROJECT: Mke2fs
|
||||
* FILE: Inode.c
|
||||
* PROGRAMMER: Matt Wu <mattwu@163.com>
|
||||
* HOMEPAGE: http://ext2.yeah.net
|
||||
*/
|
||||
|
||||
/* INCLUDES **************************************************************/
|
||||
|
||||
#include "Mke2fs.h"
|
||||
#include <debug.h>
|
||||
|
||||
/* DEFINITIONS ***********************************************************/
|
||||
|
||||
extern char *device_name;
|
||||
|
||||
/* FUNCTIONS *************************************************************/
|
||||
|
||||
|
||||
bool ext2_get_inode_lba(PEXT2_FILESYS Ext2Sys, ULONG no, LONGLONG *offset)
|
||||
{
|
||||
LONGLONG loc = 0;
|
||||
PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
|
||||
|
||||
if (no < 1 || no > pExt2Sb->s_inodes_count)
|
||||
{
|
||||
DPRINT1("Mke2fs: Inode value %lu was out of range in load_inode.(1-%ld)\n",
|
||||
no, pExt2Sb->s_inodes_count);
|
||||
*offset = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
loc = (LONGLONG)(Ext2Sys->blocksize) * Ext2Sys->group_desc[(no - 1) / pExt2Sb->s_inodes_per_group].bg_inode_table +
|
||||
((no - 1) % pExt2Sb->s_inodes_per_group) * sizeof(EXT2_INODE);
|
||||
|
||||
*offset = loc;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ext2_load_inode(PEXT2_FILESYS Ext2Sys, ULONG no, PEXT2_INODE pInode)
|
||||
{
|
||||
LONGLONG Offset;
|
||||
bool bRet = false;
|
||||
|
||||
if (ext2_get_inode_lba(Ext2Sys, no, &Offset))
|
||||
{
|
||||
bRet = NT_SUCCESS(Ext2ReadDisk(
|
||||
Ext2Sys,
|
||||
Offset,
|
||||
sizeof(EXT2_INODE),
|
||||
(unsigned char *)pInode));
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
bool ext2_save_inode(PEXT2_FILESYS Ext2Sys, ULONG no, PEXT2_INODE pInode)
|
||||
{
|
||||
LONGLONG offset;
|
||||
bool bRet = false;
|
||||
|
||||
if (ext2_get_inode_lba(Ext2Sys, no, &offset))
|
||||
{
|
||||
bRet = NT_SUCCESS(Ext2WriteDisk(
|
||||
Ext2Sys,
|
||||
offset,
|
||||
sizeof(EXT2_INODE),
|
||||
(unsigned char *)pInode));
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Right now, just search forward from the parent directory's block
|
||||
* group to find the next free inode.
|
||||
*
|
||||
* Should have a special policy for directories.
|
||||
*/
|
||||
|
||||
bool ext2_new_inode(PEXT2_FILESYS fs, ULONG dir, int mode,
|
||||
PEXT2_INODE_BITMAP map, ULONG *ret)
|
||||
{
|
||||
ULONG dir_group = 0;
|
||||
ULONG i;
|
||||
ULONG start_inode;
|
||||
|
||||
if (!map)
|
||||
map = fs->inode_map;
|
||||
|
||||
if (!map)
|
||||
return false;
|
||||
|
||||
if (dir > 0)
|
||||
dir_group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->ext2_sb);
|
||||
|
||||
start_inode = (dir_group * EXT2_INODES_PER_GROUP(fs->ext2_sb)) + 1;
|
||||
|
||||
if (start_inode < EXT2_FIRST_INODE(fs->ext2_sb))
|
||||
start_inode = EXT2_FIRST_INODE(fs->ext2_sb);
|
||||
|
||||
i = start_inode;
|
||||
|
||||
do
|
||||
{
|
||||
if (!ext2_test_inode_bitmap(map, i))
|
||||
break;
|
||||
|
||||
i++;
|
||||
|
||||
if (i > fs->ext2_sb->s_inodes_count)
|
||||
i = EXT2_FIRST_INODE(fs->ext2_sb);
|
||||
|
||||
} while (i != start_inode);
|
||||
|
||||
if (ext2_test_inode_bitmap(map, i))
|
||||
return false;
|
||||
|
||||
*ret = i;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ext2_expand_block( PEXT2_FILESYS Ext2Sys, PEXT2_INODE Inode,
|
||||
ULONG dwContent, ULONG Index, int layer,
|
||||
ULONG newBlk, ULONG *dwRet, ULONG *off )
|
||||
{
|
||||
ULONG *pData = NULL;
|
||||
ULONG i = 0, j = 0, temp = 1;
|
||||
ULONG dwBlk;
|
||||
ULONG dwNewBlk = newBlk;
|
||||
bool bDirty = false;
|
||||
bool bRet = true;
|
||||
ULONG Offset = 0;
|
||||
|
||||
PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
|
||||
|
||||
pData = (ULONG *)RtlAllocateHeap(RtlGetProcessHeap(), 0, Ext2Sys->blocksize);
|
||||
|
||||
if (!pData)
|
||||
{
|
||||
bRet = false;
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
if (!ext2_read_block(Ext2Sys, dwContent, (void *)pData))
|
||||
{
|
||||
bRet = false;
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
if (layer == 1)
|
||||
{
|
||||
*dwRet = dwContent;
|
||||
*off = Index;
|
||||
pData[Index] = newBlk;
|
||||
|
||||
bDirty = TRUE;
|
||||
}
|
||||
else if (layer <= 3)
|
||||
{
|
||||
temp = 1 << ((10 + pExt2Sb->s_log_block_size - 2) * (layer - 1));
|
||||
|
||||
i = Index / temp;
|
||||
j = Index % temp;
|
||||
|
||||
dwBlk = pData[i];
|
||||
|
||||
if (dwBlk == 0)
|
||||
{
|
||||
if (ext2_alloc_block(Ext2Sys, 0, &dwBlk) )
|
||||
{
|
||||
pData[i] = dwBlk;
|
||||
bDirty = true;
|
||||
|
||||
Inode->i_blocks += (Ext2Sys->blocksize / SECTOR_SIZE);
|
||||
}
|
||||
|
||||
if (!bDirty)
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
if (!ext2_expand_block(Ext2Sys, Inode, dwBlk, j, layer - 1, bDirty, &dwNewBlk, &Offset))
|
||||
{
|
||||
bRet = false;
|
||||
DPRINT1("Mke2fs: ext2_expand_block: ... error recuise...\n");
|
||||
goto errorout;
|
||||
}
|
||||
}
|
||||
|
||||
if (bDirty)
|
||||
{
|
||||
bRet = ext2_write_block(Ext2Sys, dwContent, (void *)pData);
|
||||
}
|
||||
|
||||
|
||||
errorout:
|
||||
|
||||
if (pData)
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, pData);
|
||||
|
||||
if (bRet && dwRet)
|
||||
*dwRet = dwNewBlk;
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool ext2_expand_inode( PEXT2_FILESYS Ext2Sys,
|
||||
PEXT2_INODE Inode,
|
||||
ULONG newBlk )
|
||||
{
|
||||
ULONG dwSizes[4] = {12, 1, 1, 1};
|
||||
ULONG Index = 0;
|
||||
ULONG dwTotal = 0;
|
||||
ULONG dwBlk = 0, dwNewBlk = 0, Offset = 0;
|
||||
PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
|
||||
int i = 0;
|
||||
bool bRet = true;
|
||||
ULONG TotalBlocks;
|
||||
|
||||
TotalBlocks = Inode->i_blocks / (Ext2Sys->blocksize / SECTOR_SIZE);
|
||||
Index = Ext2DataBlocks(Ext2Sys, TotalBlocks);
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
dwSizes[i] = dwSizes[i] << ((10 + pExt2Sb->s_log_block_size - 2) * i);
|
||||
dwTotal += dwSizes[i];
|
||||
}
|
||||
|
||||
if (Index >= dwTotal)
|
||||
{
|
||||
DPRINT1("Mke2fs: ext2_expand_inode: beyond the maxinum size of an inode.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (Index < dwSizes[i])
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
Inode->i_block[Index] = newBlk;
|
||||
}
|
||||
else
|
||||
{
|
||||
dwBlk = Inode->i_block[(i + 12 - 1)];
|
||||
|
||||
if (dwBlk == 0)
|
||||
{
|
||||
if (ext2_alloc_block(Ext2Sys, 0, &dwBlk))
|
||||
{
|
||||
Inode->i_block[(i + 12 - 1)] = dwBlk;
|
||||
|
||||
Inode->i_blocks += (Ext2Sys->blocksize / SECTOR_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
dwNewBlk = 0;
|
||||
bRet = ext2_expand_block(
|
||||
Ext2Sys,
|
||||
Inode,
|
||||
dwBlk,
|
||||
Index,
|
||||
i,
|
||||
newBlk,
|
||||
&dwNewBlk,
|
||||
&Offset );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
Index -= dwSizes[i];
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
bool ext2_get_block(PEXT2_FILESYS Ext2Sys, ULONG dwContent, ULONG Index, int layer, ULONG *dwRet)
|
||||
{
|
||||
ULONG *pData = NULL;
|
||||
LONGLONG Offset = 0;
|
||||
ULONG i = 0, j = 0, temp = 1;
|
||||
ULONG dwBlk = 0;
|
||||
bool bRet = true;
|
||||
|
||||
PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
|
||||
|
||||
Offset = (LONGLONG) dwContent;
|
||||
Offset = Offset * Ext2Sys->blocksize;
|
||||
|
||||
pData = (ULONG *)RtlAllocateHeap(RtlGetProcessHeap(), 0, Ext2Sys->blocksize);
|
||||
|
||||
if (!pData)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
memset(pData, 0, Ext2Sys->blocksize);
|
||||
|
||||
if (layer == 0)
|
||||
{
|
||||
dwBlk = dwContent;
|
||||
}
|
||||
else if (layer <= 3)
|
||||
{
|
||||
|
||||
if (!ext2_read_block(Ext2Sys, dwContent, (void *)pData))
|
||||
{
|
||||
bRet = false;
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
temp = 1 << ((10 + pExt2Sb->s_log_block_size - 2) * (layer - 1));
|
||||
|
||||
i = Index / temp;
|
||||
j = Index % temp;
|
||||
|
||||
if (!ext2_get_block(Ext2Sys, pData[i], j, layer - 1, &dwBlk))
|
||||
{
|
||||
bRet = false;
|
||||
DPRINT1("Mke2fs: ext2_get_block: ... error recuise...\n");
|
||||
goto errorout;
|
||||
}
|
||||
}
|
||||
|
||||
errorout:
|
||||
|
||||
if (pData)
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, pData);
|
||||
|
||||
if (bRet && dwRet)
|
||||
*dwRet = dwBlk;
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool ext2_block_map(PEXT2_FILESYS Ext2Sys, PEXT2_INODE inode, ULONG block, ULONG *dwRet)
|
||||
{
|
||||
ULONG dwSizes[4] = { 12, 1, 1, 1 };
|
||||
ULONG Index = 0;
|
||||
ULONG dwBlk = 0;
|
||||
PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
|
||||
UINT i;
|
||||
bool bRet = false;
|
||||
|
||||
Index = block;
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
dwSizes[i] = dwSizes[i] << ((10 + pExt2Sb->s_log_block_size - 2) * i);
|
||||
}
|
||||
|
||||
if (Index >= inode->i_blocks / (Ext2Sys->blocksize / SECTOR_SIZE))
|
||||
{
|
||||
DPRINT1("Mke2fs: ext2_block_map: beyond the size of the inode.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < 4; i++)
|
||||
{
|
||||
if (Index < dwSizes[i])
|
||||
{
|
||||
dwBlk = inode->i_block[i==0 ? (Index):(i + 12 - 1)];
|
||||
|
||||
bRet = ext2_get_block(Ext2Sys, dwBlk, Index , i, &dwBlk);
|
||||
|
||||
break;
|
||||
}
|
||||
Index -= dwSizes[i];
|
||||
}
|
||||
|
||||
if (bRet && dwBlk)
|
||||
{
|
||||
if (dwRet)
|
||||
*dwRet = dwBlk;
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
ULONG ext2_build_bdl(PEXT2_FILESYS Ext2Sys,
|
||||
PEXT2_INODE ext2_inode,
|
||||
IN ULONG offset,
|
||||
IN ULONG size,
|
||||
OUT PEXT2_BDL *ext2_bdl )
|
||||
{
|
||||
ULONG nBeg, nEnd, nBlocks;
|
||||
ULONG dwBlk;
|
||||
ULONG i;
|
||||
ULONG dwBytes = 0;
|
||||
LONGLONG lba;
|
||||
|
||||
PEXT2_BDL ext2bdl = NULL;
|
||||
|
||||
*ext2_bdl = NULL;
|
||||
|
||||
if (offset >= ext2_inode->i_size)
|
||||
{
|
||||
DPRINT1("Mke2fs: ext2_build_bdl: beyond the file range.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
if (offset + size > ext2_inode->i_size)
|
||||
{
|
||||
size = ext2_inode->i_size - offset;
|
||||
}
|
||||
*/
|
||||
|
||||
nBeg = offset / Ext2Sys->blocksize;
|
||||
nEnd = (size + offset + Ext2Sys->blocksize - 1) / Ext2Sys->blocksize;
|
||||
|
||||
nBlocks = nEnd - nBeg;
|
||||
|
||||
if (nBlocks > 0)
|
||||
{
|
||||
ext2bdl = (PEXT2_BDL)
|
||||
RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(EXT2_BDL) * nBlocks);
|
||||
|
||||
if (ext2bdl)
|
||||
{
|
||||
|
||||
memset(ext2bdl, 0, sizeof(EXT2_BDL) * nBlocks);
|
||||
|
||||
for (i = nBeg; i < nEnd; i++)
|
||||
{
|
||||
if (!ext2_block_map(Ext2Sys, ext2_inode, i, &dwBlk))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
lba = (LONGLONG) dwBlk;
|
||||
lba = lba * Ext2Sys->blocksize;
|
||||
|
||||
if (nBlocks == 1) // ie. (nBeg == nEnd - 1)
|
||||
{
|
||||
dwBytes = size;
|
||||
ext2bdl[i - nBeg].Lba = lba + (LONGLONG)(offset % (Ext2Sys->blocksize));
|
||||
ext2bdl[i - nBeg].Length = dwBytes;
|
||||
ext2bdl[i - nBeg].Offset = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (i == nBeg)
|
||||
{
|
||||
dwBytes = Ext2Sys->blocksize - (offset % (Ext2Sys->blocksize));
|
||||
ext2bdl[i - nBeg].Lba = lba + (LONGLONG)(offset % (Ext2Sys->blocksize));
|
||||
ext2bdl[i - nBeg].Length = dwBytes;
|
||||
ext2bdl[i - nBeg].Offset = 0;
|
||||
}
|
||||
else if (i == nEnd - 1)
|
||||
{
|
||||
ext2bdl[i - nBeg].Lba = lba;
|
||||
ext2bdl[i - nBeg].Length = size - dwBytes;
|
||||
ext2bdl[i - nBeg].Offset = dwBytes;
|
||||
dwBytes = size;
|
||||
}
|
||||
else
|
||||
{
|
||||
ext2bdl[i - nBeg].Lba = lba;
|
||||
ext2bdl[i - nBeg].Length = Ext2Sys->blocksize;
|
||||
ext2bdl[i - nBeg].Offset = dwBytes;
|
||||
dwBytes += Ext2Sys->blocksize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*ext2_bdl = ext2bdl;
|
||||
return nBlocks;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
|
||||
if (ext2bdl)
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ext2bdl);
|
||||
|
||||
// Error
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool ext2_read_inode(PEXT2_FILESYS Ext2Sys,
|
||||
ULONG ino,
|
||||
ULONG offset,
|
||||
PVOID Buffer,
|
||||
ULONG size,
|
||||
PULONG dwReturn)
|
||||
{
|
||||
PEXT2_BDL ext2_bdl = NULL;
|
||||
ULONG blocks, i;
|
||||
bool bRet = true;
|
||||
EXT2_INODE ext2_inode;
|
||||
ULONG dwTotal = 0;
|
||||
|
||||
if (!ext2_load_inode(Ext2Sys, ino, &ext2_inode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
blocks = ext2_build_bdl(Ext2Sys, &ext2_inode, offset, size, &ext2_bdl);
|
||||
|
||||
if (blocks <= 0)
|
||||
return false;
|
||||
|
||||
|
||||
for(i = 0; i < blocks; i++)
|
||||
{
|
||||
bRet = NT_SUCCESS(Ext2ReadDisk(
|
||||
Ext2Sys,
|
||||
ext2_bdl[i].Lba,
|
||||
ext2_bdl[i].Length,
|
||||
(PUCHAR)Buffer + ext2_bdl[i].Offset
|
||||
));
|
||||
|
||||
if (!bRet)
|
||||
break;
|
||||
dwTotal += ext2_bdl[i].Length;
|
||||
}
|
||||
|
||||
*dwReturn = dwTotal;
|
||||
|
||||
if (ext2_bdl)
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ext2_bdl);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
bool ext2_write_inode (PEXT2_FILESYS Ext2Sys,
|
||||
ULONG ino,
|
||||
ULONG offset,
|
||||
PVOID Buffer,
|
||||
ULONG size,
|
||||
PULONG dwReturn )
|
||||
{
|
||||
PEXT2_BDL ext2_bdl = NULL;
|
||||
ULONG blocks, i;
|
||||
bool bRet = true;
|
||||
EXT2_INODE inode;
|
||||
ULONG dwTotal = 0;
|
||||
ULONG dwBlk = 0;
|
||||
ULONG TotalBlks;
|
||||
|
||||
blocks = (size + offset + Ext2Sys->blocksize - 1) / Ext2Sys->blocksize;
|
||||
|
||||
if (!ext2_load_inode(Ext2Sys, ino, &inode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
TotalBlks = inode.i_blocks / (Ext2Sys->blocksize / SECTOR_SIZE);
|
||||
TotalBlks = Ext2DataBlocks(Ext2Sys, TotalBlks);
|
||||
|
||||
if (blocks > TotalBlks)
|
||||
{
|
||||
for (i=0; i < (blocks - TotalBlks); i++)
|
||||
{
|
||||
if (ext2_alloc_block(Ext2Sys, 0, &dwBlk) )
|
||||
{
|
||||
ext2_expand_inode(Ext2Sys, &inode, dwBlk);
|
||||
inode.i_blocks += (Ext2Sys->blocksize/SECTOR_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
blocks = ext2_build_bdl(Ext2Sys, &inode, offset, size, &ext2_bdl);
|
||||
|
||||
if (blocks <= 0)
|
||||
return false;
|
||||
|
||||
for(i = 0; i < blocks; i++)
|
||||
{
|
||||
bRet = NT_SUCCESS(Ext2WriteDisk(
|
||||
Ext2Sys,
|
||||
ext2_bdl[i].Lba,
|
||||
ext2_bdl[i].Length,
|
||||
(PUCHAR)Buffer + ext2_bdl[i].Offset
|
||||
));
|
||||
|
||||
if (!bRet)
|
||||
{
|
||||
goto errorout;
|
||||
}
|
||||
|
||||
dwTotal += ext2_bdl[i].Length;
|
||||
}
|
||||
|
||||
*dwReturn = dwTotal;
|
||||
|
||||
if (size + offset > inode.i_size)
|
||||
{
|
||||
inode.i_size = size + offset;
|
||||
}
|
||||
|
||||
ext2_save_inode(Ext2Sys, ino, &inode);
|
||||
|
||||
|
||||
errorout:
|
||||
|
||||
if (ext2_bdl)
|
||||
RtlFreeHeap(RtlGetProcessHeap(), 0, ext2_bdl);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
bool
|
||||
ext2_add_entry( PEXT2_FILESYS Ext2Sys,
|
||||
ULONG parent, ULONG inode,
|
||||
int filetype, char *name )
|
||||
{
|
||||
PEXT2_DIR_ENTRY2 dir = NULL, newdir = NULL;
|
||||
EXT2_INODE parent_inode;
|
||||
ULONG dwRet;
|
||||
char *buf;
|
||||
int rec_len;
|
||||
bool bRet = false;
|
||||
|
||||
rec_len = EXT2_DIR_REC_LEN(strlen(name));
|
||||
|
||||
if (!ext2_load_inode(Ext2Sys, parent, &parent_inode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, parent_inode.i_size);
|
||||
|
||||
if (!ext2_read_inode(Ext2Sys, parent, 0, buf, parent_inode.i_size, &dwRet))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
dir = (PEXT2_DIR_ENTRY2) buf;
|
||||
|
||||
while ((char *)dir < buf + parent_inode.i_size)
|
||||
{
|
||||
if ((dir->inode == 0 && dir->rec_len >= rec_len) ||
|
||||
(dir->rec_len >= dir->name_len + rec_len) )
|
||||
{
|
||||
if (dir->inode)
|
||||
{
|
||||
newdir = (PEXT2_DIR_ENTRY2) ((PUCHAR)dir + EXT2_DIR_REC_LEN(dir->name_len));
|
||||
newdir->rec_len = dir->rec_len - EXT2_DIR_REC_LEN(dir->name_len);
|
||||
|
||||
dir->rec_len = EXT2_DIR_REC_LEN(dir->name_len);
|
||||
|
||||
dir = newdir;
|
||||
}
|
||||
|
||||
dir->file_type = filetype;
|
||||
dir->inode = inode;
|
||||
dir->name_len = strlen(name);
|
||||
memcpy(dir->name, name, strlen(name));
|
||||
|
||||
bRet = true;
|
||||
break;
|
||||
}
|
||||
|
||||
dir = (PEXT2_DIR_ENTRY2) (dir->rec_len + (PUCHAR) dir);
|
||||
}
|
||||
|
||||
|
||||
if (bRet)
|
||||
return ext2_write_inode(Ext2Sys, parent, 0, buf, parent_inode.i_size, &dwRet);
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
bool ext2_reserve_inodes(PEXT2_FILESYS fs)
|
||||
{
|
||||
ULONG i;
|
||||
int group;
|
||||
|
||||
for (i = EXT2_ROOT_INO + 1; i < EXT2_FIRST_INODE(fs->ext2_sb); i++)
|
||||
{
|
||||
ext2_mark_inode_bitmap(fs->inode_map, i);
|
||||
group = ext2_group_of_ino(fs, i);
|
||||
fs->group_desc[group].bg_free_inodes_count--;
|
||||
fs->ext2_sb->s_free_inodes_count--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue