* remove little unused code

* code cleanup
This commit is contained in:
giantpune 2010-09-18 23:16:05 +00:00
parent e1a36e8988
commit 9e79c9d99b
326 changed files with 87736 additions and 80266 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r950</version>
<release_date>201009182245</release_date>
<version>1.0 r951</version>
<release_date>201009182308</release_date>
<short_description>Loads games from USB-devices</short_description>
<long_description>USB Loader GX is a libwiigui based USB iso loader with a wii-like GUI. You can install games to your HDDs and boot them with shorter loading times.
The interactive GUI is completely controllable with WiiMote, Classic Controller or GC Controller.

BIN
data/magic_patcher.o Normal file

Binary file not shown.

View File

@ -37,7 +37,8 @@
*
* Font face character glyph relevant data structure.
*/
typedef struct ftgxCharData_ {
typedef struct ftgxCharData_
{
int16_t renderOffsetX; /**< Texture X axis bearing offset. */
uint16_t glyphAdvanceX; /**< Character glyph X coordinate advance in pixels. */
uint32_t glyphIndex; /**< Charachter glyph index in the font face. */
@ -56,7 +57,8 @@ typedef struct ftgxCharData_ {
*
* Offset structure which hold both a maximum and minimum value.
*/
typedef struct ftgxDataOffset_ {
typedef struct ftgxDataOffset_
{
int16_t ascender; /**< Maximum data offset. */
int16_t descender; /**< Minimum data offset. */
int16_t max; /**< Maximum data offset. */

View File

@ -121,7 +121,8 @@ bool ZipFile::ExtractAll(const char *dest)
done += ret;
} while(done < uncompressed_size);
}
while ( done < uncompressed_size );
fclose( pfile );
unzCloseCurrentFile( File );

View File

@ -15,7 +15,8 @@
*
* Initializes the Wii's audio subsystem
***************************************************************************/
void InitAudio() {
void InitAudio()
{
AUDIO_Init( NULL );
ASND_Init();
ASND_Pause( 0 );
@ -27,7 +28,8 @@ void InitAudio() {
* Shuts down audio subsystem. Useful to avoid unpleasant sounds if a
* crash occurs during shutdown.
***************************************************************************/
void ShutdownAudio() {
void ShutdownAudio()
{
ASND_Pause( 1 );
ASND_End();
}

View File

@ -552,7 +552,8 @@ unsigned char * MD5fromFile(unsigned char *dst, const char *src)
file = fopen( src, "rb" );
if (file==NULL){
if ( file == NULL )
{
return NULL;
}
@ -569,7 +570,8 @@ unsigned char * MD5fromFile(unsigned char *dst, const char *src)
unsigned char * buffer = malloc( blksize );
if(buffer == NULL){
if ( buffer == NULL )
{
//no memory
fclose( file );
return NULL;
@ -580,7 +582,8 @@ unsigned char * MD5fromFile(unsigned char *dst, const char *src)
read = fread( buffer, 1, blksize, file );
( void )auth_md5SumCtx( ctx, buffer, read ); /* Pass only one block. */
} while(read > 0);
}
while ( read > 0 );
fclose( file );
free( buffer );

View File

@ -39,7 +39,8 @@ s32 dump_banner(const u8* discid,const char * dest)
ret = WDVD_OpenPartition( offset );
if (ret < 0) {
if ( ret < 0 )
{
//printf("ERROR: OpenPartition(0x%llx) %d\n", offset, ret);
return ret;
}

View File

@ -15,7 +15,8 @@ GuiBanner::GuiBanner(const char *tplfilepath)
FILE *tplfp = fopen( tplfilepath, "rb" );
if(tplfp !=NULL) {
if ( tplfp != NULL )
{
unsigned short heighttemp = 0;
unsigned short widthtemp = 0;
@ -27,7 +28,8 @@ GuiBanner::GuiBanner(const char *tplfilepath)
tplfilesize = ftell ( tplfp );
rewind ( tplfp );
memory = memalign( 32, tplfilesize );
if(!memory) {
if ( !memory )
{
fclose( tplfp );
return;
}
@ -38,13 +40,15 @@ GuiBanner::GuiBanner(const char *tplfilepath)
int ret;
ret = TPL_OpenTPLFromMemory( &tplfile, memory, tplfilesize );
if(ret < 0) {
if ( ret < 0 )
{
free( memory );
memory = NULL;
return;
}
ret = TPL_GetTexture( &tplfile, 0, &texObj );
if(ret < 0) {
if ( ret < 0 )
{
free( memory );
memory = NULL;
return;
@ -56,7 +60,9 @@ GuiBanner::GuiBanner(const char *tplfilepath)
widescreen = 0;
filecheck = true;
} else {
}
else
{
filecheck = false;
fclose( tplfp );
}
@ -76,13 +82,15 @@ GuiBanner::GuiBanner(void *mem, u32 len, int w, int h)
int ret;
ret = TPL_OpenTPLFromMemory( &tplfile, memory, tplfilesize );
if(ret < 0) {
if ( ret < 0 )
{
free( memory );
memory = NULL;
return;
}
ret = TPL_GetTexture( &tplfile, 0, &texObj );
if(ret < 0) {
if ( ret < 0 )
{
free( memory );
memory = NULL;
return;
@ -94,7 +102,8 @@ GuiBanner::GuiBanner(void *mem, u32 len, int w, int h)
GuiBanner::~GuiBanner()
{
if(memory != NULL) {
if ( memory != NULL )
{
free( memory );
memory = NULL;
}

View File

@ -72,7 +72,8 @@ void md5(u8 *data, u32 len, u8 *hash)
}
typedef struct {
typedef struct
{
u8 zeroes[0x40];
u32 imet; // "IMET"
u8 zero_six_zero_three[8]; // fixed, unknown purpose
@ -89,7 +90,8 @@ typedef struct {
u8 crypto[0x10];
} imet_data_t;
typedef struct {
typedef struct
{
u32 imd5_tag; // 0x494D4435 "IMD5";
u32 size; // size of the rest of part B, starting from next field.
u8 zeroes[8];
@ -148,13 +150,16 @@ u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
out_ptr = decompressed_data;
while (in_ptr < data_end) {
while ( in_ptr < data_end )
{
int bit;
u8 bitmask = *in_ptr;
in_ptr++;
for (bit = 0x80; bit != 0; bit >>= 1) {
if (bitmask & bit) {
for ( bit = 0x80; bit != 0; bit >>= 1 )
{
if ( bitmask & bit )
{
// Next section is compressed
u8 rep_length;
u16 rep_offset;
@ -164,14 +169,17 @@ u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
in_ptr++;
rep_offset = *in_ptr | ( rep_offset << 8 );
in_ptr++;
if (out_ptr-decompressed_data < rep_offset) {
if ( out_ptr - decompressed_data < rep_offset )
{
return NULL;
}
for ( ; rep_length > 0; rep_length--) {
for ( ; rep_length > 0; rep_length-- )
{
*out_ptr = out_ptr[-rep_offset-1];
out_ptr++;
if (out_ptr >= out_end) {
if ( out_ptr >= out_end )
{
// Need to grow buffer
decompressed_data = realloc( decompressed_data, unpacked_size * 2 );
out_ptr = decompressed_data + unpacked_size;
@ -179,11 +187,14 @@ u8* decompress_lz77(u8 *data, size_t data_size, size_t* decompressed_size)
out_end = decompressed_data + unpacked_size;
}
}
} else {
}
else
{
// Just copy byte
*out_ptr = *in_ptr;
out_ptr++;
if (out_ptr >= out_end) {
if ( out_ptr >= out_end )
{
// Need to grow buffer
decompressed_data = realloc( decompressed_data, unpacked_size * 2 );
out_ptr = decompressed_data + unpacked_size;
@ -209,22 +220,26 @@ static int write_imd5_lz77(u8* data, size_t size, char* outname)
size_t decompressed_size;
tag = be32( ( u8* ) & header->imd5_tag );
if (tag != 0x494D4435) {
if ( tag != 0x494D4435 )
{
return -4;
}
md5( data + 32, size - 32, md5_calc );
if (memcmp(&header->md5, md5_calc, 0x10)) {
if ( memcmp( &header->md5, md5_calc, 0x10 ) )
{
return -5;
}
size_in_imd5 = be32( ( u8* ) & header->size );
if (size_in_imd5 != size - 32) {
if ( size_in_imd5 != size - 32 )
{
return -6;
}
tag = be32( ( u8* ) & header->payload_tag );
if (tag == 0x4C5A3737) {
if ( tag == 0x4C5A3737 )
{
// "LZ77" - uncompress
decompressed_data = decompress_lz77( data + sizeof( imd5_header_t ), size - sizeof( imd5_header_t ), &decompressed_size );
if ( decompressed_data == NULL )
@ -233,7 +248,9 @@ static int write_imd5_lz77(u8* data, size_t size, char* outname)
//printf(", uncompressed %d bytes, md5 ok", decompressed_size);
free( decompressed_data );
} else {
}
else
{
write_file( &header->payload_tag, size - 32, outname );
//printf(", md5 ok");
}
@ -257,7 +274,8 @@ static int do_U8_archive(FILE *fp)
fread( &header, 1, sizeof header, fp );
tag = be32( ( u8* ) & header.tag );
if (tag != 0x55AA382D) {
if ( tag != 0x55AA382D )
{
return -1;
}
@ -275,7 +293,8 @@ static int do_U8_archive(FILE *fp)
fread( string_table, 1, rest_size, fp );
current_offset = data_offset;
for (i = 0; i < num_nodes; i++) {
for ( i = 0; i < num_nodes; i++ )
{
U8_node* node = &nodes[i];
u16 type = be16( ( u8* ) & node->type );
u16 name_offset = be16( ( u8* ) & node->name_offset );
@ -284,25 +303,31 @@ static int do_U8_archive(FILE *fp)
char* name = ( char* ) & string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
if ( type == 0x0100 )
{
// Directory
mkdir( name, 0777 );
chdir( name );
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
}
else
{
// Normal file
u8 padding[32];
if (type != 0x0000) {
if ( type != 0x0000 )
{
free( string_table );
return -2;
}
if (current_offset < my_data_offset) {
if ( current_offset < my_data_offset )
{
int diff = my_data_offset - current_offset;
if (diff > 32) {
if ( diff > 32 )
{
free( string_table );
return -3;
}
@ -316,14 +341,16 @@ static int do_U8_archive(FILE *fp)
int result;
result = write_imd5_lz77( file_data, size, name );
if ( result < 0 )
{free(string_table);
{
free( string_table );
return result;
}
//printf(")\n");
current_offset += size;
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
while ( dir_stack[dir_index] == i + 2 && dir_index > 0 )
{
chdir( ".." );
dir_index--;
}
@ -357,7 +384,8 @@ void do_U8_archivebanner(FILE *fp)
fread( &header, 1, sizeof header, fp );
tag = be32( ( u8* ) & header.tag );
if (tag != 0x55AA382D) {
if ( tag != 0x55AA382D )
{
//printf("No U8 tag");
exit( 0 );
}
@ -375,7 +403,8 @@ void do_U8_archivebanner(FILE *fp)
string_table = malloc( rest_size );
fread( string_table, 1, rest_size, fp );
for (i = 0; i < num_nodes; i++) {
for ( i = 0; i < num_nodes; i++ )
{
U8_node* node = &nodes[i];
u16 type = be16( ( u8* ) & node->type );
u16 name_offset = be16( ( u8* ) & node->name_offset );
@ -384,16 +413,20 @@ void do_U8_archivebanner(FILE *fp)
char* name = ( char* ) & string_table[name_offset];
u8* file_data;
if (type == 0x0100) {
if ( type == 0x0100 )
{
// Directory
mkdir( name, 0777 );
chdir( name );
dir_stack[++dir_index] = size;
//printf("%*s%s/\n", dir_index, "", name);
} else {
}
else
{
// Normal file
if (type != 0x0000) {
if ( type != 0x0000 )
{
printf( "Unknown type" );
exit( 0 );
}
@ -406,7 +439,8 @@ void do_U8_archivebanner(FILE *fp)
//printf("%*s %s (%d bytes)\n", dir_index, "", name, size);
}
while (dir_stack[dir_index] == i+2 && dir_index > 0) {
while ( dir_stack[dir_index] == i + 2 && dir_index > 0 )
{
chdir( ".." );
dir_index--;
}

View File

@ -23,7 +23,8 @@ extern GuiWindow * mainWindow;
/****************************************************************************
* CheatMenu
***************************************************************************/
int CheatMenu(const char * gameID) {
int CheatMenu( const char * gameID )
{
int choice = 0;
bool exit = false;
int ret = 1;
@ -65,7 +66,8 @@ int CheatMenu(const char * gameID) {
int download = 0;
switch (check) {
switch ( check )
{
case -1:
WindowPrompt( tr( "Error" ), tr( "Cheatfile is blank" ), tr( "OK" ) );
break;
@ -92,7 +94,8 @@ int CheatMenu(const char * gameID) {
titleTxt.SetMaxWidth( 350, SCROLL_HORIZONTAL );
titleTxt.SetPosition( 12, 40 );
for (int i = 0; i <= cntcheats; i++) {
for ( int i = 0; i <= cntcheats; i++ )
{
cheatslst.SetValue( i, "%s", c.getCheatName( i ).c_str() );
cheatslst.SetName( i, "OFF" );
}
@ -109,34 +112,46 @@ int CheatMenu(const char * gameID) {
mainWindow->Append( &w );
ResumeGui();
while (!exit) {
while ( !exit )
{
VIDEO_WaitVSync ();
ret = chtBrowser.GetClickedOption();
if (ret != -1) {
if ( ret != -1 )
{
const char *strCheck = cheatslst.GetName( ret );
if (strncmp(strCheck,"ON",2) == 0) {
if ( strncmp( strCheck, "ON", 2 ) == 0 )
{
cheatslst.SetName( ret, "%s", "OFF" );
} else if (strncmp(strCheck,"OFF",3) == 0) {
}
else if ( strncmp( strCheck, "OFF", 3 ) == 0 )
{
cheatslst.SetName( ret, "%s", "ON" );
}
}
if (createBtn.GetState() == STATE_CLICKED) {
if ( createBtn.GetState() == STATE_CLICKED )
{
createBtn.ResetState();
if (cntcheats > 0) {
if ( cntcheats > 0 )
{
int selectednrs[30];
int x = 0;
for (int i = 0; i <= cntcheats; i++) {
for ( int i = 0; i <= cntcheats; i++ )
{
const char *strCheck = cheatslst.GetName( i );
if (strncmp(strCheck,"ON",2) == 0) {
if ( strncmp( strCheck, "ON", 2 ) == 0 )
{
selectednrs[x] = i;
x++;
}
}
if (x == 0) {
if ( x == 0 )
{
WindowPrompt( tr( "Error" ), tr( "No cheats were selected" ), tr( "OK" ) );
} else {
}
else
{
subfoldercreate( Settings.Cheatcodespath );
string chtpath = Settings.Cheatcodespath;
string gctfname = chtpath + c.getGameID() + ".gct";
@ -145,10 +160,12 @@ int CheatMenu(const char * gameID) {
exit = true;
break;
}
} else WindowPrompt(tr("Error"),tr("Could not create GCT file"),tr("OK"));
}
else WindowPrompt( tr( "Error" ), tr( "Could not create GCT file" ), tr( "OK" ) );
}
if (backBtn.GetState() == STATE_CLICKED) {
if ( backBtn.GetState() == STATE_CLICKED )
{
backBtn.ResetState();
exit = true;
break;

View File

@ -12,11 +12,13 @@
#define ERRORRANGE "Error: CheatNr out of range"
GCTCheats::GCTCheats(void) {
GCTCheats::GCTCheats( void )
{
iCntCheats = 0;
}
GCTCheats::~GCTCheats(void) {
GCTCheats::~GCTCheats( void )
{
string sGameID = "";
string sGameTitle = "";
@ -25,43 +27,59 @@ GCTCheats::~GCTCheats(void) {
string sCheatComment[MAXCHEATS];*/
}
int GCTCheats::getCnt() {
int GCTCheats::getCnt()
{
return iCntCheats;
}
string GCTCheats::getGameName(void) {
string GCTCheats::getGameName( void )
{
return sGameTitle;
}
string GCTCheats::getGameID(void) {
string GCTCheats::getGameID( void )
{
return sGameID;
}
string GCTCheats::getCheat(int nr) {
if (nr <= (iCntCheats-1)) {
string GCTCheats::getCheat( int nr )
{
if ( nr <= ( iCntCheats - 1 ) )
{
return sCheats[nr];
} else {
}
else
{
return ERRORRANGE;
}
}
string GCTCheats::getCheatName(int nr) {
if (nr <= (iCntCheats-1)) {
string GCTCheats::getCheatName( int nr )
{
if ( nr <= ( iCntCheats - 1 ) )
{
return sCheatName[nr];
} else {
}
else
{
return ERRORRANGE;
}
}
string GCTCheats::getCheatComment(int nr) {
if (nr <= (iCntCheats-1)) {
string GCTCheats::getCheatComment( int nr )
{
if ( nr <= ( iCntCheats - 1 ) )
{
return sCheatComment[nr];
} else {
}
else
{
return ERRORRANGE;
}
}
int GCTCheats::createGCT(int nr,const char * filename) {
int GCTCheats::createGCT( int nr, const char * filename )
{
if ( nr == 0 )
return 0;
@ -83,7 +101,8 @@ int GCTCheats::createGCT(int nr,const char * filename) {
long int li;
int len = buf.size();
while (x < len) {
while ( x < len )
{
string temp = buf.substr( x, 2 );
li = strtol( temp.c_str(), NULL, 16 );
temp = li;
@ -96,7 +115,8 @@ int GCTCheats::createGCT(int nr,const char * filename) {
return 1;
}
int GCTCheats::createGCT(const char * chtbuffer,const char * filename) {
int GCTCheats::createGCT( const char * chtbuffer, const char * filename )
{
ofstream filestr;
filestr.open( filename );
@ -115,7 +135,8 @@ int GCTCheats::createGCT(const char * chtbuffer,const char * filename) {
long int li;
int len = buf.size();
while (x < len) {
while ( x < len )
{
string temp = buf.substr( x, 2 );
li = strtol( temp.c_str(), NULL, 16 );
temp = li;
@ -130,7 +151,8 @@ int GCTCheats::createGCT(const char * chtbuffer,const char * filename) {
return 1;
}
int GCTCheats::createGCT(int nr[],int cnt,const char * filename) {
int GCTCheats::createGCT( int nr[], int cnt, const char * filename )
{
if ( cnt == 0 )
return 0;
@ -148,14 +170,16 @@ int GCTCheats::createGCT(int nr[],int cnt,const char * filename) {
filestr.write( header, sizeof( header ) );
int c = 0;
while (c != cnt) {
while ( c != cnt )
{
int actnr = nr[c];
string buf = getCheat( actnr );
long int li;
int len = buf.size();
int x = 0;
while (x < len) {
while ( x < len )
{
string temp = buf.substr( x, 2 );
li = strtol( temp.c_str(), NULL, 16 );
temp = li;
@ -170,7 +194,8 @@ int GCTCheats::createGCT(int nr[],int cnt,const char * filename) {
return 1;
}
int GCTCheats::openTxtfile(const char * filename) {
int GCTCheats::openTxtfile( const char * filename )
{
ifstream filestr;
int i = 0;
string str;
@ -196,7 +221,8 @@ int GCTCheats::openTxtfile(const char * filename) {
if ( !sGameTitle[sGameTitle.length() - 1] == '\r' )
filestr.seekg( 0, ios_base::beg );
while (!filestr.eof()) {
while ( !filestr.eof() )
{
getline( filestr, sCheatName[i] ); // '\n' delimiter by default
if ( sCheatName[i][sCheatName[i].length() - 1] == '\r' )
sCheatName[i].erase( sCheatName[i].length() - 1 );
@ -204,31 +230,38 @@ int GCTCheats::openTxtfile(const char * filename) {
string cheatdata;
bool emptyline = false;
do {
do
{
getline( filestr, str );
if ( str[str.length() - 1] == '\r' )
str.erase( str.length() - 1 );
if (str == "" || str[0] == '\r' || str[0] == '\n') {
if ( str == "" || str[0] == '\r' || str[0] == '\n' )
{
emptyline = true;
break;
}
if (IsCode(str)) {
if ( IsCode( str ) )
{
// remove any garbage (comment) after code
while (str.size() > 17) {
while ( str.size() > 17 )
{
str.erase( str.length() - 1 );
}
cheatdata.append( str );
size_t found = cheatdata.find( ' ' );
cheatdata.replace( found, 1, "" );
} else {
}
else
{
//printf("%i",str.size());
sCheatComment[i] = str;
}
if ( filestr.eof() ) break;
} while (!emptyline);
}
while ( !emptyline );
sCheats[i] = cheatdata;
i++;
@ -239,14 +272,17 @@ int GCTCheats::openTxtfile(const char * filename) {
return 1;
}
bool GCTCheats::IsCode(const std::string& str) {
if (str[8] == ' ' && str.size() >= 17) {
bool GCTCheats::IsCode( const std::string& str )
{
if ( str[8] == ' ' && str.size() >= 17 )
{
// accept strings longer than 17 in case there is a comment on the same line as the code
char part1[9];
char part2[9];
snprintf( part1, sizeof( part1 ), "%c%c%c%c%c%c%c%c", str[0], str[1], str[2], str[3], str[4], str[5], str[6], str[7] );
snprintf( part2, sizeof( part2 ), "%c%c%c%c%c%c%c%c", str[9], str[10], str[11], str[12], str[13], str[14], str[15], str[16] );
if ((strtok(part1,"0123456789ABCDEFabcdef") == NULL) && (strtok(part2,"0123456789ABCDEFabcdef") == NULL)) {
if ( ( strtok( part1, "0123456789ABCDEFabcdef" ) == NULL ) && ( strtok( part2, "0123456789ABCDEFabcdef" ) == NULL ) )
{
return true;
}
}

View File

@ -14,7 +14,8 @@
using namespace std;
//!Handles Ocarina TXT Cheatfiles
class GCTCheats {
class GCTCheats
{
private:
string sGameID;
string sGameTitle;

View File

@ -44,7 +44,8 @@ sec_t fat_wbfs_sec = 0;
int fs_ntfs_mount = 0;
sec_t fs_ntfs_sec = 0;
int USBDevice_Init() {
int USBDevice_Init()
{
#ifdef DEBUG_FAT
gprintf( "\nUSBDevice_Init()" );
#endif
@ -55,7 +56,8 @@ int USBDevice_Init() {
//try first mount with cIOS
// if (!fatMount("USB", &__io_wiiums, 0, CACHE, SECTORS)) {
// //try now mount with libogc
if (!fatMount("USB", &__io_usbstorage2, 0, CACHE, SECTORS)) {
if ( !fatMount( "USB", &__io_usbstorage2, 0, CACHE, SECTORS ) )
{
#ifdef DEBUG_FAT
gprintf( ":-1" );
#endif
@ -71,7 +73,8 @@ int USBDevice_Init() {
return 0;
}
void USBDevice_deInit() {
void USBDevice_deInit()
{
#ifdef DEBUG_FAT
gprintf( "\nUSBDevice_deInit()" );
#endif
@ -82,7 +85,8 @@ void USBDevice_deInit() {
fat_usb_sec = 0;
}
int WBFSDevice_Init(u32 sector) {
int WBFSDevice_Init( u32 sector )
{
//closing all open Files write back the cache and then shutdown em!
fatUnmount( "WBFS:/" );
//right now mounts first FAT-partition
@ -90,21 +94,24 @@ int WBFSDevice_Init(u32 sector) {
//try first mount with cIOS
// if (!fatMount("WBFS", &__io_wiiums, 0, CACHE, SECTORS)) {
//try now mount with libogc
if (!fatMount("WBFS", &__io_usbstorage2, 0, CACHE, SECTORS)) {
if ( !fatMount( "WBFS", &__io_usbstorage2, 0, CACHE, SECTORS ) )
{
return -1;
}
// }
fat_wbfs_mount = 1;
fat_wbfs_sec = _FAT_startSector;
if (sector && fat_wbfs_sec != sector) {
if ( sector && fat_wbfs_sec != sector )
{
// This is an error situation...actually, but is ignored in Config loader also
// Should ask Oggzee about it...
}
return 0;
}
void WBFSDevice_deInit() {
void WBFSDevice_deInit()
{
//closing all open Files write back the cache and then shutdown em!
fatUnmount( "WBFS:/" );
@ -112,21 +119,24 @@ void WBFSDevice_deInit() {
fat_wbfs_sec = 0;
}
int isInserted(const char *path) {
int isInserted( const char *path )
{
if ( !strncmp( path, "USB:", 4 ) )
return 1;
return __io_sdhc.isInserted() || __io_wiisd.isInserted();
}
int SDCard_Init() {
int SDCard_Init()
{
#ifdef DEBUG_FAT
gprintf( "\nSDCard_Init()" );
#endif
//closing all open Files write back the cache and then shutdown em!
fatUnmount( "SD:/" );
//right now mounts first FAT-partition
if (fatMount("SD", &__io_wiisd, 0, CACHE, SECTORS)) {
if ( fatMount( "SD", &__io_wiisd, 0, CACHE, SECTORS ) )
{
fat_sd_mount = MOUNT_SD;
fat_sd_sec = _FAT_startSector;
#ifdef DEBUG_FAT
@ -134,7 +144,8 @@ int SDCard_Init() {
#endif
return 1;
}
else if (fatMount("SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE)) {
else if ( fatMount( "SD", &__io_sdhc, 0, CACHE, SDHC_SECTOR_SIZE ) )
{
fat_sd_mount = MOUNT_SDHC;
fat_sd_sec = _FAT_startSector;
#ifdef DEBUG_FAT
@ -148,7 +159,8 @@ int SDCard_Init() {
return -1;
}
void SDCard_deInit() {
void SDCard_deInit()
{
#ifdef DEBUG_FAT
gprintf( "\nSDCard_deInit()" );
#endif
@ -178,28 +190,37 @@ s32 MountNTFS(u32 sector)
setlocale( LC_CTYPE, "C-UTF-8" );
setlocale( LC_MESSAGES, "C-UTF-8" );
if (wbfsDev == WBFS_DEVICE_USB) {
if ( wbfsDev == WBFS_DEVICE_USB )
{
/* Initialize WBFS interface */
// if (!__io_wiiums.startup()) {
ret = __io_usbstorage2.startup();
if (!ret) {
if ( !ret )
{
return -1;
}
// }
/* Mount device */
// if (!ntfsMount("NTFS", &__io_wiiums, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_RECOVER)) {
ret = ntfsMount( "NTFS", &__io_usbstorage2, sector, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_READ_ONLY | NTFS_RECOVER );
if (!ret) {
if ( !ret )
{
return -2;
}
// }
} else if (wbfsDev == WBFS_DEVICE_SDHC) {
if (sdhc_mode_sd == 0) {
}
else if ( wbfsDev == WBFS_DEVICE_SDHC )
{
if ( sdhc_mode_sd == 0 )
{
ret = ntfsMount( "NTFS", &__io_sdhc, 0, CACHE, SECTORS, NTFS_SHOW_HIDDEN_FILES | NTFS_READ_ONLY | NTFS_RECOVER );
} else {
}
else
{
ret = ntfsMount( "NTFS", &__io_sdhc, 0, CACHE, SECTORS_SD, NTFS_SHOW_HIDDEN_FILES | NTFS_READ_ONLY | NTFS_RECOVER );
}
if (!ret) {
if ( !ret )
{
return -5;
}
}

View File

@ -2,7 +2,8 @@
#define _FATMOUNTER_H_
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
extern int fat_sd_mount;

View File

@ -4,7 +4,8 @@
#define _GECKO_H_
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
char ascii( char s );

View File

@ -48,7 +48,8 @@ u8 boothomebrew = 0;
/****************************************************************************
* roundup Function
***************************************************************************/
int roundup(float number) {
int roundup( float number )
{
if ( number == ( int ) number )
return ( int ) number;
else
@ -58,7 +59,8 @@ int roundup(float number) {
/****************************************************************************
* MenuHomebrewBrowse
***************************************************************************/
int MenuHomebrewBrowse() {
int MenuHomebrewBrowse()
{
int menu = MENU_NONE;
int choice = 0;
@ -66,12 +68,14 @@ int MenuHomebrewBrowse() {
u32 filecount = HomebrewFiles.GetFilecount();
if (!filecount) {
if ( !filecount )
{
WindowPrompt( tr( "No .dol or .elf files found." ), 0, tr( "OK" ) );
return MENU_DISCLIST;
}
enum {
enum
{
FADE,
LEFT,
RIGHT
@ -141,7 +145,8 @@ int MenuHomebrewBrowse() {
GuiImageData *IconData[4];
GuiImage *IconImg[4];
for (int i = 0; i < 4; i++) {
for ( int i = 0; i < 4; i++ )
{
IconData[i] = NULL;
IconImg[i] = NULL;
}
@ -150,7 +155,8 @@ int MenuHomebrewBrowse() {
GuiText backBtnTxt( tr( "Back" ) , 22, THEME.prompttext );
backBtnTxt.SetMaxWidth( btnOutline.GetWidth() - 30 );
GuiImage backBtnImg( &btnOutline );
if (Settings.wsprompt == yes) {
if ( Settings.wsprompt == yes )
{
backBtnTxt.SetWidescreen( CFG.widescreen );
backBtnImg.SetWidescreen( CFG.widescreen );
}
@ -297,7 +303,8 @@ int MenuHomebrewBrowse() {
MainButton4.SetTrigger( &trigA );
GuiImage wifiImg( &wifiImgData );
if (Settings.wsprompt == yes) {
if ( Settings.wsprompt == yes )
{
wifiImg.SetWidescreen( CFG.widescreen );
}
GuiButton wifiBtn( wifiImg.GetWidth(), wifiImg.GetHeight() );
@ -332,7 +339,8 @@ int MenuHomebrewBrowse() {
const int pages = roundup( filecount / 4.0f );
bool wifi_btn_loaded = false;
while (menu == MENU_NONE) { //set pageToDisplay to 0 to quit
while ( menu == MENU_NONE ) //set pageToDisplay to 0 to quit
{
VIDEO_WaitVSync ();
menu = MENU_NONE;
@ -345,13 +353,16 @@ int MenuHomebrewBrowse() {
MainButton3.StopEffect();
MainButton4.StopEffect();
if (slidedirection == RIGHT) {
if ( slidedirection == RIGHT )
{
MainButton1.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 60 );
MainButton2.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 60 );
MainButton3.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 60 );
MainButton4.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_OUT, 60 );
while ( MainButton1.GetEffect() > 0 ) usleep( 50 );
} else if (slidedirection == LEFT) {
}
else if ( slidedirection == LEFT )
{
MainButton1.SetEffect( EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 60 );
MainButton2.SetEffect( EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 60 );
MainButton3.SetEffect( EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 60 );
@ -364,20 +375,25 @@ int MenuHomebrewBrowse() {
mainWindow->RemoveAll();
/** Set new icons **/
for (int i = 0; i < 4; i++) {
if (IconData[i] != NULL) {
for ( int i = 0; i < 4; i++ )
{
if ( IconData[i] != NULL )
{
delete IconData[i];
IconData[i] = NULL;
}
if (IconImg[i] != NULL) {
if ( IconImg[i] != NULL )
{
delete IconImg[i];
IconImg[i] = NULL;
}
if (fileoffset+i < (int) filecount) {
if ( fileoffset + i < ( int ) filecount )
{
char iconpath[200];
snprintf( iconpath, sizeof( iconpath ), "%sicon.png", HomebrewFiles.GetFilepath( fileoffset + i ) );
IconData[i] = new GuiImageData( iconpath, 0 );
if (IconData[i]->GetImage()) {
if ( IconData[i]->GetImage() )
{
IconImg[i] = new GuiImage( IconData[i] );
IconImg[i]->SetAlignment( ALIGN_LEFT, ALIGN_MIDDLE );
IconImg[i]->SetPosition( 12, 0 );
@ -414,20 +430,25 @@ int MenuHomebrewBrowse() {
w.Append( &GoRightBtn );
w.Append( &GoLeftBtn );
if (pageToDisplay == pages) {
if ( pageToDisplay == pages )
{
int buttonsleft = filecount - ( pages - 1 ) * 4;
char * shortpath = NULL;
char temp[200];
if (buttonsleft > 0) {
if ( buttonsleft > 0 )
{
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset ) );
if (XMLInfo[0].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[0].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[0].GetName() );
MainButton1Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[0].GetShortDescription() );
MainButton1DescTxt.SetText( MainButtonText );
MainButton1DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset ) ), "%s", HomebrewFiles.GetFilepath( fileoffset ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset ) );
@ -439,15 +460,19 @@ int MenuHomebrewBrowse() {
}
w.Append( &MainButton1 );
}
if (buttonsleft > 1) {
if ( buttonsleft > 1 )
{
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset + 1 ) );
if (XMLInfo[1].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[1].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[1].GetName() );
MainButton2Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[1].GetShortDescription() );
MainButton2DescTxt.SetText( MainButtonText );
MainButton2DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 1 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 1 ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 1 ) );
@ -459,15 +484,19 @@ int MenuHomebrewBrowse() {
}
w.Append( &MainButton2 );
}
if (buttonsleft > 2) {
if ( buttonsleft > 2 )
{
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset + 2 ) );
if (XMLInfo[3].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[3].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetName() );
MainButton3Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetShortDescription() );
MainButton3DescTxt.SetText( MainButtonText );
MainButton3DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 2 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 2 ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 2 ) );
@ -479,15 +508,19 @@ int MenuHomebrewBrowse() {
}
w.Append( &MainButton3 );
}
if (buttonsleft > 3) {
if ( buttonsleft > 3 )
{
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset + 3 ) );
if (XMLInfo[3].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[3].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetName() );
MainButton4Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetShortDescription() );
MainButton4DescTxt.SetText( MainButtonText );
MainButton4DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 3 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 3 ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 3 ) );
@ -499,18 +532,23 @@ int MenuHomebrewBrowse() {
}
w.Append( &MainButton4 );
}
} else {
}
else
{
char temp[200];
char *shortpath = NULL;
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset ) );
if (XMLInfo[0].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[0].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[0].GetName() );
MainButton1Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[0].GetShortDescription() );
MainButton1DescTxt.SetText( MainButtonText );
MainButton1DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset ) ), "%s", HomebrewFiles.GetFilepath( fileoffset ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset ) );
@ -524,13 +562,16 @@ int MenuHomebrewBrowse() {
w.Append( &MainButton1 );
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset + 1 ) );
if (XMLInfo[1].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[1].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[1].GetName() );
MainButton2Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[1].GetShortDescription() );
MainButton2DescTxt.SetText( MainButtonText );
MainButton2DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 1 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 1 ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 1 ) );
@ -544,13 +585,16 @@ int MenuHomebrewBrowse() {
w.Append( &MainButton2 );
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset + 2 ) );
if (XMLInfo[3].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[3].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetName() );
MainButton3Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetShortDescription() );
MainButton3DescTxt.SetText( MainButtonText );
MainButton3DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 2 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 2 ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 2 ) );
@ -563,13 +607,16 @@ int MenuHomebrewBrowse() {
w.Append( &MainButton3 );
snprintf( temp, sizeof( temp ), "%smeta.xml", HomebrewFiles.GetFilepath( fileoffset + 3 ) );
if (XMLInfo[3].LoadHomebrewXMLData(temp) > 0) {
if ( XMLInfo[3].LoadHomebrewXMLData( temp ) > 0 )
{
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetName() );
MainButton4Txt.SetText( MainButtonText );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s", XMLInfo[3].GetShortDescription() );
MainButton4DescTxt.SetText( MainButtonText );
MainButton4DescOverTxt.SetText( MainButtonText );
} else {
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 3 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 3 ) );
shortpath = strrchr( temp, '/' );
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 3 ) );
@ -593,17 +640,22 @@ int MenuHomebrewBrowse() {
MainButton3.SetEffectGrow();
MainButton4.SetEffectGrow();
if (slidedirection == FADE) {
if ( slidedirection == FADE )
{
MainButton1.SetEffect( EFFECT_FADE, 20 );
MainButton2.SetEffect( EFFECT_FADE, 20 );
MainButton3.SetEffect( EFFECT_FADE, 20 );
MainButton4.SetEffect( EFFECT_FADE, 20 );
} else if (slidedirection == LEFT) {
}
else if ( slidedirection == LEFT )
{
MainButton1.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 60 );
MainButton2.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 60 );
MainButton3.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 60 );
MainButton4.SetEffect( EFFECT_SLIDE_LEFT | EFFECT_SLIDE_IN, 60 );
} else if (slidedirection == RIGHT) {
}
else if ( slidedirection == RIGHT )
{
MainButton1.SetEffect( EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 60 );
MainButton2.SetEffect( EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 60 );
MainButton3.SetEffect( EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_IN, 60 );
@ -616,10 +668,12 @@ int MenuHomebrewBrowse() {
while ( MainButton1.GetEffect() > 0 ) usleep( 50 );
while (!changed) {
while ( !changed )
{
VIDEO_WaitVSync ();
if (MainButton1.GetState() == STATE_CLICKED) {
if ( MainButton1.GetState() == STATE_CLICKED )
{
char temp[200];
char iconpath[200];
char metapath[200];
@ -639,14 +693,17 @@ int MenuHomebrewBrowse() {
snprintf( temp, sizeof( temp ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset ) );
int choice = HBCWindowPrompt( XMLInfo[0].GetName(), XMLInfo[0].GetCoder(), XMLInfo[0].GetVersion(), XMLInfo[0].GetReleasedate(), XMLInfo[0].GetLongDescription(), iconpath, filesize );
if (choice == 1) {
if ( choice == 1 )
{
boothomebrew = 1;
menu = MENU_EXIT;
snprintf( Settings.selected_homebrew, sizeof( Settings.selected_homebrew ), "%s%s", HomebrewFiles.GetFilepath( fileoffset ), HomebrewFiles.GetFilename( fileoffset ) );
break;
}
MainButton1.ResetState();
} else if (MainButton2.GetState() == STATE_CLICKED) {
}
else if ( MainButton2.GetState() == STATE_CLICKED )
{
char temp[200];
char iconpath[200];
char metapath[200];
@ -666,14 +723,17 @@ int MenuHomebrewBrowse() {
snprintf( temp, sizeof( temp ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 1 ) );
int choice = HBCWindowPrompt( XMLInfo[1].GetName(), XMLInfo[1].GetCoder(), XMLInfo[1].GetVersion(), XMLInfo[1].GetReleasedate(), XMLInfo[1].GetLongDescription(), iconpath, filesize );
if (choice == 1) {
if ( choice == 1 )
{
boothomebrew = 1;
menu = MENU_EXIT;
snprintf( Settings.selected_homebrew, sizeof( Settings.selected_homebrew ), "%s%s", HomebrewFiles.GetFilepath( fileoffset + 1 ), HomebrewFiles.GetFilename( fileoffset + 1 ) );
break;
}
MainButton2.ResetState();
} else if (MainButton3.GetState() == STATE_CLICKED) {
}
else if ( MainButton3.GetState() == STATE_CLICKED )
{
char temp[200];
char iconpath[200];
char metapath[200];
@ -693,14 +753,17 @@ int MenuHomebrewBrowse() {
snprintf( temp, sizeof( temp ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 2 ) );
int choice = HBCWindowPrompt( XMLInfo[2].GetName(), XMLInfo[2].GetCoder(), XMLInfo[2].GetVersion(), XMLInfo[2].GetReleasedate(), XMLInfo[2].GetLongDescription(), iconpath, filesize );
if (choice == 1) {
if ( choice == 1 )
{
boothomebrew = 1;
menu = MENU_EXIT;
snprintf( Settings.selected_homebrew, sizeof( Settings.selected_homebrew ), "%s%s", HomebrewFiles.GetFilepath( fileoffset + 2 ), HomebrewFiles.GetFilename( fileoffset + 2 ) );
break;
}
MainButton3.ResetState();
} else if (MainButton4.GetState() == STATE_CLICKED) {
}
else if ( MainButton4.GetState() == STATE_CLICKED )
{
char temp[200];
char iconpath[200];
char metapath[200];
@ -720,7 +783,8 @@ int MenuHomebrewBrowse() {
snprintf( temp, sizeof( temp ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset + 3 ) );
int choice = HBCWindowPrompt( XMLInfo[3].GetName(), XMLInfo[3].GetCoder(), XMLInfo[3].GetVersion(), XMLInfo[3].GetReleasedate(), XMLInfo[3].GetLongDescription(), iconpath, filesize );
if (choice == 1) {
if ( choice == 1 )
{
boothomebrew = 1;
menu = MENU_EXIT;
snprintf( Settings.selected_homebrew, sizeof( Settings.selected_homebrew ), "%s%s", HomebrewFiles.GetFilepath( fileoffset + 3 ), HomebrewFiles.GetFilename( fileoffset + 3 ) );
@ -734,12 +798,14 @@ int MenuHomebrewBrowse() {
else if ( reset == 1 )
Sys_Reboot();
else if (backBtn.GetState() == STATE_CLICKED) {
else if ( backBtn.GetState() == STATE_CLICKED )
{
menu = MENU_DISCLIST;
changed = true;
}
else if (GoLeftBtn.GetState() == STATE_CLICKED) {
else if ( GoLeftBtn.GetState() == STATE_CLICKED )
{
pageToDisplay--;
/** Change direction of the flying buttons **/
if ( pageToDisplay < 1 )
@ -749,7 +815,8 @@ int MenuHomebrewBrowse() {
GoLeftBtn.ResetState();
}
else if (GoRightBtn.GetState() == STATE_CLICKED) {
else if ( GoRightBtn.GetState() == STATE_CLICKED )
{
pageToDisplay++;
/** Change direction of the flying buttons **/
if ( pageToDisplay > pages )
@ -759,28 +826,36 @@ int MenuHomebrewBrowse() {
GoRightBtn.ResetState();
}
else if (wifiBtn.GetState() == STATE_CLICKED) {
else if ( wifiBtn.GetState() == STATE_CLICKED )
{
ResumeNetworkWait();
wifiBtn.ResetState();
}
else if (homo.GetState() == STATE_CLICKED) {
else if ( homo.GetState() == STATE_CLICKED )
{
cfg_save_global();
bgMusic->Pause();
choice = WindowExitPrompt();
bgMusic->Resume();
if (choice == 3) {
if ( choice == 3 )
{
Sys_LoadMenu(); // Back to System Menu
} else if (choice == 2) {
}
else if ( choice == 2 )
{
Sys_BackToLoader();
} else {
}
else
{
homo.ResetState();
}
}
else if (infilesize > 0) {
else if ( infilesize > 0 )
{
char filesizetxt[50];
char temp[50];
@ -793,14 +868,18 @@ int MenuHomebrewBrowse() {
int choice = WindowPrompt( filesizetxt, temp, tr( "OK" ), tr( "Cancel" ) );
if (choice == 1) {
if ( choice == 1 )
{
int res = AllocHomebrewMemory( infilesize );
if (res < 0) {
if ( res < 0 )
{
CloseConnection();
WindowPrompt( tr( "Not enough free memory." ), 0, tr( "OK" ) );
} else {
}
else
{
u32 read = 0;
u8 *temp = NULL;
int len = NETWORKBLOCKSIZE;
@ -808,7 +887,8 @@ int MenuHomebrewBrowse() {
bool error = false;
u8 *ptr = temp;
while (read < infilesize) {
while ( read < infilesize )
{
ShowProgress( tr( "Receiving file from:" ), GetIncommingIP(), NULL, read, infilesize, true );
@ -819,12 +899,14 @@ int MenuHomebrewBrowse() {
int result = network_read( ptr, len );
if (result < 0) {
if ( result < 0 )
{
WindowPrompt( tr( "Error while transfering data." ), 0, tr( "OK" ) );
error = true;
break;
}
if (!result) {
if ( !result )
{
break;
}
@ -834,15 +916,18 @@ int MenuHomebrewBrowse() {
}
char filename[101];
if (!error) {
if ( !error )
{
network_read( ( u8* ) &filename, 100 );
// Do we need to unzip this thing?
if (wiiloadVersion[0] > 0 || wiiloadVersion[1] > 4) {
if ( wiiloadVersion[0] > 0 || wiiloadVersion[1] > 4 )
{
// We need to unzip...
if (temp[0] == 'P' && temp[1] == 'K' && temp[2] == 0x03 && temp[3] == 0x04) {
if ( temp[0] == 'P' && temp[1] == 'K' && temp[2] == 0x03 && temp[3] == 0x04 )
{
// It's a zip file, unzip to the apps directory
// Zip archive, ask for permission to install the zip
@ -857,9 +942,12 @@ int MenuHomebrewBrowse() {
// Now unzip the zip file...
unzFile uf = unzOpen( zippath );
if (uf==NULL) {
if ( uf == NULL )
{
error = true;
} else {
}
else
{
extractZip( uf, 0, 1, 0, Settings.homebrewapps_path );
unzCloseCurrentFile( uf );
@ -869,10 +957,14 @@ int MenuHomebrewBrowse() {
menu = MENU_HOMEBREWBROWSE;
break;
}
} else {
}
else
{
error = true;
}
} else if (uncfilesize != 0) { // if uncfilesize == 0, it's not compressed
}
else if ( uncfilesize != 0 ) // if uncfilesize == 0, it's not compressed
{
// It's compressed, uncompress
u8 *unc = ( u8 * ) malloc( uncfilesize );
uLongf f = uncfilesize;
@ -885,7 +977,8 @@ int MenuHomebrewBrowse() {
}
}
if (!error && strstr(filename,".zip") == NULL) {
if ( !error && strstr( filename, ".zip" ) == NULL )
{
innetbuffer = temp;
}
@ -893,21 +986,29 @@ int MenuHomebrewBrowse() {
ProgressStop();
if (error || read != infilesize) {
if ( error || read != infilesize )
{
WindowPrompt( tr( "Error:" ), tr( "No data could be read." ), tr( "OK" ) );
FreeHomebrewBuffer();
} else {
}
else
{
if ( strstr( filename, ".dol" ) || strstr( filename, ".DOL" )
|| strstr(filename,".elf") || strstr(filename,".ELF")) {
|| strstr( filename, ".elf" ) || strstr( filename, ".ELF" ) )
{
boothomebrew = 2;
AddBootArgument( filename );
menu = MENU_EXIT;
CloseConnection();
break;
} else if (strstr(filename,".zip")) {
}
else if ( strstr( filename, ".zip" ) )
{
WindowPrompt( tr( "Success:" ), tr( "Uploaded ZIP file installed to homebrew directory." ), tr( "OK" ) );
CloseConnection();
} else {
}
else
{
FreeHomebrewBuffer();
WindowPrompt( tr( "ERROR:" ), tr( "Not a DOL/ELF file." ), tr( "OK" ) );
}
@ -918,7 +1019,8 @@ int MenuHomebrewBrowse() {
ResumeNetworkWait();
}
else if (channelBtn.GetState() == STATE_CLICKED) {
else if ( channelBtn.GetState() == STATE_CLICKED )
{
w.SetState( STATE_DISABLED );
//10001 are the channels that are installed as channels, not including shop channel/mii channel etc
TitleBrowser();
@ -929,8 +1031,10 @@ int MenuHomebrewBrowse() {
}
if (IsNetworkInit()) {
if (!wifi_btn_loaded) {
if ( IsNetworkInit() )
{
if ( !wifi_btn_loaded )
{
wifiBtn.SetAlpha( 255 );
titleTT = new GuiTooltip( GetNetworkIP() );
@ -947,12 +1051,15 @@ int MenuHomebrewBrowse() {
HaltGui();
for (int i = 0; i < 4; i++) {
if (IconData[i] != NULL) {
for ( int i = 0; i < 4; i++ )
{
if ( IconData[i] != NULL )
{
delete IconData[i];
IconData[i] = NULL;
}
if (IconImg[i] != NULL) {
if ( IconImg[i] != NULL )
{
delete IconImg[i];
IconImg[i] = NULL;
}

View File

@ -9,11 +9,13 @@
#include "HomebrewFiles.h"
HomebrewFiles::HomebrewFiles(const char * path) {
HomebrewFiles::HomebrewFiles( const char * path )
{
filecount = 0;
FileInfo = ( FileInfos * ) malloc( sizeof( FileInfos ) );
if (!FileInfo) {
if ( !FileInfo )
{
return;
}
@ -23,42 +25,54 @@ HomebrewFiles::HomebrewFiles(const char * path) {
this->SortList();
}
HomebrewFiles::~HomebrewFiles() {
if (FileInfo) {
HomebrewFiles::~HomebrewFiles()
{
if ( FileInfo )
{
free( FileInfo );
FileInfo = NULL;
}
}
bool HomebrewFiles::LoadPath(const char * folderpath) {
bool HomebrewFiles::LoadPath( const char * folderpath )
{
struct stat st;
DIR_ITER *dir = NULL;
char filename[1024];
dir = diropen( folderpath );
if (dir == NULL) {
if ( dir == NULL )
{
return false;
}
while (dirnext(dir,filename,&st) == 0) {
if ((st.st_mode & S_IFDIR) != 0) {
if (strcmp(filename,".") != 0 && strcmp(filename,"..") != 0) {
while ( dirnext( dir, filename, &st ) == 0 )
{
if ( ( st.st_mode & S_IFDIR ) != 0 )
{
if ( strcmp( filename, "." ) != 0 && strcmp( filename, ".." ) != 0 )
{
char currentname[200];
snprintf( currentname, sizeof( currentname ), "%s%s/", folderpath, filename );
this->LoadPath( currentname );
}
} else {
}
else
{
char temp[5];
for (int i = 0; i < 5; i++) {
for ( int i = 0; i < 5; i++ )
{
temp[i] = filename[strlen( filename )-4+i];
}
if ( ( strncasecmp( temp, ".dol", 4 ) == 0 || strncasecmp( temp, ".elf", 4 ) == 0 )
&& filecount < MAXHOMEBREWS && filename[0]!='.') {
&& filecount < MAXHOMEBREWS && filename[0] != '.' )
{
FileInfo = ( FileInfos * ) realloc( FileInfo, ( filecount + 1 ) * sizeof( FileInfos ) );
if (!FileInfo) {
if ( !FileInfo )
{
free( FileInfo );
FileInfo = NULL;
filecount = 0;
@ -80,37 +94,43 @@ bool HomebrewFiles::LoadPath(const char * folderpath) {
return true;
}
char * HomebrewFiles::GetFilename(int ind) {
char * HomebrewFiles::GetFilename( int ind )
{
if ( ind > filecount )
return NULL;
else
return FileInfo[ind].FileName;
}
char * HomebrewFiles::GetFilepath(int ind) {
char * HomebrewFiles::GetFilepath( int ind )
{
if ( ind > filecount )
return NULL;
else
return FileInfo[ind].FilePath;
}
unsigned int HomebrewFiles::GetFilesize(int ind) {
unsigned int HomebrewFiles::GetFilesize( int ind )
{
if ( ind > filecount || !filecount || !FileInfo )
return NULL;
else
return FileInfo[ind].FileSize;
}
int HomebrewFiles::GetFilecount() {
int HomebrewFiles::GetFilecount()
{
return filecount;
}
static int ListCompare(const void *a, const void *b) {
static int ListCompare( const void *a, const void *b )
{
FileInfos *ab = ( FileInfos* ) a;
FileInfos *bb = ( FileInfos* ) b;
return stricmp( ( char * ) ab->FilePath, ( char * ) bb->FilePath );
}
void HomebrewFiles::SortList() {
void HomebrewFiles::SortList()
{
qsort( FileInfo, filecount, sizeof( FileInfos ), ListCompare );
}

View File

@ -7,13 +7,15 @@
#define MAXHOMEBREWS 500
typedef struct {
typedef struct
{
char FileName[100];
char FilePath[150];
unsigned int FileSize;
} FileInfos;
class HomebrewFiles {
class HomebrewFiles
{
public:
//!Constructor
//!\param path Path where to check for homebrew files

View File

@ -8,7 +8,8 @@
#include "dolloader.h"
typedef struct _dolheader {
typedef struct _dolheader
{
u32 text_pos[7];
u32 data_pos[11];
u32 text_start[7];
@ -20,19 +21,23 @@ typedef struct _dolheader {
u32 entry_point;
} dolheader;
u32 load_dol(const void *dolstart, struct __argv *argv) {
u32 load_dol( const void *dolstart, struct __argv *argv )
{
u32 i;
dolheader *dolfile;
if (dolstart) {
if ( dolstart )
{
dolfile = ( dolheader * ) dolstart;
for (i = 0; i < 7; i++) {
for ( i = 0; i < 7; i++ )
{
if ( ( !dolfile->text_size[i] ) || ( dolfile->text_start[i] < 0x100 ) ) continue;
ICInvalidateRange ( ( void * ) dolfile->text_start[i], dolfile->text_size[i] );
memcpy( ( void * ) dolfile->text_start[i], dolstart + dolfile->text_pos[i], dolfile->text_size[i] );
}
for (i = 0; i < 11; i++) {
for ( i = 0; i < 11; i++ )
{
if ( ( !dolfile->data_size[i] ) || ( dolfile->data_start[i] < 0x100 ) ) continue;
memcpy( ( void * ) dolfile->data_start[i], dolstart + dolfile->data_pos[i], dolfile->data_size[i] );
DCFlushRangeNoSync ( ( void * ) dolfile->data_start[i], dolfile->data_size[i] );
@ -41,7 +46,8 @@ u32 load_dol(const void *dolstart, struct __argv *argv) {
memset ( ( void * ) dolfile->bss_start, 0, dolfile->bss_size );
DCFlushRange( ( void * ) dolfile->bss_start, dolfile->bss_size );
if (argv && argv->argvMagic == ARGV_MAGIC) {
if ( argv && argv->argvMagic == ARGV_MAGIC )
{
void *new_argv = ( void * )( dolfile->entry_point + 8 );
memcpy( new_argv, argv, sizeof( *argv ) );
DCFlushRange( new_argv, sizeof( *argv ) );

View File

@ -2,7 +2,8 @@
#define _DOLLOADER_H_
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
extern void __exception_closeall();

View File

@ -77,8 +77,10 @@ void SetupPads()
* ShutoffRumble
***************************************************************************/
void ShutoffRumble() {
for (int i=0;i<4;i++) {
void ShutoffRumble()
{
for ( int i = 0; i < 4; i++ )
{
WPAD_Rumble( i, 0 );
rumbleCount[i] = 0;
}
@ -88,14 +90,20 @@ void ShutoffRumble() {
* DoRumble
***************************************************************************/
void DoRumble(int i) {
if (rumbleRequest[i] && rumbleCount[i] < 3) {
void DoRumble( int i )
{
if ( rumbleRequest[i] && rumbleCount[i] < 3 )
{
WPAD_Rumble( i, 1 ); // rumble on
rumbleCount[i]++;
} else if (rumbleRequest[i]) {
}
else if ( rumbleRequest[i] )
{
rumbleCount[i] = 20;
rumbleRequest[i] = 0;
} else {
}
else
{
if ( rumbleCount[i] )
rumbleCount[i]--;
WPAD_Rumble( i, 0 ); // rumble off
@ -108,25 +116,31 @@ void DoRumble(int i) {
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 WPAD_Stick(u8 chan, u8 right, int axis) {
s8 WPAD_Stick( u8 chan, u8 right, int axis )
{
float mag = 0.0;
float ang = 0.0;
WPADData *data = WPAD_Data( chan );
switch (data->exp.type) {
switch ( data->exp.type )
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0) {
if ( right == 0 )
{
mag = data->exp.nunchuk.js.mag;
ang = data->exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0) {
if ( right == 0 )
{
mag = data->exp.classic.ljs.mag;
ang = data->exp.classic.ljs.ang;
} else {
}
else
{
mag = data->exp.classic.rjs.mag;
ang = data->exp.classic.rjs.ang;
}

View File

@ -13,7 +13,8 @@
#include "network/networkops.h"
#include "network/http.h"
int updateLanguageFiles() {
int updateLanguageFiles()
{
char languageFiles[50][MAXLANGUAGEFILES];
//get all the files in the language path
@ -23,10 +24,12 @@ int updateLanguageFiles() {
if ( !countfiles ) return -2;
//now from the files we got, get only the .lang files
for (int cnt = 0; cnt < countfiles; cnt++) {
for ( int cnt = 0; cnt < countfiles; cnt++ )
{
char filename[64];
strlcpy( filename, GetFileName( cnt ), sizeof( filename ) );
if (strcasestr(filename,".lang")) {
if ( strcasestr( filename, ".lang" ) )
{
strcpy( languageFiles[cnt], filename );
}
}
@ -36,9 +39,11 @@ int updateLanguageFiles() {
//we assume that the network will already be init by another function
// ( that has gui eletents in it because this one doesn't)
int done = 0, j = 0;
if (IsNetworkInit()) {
if ( IsNetworkInit() )
{
//build the URL, save path, and download each file and save it
while (j<countfiles) {
while ( j < countfiles )
{
char savepath[150];
char codeurl[200];
snprintf( codeurl, sizeof( codeurl ), "http://usbloader-gui.googlecode.com/svn/trunk/Languages/%s", languageFiles[j] );
@ -46,10 +51,12 @@ int updateLanguageFiles() {
struct block file = downloadfile( codeurl );
if (file.data != NULL) {
if ( file.data != NULL )
{
FILE * pfile;
pfile = fopen( savepath, "wb" );
if(pfile != NULL) {
if ( pfile != NULL )
{
fwrite( file.data, 1, file.size, pfile );
fclose( pfile );
free( file.data );

View File

@ -4,7 +4,8 @@
#include <gctypes.h>
#include "gettext.h"
typedef struct _MSG {
typedef struct _MSG
{
u32 id;
char* msgstr;
struct _MSG *next;
@ -18,17 +19,20 @@ static MSG *baseMSG=0;
[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
1986, 1987 Bell Telephone Laboratories, Inc.] */
static inline u32
hash_string (const char *str_param) {
hash_string ( const char *str_param )
{
u32 hval, g;
const char *str = str_param;
/* Compute the hash value for the given string. */
hval = 0;
while (*str != '\0') {
while ( *str != '\0' )
{
hval <<= 4;
hval += ( u8 ) * str++;
g = hval & ( ( u32 ) 0xf << ( HASHWORDBITS - 4 ) );
if (g != 0) {
if ( g != 0 )
{
hval ^= g >> ( HASHWORDBITS - 8 );
hval ^= g;
}
@ -38,7 +42,8 @@ hash_string (const char *str_param) {
/* Expand some escape sequences found in the argument string. */
static char *
expand_escape (const char *str) {
expand_escape ( const char *str )
{
char *retval, *rp;
const char *cp = str;
@ -50,10 +55,12 @@ expand_escape (const char *str) {
*rp++ = *cp++;
if ( cp[0] == '\0' )
goto terminate;
do {
do
{
/* Here cp[0] == '\\'. */
switch (*++cp) {
switch ( *++cp )
{
case '\"': /* " */
*rp++ = '\"';
++cp;
@ -97,14 +104,17 @@ expand_escape (const char *str) {
case '4':
case '5':
case '6':
case '7': {
case '7':
{
int ch = *cp++ - '0';
if (*cp >= '0' && *cp <= '7') {
if ( *cp >= '0' && *cp <= '7' )
{
ch *= 8;
ch += *cp++ - '0';
if (*cp >= '0' && *cp <= '7') {
if ( *cp >= '0' && *cp <= '7' )
{
ch *= 8;
ch += *cp++ - '0';
}
@ -119,7 +129,8 @@ expand_escape (const char *str) {
while ( cp[0] != '\0' && cp[0] != '\\' )
*rp++ = *cp++;
} while (cp[0] != '\0');
}
while ( cp[0] != '\0' );
/* Terminate string. */
terminate:
@ -127,27 +138,33 @@ terminate:
return retval;
}
static MSG *findMSG(u32 id) {
static MSG *findMSG( u32 id )
{
MSG *msg;
for (msg=baseMSG; msg; msg=msg->next) {
for ( msg = baseMSG; msg; msg = msg->next )
{
if ( msg->id == id )
return msg;
}
return NULL;
}
static MSG *setMSG(const char *msgid, const char *msgstr) {
static MSG *setMSG( const char *msgid, const char *msgstr )
{
u32 id = hash_string( msgid );
MSG *msg = findMSG( id );
if (!msg) {
if ( !msg )
{
msg = ( MSG * )malloc( sizeof( MSG ) );
msg->id = id;
msg->msgstr = NULL;
msg->next = baseMSG;
baseMSG = msg;
}
if (msg) {
if (msgstr) {
if ( msg )
{
if ( msgstr )
{
if ( msg->msgstr ) free( msg->msgstr );
//msg->msgstr = strdup(msgstr);
msg->msgstr = expand_escape( msgstr );
@ -156,8 +173,10 @@ static MSG *setMSG(const char *msgid, const char *msgstr) {
}
return NULL;
}
void gettextCleanUp(void) {
while (baseMSG) {
void gettextCleanUp( void )
{
while ( baseMSG )
{
MSG *nextMsg = baseMSG->next;
free( baseMSG->msgstr );
free( baseMSG );
@ -166,7 +185,8 @@ void gettextCleanUp(void) {
}
bool gettextLoadLanguage(const char* langFile) {
bool gettextLoadLanguage( const char* langFile )
{
FILE *f;
char line[200];
char *lastID = NULL;
@ -176,23 +196,29 @@ bool gettextLoadLanguage(const char* langFile) {
if ( !f )
return false;
while (fgets(line, sizeof(line), f)) {
while ( fgets( line, sizeof( line ), f ) )
{
// lines starting with # are comments
if ( line[0] == '#' )
continue;
else if (strncmp(line, "msgid \"", 7) == 0) {
else if ( strncmp( line, "msgid \"", 7 ) == 0 )
{
char *msgid, *end;
if (lastID) {
if ( lastID )
{
free( lastID );
lastID = NULL;
}
msgid = &line[7];
end = strrchr( msgid, '"' );
if (end && end-msgid>1) {
if ( end && end - msgid > 1 )
{
*end = 0;
lastID = strdup( msgid );
}
} else if (strncmp(line, "msgstr \"", 8) == 0) {
}
else if ( strncmp( line, "msgstr \"", 8 ) == 0 )
{
char *msgstr, *end;
if ( lastID == NULL )
@ -200,7 +226,8 @@ bool gettextLoadLanguage(const char* langFile) {
msgstr = &line[8];
end = strrchr( msgstr, '"' );
if (end && end-msgstr>1) {
if ( end && end - msgstr > 1 )
{
*end = 0;
setMSG( lastID, msgstr );
}
@ -213,7 +240,8 @@ bool gettextLoadLanguage(const char* langFile) {
fclose( f );
return true;
}
const char *gettext(const char *msgid) {
const char *gettext( const char *msgid )
{
MSG *msg = findMSG( hash_string( msgid ) );
if ( msg && msg->msgstr ) return msg->msgstr;
return msgid;

View File

@ -2,7 +2,8 @@
#define _GETTEXT_H_
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif

View File

@ -34,20 +34,24 @@
/*-----------------------------------------------------------------
Functions to deal with little endian values stored in uint8_t arrays
-----------------------------------------------------------------*/
static inline uint16_t u8array_to_u16 (const uint8_t* item, int offset) {
static inline uint16_t u8array_to_u16 ( const uint8_t* item, int offset )
{
return ( item[offset] | ( item[offset + 1] << 8 ) );
}
static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) {
static inline uint32_t u8array_to_u32 ( const uint8_t* item, int offset )
{
return ( item[offset] | ( item[offset + 1] << 8 ) | ( item[offset + 2] << 16 ) | ( item[offset + 3] << 24 ) );
}
static inline void u16_to_u8array (uint8_t* item, int offset, uint16_t value) {
static inline void u16_to_u8array ( uint8_t* item, int offset, uint16_t value )
{
item[offset] = ( uint8_t ) value;
item[offset + 1] = ( uint8_t )( value >> 8 );
}
static inline void u32_to_u8array (uint8_t* item, int offset, uint32_t value) {
static inline void u32_to_u8array ( uint8_t* item, int offset, uint32_t value )
{
item[offset] = ( uint8_t ) value;
item[offset + 1] = ( uint8_t )( value >> 8 );
item[offset + 2] = ( uint8_t )( value >> 16 );

View File

@ -42,7 +42,8 @@
#define PAGE_SECTORS 64
#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS)
typedef struct {
typedef struct
{
sec_t sector;
unsigned int count;
unsigned int last_access;
@ -50,7 +51,8 @@ typedef struct {
uint8_t* cache;
} CACHE_ENTRY;
typedef struct {
typedef struct
{
const DISC_INTERFACE* disc;
sec_t endOfPartition;
unsigned int numberOfPages;
@ -99,14 +101,16 @@ bool _FAT_cache_readSectors (CACHE* cache, sec_t sector, sec_t numSectors, void*
/*
Read a full sector from the cache
*/
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
static inline bool _FAT_cache_readSector ( CACHE* cache, void* buffer, sec_t sector )
{
return _FAT_cache_readPartialSector ( cache, buffer, sector, 0, BYTES_PER_READ );
}
/*
Write a full sector to the cache
*/
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
static inline bool _FAT_cache_writeSector ( CACHE* cache, const void* buffer, sec_t sector )
{
return _FAT_cache_writePartialSector ( cache, buffer, sector, 0, BYTES_PER_READ );
}

File diff suppressed because it is too large Load Diff

View File

@ -59,13 +59,15 @@
typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE;
typedef struct {
typedef struct
{
uint32_t cluster;
sec_t sector;
int32_t offset;
} DIR_ENTRY_POSITION;
typedef struct {
typedef struct
{
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
DIR_ENTRY_POSITION dataStart; // Points to the start of the LFN entries of a file, or the alias for no LFN
DIR_ENTRY_POSITION dataEnd; // Always points to the file/directory's alias entry
@ -73,7 +75,8 @@ typedef struct {
} DIR_ENTRY;
// Directory entry offsets
enum DIR_ENTRY_offset {
enum DIR_ENTRY_offset
{
DIR_ENTRY_name = 0x00,
DIR_ENTRY_extension = 0x08,
DIR_ENTRY_attributes = 0x0B,
@ -92,15 +95,18 @@ enum DIR_ENTRY_offset {
/*
Returns true if the file specified by entry is a directory
*/
static inline bool _FAT_directory_isDirectory (DIR_ENTRY* entry) {
static inline bool _FAT_directory_isDirectory ( DIR_ENTRY* entry )
{
return ( ( entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR ) != 0 );
}
static inline bool _FAT_directory_isWritable (DIR_ENTRY* entry) {
static inline bool _FAT_directory_isWritable ( DIR_ENTRY* entry )
{
return ( ( entry->entryData[DIR_ENTRY_attributes] & ATTRIB_RO ) == 0 );
}
static inline bool _FAT_directory_isDot (DIR_ENTRY* entry) {
static inline bool _FAT_directory_isDot ( DIR_ENTRY* entry )
{
return ( ( entry->filename[0] == '.' ) && ( ( entry->filename[1] == '\0' ) ||
( ( entry->filename[1] == '.' ) && entry->filename[2] == '\0' ) ) );
}

View File

@ -35,7 +35,8 @@
A list of all default devices to try at startup,
terminated by a {NULL,NULL} entry.
*/
typedef struct {
typedef struct
{
const char* name;
const DISC_INTERFACE* ( *getInterface )( void );
} INTERFACE_ID;
@ -45,7 +46,8 @@ extern const INTERFACE_ID _FAT_disc_interfaces[];
Check if a disc is inserted
Return true if a disc is inserted and ready, false otherwise
*/
static inline bool _FAT_disc_isInserted (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_isInserted ( const DISC_INTERFACE* disc )
{
return disc->isInserted();
}
@ -56,7 +58,8 @@ else it is at least 1
sector is 0 or greater
buffer is a pointer to the memory to fill
*/
static inline bool _FAT_disc_readSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, void* buffer) {
static inline bool _FAT_disc_readSectors ( const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, void* buffer )
{
return disc->readSectors ( sector, numSectors, buffer );
}
@ -67,21 +70,24 @@ else it is at least 1
sector is 0 or greater
buffer is a pointer to the memory to read from
*/
static inline bool _FAT_disc_writeSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, const void* buffer) {
static inline bool _FAT_disc_writeSectors ( const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, const void* buffer )
{
return disc->writeSectors ( sector, numSectors, buffer );
}
/*
Reset the card back to a ready state
*/
static inline bool _FAT_disc_clearStatus (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_clearStatus ( const DISC_INTERFACE* disc )
{
return disc->clearStatus();
}
/*
Initialise the disc to a state ready for data reading or writing
*/
static inline bool _FAT_disc_startup (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_startup ( const DISC_INTERFACE* disc )
{
return disc->startup();
}
@ -89,21 +95,24 @@ static inline bool _FAT_disc_startup (const DISC_INTERFACE* disc) {
Put the disc in a state ready for power down.
Complete any pending writes and disable the disc if necessary
*/
static inline bool _FAT_disc_shutdown (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_shutdown ( const DISC_INTERFACE* disc )
{
return disc->shutdown();
}
/*
Return a 32 bit value unique to each type of interface
*/
static inline uint32_t _FAT_disc_hostType (const DISC_INTERFACE* disc) {
static inline uint32_t _FAT_disc_hostType ( const DISC_INTERFACE* disc )
{
return disc->ioType;
}
/*
Return a 32 bit value that specifies the capabilities of the disc
*/
static inline uint32_t _FAT_disc_features (const DISC_INTERFACE* disc) {
static inline uint32_t _FAT_disc_features ( const DISC_INTERFACE* disc )
{
return disc->features;
}

View File

@ -43,21 +43,26 @@ The list is terminated by a NULL/NULL entry.
#include "usbloader/usbstorage2.h"
#include <sdcard/gcsd.h>
static const DISC_INTERFACE* get_io_wiisd (void) {
static const DISC_INTERFACE* get_io_wiisd ( void )
{
return &__io_wiisd;
}
static const DISC_INTERFACE* get_io_usbstorage (void) {
static const DISC_INTERFACE* get_io_usbstorage ( void )
{
return &__io_usbstorage2;
}
static const DISC_INTERFACE* get_io_gcsda (void) {
static const DISC_INTERFACE* get_io_gcsda ( void )
{
return &__io_gcsda;
}
static const DISC_INTERFACE* get_io_gcsdb (void) {
static const DISC_INTERFACE* get_io_gcsdb ( void )
{
return &__io_gcsdb;
}
const INTERFACE_ID _FAT_disc_interfaces[] = {
const INTERFACE_ID _FAT_disc_interfaces[] =
{
{"sd", get_io_wiisd},
{"usb", get_io_usbstorage},
{"carda", get_io_gcsda},

View File

@ -35,7 +35,8 @@
A list of all default devices to try at startup,
terminated by a {NULL,NULL} entry.
*/
typedef struct {
typedef struct
{
const char* name;
const DISC_INTERFACE* ( *getInterface )( void );
} INTERFACE_ID;
@ -45,7 +46,8 @@ extern const INTERFACE_ID _FAT_disc_interfaces[];
Check if a disc is inserted
Return true if a disc is inserted and ready, false otherwise
*/
static inline bool _FAT_disc_isInserted (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_isInserted ( const DISC_INTERFACE* disc )
{
return disc->isInserted();
}
@ -56,7 +58,8 @@ else it is at least 1
sector is 0 or greater
buffer is a pointer to the memory to fill
*/
static inline bool _FAT_disc_readSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, void* buffer) {
static inline bool _FAT_disc_readSectors ( const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, void* buffer )
{
return disc->readSectors ( sector, numSectors, buffer );
}
@ -67,21 +70,24 @@ else it is at least 1
sector is 0 or greater
buffer is a pointer to the memory to read from
*/
static inline bool _FAT_disc_writeSectors (const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, const void* buffer) {
static inline bool _FAT_disc_writeSectors ( const DISC_INTERFACE* disc, sec_t sector, sec_t numSectors, const void* buffer )
{
return disc->writeSectors ( sector, numSectors, buffer );
}
/*
Reset the card back to a ready state
*/
static inline bool _FAT_disc_clearStatus (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_clearStatus ( const DISC_INTERFACE* disc )
{
return disc->clearStatus();
}
/*
Initialise the disc to a state ready for data reading or writing
*/
static inline bool _FAT_disc_startup (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_startup ( const DISC_INTERFACE* disc )
{
return disc->startup();
}
@ -89,21 +95,24 @@ static inline bool _FAT_disc_startup (const DISC_INTERFACE* disc) {
Put the disc in a state ready for power down.
Complete any pending writes and disable the disc if necessary
*/
static inline bool _FAT_disc_shutdown (const DISC_INTERFACE* disc) {
static inline bool _FAT_disc_shutdown ( const DISC_INTERFACE* disc )
{
return disc->shutdown();
}
/*
Return a 32 bit value unique to each type of interface
*/
static inline uint32_t _FAT_disc_hostType (const DISC_INTERFACE* disc) {
static inline uint32_t _FAT_disc_hostType ( const DISC_INTERFACE* disc )
{
return disc->ioType;
}
/*
Return a 32 bit value that specifies the capabilities of the disc
*/
static inline uint32_t _FAT_disc_features (const DISC_INTERFACE* disc) {
static inline uint32_t _FAT_disc_features ( const DISC_INTERFACE* disc )
{
return disc->features;
}

View File

@ -31,7 +31,8 @@
#define _LIBFAT_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#include <stdint.h>

View File

@ -46,21 +46,25 @@
#define CACHE_FREE UINT_MAX
CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition) {
CACHE* _FAT_cache_constructor ( unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition )
{
CACHE* cache;
unsigned int i;
CACHE_ENTRY* cacheEntries;
if (numberOfPages < 2) {
if ( numberOfPages < 2 )
{
numberOfPages = 2;
}
if (sectorsPerPage < 8) {
if ( sectorsPerPage < 8 )
{
sectorsPerPage = 8;
}
cache = ( CACHE* ) _FAT_mem_allocate ( sizeof( CACHE ) );
if (cache == NULL) {
if ( cache == NULL )
{
return NULL;
}
@ -71,12 +75,14 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
cacheEntries = ( CACHE_ENTRY* ) _FAT_mem_allocate ( sizeof( CACHE_ENTRY ) * numberOfPages );
if (cacheEntries == NULL) {
if ( cacheEntries == NULL )
{
_FAT_mem_free ( cache );
return NULL;
}
for (i = 0; i < numberOfPages; i++) {
for ( i = 0; i < numberOfPages; i++ )
{
cacheEntries[i].sector = CACHE_FREE;
cacheEntries[i].count = 0;
cacheEntries[i].last_access = 0;
@ -89,13 +95,15 @@ CACHE* _FAT_cache_constructor (unsigned int numberOfPages, unsigned int sectorsP
return cache;
}
void _FAT_cache_destructor (CACHE* cache) {
void _FAT_cache_destructor ( CACHE* cache )
{
unsigned int i;
// Clear out cache before destroying it
_FAT_cache_flush( cache );
// Free memory in reverse allocation order
for (i = 0; i < cache->numberOfPages; i++) {
for ( i = 0; i < cache->numberOfPages; i++ )
{
_FAT_mem_free ( cache->cacheEntries[i].cache );
}
_FAT_mem_free ( cache->cacheEntries );
@ -105,7 +113,8 @@ void _FAT_cache_destructor (CACHE* cache) {
static u32 accessCounter = 0;
static u32 accessTime(){
static u32 accessTime()
{
accessCounter++;
return accessCounter;
}
@ -122,20 +131,24 @@ static CACHE_ENTRY* _FAT_cache_getPage(CACHE *cache,sec_t sector)
unsigned int oldUsed = 0;
unsigned int oldAccess = UINT_MAX;
for(i=0;i<numberOfPages;i++) {
if(sector>=cacheEntries[i].sector && sector<(cacheEntries[i].sector + cacheEntries[i].count)) {
for ( i = 0; i < numberOfPages; i++ )
{
if ( sector >= cacheEntries[i].sector && sector < ( cacheEntries[i].sector + cacheEntries[i].count ) )
{
cacheEntries[i].last_access = accessTime();
return &( cacheEntries[i] );
}
if(foundFree==false && (cacheEntries[i].sector==CACHE_FREE || cacheEntries[i].last_access<oldAccess)) {
if ( foundFree == false && ( cacheEntries[i].sector == CACHE_FREE || cacheEntries[i].last_access < oldAccess ) )
{
if ( cacheEntries[i].sector == CACHE_FREE ) foundFree = true;
oldUsed = i;
oldAccess = cacheEntries[i].last_access;
}
}
if(foundFree==false && cacheEntries[oldUsed].dirty==true) {
if ( foundFree == false && cacheEntries[oldUsed].dirty == true )
{
if ( !_FAT_disc_writeSectors( cache->disc, cacheEntries[oldUsed].sector, cacheEntries[oldUsed].count, cacheEntries[oldUsed].cache ) ) return NULL;
cacheEntries[oldUsed].dirty = false;
}
@ -160,7 +173,8 @@ bool _FAT_cache_readSectors(CACHE *cache,sec_t sector,sec_t numSectors,void *buf
CACHE_ENTRY *entry;
uint8_t *dest = buffer;
while(numSectors>0) {
while ( numSectors > 0 )
{
entry = _FAT_cache_getPage( cache, sector );
if ( entry == NULL ) return false;
@ -197,11 +211,13 @@ bool _FAT_cache_readPartialSector (CACHE* cache, void* buffer, sec_t sector, uns
return true;
}
bool _FAT_cache_readLittleEndianValue (CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes) {
bool _FAT_cache_readLittleEndianValue ( CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes )
{
uint8_t buf[4];
if ( !_FAT_cache_readPartialSector( cache, buf, sector, offset, num_bytes ) ) return false;
switch(num_bytes) {
switch ( num_bytes )
{
case 1: *value = buf[0]; break;
case 2: *value = u8array_to_u16( buf, 0 ); break;
case 4: *value = u8array_to_u32( buf, 0 ); break;
@ -230,10 +246,12 @@ bool _FAT_cache_writePartialSector (CACHE* cache, const void* buffer, sec_t sect
return true;
}
bool _FAT_cache_writeLittleEndianValue (CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int size) {
bool _FAT_cache_writeLittleEndianValue ( CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int size )
{
uint8_t buf[4] = {0, 0, 0, 0};
switch(size) {
switch ( size )
{
case 1: buf[0] = value; break;
case 2: u16_to_u8array( buf, 0, value ); break;
case 4: u32_to_u8array( buf, 0, value ); break;
@ -265,7 +283,8 @@ bool _FAT_cache_eraseWritePartialSector (CACHE* cache, const void* buffer, sec_t
}
static CACHE_ENTRY* _FAT_cache_findPage(CACHE *cache, sec_t sector, sec_t count) {
static CACHE_ENTRY* _FAT_cache_findPage( CACHE *cache, sec_t sector, sec_t count )
{
unsigned int i;
CACHE_ENTRY* cacheEntries = cache->cacheEntries;
@ -273,16 +292,22 @@ static CACHE_ENTRY* _FAT_cache_findPage(CACHE *cache, sec_t sector, sec_t count)
CACHE_ENTRY *entry = NULL;
sec_t lowest = UINT_MAX;
for(i=0;i<numberOfPages;i++) {
if (cacheEntries[i].sector != CACHE_FREE) {
for ( i = 0; i < numberOfPages; i++ )
{
if ( cacheEntries[i].sector != CACHE_FREE )
{
bool intersect;
if (sector > cacheEntries[i].sector) {
if ( sector > cacheEntries[i].sector )
{
intersect = sector - cacheEntries[i].sector < cacheEntries[i].count;
} else {
}
else
{
intersect = cacheEntries[i].sector - sector < count;
}
if ( intersect && (cacheEntries[i].sector < lowest)) {
if ( intersect && ( cacheEntries[i].sector < lowest ) )
{
lowest = cacheEntries[i].sector;
entry = &cacheEntries[i];
}
@ -303,9 +328,11 @@ bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, cons
{
entry = _FAT_cache_findPage( cache, sector, numSectors );
if(entry!=NULL) {
if ( entry != NULL )
{
if ( entry->sector > sector) {
if ( entry->sector > sector )
{
secs_to_write = entry->sector - sector;
@ -328,7 +355,9 @@ bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, cons
entry->dirty = true;
} else {
}
else
{
_FAT_disc_writeSectors( cache->disc, sector, numSectors, src );
numSectors = 0;
}
@ -339,12 +368,16 @@ bool _FAT_cache_writeSectors (CACHE* cache, sec_t sector, sec_t numSectors, cons
/*
Flushes all dirty pages to disc, clearing the dirty flag.
*/
bool _FAT_cache_flush (CACHE* cache) {
bool _FAT_cache_flush ( CACHE* cache )
{
unsigned int i;
for (i = 0; i < cache->numberOfPages; i++) {
if (cache->cacheEntries[i].dirty) {
if (!_FAT_disc_writeSectors (cache->disc, cache->cacheEntries[i].sector, cache->cacheEntries[i].count, cache->cacheEntries[i].cache)) {
for ( i = 0; i < cache->numberOfPages; i++ )
{
if ( cache->cacheEntries[i].dirty )
{
if ( !_FAT_disc_writeSectors ( cache->disc, cache->cacheEntries[i].sector, cache->cacheEntries[i].count, cache->cacheEntries[i].cache ) )
{
return false;
}
}
@ -354,10 +387,12 @@ bool _FAT_cache_flush (CACHE* cache) {
return true;
}
void _FAT_cache_invalidate (CACHE* cache) {
void _FAT_cache_invalidate ( CACHE* cache )
{
unsigned int i;
_FAT_cache_flush( cache );
for (i = 0; i < cache->numberOfPages; i++) {
for ( i = 0; i < cache->numberOfPages; i++ )
{
cache->cacheEntries[i].sector = CACHE_FREE;
cache->cacheEntries[i].last_access = 0;
cache->cacheEntries[i].count = 0;

View File

@ -42,7 +42,8 @@
#define PAGE_SECTORS 64
#define CACHE_PAGE_SIZE (BYTES_PER_READ * PAGE_SECTORS)
typedef struct {
typedef struct
{
sec_t sector;
unsigned int count;
unsigned int last_access;
@ -50,7 +51,8 @@ typedef struct {
uint8_t* cache;
} CACHE_ENTRY;
typedef struct {
typedef struct
{
const DISC_INTERFACE* disc;
sec_t endOfPartition;
unsigned int numberOfPages;
@ -99,14 +101,16 @@ bool _FAT_cache_readSectors (CACHE* cache, sec_t sector, sec_t numSectors, void*
/*
Read a full sector from the cache
*/
static inline bool _FAT_cache_readSector (CACHE* cache, void* buffer, sec_t sector) {
static inline bool _FAT_cache_readSector ( CACHE* cache, void* buffer, sec_t sector )
{
return _FAT_cache_readPartialSector ( cache, buffer, sector, 0, BYTES_PER_READ );
}
/*
Write a full sector to the cache
*/
static inline bool _FAT_cache_writeSector (CACHE* cache, const void* buffer, sec_t sector) {
static inline bool _FAT_cache_writeSector ( CACHE* cache, const void* buffer, sec_t sector )
{
return _FAT_cache_writePartialSector ( cache, buffer, sector, 0, BYTES_PER_READ );
}

View File

@ -45,22 +45,26 @@
#include "lock.h"
int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
int _FAT_stat_r ( struct _reent *r, const char *path, struct stat *st )
{
PARTITION* partition = NULL;
DIR_ENTRY dirEntry;
// Get the partition this file is on
partition = _FAT_partition_getPartitionFromPath ( path );
if (partition == NULL) {
if ( partition == NULL )
{
r->_errno = ENODEV;
return -1;
}
// Move the path pointer to the start of the actual path
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
path = strchr ( path, ':' ) + 1;
}
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
r->_errno = EINVAL;
return -1;
}
@ -68,7 +72,8 @@ int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
_FAT_lock( &partition->lock );
// Search for the file on the disc
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) {
if ( !_FAT_directory_entryFromPath ( partition, &dirEntry, path, NULL ) )
{
_FAT_unlock( &partition->lock );
r->_errno = ENOENT;
return -1;
@ -81,12 +86,14 @@ int _FAT_stat_r (struct _reent *r, const char *path, struct stat *st) {
return 0;
}
int _FAT_link_r (struct _reent *r, const char *existing, const char *newLink) {
int _FAT_link_r ( struct _reent *r, const char *existing, const char *newLink )
{
r->_errno = ENOTSUP;
return -1;
}
int _FAT_unlink_r (struct _reent *r, const char *path) {
int _FAT_unlink_r ( struct _reent *r, const char *path )
{
PARTITION* partition = NULL;
DIR_ENTRY dirEntry;
DIR_ENTRY dirContents;
@ -96,22 +103,26 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
// Get the partition this directory is on
partition = _FAT_partition_getPartitionFromPath ( path );
if (partition == NULL) {
if ( partition == NULL )
{
r->_errno = ENODEV;
return -1;
}
// Make sure we aren't trying to write to a read-only disc
if (partition->readOnly) {
if ( partition->readOnly )
{
r->_errno = EROFS;
return -1;
}
// Move the path pointer to the start of the actual path
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
path = strchr ( path, ':' ) + 1;
}
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
r->_errno = EINVAL;
return -1;
}
@ -119,7 +130,8 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
_FAT_lock( &partition->lock );
// Search for the file on the disc
if (!_FAT_directory_entryFromPath (partition, &dirEntry, path, NULL)) {
if ( !_FAT_directory_entryFromPath ( partition, &dirEntry, path, NULL ) )
{
_FAT_unlock( &partition->lock );
r->_errno = ENOENT;
return -1;
@ -129,11 +141,14 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
// If this is a directory, make sure it is empty
if (_FAT_directory_isDirectory (&dirEntry)) {
if ( _FAT_directory_isDirectory ( &dirEntry ) )
{
nextEntry = _FAT_directory_getFirstEntry ( partition, &dirContents, cluster );
while (nextEntry) {
if (!_FAT_directory_isDot (&dirContents)) {
while ( nextEntry )
{
if ( !_FAT_directory_isDot ( &dirContents ) )
{
// The directory had something in it that isn't a reference to itself or it's parent
_FAT_unlock( &partition->lock );
r->_errno = EPERM;
@ -143,49 +158,60 @@ int _FAT_unlink_r (struct _reent *r, const char *path) {
}
}
if (_FAT_fat_isValidCluster(partition, cluster)) {
if ( _FAT_fat_isValidCluster( partition, cluster ) )
{
// Remove the cluster chain for this file
if (!_FAT_fat_clearLinks (partition, cluster)) {
if ( !_FAT_fat_clearLinks ( partition, cluster ) )
{
r->_errno = EIO;
errorOccured = true;
}
}
// Remove the directory entry for this file
if (!_FAT_directory_removeEntry (partition, &dirEntry)) {
if ( !_FAT_directory_removeEntry ( partition, &dirEntry ) )
{
r->_errno = EIO;
errorOccured = true;
}
// Flush any sectors in the disc cache
if (!_FAT_cache_flush(partition->cache)) {
if ( !_FAT_cache_flush( partition->cache ) )
{
r->_errno = EIO;
errorOccured = true;
}
_FAT_unlock( &partition->lock );
if (errorOccured) {
if ( errorOccured )
{
return -1;
} else {
}
else
{
return 0;
}
}
int _FAT_chdir_r (struct _reent *r, const char *path) {
int _FAT_chdir_r ( struct _reent *r, const char *path )
{
PARTITION* partition = NULL;
// Get the partition this directory is on
partition = _FAT_partition_getPartitionFromPath ( path );
if (partition == NULL) {
if ( partition == NULL )
{
r->_errno = ENODEV;
return -1;
}
// Move the path pointer to the start of the actual path
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
path = strchr ( path, ':' ) + 1;
}
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
r->_errno = EINVAL;
return -1;
}
@ -193,11 +219,14 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
_FAT_lock( &partition->lock );
// Try changing directory
if (_FAT_directory_chdir (partition, path)) {
if ( _FAT_directory_chdir ( partition, path ) )
{
// Successful
_FAT_unlock( &partition->lock );
return 0;
} else {
}
else
{
// Failed
_FAT_unlock( &partition->lock );
r->_errno = ENOTDIR;
@ -205,7 +234,8 @@ int _FAT_chdir_r (struct _reent *r, const char *path) {
}
}
int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
int _FAT_rename_r ( struct _reent *r, const char *oldName, const char *newName )
{
PARTITION* partition = NULL;
DIR_ENTRY oldDirEntry;
DIR_ENTRY newDirEntry;
@ -214,7 +244,8 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
// Get the partition this directory is on
partition = _FAT_partition_getPartitionFromPath ( oldName );
if (partition == NULL) {
if ( partition == NULL )
{
r->_errno = ENODEV;
return -1;
}
@ -222,46 +253,54 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
_FAT_lock( &partition->lock );
// Make sure the same partition is used for the old and new names
if (partition != _FAT_partition_getPartitionFromPath (newName)) {
if ( partition != _FAT_partition_getPartitionFromPath ( newName ) )
{
_FAT_unlock( &partition->lock );
r->_errno = EXDEV;
return -1;
}
// Make sure we aren't trying to write to a read-only disc
if (partition->readOnly) {
if ( partition->readOnly )
{
_FAT_unlock( &partition->lock );
r->_errno = EROFS;
return -1;
}
// Move the path pointer to the start of the actual path
if (strchr (oldName, ':') != NULL) {
if ( strchr ( oldName, ':' ) != NULL )
{
oldName = strchr ( oldName, ':' ) + 1;
}
if (strchr (oldName, ':') != NULL) {
if ( strchr ( oldName, ':' ) != NULL )
{
_FAT_unlock( &partition->lock );
r->_errno = EINVAL;
return -1;
}
if (strchr (newName, ':') != NULL) {
if ( strchr ( newName, ':' ) != NULL )
{
newName = strchr ( newName, ':' ) + 1;
}
if (strchr (newName, ':') != NULL) {
if ( strchr ( newName, ':' ) != NULL )
{
_FAT_unlock( &partition->lock );
r->_errno = EINVAL;
return -1;
}
// Search for the file on the disc
if (!_FAT_directory_entryFromPath (partition, &oldDirEntry, oldName, NULL)) {
if ( !_FAT_directory_entryFromPath ( partition, &oldDirEntry, oldName, NULL ) )
{
_FAT_unlock( &partition->lock );
r->_errno = ENOENT;
return -1;
}
// Make sure there is no existing file / directory with the new name
if (_FAT_directory_entryFromPath (partition, &newDirEntry, newName, NULL)) {
if ( _FAT_directory_entryFromPath ( partition, &newDirEntry, newName, NULL ) )
{
_FAT_unlock( &partition->lock );
r->_errno = EEXIST;
return -1;
@ -270,15 +309,19 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
// Create the new file entry
// Get the directory it has to go in
pathEnd = strrchr ( newName, DIR_SEPARATOR );
if (pathEnd == NULL) {
if ( pathEnd == NULL )
{
// No path was specified
dirCluster = partition->cwdCluster;
pathEnd = newName;
} else {
}
else
{
// Path was specified -- get the right dirCluster
// Recycling newDirEntry, since it needs to be recreated anyway
if ( !_FAT_directory_entryFromPath ( partition, &newDirEntry, newName, pathEnd ) ||
!_FAT_directory_isDirectory(&newDirEntry)) {
!_FAT_directory_isDirectory( &newDirEntry ) )
{
_FAT_unlock( &partition->lock );
r->_errno = ENOTDIR;
return -1;
@ -295,21 +338,24 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
strncpy ( newDirEntry.filename, pathEnd, MAX_FILENAME_LENGTH - 1 );
// Write the new entry
if (!_FAT_directory_addEntry (partition, &newDirEntry, dirCluster)) {
if ( !_FAT_directory_addEntry ( partition, &newDirEntry, dirCluster ) )
{
_FAT_unlock( &partition->lock );
r->_errno = ENOSPC;
return -1;
}
// Remove the old entry
if (!_FAT_directory_removeEntry (partition, &oldDirEntry)) {
if ( !_FAT_directory_removeEntry ( partition, &oldDirEntry ) )
{
_FAT_unlock( &partition->lock );
r->_errno = EIO;
return -1;
}
// Flush any sectors in the disc cache
if (!_FAT_cache_flush (partition->cache)) {
if ( !_FAT_cache_flush ( partition->cache ) )
{
_FAT_unlock( &partition->lock );
r->_errno = EIO;
return -1;
@ -319,7 +365,8 @@ int _FAT_rename_r (struct _reent *r, const char *oldName, const char *newName) {
return 0;
}
int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
int _FAT_mkdir_r ( struct _reent *r, const char *path, int mode )
{
PARTITION* partition = NULL;
bool fileExists;
DIR_ENTRY dirEntry;
@ -328,16 +375,19 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
uint8_t newEntryData[DIR_ENTRY_DATA_SIZE];
partition = _FAT_partition_getPartitionFromPath ( path );
if (partition == NULL) {
if ( partition == NULL )
{
r->_errno = ENODEV;
return -1;
}
// Move the path pointer to the start of the actual path
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
path = strchr ( path, ':' ) + 1;
}
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
r->_errno = EINVAL;
return -1;
}
@ -348,13 +398,15 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
fileExists = _FAT_directory_entryFromPath ( partition, &dirEntry, path, NULL );
// Make sure it doesn't exist
if (fileExists) {
if ( fileExists )
{
_FAT_unlock( &partition->lock );
r->_errno = EEXIST;
return -1;
}
if (partition->readOnly) {
if ( partition->readOnly )
{
// We can't write to a read-only partition
_FAT_unlock( &partition->lock );
r->_errno = EROFS;
@ -363,15 +415,19 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
// Get the directory it has to go in
pathEnd = strrchr ( path, DIR_SEPARATOR );
if (pathEnd == NULL) {
if ( pathEnd == NULL )
{
// No path was specified
parentCluster = partition->cwdCluster;
pathEnd = path;
} else {
}
else
{
// Path was specified -- get the right parentCluster
// Recycling dirEntry, since it needs to be recreated anyway
if ( !_FAT_directory_entryFromPath ( partition, &dirEntry, path, pathEnd ) ||
!_FAT_directory_isDirectory(&dirEntry)) {
!_FAT_directory_isDirectory( &dirEntry ) )
{
_FAT_unlock( &partition->lock );
r->_errno = ENOTDIR;
return -1;
@ -397,7 +453,8 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
// Get a cluster for the new directory
dirCluster = _FAT_fat_linkFreeClusterCleared ( partition, CLUSTER_FREE );
if (!_FAT_fat_isValidCluster(partition, dirCluster)) {
if ( !_FAT_fat_isValidCluster( partition, dirCluster ) )
{
// No space left on disc for the cluster
_FAT_unlock( &partition->lock );
r->_errno = ENOSPC;
@ -407,7 +464,8 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
u16_to_u8array ( dirEntry.entryData, DIR_ENTRY_clusterHigh, dirCluster >> 16 );
// Write the new directory's entry to it's parent
if (!_FAT_directory_addEntry (partition, &dirEntry, parentCluster)) {
if ( !_FAT_directory_addEntry ( partition, &dirEntry, parentCluster ) )
{
_FAT_unlock( &partition->lock );
r->_errno = ENOSPC;
return -1;
@ -441,7 +499,8 @@ int _FAT_mkdir_r (struct _reent *r, const char *path, int mode) {
_FAT_fat_clusterToSector ( partition, dirCluster ), DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
// Flush any sectors in the disc cache
if (!_FAT_cache_flush(partition->cache)) {
if ( !_FAT_cache_flush( partition->cache ) )
{
_FAT_unlock( &partition->lock );
r->_errno = EIO;
return -1;
@ -458,7 +517,8 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
// Get the partition of the requested path
partition = _FAT_partition_getPartitionFromPath ( path );
if (partition == NULL) {
if ( partition == NULL )
{
r->_errno = ENODEV;
return -1;
}
@ -493,22 +553,26 @@ int _FAT_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
return 0;
}
DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path) {
DIR_ITER* _FAT_diropen_r( struct _reent *r, DIR_ITER *dirState, const char *path )
{
DIR_ENTRY dirEntry;
DIR_STATE_STRUCT* state = ( DIR_STATE_STRUCT* ) ( dirState->dirStruct );
bool fileExists;
state->partition = _FAT_partition_getPartitionFromPath ( path );
if (state->partition == NULL) {
if ( state->partition == NULL )
{
r->_errno = ENODEV;
return NULL;
}
// Move the path pointer to the start of the actual path
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
path = strchr ( path, ':' ) + 1;
}
if (strchr (path, ':') != NULL) {
if ( strchr ( path, ':' ) != NULL )
{
r->_errno = EINVAL;
return NULL;
}
@ -518,14 +582,16 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path)
// Get the start cluster of the directory
fileExists = _FAT_directory_entryFromPath ( state->partition, &dirEntry, path, NULL );
if (!fileExists) {
if ( !fileExists )
{
_FAT_unlock( &state->partition->lock );
r->_errno = ENOENT;
return NULL;
}
// Make sure it is a directory
if (! _FAT_directory_isDirectory (&dirEntry)) {
if ( ! _FAT_directory_isDirectory ( &dirEntry ) )
{
_FAT_unlock( &state->partition->lock );
r->_errno = ENOTDIR;
return NULL;
@ -544,13 +610,15 @@ DIR_ITER* _FAT_diropen_r(struct _reent *r, DIR_ITER *dirState, const char *path)
return ( DIR_ITER* ) state;
}
int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) {
int _FAT_dirreset_r ( struct _reent *r, DIR_ITER *dirState )
{
DIR_STATE_STRUCT* state = ( DIR_STATE_STRUCT* ) ( dirState->dirStruct );
_FAT_lock( &state->partition->lock );
// Make sure we are still using this entry
if (!state->inUse) {
if ( !state->inUse )
{
_FAT_unlock( &state->partition->lock );
r->_errno = EBADF;
return -1;
@ -564,20 +632,23 @@ int _FAT_dirreset_r (struct _reent *r, DIR_ITER *dirState) {
return 0;
}
int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat) {
int _FAT_dirnext_r ( struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat )
{
DIR_STATE_STRUCT* state = ( DIR_STATE_STRUCT* ) ( dirState->dirStruct );
_FAT_lock( &state->partition->lock );
// Make sure we are still using this entry
if (!state->inUse) {
if ( !state->inUse )
{
_FAT_unlock( &state->partition->lock );
r->_errno = EBADF;
return -1;
}
// Make sure there is another file to report on
if (! state->validEntry) {
if ( ! state->validEntry )
{
_FAT_unlock( &state->partition->lock );
r->_errno = ENOENT;
return -1;
@ -586,7 +657,8 @@ int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
// Get the filename
strncpy ( filename, state->currentEntry.filename, MAX_FILENAME_LENGTH );
// Get the stats, if requested
if (filestat != NULL) {
if ( filestat != NULL )
{
_FAT_directory_entryStat ( state->partition, &( state->currentEntry ), filestat );
}
@ -598,7 +670,8 @@ int _FAT_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
return 0;
}
int _FAT_dirclose_r (struct _reent *r, DIR_ITER *dirState) {
int _FAT_dirclose_r ( struct _reent *r, DIR_ITER *dirState )
{
DIR_STATE_STRUCT* state = ( DIR_STATE_STRUCT* ) ( dirState->dirStruct );
// We are no longer using this entry

View File

@ -39,7 +39,8 @@
#include "common.h"
#include "directory.h"
typedef struct {
typedef struct
{
PARTITION* partition;
DIR_ENTRY currentEntry;
uint32_t startCluster;

File diff suppressed because it is too large Load Diff

View File

@ -41,7 +41,8 @@
#define FILE_MAX_SIZE ((uint32_t)0xFFFFFFFF) // 4GiB - 1B
typedef struct {
typedef struct
{
u32 cluster;
sec_t sector;
s32 byte;
@ -49,7 +50,8 @@ typedef struct {
struct _FILE_STRUCT;
struct _FILE_STRUCT {
struct _FILE_STRUCT
{
uint32_t filesize;
uint32_t startCluster;
uint32_t currentPosition;

View File

@ -41,7 +41,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
sec_t sector;
int offset;
if (cluster == CLUSTER_FREE) {
if ( cluster == CLUSTER_FREE )
{
return CLUSTER_FREE;
}
@ -62,7 +63,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
offset++;
if (offset >= BYTES_PER_READ) {
if ( offset >= BYTES_PER_READ )
{
offset = 0;
sector++;
}
@ -71,9 +73,12 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
_FAT_cache_readLittleEndianValue ( partition->cache, &nextCluster_h, sector, offset, sizeof( u8 ) );
nextCluster |= ( nextCluster_h << 8 );
if (cluster & 0x01) {
if ( cluster & 0x01 )
{
nextCluster = nextCluster >> 4;
} else {
}
else
{
nextCluster &= 0x0FFF;
}
@ -90,7 +95,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
_FAT_cache_readLittleEndianValue ( partition->cache, &nextCluster, sector, offset, sizeof( u16 ) );
if (nextCluster >= 0xFFF7) {
if ( nextCluster >= 0xFFF7 )
{
nextCluster = CLUSTER_EOF;
}
break;
@ -101,7 +107,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
_FAT_cache_readLittleEndianValue ( partition->cache, &nextCluster, sector, offset, sizeof( u32 ) );
if (nextCluster >= 0x0FFFFFF7) {
if ( nextCluster >= 0x0FFFFFF7 )
{
nextCluster = CLUSTER_EOF;
}
break;
@ -118,7 +125,8 @@ uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster)
writes value into the correct offset within a partition's FAT, based
on the cluster number.
*/
static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint32_t value) {
static bool _FAT_fat_writeFatEntry ( PARTITION* partition, uint32_t cluster, uint32_t value )
{
sec_t sector;
int offset;
uint32_t oldValue;
@ -138,7 +146,8 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
sector = partition->fat.fatStart + ( ( ( cluster * 3 ) / 2 ) / BYTES_PER_READ );
offset = ( ( cluster * 3 ) / 2 ) % BYTES_PER_READ;
if (cluster & 0x01) {
if ( cluster & 0x01 )
{
_FAT_cache_readLittleEndianValue ( partition->cache, &oldValue, sector, offset, sizeof( u8 ) );
@ -147,19 +156,23 @@ static bool _FAT_fat_writeFatEntry (PARTITION* partition, uint32_t cluster, uint
_FAT_cache_writeLittleEndianValue ( partition->cache, value & 0xFF, sector, offset, sizeof( u8 ) );
offset++;
if (offset >= BYTES_PER_READ) {
if ( offset >= BYTES_PER_READ )
{
offset = 0;
sector++;
}
_FAT_cache_writeLittleEndianValue ( partition->cache, ( value >> 8 ) & 0xFF, sector, offset, sizeof( u8 ) );
} else {
}
else
{
_FAT_cache_writeLittleEndianValue ( partition->cache, value, sector, offset, sizeof( u8 ) );
offset++;
if (offset >= BYTES_PER_READ) {
if ( offset >= BYTES_PER_READ )
{
offset = 0;
sector++;
}
@ -203,7 +216,8 @@ to end of file, links the input cluster to it then returns the
cluster number
If an error occurs, return CLUSTER_ERROR
-----------------------------------------------------------------*/
uint32_t _FAT_fat_linkFreeCluster(PARTITION* partition, uint32_t cluster) {
uint32_t _FAT_fat_linkFreeCluster( PARTITION* partition, uint32_t cluster )
{
uint32_t firstFree;
uint32_t curLink;
uint32_t lastCluster;
@ -211,32 +225,40 @@ uint32_t _FAT_fat_linkFreeCluster(PARTITION* partition, uint32_t cluster) {
lastCluster = partition->fat.lastCluster;
if (cluster > lastCluster) {
if ( cluster > lastCluster )
{
return CLUSTER_ERROR;
}
// Check if the cluster already has a link, and return it if so
curLink = _FAT_fat_nextCluster( partition, cluster );
if ((curLink >= CLUSTER_FIRST) && (curLink <= lastCluster)) {
if ( ( curLink >= CLUSTER_FIRST ) && ( curLink <= lastCluster ) )
{
return curLink; // Return the current link - don't allocate a new one
}
// Get a free cluster
firstFree = partition->fat.firstFree;
// Start at first valid cluster
if (firstFree < CLUSTER_FIRST) {
if ( firstFree < CLUSTER_FIRST )
{
firstFree = CLUSTER_FIRST;
}
// Search until a free cluster is found
while (_FAT_fat_nextCluster(partition, firstFree) != CLUSTER_FREE) {
while ( _FAT_fat_nextCluster( partition, firstFree ) != CLUSTER_FREE )
{
firstFree++;
if (firstFree > lastCluster) {
if (loopedAroundFAT) {
if ( firstFree > lastCluster )
{
if ( loopedAroundFAT )
{
// If couldn't get a free cluster then return an error
partition->fat.firstFree = firstFree;
return CLUSTER_ERROR;
} else {
}
else
{
// Try looping back to the beginning of the FAT
// This was suggested by loopy
firstFree = CLUSTER_FIRST;
@ -263,7 +285,8 @@ to end of file, links the input cluster to it, clears the new
cluster to 0 valued bytes, then returns the cluster number
If an error occurs, return CLUSTER_ERROR
-----------------------------------------------------------------*/
uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster) {
uint32_t _FAT_fat_linkFreeClusterCleared ( PARTITION* partition, uint32_t cluster )
{
uint32_t newCluster;
uint32_t i;
uint8_t emptySector[BYTES_PER_READ];
@ -271,13 +294,15 @@ uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster
// Link the cluster
newCluster = _FAT_fat_linkFreeCluster( partition, cluster );
if (newCluster == CLUSTER_FREE || newCluster == CLUSTER_ERROR) {
if ( newCluster == CLUSTER_FREE || newCluster == CLUSTER_ERROR )
{
return CLUSTER_ERROR;
}
// Clear all the sectors within the cluster
memset ( emptySector, 0, BYTES_PER_READ );
for (i = 0; i < partition->sectorsPerCluster; i++) {
for ( i = 0; i < partition->sectorsPerCluster; i++ )
{
_FAT_cache_writeSectors ( partition->cache,
_FAT_fat_clusterToSector ( partition, newCluster ) + i,
1, emptySector );
@ -291,18 +316,21 @@ uint32_t _FAT_fat_linkFreeClusterCleared (PARTITION* partition, uint32_t cluster
_FAT_fat_clearLinks
frees any cluster used by a file
-----------------------------------------------------------------*/
bool _FAT_fat_clearLinks (PARTITION* partition, uint32_t cluster) {
bool _FAT_fat_clearLinks ( PARTITION* partition, uint32_t cluster )
{
uint32_t nextCluster;
if ( ( cluster < CLUSTER_FIRST ) || ( cluster > partition->fat.lastCluster /* This will catch CLUSTER_ERROR */ ) )
return false;
// If this clears up more space in the FAT before the current free pointer, move it backwards
if (cluster < partition->fat.firstFree) {
if ( cluster < partition->fat.firstFree )
{
partition->fat.firstFree = cluster;
}
while ((cluster != CLUSTER_EOF) && (cluster != CLUSTER_FREE) && (cluster != CLUSTER_ERROR)) {
while ( ( cluster != CLUSTER_EOF ) && ( cluster != CLUSTER_FREE ) && ( cluster != CLUSTER_ERROR ) )
{
// Store next cluster before erasing the link
nextCluster = _FAT_fat_nextCluster ( partition, cluster );
@ -324,25 +352,31 @@ If chainLength is 1, the first cluster is kept and the rest are
dropped, and so on.
Return the last cluster left in the chain.
-----------------------------------------------------------------*/
uint32_t _FAT_fat_trimChain (PARTITION* partition, uint32_t startCluster, unsigned int chainLength) {
uint32_t _FAT_fat_trimChain ( PARTITION* partition, uint32_t startCluster, unsigned int chainLength )
{
uint32_t nextCluster;
if (chainLength == 0) {
if ( chainLength == 0 )
{
// Drop the entire chain
_FAT_fat_clearLinks ( partition, startCluster );
return CLUSTER_FREE;
} else {
}
else
{
// Find the last cluster in the chain, and the one after it
chainLength--;
nextCluster = _FAT_fat_nextCluster ( partition, startCluster );
while ((chainLength > 0) && (nextCluster != CLUSTER_FREE) && (nextCluster != CLUSTER_EOF)) {
while ( ( chainLength > 0 ) && ( nextCluster != CLUSTER_FREE ) && ( nextCluster != CLUSTER_EOF ) )
{
chainLength--;
startCluster = nextCluster;
nextCluster = _FAT_fat_nextCluster ( partition, startCluster );
}
// Drop all clusters after the last in the chain
if (nextCluster != CLUSTER_FREE && nextCluster != CLUSTER_EOF) {
if ( nextCluster != CLUSTER_FREE && nextCluster != CLUSTER_EOF )
{
_FAT_fat_clearLinks ( partition, nextCluster );
}
@ -357,8 +391,10 @@ uint32_t _FAT_fat_trimChain (PARTITION* partition, uint32_t startCluster, unsign
_FAT_fat_lastCluster
Trace the cluster links until the last one is found
-----------------------------------------------------------------*/
uint32_t _FAT_fat_lastCluster (PARTITION* partition, uint32_t cluster) {
while ((_FAT_fat_nextCluster(partition, cluster) != CLUSTER_FREE) && (_FAT_fat_nextCluster(partition, cluster) != CLUSTER_EOF)) {
uint32_t _FAT_fat_lastCluster ( PARTITION* partition, uint32_t cluster )
{
while ( ( _FAT_fat_nextCluster( partition, cluster ) != CLUSTER_FREE ) && ( _FAT_fat_nextCluster( partition, cluster ) != CLUSTER_EOF ) )
{
cluster = _FAT_fat_nextCluster( partition, cluster );
}
return cluster;
@ -368,12 +404,15 @@ uint32_t _FAT_fat_lastCluster (PARTITION* partition, uint32_t cluster) {
_FAT_fat_freeClusterCount
Return the number of free clusters available
-----------------------------------------------------------------*/
unsigned int _FAT_fat_freeClusterCount (PARTITION* partition) {
unsigned int _FAT_fat_freeClusterCount ( PARTITION* partition )
{
unsigned int count = 0;
uint32_t curCluster;
for (curCluster = CLUSTER_FIRST; curCluster <= partition->fat.lastCluster; curCluster++) {
if (_FAT_fat_nextCluster(partition, curCluster) == CLUSTER_FREE) {
for ( curCluster = CLUSTER_FIRST; curCluster <= partition->fat.lastCluster; curCluster++ )
{
if ( _FAT_fat_nextCluster( partition, curCluster ) == CLUSTER_FREE )
{
count++;
}
}

View File

@ -57,13 +57,15 @@ uint32_t _FAT_fat_lastCluster (PARTITION* partition, uint32_t cluster);
unsigned int _FAT_fat_freeClusterCount ( PARTITION* partition );
static inline sec_t _FAT_fat_clusterToSector (PARTITION* partition, uint32_t cluster) {
static inline sec_t _FAT_fat_clusterToSector ( PARTITION* partition, uint32_t cluster )
{
return ( cluster >= CLUSTER_FIRST ) ?
( ( cluster - CLUSTER_FIRST ) * ( sec_t )partition->sectorsPerCluster ) + partition->dataStart :
partition->rootDirStart;
}
static inline bool _FAT_fat_isValidCluster (PARTITION* partition, uint32_t cluster) {
static inline bool _FAT_fat_isValidCluster ( PARTITION* partition, uint32_t cluster )
{
return ( cluster >= CLUSTER_FIRST ) && ( cluster <= partition->fat.lastCluster /* This will catch CLUSTER_ERROR */ );
}

View File

@ -40,12 +40,14 @@
#define MAX_DAY 31
#define MIN_DAY 1
uint16_t _FAT_filetime_getTimeFromRTC (void) {
uint16_t _FAT_filetime_getTimeFromRTC ( void )
{
#ifdef USE_RTC_TIME
struct tm timeParts;
time_t epochTime;
if (time(&epochTime) == (time_t)-1) {
if ( time( &epochTime ) == ( time_t ) - 1 )
{
return 0;
}
localtime_r( &epochTime, &timeParts );
@ -67,12 +69,14 @@ uint16_t _FAT_filetime_getTimeFromRTC (void) {
}
uint16_t _FAT_filetime_getDateFromRTC (void) {
uint16_t _FAT_filetime_getDateFromRTC ( void )
{
#ifdef USE_RTC_TIME
struct tm timeParts;
time_t epochTime;
if (time(&epochTime) == (time_t)-1) {
if ( time( &epochTime ) == ( time_t ) - 1 )
{
return 0;
}
localtime_r( &epochTime, &timeParts );
@ -90,7 +94,8 @@ uint16_t _FAT_filetime_getDateFromRTC (void) {
#endif
}
time_t _FAT_filetime_to_time_t (uint16_t t, uint16_t d) {
time_t _FAT_filetime_to_time_t ( uint16_t t, uint16_t d )
{
struct tm timeParts;
timeParts.tm_hour = t >> 11;

View File

@ -38,7 +38,8 @@
#include "mem_allocate.h"
#include "disc_fat.h"
static const devoptab_t dotab_fat = {
static const devoptab_t dotab_fat =
{
"fat",
sizeof ( FILE_STRUCT ),
_FAT_open_r,
@ -64,7 +65,8 @@ static const devoptab_t dotab_fat = {
NULL /* Device data */
};
bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage) {
bool fatMount ( const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage )
{
PARTITION* partition;
devoptab_t* devops;
char* nameCopy;
@ -72,13 +74,15 @@ bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSec
if ( !interface->startup() )
return false;
if(!interface->isInserted()) {
if ( !interface->isInserted() )
{
interface->shutdown();
return false;
}
devops = _FAT_mem_allocate ( sizeof( devoptab_t ) + strlen( name ) + 1 );
if (!devops) {
if ( !devops )
{
interface->shutdown();
return false;
}
@ -87,7 +91,8 @@ bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSec
// Initialize the file system
partition = _FAT_partition_constructor ( interface, cacheSize, SectorsPerPage, startSector );
if (!partition) {
if ( !partition )
{
_FAT_mem_free ( devops );
interface->shutdown();
return false;
@ -104,26 +109,31 @@ bool fatMount (const char* name, const DISC_INTERFACE* interface, sec_t startSec
return true;
}
bool fatMountSimple (const char* name, const DISC_INTERFACE* interface) {
bool fatMountSimple ( const char* name, const DISC_INTERFACE* interface )
{
return fatMount ( name, interface, 0, DEFAULT_CACHE_PAGES, DEFAULT_SECTORS_PAGE );
}
void fatUnmount (const char* name) {
void fatUnmount ( const char* name )
{
devoptab_t *devops;
PARTITION* partition;
const DISC_INTERFACE *disc;
devops = ( devoptab_t* )GetDeviceOpTab ( name );
if (!devops) {
if ( !devops )
{
return;
}
// Perform a quick check to make sure we're dealing with a libfat controlled device
if (devops->open_r != dotab_fat.open_r) {
if ( devops->open_r != dotab_fat.open_r )
{
return;
}
if (RemoveDevice (name) == -1) {
if ( RemoveDevice ( name ) == -1 )
{
return;
}
@ -134,7 +144,8 @@ void fatUnmount (const char* name) {
disc->shutdown();
}
bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) {
bool fatInit ( uint32_t cacheSize, bool setAsDefaultDevice )
{
int i;
int defaultDevice = -1;
const DISC_INTERFACE *disc;
@ -144,25 +155,30 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) {
i++ )
{
disc = _FAT_disc_interfaces[i].getInterface();
if (fatMount (_FAT_disc_interfaces[i].name, disc, 0, cacheSize, DEFAULT_SECTORS_PAGE)) {
if ( fatMount ( _FAT_disc_interfaces[i].name, disc, 0, cacheSize, DEFAULT_SECTORS_PAGE ) )
{
// The first device to successfully mount is set as the default
if (defaultDevice < 0) {
if ( defaultDevice < 0 )
{
defaultDevice = i;
}
}
}
if (defaultDevice < 0) {
if ( defaultDevice < 0 )
{
// None of our devices mounted
return false;
}
if (setAsDefaultDevice) {
if ( setAsDefaultDevice )
{
char filePath[MAXPATHLEN * 2];
strcpy ( filePath, _FAT_disc_interfaces[defaultDevice].name );
strcat ( filePath, ":/" );
#ifdef ARGV_MAGIC
if ( __system_argv->argvMagic == ARGV_MAGIC && __system_argv->argc >= 1 && strrchr( __system_argv->argv[0], '/' )!=NULL ) {
if ( __system_argv->argvMagic == ARGV_MAGIC && __system_argv->argc >= 1 && strrchr( __system_argv->argv[0], '/' ) != NULL )
{
// Check the app's path against each of our mounted devices, to see
// if we can support it. If so, change to that path.
for ( i = 0;
@ -176,7 +192,8 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) {
strcpy( filePath, __system_argv->argv[0] );
lastSlash = strrchr( filePath, '/' );
if ( NULL != lastSlash) {
if ( NULL != lastSlash )
{
if ( *( lastSlash - 1 ) == ':' ) lastSlash++;
*lastSlash = 0;
}
@ -190,7 +207,8 @@ bool fatInit (uint32_t cacheSize, bool setAsDefaultDevice) {
return true;
}
bool fatInitDefault (void) {
bool fatInitDefault ( void )
{
return fatInit ( DEFAULT_CACHE_PAGES, true );
}

View File

@ -33,16 +33,19 @@
#include <malloc.h>
static inline void* _FAT_mem_allocate (size_t size) {
static inline void* _FAT_mem_allocate ( size_t size )
{
return malloc ( size );
}
static inline void* _FAT_mem_align (size_t size) {
static inline void* _FAT_mem_align ( size_t size )
{
return memalign ( 32, size );
}
static inline void _FAT_mem_free (void* mem) {
static inline void _FAT_mem_free ( void* mem )
{
free ( mem );
}

View File

@ -50,7 +50,8 @@ Data offsets
*/
// BIOS Parameter Block offsets
enum BPB {
enum BPB
{
BPB_jmpBoot = 0x00,
BPB_OEMName = 0x03,
// BIOS Parameter Block
@ -107,24 +108,28 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
// Read first sector of disc
if (!_FAT_disc_readSectors (disc, 0, 1, sectorBuffer)) {
if ( !_FAT_disc_readSectors ( disc, 0, 1, sectorBuffer ) )
{
return 0;
}
memcpy( part_table, sectorBuffer + 0x1BE, 16*4 );
ptr = part_table;
for(i=0;i<4;i++,ptr+=16) {
for ( i = 0; i < 4; i++, ptr += 16 )
{
sec_t part_lba = u8array_to_u32( ptr, 0x8 );
if ( !memcmp( sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
!memcmp( sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) )
{
return part_lba;
}
if ( ptr[4] == 0 ) continue;
if(ptr[4]==0x0F) {
if ( ptr[4] == 0x0F )
{
sec_t part_lba2 = part_lba;
sec_t next_lba2 = 0;
int n;
@ -146,10 +151,13 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
if ( next_lba2 == 0 ) break;
}
} else {
}
else
{
if ( !_FAT_disc_readSectors ( disc, part_lba, 1, sectorBuffer ) ) return 0;
if ( !memcmp( sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) ||
!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
!memcmp( sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) )
{
return part_lba;
}
}
@ -157,31 +165,42 @@ sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
return 0;
}
PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector) {
PARTITION* _FAT_partition_constructor ( const DISC_INTERFACE* disc, uint32_t cacheSize, uint32_t sectorsPerPage, sec_t startSector )
{
PARTITION* partition;
uint8_t sectorBuffer[BYTES_PER_READ] = {0};
// Read first sector of disc
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
if ( !_FAT_disc_readSectors ( disc, startSector, 1, sectorBuffer ) )
{
return NULL;
}
// Make sure it is a valid MBR or boot sector
if ( (sectorBuffer[BPB_bootSig_55] != 0x55) || (sectorBuffer[BPB_bootSig_AA] != 0xAA)) {
if ( ( sectorBuffer[BPB_bootSig_55] != 0x55 ) || ( sectorBuffer[BPB_bootSig_AA] != 0xAA ) )
{
return NULL;
}
if (startSector != 0) {
if ( startSector != 0 )
{
// We're told where to start the partition, so just accept it
} else if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
}
else if ( !memcmp( sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) )
{
// Check if there is a FAT string, which indicates this is a boot sector
startSector = 0;
} else if (!memcmp(sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG))) {
}
else if ( !memcmp( sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) )
{
// Check for FAT32
startSector = 0;
} else {
}
else
{
startSector = FindFirstValidPartition( disc );
if (!_FAT_disc_readSectors (disc, startSector, 1, sectorBuffer)) {
if ( !_FAT_disc_readSectors ( disc, startSector, 1, sectorBuffer ) )
{
return NULL;
}
}
@ -201,7 +220,8 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
}
partition = ( PARTITION* ) _FAT_mem_allocate ( sizeof( PARTITION ) );
if (partition == NULL) {
if ( partition == NULL )
{
return NULL;
}
@ -215,12 +235,14 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
// Store required information about the file system
partition->fat.sectorsPerFat = u8array_to_u16( sectorBuffer, BPB_sectorsPerFAT );
if (partition->fat.sectorsPerFat == 0) {
if ( partition->fat.sectorsPerFat == 0 )
{
partition->fat.sectorsPerFat = u8array_to_u32( sectorBuffer, BPB_FAT32_sectorsPerFAT32 );
}
partition->numberOfSectors = u8array_to_u16( sectorBuffer, BPB_numSectorsSmall );
if (partition->numberOfSectors == 0) {
if ( partition->numberOfSectors == 0 )
{
partition->numberOfSectors = u8array_to_u32( sectorBuffer, BPB_numSectors );
}
@ -240,21 +262,30 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
partition->fat.lastCluster = clusterCount + CLUSTER_FIRST - 1;
partition->fat.firstFree = CLUSTER_FIRST;
if (clusterCount < CLUSTERS_PER_FAT12) {
if ( clusterCount < CLUSTERS_PER_FAT12 )
{
partition->filesysType = FS_FAT12; // FAT12 volume
} else if (clusterCount < CLUSTERS_PER_FAT16) {
}
else if ( clusterCount < CLUSTERS_PER_FAT16 )
{
partition->filesysType = FS_FAT16; // FAT16 volume
} else {
}
else
{
partition->filesysType = FS_FAT32; // FAT32 volume
}
if (partition->filesysType != FS_FAT32) {
if ( partition->filesysType != FS_FAT32 )
{
partition->rootDirCluster = FAT16_ROOT_DIR_CLUSTER;
} else {
}
else
{
// Set up for the FAT32 way
partition->rootDirCluster = u8array_to_u32( sectorBuffer, BPB_FAT32_rootClus );
// Check if FAT mirroring is enabled
if (!(sectorBuffer[BPB_FAT32_extFlags] & 0x80)) {
if ( !( sectorBuffer[BPB_FAT32_extFlags] & 0x80 ) )
{
// Use the active FAT
partition->fat.fatStart = partition->fat.fatStart + ( partition->fat.sectorsPerFat * ( sectorBuffer[BPB_FAT32_extFlags] & 0x0F ) );
}
@ -276,14 +307,16 @@ PARTITION* _FAT_partition_constructor (const DISC_INTERFACE* disc, uint32_t cach
return partition;
}
void _FAT_partition_destructor (PARTITION* partition) {
void _FAT_partition_destructor ( PARTITION* partition )
{
FILE_STRUCT* nextFile;
_FAT_lock( &partition->lock );
// Synchronize open files
nextFile = partition->firstOpenFile;
while (nextFile) {
while ( nextFile )
{
_FAT_syncToDisc ( nextFile );
nextFile = nextFile->nextOpenFile;
}
@ -299,12 +332,14 @@ void _FAT_partition_destructor (PARTITION* partition) {
_FAT_mem_free ( partition );
}
PARTITION* _FAT_partition_getPartitionFromPath (const char* path) {
PARTITION* _FAT_partition_getPartitionFromPath ( const char* path )
{
const devoptab_t *devops;
devops = GetDeviceOpTab ( path );
if (!devops) {
if ( !devops )
{
return NULL;
}

View File

@ -40,14 +40,16 @@ extern const char* DEVICE_NAME;
// Filesystem type
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
typedef struct {
typedef struct
{
sec_t fatStart;
uint32_t sectorsPerFat;
uint32_t lastCluster;
uint32_t firstFree;
} FAT;
typedef struct {
typedef struct
{
const DISC_INTERFACE* disc;
CACHE* cache;
// Info about the partition

File diff suppressed because it is too large Load Diff

View File

@ -122,7 +122,8 @@ typedef char BIGSID[40];
* (private to this module)
*/
struct MAPLIST {
struct MAPLIST
{
struct MAPLIST *next;
char *uidstr; /* uid text from the same record */
char *gidstr; /* gid text from the same record */

File diff suppressed because it is too large Load Diff

View File

@ -49,7 +49,8 @@ extern ntfschar TXF_DATA[10];
*
* TODO: Describe them.
*/
typedef enum {
typedef enum
{
LCN_HOLE = -1, /* Keep this as highest value or die! */
LCN_RL_NOT_MAPPED = -2,
LCN_ENOENT = -3,
@ -75,7 +76,8 @@ typedef enum {
* any modification of the search context, to automagically get the next
* matching attribute.
*/
struct _ntfs_attr_search_ctx {
struct _ntfs_attr_search_ctx
{
MFT_RECORD *mrec;
ATTR_RECORD *attr;
BOOL is_first;
@ -174,7 +176,8 @@ static __inline__ int ntfs_attrs_walk(ntfs_attr_search_ctx *ctx)
* @state contains NTFS attribute specific flags describing this attribute
* structure. See ntfs_attr_state_bits above.
*/
struct _ntfs_attr {
struct _ntfs_attr
{
runlist_element *rl;
ntfs_inode *ni;
ATTR_TYPES type;
@ -196,7 +199,8 @@ struct _ntfs_attr {
* enum ntfs_attr_state_bits - bits for the state field in the ntfs_attr
* structure
*/
typedef enum {
typedef enum
{
NA_Initialized, /* 1: structure is initialized. */
NA_NonResident, /* 1: Attribute is not resident. */
NA_BeingNonResident, /* 1: Attribute is being made not resident. */
@ -243,7 +247,8 @@ GenNAttrIno(Sparse, FILE_ATTR_SPARSE_FILE)
*
* For convenience. Used in the attr structure.
*/
typedef union {
typedef union
{
u8 _default; /* Unnamed u8 to serve as default when just using
a_val without specifying any of the below. */
STANDARD_INFORMATION std_inf;

File diff suppressed because it is too large Load Diff

View File

@ -62,7 +62,8 @@ int ntfs_attrlist_need(ntfs_inode *ni)
{
ATTR_LIST_ENTRY *ale;
if (!ni) {
if ( !ni )
{
ntfs_log_trace( "Invalid arguments.\n" );
errno = EINVAL;
return -1;
@ -70,13 +71,15 @@ int ntfs_attrlist_need(ntfs_inode *ni)
ntfs_log_trace( "Entering for inode 0x%llx.\n", ( long long ) ni->mft_no );
if (!NInoAttrList(ni)) {
if ( !NInoAttrList( ni ) )
{
ntfs_log_trace( "Inode haven't got attribute list.\n" );
errno = EINVAL;
return -1;
}
if (!ni->attr_list) {
if ( !ni->attr_list )
{
ntfs_log_trace( "Corrupt in-memory struct.\n" );
errno = EINVAL;
return -1;
@ -84,7 +87,8 @@ int ntfs_attrlist_need(ntfs_inode *ni)
errno = 0;
ale = ( ATTR_LIST_ENTRY * )ni->attr_list;
while ((u8*)ale < ni->attr_list + ni->attr_list_size) {
while ( ( u8* )ale < ni->attr_list + ni->attr_list_size )
{
if ( MREF_LE( ale->mft_reference ) != ni->mft_no )
return 1;
ale = ( ATTR_LIST_ENTRY * )( ( u8* )ale + le16_to_cpu( ale->length ) );
@ -117,7 +121,8 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
( long long ) ni->mft_no,
( unsigned ) le32_to_cpu( attr->type ) );
if (!ni || !attr) {
if ( !ni || !attr )
{
ntfs_log_trace( "Invalid arguments.\n" );
errno = EINVAL;
return -1;
@ -128,7 +133,8 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
if ( ni->nr_extents == -1 )
ni = ni->base_ni;
if (!NInoAttrList(ni)) {
if ( !NInoAttrList( ni ) )
{
ntfs_log_trace( "Attribute list isn't present.\n" );
errno = ENOENT;
return -1;
@ -143,7 +149,8 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
/* Find place for the new entry. */
ctx = ntfs_attr_get_search_ctx( ni, NULL );
if (!ctx) {
if ( !ctx )
{
err = errno;
goto err_out;
}
@ -153,9 +160,11 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
( attr->non_resident ) ? le64_to_cpu( attr->lowest_vcn ) :
0, ( attr->non_resident ) ? NULL : ( ( u8* )attr +
le16_to_cpu( attr->value_offset ) ), ( attr->non_resident ) ?
0 : le32_to_cpu(attr->value_length), ctx)) {
0 : le32_to_cpu( attr->value_length ), ctx ) )
{
/* Found some extent, check it to be before new extent. */
if (ctx->al_entry->lowest_vcn == attr->lowest_vcn) {
if ( ctx->al_entry->lowest_vcn == attr->lowest_vcn )
{
err = EEXIST;
ntfs_log_trace( "Such attribute already present in the "
"attribute list.\n" );
@ -165,9 +174,12 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
/* Add new entry after this extent. */
ale = ( ATTR_LIST_ENTRY* )( ( u8* )ctx->al_entry +
le16_to_cpu( ctx->al_entry->length ) );
} else {
}
else
{
/* Check for real errors. */
if (errno != ENOENT) {
if ( errno != ENOENT )
{
err = errno;
ntfs_log_trace( "Attribute lookup failed.\n" );
ntfs_attr_put_search_ctx( ctx );
@ -201,12 +213,14 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
/* Resize $ATTRIBUTE_LIST to new length. */
na = ntfs_attr_open( ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0 );
if (!na) {
if ( !na )
{
err = errno;
ntfs_log_trace( "Failed to open $ATTRIBUTE_LIST attribute.\n" );
goto err_out;
}
if (ntfs_attr_truncate(na, ni->attr_list_size + entry_len)) {
if ( ntfs_attr_truncate( na, ni->attr_list_size + entry_len ) )
{
err = errno;
ntfs_log_trace( "$ATTRIBUTE_LIST resize failed.\n" );
goto err_out;
@ -250,7 +264,8 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
ATTR_LIST_ENTRY *ale;
int err;
if (!ctx || !ctx->ntfs_ino || !ctx->al_entry) {
if ( !ctx || !ctx->ntfs_ino || !ctx->al_entry )
{
ntfs_log_trace( "Invalid arguments.\n" );
errno = EINVAL;
return -1;
@ -267,7 +282,8 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
( unsigned ) le32_to_cpu( ctx->al_entry->type ),
( long long ) le64_to_cpu( ctx->al_entry->lowest_vcn ) );
if (!NInoAttrList(base_ni)) {
if ( !NInoAttrList( base_ni ) )
{
ntfs_log_trace( "Attribute list isn't present.\n" );
errno = ENOENT;
return -1;
@ -281,12 +297,14 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
/* Reisze $ATTRIBUTE_LIST to new length. */
na = ntfs_attr_open( base_ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0 );
if (!na) {
if ( !na )
{
err = errno;
ntfs_log_trace( "Failed to open $ATTRIBUTE_LIST attribute.\n" );
goto err_out;
}
if (ntfs_attr_truncate(na, new_al_len)) {
if ( ntfs_attr_truncate( na, new_al_len ) )
{
err = errno;
ntfs_log_trace( "$ATTRIBUTE_LIST resize failed.\n" );
goto err_out;

View File

@ -34,20 +34,24 @@
/*-----------------------------------------------------------------
Functions to deal with little endian values stored in uint8_t arrays
-----------------------------------------------------------------*/
static inline uint16_t u8array_to_u16 (const uint8_t* item, int offset) {
static inline uint16_t u8array_to_u16 ( const uint8_t* item, int offset )
{
return ( item[offset] | ( item[offset + 1] << 8 ) );
}
static inline uint32_t u8array_to_u32 (const uint8_t* item, int offset) {
static inline uint32_t u8array_to_u32 ( const uint8_t* item, int offset )
{
return ( item[offset] | ( item[offset + 1] << 8 ) | ( item[offset + 2] << 16 ) | ( item[offset + 3] << 24 ) );
}
static inline void u16_to_u8array (uint8_t* item, int offset, uint16_t value) {
static inline void u16_to_u8array ( uint8_t* item, int offset, uint16_t value )
{
item[offset] = ( uint8_t ) value;
item[offset + 1] = ( uint8_t )( value >> 8 );
}
static inline void u32_to_u8array (uint8_t* item, int offset, uint32_t value) {
static inline void u32_to_u8array ( uint8_t* item, int offset, uint32_t value )
{
item[offset] = ( uint8_t ) value;
item[offset + 1] = ( uint8_t )( value >> 8 );
item[offset + 2] = ( uint8_t )( value >> 16 );

View File

@ -119,7 +119,8 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
u8 *buf, *lastbyte_buf;
int bit, firstbyte, lastbyte, lastbyte_pos, tmp, ret = -1;
if (!na || start_bit < 0 || count < 0) {
if ( !na || start_bit < 0 || count < 0 )
{
errno = EINVAL;
ntfs_log_perror( "%s: Invalid argument (%p, %lld, %lld)",
__FUNCTION__, na, ( long long )start_bit, ( long long )count );
@ -145,16 +146,19 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
memset( buf, value ? 0xff : 0, bufsize );
/* If there is a first partial byte... */
if (bit) {
if ( bit )
{
/* read it in... */
br = ntfs_attr_pread( na, start_bit >> 3, 1, buf );
if (br != 1) {
if ( br != 1 )
{
if ( br >= 0 )
errno = EIO;
goto free_err_out;
}
/* and set or clear the appropriate bits in it. */
while ((bit & 7) && count--) {
while ( ( bit & 7 ) && count-- )
{
if ( value )
*buf |= 1 << bit++;
else
@ -168,11 +172,14 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
lastbyte = 0;
lastbyte_buf = NULL;
bit = count & 7;
do {
do
{
/* If there is a last partial byte... */
if (count > 0 && bit) {
if ( count > 0 && bit )
{
lastbyte_pos = ( ( count + 7 ) >> 3 ) + firstbyte;
if (!lastbyte_pos) {
if ( !lastbyte_pos )
{
// FIXME: Eeek! BUG!
ntfs_log_error( "Lastbyte is zero. Leaving "
"inconsistent metadata.\n" );
@ -180,13 +187,15 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
goto free_err_out;
}
/* and it is in the currently loaded bitmap window... */
if (lastbyte_pos <= bufsize) {
if ( lastbyte_pos <= bufsize )
{
lastbyte_buf = buf + lastbyte_pos - 1;
/* read the byte in... */
br = ntfs_attr_pread( na, ( start_bit + count ) >>
3, 1, lastbyte_buf );
if (br != 1) {
if ( br != 1 )
{
// FIXME: Eeek! We need rollback! (AIA)
if ( br >= 0 )
errno = EIO;
@ -196,7 +205,8 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
goto free_err_out;
}
/* and set/clear the appropriate bits in it. */
while (bit && count--) {
while ( bit && count-- )
{
if ( value )
*lastbyte_buf |= 1 << --bit;
else
@ -212,7 +222,8 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
/* Write the prepared buffer to disk. */
tmp = ( start_bit >> 3 ) - firstbyte;
br = ntfs_attr_pwrite( na, tmp, bufsize, buf );
if (br != bufsize) {
if ( br != bufsize )
{
// FIXME: Eeek! We need rollback! (AIA)
if ( br >= 0 )
errno = EIO;
@ -224,7 +235,8 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
/* Update counters. */
tmp = ( bufsize - firstbyte - lastbyte ) << 3;
if (firstbyte) {
if ( firstbyte )
{
firstbyte = 0;
/*
* Re-set the partial first byte so a subsequent write
@ -237,7 +249,8 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
if ( bufsize > ( tmp = ( count + 7 ) >> 3 ) )
bufsize = tmp;
if (lastbyte && count != 0) {
if ( lastbyte && count != 0 )
{
// FIXME: Eeek! BUG!
ntfs_log_error( "Last buffer but count is not zero "
"(%lld). Leaving inconsistent metadata.\n",
@ -245,7 +258,8 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
errno = EIO;
goto free_err_out;
}
} while (count > 0);
}
while ( count > 0 );
ret = 0;

View File

@ -65,21 +65,24 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
ntfs_log_debug( "Beginning bootsector check.\n" );
ntfs_log_debug( "Checking OEMid, NTFS signature.\n" );
if (b->oem_id != cpu_to_le64(0x202020205346544eULL)) { /* "NTFS " */
if ( b->oem_id != cpu_to_le64( 0x202020205346544eULL ) ) /* "NTFS " */
{
ntfs_log_error( "NTFS signature is missing.\n" );
goto not_ntfs;
}
ntfs_log_debug( "Checking bytes per sector.\n" );
if ( le16_to_cpu( b->bpb.bytes_per_sector ) < 256 ||
le16_to_cpu(b->bpb.bytes_per_sector) > 4096) {
le16_to_cpu( b->bpb.bytes_per_sector ) > 4096 )
{
ntfs_log_error( "Unexpected bytes per sector value (%d).\n",
le16_to_cpu( b->bpb.bytes_per_sector ) );
goto not_ntfs;
}
ntfs_log_debug( "Checking sectors per cluster.\n" );
switch (b->bpb.sectors_per_cluster) {
switch ( b->bpb.sectors_per_cluster )
{
case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128:
break;
default:
@ -91,7 +94,8 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
ntfs_log_debug( "Checking cluster size.\n" );
i = ( u32 )le16_to_cpu( b->bpb.bytes_per_sector ) *
b->bpb.sectors_per_cluster;
if (i > 65536) {
if ( i > 65536 )
{
ntfs_log_error( "Unexpected cluster size (%d).\n", i );
goto not_ntfs;
}
@ -102,7 +106,8 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
le16_to_cpu( b->bpb.sectors ) ||
le16_to_cpu( b->bpb.sectors_per_fat ) ||
le32_to_cpu( b->bpb.large_sectors ) ||
b->bpb.fats) {
b->bpb.fats )
{
ntfs_log_error( "Reserved fields aren't zero "
"(%d, %d, %d, %d, %d, %d).\n",
le16_to_cpu( b->bpb.reserved_sectors ),
@ -116,8 +121,10 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
ntfs_log_debug( "Checking clusters per mft record.\n" );
if ( ( u8 )b->clusters_per_mft_record < 0xe1 ||
(u8)b->clusters_per_mft_record > 0xf7) {
switch (b->clusters_per_mft_record) {
( u8 )b->clusters_per_mft_record > 0xf7 )
{
switch ( b->clusters_per_mft_record )
{
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
break;
default:
@ -129,8 +136,10 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
ntfs_log_debug( "Checking clusters per index block.\n" );
if ( ( u8 )b->clusters_per_index_record < 0xe1 ||
(u8)b->clusters_per_index_record > 0xf7) {
switch (b->clusters_per_index_record) {
( u8 )b->clusters_per_index_record > 0xf7 )
{
switch ( b->clusters_per_index_record )
{
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
break;
default:
@ -188,7 +197,8 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
*/
sectors_per_cluster = bs->bpb.sectors_per_cluster;
ntfs_log_debug( "SectorsPerCluster = 0x%x\n", sectors_per_cluster );
if (sectors_per_cluster & (sectors_per_cluster - 1)) {
if ( sectors_per_cluster & ( sectors_per_cluster - 1 ) )
{
ntfs_log_error( "sectors_per_cluster (%d) is not a power of 2."
"\n", sectors_per_cluster );
return -1;
@ -196,13 +206,15 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
sectors = sle64_to_cpu( bs->number_of_sectors );
ntfs_log_debug( "NumberOfSectors = %lld\n", ( long long )sectors );
if (!sectors) {
if ( !sectors )
{
ntfs_log_error( "Volume size is set to zero.\n" );
return -1;
}
if ( vol->dev->d_ops->seek( vol->dev,
( sectors - 1 ) << vol->sector_size_bits,
SEEK_SET) == -1) {
SEEK_SET ) == -1 )
{
ntfs_log_perror( "Failed to read last sector (%lld)",
( long long )sectors );
ntfs_log_error( "%s", last_sector_error );
@ -216,7 +228,8 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
ntfs_log_debug( "MFT LCN = %lld\n", ( long long )vol->mft_lcn );
ntfs_log_debug( "MFTMirr LCN = %lld\n", ( long long )vol->mftmirr_lcn );
if ( vol->mft_lcn > vol->nr_clusters ||
vol->mftmirr_lcn > vol->nr_clusters) {
vol->mftmirr_lcn > vol->nr_clusters )
{
ntfs_log_error( "$MFT LCN (%lld) or $MFTMirr LCN (%lld) is "
"greater than the number of clusters (%lld).\n",
( long long )vol->mft_lcn, ( long long )vol->mftmirr_lcn,
@ -225,7 +238,8 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
}
vol->cluster_size = sectors_per_cluster * vol->sector_size;
if (vol->cluster_size & (vol->cluster_size - 1)) {
if ( vol->cluster_size & ( vol->cluster_size - 1 ) )
{
ntfs_log_error( "cluster_size (%d) is not a power of 2.\n",
vol->cluster_size );
return -1;
@ -250,7 +264,8 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
vol->mft_record_size = 1 << -c;
else
vol->mft_record_size = c << vol->cluster_size_bits;
if (vol->mft_record_size & (vol->mft_record_size - 1)) {
if ( vol->mft_record_size & ( vol->mft_record_size - 1 ) )
{
ntfs_log_error( "mft_record_size (%d) is not a power of 2.\n",
vol->mft_record_size );
return -1;

View File

@ -67,12 +67,15 @@ static void inserthashindex(struct CACHE_HEADER *cache,
struct HASH_ENTRY *link;
struct HASH_ENTRY *first;
if (cache->dohash) {
if ( cache->dohash )
{
h = cache->dohash( current );
if ((h >= 0) && (h < cache->max_hash)) {
if ( ( h >= 0 ) && ( h < cache->max_hash ) )
{
/* get a free link and insert at top of hash list */
link = cache->free_hash;
if (link) {
if ( link )
{
cache->free_hash = link->next;
first = cache->first_hash[h];
if ( first )
@ -81,13 +84,17 @@ static void inserthashindex(struct CACHE_HEADER *cache,
link->next = NULL;
link->entry = current;
cache->first_hash[h] = link;
} else {
}
else
{
ntfs_log_error( "No more hash entries,"
" cache %s hashing dropped\n",
cache->name );
cache->dohash = ( cache_hash )NULL;
}
} else {
}
else
{
ntfs_log_error( "Illegal hash value,"
" cache %s hashing dropped\n",
cache->name );
@ -106,29 +113,37 @@ static void drophashindex(struct CACHE_HEADER *cache,
struct HASH_ENTRY *link;
struct HASH_ENTRY *previous;
if (cache->dohash) {
if ((hash >= 0) && (hash < cache->max_hash)) {
if ( cache->dohash )
{
if ( ( hash >= 0 ) && ( hash < cache->max_hash ) )
{
/* find the link and unlink */
link = cache->first_hash[hash];
previous = ( struct HASH_ENTRY* )NULL;
while (link && (link->entry != current)) {
while ( link && ( link->entry != current ) )
{
previous = link;
link = link->next;
}
if (link) {
if ( link )
{
if ( previous )
previous->next = link->next;
else
cache->first_hash[hash] = link->next;
link->next = cache->free_hash;
cache->free_hash = link;
} else {
}
else
{
ntfs_log_error( "Bad hash list,"
" cache %s hashing dropped\n",
cache->name );
cache->dohash = ( cache_hash )NULL;
}
} else {
}
else
{
ntfs_log_error( "Illegal hash value,"
" cache %s hashing dropped\n",
cache->name );
@ -153,8 +168,10 @@ struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache,
int h;
current = ( struct CACHED_GENERIC* )NULL;
if (cache) {
if (cache->dohash) {
if ( cache )
{
if ( cache->dohash )
{
/*
* When possible, use the hash table to
* locate the entry if present
@ -166,21 +183,25 @@ struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache,
if ( link )
current = link->entry;
}
if (!cache->dohash) {
if ( !cache->dohash )
{
/*
* Search sequentially in LRU list if no hash table
* or if hashing has just failed
*/
current = cache->most_recent_entry;
while ( current
&& compare(current, wanted)) {
&& compare( current, wanted ) )
{
current = current->next;
}
}
if (current) {
if ( current )
{
previous = current->previous;
cache->hits++;
if (previous) {
if ( previous )
{
/*
* found and not at head of list, unlink from current
* position and relink as head of list
@ -219,8 +240,10 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
int h;
current = ( struct CACHED_GENERIC* )NULL;
if (cache) {
if (cache->dohash) {
if ( cache )
{
if ( cache->dohash )
{
/*
* When possible, use the hash table to
* find out whether the entry if present
@ -229,11 +252,13 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
link = cache->first_hash[h];
while ( link && compare( link->entry, item ) )
link = link->next;
if (link) {
if ( link )
{
current = link->entry;
}
}
if (!cache->dohash) {
if ( !cache->dohash )
{
/*
* Search sequentially in LRU list to locate the end,
* and find out whether the entry is already in list
@ -242,12 +267,14 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
*/
current = cache->most_recent_entry;
while ( current
&& compare(current, item)) {
&& compare( current, item ) )
{
current = current->next;
}
}
if (!current) {
if ( !current )
{
/*
* Not in list, get a free entry or reuse the
* last entry, and relink as head of list
@ -256,18 +283,23 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
* an entry is reused.
*/
if (cache->free_entry) {
if ( cache->free_entry )
{
current = cache->free_entry;
cache->free_entry = cache->free_entry->next;
if (item->varsize) {
if ( item->varsize )
{
current->variable = ntfs_malloc(
item->varsize );
} else
}
else
current->variable = ( void* )NULL;
current->varsize = item->varsize;
if ( !cache->oldest_entry )
cache->oldest_entry = current;
} else {
}
else
{
/* reusing the oldest entry */
current = cache->oldest_entry;
before = current->previous;
@ -278,7 +310,8 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
if ( cache->dofree )
cache->dofree( current );
cache->oldest_entry = current->previous;
if (item->varsize) {
if ( item->varsize )
{
if ( current->varsize )
current->variable = realloc(
current->variable,
@ -286,7 +319,9 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
else
current->variable = ntfs_malloc(
item->varsize );
} else {
}
else
{
if ( current->varsize )
free( current->variable );
current->variable = ( void* )NULL;
@ -299,11 +334,15 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
cache->most_recent_entry->previous = current;
cache->most_recent_entry = current;
memcpy( current->fixed, item->fixed, cache->fixed_size );
if (item->varsize) {
if (current->variable) {
if ( item->varsize )
{
if ( current->variable )
{
memcpy( current->variable,
item->variable, item->varsize );
} else {
}
else
{
/*
* no more memory for variable part
* recycle entry in free list
@ -314,7 +353,9 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
cache->free_entry = current;
current = ( struct CACHED_GENERIC* )NULL;
}
} else {
}
else
{
current->variable = ( void* )NULL;
current->varsize = 0;
}
@ -384,21 +425,26 @@ int ntfs_invalidate_cache(struct CACHE_HEADER *cache,
current = ( struct CACHED_GENERIC* )NULL;
count = 0;
if (cache) {
if (!(flags & CACHE_NOHASH) && cache->dohash) {
if ( cache )
{
if ( !( flags & CACHE_NOHASH ) && cache->dohash )
{
/*
* When possible, use the hash table to
* find out whether the entry if present
*/
h = cache->dohash( item );
link = cache->first_hash[h];
while (link) {
while ( link )
{
if ( compare( link->entry, item ) )
link = link->next;
else {
else
{
current = link->entry;
link = link->next;
if (current) {
if ( current )
{
drophashindex( cache, current, h );
do_invalidate( cache,
current, flags );
@ -407,14 +453,17 @@ int ntfs_invalidate_cache(struct CACHE_HEADER *cache,
}
}
}
if ((flags & CACHE_NOHASH) || !cache->dohash) {
if ( ( flags & CACHE_NOHASH ) || !cache->dohash )
{
/*
* Search sequentially in LRU list
*/
current = cache->most_recent_entry;
previous = ( struct CACHED_GENERIC* )NULL;
while (current) {
if (!compare(current, item)) {
while ( current )
{
if ( !compare( current, item ) )
{
next = current->next;
if ( cache->dohash )
drophashindex( cache, current,
@ -422,7 +471,9 @@ int ntfs_invalidate_cache(struct CACHE_HEADER *cache,
do_invalidate( cache, current, flags );
current = next;
count++;
} else {
}
else
{
previous = current;
current = current->next;
}
@ -438,7 +489,8 @@ int ntfs_remove_cache(struct CACHE_HEADER *cache,
int count;
count = 0;
if (cache) {
if ( cache )
{
if ( cache->dohash )
drophashindex( cache, item, cache->dohash( item ) );
do_invalidate( cache, item, flags );
@ -455,8 +507,10 @@ static void ntfs_free_cache(struct CACHE_HEADER *cache)
{
struct CACHED_GENERIC *entry;
if (cache) {
for (entry=cache->most_recent_entry; entry; entry=entry->next) {
if ( cache )
{
for ( entry = cache->most_recent_entry; entry; entry = entry->next )
{
if ( cache->dofree )
cache->dofree( entry );
if ( entry->variable )
@ -491,14 +545,18 @@ static struct CACHE_HEADER *ntfs_create_cache(const char *name,
size += item_count*sizeof( struct HASH_ENTRY )
+ max_hash*sizeof( struct HASH_ENTRY* );
cache = ( struct CACHE_HEADER* )ntfs_malloc( size );
if (cache) {
if ( cache )
{
/* header */
cache->name = name;
cache->dofree = dofree;
if (dohash && max_hash) {
if ( dohash && max_hash )
{
cache->dohash = dohash;
cache->max_hash = max_hash;
} else {
}
else
{
cache->dohash = ( cache_hash )NULL;
cache->max_hash = 0;
}
@ -511,7 +569,8 @@ static struct CACHE_HEADER *ntfs_create_cache(const char *name,
cache->oldest_entry = ( struct CACHED_GENERIC* )NULL;
cache->free_entry = &cache->entry[0];
pc = &cache->entry[0];
for (i=0; i<(item_count - 1); i++) {
for ( i = 0; i < ( item_count - 1 ); i++ )
{
qc = ( struct CACHED_GENERIC* )( ( char* )pc
+ full_item_size );
pc->next = qc;
@ -524,17 +583,20 @@ static struct CACHE_HEADER *ntfs_create_cache(const char *name,
pc->variable = ( void* )NULL;
pc->varsize = 0;
if (max_hash) {
if ( max_hash )
{
/* chain the hash entries */
ph = ( struct HASH_ENTRY* )( ( ( char* )pc ) + full_item_size );
cache->free_hash = ph;
for (i=0; i<(item_count - 1); i++) {
for ( i = 0; i < ( item_count - 1 ); i++ )
{
qh = &ph[1];
ph->next = qh;
ph = qh;
}
/* special for the last entry */
if (item_count) {
if ( item_count )
{
ph->next = ( struct HASH_ENTRY* )NULL;
}
/* create and initialize the hash indexes */
@ -542,7 +604,9 @@ static struct CACHE_HEADER *ntfs_create_cache(const char *name,
cache->first_hash = px;
for ( i = 0; i < max_hash; i++ )
px[i] = ( struct HASH_ENTRY* )NULL;
} else {
}
else
{
cache->free_hash = ( struct HASH_ENTRY* )NULL;
cache->first_hash = ( struct HASH_ENTRY** )NULL;
}

View File

@ -24,19 +24,22 @@
#include "volume.h"
struct CACHED_GENERIC {
struct CACHED_GENERIC
{
struct CACHED_GENERIC *next;
struct CACHED_GENERIC *previous;
void *variable;
size_t varsize;
union {
union
{
/* force alignment for pointers and u64 */
u64 u64align;
void *ptralign;
} fixed[0];
} ;
struct CACHED_INODE {
struct CACHED_INODE
{
struct CACHED_INODE *next;
struct CACHED_INODE *previous;
const char *pathname;
@ -45,7 +48,8 @@ struct CACHED_INODE {
u64 inum;
} ;
struct CACHED_NIDATA {
struct CACHED_NIDATA
{
struct CACHED_NIDATA *next;
struct CACHED_NIDATA *previous;
const char *pathname; /* not used */
@ -55,7 +59,8 @@ struct CACHED_NIDATA {
ntfs_inode *ni;
} ;
struct CACHED_LOOKUP {
struct CACHED_LOOKUP
{
struct CACHED_LOOKUP *next;
struct CACHED_LOOKUP *previous;
const char *name;
@ -65,7 +70,8 @@ struct CACHED_LOOKUP {
u64 inum;
} ;
enum {
enum
{
CACHE_FREE = 1,
CACHE_NOHASH = 2
} ;
@ -75,12 +81,14 @@ typedef int (*cache_compare)(const struct CACHED_GENERIC *cached,
typedef void ( *cache_free )( const struct CACHED_GENERIC *cached );
typedef int ( *cache_hash )( const struct CACHED_GENERIC *cached );
struct HASH_ENTRY {
struct HASH_ENTRY
{
struct HASH_ENTRY *next;
struct CACHED_GENERIC *entry;
} ;
struct CACHE_HEADER {
struct CACHE_HEADER
{
const char *name;
struct CACHED_GENERIC *most_recent_entry;
struct CACHED_GENERIC *oldest_entry;

View File

@ -45,23 +45,27 @@
#define CACHE_FREE UINT_MAX
NTFS_CACHE* _NTFS_cache_constructor (unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, sec_t sectorSize) {
NTFS_CACHE* _NTFS_cache_constructor ( unsigned int numberOfPages, unsigned int sectorsPerPage, const DISC_INTERFACE* discInterface, sec_t endOfPartition, sec_t sectorSize )
{
NTFS_CACHE* cache;
unsigned int i;
NTFS_CACHE_ENTRY* cacheEntries;
if ( numberOfPages == 0 || sectorsPerPage == 0 ) return NULL;
if (numberOfPages < 4) {
if ( numberOfPages < 4 )
{
numberOfPages = 4;
}
if (sectorsPerPage < 32) {
if ( sectorsPerPage < 32 )
{
sectorsPerPage = 32;
}
cache = ( NTFS_CACHE* ) ntfs_alloc ( sizeof( NTFS_CACHE ) );
if (cache == NULL) {
if ( cache == NULL )
{
return NULL;
}
@ -73,12 +77,14 @@ NTFS_CACHE* _NTFS_cache_constructor (unsigned int numberOfPages, unsigned int se
cacheEntries = ( NTFS_CACHE_ENTRY* ) ntfs_alloc ( sizeof( NTFS_CACHE_ENTRY ) * numberOfPages );
if (cacheEntries == NULL) {
if ( cacheEntries == NULL )
{
ntfs_free ( cache );
return NULL;
}
for (i = 0; i < numberOfPages; i++) {
for ( i = 0; i < numberOfPages; i++ )
{
cacheEntries[i].sector = CACHE_FREE;
cacheEntries[i].count = 0;
cacheEntries[i].last_access = 0;
@ -91,7 +97,8 @@ NTFS_CACHE* _NTFS_cache_constructor (unsigned int numberOfPages, unsigned int se
return cache;
}
void _NTFS_cache_destructor (NTFS_CACHE* cache) {
void _NTFS_cache_destructor ( NTFS_CACHE* cache )
{
unsigned int i;
if ( cache == NULL ) return;
@ -100,7 +107,8 @@ void _NTFS_cache_destructor (NTFS_CACHE* cache) {
_NTFS_cache_flush( cache );
// Free memory in reverse allocation order
for (i = 0; i < cache->numberOfPages; i++) {
for ( i = 0; i < cache->numberOfPages; i++ )
{
ntfs_free ( cache->cacheEntries[i].cache );
}
ntfs_free ( cache->cacheEntries );
@ -109,7 +117,8 @@ void _NTFS_cache_destructor (NTFS_CACHE* cache) {
static u32 accessCounter = 0;
static u32 accessTime(){
static u32 accessTime()
{
accessCounter++;
return accessCounter;
}
@ -125,20 +134,24 @@ static NTFS_CACHE_ENTRY* _NTFS_cache_getPage(NTFS_CACHE *cache,sec_t sector)
unsigned int oldUsed = 0;
unsigned int oldAccess = UINT_MAX;
for(i=0;i<numberOfPages;i++) {
if(sector>=cacheEntries[i].sector && sector<(cacheEntries[i].sector + cacheEntries[i].count)) {
for ( i = 0; i < numberOfPages; i++ )
{
if ( sector >= cacheEntries[i].sector && sector < ( cacheEntries[i].sector + cacheEntries[i].count ) )
{
cacheEntries[i].last_access = accessTime();
return &( cacheEntries[i] );
}
if(foundFree==false && (cacheEntries[i].sector==CACHE_FREE || cacheEntries[i].last_access<oldAccess)) {
if ( foundFree == false && ( cacheEntries[i].sector == CACHE_FREE || cacheEntries[i].last_access < oldAccess ) )
{
if ( cacheEntries[i].sector == CACHE_FREE ) foundFree = true;
oldUsed = i;
oldAccess = cacheEntries[i].last_access;
}
}
if(foundFree==false && cacheEntries[oldUsed].dirty==true) {
if ( foundFree == false && cacheEntries[oldUsed].dirty == true )
{
if ( !cache->disc->writeSectors( cacheEntries[oldUsed].sector, cacheEntries[oldUsed].count, cacheEntries[oldUsed].cache ) ) return NULL;
cacheEntries[oldUsed].dirty = false;
}
@ -155,7 +168,8 @@ static NTFS_CACHE_ENTRY* _NTFS_cache_getPage(NTFS_CACHE *cache,sec_t sector)
return &( cacheEntries[oldUsed] );
}
static NTFS_CACHE_ENTRY* _NTFS_cache_findPage(NTFS_CACHE *cache, sec_t sector, sec_t count) {
static NTFS_CACHE_ENTRY* _NTFS_cache_findPage( NTFS_CACHE *cache, sec_t sector, sec_t count )
{
unsigned int i;
NTFS_CACHE_ENTRY* cacheEntries = cache->cacheEntries;
@ -163,16 +177,22 @@ static NTFS_CACHE_ENTRY* _NTFS_cache_findPage(NTFS_CACHE *cache, sec_t sector, s
NTFS_CACHE_ENTRY *entry = NULL;
sec_t lowest = UINT_MAX;
for(i=0;i<numberOfPages;i++) {
if (cacheEntries[i].sector != CACHE_FREE) {
for ( i = 0; i < numberOfPages; i++ )
{
if ( cacheEntries[i].sector != CACHE_FREE )
{
bool intersect;
if (sector > cacheEntries[i].sector) {
if ( sector > cacheEntries[i].sector )
{
intersect = sector - cacheEntries[i].sector < cacheEntries[i].count;
} else {
}
else
{
intersect = cacheEntries[i].sector - sector < count;
}
if ( intersect && (cacheEntries[i].sector < lowest)) {
if ( intersect && ( cacheEntries[i].sector < lowest ) )
{
lowest = cacheEntries[i].sector;
entry = &cacheEntries[i];
}
@ -189,7 +209,8 @@ bool _NTFS_cache_readSectors(NTFS_CACHE *cache,sec_t sector,sec_t numSectors,voi
NTFS_CACHE_ENTRY *entry;
uint8_t *dest = buffer;
while(numSectors>0) {
while ( numSectors > 0 )
{
entry = _NTFS_cache_getPage( cache, sector );
if ( entry == NULL ) return false;
@ -227,11 +248,13 @@ bool _NTFS_cache_readPartialSector (NTFS_CACHE* cache, void* buffer, sec_t secto
return true;
}
bool _NTFS_cache_readLittleEndianValue (NTFS_CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes) {
bool _NTFS_cache_readLittleEndianValue ( NTFS_CACHE* cache, uint32_t *value, sec_t sector, unsigned int offset, int num_bytes )
{
uint8_t buf[4];
if ( !_NTFS_cache_readPartialSector( cache, buf, sector, offset, num_bytes ) ) return false;
switch(num_bytes) {
switch ( num_bytes )
{
case 1: *value = buf[0]; break;
case 2: *value = u8array_to_u16( buf, 0 ); break;
case 4: *value = u8array_to_u32( buf, 0 ); break;
@ -261,10 +284,12 @@ bool _NTFS_cache_writePartialSector (NTFS_CACHE* cache, const void* buffer, sec_
return true;
}
bool _NTFS_cache_writeLittleEndianValue (NTFS_CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int size) {
bool _NTFS_cache_writeLittleEndianValue ( NTFS_CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int size )
{
uint8_t buf[4] = {0, 0, 0, 0};
switch(size) {
switch ( size )
{
case 1: buf[0] = value; break;
case 2: u16_to_u8array( buf, 0, value ); break;
case 4: u32_to_u8array( buf, 0, value ); break;
@ -307,9 +332,11 @@ bool _NTFS_cache_writeSectors (NTFS_CACHE* cache, sec_t sector, sec_t numSectors
{
entry = _NTFS_cache_findPage( cache, sector, numSectors );
if(entry!=NULL) {
if ( entry != NULL )
{
if ( entry->sector > sector) {
if ( entry->sector > sector )
{
secs_to_write = entry->sector - sector;
@ -332,7 +359,9 @@ bool _NTFS_cache_writeSectors (NTFS_CACHE* cache, sec_t sector, sec_t numSectors
entry->dirty = true;
} else {
}
else
{
cache->disc->writeSectors( sector, numSectors, src );
numSectors = 0;
}
@ -343,13 +372,17 @@ bool _NTFS_cache_writeSectors (NTFS_CACHE* cache, sec_t sector, sec_t numSectors
/*
Flushes all dirty pages to disc, clearing the dirty flag.
*/
bool _NTFS_cache_flush (NTFS_CACHE* cache) {
bool _NTFS_cache_flush ( NTFS_CACHE* cache )
{
unsigned int i;
if ( cache == NULL ) return true;
for (i = 0; i < cache->numberOfPages; i++) {
if (cache->cacheEntries[i].dirty) {
if (!cache->disc->writeSectors (cache->cacheEntries[i].sector, cache->cacheEntries[i].count, cache->cacheEntries[i].cache)) {
for ( i = 0; i < cache->numberOfPages; i++ )
{
if ( cache->cacheEntries[i].dirty )
{
if ( !cache->disc->writeSectors ( cache->cacheEntries[i].sector, cache->cacheEntries[i].count, cache->cacheEntries[i].cache ) )
{
return false;
}
}
@ -359,13 +392,15 @@ bool _NTFS_cache_flush (NTFS_CACHE* cache) {
return true;
}
void _NTFS_cache_invalidate (NTFS_CACHE* cache) {
void _NTFS_cache_invalidate ( NTFS_CACHE* cache )
{
unsigned int i;
if ( cache == NULL )
return;
_NTFS_cache_flush( cache );
for (i = 0; i < cache->numberOfPages; i++) {
for ( i = 0; i < cache->numberOfPages; i++ )
{
cache->cacheEntries[i].sector = CACHE_FREE;
cache->cacheEntries[i].last_access = 0;
cache->cacheEntries[i].count = 0;

View File

@ -46,7 +46,8 @@
#include <ogc/disc_io.h>
#include <gccore.h>
typedef struct {
typedef struct
{
sec_t sector;
unsigned int count;
u64 last_access;
@ -54,7 +55,8 @@ typedef struct {
u8* cache;
} NTFS_CACHE_ENTRY;
typedef struct {
typedef struct
{
const DISC_INTERFACE* disc;
sec_t endOfPartition;
unsigned int numberOfPages;

View File

@ -60,7 +60,8 @@ static int ntfs_collate_binary(ntfs_volume *vol __attribute__((unused)),
ntfs_log_trace( "Entering.\n" );
rc = memcmp( data1, data2, min( data1_len, data2_len ) );
if (!rc && (data1_len != data2_len)) {
if ( !rc && ( data1_len != data2_len ) )
{
if ( data1_len < data2_len )
rc = -1;
else
@ -90,7 +91,8 @@ static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)),
u32 d1, d2;
ntfs_log_trace( "Entering.\n" );
if (data1_len != data2_len || data1_len != 4) {
if ( data1_len != data2_len || data1_len != 4 )
{
ntfs_log_error( "data1_len or/and data2_len not equal to 4.\n" );
return NTFS_COLLATION_ERROR;
}
@ -98,7 +100,8 @@ static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)),
d2 = le32_to_cpup( data2 );
if ( d1 < d2 )
rc = -1;
else {
else
{
if ( d1 == d2 )
rc = 0;
else
@ -124,22 +127,26 @@ static int ntfs_collate_ntofs_ulongs(ntfs_volume *vol __attribute__((unused)),
u32 d1, d2;
ntfs_log_trace( "Entering.\n" );
if ((data1_len != data2_len) || (data1_len <= 0) || (data1_len & 3)) {
if ( ( data1_len != data2_len ) || ( data1_len <= 0 ) || ( data1_len & 3 ) )
{
ntfs_log_error( "data1_len or data2_len not valid\n" );
return NTFS_COLLATION_ERROR;
}
p1 = ( const le32* )data1;
p2 = ( const le32* )data2;
len = data1_len;
do {
do
{
d1 = le32_to_cpup( p1 );
p1++;
d2 = le32_to_cpup( p2 );
p2++;
} while ((d1 == d2) && ((len -= 4) > 0));
}
while ( ( d1 == d2 ) && ( ( len -= 4 ) > 0 ) );
if ( d1 < d2 )
rc = -1;
else {
else
{
if ( d1 == d2 )
rc = 0;
else
@ -171,7 +178,8 @@ static int ntfs_collate_ntofs_security_hash(ntfs_volume *vol __attribute__((unus
const le32 *p1, *p2;
ntfs_log_trace( "Entering.\n" );
if (data1_len != data2_len || data1_len != 8) {
if ( data1_len != data2_len || data1_len != 8 )
{
ntfs_log_error( "data1_len or/and data2_len not equal to 8.\n" );
return NTFS_COLLATION_ERROR;
}
@ -181,17 +189,20 @@ static int ntfs_collate_ntofs_security_hash(ntfs_volume *vol __attribute__((unus
d2 = le32_to_cpup( p2 );
if ( d1 < d2 )
rc = -1;
else {
else
{
if ( d1 > d2 )
rc = 1;
else {
else
{
p1++;
p2++;
d1 = le32_to_cpup( p1 );
d2 = le32_to_cpup( p2 );
if ( d1 < d2 )
rc = -1;
else {
else
{
if ( d1 > d2 )
rc = 1;
else
@ -246,7 +257,8 @@ COLLATE ntfs_get_collate_function(COLLATION_RULES cr)
{
COLLATE collate;
switch (cr) {
switch ( cr )
{
case COLLATION_BINARY :
collate = ntfs_collate_binary;
break;

View File

@ -41,23 +41,28 @@ int ffs(int x)
if ( !x )
return 0;
if (!(x & 0xffff)) {
if ( !( x & 0xffff ) )
{
x >>= 16;
r += 16;
}
if (!(x & 0xff)) {
if ( !( x & 0xff ) )
{
x >>= 8;
r += 8;
}
if (!(x & 0xf)) {
if ( !( x & 0xf ) )
{
x >>= 4;
r += 4;
}
if (!(x & 3)) {
if ( !( x & 3 ) )
{
x >>= 2;
r += 2;
}
if (!(x & 1)) {
if ( !( x & 1 ) )
{
x >>= 1;
r += 1;
}
@ -120,10 +125,12 @@ static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpa
#include <unistd.h>
#endif
int daemon(int nochdir, int noclose) {
int daemon( int nochdir, int noclose )
{
int fd;
switch (fork()) {
switch ( fork() )
{
case -1:
return ( -1 );
case 0:
@ -138,7 +145,8 @@ int daemon(int nochdir, int noclose) {
if ( !nochdir )
( void )chdir( "/" );
if (!noclose && (fd = open("/dev/null", O_RDWR, 0)) != -1) {
if ( !noclose && ( fd = open( "/dev/null", O_RDWR, 0 ) ) != -1 )
{
( void )dup2( fd, 0 );
( void )dup2( fd, 1 );
( void )dup2( fd, 2 );
@ -218,7 +226,8 @@ static const char rcsid[] = "$Id: compat.c,v 1.1.1.1.2.1 2008-08-16 15:17:44 jpa
*
* If *stringp is NULL, strsep returns NULL.
*/
char *strsep(char **stringp, const char *delim) {
char *strsep( char **stringp, const char *delim )
{
char *s;
const char *spanp;
int c, sc;
@ -226,11 +235,14 @@ char *strsep(char **stringp, const char *delim) {
if ( ( s = *stringp ) == NULL )
return ( NULL );
for (tok = s;;) {
for ( tok = s;; )
{
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
do
{
if ( ( sc = *spanp++ ) == c )
{
if ( c == 0 )
s = NULL;
else
@ -238,7 +250,8 @@ char *strsep(char **stringp, const char *delim) {
*stringp = s;
return ( tok );
}
} while (sc != 0);
}
while ( sc != 0 );
}
/* NOTREACHED */
}

File diff suppressed because it is too large Load Diff

View File

@ -47,18 +47,22 @@ void ntfs_debug_runlist_dump(const runlist_element *rl)
int i = 0;
const char *lcn_str[5] = { "LCN_HOLE ", "LCN_RL_NOT_MAPPED",
"LCN_ENOENT ", "LCN_EINVAL ",
"LCN_unknown " };
"LCN_unknown "
};
ntfs_log_debug( "NTFS-fs DEBUG: Dumping runlist (values in hex):\n" );
if (!rl) {
if ( !rl )
{
ntfs_log_debug( "Run list not present.\n" );
return;
}
ntfs_log_debug( "VCN LCN Run length\n" );
do {
do
{
LCN lcn = ( rl + i )->lcn;
if (lcn < (LCN)0) {
if ( lcn < ( LCN )0 )
{
int idx = -lcn - 1;
if ( idx > -LCN_EINVAL - 1 )
@ -67,12 +71,14 @@ void ntfs_debug_runlist_dump(const runlist_element *rl)
( long long )rl[i].vcn, lcn_str[idx],
( long long )rl[i].length,
rl[i].length ? "" : " (runlist end)" );
} else
}
else
ntfs_log_debug( "%-16lld %-16lld %-16lld%s\n",
( long long )rl[i].vcn, ( long long )rl[i].lcn,
( long long )rl[i].length,
rl[i].length ? "" : " (runlist end)" );
} while (rl[i++].length);
}
while ( rl[i++].length );
}
#endif

View File

@ -108,14 +108,17 @@ struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
{
struct ntfs_device *dev;
if (!name) {
if ( !name )
{
errno = EINVAL;
return NULL;
}
dev = ntfs_malloc( sizeof( struct ntfs_device ) );
if (dev) {
if (!(dev->d_name = strdup(name))) {
if ( dev )
{
if ( !( dev->d_name = strdup( name ) ) )
{
int eo = errno;
free( dev );
errno = eo;
@ -141,11 +144,13 @@ struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
*/
int ntfs_device_free( struct ntfs_device *dev )
{
if (!dev) {
if ( !dev )
{
errno = EINVAL;
return -1;
}
if (NDevOpen(dev)) {
if ( NDevOpen( dev ) )
{
errno = EBUSY;
return -1;
}
@ -180,7 +185,8 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
ntfs_log_trace( "pos %lld, count %lld\n", ( long long )pos, ( long long )count );
if (!b || count < 0 || pos < 0) {
if ( !b || count < 0 || pos < 0 )
{
errno = EINVAL;
return -1;
}
@ -189,7 +195,8 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
dops = dev->d_ops;
for (total = 0; count; count -= br, total += br) {
for ( total = 0; count; count -= br, total += br )
{
br = dops->pread( dev, ( char* )b + total, count, pos + total );
/* If everything ok, continue. */
if ( br > 0 )
@ -231,13 +238,15 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
ntfs_log_trace( "pos %lld, count %lld\n", ( long long )pos, ( long long )count );
if (!b || count < 0 || pos < 0) {
if ( !b || count < 0 || pos < 0 )
{
errno = EINVAL;
goto out;
}
if ( !count )
return 0;
if (NDevReadOnly(dev)) {
if ( NDevReadOnly( dev ) )
{
errno = EROFS;
goto out;
}
@ -245,7 +254,8 @@ s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
dops = dev->d_ops;
NDevSetDirty( dev );
for (total = 0; count; count -= written, total += written) {
for ( total = 0; count; count -= written, total += written )
{
written = dops->pwrite( dev, ( const char* )b + total, count,
pos + total );
/* If everything ok, continue. */
@ -299,7 +309,8 @@ s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count,
{
s64 br, i;
if (bksize & (bksize - 1) || bksize % NTFS_BLOCK_SIZE) {
if ( bksize & ( bksize - 1 ) || bksize % NTFS_BLOCK_SIZE )
{
errno = EINVAL;
return -1;
}
@ -356,19 +367,22 @@ s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
{
s64 written, i;
if (count < 0 || bksize % NTFS_BLOCK_SIZE) {
if ( count < 0 || bksize % NTFS_BLOCK_SIZE )
{
errno = EINVAL;
return -1;
}
if ( !count )
return 0;
/* Prepare data for writing. */
for (i = 0; i < count; ++i) {
for ( i = 0; i < count; ++i )
{
int err;
err = ntfs_mst_pre_write_fixup( ( NTFS_RECORD* )
( ( u8* )b + i * bksize ), bksize );
if (err < 0) {
if ( err < 0 )
{
/* Abort write at this position. */
if ( !i )
return err;
@ -403,11 +417,13 @@ s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count,
{
s64 br;
if (!vol || lcn < 0 || count < 0) {
if ( !vol || lcn < 0 || count < 0 )
{
errno = EINVAL;
return -1;
}
if (vol->nr_clusters < lcn + count) {
if ( vol->nr_clusters < lcn + count )
{
errno = ESPIPE;
ntfs_log_perror( "Trying to read outside of volume "
"(%lld < %lld)", ( long long )vol->nr_clusters,
@ -416,7 +432,8 @@ s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count,
}
br = ntfs_pread( vol->dev, lcn << vol->cluster_size_bits,
count << vol->cluster_size_bits, b );
if (br < 0) {
if ( br < 0 )
{
ntfs_log_perror( "Error reading cluster(s)" );
return br;
}
@ -439,11 +456,13 @@ s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
{
s64 bw;
if (!vol || lcn < 0 || count < 0) {
if ( !vol || lcn < 0 || count < 0 )
{
errno = EINVAL;
return -1;
}
if (vol->nr_clusters < lcn + count) {
if ( vol->nr_clusters < lcn + count )
{
errno = ESPIPE;
ntfs_log_perror( "Trying to write outside of volume "
"(%lld < %lld)", ( long long )vol->nr_clusters,
@ -455,7 +474,8 @@ s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
count << vol->cluster_size_bits, b );
else
bw = count << vol->cluster_size_bits;
if (bw < 0) {
if ( bw < 0 )
{
ntfs_log_perror( "Error writing cluster(s)" );
return bw;
}
@ -498,14 +518,16 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
{
s64 high, low;
if (!dev || block_size <= 0 || (block_size - 1) & block_size) {
if ( !dev || block_size <= 0 || ( block_size - 1 ) & block_size )
{
errno = EINVAL;
return -1;
}
#ifdef BLKGETSIZE64
{ u64 size;
if (dev->d_ops->ioctl(dev, BLKGETSIZE64, &size) >= 0) {
if ( dev->d_ops->ioctl( dev, BLKGETSIZE64, &size ) >= 0 )
{
ntfs_log_debug( "BLKGETSIZE64 nr bytes = %llu (0x%llx)\n",
( unsigned long long )size,
( unsigned long long )size );
@ -516,7 +538,8 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
#ifdef BLKGETSIZE
{ unsigned long size;
if (dev->d_ops->ioctl(dev, BLKGETSIZE, &size) >= 0) {
if ( dev->d_ops->ioctl( dev, BLKGETSIZE, &size ) >= 0 )
{
ntfs_log_debug( "BLKGETSIZE nr 512 byte blocks = %lu (0x%lx)\n",
size, size );
return ( s64 )size * 512 / block_size;
@ -526,7 +549,8 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
#ifdef FDGETPRM
{ struct floppy_struct this_floppy;
if (dev->d_ops->ioctl(dev, FDGETPRM, &this_floppy) >= 0) {
if ( dev->d_ops->ioctl( dev, FDGETPRM, &this_floppy ) >= 0 )
{
ntfs_log_debug( "FDGETPRM nr 512 byte blocks = %lu (0x%lx)\n",
( unsigned long )this_floppy.size,
( unsigned long )this_floppy.size );
@ -541,7 +565,8 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
low = 0LL;
for ( high = 1024LL; !ntfs_device_offset_valid( dev, high ); high <<= 1 )
low = high;
while (low < high - 1LL) {
while ( low < high - 1LL )
{
const s64 mid = ( low + high ) / 2;
if ( !ntfs_device_offset_valid( dev, mid ) )
@ -567,14 +592,16 @@ s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size)
*/
s64 ntfs_device_partition_start_sector_get( struct ntfs_device *dev )
{
if (!dev) {
if ( !dev )
{
errno = EINVAL;
return -1;
}
#ifdef HDIO_GETGEO
{ struct hd_geometry geo;
if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) {
if ( !dev->d_ops->ioctl( dev, HDIO_GETGEO, &geo ) )
{
ntfs_log_debug( "HDIO_GETGEO start_sect = %lu (0x%lx)\n",
geo.start, geo.start );
return geo.start;
@ -600,14 +627,16 @@ s64 ntfs_device_partition_start_sector_get(struct ntfs_device *dev)
*/
int ntfs_device_heads_get( struct ntfs_device *dev )
{
if (!dev) {
if ( !dev )
{
errno = EINVAL;
return -1;
}
#ifdef HDIO_GETGEO
{ struct hd_geometry geo;
if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) {
if ( !dev->d_ops->ioctl( dev, HDIO_GETGEO, &geo ) )
{
ntfs_log_debug( "HDIO_GETGEO heads = %u (0x%x)\n",
( unsigned )geo.heads,
( unsigned )geo.heads );
@ -634,14 +663,16 @@ int ntfs_device_heads_get(struct ntfs_device *dev)
*/
int ntfs_device_sectors_per_track_get( struct ntfs_device *dev )
{
if (!dev) {
if ( !dev )
{
errno = EINVAL;
return -1;
}
#ifdef HDIO_GETGEO
{ struct hd_geometry geo;
if (!dev->d_ops->ioctl(dev, HDIO_GETGEO, &geo)) {
if ( !dev->d_ops->ioctl( dev, HDIO_GETGEO, &geo ) )
{
ntfs_log_debug( "HDIO_GETGEO sectors_per_track = %u (0x%x)\n",
( unsigned )geo.sectors,
( unsigned )geo.sectors );
@ -668,7 +699,8 @@ int ntfs_device_sectors_per_track_get(struct ntfs_device *dev)
*/
int ntfs_device_sector_size_get( struct ntfs_device *dev )
{
if (!dev) {
if ( !dev )
{
errno = EINVAL;
return -1;
}
@ -676,7 +708,8 @@ int ntfs_device_sector_size_get(struct ntfs_device *dev)
{
int sect_size = 0;
if (!dev->d_ops->ioctl(dev, BLKSSZGET, &sect_size)) {
if ( !dev->d_ops->ioctl( dev, BLKSSZGET, &sect_size ) )
{
ntfs_log_debug( "BLKSSZGET sector size = %d bytes\n",
sect_size );
return sect_size;
@ -704,14 +737,16 @@ int ntfs_device_sector_size_get(struct ntfs_device *dev)
int ntfs_device_block_size_set( struct ntfs_device *dev,
int block_size __attribute__( ( unused ) ) )
{
if (!dev) {
if ( !dev )
{
errno = EINVAL;
return -1;
}
#ifdef BLKBSZSET
{
size_t s_block_size = block_size;
if (!dev->d_ops->ioctl(dev, BLKBSZSET, &s_block_size)) {
if ( !dev->d_ops->ioctl( dev, BLKBSZSET, &s_block_size ) )
{
ntfs_log_debug( "Used BLKBSZSET to set block size to "
"%d bytes.\n", block_size );
return 0;

View File

@ -36,7 +36,8 @@
*
* Defined bits for the state field in the ntfs_device structure.
*/
typedef enum {
typedef enum
{
ND_Open, /* 1: Device is open. */
ND_ReadOnly, /* 1: Device is read-only. */
ND_Dirty, /* 1: Device is dirty, needs sync. */
@ -69,7 +70,8 @@ typedef enum {
* The ntfs device structure defining all operations needed to access the low
* level device underlying the ntfs volume.
*/
struct ntfs_device {
struct ntfs_device
{
struct ntfs_device_operations *d_ops; /* Device operations. */
unsigned long d_state; /* State of the device. */
char *d_name; /* Name of device. */
@ -85,7 +87,8 @@ struct stat;
* The ntfs device operations defining all operations that can be performed on
* the low level device described by an ntfs device structure.
*/
struct ntfs_device_operations {
struct ntfs_device_operations
{
int ( *open )( struct ntfs_device *dev, int flags );
int ( *close )( struct ntfs_device *dev );
s64 ( *seek )( struct ntfs_device *dev, s64 offset, int whence );

View File

@ -45,7 +45,8 @@
/**
* struct hd_geometry -
*/
struct hd_geometry {
struct hd_geometry
{
unsigned char heads;
unsigned char sectors;
unsigned short cylinders;

File diff suppressed because it is too large Load Diff

View File

@ -60,7 +60,8 @@
#ifdef HAVE_SETXATTR /* extended attributes interface required */
static ntfschar logged_utility_stream_name[] = {
static ntfschar logged_utility_stream_name[] =
{
const_cpu_to_le16( '$' ),
const_cpu_to_le16( 'E' ),
const_cpu_to_le16( 'F' ),
@ -78,32 +79,43 @@ int ntfs_get_efs_info(ntfs_inode *ni, char *value, size_t size)
EFS_ATTR_HEADER *efs_info;
s64 attr_size = 0;
if (ni) {
if (ni->flags & FILE_ATTR_ENCRYPTED) {
if ( ni )
{
if ( ni->flags & FILE_ATTR_ENCRYPTED )
{
efs_info = ( EFS_ATTR_HEADER* )ntfs_attr_readall( ni,
AT_LOGGED_UTILITY_STREAM, ( ntfschar* )NULL, 0,
&attr_size );
if ( efs_info
&& (le32_to_cpu(efs_info->length) == attr_size)) {
if (attr_size <= (s64)size) {
&& ( le32_to_cpu( efs_info->length ) == attr_size ) )
{
if ( attr_size <= ( s64 )size )
{
if ( value )
memcpy( value, efs_info, attr_size );
else {
else
{
errno = EFAULT;
attr_size = 0;
}
} else
if (size) {
}
else if ( size )
{
errno = ERANGE;
attr_size = 0;
}
free ( efs_info );
} else {
if (efs_info) {
}
else
{
if ( efs_info )
{
free( efs_info );
ntfs_log_error( "Bad efs_info for inode %lld\n",
( long long )ni->mft_no );
} else {
}
else
{
ntfs_log_error( "Could not get efsinfo"
" for inode %lld\n",
( long long )ni->mft_no );
@ -111,7 +123,9 @@ int ntfs_get_efs_info(ntfs_inode *ni, char *value, size_t size)
errno = EIO;
attr_size = 0;
}
} else {
}
else
{
errno = ENODATA;
ntfs_log_trace( "Inode %lld is not encrypted\n",
( long long )ni->mft_no );
@ -145,45 +159,57 @@ static int fixup_loop(ntfs_inode *ni)
int res = 0;
maxcnt = 0;
do {
do
{
restart = FALSE;
ctx = ntfs_attr_get_search_ctx( ni, NULL );
if (!ctx) {
if ( !ctx )
{
ntfs_log_error( "Failed to get ctx for efs\n" );
res = -1;
}
cnt = 0;
while ( !restart && !res
&& !ntfs_attr_lookup( AT_DATA, NULL, 0,
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
cnt++;
a = ctx->attr;
na = ntfs_attr_open( ctx->ntfs_ino, AT_DATA,
( ntfschar* )( ( u8* )a + le16_to_cpu( a->name_offset ) ),
a->name_length );
if (!na) {
if ( !na )
{
ntfs_log_error( "can't open DATA Attribute\n" );
res = -1;
}
if (na && !(ctx->attr->flags & ATTR_IS_ENCRYPTED)) {
if ( na && !( ctx->attr->flags & ATTR_IS_ENCRYPTED ) )
{
if ( !NAttrNonResident( na )
&& ntfs_attr_make_non_resident(na, ctx)) {
&& ntfs_attr_make_non_resident( na, ctx ) )
{
/*
* ntfs_attr_make_non_resident fails if there
* is not enough space in the MFT record.
* When this happens, force making non-resident
* so that some other attribute is expelled.
*/
if (ntfs_attr_force_non_resident(na)) {
if ( ntfs_attr_force_non_resident( na ) )
{
res = -1;
} else {
}
else
{
/* make sure there is some progress */
if (cnt <= maxcnt) {
if ( cnt <= maxcnt )
{
errno = EIO;
ntfs_log_error( "Multiple failure"
" making non resident\n" );
res = -1;
} else {
}
else
{
ntfs_attr_put_search_ctx( ctx );
ctx = ( ntfs_attr_search_ctx* )NULL;
restart = TRUE;
@ -192,7 +218,8 @@ static int fixup_loop(ntfs_inode *ni)
}
}
if ( !restart && !res
&& ntfs_efs_fixup_attribute(ctx, na)) {
&& ntfs_efs_fixup_attribute( ctx, na ) )
{
ntfs_log_error( "Error in efs fixup of AT_DATA Attribute\n" );
res = -1;
}
@ -201,7 +228,8 @@ static int fixup_loop(ntfs_inode *ni)
ntfs_attr_close( na );
}
first = FALSE;
} while (restart && !res);
}
while ( restart && !res );
if ( ctx )
ntfs_attr_put_search_ctx( ctx );
return ( res );
@ -223,13 +251,18 @@ int ntfs_set_efs_info(ntfs_inode *ni, const char *value, size_t size,
const EFS_ATTR_HEADER *info_header;
res = 0;
if (ni && value && size) {
if (ni->flags & (FILE_ATTR_ENCRYPTED | FILE_ATTR_COMPRESSED)) {
if (ni->flags & FILE_ATTR_ENCRYPTED) {
if ( ni && value && size )
{
if ( ni->flags & ( FILE_ATTR_ENCRYPTED | FILE_ATTR_COMPRESSED ) )
{
if ( ni->flags & FILE_ATTR_ENCRYPTED )
{
ntfs_log_trace( "Inode %lld already encrypted\n",
( long long )ni->mft_no );
errno = EEXIST;
} else {
}
else
{
/*
* Possible problem : if encrypted file was
* restored in a compressed directory, it was
@ -244,13 +277,16 @@ int ntfs_set_efs_info(ntfs_inode *ni, const char *value, size_t size,
}
info_header = ( const EFS_ATTR_HEADER* )value;
/* make sure we get a likely efsinfo */
if (le32_to_cpu(info_header->length) != size) {
if ( le32_to_cpu( info_header->length ) != size )
{
errno = EINVAL;
return ( -1 );
}
if ( !ntfs_attr_exist( ni, AT_LOGGED_UTILITY_STREAM,
(ntfschar*)NULL,0)) {
if (!(flags & XATTR_REPLACE)) {
( ntfschar* )NULL, 0 ) )
{
if ( !( flags & XATTR_REPLACE ) )
{
/*
* no logged_utility_stream attribute : add one,
* apparently, this does not feed the new value in
@ -258,28 +294,36 @@ int ntfs_set_efs_info(ntfs_inode *ni, const char *value, size_t size,
res = ntfs_attr_add( ni, AT_LOGGED_UTILITY_STREAM,
logged_utility_stream_name, 4,
( u8* )NULL, ( s64 )size );
} else {
}
else
{
errno = ENODATA;
res = -1;
}
} else {
}
else
{
errno = EEXIST;
res = -1;
}
if (!res) {
if ( !res )
{
/*
* open and update the existing efs data
*/
na = ntfs_attr_open( ni, AT_LOGGED_UTILITY_STREAM,
logged_utility_stream_name, 4 );
if (na) {
if ( na )
{
/* resize attribute */
res = ntfs_attr_truncate( na, ( s64 )size );
/* overwrite value if any */
if (!res && value) {
if ( !res && value )
{
written = ( int )ntfs_attr_pwrite( na,
( s64 )0, ( s64 )size, value );
if (written != (s64)size) {
if ( written != ( s64 )size )
{
ntfs_log_error( "Failed to "
"update efs data\n" );
errno = EIO;
@ -287,12 +331,15 @@ int ntfs_set_efs_info(ntfs_inode *ni, const char *value, size_t size,
}
}
ntfs_attr_close( na );
} else
}
else
res = -1;
}
if (!res) {
if ( !res )
{
/* Don't handle AT_DATA Attribute(s) if inode is a directory */
if (!(ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
if ( !( ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ) )
{
/* iterate over AT_DATA attributes */
/* set encrypted flag, truncate attribute to match padding bytes */
@ -303,7 +350,9 @@ int ntfs_set_efs_info(ntfs_inode *ni, const char *value, size_t size,
NInoSetDirty( ni );
NInoFileNameSetDirty( ni );
}
} else {
}
else
{
errno = EINVAL;
res = -1;
}
@ -330,24 +379,31 @@ int ntfs_efs_fixup_attribute(ntfs_attr_search_ctx *ctx, ntfs_attr *na)
ntfs_inode *ni;
BOOL close_ctx = FALSE;
if (!na) {
if ( !na )
{
ntfs_log_error( "no na specified for efs_fixup_attribute\n" );
goto err_out;
}
if (!ctx) {
if ( !ctx )
{
ctx = ntfs_attr_get_search_ctx( na->ni, NULL );
if (!ctx) {
if ( !ctx )
{
ntfs_log_error( "Failed to get ctx for efs\n" );
goto err_out;
}
close_ctx = TRUE;
if ( ntfs_attr_lookup( AT_DATA, na->name, na->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
ntfs_log_error( "attr lookup for AT_DATA attribute failed in efs fixup\n" );
goto err_out;
}
} else {
if (!NAttrNonResident(na)) {
}
else
{
if ( !NAttrNonResident( na ) )
{
ntfs_log_error( "Cannot make non resident"
" when a context has been allocated\n" );
goto err_out;
@ -356,19 +412,23 @@ int ntfs_efs_fixup_attribute(ntfs_attr_search_ctx *ctx, ntfs_attr *na)
/* no extra bytes are added to void attributes */
oldsize = na->data_size;
if (oldsize) {
if ( oldsize )
{
/* make sure size is valid for a raw encrypted stream */
if ((oldsize & 511) != 2) {
if ( ( oldsize & 511 ) != 2 )
{
ntfs_log_error( "Bad raw encrypted stream\n" );
goto err_out;
}
/* read padding length from last two bytes of attribute */
if (ntfs_attr_pread(na, oldsize - 2, 2, &appended_bytes) != 2) {
if ( ntfs_attr_pread( na, oldsize - 2, 2, &appended_bytes ) != 2 )
{
ntfs_log_error( "Error reading padding length\n" );
goto err_out;
}
padding_length = le16_to_cpu( appended_bytes );
if (padding_length > 511 || padding_length > na->data_size-2) {
if ( padding_length > 511 || padding_length > na->data_size - 2 )
{
errno = EINVAL;
ntfs_log_error( "invalid padding length %d for data_size %lld\n",
padding_length, ( long long )oldsize );
@ -380,11 +440,13 @@ int ntfs_efs_fixup_attribute(ntfs_attr_search_ctx *ctx, ntfs_attr *na)
* for the last two bytes, but do not truncate to new size
* to avoid losing useful data
*/
if (ntfs_attr_truncate(na, oldsize - 2)) {
if ( ntfs_attr_truncate( na, oldsize - 2 ) )
{
ntfs_log_error( "Error truncating attribute\n" );
goto err_out;
}
} else
}
else
newsize = 0;
/*
@ -394,12 +456,16 @@ int ntfs_efs_fixup_attribute(ntfs_attr_search_ctx *ctx, ntfs_attr *na)
* resident.
*/
if ( !NAttrNonResident( na )
&& ntfs_attr_make_non_resident(na, ctx)) {
&& ntfs_attr_make_non_resident( na, ctx ) )
{
if ( !close_ctx
|| ntfs_attr_force_non_resident(na)) {
|| ntfs_attr_force_non_resident( na ) )
{
ntfs_log_error( "Error making DATA attribute non-resident\n" );
goto err_out;
} else {
}
else
{
/*
* must reinitialize context after forcing
* non-resident. We need a context for updating
@ -408,14 +474,16 @@ int ntfs_efs_fixup_attribute(ntfs_attr_search_ctx *ctx, ntfs_attr *na)
*/
ntfs_attr_reinit_search_ctx( ctx );
if ( ntfs_attr_lookup( AT_DATA, na->name, na->name_len,
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
ntfs_log_error( "attr lookup for AT_DATA attribute failed in efs fixup\n" );
goto err_out;
}
}
}
ni = na->ni;
if (!na->name_len) {
if ( !na->name_len )
{
ni->data_size = newsize;
ni->allocated_size = na->allocated_size;
}

View File

@ -80,32 +80,37 @@ static int ntfs_device_gekko_io_open(struct ntfs_device *dev, int flags)
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return -1;
}
// Get the device interface
const DISC_INTERFACE* interface = fd->interface;
if (!interface) {
if ( !interface )
{
errno = ENODEV;
return -1;
}
// Start the device interface and ensure that it is inserted
if (!interface->startup()) {
if ( !interface->startup() )
{
ntfs_log_perror( "device failed to start\n" );
errno = EIO;
return -1;
}
if (!interface->isInserted()) {
if ( !interface->isInserted() )
{
ntfs_log_perror( "device media is not inserted\n" );
errno = EIO;
return -1;
}
// Check that the device isn't already open (used by another volume?)
if (NDevOpen(dev)) {
if ( NDevOpen( dev ) )
{
ntfs_log_perror( "device is busy (already open)\n" );
errno = EBUSY;
return -1;
@ -113,12 +118,16 @@ static int ntfs_device_gekko_io_open(struct ntfs_device *dev, int flags)
// Check that there is a valid NTFS boot sector at the start of the device
NTFS_BOOT_SECTOR boot;
if (interface->readSectors(fd->startSector, 1, &boot)) {
if (!ntfs_boot_sector_is_ntfs(&boot)) {
if ( interface->readSectors( fd->startSector, 1, &boot ) )
{
if ( !ntfs_boot_sector_is_ntfs( &boot ) )
{
errno = EINVALPART;
return -1;
}
} else {
}
else
{
ntfs_log_perror( "read failure @ sector %d\n", fd->startSector );
errno = EIO;
return -1;
@ -133,7 +142,8 @@ static int ntfs_device_gekko_io_open(struct ntfs_device *dev, int flags)
fd->ino = le64_to_cpu( boot.volume_serial_number );
// Mark the device as read-only (if required)
if (flags & O_RDONLY) {
if ( flags & O_RDONLY )
{
NDevSetReadOnly( dev );
}
@ -156,13 +166,15 @@ static int ntfs_device_gekko_io_close(struct ntfs_device *dev)
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return -1;
}
// Check that the device is actually open
if (!NDevOpen(dev)) {
if ( !NDevOpen( dev ) )
{
ntfs_log_perror( "device is not open\n" );
errno = EIO;
return -1;
@ -173,7 +185,8 @@ static int ntfs_device_gekko_io_close(struct ntfs_device *dev)
NDevClearBlock( dev );
// Flush the device (if dirty and not read-only)
if (NDevDirty(dev) && !NDevReadOnly(dev)) {
if ( NDevDirty( dev ) && !NDevReadOnly( dev ) )
{
ntfs_log_debug( "device is dirty, will now sync\n" );
// ...?
@ -184,7 +197,8 @@ static int ntfs_device_gekko_io_close(struct ntfs_device *dev)
}
// Flush and destroy the cache (if required)
if (fd->cache) {
if ( fd->cache )
{
_NTFS_cache_flush( fd->cache );
_NTFS_cache_destructor( fd->cache );
}
@ -211,13 +225,15 @@ static s64 ntfs_device_gekko_io_seek(struct ntfs_device *dev, s64 offset, int wh
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return -1;
}
// Set the current position on the device (in bytes)
switch(whence) {
switch ( whence )
{
case SEEK_SET: fd->pos = MIN( MAX( offset, 0 ), fd->len ); break;
case SEEK_CUR: fd->pos = MIN( MAX( fd->pos + offset, 0 ), fd->len ); break;
case SEEK_END: fd->pos = MIN( MAX( fd->len + offset, 0 ), fd->len ); break;
@ -267,14 +283,16 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return -1;
}
// Get the device interface
const DISC_INTERFACE* interface = fd->interface;
if (!interface) {
if ( !interface )
{
errno = ENODEV;
return -1;
}
@ -294,20 +312,24 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
u8 *buffer = NULL;
// Determine the range of sectors required for this read
if (offset > 0) {
if ( offset > 0 )
{
sec_start += ( sec_t ) floor( ( f64 ) offset / ( f64 ) fd->sectorSize );
}
if (buffer_offset+count > fd->sectorSize) {
if ( buffer_offset + count > fd->sectorSize )
{
sec_count = ( sec_t ) ceil( ( f64 ) ( buffer_offset + count ) / ( f64 ) fd->sectorSize );
}
// If this read happens to be on the sector boundaries then do the read straight into the destination buffer
if((buffer_offset == 0) && (count % fd->sectorSize == 0)) {
if ( ( buffer_offset == 0 ) && ( count % fd->sectorSize == 0 ) )
{
// Read from the device
ntfs_log_trace( "direct read from sector %d (%d sector(s) long)\n", sec_start, sec_count );
if (!ntfs_device_gekko_io_readsectors(dev, sec_start, sec_count, buf)) {
if ( !ntfs_device_gekko_io_readsectors( dev, sec_start, sec_count, buf ) )
{
ntfs_log_perror( "direct read failure @ sector %d (%d sector(s) long)\n", sec_start, sec_count );
errno = EIO;
return -1;
@ -320,7 +342,8 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
// Allocate a buffer to hold the read data
buffer = ( u8* )ntfs_alloc( sec_count * fd->sectorSize );
if (!buffer) {
if ( !buffer )
{
errno = ENOMEM;
return -1;
}
@ -328,7 +351,8 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
// Read from the device
ntfs_log_trace( "buffered read from sector %d (%d sector(s) long)\n", sec_start, sec_count );
ntfs_log_trace( "count: %d sec_count:%d fd->sectorSize: %d )\n", ( u32 )count, ( u32 )sec_count, ( u32 )fd->sectorSize );
if (!ntfs_device_gekko_io_readsectors(dev, sec_start, sec_count, buffer)) {
if ( !ntfs_device_gekko_io_readsectors( dev, sec_start, sec_count, buffer ) )
{
ntfs_log_perror( "buffered read failure @ sector %d (%d sector(s) long)\n", sec_start, sec_count );
ntfs_free( buffer );
errno = EIO;
@ -353,25 +377,29 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return -1;
}
// Get the device interface
const DISC_INTERFACE* interface = fd->interface;
if (!interface) {
if ( !interface )
{
errno = ENODEV;
return -1;
}
// Check that the device can be written to
if (NDevReadOnly(dev)) {
if ( NDevReadOnly( dev ) )
{
errno = EROFS;
return -1;
}
if(count < 0 || offset < 0) {
if ( count < 0 || offset < 0 )
{
errno = EROFS;
return -1;
}
@ -385,10 +413,12 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
u8 *buffer = NULL;
// Determine the range of sectors required for this write
if (offset > 0) {
if ( offset > 0 )
{
sec_start += ( sec_t ) floor( ( f64 ) offset / ( f64 ) fd->sectorSize );
}
if ((buffer_offset+count) > fd->sectorSize) {
if ( ( buffer_offset + count ) > fd->sectorSize )
{
sec_count = ( sec_t ) ceil( ( f64 ) ( buffer_offset + count ) / ( f64 ) fd->sectorSize );
}
@ -397,7 +427,8 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
{
// Write to the device
ntfs_log_trace( "direct write to sector %d (%d sector(s) long)\n", sec_start, sec_count );
if (!ntfs_device_gekko_io_writesectors(dev, sec_start, sec_count, buf)) {
if ( !ntfs_device_gekko_io_writesectors( dev, sec_start, sec_count, buf ) )
{
ntfs_log_perror( "direct write failure @ sector %d (%d sector(s) long)\n", sec_start, sec_count );
errno = EIO;
return -1;
@ -408,7 +439,8 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
{
// Allocate a buffer to hold the write data
buffer = ( u8 * ) ntfs_alloc( sec_count * fd->sectorSize );
if (!buffer) {
if ( !buffer )
{
errno = ENOMEM;
return -1;
}
@ -417,7 +449,8 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
// we just read in the buffer edges where the data overlaps with the rest of the disc
if ( buffer_offset != 0 )
{
if (!ntfs_device_gekko_io_readsectors(dev, sec_start, 1, buffer)) {
if ( !ntfs_device_gekko_io_readsectors( dev, sec_start, 1, buffer ) )
{
ntfs_log_perror( "read failure @ sector %d\n", sec_start );
ntfs_free( buffer );
errno = EIO;
@ -426,7 +459,8 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
}
if ( ( buffer_offset + count ) % fd->sectorSize != 0 )
{
if (!ntfs_device_gekko_io_readsectors(dev, sec_start + sec_count - 1, 1, buffer + ((sec_count-1) * fd->sectorSize))) {
if ( !ntfs_device_gekko_io_readsectors( dev, sec_start + sec_count - 1, 1, buffer + ( ( sec_count - 1 ) * fd->sectorSize ) ) )
{
ntfs_log_perror( "read failure @ sector %d\n", sec_start + sec_count - 1 );
ntfs_free( buffer );
errno = EIO;
@ -439,7 +473,8 @@ static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset,
// Write to the device
ntfs_log_trace( "buffered write to sector %d (%d sector(s) long)\n", sec_start, sec_count );
if (!ntfs_device_gekko_io_writesectors(dev, sec_start, sec_count, buffer)) {
if ( !ntfs_device_gekko_io_writesectors( dev, sec_start, sec_count, buffer ) )
{
ntfs_log_perror( "buffered write failure @ sector %d\n", sec_start );
ntfs_free( buffer );
errno = EIO;
@ -460,7 +495,8 @@ static bool ntfs_device_gekko_io_readsectors(struct ntfs_device *dev, sec_t sect
{
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return false;
}
@ -477,7 +513,8 @@ static bool ntfs_device_gekko_io_writesectors(struct ntfs_device *dev, sec_t sec
{
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return false;
}
@ -500,7 +537,8 @@ static int ntfs_device_gekko_io_sync(struct ntfs_device *dev)
ntfs_log_trace( "dev %p\n", dev );
// Check that the device can be written to
if (NDevReadOnly(dev)) {
if ( NDevReadOnly( dev ) )
{
errno = EROFS;
return -1;
}
@ -509,8 +547,10 @@ static int ntfs_device_gekko_io_sync(struct ntfs_device *dev)
NDevClearDirty( dev );
// Flush any sectors in the disc cache (if required)
if (fd->cache) {
if (!_NTFS_cache_flush(fd->cache)) {
if ( fd->cache )
{
if ( !_NTFS_cache_flush( fd->cache ) )
{
errno = EIO;
return -1;
}
@ -528,7 +568,8 @@ static int ntfs_device_gekko_io_stat(struct ntfs_device *dev, struct stat *buf)
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return -1;
}
@ -565,17 +606,20 @@ static int ntfs_device_gekko_io_ioctl(struct ntfs_device *dev, int request, void
// Get the device driver descriptor
gekko_fd *fd = DEV_FD( dev );
if (!fd) {
if ( !fd )
{
errno = EBADF;
return -1;
}
// Figure out which i/o control was requested
switch (request) {
switch ( request )
{
// Get block device size (sectors)
#if defined(BLKGETSIZE)
case BLKGETSIZE: {
case BLKGETSIZE:
{
*( u32* )argp = fd->sectorCount;
return 0;
}
@ -583,7 +627,8 @@ static int ntfs_device_gekko_io_ioctl(struct ntfs_device *dev, int request, void
// Get block device size (bytes)
#if defined(BLKGETSIZE64)
case BLKGETSIZE64: {
case BLKGETSIZE64:
{
*( u64* )argp = ( fd->sectorCount * fd->sectorSize );
return 0;
}
@ -591,7 +636,8 @@ static int ntfs_device_gekko_io_ioctl(struct ntfs_device *dev, int request, void
// Get hard drive geometry
#if defined(HDIO_GETGEO)
case HDIO_GETGEO: {
case HDIO_GETGEO:
{
struct hd_geometry *geo = ( struct hd_geometry* )argp;
geo->sectors = 0;
geo->heads = 0;
@ -603,7 +649,8 @@ static int ntfs_device_gekko_io_ioctl(struct ntfs_device *dev, int request, void
// Get block device sector size (bytes)
#if defined(BLKSSZGET)
case BLKSSZGET: {
case BLKSSZGET:
{
*( int* )argp = fd->sectorSize;
return 0;
}
@ -611,7 +658,8 @@ static int ntfs_device_gekko_io_ioctl(struct ntfs_device *dev, int request, void
// Set block device block size (bytes)
#if defined(BLKBSZSET)
case BLKBSZSET: {
case BLKBSZSET:
{
int sectorSize = *( int* )argp;
fd->sectorSize = sectorSize;
return 0;
@ -619,7 +667,8 @@ static int ntfs_device_gekko_io_ioctl(struct ntfs_device *dev, int request, void
#endif
// Unimplemented ioctrl
default: {
default:
{
ntfs_log_perror( "Unimplemented ioctrl %i\n", request );
errno = EOPNOTSUPP;
return -1;
@ -633,7 +682,8 @@ static int ntfs_device_gekko_io_ioctl(struct ntfs_device *dev, int request, void
/**
* Device operations for working with gekko style devices and files.
*/
struct ntfs_device_operations ntfs_device_gekko_io_ops = {
struct ntfs_device_operations ntfs_device_gekko_io_ops =
{
.open = ntfs_device_gekko_io_open,
.close = ntfs_device_gekko_io_close,
.seek = ntfs_device_gekko_io_seek,

View File

@ -33,7 +33,8 @@
/**
* gekko_fd - Gekko device driver descriptor
*/
typedef struct _gekko_fd {
typedef struct _gekko_fd
{
const DISC_INTERFACE* interface; /* Device disc interface */
sec_t startSector; /* LBA of partition start */
sec_t hiddenSectors; /* LBA offset to true partition start (as described by boot sector) */

View File

@ -88,7 +88,8 @@ static int ntfs_ib_write(ntfs_index_context *icx, INDEX_BLOCK *ib)
ret = ntfs_attr_mst_pwrite( icx->ia_na, ntfs_ib_vcn_to_pos( icx, vcn ),
1, icx->block_size, ib );
if (ret != 1) {
if ( ret != 1 )
{
ntfs_log_perror( "Failed to write index block %lld, inode %llu",
( long long )vcn, ( unsigned long long )icx->ni->mft_no );
return STATUS_ERROR;
@ -123,7 +124,8 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *ni,
ntfs_log_trace( "Entering\n" );
if (!ni) {
if ( !ni )
{
errno = EINVAL;
return NULL;
}
@ -131,7 +133,8 @@ ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *ni,
ni = ni->base_ni;
icx = ntfs_calloc( sizeof( ntfs_index_context ) );
if ( icx )
*icx = (ntfs_index_context) {
*icx = ( ntfs_index_context )
{
.ni = ni,
.name = name,
.name_len = name_len,
@ -149,8 +152,10 @@ static void ntfs_index_ctx_free(ntfs_index_context *icx)
if ( icx->actx )
ntfs_attr_put_search_ctx( icx->actx );
if (!icx->is_in_root) {
if (icx->ib_dirty) {
if ( !icx->is_in_root )
{
if ( icx->ib_dirty )
{
/* FIXME: Error handling!!! */
ntfs_ib_write( icx, icx->ib );
}
@ -184,7 +189,8 @@ void ntfs_index_ctx_reinit(ntfs_index_context *icx)
ntfs_index_ctx_free( icx );
*icx = (ntfs_index_context) {
*icx = ( ntfs_index_context )
{
.ni = icx->ni,
.name = icx->name,
.name_len = icx->name_len,
@ -261,7 +267,8 @@ static INDEX_ENTRY *ntfs_ie_prev(INDEX_HEADER *ih, INDEX_ENTRY *ie)
tmp = ntfs_ie_get_first( ih );
while (tmp != ie) {
while ( tmp != ie )
{
ie_prev = tmp;
tmp = ntfs_ie_get_next( tmp );
}
@ -293,7 +300,8 @@ void ntfs_ih_filename_dump(INDEX_HEADER *ih)
ntfs_log_trace( "Entering\n" );
ie = ntfs_ie_get_first( ih );
while (!ntfs_ie_end(ie)) {
while ( !ntfs_ie_end( ie ) )
{
ntfs_ie_filename_dump( ie );
ie = ntfs_ie_get_next( ie );
}
@ -380,7 +388,8 @@ static INDEX_ENTRY *ntfs_ie_dup_novcn(INDEX_ENTRY *ie)
size -= sizeof( VCN );
dup = ntfs_malloc( size );
if (dup) {
if ( dup )
{
memcpy( dup, ie, size );
dup->ie_flags &= ~INDEX_ENTRY_NODE;
dup->length = cpu_to_le16( size );
@ -394,7 +403,8 @@ static int ntfs_ia_check(ntfs_index_context *icx, INDEX_BLOCK *ib, VCN vcn)
ntfs_log_trace( "Entering\n" );
if (!ntfs_is_indx_record(ib->magic)) {
if ( !ntfs_is_indx_record( ib->magic ) )
{
ntfs_log_error( "Corrupt index block signature: vcn %lld inode "
"%llu\n", ( long long )vcn,
@ -402,7 +412,8 @@ static int ntfs_ia_check(ntfs_index_context *icx, INDEX_BLOCK *ib, VCN vcn)
return -1;
}
if (sle64_to_cpu(ib->index_block_vcn) != vcn) {
if ( sle64_to_cpu( ib->index_block_vcn ) != vcn )
{
ntfs_log_error( "Corrupt index block: VCN (%lld) is different "
"from expected VCN (%lld) in inode %llu\n",
@ -412,7 +423,8 @@ static int ntfs_ia_check(ntfs_index_context *icx, INDEX_BLOCK *ib, VCN vcn)
return -1;
}
if (ib_size != icx->block_size) {
if ( ib_size != icx->block_size )
{
ntfs_log_error( "Corrupt index block : VCN (%lld) of inode %llu "
"has a size (%u) differing from the index "
@ -437,13 +449,15 @@ static INDEX_ROOT *ntfs_ir_lookup(ntfs_inode *ni, ntfschar *name,
return NULL;
if ( ntfs_attr_lookup( AT_INDEX_ROOT, name, name_len, CASE_SENSITIVE,
0, NULL, 0, *ctx)) {
0, NULL, 0, *ctx ) )
{
ntfs_log_perror( "Failed to lookup $INDEX_ROOT" );
goto err_out;
}
a = ( *ctx )->attr;
if (a->non_resident) {
if ( a->non_resident )
{
errno = EINVAL;
ntfs_log_perror( "Non-resident $INDEX_ROOT detected" );
goto err_out;
@ -451,7 +465,8 @@ static INDEX_ROOT *ntfs_ir_lookup(ntfs_inode *ni, ntfschar *name,
ir = ( INDEX_ROOT * )( ( char * )a + le16_to_cpu( a->value_offset ) );
err_out:
if (!ir) {
if ( !ir )
{
ntfs_attr_put_search_ctx( *ctx );
*ctx = NULL;
}
@ -497,10 +512,12 @@ static int ntfs_ie_lookup(const void *key, const int key_len,
* Loop until we exceed valid memory (corruption case) or until we
* reach the last entry.
*/
for (ie = ntfs_ie_get_first(ih); ; ie = ntfs_ie_get_next(ie)) {
for ( ie = ntfs_ie_get_first( ih ); ; ie = ntfs_ie_get_next( ie ) )
{
/* Bounds checks. */
if ( ( u8 * )ie + sizeof( INDEX_ENTRY_HEADER ) > index_end ||
(u8 *)ie + le16_to_cpu(ie->length) > index_end) {
( u8 * )ie + le16_to_cpu( ie->length ) > index_end )
{
errno = ERANGE;
ntfs_log_error( "Index entry out of bounds in inode "
"%llu.\n",
@ -517,14 +534,16 @@ static int ntfs_ie_lookup(const void *key, const int key_len,
* Not a perfect match, need to do full blown collation so we
* know which way in the B+tree we have to go.
*/
if (!icx->collate) {
if ( !icx->collate )
{
ntfs_log_error( "Collation function not defined\n" );
errno = EOPNOTSUPP;
return STATUS_ERROR;
}
rc = icx->collate( icx->ni->vol, key, key_len,
&ie->key, le16_to_cpu( ie->key_length ) );
if (rc == NTFS_COLLATION_ERROR) {
if ( rc == NTFS_COLLATION_ERROR )
{
ntfs_log_error( "Collation error. Perhaps a filename "
"contains invalid characters?\n" );
errno = ERANGE;
@ -538,7 +557,8 @@ static int ntfs_ie_lookup(const void *key, const int key_len,
if ( rc == -1 )
break;
if (!rc) {
if ( !rc )
{
*ie_out = ie;
errno = 0;
icx->parent_pos[icx->pindex] = item;
@ -552,7 +572,8 @@ static int ntfs_ie_lookup(const void *key, const int key_len,
* presence of a child node and if not present return with errno ENOENT,
* otherwise we will keep searching in another index block.
*/
if (!(ie->ie_flags & INDEX_ENTRY_NODE)) {
if ( !( ie->ie_flags & INDEX_ENTRY_NODE ) )
{
ntfs_log_debug( "Index entry wasn't found.\n" );
*ie_out = ie;
errno = ENOENT;
@ -561,7 +582,8 @@ static int ntfs_ie_lookup(const void *key, const int key_len,
/* Get the starting vcn of the index_block holding the child node. */
*vcn = ntfs_ie_get_vcn( ie );
if (*vcn < 0) {
if ( *vcn < 0 )
{
errno = EINVAL;
ntfs_log_perror( "Negative vcn in inode %llu",
( unsigned long long )icx->ni->mft_no );
@ -579,7 +601,8 @@ static ntfs_attr *ntfs_ia_open(ntfs_index_context *icx, ntfs_inode *ni)
ntfs_attr *na;
na = ntfs_attr_open( ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len );
if (!na) {
if ( !na )
{
ntfs_log_perror( "Failed to open index allocation of inode "
"%llu", ( unsigned long long )ni->mft_no );
return NULL;
@ -597,7 +620,8 @@ static int ntfs_ib_read(ntfs_index_context *icx, VCN vcn, INDEX_BLOCK *dst)
pos = ntfs_ib_vcn_to_pos( icx, vcn );
ret = ntfs_attr_mst_pread( icx->ia_na, pos, 1, icx->block_size, ( u8 * )dst );
if (ret != 1) {
if ( ret != 1 )
{
if ( ret == -1 )
ntfs_log_perror( "Failed to read index block" );
else
@ -615,7 +639,8 @@ static int ntfs_ib_read(ntfs_index_context *icx, VCN vcn, INDEX_BLOCK *dst)
static int ntfs_icx_parent_inc( ntfs_index_context *icx )
{
icx->pindex++;
if (icx->pindex >= MAX_PARENT_VCN) {
if ( icx->pindex >= MAX_PARENT_VCN )
{
errno = EOPNOTSUPP;
ntfs_log_perror( "Index is over %d level deep", MAX_PARENT_VCN );
return STATUS_ERROR;
@ -626,7 +651,8 @@ static int ntfs_icx_parent_inc(ntfs_index_context *icx)
static int ntfs_icx_parent_dec( ntfs_index_context *icx )
{
icx->pindex--;
if (icx->pindex < 0) {
if ( icx->pindex < 0 )
{
errno = EINVAL;
ntfs_log_perror( "Corrupt index pointer (%d)", icx->pindex );
return STATUS_ERROR;
@ -677,21 +703,24 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic
ntfs_log_trace( "Entering\n" );
if (!key || key_len <= 0) {
if ( !key || key_len <= 0 )
{
errno = EINVAL;
ntfs_log_perror( "key: %p key_len: %d", key, key_len );
return -1;
}
ir = ntfs_ir_lookup( ni, icx->name, icx->name_len, &icx->actx );
if (!ir) {
if ( !ir )
{
if ( errno == ENOENT )
errno = EIO;
return -1;
}
icx->block_size = le32_to_cpu( ir->index_block_size );
if (icx->block_size < NTFS_BLOCK_SIZE) {
if ( icx->block_size < NTFS_BLOCK_SIZE )
{
errno = EINVAL;
ntfs_log_perror( "Index block size (%d) is smaller than the "
"sector size (%d)", icx->block_size, NTFS_BLOCK_SIZE );
@ -704,7 +733,8 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic
icx->vcn_size_bits = ni->vol->sector_size_bits;
/* get the appropriate collation function */
icx->collate = ntfs_get_collate_function( ir->collation_rule );
if (!icx->collate) {
if ( !icx->collate )
{
err = errno = EOPNOTSUPP;
ntfs_log_perror( "Unknown collation rule 0x%x",
( unsigned )le32_to_cpu( ir->collation_rule ) );
@ -717,14 +747,16 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic
* within the index block.
*/
ret = ntfs_ie_lookup( key, key_len, icx, &ir->index, &vcn, &ie );
if (ret == STATUS_ERROR) {
if ( ret == STATUS_ERROR )
{
err = errno;
goto err_out;
}
icx->ir = ir;
if (ret != STATUS_KEEP_SEARCHING) {
if ( ret != STATUS_KEEP_SEARCHING )
{
/* STATUS_OK or STATUS_NOT_FOUND */
err = errno;
icx->is_in_root = TRUE;
@ -739,7 +771,8 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic
goto err_out;
ib = ntfs_malloc( icx->block_size );
if (!ib) {
if ( !ib )
{
err = errno;
goto err_out;
}
@ -747,7 +780,8 @@ int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ic
descend_into_child_node:
icx->parent_vcn[icx->pindex] = old_vcn;
if (ntfs_icx_parent_inc(icx)) {
if ( ntfs_icx_parent_inc( icx ) )
{
err = errno;
goto err_out;
}
@ -759,7 +793,8 @@ descend_into_child_node:
goto err_out;
ret = ntfs_ie_lookup( key, key_len, icx, &ib->index, &vcn, &ie );
if (ret != STATUS_KEEP_SEARCHING) {
if ( ret != STATUS_KEEP_SEARCHING )
{
err = errno;
if ( ret == STATUS_ERROR )
goto err_out;
@ -771,7 +806,8 @@ descend_into_child_node:
goto done;
}
if ((ib->index.ih_flags & NODE_MASK) == LEAF_NODE) {
if ( ( ib->index.ih_flags & NODE_MASK ) == LEAF_NODE )
{
ntfs_log_error( "Index entry with child node found in a leaf "
"node in inode 0x%llx.\n",
( unsigned long long )ni->mft_no );
@ -790,7 +826,8 @@ done:
icx->data = ( u8 * )ie + offsetof( INDEX_ENTRY, key );
icx->data_len = le16_to_cpu( ie->key_length );
ntfs_log_trace( "Done.\n" );
if (err) {
if ( err )
{
errno = err;
return -1;
}
@ -843,7 +880,8 @@ static INDEX_ENTRY *ntfs_ie_get_median(INDEX_HEADER *ih)
ie = ie_start = ntfs_ie_get_first( ih );
ie_end = ( u8 * )ntfs_ie_get_end( ih );
while ((u8 *)ie < ie_end && !ntfs_ie_end(ie)) {
while ( ( u8 * )ie < ie_end && !ntfs_ie_end( ie ) )
{
ie = ntfs_ie_get_next( ie );
i++;
}
@ -883,7 +921,8 @@ static int ntfs_ibm_add(ntfs_index_context *icx)
*/
memset( bmp, 0, sizeof( bmp ) );
if ( ntfs_attr_add( icx->ni, AT_BITMAP, icx->name, icx->name_len,
bmp, sizeof(bmp))) {
bmp, sizeof( bmp ) ) )
{
ntfs_log_perror( "Failed to add AT_BITMAP" );
return STATUS_ERROR;
}
@ -903,21 +942,26 @@ static int ntfs_ibm_modify(ntfs_index_context *icx, VCN vcn, int set)
ntfs_log_trace( "%s vcn: %lld\n", set ? "set" : "clear", ( long long )vcn );
na = ntfs_attr_open( icx->ni, AT_BITMAP, icx->name, icx->name_len );
if (!na) {
if ( !na )
{
ntfs_log_perror( "Failed to open $BITMAP attribute" );
return -1;
}
if (set) {
if (na->data_size < bpos + 1) {
if (ntfs_attr_truncate(na, (na->data_size + 8) & ~7)) {
if ( set )
{
if ( na->data_size < bpos + 1 )
{
if ( ntfs_attr_truncate( na, ( na->data_size + 8 ) & ~7 ) )
{
ntfs_log_perror( "Failed to truncate AT_BITMAP" );
goto err_na;
}
}
}
if (ntfs_attr_pread(na, bpos, 1, &byte) != 1) {
if ( ntfs_attr_pread( na, bpos, 1, &byte ) != 1 )
{
ntfs_log_perror( "Failed to read $BITMAP" );
goto err_na;
}
@ -927,7 +971,8 @@ static int ntfs_ibm_modify(ntfs_index_context *icx, VCN vcn, int set)
else
byte &= ~bit;
if (ntfs_attr_pwrite(na, bpos, 1, &byte) != 1) {
if ( ntfs_attr_pwrite( na, bpos, 1, &byte ) != 1 )
{
ntfs_log_perror( "Failed to write $Bitmap" );
goto err_na;
}
@ -962,13 +1007,16 @@ static VCN ntfs_ibm_get_free(ntfs_index_context *icx)
if ( !bm )
return ( VCN ) - 1;
for (byte = 0; byte < size; byte++) {
for ( byte = 0; byte < size; byte++ )
{
if ( bm[byte] == 255 )
continue;
for (bit = 0; bit < 8; bit++) {
if (!(bm[byte] & (1 << bit))) {
for ( bit = 0; bit < 8; bit++ )
{
if ( !( bm[byte] & ( 1 << bit ) ) )
{
vcn = ntfs_ibm_pos_to_vcn( icx, byte * 8 + bit );
goto out;
}
@ -1030,7 +1078,8 @@ static void ntfs_ir_nill(INDEX_ROOT *ir)
/*
* Move the index root termination entry forward
*/
if ((char *)ie_last > ies_start) {
if ( ( char * )ie_last > ies_start )
{
memmove( ies_start, ( char * )ie_last, le16_to_cpu( ie_last->length ) );
ie_last = ( INDEX_ENTRY * )ies_start;
}
@ -1098,10 +1147,12 @@ static int ntfs_ia_add(ntfs_index_context *icx)
if ( ntfs_ibm_add( icx ) )
return -1;
if (!ntfs_attr_exist(icx->ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len)) {
if ( !ntfs_attr_exist( icx->ni, AT_INDEX_ALLOCATION, icx->name, icx->name_len ) )
{
if ( ntfs_attr_add( icx->ni, AT_INDEX_ALLOCATION, icx->name,
icx->name_len, NULL, 0)) {
icx->name_len, NULL, 0 ) )
{
ntfs_log_perror( "Failed to add AT_INDEX_ALLOCATION" );
return -1;
}
@ -1142,7 +1193,8 @@ static int ntfs_ir_reparent(ntfs_index_context *icx)
goto clear_bmp;
ib = ntfs_ir_to_ib( ir, new_ib_vcn );
if (ib == NULL) {
if ( ib == NULL )
{
ntfs_log_perror( "Failed to move index root to index block" );
goto clear_bmp;
}
@ -1200,7 +1252,8 @@ static int ntfs_ir_truncate(ntfs_index_context *icx, int data_size)
ntfs_log_trace( "Entering\n" );
na = ntfs_attr_open( icx->ni, AT_INDEX_ROOT, icx->name, icx->name_len );
if (!na) {
if ( !na )
{
ntfs_log_perror( "Failed to open INDEX_ROOT" );
return STATUS_ERROR;
}
@ -1209,7 +1262,8 @@ static int ntfs_ir_truncate(ntfs_index_context *icx, int data_size)
* INDEX_BLOCK, so ENOSPC isn't a real error.
*/
ret = ntfs_attr_truncate( na, data_size + offsetof( INDEX_ROOT, index ) );
if (ret == STATUS_OK) {
if ( ret == STATUS_OK )
{
icx->ir = ntfs_ir_lookup2( icx->ni, icx->name, icx->name_len );
if ( !icx->ir )
@ -1217,7 +1271,8 @@ static int ntfs_ir_truncate(ntfs_index_context *icx, int data_size)
icx->ir->index.allocated_size = cpu_to_le32( data_size );
} else if (ret == STATUS_ERROR)
}
else if ( ret == STATUS_ERROR )
ntfs_log_perror( "Failed to truncate INDEX_ROOT" );
ntfs_attr_close( na );
@ -1237,7 +1292,8 @@ static int ntfs_ir_make_space(ntfs_index_context *icx, int data_size)
ntfs_log_trace( "Entering\n" );
ret = ntfs_ir_truncate( icx, data_size );
if (ret == STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT) {
if ( ret == STATUS_RESIDENT_ATTRIBUTE_FILLED_MFT )
{
ret = ntfs_ir_reparent( icx );
if ( ret == STATUS_OK )
@ -1364,7 +1420,8 @@ static int ntfs_ib_insert(ntfs_index_context *icx, INDEX_ENTRY *ie, VCN new_vcn)
idx_size = le32_to_cpu( ib->index.index_length );
allocated_size = le32_to_cpu( ib->index.allocated_size );
/* FIXME: sizeof(VCN) should be included only if ie has no VCN */
if (idx_size + le16_to_cpu(ie->length) + sizeof(VCN) > allocated_size) {
if ( idx_size + le16_to_cpu( ie->length ) + sizeof( VCN ) > allocated_size )
{
err = ntfs_ib_split( icx, ib );
if ( err == STATUS_OK )
err = STATUS_KEEP_SEARCHING;
@ -1405,7 +1462,8 @@ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib)
if ( new_vcn == -1 )
return STATUS_ERROR;
if (ntfs_ib_copy_tail(icx, ib, median, new_vcn)) {
if ( ntfs_ib_copy_tail( icx, ib, median, new_vcn ) )
{
ntfs_ibm_clear( icx, new_vcn );
return STATUS_ERROR;
}
@ -1415,7 +1473,8 @@ static int ntfs_ib_split(ntfs_index_context *icx, INDEX_BLOCK *ib)
else
ret = ntfs_ib_insert( icx, median, new_vcn );
if (ret != STATUS_OK) {
if ( ret != STATUS_OK )
{
ntfs_ibm_clear( icx, new_vcn );
return ret;
}
@ -1441,14 +1500,17 @@ int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie)
*/
#endif
while (1) {
while ( 1 )
{
if (!ntfs_index_lookup(&ie->key, le16_to_cpu(ie->key_length), icx)) {
if ( !ntfs_index_lookup( &ie->key, le16_to_cpu( ie->key_length ), icx ) )
{
errno = EEXIST;
ntfs_log_perror( "Index already have such entry" );
goto err_out;
}
if (errno != ENOENT) {
if ( errno != ENOENT )
{
ntfs_log_perror( "Failed to find place for new entry" );
goto err_out;
}
@ -1467,10 +1529,13 @@ int ntfs_ie_add(ntfs_index_context *icx, INDEX_ENTRY *ie)
ntfs_log_trace( "index block sizes: allocated: %d needed: %d\n",
allocated_size, new_size );
if (icx->is_in_root) {
if ( icx->is_in_root )
{
if ( ntfs_ir_make_space( icx, new_size ) == STATUS_ERROR )
goto err_out;
} else {
}
else
{
if ( ntfs_ib_split( icx, icx->ib ) == STATUS_ERROR )
goto err_out;
}
@ -1504,7 +1569,8 @@ int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn, MFT_REF mref)
ntfs_log_trace( "Entering\n" );
if (!ni || !fn) {
if ( !ni || !fn )
{
ntfs_log_error( "Invalid arguments.\n" );
errno = EINVAL;
return -1;
@ -1552,8 +1618,7 @@ static int ntfs_ih_takeout(ntfs_index_context *icx, INDEX_HEADER *ih,
if ( ntfs_icx_parent_vcn( icx ) == VCN_INDEX_ROOT_PARENT )
ntfs_inode_mark_dirty( icx->actx->ntfs_ino );
else
if (ntfs_ib_write(icx, ib))
else if ( ntfs_ib_write( icx, ib ) )
goto out;
ntfs_index_ctx_reinit( icx );
@ -1621,7 +1686,8 @@ static int ntfs_index_rm_leaf(ntfs_index_context *icx)
if ( ntfs_icx_parent_vcn( icx ) == VCN_INDEX_ROOT_PARENT )
parent_ih = &icx->ir->index;
else {
else
{
ib = ntfs_malloc( icx->block_size );
if ( !ib )
return STATUS_ERROR;
@ -1633,14 +1699,17 @@ static int ntfs_index_rm_leaf(ntfs_index_context *icx)
}
ie = ntfs_ie_get_by_pos( parent_ih, ntfs_icx_parent_pos( icx ) );
if (!ntfs_ie_end(ie)) {
if ( !ntfs_ie_end( ie ) )
{
ret = ntfs_ih_takeout( icx, parent_ih, ie, ib );
goto out;
}
if (ntfs_ih_zero_entry(parent_ih)) {
if ( ntfs_ih_zero_entry( parent_ih ) )
{
if (ntfs_icx_parent_vcn(icx) == VCN_INDEX_ROOT_PARENT) {
if ( ntfs_icx_parent_vcn( icx ) == VCN_INDEX_ROOT_PARENT )
{
ntfs_ir_leafify( icx, parent_ih );
goto ok;
}
@ -1670,7 +1739,8 @@ static int ntfs_index_rm_node(ntfs_index_context *icx)
ntfs_log_trace( "Entering\n" );
if (!icx->ia_na) {
if ( !icx->ia_na )
{
icx->ia_na = ntfs_ia_open( icx, icx->ni );
if ( !icx->ia_na )
return STATUS_ERROR;
@ -1699,7 +1769,8 @@ descend:
if ( ( ib->index.ih_flags & NODE_MASK ) == INDEX_NODE )
goto descend;
if (ntfs_ih_zero_entry(&ib->index)) {
if ( ntfs_ih_zero_entry( &ib->index ) )
{
errno = EIO;
ntfs_log_perror( "Empty index block" );
goto out;
@ -1721,8 +1792,10 @@ descend:
delta = le16_to_cpu( ie->length ) - le16_to_cpu( icx->entry->length );
new_size = le32_to_cpu( ih->index_length ) + delta;
if (delta > 0) {
if (icx->is_in_root) {
if ( delta > 0 )
{
if ( icx->is_in_root )
{
ret = ntfs_ir_make_space( icx, new_size );
if ( ret != STATUS_OK )
goto out2;
@ -1730,7 +1803,9 @@ descend:
ih = &icx->ir->index;
entry = ntfs_ie_get_by_pos( ih, entry_pos );
} else if (new_size > le32_to_cpu(ih->allocated_size)) {
}
else if ( new_size > le32_to_cpu( ih->allocated_size ) )
{
icx->pindex = pindex;
ret = ntfs_ib_split( icx, icx->ib );
if ( ret == STATUS_OK )
@ -1742,20 +1817,22 @@ descend:
ntfs_ie_delete( ih, entry );
ntfs_ie_insert( ih, ie, entry );
if (icx->is_in_root) {
if ( icx->is_in_root )
{
if ( ntfs_ir_truncate( icx, new_size ) )
goto out2;
} else
if (ntfs_icx_ib_write(icx))
}
else if ( ntfs_icx_ib_write( icx ) )
goto out2;
ntfs_ie_delete( &ib->index, ie_succ );
if (ntfs_ih_zero_entry(&ib->index)) {
if ( ntfs_ih_zero_entry( &ib->index ) )
{
if ( ntfs_index_rm_leaf( icx ) )
goto out2;
} else
if (ntfs_ib_write(icx, ib))
}
else if ( ntfs_ib_write( icx, ib ) )
goto out2;
ret = STATUS_OK;
@ -1784,7 +1861,8 @@ int ntfs_index_rm(ntfs_index_context *icx)
ntfs_log_trace( "Entering\n" );
if (!icx || (!icx->ib && !icx->ir) || ntfs_ie_end(icx->entry)) {
if ( !icx || ( !icx->ib && !icx->ir ) || ntfs_ie_end( icx->entry ) )
{
ntfs_log_error( "Invalid arguments.\n" );
errno = EINVAL;
goto err_out;
@ -1794,22 +1872,28 @@ int ntfs_index_rm(ntfs_index_context *icx)
else
ih = &icx->ib->index;
if (icx->entry->ie_flags & INDEX_ENTRY_NODE) {
if ( icx->entry->ie_flags & INDEX_ENTRY_NODE )
{
ret = ntfs_index_rm_node( icx );
} else if (icx->is_in_root || !ntfs_ih_one_entry(ih)) {
}
else if ( icx->is_in_root || !ntfs_ih_one_entry( ih ) )
{
ntfs_ie_delete( ih, icx->entry );
if (icx->is_in_root) {
if ( icx->is_in_root )
{
err = ntfs_ir_truncate( icx, le32_to_cpu( ih->index_length ) );
if ( err != STATUS_OK )
goto err_out;
} else
if (ntfs_icx_ib_write(icx))
}
else if ( ntfs_icx_ib_write( icx ) )
goto err_out;
} else {
}
else
{
if ( ntfs_index_rm_leaf( icx ) )
goto err_out;
}
@ -1830,14 +1914,16 @@ int ntfs_index_remove(ntfs_inode *dir_ni, ntfs_inode *ni,
if ( !icx )
return -1;
while (1) {
while ( 1 )
{
if ( ntfs_index_lookup( key, keylen, icx ) )
goto err_out;
if ( ( ( ( FILE_NAME_ATTR * )icx->data )->file_attributes &
FILE_ATTR_REPARSE_POINT )
&& !ntfs_possible_symlink(ni)) {
&& !ntfs_possible_symlink( ni ) )
{
errno = EOPNOTSUPP;
goto err_out;
}
@ -1910,9 +1996,11 @@ static INDEX_ENTRY *ntfs_index_walk_down(INDEX_ENTRY *ie,
s64 vcn;
entry = ie;
do {
do
{
vcn = ntfs_ie_get_vcn( entry );
if (ictx->is_in_root) {
if ( ictx->is_in_root )
{
/* down from level zero */
@ -1920,7 +2008,9 @@ static INDEX_ENTRY *ntfs_index_walk_down(INDEX_ENTRY *ie,
ictx->ib = ( INDEX_BLOCK* )ntfs_malloc( ictx->block_size );
ictx->pindex = 1;
ictx->is_in_root = FALSE;
} else {
}
else
{
/* down from non-zero level */
@ -1928,12 +2018,15 @@ static INDEX_ENTRY *ntfs_index_walk_down(INDEX_ENTRY *ie,
}
ictx->parent_pos[ictx->pindex] = 0;
ictx->parent_vcn[ictx->pindex] = vcn;
if (!ntfs_ib_read(ictx,vcn,ictx->ib)) {
if ( !ntfs_ib_read( ictx, vcn, ictx->ib ) )
{
ictx->entry = ntfs_ie_get_first( &ictx->ib->index );
entry = ictx->entry;
} else
}
else
entry = ( INDEX_ENTRY* )NULL;
} while (entry && (entry->ie_flags & INDEX_ENTRY_NODE));
}
while ( entry && ( entry->ie_flags & INDEX_ENTRY_NODE ) );
return ( entry );
}
@ -1950,10 +2043,13 @@ static INDEX_ENTRY *ntfs_index_walk_up(INDEX_ENTRY *ie,
s64 vcn;
entry = ie;
if (ictx->pindex > 0) {
do {
if ( ictx->pindex > 0 )
{
do
{
ictx->pindex--;
if (!ictx->pindex) {
if ( !ictx->pindex )
{
/* we have reached the root */
@ -1972,20 +2068,26 @@ static INDEX_ENTRY *ntfs_index_walk_up(INDEX_ENTRY *ie,
ictx->parent_pos[ictx->pindex] );
else
entry = ( INDEX_ENTRY* )NULL;
} else {
}
else
{
/* up into non-root node */
vcn = ictx->parent_vcn[ictx->pindex];
if (!ntfs_ib_read(ictx,vcn,ictx->ib)) {
if ( !ntfs_ib_read( ictx, vcn, ictx->ib ) )
{
entry = ntfs_ie_get_by_pos(
&ictx->ib->index,
ictx->parent_pos[ictx->pindex] );
} else
}
else
entry = ( INDEX_ENTRY* )NULL;
}
ictx->entry = entry;
} while (entry && (ictx->pindex > 0)
}
while ( entry && ( ictx->pindex > 0 )
&& ( entry->ie_flags & INDEX_ENTRY_END ) );
} else
}
else
entry = ( INDEX_ENTRY* )NULL;
return ( entry );
}
@ -2030,7 +2132,8 @@ INDEX_ENTRY *ntfs_index_next(INDEX_ENTRY *ie, ntfs_index_context *ictx)
if ( ie->ie_flags & INDEX_ENTRY_END )
next = ntfs_index_walk_up( ie, ictx );
else {
else
{
/*
* get next entry in same node
* there is always one after any entry with data
@ -2042,13 +2145,17 @@ INDEX_ENTRY *ntfs_index_next(INDEX_ENTRY *ie, ntfs_index_context *ictx)
/* walk down if it has a subnode */
if (flags & INDEX_ENTRY_NODE) {
if ( flags & INDEX_ENTRY_NODE )
{
next = ntfs_index_walk_down( next, ictx );
} else {
}
else
{
/* walk up it has no subnode, nor data */
if (flags & INDEX_ENTRY_END) {
if ( flags & INDEX_ENTRY_END )
{
next = ntfs_index_walk_up( next, ictx );
}
}

View File

@ -112,7 +112,8 @@ typedef int (*COLLATE)(ntfs_volume *vol, const void *data1, int len1,
* the call to ntfs_index_ctx_put() to ensure that the changes are written
* to disk.
*/
typedef struct {
typedef struct
{
ntfs_inode *ni;
ntfschar *name;
u32 name_len;

View File

@ -166,7 +166,8 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
int olderrno;
ntfs_log_enter( "Entering for inode %lld\n", ( long long )MREF( mref ) );
if (!vol) {
if ( !vol )
{
errno = EINVAL;
goto out;
}
@ -175,7 +176,8 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
goto out;
if ( ntfs_file_record_read( vol, mref, &ni->mrec, NULL ) )
goto err_out;
if (!(ni->mrec->flags & MFT_RECORD_IN_USE)) {
if ( !( ni->mrec->flags & MFT_RECORD_IN_USE ) )
{
errno = ENOENT;
goto err_out;
}
@ -185,7 +187,8 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
goto err_out;
/* Receive some basic information about inode. */
if ( ntfs_attr_lookup( AT_STANDARD_INFORMATION, AT_UNNAMED,
0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
0, CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
if ( !ni->mrec->base_mft_record )
ntfs_log_perror( "No STANDARD_INFORMATION in base record"
" %lld", ( long long )MREF( mref ) );
@ -201,13 +204,16 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
/* JPA insert v3 extensions if present */
/* length may be seen as 72 (v1.x) or 96 (v3.x) */
lthle = ctx->attr->length;
if (le32_to_cpu(lthle) > sizeof(STANDARD_INFORMATION)) {
if ( le32_to_cpu( lthle ) > sizeof( STANDARD_INFORMATION ) )
{
set_nino_flag( ni, v3_Extensions );
ni->owner_id = std_info->owner_id;
ni->security_id = std_info->security_id;
ni->quota_charged = std_info->quota_charged;
ni->usn = std_info->usn;
} else {
}
else
{
clear_nino_flag( ni, v3_Extensions );
ni->owner_id = const_cpu_to_le32( 0 );
ni->security_id = const_cpu_to_le32( 0 );
@ -215,7 +221,8 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
/* Set attribute list information. */
olderrno = errno;
if ( ntfs_attr_lookup( AT_ATTRIBUTE_LIST, AT_UNNAMED, 0,
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
if ( errno != ENOENT )
goto put_err_out;
/* Attribute list attribute does not present. */
@ -227,7 +234,8 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
l = ntfs_get_attribute_value_length( ctx->attr );
if ( !l )
goto put_err_out;
if (l > 0x40000) {
if ( l > 0x40000 )
{
errno = EIO;
ntfs_log_perror( "Too large attrlist attribute (%lld), inode "
"%lld", ( long long )l, ( long long )MREF( mref ) );
@ -240,7 +248,8 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
l = ntfs_get_attribute_value( vol, ctx->attr, ni->attr_list );
if ( !l )
goto put_err_out;
if (l != ni->attr_list_size) {
if ( l != ni->attr_list_size )
{
errno = EIO;
ntfs_log_perror( "Unexpected attrlist size (%lld <> %u), inode "
"%lld", ( long long )l, ni->attr_list_size,
@ -249,15 +258,19 @@ static ntfs_inode *ntfs_inode_real_open(ntfs_volume *vol, const MFT_REF mref)
}
get_size:
olderrno = errno;
if (ntfs_attr_lookup(AT_DATA, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx)) {
if ( ntfs_attr_lookup( AT_DATA, AT_UNNAMED, 0, 0, 0, NULL, 0, ctx ) )
{
if ( errno != ENOENT )
goto put_err_out;
/* Directory or special file. */
/* restore previous errno to avoid misinterpretation */
errno = olderrno;
ni->data_size = ni->allocated_size = 0;
} else {
if (ctx->attr->non_resident) {
}
else
{
if ( ctx->attr->non_resident )
{
ni->data_size = sle64_to_cpu( ctx->attr->data_size );
if ( ctx->attr->flags &
( ATTR_IS_COMPRESSED | ATTR_IS_SPARSE ) )
@ -266,7 +279,9 @@ get_size:
else
ni->allocated_size = sle64_to_cpu(
ctx->attr->allocated_size );
} else {
}
else
{
ni->data_size = le32_to_cpu( ctx->attr->value_length );
ni->allocated_size = ( ni->data_size + 7 ) & ~7;
}
@ -320,23 +335,30 @@ int ntfs_inode_real_close(ntfs_inode *ni)
ntfs_log_enter( "Entering for inode %lld\n", ( long long )ni->mft_no );
/* If we have dirty metadata, write it out. */
if (NInoDirty(ni) || NInoAttrListDirty(ni)) {
if (ntfs_inode_sync(ni)) {
if ( NInoDirty( ni ) || NInoAttrListDirty( ni ) )
{
if ( ntfs_inode_sync( ni ) )
{
if ( errno != EIO )
errno = EBUSY;
goto err;
}
}
/* Is this a base inode with mapped extent inodes? */
if (ni->nr_extents > 0) {
while (ni->nr_extents > 0) {
if (ntfs_inode_real_close(ni->extent_nis[0])) {
if ( ni->nr_extents > 0 )
{
while ( ni->nr_extents > 0 )
{
if ( ntfs_inode_real_close( ni->extent_nis[0] ) )
{
if ( errno != EIO )
errno = EBUSY;
goto err;
}
}
} else if (ni->nr_extents == -1) {
}
else if ( ni->nr_extents == -1 )
{
ntfs_inode **tmp_nis;
ntfs_inode *base_ni;
s32 i;
@ -346,7 +368,8 @@ int ntfs_inode_real_close(ntfs_inode *ni)
* base inode before destroying it.
*/
base_ni = ni->base_ni;
for (i = 0; i < base_ni->nr_extents; ++i) {
for ( i = 0; i < base_ni->nr_extents; ++i )
{
tmp_nis = base_ni->extent_nis;
if ( tmp_nis[i] != ni )
continue;
@ -355,7 +378,8 @@ int ntfs_inode_real_close(ntfs_inode *ni)
( base_ni->nr_extents - i - 1 ) *
sizeof( ntfs_inode * ) );
/* Buffer should be for multiple of four extents. */
if ((--base_ni->nr_extents) & 3) {
if ( ( --base_ni->nr_extents ) & 3 )
{
i = -1;
break;
}
@ -363,14 +387,17 @@ int ntfs_inode_real_close(ntfs_inode *ni)
* ElectricFence is unhappy with realloc(x,0) as free(x)
* thus we explicitly separate these two cases.
*/
if (base_ni->nr_extents) {
if ( base_ni->nr_extents )
{
/* Resize the memory buffer. */
tmp_nis = realloc( tmp_nis, base_ni->nr_extents *
sizeof( ntfs_inode * ) );
/* Ignore errors, they don't really matter. */
if ( tmp_nis )
base_ni->extent_nis = tmp_nis;
} else if (tmp_nis) {
}
else if ( tmp_nis )
{
free( tmp_nis );
base_ni->extent_nis = ( ntfs_inode** )NULL;
}
@ -473,12 +500,15 @@ ntfs_inode *ntfs_inode_open(ntfs_volume *vol, const MFT_REF mref)
item.varsize = 0;
cached = ( struct CACHED_NIDATA* )ntfs_fetch_cache( vol->nidata_cache,
GENERIC( &item ), idata_cache_compare );
if (cached) {
if ( cached )
{
ni = cached->ni;
/* do not keep open entries in cache */
ntfs_remove_cache( vol->nidata_cache,
( struct CACHED_GENERIC* )cached, 0 );
} else {
}
else
{
ni = ntfs_inode_real_open( vol, mref );
}
#else
@ -504,24 +534,29 @@ int ntfs_inode_close(ntfs_inode *ni)
BOOL dirty;
struct CACHED_NIDATA item;
if (ni) {
if ( ni )
{
debug_double_inode( ni->mft_no, 0 );
/* do not cache system files : could lead to double entries */
if ( ni->vol && ni->vol->nidata_cache
&& ( ( ni->mft_no == FILE_root )
|| ( ( ni->mft_no >= FILE_first_user )
&& !(ni->mrec->flags & MFT_RECORD_IS_4)))) {
&& !( ni->mrec->flags & MFT_RECORD_IS_4 ) ) ) )
{
/* If we have dirty metadata, write it out. */
dirty = NInoDirty( ni ) || NInoAttrListDirty( ni );
if (dirty) {
if ( dirty )
{
res = ntfs_inode_sync( ni );
/* do a real close if sync failed */
if ( res )
ntfs_inode_real_close( ni );
} else
}
else
res = 0;
if (!res) {
if ( !res )
{
/* feed idata into cache */
item.inum = ni->mft_no;
item.ni = ni;
@ -531,11 +566,14 @@ int ntfs_inode_close(ntfs_inode *ni)
ntfs_enter_cache( ni->vol->nidata_cache,
GENERIC( &item ), idata_cache_compare );
}
} else {
}
else
{
/* cache not ready or system file, really close */
res = ntfs_inode_real_close( ni );
}
} else
}
else
res = 0;
#else
res = ntfs_inode_real_close( ni );
@ -575,7 +613,8 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
ntfs_inode **extent_nis;
int i;
if (!base_ni) {
if ( !base_ni )
{
errno = EINVAL;
ntfs_log_perror( "%s", __FUNCTION__ );
return NULL;
@ -586,9 +625,11 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
( unsigned long long )base_ni->mft_no );
/* Is the extent inode already open and attached to the base inode? */
if (base_ni->nr_extents > 0) {
if ( base_ni->nr_extents > 0 )
{
extent_nis = base_ni->extent_nis;
for (i = 0; i < base_ni->nr_extents; i++) {
for ( i = 0; i < base_ni->nr_extents; i++ )
{
u16 seq_no;
ni = extent_nis[i];
@ -597,7 +638,8 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
/* Verify the sequence number if given. */
seq_no = MSEQNO_LE( mref );
if ( seq_no && seq_no != le16_to_cpu(
ni->mrec->sequence_number)) {
ni->mrec->sequence_number ) )
{
errno = EIO;
ntfs_log_perror( "Found stale extent mft "
"reference mft=%lld",
@ -617,13 +659,15 @@ ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref)
ni->nr_extents = -1;
ni->base_ni = base_ni;
/* Attach extent inode to base inode, reallocating memory if needed. */
if (!(base_ni->nr_extents & 3)) {
if ( !( base_ni->nr_extents & 3 ) )
{
i = ( base_ni->nr_extents + 4 ) * sizeof( ntfs_inode * );
extent_nis = ntfs_malloc( i );
if ( !extent_nis )
goto err_out;
if (base_ni->nr_extents) {
if ( base_ni->nr_extents )
{
memcpy( extent_nis, base_ni->extent_nis,
i - 4 * sizeof( ntfs_inode * ) );
free( base_ni->extent_nis );
@ -651,7 +695,8 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
ATTR_LIST_ENTRY *ale;
u64 prev_attached = 0;
if (!ni) {
if ( !ni )
{
ntfs_log_trace( "Invalid arguments.\n" );
errno = EINVAL;
return -1;
@ -666,7 +711,8 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
if ( !NInoAttrList( ni ) )
return 0;
if (!ni->attr_list) {
if ( !ni->attr_list )
{
ntfs_log_trace( "Corrupt in-memory struct.\n" );
errno = EINVAL;
return -1;
@ -675,10 +721,13 @@ int ntfs_inode_attach_all_extents(ntfs_inode *ni)
/* Walk through attribute list and attach all extents. */
errno = 0;
ale = ( ATTR_LIST_ENTRY * )ni->attr_list;
while ((u8*)ale < ni->attr_list + ni->attr_list_size) {
while ( ( u8* )ale < ni->attr_list + ni->attr_list_size )
{
if ( ni->mft_no != MREF_LE( ale->mft_reference ) &&
prev_attached != MREF_LE(ale->mft_reference)) {
if (!ntfs_extent_inode_open(ni, ale->mft_reference)) {
prev_attached != MREF_LE( ale->mft_reference ) )
{
if ( !ntfs_extent_inode_open( ni, ale->mft_reference ) )
{
ntfs_log_trace( "Couldn't attach extent inode.\n" );
return -1;
}
@ -708,7 +757,8 @@ static int ntfs_inode_sync_standard_information(ntfs_inode *ni)
if ( !ctx )
return -1;
if ( ntfs_attr_lookup( AT_STANDARD_INFORMATION, AT_UNNAMED,
0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
0, CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
ntfs_log_perror( "Failed to sync standard info (inode %lld)",
( long long )ni->mft_no );
ntfs_attr_put_search_ctx( ctx );
@ -717,7 +767,8 @@ static int ntfs_inode_sync_standard_information(ntfs_inode *ni)
std_info = ( STANDARD_INFORMATION * )( ( u8 * )ctx->attr +
le16_to_cpu( ctx->attr->value_offset ) );
std_info->file_attributes = ni->flags;
if (!test_nino_flag(ni, TimesSet)) {
if ( !test_nino_flag( ni, TimesSet ) )
{
std_info->creation_time = ni->creation_time;
std_info->last_data_change_time = ni->last_data_change_time;
std_info->last_mft_change_time = ni->last_mft_change_time;
@ -732,7 +783,8 @@ static int ntfs_inode_sync_standard_information(ntfs_inode *ni)
&& ( lth <= sizeof( STANDARD_INFORMATION ) ) )
ntfs_log_error( "bad sync of standard information\n" );
if (lth > sizeof(STANDARD_INFORMATION)) {
if ( lth > sizeof( STANDARD_INFORMATION ) )
{
std_info->owner_id = ni->owner_id;
std_info->security_id = ni->security_id;
std_info->quota_charged = ni->quota_charged;
@ -765,15 +817,18 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
ntfs_log_trace( "Entering for inode %lld\n", ( long long )ni->mft_no );
ctx = ntfs_attr_get_search_ctx( ni, NULL );
if (!ctx) {
if ( !ctx )
{
err = errno;
goto err_out;
}
/* Collect the reparse tag, if any */
reparse_tag = cpu_to_le32( 0 );
if (ni->flags & FILE_ATTR_REPARSE_POINT) {
if ( ni->flags & FILE_ATTR_REPARSE_POINT )
{
if ( !ntfs_attr_lookup( AT_REPARSE_POINT, NULL,
0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
0, CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
rpp = ( REPARSE_POINT* )( ( u8 * )ctx->attr +
le16_to_cpu( ctx->attr->value_offset ) );
reparse_tag = rpp->reparse_tag;
@ -781,10 +836,12 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
ntfs_attr_reinit_search_ctx( ctx );
}
/* Walk through all FILE_NAME attributes and update them. */
while (!ntfs_attr_lookup(AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, ctx)) {
while ( !ntfs_attr_lookup( AT_FILE_NAME, NULL, 0, 0, 0, NULL, 0, ctx ) )
{
fn = ( FILE_NAME_ATTR * )( ( u8 * )ctx->attr +
le16_to_cpu( ctx->attr->value_offset ) );
if (MREF_LE(fn->parent_directory) == ni->mft_no) {
if ( MREF_LE( fn->parent_directory ) == ni->mft_no )
{
/*
* WARNING: We cheat here and obtain 2 attribute
* search contexts for one inode (first we obtained
@ -793,13 +850,14 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
* but will deadlock in the kernel.
*/
index_ni = ni;
} else
if (dir_ni)
}
else if ( dir_ni )
index_ni = dir_ni;
else
index_ni = ntfs_inode_open( ni->vol,
le64_to_cpu( fn->parent_directory ) );
if (!index_ni) {
if ( !index_ni )
{
if ( !err )
err = errno;
ntfs_log_perror( "Failed to open inode %lld with index",
@ -807,7 +865,8 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
continue;
}
ictx = ntfs_index_ctx_get( index_ni, NTFS_INDEX_I30, 4 );
if (!ictx) {
if ( !ictx )
{
if ( !err )
err = errno;
ntfs_log_perror( "Failed to get index ctx, inode %lld",
@ -817,8 +876,10 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
err = errno;
continue;
}
if (ntfs_index_lookup(fn, sizeof(FILE_NAME_ATTR), ictx)) {
if (!err) {
if ( ntfs_index_lookup( fn, sizeof( FILE_NAME_ATTR ), ictx ) )
{
if ( !err )
{
if ( errno == ENOENT )
err = EIO;
else
@ -839,18 +900,22 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
if ( ni->mrec->flags & MFT_RECORD_IS_DIRECTORY )
fnx->data_size = fnx->allocated_size
= const_cpu_to_le64( 0 );
else {
else
{
fnx->allocated_size = cpu_to_sle64( ni->allocated_size );
fnx->data_size = cpu_to_sle64( ni->data_size );
}
/* update or clear the reparse tag in the index */
fnx->reparse_point_tag = reparse_tag;
if (!test_nino_flag(ni, TimesSet)) {
if ( !test_nino_flag( ni, TimesSet ) )
{
fnx->creation_time = ni->creation_time;
fnx->last_data_change_time = ni->last_data_change_time;
fnx->last_mft_change_time = ni->last_mft_change_time;
fnx->last_access_time = ni->last_access_time;
} else {
}
else
{
fnx->creation_time = fn->creation_time;
fnx->last_data_change_time = fn->last_data_change_time;
fnx->last_mft_change_time = fn->last_mft_change_time;
@ -863,14 +928,16 @@ static int ntfs_inode_sync_file_name(ntfs_inode *ni, ntfs_inode *dir_ni)
err = errno;
}
/* Check for real error occurred. */
if (errno != ENOENT) {
if ( errno != ENOENT )
{
err = errno;
ntfs_log_perror( "Attribute lookup failed, inode %lld",
( long long )ni->mft_no );
goto err_out;
}
ntfs_attr_put_search_ctx( ctx );
if (err) {
if ( err )
{
errno = err;
return -1;
}
@ -905,7 +972,8 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
{
int ret = 0;
int err = 0;
if (!ni) {
if ( !ni )
{
errno = EINVAL;
ntfs_log_error( "Failed to sync NULL inode\n" );
return -1;
@ -915,8 +983,10 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
/* Update STANDARD_INFORMATION. */
if ( ( ni->mrec->flags & MFT_RECORD_IN_USE ) && ni->nr_extents != -1 &&
ntfs_inode_sync_standard_information(ni)) {
if (!err || errno == EIO) {
ntfs_inode_sync_standard_information( ni ) )
{
if ( !err || errno == EIO )
{
err = errno;
if ( err != EIO )
err = EBUSY;
@ -926,8 +996,10 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
/* Update FILE_NAME's in the index. */
if ( ( ni->mrec->flags & MFT_RECORD_IN_USE ) && ni->nr_extents != -1 &&
NInoFileNameTestAndClearDirty( ni ) &&
ntfs_inode_sync_file_name(ni, dir_ni)) {
if (!err || errno == EIO) {
ntfs_inode_sync_file_name( ni, dir_ni ) )
{
if ( !err || errno == EIO )
{
err = errno;
if ( err != EIO )
err = EBUSY;
@ -939,12 +1011,15 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
/* Write out attribute list from cache to disk. */
if ( ( ni->mrec->flags & MFT_RECORD_IN_USE ) && ni->nr_extents != -1 &&
NInoAttrList(ni) && NInoAttrListTestAndClearDirty(ni)) {
NInoAttrList( ni ) && NInoAttrListTestAndClearDirty( ni ) )
{
ntfs_attr *na;
na = ntfs_attr_open( ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0 );
if (!na) {
if (!err || errno == EIO) {
if ( !na )
{
if ( !err || errno == EIO )
{
err = errno;
if ( err != EIO )
err = EBUSY;
@ -956,10 +1031,13 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
goto sync_inode;
}
if (na->data_size == ni->attr_list_size) {
if ( na->data_size == ni->attr_list_size )
{
if ( ntfs_attr_pwrite( na, 0, ni->attr_list_size,
ni->attr_list) != ni->attr_list_size) {
if (!err || errno == EIO) {
ni->attr_list ) != ni->attr_list_size )
{
if ( !err || errno == EIO )
{
err = errno;
if ( err != EIO )
err = EBUSY;
@ -969,7 +1047,9 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
}
NInoAttrListSetDirty( ni );
}
} else {
}
else
{
err = EIO;
ntfs_log_error( "Attribute list sync failed (bad size, "
"inode %lld)\n", ( long long )ni->mft_no );
@ -980,9 +1060,12 @@ static int ntfs_inode_sync_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
sync_inode:
/* Write this inode out to the $MFT (and $MFTMirr if applicable). */
if (NInoTestAndClearDirty(ni)) {
if (ntfs_mft_record_write(ni->vol, ni->mft_no, ni->mrec)) {
if (!err || errno == EIO) {
if ( NInoTestAndClearDirty( ni ) )
{
if ( ntfs_mft_record_write( ni->vol, ni->mft_no, ni->mrec ) )
{
if ( !err || errno == EIO )
{
err = errno;
if ( err != EIO )
err = EBUSY;
@ -994,10 +1077,12 @@ sync_inode:
}
/* If this is a base inode with extents write all dirty extents, too. */
if (ni->nr_extents > 0) {
if ( ni->nr_extents > 0 )
{
s32 i;
for (i = 0; i < ni->nr_extents; ++i) {
for ( i = 0; i < ni->nr_extents; ++i )
{
ntfs_inode *eni;
eni = ni->extent_nis[i];
@ -1005,8 +1090,10 @@ sync_inode:
continue;
if ( ntfs_mft_record_write( eni->vol, eni->mft_no,
eni->mrec)) {
if (!err || errno == EIO) {
eni->mrec ) )
{
if ( !err || errno == EIO )
{
err = errno;
if ( err != EIO )
err = EBUSY;
@ -1020,7 +1107,8 @@ sync_inode:
}
}
if (err) {
if ( err )
{
errno = err;
ret = -1;
}
@ -1043,10 +1131,12 @@ int ntfs_inode_close_in_dir(ntfs_inode *ni, ntfs_inode *dir_ni)
int res;
res = ntfs_inode_sync_in_dir( ni, dir_ni );
if (res) {
if ( res )
{
if ( errno != EIO )
errno = EBUSY;
} else
}
else
res = ntfs_inode_close( ni );
return ( res );
}
@ -1071,7 +1161,8 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
ATTR_LIST_ENTRY *ale = NULL;
ntfs_attr *na;
if (!ni) {
if ( !ni )
{
errno = EINVAL;
ntfs_log_perror( "%s", __FUNCTION__ );
return -1;
@ -1079,7 +1170,8 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
ntfs_log_trace( "inode %llu\n", ( unsigned long long ) ni->mft_no );
if (NInoAttrList(ni) || ni->nr_extents) {
if ( NInoAttrList( ni ) || ni->nr_extents )
{
errno = EEXIST;
ntfs_log_perror( "Inode already has attribute list" );
return -1;
@ -1087,16 +1179,19 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
/* Form attribute list. */
ctx = ntfs_attr_get_search_ctx( ni, NULL );
if (!ctx) {
if ( !ctx )
{
err = errno;
goto err_out;
}
/* Walk through all attributes. */
while (!ntfs_attr_lookup(AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx)) {
while ( !ntfs_attr_lookup( AT_UNUSED, NULL, 0, 0, 0, NULL, 0, ctx ) )
{
int ale_size;
if (ctx->attr->type == AT_ATTRIBUTE_LIST) {
if ( ctx->attr->type == AT_ATTRIBUTE_LIST )
{
err = EIO;
ntfs_log_perror( "Attribute list already present" );
goto put_err_out;
@ -1107,7 +1202,8 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
al_len += ale_size;
aln = realloc( al, al_len );
if (!aln) {
if ( !aln )
{
err = errno;
ntfs_log_perror( "Failed to realloc %d bytes", al_len );
goto put_err_out;
@ -1136,7 +1232,8 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
ale = ( ATTR_LIST_ENTRY * )( al + al_len );
}
/* Check for real error occurred. */
if (errno != ENOENT) {
if ( errno != ENOENT )
{
err = errno;
ntfs_log_perror( "%s: Attribute lookup failed, inode %lld",
__FUNCTION__, ( long long )ni->mft_no );
@ -1152,9 +1249,11 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
/* Free space if there is not enough it for $ATTRIBUTE_LIST. */
if ( le32_to_cpu( ni->mrec->bytes_allocated ) -
le32_to_cpu( ni->mrec->bytes_in_use ) <
offsetof(ATTR_RECORD, resident_end)) {
offsetof( ATTR_RECORD, resident_end ) )
{
if ( ntfs_inode_free_space( ni,
offsetof(ATTR_RECORD, resident_end))) {
offsetof( ATTR_RECORD, resident_end ) ) )
{
/* Failed to free space. */
err = errno;
ntfs_log_perror( "Failed to free space for attrlist" );
@ -1164,7 +1263,8 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
/* Add $ATTRIBUTE_LIST to mft record. */
if ( ntfs_resident_attr_record_add( ni,
AT_ATTRIBUTE_LIST, NULL, 0, NULL, 0, 0) < 0) {
AT_ATTRIBUTE_LIST, NULL, 0, NULL, 0, 0 ) < 0 )
{
err = errno;
ntfs_log_perror( "Couldn't add $ATTRIBUTE_LIST to MFT" );
goto rollback;
@ -1172,12 +1272,14 @@ int ntfs_inode_add_attrlist(ntfs_inode *ni)
/* Resize it. */
na = ntfs_attr_open( ni, AT_ATTRIBUTE_LIST, AT_UNNAMED, 0 );
if (!na) {
if ( !na )
{
err = errno;
ntfs_log_perror( "Failed to open just added $ATTRIBUTE_LIST" );
goto remove_attrlist_record;
}
if (ntfs_attr_truncate(na, al_len)) {
if ( ntfs_attr_truncate( na, al_len ) )
{
err = errno;
ntfs_log_perror( "Failed to resize just added $ATTRIBUTE_LIST" );
ntfs_attr_close( na );
@ -1195,10 +1297,12 @@ remove_attrlist_record:
/* Remove $ATTRIBUTE_LIST record. */
ntfs_attr_reinit_search_ctx( ctx );
if ( !ntfs_attr_lookup( AT_ATTRIBUTE_LIST, NULL, 0,
CASE_SENSITIVE, 0, NULL, 0, ctx)) {
CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
if ( ntfs_attr_record_rm( ctx ) )
ntfs_log_perror( "Rollback failed to remove attrlist" );
} else
}
else
ntfs_log_perror( "Rollback failed to find attrlist" );
/* Setup back in-memory runlist. */
ni->attr_list = al;
@ -1211,17 +1315,21 @@ rollback:
*/
ntfs_attr_reinit_search_ctx( ctx );
ale = ( ATTR_LIST_ENTRY* )al;
while ((u8*)ale < al + al_len) {
if (MREF_LE(ale->mft_reference) != ni->mft_no) {
while ( ( u8* )ale < al + al_len )
{
if ( MREF_LE( ale->mft_reference ) != ni->mft_no )
{
if ( !ntfs_attr_lookup( ale->type, ale->name,
ale->name_length,
CASE_SENSITIVE,
sle64_to_cpu( ale->lowest_vcn ),
NULL, 0, ctx)) {
NULL, 0, ctx ) )
{
if ( ntfs_attr_record_move_to( ctx, ni ) )
ntfs_log_perror( "Rollback failed to "
"move attribute" );
} else
}
else
ntfs_log_perror( "Rollback failed to find attr" );
ntfs_attr_reinit_search_ctx( ctx );
}
@ -1252,7 +1360,8 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
ntfs_attr_search_ctx *ctx;
int freed;
if (!ni || size < 0) {
if ( !ni || size < 0 )
{
errno = EINVAL;
ntfs_log_perror( "%s: ni=%p size=%d", __FUNCTION__, ni, size );
return -1;
@ -1277,13 +1386,15 @@ int ntfs_inode_free_space(ntfs_inode *ni, int size)
if ( ntfs_attr_position( AT_FILE_NAME, ctx ) )
goto put_err_out;
while (1) {
while ( 1 )
{
int record_size;
/*
* Check whether attribute is from different MFT record. If so,
* find next, because we don't need such.
*/
while (ctx->ntfs_ino->mft_no != ni->mft_no) {
while ( ctx->ntfs_ino->mft_no != ni->mft_no )
{
retry:
if ( ntfs_attr_position( AT_UNUSED, ctx ) )
goto put_err_out;
@ -1298,14 +1409,16 @@ retry:
record_size = le32_to_cpu( ctx->attr->length );
if (ntfs_attr_record_move_away(ctx, 0)) {
if ( ntfs_attr_record_move_away( ctx, 0 ) )
{
ntfs_log_perror( "Failed to move out attribute #2" );
break;
}
freed += record_size;
/* Check whether we are done. */
if (size <= freed) {
if ( size <= freed )
{
ntfs_attr_put_search_ctx( ctx );
return 0;
}
@ -1339,7 +1452,8 @@ void ntfs_inode_update_times(ntfs_inode *ni, ntfs_time_update_flags mask)
{
ntfs_time now;
if (!ni) {
if ( !ni )
{
ntfs_log_error( "%s(): Invalid arguments.\n", __FUNCTION__ );
return;
}
@ -1377,7 +1491,8 @@ int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr)
int len, ret = 0;
ntfschar *ustr;
if (!attr) {
if ( !attr )
{
ntfs_log_error( "Invalid argument.\n" );
errno = EINVAL;
return -1;
@ -1389,7 +1504,8 @@ int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *attr)
if ( attr->type != AT_DATA )
return 0;
if ((ustr = ntfs_str2ucs("$Bad", &len)) == NULL) {
if ( ( ustr = ntfs_str2ucs( "$Bad", &len ) ) == NULL )
{
ntfs_log_perror( "Couldn't convert '$Bad' to Unicode" );
return -1;
}
@ -1425,32 +1541,40 @@ int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size)
ret = 0;
ctx = ntfs_attr_get_search_ctx( ni, NULL );
if (ctx) {
if ( ctx )
{
if ( ntfs_attr_lookup( AT_STANDARD_INFORMATION, AT_UNNAMED,
0, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
0, CASE_SENSITIVE, 0, NULL, 0, ctx ) )
{
ntfs_log_perror( "Failed to get standard info (inode %lld)",
( long long )ni->mft_no );
} else {
}
else
{
std_info = ( STANDARD_INFORMATION * )( ( u8 * )ctx->attr +
le16_to_cpu( ctx->attr->value_offset ) );
if (value && (size >= 8)) {
if ( value && ( size >= 8 ) )
{
times = ( u64* )value;
times[0] = le64_to_cpu( std_info->creation_time );
ret = 8;
if (size >= 16) {
if ( size >= 16 )
{
times[1] = le64_to_cpu( std_info->last_data_change_time );
ret = 16;
}
if (size >= 24) {
if ( size >= 24 )
{
times[2] = le64_to_cpu( std_info->last_access_time );
ret = 24;
}
if (size >= 32) {
if ( size >= 32 )
{
times[3] = le64_to_cpu( std_info->last_mft_change_time );
ret = 32;
}
} else
if (!size)
}
else if ( !size )
ret = 32;
else
ret = -ERANGE;
@ -1486,18 +1610,23 @@ int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size,
int ret;
ret = -1;
if ((size >= 8) && !(flags & XATTR_CREATE)) {
if ( ( size >= 8 ) && !( flags & XATTR_CREATE ) )
{
times = ( const u64* )value;
now = ntfs_current_time();
/* update the standard information attribute */
ctx = ntfs_attr_get_search_ctx( ni, NULL );
if (ctx) {
if ( ctx )
{
if ( ntfs_attr_lookup( AT_STANDARD_INFORMATION,
AT_UNNAMED, 0, CASE_SENSITIVE,
0, NULL, 0, ctx)) {
0, NULL, 0, ctx ) )
{
ntfs_log_perror( "Failed to get standard info (inode %lld)",
( long long )ni->mft_no );
} else {
}
else
{
std_info = ( STANDARD_INFORMATION * )( ( u8 * )ctx->attr +
le16_to_cpu( ctx->attr->value_offset ) );
/*
@ -1512,12 +1641,14 @@ int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size,
std_info->creation_time = cpu_to_le64( times[0] );
ni->creation_time
= std_info->creation_time;
if (size >= 16) {
if ( size >= 16 )
{
std_info->last_data_change_time = cpu_to_le64( times[1] );
ni->last_data_change_time
= std_info->last_data_change_time;
}
if (size >= 24) {
if ( size >= 24 )
{
std_info->last_access_time = cpu_to_le64( times[2] );
ni->last_access_time
= std_info->last_access_time;
@ -1532,7 +1663,8 @@ int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size,
cnt = 0;
while ( !ntfs_attr_lookup( AT_FILE_NAME,
AT_UNNAMED, 0, CASE_SENSITIVE,
0, NULL, 0, ctx)) {
0, NULL, 0, ctx ) )
{
fn = ( FILE_NAME_ATTR* )( ( u8 * )ctx->attr +
le16_to_cpu( ctx->attr->value_offset ) );
fn->creation_time
@ -1548,15 +1680,16 @@ int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size,
}
if ( cnt )
ret = 0;
else {
else
{
ntfs_log_perror( "Failed to get file names (inode %lld)",
( long long )ni->mft_no );
}
}
ntfs_attr_put_search_ctx( ctx );
}
} else
if (size < 8)
}
else if ( size < 8 )
errno = ERANGE;
else
errno = EEXIST;

View File

@ -40,7 +40,8 @@ typedef struct _ntfs_inode ntfs_inode;
* Defined bits for the state field in the ntfs_inode structure.
* (f) = files only, (d) = directories only
*/
typedef enum {
typedef enum
{
NI_Dirty, /* 1: Mft record needs to be written to disk. */
/* The NI_AttrList* tests only make sense for base inodes. */
@ -103,7 +104,8 @@ typedef enum {
* It is just used as an extension to the fields already provided in the VFS
* inode.
*/
struct _ntfs_inode {
struct _ntfs_inode
{
u64 mft_no; /* Inode / mft record number. */
MFT_RECORD *mrec; /* The actual mft record of the inode. */
ntfs_volume *vol; /* Pointer to the ntfs volume of this inode. */
@ -122,7 +124,8 @@ struct _ntfs_inode {
s32 nr_extents; /* For a base mft record, the number of
attached extent inodes (0 if none), for
extent records this is -1. */
union { /* This union is only used if nr_extents != 0. */
union /* This union is only used if nr_extents != 0. */
{
ntfs_inode **extent_nis;/* For nr_extents > 0, array of the
ntfs inodes of the extent mft
records belonging to this base
@ -166,7 +169,8 @@ struct _ntfs_inode {
le64 usn;
};
typedef enum {
typedef enum
{
NTFS_UPDATE_ATIME = 1 << 0,
NTFS_UPDATE_MTIME = 1 << 1,
NTFS_UPDATE_CTIME = 1 << 2,

View File

@ -46,7 +46,8 @@
/**
* struct BIOS_PARAMETER_BLOCK - BIOS parameter block (bpb) structure.
*/
typedef struct {
typedef struct
{
u16 bytes_per_sector; /* Size of a sector in bytes. */
u8 sectors_per_cluster; /* Size of a cluster in sectors. */
u16 reserved_sectors; /* zero */
@ -67,7 +68,8 @@ typedef struct {
/**
* struct NTFS_BOOT_SECTOR - NTFS boot sector structure.
*/
typedef struct {
typedef struct
{
u8 jump[3]; /* Irrelevant (jump to boot up code).*/
u64 oem_id; /* Magic "NTFS ". */
/*0x0b*/BIOS_PARAMETER_BLOCK bpb; /* See BIOS_PARAMETER_BLOCK. */
@ -100,7 +102,8 @@ typedef struct {
* Magic identifiers present at the beginning of all ntfs record containing
* records (like mft records for example).
*/
typedef enum {
typedef enum
{
/* Found in $MFT/$DATA. */
magic_FILE = const_cpu_to_le32( 0x454c4946 ), /* Mft entry. */
magic_INDX = const_cpu_to_le32( 0x58444e49 ), /* Index buffer. */
@ -182,7 +185,8 @@ typedef enum {
* This formula can be used as a consistency check in that usa_ofs +
* (usa_count * 2) has to be less than or equal to 510.
*/
typedef struct {
typedef struct
{
NTFS_RECORD_TYPES magic;/* A four-byte magic identifying the
record type and/or status. */
u16 usa_ofs; /* Offset to the Update Sequence Array (usa)
@ -201,7 +205,8 @@ typedef struct {
* mft records. Also, the sequence number for each of the system files is
* always equal to their mft record number and it is never modified.
*/
typedef enum {
typedef enum
{
FILE_MFT = 0, /* Master file table (mft). Data attribute
contains the entries and bitmap attribute
records which ones are in use (bit==1). */
@ -254,7 +259,8 @@ typedef enum {
* index, that means an INDEX_ROOT and an INDEX_ALLOCATION with a name other
* than "$I30". It is unknown if it is limited to metadata files only.
*/
typedef enum {
typedef enum
{
MFT_RECORD_IN_USE = const_cpu_to_le16( 0x0001 ),
MFT_RECORD_IS_DIRECTORY = const_cpu_to_le16( 0x0002 ),
MFT_RECORD_IS_4 = const_cpu_to_le16( 0x0004 ),
@ -335,7 +341,8 @@ typedef u64 MFT_REF;
* in that it only consists of the attribute type code AT_END and none of the
* other members of the attribute structure are present.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
NTFS_RECORD_TYPES magic;/* Usually the magic is "FILE". */
@ -409,7 +416,8 @@ typedef struct {
*
* This is the version without the NTFS 3.1+ specific fields.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
NTFS_RECORD_TYPES magic;/* Usually the magic is "FILE". */
@ -486,7 +494,8 @@ typedef struct {
* enum exchanging AT_ for the dollar sign ($). If that isn't a revealing
* choice of symbol... (-;
*/
typedef enum {
typedef enum
{
AT_UNUSED = const_cpu_to_le32( 0 ),
AT_STANDARD_INFORMATION = const_cpu_to_le32( 0x10 ),
AT_ATTRIBUTE_LIST = const_cpu_to_le32( 0x20 ),
@ -545,7 +554,8 @@ typedef enum {
* the 2nd object_id. If the first u32 values of both object_ids were
* equal then the second u32 values would be compared, etc.
*/
typedef enum {
typedef enum
{
COLLATION_BINARY = const_cpu_to_le32( 0 ), /* Collate by binary
compare where the first byte is most
significant. */
@ -573,7 +583,8 @@ typedef enum {
* name attribute has this flag set and this is the only attribute indexed in
* NT4.
*/
typedef enum {
typedef enum
{
ATTR_DEF_INDEXABLE = const_cpu_to_le32( 0x02 ), /* Attribute can be
indexed. */
ATTR_DEF_MULTIPLE = const_cpu_to_le32( 0x04 ), /* Attribute type
@ -611,9 +622,11 @@ typedef enum {
* attribute can be resident/non-resident and possibly other things, but the
* actual bits are unknown.
*/
typedef struct {
typedef struct
{
/*hex ofs*/
/* 0*/ ntfschar name[0x40]; /* Unicode name of the attribute. Zero
/* 0*/
ntfschar name[0x40]; /* Unicode name of the attribute. Zero
terminated. */
/* 80*/ ATTR_TYPES type; /* Type of the attribute. */
/* 84*/ u32 display_rule; /* Default display rule.
@ -628,7 +641,8 @@ typedef struct {
/**
* enum ATTR_FLAGS - Attribute flags (16-bit).
*/
typedef enum {
typedef enum
{
ATTR_IS_COMPRESSED = const_cpu_to_le16( 0x0001 ),
ATTR_COMPRESSION_MASK = const_cpu_to_le16( 0x00ff ), /* Compression
method mask. Also, first
@ -707,7 +721,8 @@ typedef enum {
/**
* enum RESIDENT_ATTR_FLAGS - Flags of resident attributes (8-bit).
*/
typedef enum {
typedef enum
{
RESIDENT_ATTR_IS_INDEXED = 0x01, /* Attribute is referenced in an index
(has implications for deleting and
modifying the attribute). */
@ -718,9 +733,11 @@ typedef enum {
*
* Always aligned to 8-byte boundary.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0*/ ATTR_TYPES type; /* The (32-bit) type of the attribute. */
/* 0*/
ATTR_TYPES type; /* The (32-bit) type of the attribute. */
/* 4*/ u32 length; /* Byte size of the resident part of the
attribute (aligned to 8-byte boundary).
Used to get to the next attribute. */
@ -742,10 +759,13 @@ typedef struct {
number is unique within this mft record (see
MFT_RECORD/next_attribute_instance notes
above for more details). */
/* 16*/ union {
/* 16*/ union
{
/* Resident attributes. */
struct {
/* 16 */ u32 value_length; /* Byte size of attribute value. */
struct
{
/* 16 */
u32 value_length; /* Byte size of attribute value. */
/* 20 */ u16 value_offset; /* Byte offset of the attribute
value from the start of the
attribute record. When creating,
@ -761,8 +781,10 @@ typedef struct {
a resident attribute. */
} __attribute__( ( __packed__ ) );
/* Non-resident attributes. */
struct {
/* 16*/ VCN lowest_vcn; /* Lowest valid virtual cluster number
struct
{
/* 16*/
VCN lowest_vcn; /* Lowest valid virtual cluster number
for this portion of the attribute value or
0 if this is the only extent (usually the
case). - Only when an attribute list is used
@ -825,7 +847,8 @@ typedef ATTR_RECORD ATTR_REC;
/**
* enum FILE_ATTR_FLAGS - File attribute flags (32-bit).
*/
typedef enum {
typedef enum
{
/*
* These flags are only present in the STANDARD_INFORMATION attribute
* (in the field file_attributes).
@ -905,9 +928,11 @@ typedef enum {
* correct by practical experimentation on Windows NT4 SP6a and is hence
* assumed to be the one and only correct interpretation.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0*/ s64 creation_time; /* Time file was created. Updated when
/* 0*/
s64 creation_time; /* Time file was created. Updated when
a filename is changed(?). */
/* 8*/ s64 last_data_change_time; /* Time the data attribute was last
modified. */
@ -922,16 +947,20 @@ typedef struct {
last access times updates can be
disabled altogether for speed. */
/* 32*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
/* 36*/ union {
/* 36*/ union
{
/* NTFS 1.2 (and previous, presumably) */
struct {
/* 36 */ u8 reserved12[12]; /* Reserved/alignment to 8-byte
struct
{
/* 36 */
u8 reserved12[12]; /* Reserved/alignment to 8-byte
boundary. */
/* 48 */ void *v1_end[0]; /* Marker for offsetof(). */
} __attribute__( ( __packed__ ) );
/* sizeof() = 48 bytes */
/* NTFS 3.0 */
struct {
struct
{
/*
* If a volume has been upgraded from a previous NTFS version, then these
* fields are present only if the file has been accessed since the upgrade.
@ -951,7 +980,8 @@ typedef struct {
* views that as a corruption, assuming that it behaves like this for all
* attributes.
*/
/* 36*/ u32 maximum_versions; /* Maximum allowed versions for
/* 36*/
u32 maximum_versions; /* Maximum allowed versions for
file. Zero if version numbering is disabled. */
/* 40*/ u32 version_number; /* This file's version (if any).
Set to zero if maximum_versions is zero. */
@ -1016,9 +1046,11 @@ typedef struct {
* NTFS 3.0 volumes).
* - There are many named streams.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0*/ ATTR_TYPES type; /* Type of referenced attribute. */
/* 0*/
ATTR_TYPES type; /* Type of referenced attribute. */
/* 4*/ u16 length; /* Byte size of this entry. */
/* 6*/ u8 name_length; /* Size in Unicode chars of the name of the
attribute or 0 if unnamed. */
@ -1057,7 +1089,8 @@ typedef struct {
* enum FILE_NAME_TYPE_FLAGS - Possible namespaces for filenames in ntfs.
* (8-bit).
*/
typedef enum {
typedef enum
{
FILE_NAME_POSIX = 0x00,
/* This is the largest namespace. It is case sensitive and
allows all Unicode characters except for: '\0' and '/'.
@ -1093,9 +1126,11 @@ typedef enum {
* correct by practical experimentation on Windows NT4 SP6a and is hence
* assumed to be the one and only correct interpretation.
*/
typedef struct {
typedef struct
{
/*hex ofs*/
/* 0*/ MFT_REF parent_directory; /* Directory this filename is
/* 0*/
MFT_REF parent_directory; /* Directory this filename is
referenced from. */
/* 8*/ s64 creation_time; /* Time file was created. */
/* 10*/ s64 last_data_change_time; /* Time the data attribute was last
@ -1116,9 +1151,13 @@ typedef struct {
/* 30*/ s64 data_size; /* Byte size of actual data in data
attribute. */
/* 38*/ FILE_ATTR_FLAGS file_attributes; /* Flags describing the file. */
/* 3c*/ union {
/* 3c*/ struct {
/* 3c*/ u16 packed_ea_size; /* Size of the buffer needed to
/* 3c*/ union
{
/* 3c*/
struct
{
/* 3c*/
u16 packed_ea_size; /* Size of the buffer needed to
pack the extended attributes
(EAs), if such are present.*/
/* 3e*/ u16 reserved; /* Reserved for alignment. */
@ -1146,7 +1185,8 @@ typedef struct {
* Example of a GUID:
* 1F010768-5A73-BC91-0010-A52216A7227B
*/
typedef struct {
typedef struct
{
u32 data1; /* The first eight hexadecimal digits of the GUID. */
u16 data2; /* The first group of four hexadecimal digits. */
u16 data3; /* The second group of four hexadecimal digits. */
@ -1168,11 +1208,14 @@ typedef struct {
* equals the object_id. Optional (i.e. can be zero).
* domain_id - Reserved (always zero).
*/
typedef struct {
typedef struct
{
MFT_REF mft_reference; /* Mft record containing the object_id in
the index entry key. */
union {
struct {
union
{
struct
{
GUID birth_volume_id;
GUID birth_object_id;
GUID domain_id;
@ -1186,7 +1229,8 @@ typedef struct {
*
* NOTE: Always resident.
*/
typedef struct {
typedef struct
{
GUID object_id; /* Unique id assigned to the
file.*/
/* The following fields are optional. The attribute value size is 16
@ -1196,8 +1240,10 @@ typedef struct {
when the fields are missing here, it is well possible that they are
to be found within the $Extend/$ObjId system file indexed under the
above object_id. */
union {
struct {
union
{
struct
{
GUID birth_volume_id; /* Unique id of volume on which
the file was first created.*/
GUID birth_object_id; /* Unique id of file when it was
@ -1215,7 +1261,8 @@ typedef struct {
* The pre-defined IDENTIFIER_AUTHORITIES used as SID_IDENTIFIER_AUTHORITY in
* the SID structure (see below).
*/
typedef enum { /* SID string prefix. */
typedef enum /* SID string prefix. */
{
SECURITY_NULL_SID_AUTHORITY = {0, 0, 0, 0, 0, 0}, /* S-1-0 */
SECURITY_WORLD_SID_AUTHORITY = {0, 0, 0, 0, 0, 1}, /* S-1-1 */
SECURITY_LOCAL_SID_AUTHORITY = {0, 0, 0, 0, 0, 2}, /* S-1-2 */
@ -1237,7 +1284,8 @@ typedef enum { /* SID string prefix. */
* made up of the identifier authority SECURITY_CREATOR_SID_AUTHORITY (3) and
* the relative identifier SECURITY_CREATOR_OWNER_RID (0).
*/
typedef enum { /* Identifier authority. */
typedef enum /* Identifier authority. */
{
SECURITY_NULL_RID = 0, /* S-1-0 */
SECURITY_WORLD_RID = 0, /* S-1-1 */
SECURITY_LOCAL_RID = 0, /* S-1-2 */
@ -1349,8 +1397,10 @@ typedef enum { /* Identifier authority. */
*
* NOTE: This is stored as a big endian number.
*/
typedef union {
struct {
typedef union
{
struct
{
u16 high_part; /* High 16-bits. */
u32 low_part; /* Low 32-bits. */
} __attribute__( ( __packed__ ) );
@ -1385,7 +1435,8 @@ typedef union {
* sub_authority[0] = 32, // SECURITY_BUILTIN_DOMAIN_RID
* sub_authority[1] = 544 // DOMAIN_ALIAS_RID_ADMINS
*/
typedef struct {
typedef struct
{
u8 revision;
u8 sub_authority_count;
SID_IDENTIFIER_AUTHORITY identifier_authority;
@ -1395,7 +1446,8 @@ typedef struct {
/**
* enum SID_CONSTANTS - Current constants for SIDs.
*/
typedef enum {
typedef enum
{
SID_REVISION = 1, /* Current revision level. */
SID_MAX_SUB_AUTHORITIES = 15, /* Maximum number of those. */
SID_RECOMMENDED_SUB_AUTHORITIES = 1, /* Will change to around 6 in
@ -1405,7 +1457,8 @@ typedef enum {
/**
* enum ACE_TYPES - The predefined ACE types (8-bit, see below).
*/
typedef enum {
typedef enum
{
ACCESS_MIN_MS_ACE_TYPE = 0,
ACCESS_ALLOWED_ACE_TYPE = 0,
ACCESS_DENIED_ACE_TYPE = 1,
@ -1440,7 +1493,8 @@ typedef enum {
* FAILED_ACCESS_ACE_FLAG is only used with system audit and alarm ACE types
* to indicate that a message is generated (in Windows!) for failed accesses.
*/
typedef enum {
typedef enum
{
/* The inheritance flags. */
OBJECT_INHERIT_ACE = 0x01,
CONTAINER_INHERIT_ACE = 0x02,
@ -1467,7 +1521,8 @@ typedef enum {
* which specifies the type and size of the ACE. The format of the subsequent
* data depends on the ACE type.
*/
typedef struct {
typedef struct
{
ACE_TYPES type; /* Type of the ACE. */
ACE_FLAGS flags; /* Flags describing the ACE. */
u16 size; /* Size in bytes of the ACE. */
@ -1478,7 +1533,8 @@ typedef struct {
*
* Defines the access rights.
*/
typedef enum {
typedef enum
{
/*
* The specific rights (bits 0 to 15). Depend on the type of the
* object being secured by the ACE.
@ -1616,7 +1672,8 @@ typedef enum {
*
* FIXME: What exactly is this and what is it for? (AIA)
*/
typedef struct {
typedef struct
{
ACCESS_MASK generic_read;
ACCESS_MASK generic_write;
ACCESS_MASK generic_execute;
@ -1632,7 +1689,8 @@ typedef struct {
*
* ACCESS_ALLOWED_ACE, ACCESS_DENIED_ACE, SYSTEM_AUDIT_ACE, SYSTEM_ALARM_ACE
*/
typedef struct {
typedef struct
{
/* 0 ACE_HEADER; -- Unfolded here as gcc doesn't like unnamed structs. */
ACE_TYPES type; /* Type of the ACE. */
ACE_FLAGS flags; /* Flags describing the ACE. */
@ -1646,7 +1704,8 @@ typedef struct {
/**
* enum OBJECT_ACE_FLAGS - The object ACE flags (32-bit).
*/
typedef enum {
typedef enum
{
ACE_OBJECT_TYPE_PRESENT = const_cpu_to_le32( 1 ),
ACE_INHERITED_OBJECT_TYPE_PRESENT = const_cpu_to_le32( 2 ),
} OBJECT_ACE_FLAGS;
@ -1654,7 +1713,8 @@ typedef enum {
/**
* struct ACCESS_ALLOWED_OBJECT_ACE -
*/
typedef struct {
typedef struct
{
/* 0 ACE_HEADER; -- Unfolded here as gcc doesn't like unnamed structs. */
ACE_TYPES type; /* Type of the ACE. */
ACE_FLAGS flags; /* Flags describing the ACE. */
@ -1678,7 +1738,8 @@ typedef struct {
* zero or more access control entries (ACEs). The ACL as well as each ACE
* are aligned on 4-byte boundaries.
*/
typedef struct {
typedef struct
{
u8 revision; /* Revision of this ACL. */
u8 alignment1;
u16 size; /* Allocated space in bytes for ACL. Includes this
@ -1691,7 +1752,8 @@ typedef struct {
/**
* enum ACL_CONSTANTS - Current constants for ACLs.
*/
typedef enum {
typedef enum
{
/* Current revision. */
ACL_REVISION = 2,
ACL_REVISION_DS = 4,
@ -1754,7 +1816,8 @@ typedef enum {
* and all pointer fields are expressed as offsets from the
* beginning of the security descriptor.
*/
typedef enum {
typedef enum
{
SE_OWNER_DEFAULTED = const_cpu_to_le16( 0x0001 ),
SE_GROUP_DEFAULTED = const_cpu_to_le16( 0x0002 ),
SE_DACL_PRESENT = const_cpu_to_le16( 0x0004 ),
@ -1777,7 +1840,8 @@ typedef enum {
* Self-relative security descriptor. Contains the owner and group SIDs as well
* as the sacl and dacl ACLs inside the security descriptor itself.
*/
typedef struct {
typedef struct
{
u8 revision; /* Revision level of the security descriptor. */
u8 alignment;
SECURITY_DESCRIPTOR_CONTROL control; /* Flags qualifying the type of
@ -1809,7 +1873,8 @@ typedef struct {
*
* On disk, a self-relative security descriptor is used.
*/
typedef struct {
typedef struct
{
u8 revision; /* Revision level of the security descriptor. */
u8 alignment;
SECURITY_DESCRIPTOR_CONTROL control; /* Flags qualifying the type of
@ -1835,7 +1900,8 @@ typedef struct {
*
* Current constants for security descriptors.
*/
typedef enum {
typedef enum
{
/* Current revision. */
SECURITY_DESCRIPTOR_REVISION = 1,
SECURITY_DESCRIPTOR_REVISION1 = 1,
@ -1902,7 +1968,8 @@ typedef SECURITY_DESCRIPTOR_RELATIVE SECURITY_DESCRIPTOR_ATTR;
* This header precedes each security descriptor in the $SDS data stream.
* This is also the index entry data part of both the $SII and $SDH indexes.
*/
typedef struct {
typedef struct
{
u32 hash; /* Hash of the security descriptor. */
u32 security_id; /* The security_id assigned to the descriptor. */
u64 offset; /* Byte offset of this entry in the $SDS stream. */
@ -1912,7 +1979,8 @@ typedef struct {
/**
* struct SDH_INDEX_DATA -
*/
typedef struct {
typedef struct
{
u32 hash; /* Hash of the security descriptor. */
u32 security_id; /* The security_id assigned to the descriptor. */
u64 offset; /* Byte offset of this entry in the $SDS stream. */
@ -1939,7 +2007,8 @@ typedef SECURITY_DESCRIPTOR_HEADER SII_INDEX_DATA;
* the first copy of the security descriptor will be at offset 0x51d0 in the
* $SDS data stream and the second copy will be at offset 0x451d0.
*/
typedef struct {
typedef struct
{
/* 0 SECURITY_DESCRIPTOR_HEADER; -- Unfolded here as gcc doesn't like
unnamed structs. */
u32 hash; /* Hash of the security descriptor. */
@ -1955,7 +2024,8 @@ typedef struct {
*
* The collation type is COLLATION_NTOFS_ULONG.
*/
typedef struct {
typedef struct
{
u32 security_id; /* The security_id assigned to the descriptor. */
} __attribute__( ( __packed__ ) ) SII_INDEX_KEY;
@ -1965,7 +2035,8 @@ typedef struct {
* The keys are sorted first by hash and then by security_id.
* The collation rule is COLLATION_NTOFS_SECURITY_HASH.
*/
typedef struct {
typedef struct
{
u32 hash; /* Hash of the security descriptor. */
u32 security_id; /* The security_id assigned to the descriptor. */
} __attribute__( ( __packed__ ) ) SDH_INDEX_KEY;
@ -1976,14 +2047,16 @@ typedef struct {
* NOTE: Always resident.
* NOTE: Present only in FILE_Volume.
*/
typedef struct {
typedef struct
{
ntfschar name[0]; /* The name of the volume in Unicode. */
} __attribute__( ( __packed__ ) ) VOLUME_NAME;
/**
* enum VOLUME_FLAGS - Possible flags for the volume (16-bit).
*/
typedef enum {
typedef enum
{
VOLUME_IS_DIRTY = const_cpu_to_le16( 0x0001 ),
VOLUME_RESIZE_LOG_FILE = const_cpu_to_le16( 0x0002 ),
VOLUME_UPGRADE_ON_MOUNT = const_cpu_to_le16( 0x0004 ),
@ -2003,7 +2076,8 @@ typedef enum {
* NOTE: Windows 2000 uses NTFS 3.0 while Windows NT4 service pack 6a uses
* NTFS 1.2. I haven't personally seen other values yet.
*/
typedef struct {
typedef struct
{
u64 reserved; /* Not used (yet?). */
u8 major_ver; /* Major version of the ntfs format. */
u8 minor_ver; /* Minor version of the ntfs format. */
@ -2017,14 +2091,16 @@ typedef struct {
*
* Data contents of a file (i.e. the unnamed stream) or of a named stream.
*/
typedef struct {
typedef struct
{
u8 data[0]; /* The file's data contents. */
} __attribute__( ( __packed__ ) ) DATA_ATTR;
/**
* enum INDEX_HEADER_FLAGS - Index header flags (8-bit).
*/
typedef enum {
typedef enum
{
/* When index header is in an index root attribute: */
SMALL_INDEX = 0, /* The index is small enough to fit inside the
index root attribute and there is no index
@ -2054,8 +2130,10 @@ typedef enum {
* relative to the start of the index header structure and not relative to the
* start of the index root or index allocation structures themselves.
*/
typedef struct {
/* 0*/ u32 entries_offset; /* Byte offset from the INDEX_HEADER to first
typedef struct
{
/* 0*/
u32 entries_offset; /* Byte offset from the INDEX_HEADER to first
INDEX_ENTRY, aligned to 8-byte boundary. */
/* 4*/ u32 index_length; /* Data size in byte of the INDEX_ENTRY's,
including the INDEX_HEADER, aligned to 8. */
@ -2094,8 +2172,10 @@ typedef struct {
* NOTE: The root directory (FILE_root) contains an entry for itself. Other
* directories do not contain entries for themselves, though.
*/
typedef struct {
/* 0*/ ATTR_TYPES type; /* Type of the indexed attribute. Is
typedef struct
{
/* 0*/
ATTR_TYPES type; /* Type of the indexed attribute. Is
$FILE_NAME for directories, zero
for view indexes. No other values
allowed. */
@ -2123,7 +2203,8 @@ typedef struct {
* INDEX_BLOCK structure containing an index header, followed by a sequence of
* index entries (INDEX_ENTRY structures), as described by the INDEX_HEADER.
*/
typedef struct {
typedef struct
{
/* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
NTFS_RECORD_TYPES magic;/* Magic is "INDX". */
u16 usa_ofs; /* See NTFS_RECORD definition. */
@ -2158,7 +2239,8 @@ typedef INDEX_BLOCK INDEX_ALLOCATION;
* COLLATION_NTOFS_ULONGS. FIXME: Verify whether the reparse_tag is not the
* primary key / is not a key at all. (AIA)
*/
typedef struct {
typedef struct
{
u32 reparse_tag; /* Reparse point type (inc. flags). */
MFT_REF file_id; /* Mft record of the file containing the
reparse point attribute. */
@ -2167,7 +2249,8 @@ typedef struct {
/**
* enum QUOTA_FLAGS - Quota flags (32-bit).
*/
typedef enum {
typedef enum
{
/* The user quota flags. Names explain meaning. */
QUOTA_FLAG_DEFAULT_LIMITS = const_cpu_to_le32( 0x00000001 ),
QUOTA_FLAG_LIMIT_REACHED = const_cpu_to_le32( 0x00000002 ),
@ -2211,7 +2294,8 @@ typedef enum {
*
* The $Q index entry data is the quota control entry and is defined below.
*/
typedef struct {
typedef struct
{
u32 version; /* Currently equals 2. */
QUOTA_FLAGS flags; /* Flags describing this quota entry. */
u64 bytes_used; /* How many bytes of the quota are in use. */
@ -2233,7 +2317,8 @@ typedef struct {
/**
* struct QUOTA_O_INDEX_DATA -
*/
typedef struct {
typedef struct
{
u32 owner_id;
u32 unknown; /* Always 32. Seems to be padding and it's not
counted in the INDEX_ENTRY's data_length.
@ -2243,7 +2328,8 @@ typedef struct {
/**
* enum PREDEFINED_OWNER_IDS - Predefined owner_id values (32-bit).
*/
typedef enum {
typedef enum
{
QUOTA_INVALID_ID = const_cpu_to_le32( 0x00000000 ),
QUOTA_DEFAULTS_ID = const_cpu_to_le32( 0x00000001 ),
QUOTA_FIRST_USER_ID = const_cpu_to_le32( 0x00000100 ),
@ -2252,7 +2338,8 @@ typedef enum {
/**
* enum INDEX_ENTRY_FLAGS - Index entry flags (16-bit).
*/
typedef enum {
typedef enum
{
INDEX_ENTRY_NODE = const_cpu_to_le16( 1 ), /* This entry contains a
sub-node, i.e. a reference to an index
block in form of a virtual cluster
@ -2271,10 +2358,14 @@ typedef enum {
* !!!!! SEE DESCRIPTION OF THE FIELDS AT INDEX_ENTRY !!!!!
* ==========================================================
*/
typedef struct {
/* 0*/ union {
typedef struct
{
/* 0*/
union
{
MFT_REF indexed_file;
struct {
struct
{
u16 data_offset;
u16 data_length;
u32 reservedV;
@ -2296,14 +2387,17 @@ typedef struct {
*
* NOTE: Before NTFS 3.0 only filename attributes were indexed.
*/
typedef struct {
typedef struct
{
/* 0 INDEX_ENTRY_HEADER; -- Unfolded here as gcc dislikes unnamed structs. */
union { /* Only valid when INDEX_ENTRY_END is not set. */
union /* Only valid when INDEX_ENTRY_END is not set. */
{
MFT_REF indexed_file; /* The mft reference of the file
described by this index
entry. Used for directory
indexes. */
struct { /* Used for views/indexes to find the entry's data. */
struct /* Used for views/indexes to find the entry's data. */
{
u16 data_offset; /* Data byte offset from this
INDEX_ENTRY. Follows the
index key. */
@ -2320,7 +2414,8 @@ typedef struct {
/* 12*/ INDEX_ENTRY_FLAGS ie_flags; /* Bit field of INDEX_ENTRY_* flags. */
/* 14*/ u16 reserved; /* Reserved/align to 8-byte boundary. */
/* End of INDEX_ENTRY_HEADER */
/* 16*/ union { /* The key of the indexed attribute. NOTE: Only present
/* 16*/ union
{ /* The key of the indexed attribute. NOTE: Only present
if INDEX_ENTRY_END bit in flags is not set. NOTE: On
NTFS versions before 3.0 the only valid key is the
FILE_NAME_ATTR. On NTFS 3.0+ the following
@ -2364,7 +2459,8 @@ typedef struct {
* the number of bits in the bitmap * index block size / cluster size is the
* number of clusters in the index allocation attribute.
*/
typedef struct {
typedef struct
{
u8 bitmap[0]; /* Array of bits. */
} __attribute__( ( __packed__ ) ) BITMAP_ATTR;
@ -2388,7 +2484,8 @@ typedef struct {
* bit 31: Microsoft bit. If set, the tag is owned by Microsoft. User
* defined tags have to use zero here.
*/
typedef enum {
typedef enum
{
IO_REPARSE_TAG_IS_ALIAS = const_cpu_to_le32( 0x20000000 ),
IO_REPARSE_TAG_IS_HIGH_LATENCY = const_cpu_to_le32( 0x40000000 ),
IO_REPARSE_TAG_IS_MICROSOFT = const_cpu_to_le32( 0x80000000 ),
@ -2416,7 +2513,8 @@ typedef enum {
*
* NOTE: Can be resident or non-resident.
*/
typedef struct {
typedef struct
{
u32 reparse_tag; /* Reparse point type (inc. flags). */
u16 reparse_data_length; /* Byte size of reparse data. */
u16 reserved; /* Align to 8-byte boundary. */
@ -2428,7 +2526,8 @@ typedef struct {
*
* NOTE: Always resident.
*/
typedef struct {
typedef struct
{
u16 ea_length; /* Byte size of the packed extended
attributes. */
u16 need_ea_count; /* The number of extended attributes which have
@ -2443,7 +2542,8 @@ typedef struct {
/**
* enum EA_FLAGS - Extended attribute flags (8-bit).
*/
typedef enum {
typedef enum
{
NEED_EA = 0x80, /* Indicate that the file to which the EA
belongs cannot be interpreted without
understanding the associated extended
@ -2459,7 +2559,8 @@ typedef enum {
* FIXME: It appears weird that the EA name is not Unicode. Is it true?
* FIXME: It seems that name is always uppercased. Is it true?
*/
typedef struct {
typedef struct
{
u32 next_entry_offset; /* Offset to the next EA_ATTR. */
EA_FLAGS flags; /* Flags describing the EA. */
u8 name_length; /* Length of the name of the extended
@ -2476,7 +2577,8 @@ typedef struct {
* Intended to support Native Structure Storage (NSS) - a feature removed from
* NTFS 3.0 during beta testing.
*/
typedef struct {
typedef struct
{
/* Irrelevant as feature unused. */
} __attribute__( ( __packed__ ) ) PROPERTY_SET;
@ -2491,7 +2593,8 @@ typedef struct {
* Used by the Encrypting File System (EFS). All encrypted files have this
* attribute with the name $EFS. See below for the relevant structures.
*/
typedef struct {
typedef struct
{
/* Can be anything the creator chooses. */
} __attribute__( ( __packed__ ) ) LOGGED_UTILITY_STREAM;
@ -2527,8 +2630,10 @@ typedef struct {
*
* The header of the Logged utility stream (0x100) attribute named "$EFS".
*/
typedef struct {
/* 0*/ u32 length; /* Length of EFS attribute in bytes. */
typedef struct
{
/* 0*/
u32 length; /* Length of EFS attribute in bytes. */
u32 state; /* Always 0? */
u32 version; /* Efs version. Always 2? */
u32 crypto_api_version; /* Always 0? */
@ -2551,7 +2656,8 @@ typedef struct {
/**
* struct EFS_DF_ARRAY_HEADER -
*/
typedef struct {
typedef struct
{
u32 df_count; /* Number of data decryption/recovery fields in
the array. */
} __attribute__( ( __packed__ ) ) EFS_DF_ARRAY_HEADER;
@ -2559,8 +2665,10 @@ typedef struct {
/**
* struct EFS_DF_HEADER -
*/
typedef struct {
/* 0*/ u32 df_length; /* Length of this data decryption/recovery
typedef struct
{
/* 0*/
u32 df_length; /* Length of this data decryption/recovery
field in bytes. */
u32 cred_header_offset; /* Offset in bytes to the credential header. */
u32 fek_size; /* Size in bytes of the encrypted file
@ -2573,8 +2681,10 @@ typedef struct {
/**
* struct EFS_DF_CREDENTIAL_HEADER -
*/
typedef struct {
/* 0*/ u32 cred_length; /* Length of this credential in bytes. */
typedef struct
{
/* 0*/
u32 cred_length; /* Length of this credential in bytes. */
u32 sid_offset; /* Offset in bytes to the user's sid from start
of this structure. Zero if no sid is
present. */
@ -2583,10 +2693,13 @@ typedef struct {
2 = Unexpected type.
3 = Certificate thumbprint.
other = Unknown type. */
union {
union
{
/* CryptoAPI container. */
struct {
/* 12*/ u32 container_name_offset; /* Offset in bytes to
struct
{
/* 12*/
u32 container_name_offset; /* Offset in bytes to
the name of the container from start of this
structure (may not be zero). */
/* 16*/ u32 provider_name_offset; /* Offset in bytes to
@ -2599,8 +2712,10 @@ typedef struct {
public key blob. */
} __attribute__( ( __packed__ ) );
/* Certificate thumbprint. */
struct {
/* 12*/ u32 cert_thumbprint_header_size; /* Size in
struct
{
/* 12*/
u32 cert_thumbprint_header_size; /* Size in
bytes of the header of the certificate
thumbprint. */
/* 16*/ u32 cert_thumbprint_header_offset; /* Offset in
@ -2617,8 +2732,10 @@ typedef EFS_DF_CREDENTIAL_HEADER EFS_DF_CRED_HEADER;
/**
* struct EFS_DF_CERTIFICATE_THUMBPRINT_HEADER -
*/
typedef struct {
/* 0*/ u32 thumbprint_offset; /* Offset in bytes to the thumbprint. */
typedef struct
{
/* 0*/
u32 thumbprint_offset; /* Offset in bytes to the thumbprint. */
u32 thumbprint_size; /* Size of thumbprint in bytes. */
/* 8*/ u32 container_name_offset; /* Offset in bytes to the name of the
container from start of this
@ -2635,7 +2752,8 @@ typedef struct {
typedef EFS_DF_CERTIFICATE_THUMBPRINT_HEADER EFS_DF_CERT_THUMBPRINT_HEADER;
typedef enum {
typedef enum
{
INTX_SYMBOLIC_LINK =
const_cpu_to_le64( 0x014B4E4C78746E49ULL ), /* "IntxLNK\1" */
INTX_CHARACTER_DEVICE =
@ -2644,11 +2762,14 @@ typedef enum {
const_cpu_to_le64( 0x004B4C4278746E49ULL ), /* "IntxBLK\0" */
} INTX_FILE_TYPES;
typedef struct {
typedef struct
{
INTX_FILE_TYPES magic; /* Intx file magic. */
union {
union
{
/* For character and block devices. */
struct {
struct
{
u64 major; /* Major device number. */
u64 minor; /* Minor device number. */
void *device_end[0]; /* Marker for offsetof(). */

View File

@ -55,7 +55,8 @@
#define NTFS_LCNALLOC_BSIZE 4096
#define NTFS_LCNALLOC_SKIP NTFS_LCNALLOC_BSIZE
enum {
enum
{
ZONE_MFT = 1,
ZONE_DATA1 = 2,
ZONE_DATA2 = 4
@ -94,19 +95,26 @@ static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc)
static void update_full_status( ntfs_volume *vol, LCN lcn )
{
if (lcn >= vol->mft_zone_end) {
if (vol->full_zones & ZONE_DATA1) {
if ( lcn >= vol->mft_zone_end )
{
if ( vol->full_zones & ZONE_DATA1 )
{
ntfs_cluster_update_zone_pos( vol, ZONE_DATA1, lcn );
vol->full_zones &= ~ZONE_DATA1;
}
} else
if (lcn < vol->mft_zone_start) {
if (vol->full_zones & ZONE_DATA2) {
}
else if ( lcn < vol->mft_zone_start )
{
if ( vol->full_zones & ZONE_DATA2 )
{
ntfs_cluster_update_zone_pos( vol, ZONE_DATA2, lcn );
vol->full_zones &= ~ZONE_DATA2;
}
} else {
if (vol->full_zones & ZONE_MFT) {
}
else
{
if ( vol->full_zones & ZONE_MFT )
{
ntfs_cluster_update_zone_pos( vol, ZONE_MFT, lcn );
vol->full_zones &= ~ZONE_MFT;
}
@ -122,38 +130,49 @@ static s64 max_empty_bit_range(unsigned char *buf, int size)
ntfs_log_trace( "Entering\n" );
i = 0;
while (i < size) {
switch (*buf) {
while ( i < size )
{
switch ( *buf )
{
case 0 :
do {
do
{
buf++;
run += 8;
i++;
} while ((i < size) && !*buf);
}
while ( ( i < size ) && !*buf );
break;
case 255 :
if (run > max_range) {
if ( run > max_range )
{
max_range = run;
start_pos = ( s64 )i * 8 - run;
}
run = 0;
do {
do
{
buf++;
i++;
} while ((i < size) && (*buf == 255));
}
while ( ( i < size ) && ( *buf == 255 ) );
break;
default :
for (j = 0; j < 8; j++) {
for ( j = 0; j < 8; j++ )
{
int bit = *buf & ( 1 << j );
if (bit) {
if (run > max_range) {
if ( bit )
{
if ( run > max_range )
{
max_range = run;
start_pos = ( s64 )i * 8 + ( j - run );
}
run = 0;
} else
}
else
run++;
}
i++;
@ -181,7 +200,8 @@ static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b,
*writeback = 0;
written = ntfs_attr_pwrite( vol->lcnbmp_na, pos, size, b );
if (written != size) {
if ( written != size )
{
if ( !written )
errno = EIO;
ntfs_log_perror( "Bitmap write error (%lld, %lld)",
@ -253,7 +273,8 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
start_lcn, zone == MFT_ZONE ? "MFT" : "DATA" );
if ( !vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na ||
(s8)zone < FIRST_ZONE || zone > LAST_ZONE) {
( s8 )zone < FIRST_ZONE || zone > LAST_ZONE )
{
errno = EINVAL;
ntfs_log_perror( "%s: vcn: %lld, count: %lld, lcn: %lld",
__FUNCTION__, ( long long )start_vcn,
@ -262,9 +283,11 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
}
/* Return empty runlist if @count == 0 */
if (!count) {
if ( !count )
{
rl = ntfs_malloc( 0x1000 );
if (rl) {
if ( rl )
{
rl[0].vcn = start_vcn;
rl[0].lcn = LCN_RL_NOT_MAPPED;
rl[0].length = 0;
@ -282,7 +305,8 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
has_guess = 1;
zone_start = start_lcn;
if (zone_start < 0) {
if ( zone_start < 0 )
{
if ( zone == DATA_ZONE )
zone_start = vol->data1_zone_pos;
else
@ -296,13 +320,18 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
zone_start == vol->mft_zone_end )
pass = 2;
if (zone_start < vol->mft_zone_start) {
if ( zone_start < vol->mft_zone_start )
{
zone_end = vol->mft_zone_start;
search_zone = ZONE_DATA2;
} else if (zone_start < vol->mft_zone_end) {
}
else if ( zone_start < vol->mft_zone_end )
{
zone_end = vol->mft_zone_end;
search_zone = ZONE_MFT;
} else {
}
else
{
zone_end = vol->nr_clusters;
search_zone = ZONE_DATA1;
}
@ -312,14 +341,16 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
/* Loop until all clusters are allocated. */
clusters = count;
rlpos = rlsize = 0;
while (1) {
while ( 1 )
{
/* check whether we have exhausted the current zone */
if ( search_zone & vol->full_zones )
goto zone_pass_done;
last_read_pos = bmp_pos >> 3;
br = ntfs_attr_pread( vol->lcnbmp_na, last_read_pos,
NTFS_LCNALLOC_BSIZE, buf );
if (br <= 0) {
if ( br <= 0 )
{
if ( !br )
goto zone_pass_done;
err = errno;
@ -335,15 +366,20 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
bmp_pos &= ~7;
writeback = 0;
while (lcn < buf_size) {
while ( lcn < buf_size )
{
byte = buf + ( lcn >> 3 );
bit = 1 << ( lcn & 7 );
if (has_guess) {
if (*byte & bit) {
if ( has_guess )
{
if ( *byte & bit )
{
has_guess = 0;
break;
}
} else {
}
else
{
lcn = max_empty_bit_range( buf, br );
if ( lcn < 0 )
break;
@ -354,10 +390,12 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
/* First free bit is at lcn + bmp_pos. */
/* Reallocate memory if necessary. */
if ((rlpos + 2) * (int)sizeof(runlist) >= rlsize) {
if ( ( rlpos + 2 ) * ( int )sizeof( runlist ) >= rlsize )
{
rlsize += 4096;
trl = realloc( rl, rlsize );
if (!trl) {
if ( !trl )
{
err = ENOMEM;
ntfs_log_perror( "realloc() failed" );
goto wb_err_ret;
@ -379,7 +417,8 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
* Coalesce with previous run if adjacent LCNs.
* Otherwise, append a new run.
*/
if (prev_lcn == lcn + bmp_pos - prev_run_len && rlpos) {
if ( prev_lcn == lcn + bmp_pos - prev_run_len && rlpos )
{
ntfs_log_debug( "Cluster coalesce: prev_lcn: "
"%lld lcn: %lld bmp_pos: %lld "
"prev_run_len: %lld\n",
@ -387,11 +426,14 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
( long long )lcn, ( long long )bmp_pos,
( long long )prev_run_len );
rl[rlpos - 1].length = ++prev_run_len;
} else {
}
else
{
if ( rlpos )
rl[rlpos].vcn = rl[rlpos - 1].vcn +
prev_run_len;
else {
else
{
rl[rlpos].vcn = start_vcn;
ntfs_log_debug( "Start_vcn: %lld\n",
( long long )start_vcn );
@ -407,7 +449,8 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
( long long )rl[rlpos - 1].lcn,
( long long )rl[rlpos - 1].length );
/* Done? */
if (!--clusters) {
if ( !--clusters )
{
if ( used_zone_pos )
ntfs_cluster_update_zone_pos( vol,
search_zone, lcn + bmp_pos + 1 +
@ -418,12 +461,14 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
lcn++;
}
if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) {
if ( bitmap_writeback( vol, last_read_pos, br, buf, &writeback ) )
{
err = errno;
goto err_ret;
}
if (!used_zone_pos) {
if ( !used_zone_pos )
{
used_zone_pos = 1;
@ -438,7 +483,8 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
zone_start == vol->mft_zone_end )
pass = 2;
bmp_pos = zone_start;
} else
}
else
bmp_pos += buf_size;
if ( bmp_pos < zone_end )
@ -446,7 +492,8 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
zone_pass_done:
ntfs_log_trace( "Finished current zone pass(%i).\n", pass );
if (pass == 1) {
if ( pass == 1 )
{
pass = 2;
zone_end = zone_start;
@ -469,10 +516,12 @@ zone_pass_done:
done_zones_check:
done_zones |= search_zone;
vol->full_zones |= search_zone;
if (done_zones < (ZONE_MFT + ZONE_DATA1 + ZONE_DATA2)) {
if ( done_zones < ( ZONE_MFT + ZONE_DATA1 + ZONE_DATA2 ) )
{
ntfs_log_trace( "Switching zone.\n" );
pass = 1;
if (rlpos) {
if ( rlpos )
{
LCN tc = rl[rlpos - 1].lcn +
rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP;
@ -481,7 +530,8 @@ done_zones_check:
search_zone, tc );
}
switch (search_zone) {
switch ( search_zone )
{
case ZONE_MFT:
ntfs_log_trace( "Zone switch: mft -> data1\n" );
switch_to_data1_zone: search_zone = ZONE_DATA1;
@ -499,7 +549,8 @@ switch_to_data1_zone: search_zone = ZONE_DATA1;
pass = 2;
break;
case ZONE_DATA2:
if (!(done_zones & ZONE_DATA1)) {
if ( !( done_zones & ZONE_DATA1 ) )
{
ntfs_log_trace( "data2 -> data1\n" );
goto switch_to_data1_zone;
}
@ -514,7 +565,8 @@ switch_to_data1_zone: search_zone = ZONE_DATA1;
bmp_pos = zone_start;
if (zone_start == zone_end) {
if ( zone_start == zone_end )
{
ntfs_log_trace( "Empty zone, skipped.\n" );
goto done_zones_check;
}
@ -532,13 +584,15 @@ done_ret:
rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
rl[rlpos].length = 0;
if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) {
if ( bitmap_writeback( vol, last_read_pos, br, buf, &writeback ) )
{
err = errno;
goto err_ret;
}
done_err_ret:
free( buf );
if (err) {
if ( err )
{
errno = err;
ntfs_log_perror( "Failed to allocate clusters" );
rl = NULL;
@ -553,7 +607,8 @@ wb_err_ret:
err = errno;
err_ret:
ntfs_log_trace( "At err_ret.\n" );
if (rl) {
if ( rl )
{
/* Add runlist terminator element. */
rl[rlpos].vcn = rl[rlpos - 1].vcn + rl[rlpos - 1].length;
rl[rlpos].lcn = LCN_RL_NOT_MAPPED;
@ -580,15 +635,18 @@ int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl)
ntfs_log_trace( "Entering.\n" );
for (; rl->length; rl++) {
for ( ; rl->length; rl++ )
{
ntfs_log_trace( "Dealloc lcn 0x%llx, len 0x%llx.\n",
( long long )rl->lcn, ( long long )rl->length );
if (rl->lcn >= 0) {
if ( rl->lcn >= 0 )
{
update_full_status( vol, rl->lcn );
if ( ntfs_bitmap_clear_run( vol->lcnbmp_na, rl->lcn,
rl->length)) {
rl->length ) )
{
ntfs_log_perror( "Cluster deallocation failed "
"(%lld, %lld)",
( long long )rl->lcn,
@ -623,10 +681,12 @@ int ntfs_cluster_free_basic(ntfs_volume *vol, s64 lcn, s64 count)
ntfs_log_trace( "Dealloc lcn 0x%llx, len 0x%llx.\n",
( long long )lcn, ( long long )count );
if (lcn >= 0) {
if ( lcn >= 0 )
{
update_full_status( vol, lcn );
if ( ntfs_bitmap_clear_run( vol->lcnbmp_na, lcn,
count)) {
count ) )
{
ntfs_log_perror( "Cluster deallocation failed "
"(%lld, %lld)",
( long long )lcn,
@ -668,7 +728,8 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
int ret = -1;
if ( !vol || !vol->lcnbmp_na || !na || start_vcn < 0 ||
(count < 0 && count != -1)) {
( count < 0 && count != -1 ) )
{
ntfs_log_trace( "Invalid arguments!\n" );
errno = EINVAL;
return -1;
@ -679,13 +740,15 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
na->type, ( long long )count, ( long long )start_vcn );
rl = ntfs_attr_find_vcn( na, start_vcn );
if (!rl) {
if ( !rl )
{
if ( errno == ENOENT )
ret = 0;
goto leave;
}
if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {
if ( rl->lcn < 0 && rl->lcn != LCN_HOLE )
{
errno = EIO;
ntfs_log_perror( "%s: Unexpected lcn (%lld)", __FUNCTION__,
( long long )rl->lcn );
@ -700,7 +763,8 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
if ( count >= 0 && to_free > count )
to_free = count;
if (rl->lcn != LCN_HOLE) {
if ( rl->lcn != LCN_HOLE )
{
/* Do the actual freeing of the clusters in this run. */
update_full_status( vol, rl->lcn + delta );
if ( ntfs_bitmap_clear_run( vol->lcnbmp_na, rl->lcn + delta,
@ -718,10 +782,12 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
* Loop over the remaining runs, using @count as a capping value, and
* free them.
*/
for (; rl->length && count != 0; ++rl) {
for ( ; rl->length && count != 0; ++rl )
{
// FIXME: Need to try ntfs_attr_map_runlist() for attribute
// list support! (AIA)
if (rl->lcn < 0 && rl->lcn != LCN_HOLE) {
if ( rl->lcn < 0 && rl->lcn != LCN_HOLE )
{
// FIXME: Eeek! We need rollback! (AIA)
errno = EIO;
ntfs_log_perror( "%s: Invalid lcn (%lli)",
@ -734,10 +800,12 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
if ( count >= 0 && to_free > count )
to_free = count;
if (rl->lcn != LCN_HOLE) {
if ( rl->lcn != LCN_HOLE )
{
update_full_status( vol, rl->lcn );
if ( ntfs_bitmap_clear_run( vol->lcnbmp_na, rl->lcn,
to_free)) {
to_free ) )
{
// FIXME: Eeek! We need rollback! (AIA)
ntfs_log_perror( "%s: Clearing bitmap run failed",
__FUNCTION__ );
@ -750,7 +818,8 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
count -= to_free;
}
if (count != -1 && count != 0) {
if ( count != -1 && count != 0 )
{
// FIXME: Eeek! BUG()
errno = EIO;
ntfs_log_perror( "%s: count still not zero (%lld)", __FUNCTION__,

View File

@ -31,7 +31,8 @@
/**
* enum NTFS_CLUSTER_ALLOCATION_ZONES -
*/
typedef enum {
typedef enum
{
FIRST_ZONE = 0, /* For sanity checking. */
MFT_ZONE = 0, /* Allocate from $MFT zone. */
DATA_ZONE = 1, /* Allocate from $DATA zone. */

View File

@ -71,7 +71,8 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
logfile_log_page_size < NTFS_BLOCK_SIZE ||
logfile_system_page_size &
( logfile_system_page_size - 1 ) ||
logfile_log_page_size & (logfile_log_page_size - 1)) {
logfile_log_page_size & ( logfile_log_page_size - 1 ) )
{
ntfs_log_error( "$LogFile uses unsupported page size.\n" );
return FALSE;
}
@ -79,14 +80,16 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
* We must be either at !pos (1st restart page) or at pos = system page
* size (2nd restart page).
*/
if (pos && pos != logfile_system_page_size) {
if ( pos && pos != logfile_system_page_size )
{
ntfs_log_error( "Found restart area in incorrect "
"position in $LogFile.\n" );
return FALSE;
}
/* We only know how to handle version 1.1. */
if ( sle16_to_cpu( rp->major_ver ) != 1 ||
sle16_to_cpu(rp->minor_ver) != 1) {
sle16_to_cpu( rp->minor_ver ) != 1 )
{
ntfs_log_error( "$LogFile version %i.%i is not "
"supported. (This driver supports version "
"1.1 only.)\n", ( int )sle16_to_cpu( rp->major_ver ),
@ -97,13 +100,15 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
* If chkdsk has been run the restart page may not be protected by an
* update sequence array.
*/
if (ntfs_is_chkd_record(rp->magic) && !le16_to_cpu(rp->usa_count)) {
if ( ntfs_is_chkd_record( rp->magic ) && !le16_to_cpu( rp->usa_count ) )
{
have_usa = FALSE;
goto skip_usa_checks;
}
/* Verify the size of the update sequence array. */
usa_count = 1 + ( logfile_system_page_size >> NTFS_BLOCK_SIZE_BITS );
if (usa_count != le16_to_cpu(rp->usa_count)) {
if ( usa_count != le16_to_cpu( rp->usa_count ) )
{
ntfs_log_error( "$LogFile restart page specifies "
"inconsistent update sequence array count.\n" );
return FALSE;
@ -112,7 +117,8 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
usa_ofs = le16_to_cpu( rp->usa_ofs );
usa_end = usa_ofs + usa_count * sizeof( u16 );
if ( usa_ofs < sizeof( RESTART_PAGE_HEADER ) ||
usa_end > NTFS_BLOCK_SIZE - sizeof(u16)) {
usa_end > NTFS_BLOCK_SIZE - sizeof( u16 ) )
{
ntfs_log_error( "$LogFile restart page specifies "
"inconsistent update sequence array offset.\n" );
return FALSE;
@ -127,7 +133,8 @@ skip_usa_checks:
ra_ofs = le16_to_cpu( rp->restart_area_offset );
if ( ra_ofs & 7 || ( have_usa ? ra_ofs < usa_end :
ra_ofs < sizeof( RESTART_PAGE_HEADER ) ) ||
ra_ofs > logfile_system_page_size) {
ra_ofs > logfile_system_page_size )
{
ntfs_log_error( "$LogFile restart page specifies "
"inconsistent restart area offset.\n" );
return FALSE;
@ -136,7 +143,8 @@ skip_usa_checks:
* Only restart pages modified by chkdsk are allowed to have chkdsk_lsn
* set.
*/
if (!ntfs_is_chkd_record(rp->magic) && sle64_to_cpu(rp->chkdsk_lsn)) {
if ( !ntfs_is_chkd_record( rp->magic ) && sle64_to_cpu( rp->chkdsk_lsn ) )
{
ntfs_log_error( "$LogFile restart page is not modified "
"by chkdsk but a chkdsk LSN is specified.\n" );
return FALSE;
@ -174,7 +182,8 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
* safe to access ra->client_array_offset.
*/
if ( ra_ofs + offsetof( RESTART_AREA, file_size ) >
NTFS_BLOCK_SIZE - sizeof(u16)) {
NTFS_BLOCK_SIZE - sizeof( u16 ) )
{
ntfs_log_error( "$LogFile restart area specifies "
"inconsistent file offset.\n" );
return FALSE;
@ -189,7 +198,8 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
ca_ofs = le16_to_cpu( ra->client_array_offset );
if ( ( ( ca_ofs + 7 ) & ~7 ) != ca_ofs ||
ra_ofs + ca_ofs > ( u16 )( NTFS_BLOCK_SIZE -
sizeof(u16))) {
sizeof( u16 ) ) )
{
ntfs_log_error( "$LogFile restart area specifies "
"inconsistent client array offset.\n" );
return FALSE;
@ -204,7 +214,8 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
if ( ( u32 )( ra_ofs + ra_len ) > le32_to_cpu( rp->system_page_size ) ||
( u32 )( ra_ofs + le16_to_cpu( ra->restart_area_length ) ) >
le32_to_cpu( rp->system_page_size ) ||
ra_len > le16_to_cpu(ra->restart_area_length)) {
ra_len > le16_to_cpu( ra->restart_area_length ) )
{
ntfs_log_error( "$LogFile restart area is out of bounds "
"of the system page size specified by the "
"restart page header and/or the specified "
@ -221,7 +232,8 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
le16_to_cpu( ra->log_clients ) ) ||
( ra->client_in_use_list != LOGFILE_NO_CLIENT &&
le16_to_cpu( ra->client_in_use_list ) >=
le16_to_cpu(ra->log_clients))) {
le16_to_cpu( ra->log_clients ) ) )
{
ntfs_log_error( "$LogFile restart area specifies "
"overflowing client free and/or in use lists.\n" );
return FALSE;
@ -232,25 +244,29 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
*/
file_size = ( u64 )sle64_to_cpu( ra->file_size );
fs_bits = 0;
while (file_size) {
while ( file_size )
{
file_size >>= 1;
fs_bits++;
}
if (le32_to_cpu(ra->seq_number_bits) != (u32)(67 - fs_bits)) {
if ( le32_to_cpu( ra->seq_number_bits ) != ( u32 )( 67 - fs_bits ) )
{
ntfs_log_error( "$LogFile restart area specifies "
"inconsistent sequence number bits.\n" );
return FALSE;
}
/* The log record header length must be a multiple of 8. */
if ( ( ( le16_to_cpu( ra->log_record_header_length ) + 7 ) & ~7 ) !=
le16_to_cpu(ra->log_record_header_length)) {
le16_to_cpu( ra->log_record_header_length ) )
{
ntfs_log_error( "$LogFile restart area specifies "
"inconsistent log record header length.\n" );
return FALSE;
}
/* Ditto for the log page data offset. */
if ( ( ( le16_to_cpu( ra->log_page_data_offset ) + 7 ) & ~7 ) !=
le16_to_cpu(ra->log_page_data_offset)) {
le16_to_cpu( ra->log_page_data_offset ) )
{
ntfs_log_error( "$LogFile restart area specifies "
"inconsistent log page data offset.\n" );
return FALSE;
@ -297,20 +313,23 @@ static BOOL ntfs_check_log_client_array(RESTART_PAGE_HEADER *rp)
in_free_list = TRUE;
check_list:
for ( idx_is_first = TRUE; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--,
idx = le16_to_cpu(cr->next_client)) {
idx = le16_to_cpu( cr->next_client ) )
{
if ( !nr_clients || idx >= le16_to_cpu( ra->log_clients ) )
goto err_out;
/* Set @cr to the current log client record. */
cr = ca + idx;
/* The first log client record must not have a prev_client. */
if (idx_is_first) {
if ( idx_is_first )
{
if ( cr->prev_client != LOGFILE_NO_CLIENT )
goto err_out;
idx_is_first = FALSE;
}
}
/* Switch to and check the in use list if we just did the free list. */
if (in_free_list) {
if ( in_free_list )
{
in_free_list = FALSE;
idx = le16_to_cpu( ra->client_in_use_list );
goto check_list;
@ -359,12 +378,14 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
ntfs_log_trace( "Entering.\n" );
/* Check the restart page header for consistency. */
if (!ntfs_check_restart_page_header(rp, pos)) {
if ( !ntfs_check_restart_page_header( rp, pos ) )
{
/* Error output already done inside the function. */
return EINVAL;
}
/* Check the restart area for consistency. */
if (!ntfs_check_restart_area(rp)) {
if ( !ntfs_check_restart_area( rp ) )
{
/* Error output already done inside the function. */
return EINVAL;
}
@ -385,7 +406,8 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
memcpy( trp, rp, le32_to_cpu( rp->system_page_size ) );
else if ( ntfs_attr_pread( log_na, pos,
le32_to_cpu( rp->system_page_size ), trp ) !=
le32_to_cpu(rp->system_page_size)) {
le32_to_cpu( rp->system_page_size ) )
{
err = errno;
ntfs_log_error( "Failed to read whole restart page into the "
"buffer.\n" );
@ -399,7 +421,8 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
*/
if ( ( !ntfs_is_chkd_record( trp->magic ) || le16_to_cpu( trp->usa_count ) )
&& ntfs_mst_post_read_fixup( ( NTFS_RECORD* )trp,
le32_to_cpu(rp->system_page_size))) {
le32_to_cpu( rp->system_page_size ) ) )
{
/*
* A multi sector tranfer error was detected. We only need to
* abort if the restart page contents exceed the multi sector
@ -407,7 +430,8 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
*/
if ( le16_to_cpu( rp->restart_area_offset ) +
le16_to_cpu( ra->restart_area_length ) >
NTFS_BLOCK_SIZE - (int)sizeof(u16)) {
NTFS_BLOCK_SIZE - ( int )sizeof( u16 ) )
{
ntfs_log_error( "Multi sector transfer error "
"detected in $LogFile restart page.\n" );
err = EINVAL;
@ -421,13 +445,16 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
*/
err = 0;
if ( ntfs_is_rstr_record( rp->magic ) &&
ra->client_in_use_list != LOGFILE_NO_CLIENT) {
if (!ntfs_check_log_client_array(trp)) {
ra->client_in_use_list != LOGFILE_NO_CLIENT )
{
if ( !ntfs_check_log_client_array( trp ) )
{
err = EINVAL;
goto err_out;
}
}
if (lsn) {
if ( lsn )
{
if ( ntfs_is_rstr_record( rp->magic ) )
*lsn = sle64_to_cpu( ra->current_lsn );
else /* if (ntfs_is_chkd_record(rp->magic)) */
@ -436,7 +463,8 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
ntfs_log_trace( "Done.\n" );
if ( wrp )
*wrp = trp;
else {
else
{
err_out:
free( trp );
}
@ -494,7 +522,8 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
* pages and the minimum number of log record pages.
*/
if ( size < log_page_size * 2 || ( size - log_page_size * 2 ) >>
log_page_bits < MinLogRecordPages) {
log_page_bits < MinLogRecordPages )
{
ntfs_log_error( "$LogFile is too small.\n" );
return FALSE;
}
@ -510,12 +539,14 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
* contain empty and uninitialized records, the log file can be assumed
* to be empty.
*/
for (pos = 0; pos < size; pos <<= 1) {
for ( pos = 0; pos < size; pos <<= 1 )
{
/*
* Read first NTFS_BLOCK_SIZE bytes of potential restart page.
*/
if ( ntfs_attr_pread( log_na, pos, NTFS_BLOCK_SIZE, kaddr ) !=
NTFS_BLOCK_SIZE) {
NTFS_BLOCK_SIZE )
{
ntfs_log_error( "Failed to read first NTFS_BLOCK_SIZE "
"bytes of potential restart page.\n" );
goto err_out;
@ -538,7 +569,8 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
break;
/* If not a (modified by chkdsk) restart page, continue. */
if ( !ntfs_is_rstr_recordp( ( le32* )kaddr ) &&
!ntfs_is_chkd_recordp((le32*)kaddr)) {
!ntfs_is_chkd_recordp( ( le32* )kaddr ) )
{
if ( !pos )
pos = NTFS_BLOCK_SIZE >> 1;
continue;
@ -552,12 +584,14 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
( RESTART_PAGE_HEADER* )kaddr, pos,
!rstr1_ph ? &rstr1_ph : &rstr2_ph,
!rstr1_ph ? &rstr1_lsn : &rstr2_lsn );
if (!err) {
if ( !err )
{
/*
* If we have now found the first (modified by chkdsk)
* restart page, continue looking for the second one.
*/
if (!pos) {
if ( !pos )
{
pos = NTFS_BLOCK_SIZE >> 1;
continue;
}
@ -578,17 +612,20 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
if ( !pos )
pos = NTFS_BLOCK_SIZE >> 1;
}
if (kaddr) {
if ( kaddr )
{
free( kaddr );
kaddr = NULL;
}
if (logfile_is_empty) {
if ( logfile_is_empty )
{
NVolSetLogFileEmpty( vol );
is_empty:
ntfs_log_trace( "Done. ($LogFile is empty.)\n" );
return TRUE;
}
if (!rstr1_ph) {
if ( !rstr1_ph )
{
if ( rstr2_ph )
ntfs_log_error( "BUG: rstr2_ph isn't NULL!\n" );
ntfs_log_error( "Did not find any restart pages in "
@ -596,18 +633,22 @@ is_empty:
return FALSE;
}
/* If both restart pages were found, use the more recent one. */
if (rstr2_ph) {
if ( rstr2_ph )
{
/*
* If the second restart area is more recent, switch to it.
* Otherwise just throw it away.
*/
if (rstr2_lsn > rstr1_lsn) {
if ( rstr2_lsn > rstr1_lsn )
{
ntfs_log_debug( "Using second restart page as it is more "
"recent.\n" );
free( rstr1_ph );
rstr1_ph = rstr2_ph;
/* rstr1_lsn = rstr2_lsn; */
} else {
}
else
{
ntfs_log_debug( "Using first restart page as it is more "
"recent.\n" );
free( rstr2_ph );
@ -654,16 +695,19 @@ BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp)
ntfs_log_trace( "Entering.\n" );
/* An empty $LogFile must have been clean before it got emptied. */
if (NVolLogFileEmpty(log_na->ni->vol)) {
if ( NVolLogFileEmpty( log_na->ni->vol ) )
{
ntfs_log_trace( "$LogFile is empty\n" );
return TRUE;
}
if (!rp) {
if ( !rp )
{
ntfs_log_error( "Restart page header is NULL\n" );
return FALSE;
}
if ( !ntfs_is_rstr_record( rp->magic ) &&
!ntfs_is_chkd_record(rp->magic)) {
!ntfs_is_chkd_record( rp->magic ) )
{
ntfs_log_error( "Restart page buffer is invalid\n" );
return FALSE;
}
@ -675,7 +719,8 @@ BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp)
* we assume there was an unclean shutdown.
*/
if ( ra->client_in_use_list != LOGFILE_NO_CLIENT &&
!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
!( ra->flags & RESTART_VOLUME_IS_CLEAN ) )
{
ntfs_log_error( "The disk contains an unclean file system (%d, "
"%d).\n", le16_to_cpu( ra->client_in_use_list ),
le16_to_cpu( ra->flags ) );
@ -707,7 +752,8 @@ int ntfs_empty_logfile(ntfs_attr *na)
if ( NVolLogFileEmpty( na->ni->vol ) )
return 0;
if (!NAttrNonResident(na)) {
if ( !NAttrNonResident( na ) )
{
errno = EIO;
ntfs_log_perror( "Resident $LogFile $DATA attribute" );
return -1;
@ -716,13 +762,15 @@ int ntfs_empty_logfile(ntfs_attr *na)
memset( buf, -1, NTFS_BUF_SIZE );
pos = 0;
while ((count = na->data_size - pos) > 0) {
while ( ( count = na->data_size - pos ) > 0 )
{
if ( count > NTFS_BUF_SIZE )
count = NTFS_BUF_SIZE;
count = ntfs_attr_pwrite( na, pos, count, buf );
if (count <= 0) {
if ( count <= 0 )
{
ntfs_log_perror( "Failed to reset $LogFile" );
if ( count != -1 )
errno = EIO;

View File

@ -61,10 +61,12 @@
*
* Begins the restart area.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
/* 0*/ NTFS_RECORD_TYPES magic;/* The magic is "RSTR". */
/* 0*/
NTFS_RECORD_TYPES magic;/* The magic is "RSTR". */
/* 4*/ le16 usa_ofs; /* See NTFS_RECORD definition in layout.h.
When creating, set this to be immediately
after this header structure (without any
@ -108,7 +110,8 @@ typedef struct {
* These are the so far known RESTART_AREA_* flags (16-bit) which contain
* information about the log file in which they are present.
*/
enum {
enum
{
RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16( 0x0002 ),
RESTART_SPACE_FILLER = 0xffff, /* gcc: Force enum bit width to 16. */
} __attribute__( ( __packed__ ) );
@ -122,9 +125,11 @@ typedef le16 RESTART_AREA_FLAGS;
* RESTART_PAGE_HEADER to the restart_area_offset value found in it.
* See notes at restart_area_offset above.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0*/ leLSN current_lsn; /* The current, i.e. last LSN inside the log
/* 0*/
leLSN current_lsn; /* The current, i.e. last LSN inside the log
when the restart area was last written.
This happens often but what is the interval?
Is it just fixed time or is it every time a
@ -262,9 +267,11 @@ typedef struct {
* The offset of this record is found by adding the offset of the
* RESTART_AREA to the client_array_offset value found in it.
*/
typedef struct {
typedef struct
{
/*Ofs*/
/* 0*/ leLSN oldest_lsn; /* Oldest LSN needed by this client. On create
/* 0*/
leLSN oldest_lsn; /* Oldest LSN needed by this client. On create
set to 0. */
/* 8*/ leLSN client_restart_lsn;/* LSN at which this client needs to restart
the volume, i.e. the current position within
@ -305,7 +312,8 @@ typedef struct {
* following update sequence array and then aligned to 8 byte boundary, but is
* this specified anywhere?).
*/
typedef struct {
typedef struct
{
/* 0 NTFS_RECORD; -- Unfolded here as gcc doesn't like unnamed structs. */
NTFS_RECORD_TYPES magic;/* Usually the magic is "RCRD". */
u16 usa_ofs; /* See NTFS_RECORD definition in layout.h.
@ -314,15 +322,18 @@ typedef struct {
alignment). */
u16 usa_count; /* See NTFS_RECORD definition in layout.h. */
union {
union
{
LSN last_lsn;
s64 file_offset;
} __attribute__( ( __packed__ ) ) copy;
u32 flags;
u16 page_count;
u16 page_position;
union {
struct {
union
{
struct
{
u16 next_record_offset;
u8 reserved[6];
LSN last_end_lsn;
@ -335,7 +346,8 @@ typedef struct {
*
* (Or is it log record pages?)
*/
typedef enum {
typedef enum
{
LOG_RECORD_MULTI_PAGE = const_cpu_to_le16( 0x0001 ), /* ??? */
LOG_RECORD_SIZE_PLACE_HOLDER = 0xffff,
/* This has nothing to do with the log record. It is only so
@ -345,7 +357,8 @@ typedef enum {
/**
* struct LOG_CLIENT_ID - The log client id structure identifying a log client.
*/
typedef struct {
typedef struct
{
u16 seq_number;
u16 client_index;
} __attribute__( ( __packed__ ) ) LOG_CLIENT_ID;
@ -355,7 +368,8 @@ typedef struct {
*
* Each log record seems to have a constant size of 0x70 bytes.
*/
typedef struct {
typedef struct
{
LSN this_lsn;
LSN client_previous_lsn;
LSN client_undo_next_lsn;
@ -381,7 +395,8 @@ typedef struct {
u32 alignment_or_reserved;
VCN target_vcn;
/* Now at ofs 0x50. */
struct { /* Only present if lcns_to_follow
struct
{ /* Only present if lcns_to_follow
is not 0. */
LCN lcn;
} __attribute__( ( __packed__ ) ) lcn_list[0];

View File

@ -67,7 +67,8 @@ static int tab;
* @flags: Flags which affect the output style
* @handler: Function to perform the actual logging
*/
struct ntfs_logging {
struct ntfs_logging
{
u32 levels;
u32 flags;
ntfs_log_handler *handler BROKEN_GCC_FORMAT_ATTRIBUTE;
@ -77,7 +78,8 @@ struct ntfs_logging {
* ntfs_log
* This struct controls all the logging within the library and tools.
*/
static struct ntfs_logging ntfs_log = {
static struct ntfs_logging ntfs_log =
{
#ifdef DEBUG
NTFS_LOG_LEVEL_DEBUG | NTFS_LOG_LEVEL_TRACE | NTFS_LOG_LEVEL_ENTER |
NTFS_LOG_LEVEL_LEAVE |
@ -201,7 +203,8 @@ static FILE * ntfs_log_get_stream(u32 level)
{
FILE *stream;
switch (level) {
switch ( level )
{
case NTFS_LOG_LEVEL_INFO:
case NTFS_LOG_LEVEL_QUIET:
case NTFS_LOG_LEVEL_PROGRESS:
@ -237,7 +240,8 @@ static const char * ntfs_log_get_prefix(u32 level)
{
const char *prefix;
switch (level) {
switch ( level )
{
case NTFS_LOG_LEVEL_DEBUG:
prefix = "DEBUG: ";
break;
@ -286,13 +290,15 @@ static const char * ntfs_log_get_prefix(u32 level)
*/
void ntfs_log_set_handler( ntfs_log_handler *handler )
{
if (handler) {
if ( handler )
{
ntfs_log.handler = handler;
#ifdef HAVE_SYSLOG_H
if ( handler == ntfs_log_handler_syslog )
openlog( "ntfs-3g", LOG_PID, LOG_USER );
#endif
} else
}
else
ntfs_log.handler = ntfs_log_handler_null;
}
@ -369,13 +375,15 @@ int ntfs_log_handler_syslog(const char *function __attribute__((unused)),
return 1;
#endif
ret = vsnprintf( logbuf, LOG_LINE_LEN, format, args );
if (ret < 0) {
if ( ret < 0 )
{
vsyslog( LOG_NOTICE, format, args );
ret = 1;
goto out;
}
if ((LOG_LINE_LEN > ret + 3) && (level & NTFS_LOG_LEVEL_PERROR)) {
if ( ( LOG_LINE_LEN > ret + 3 ) && ( level & NTFS_LOG_LEVEL_PERROR ) )
{
strncat( logbuf, ": ", LOG_LINE_LEN - ret - 1 );
strncat( logbuf, strerror( olderr ), LOG_LINE_LEN - ( ret + 3 ) );
ret = strlen( logbuf );
@ -424,7 +432,8 @@ int ntfs_log_handler_fprintf(const char *function, const char *file,
stream = ( FILE* )data;
#ifdef DEBUG
if (level == NTFS_LOG_LEVEL_LEAVE) {
if ( level == NTFS_LOG_LEVEL_LEAVE )
{
if ( tab )
tab--;
return 0;
@ -593,16 +602,23 @@ int ntfs_log_handler_stderr(const char *function, const char *file,
*/
BOOL ntfs_log_parse_option( const char *option )
{
if (strcmp(option, "--log-debug") == 0) {
if ( strcmp( option, "--log-debug" ) == 0 )
{
ntfs_log_set_levels( NTFS_LOG_LEVEL_DEBUG );
return TRUE;
} else if (strcmp(option, "--log-verbose") == 0) {
}
else if ( strcmp( option, "--log-verbose" ) == 0 )
{
ntfs_log_set_levels( NTFS_LOG_LEVEL_VERBOSE );
return TRUE;
} else if (strcmp(option, "--log-quiet") == 0) {
}
else if ( strcmp( option, "--log-quiet" ) == 0 )
{
ntfs_log_clear_levels( NTFS_LOG_LEVEL_QUIET );
return TRUE;
} else if (strcmp(option, "--log-trace") == 0) {
}
else if ( strcmp( option, "--log-trace" ) == 0 )
{
ntfs_log_set_levels( NTFS_LOG_LEVEL_TRACE );
return TRUE;
}

View File

@ -24,11 +24,13 @@
#include <malloc.h>
static inline void* ntfs_alloc (size_t size) {
static inline void* ntfs_alloc ( size_t size )
{
return malloc( size );
}
static inline void* ntfs_align (size_t size) {
static inline void* ntfs_align ( size_t size )
{
#ifdef __wii__
return memalign( 32, size );
#else
@ -36,7 +38,8 @@ static inline void* ntfs_align (size_t size) {
#endif
}
static inline void ntfs_free (void* mem) {
static inline void ntfs_free ( void* mem )
{
free( mem );
}

View File

@ -86,7 +86,8 @@ int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
ntfs_log_trace( "inode %llu\n", ( unsigned long long )MREF( mref ) );
if (!vol || !vol->mft_na || !b || count < 0) {
if ( !vol || !vol->mft_na || !b || count < 0 )
{
errno = EINVAL;
ntfs_log_perror( "%s: b=%p count=%lld mft=%llu", __FUNCTION__,
b, ( long long )count, ( unsigned long long )MREF( mref ) );
@ -95,7 +96,8 @@ int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
m = MREF( mref );
/* Refuse to read non-allocated mft records. */
if ( m + count > vol->mft_na->initialized_size >>
vol->mft_record_size_bits) {
vol->mft_record_size_bits )
{
errno = ESPIPE;
ntfs_log_perror( "Trying to read non-allocated mft records "
"(%lld > %lld)", ( long long )m + count,
@ -105,7 +107,8 @@ int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
}
br = ntfs_attr_mst_pread( vol->mft_na, m << vol->mft_record_size_bits,
count, vol->mft_record_size, b );
if (br != count) {
if ( br != count )
{
if ( br != -1 )
errno = EIO;
ntfs_log_perror( "Failed to read of MFT, mft=%llu count=%lld "
@ -148,14 +151,16 @@ int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
void *bmirr = NULL;
int cnt = 0, res = 0;
if (!vol || !vol->mft_na || vol->mftmirr_size <= 0 || !b || count < 0) {
if ( !vol || !vol->mft_na || vol->mftmirr_size <= 0 || !b || count < 0 )
{
errno = EINVAL;
return -1;
}
m = MREF( mref );
/* Refuse to write non-allocated mft records. */
if ( m + count > vol->mft_na->initialized_size >>
vol->mft_record_size_bits) {
vol->mft_record_size_bits )
{
errno = ESPIPE;
ntfs_log_perror( "Trying to write non-allocated mft records "
"(%lld > %lld)", ( long long )m + count,
@ -163,8 +168,10 @@ int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
vol->mft_record_size_bits );
return -1;
}
if (m < vol->mftmirr_size) {
if (!vol->mftmirr_na) {
if ( m < vol->mftmirr_size )
{
if ( !vol->mftmirr_na )
{
errno = EINVAL;
return -1;
}
@ -178,7 +185,8 @@ int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
}
bw = ntfs_attr_mst_pwrite( vol->mft_na, m << vol->mft_record_size_bits,
count, vol->mft_record_size, b );
if (bw != count) {
if ( bw != count )
{
if ( bw != -1 )
errno = EIO;
if ( bw >= 0 )
@ -188,13 +196,15 @@ int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
ntfs_log_perror( "Error writing $Mft record(s)" );
res = errno;
}
if (bmirr && bw > 0) {
if ( bmirr && bw > 0 )
{
if ( bw < cnt )
cnt = bw;
bw = ntfs_attr_mst_pwrite( vol->mftmirr_na,
m << vol->mft_record_size_bits, cnt,
vol->mft_record_size, bmirr );
if (bw != cnt) {
if ( bw != cnt )
{
if ( bw != -1 )
errno = EIO;
ntfs_log_debug( "Error: failed to sync $MFTMirr! Run "
@ -215,13 +225,15 @@ int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref,
ATTR_RECORD *a;
int ret = -1;
if (!ntfs_is_file_record(m->magic)) {
if ( !ntfs_is_file_record( m->magic ) )
{
ntfs_log_error( "Record %llu has no FILE magic (0x%x)\n",
( unsigned long long )MREF( mref ), *( le32 * )m );
goto err_out;
}
if (le32_to_cpu(m->bytes_allocated) != vol->mft_record_size) {
if ( le32_to_cpu( m->bytes_allocated ) != vol->mft_record_size )
{
ntfs_log_error( "Record %llu has corrupt allocation size "
"(%u <> %u)\n", ( unsigned long long )MREF( mref ),
vol->mft_record_size,
@ -230,7 +242,8 @@ int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref,
}
a = ( ATTR_RECORD * )( ( char * )m + le16_to_cpu( m->attrs_offset ) );
if (p2n(a) < p2n(m) || (char *)a > (char *)m + vol->mft_record_size) {
if ( p2n( a ) < p2n( m ) || ( char * )a > ( char * )m + vol->mft_record_size )
{
ntfs_log_error( "Record %llu is corrupt\n",
( unsigned long long )MREF( mref ) );
goto err_out;
@ -279,14 +292,16 @@ int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref,
{
MFT_RECORD *m;
if (!vol || !mrec) {
if ( !vol || !mrec )
{
errno = EINVAL;
ntfs_log_perror( "%s: mrec=%p", __FUNCTION__, mrec );
return -1;
}
m = *mrec;
if (!m) {
if ( !m )
{
m = ntfs_malloc( vol->mft_record_size );
if ( !m )
return -1;
@ -297,7 +312,8 @@ int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref,
if ( ntfs_mft_record_check( vol, mref, m ) )
goto err_out;
if (MSEQNO(mref) && MSEQNO(mref) != le16_to_cpu(m->sequence_number)) {
if ( MSEQNO( mref ) && MSEQNO( mref ) != le16_to_cpu( m->sequence_number ) )
{
ntfs_log_error( "Record %llu has wrong SeqNo (%d <> %d)\n",
( unsigned long long )MREF( mref ), MSEQNO( mref ),
le16_to_cpu( m->sequence_number ) );
@ -332,7 +348,8 @@ int ntfs_mft_record_layout(const ntfs_volume *vol, const MFT_REF mref,
{
ATTR_RECORD *a;
if (!vol || !mrec) {
if ( !vol || !mrec )
{
errno = EINVAL;
ntfs_log_perror( "%s: mrec=%p", __FUNCTION__, mrec );
return -1;
@ -340,9 +357,11 @@ int ntfs_mft_record_layout(const ntfs_volume *vol, const MFT_REF mref,
/* Aligned to 2-byte boundary. */
if ( vol->major_ver < 3 || ( vol->major_ver == 3 && !vol->minor_ver ) )
mrec->usa_ofs = cpu_to_le16( ( sizeof( MFT_RECORD_OLD ) + 1 ) & ~1 );
else {
else
{
/* Abort if mref is > 32 bits. */
if (MREF(mref) & 0x0000ffff00000000ull) {
if ( MREF( mref ) & 0x0000ffff00000000ull )
{
errno = ERANGE;
ntfs_log_perror( "Mft reference exceeds 32 bits" );
return -1;
@ -359,7 +378,8 @@ int ntfs_mft_record_layout(const ntfs_volume *vol, const MFT_REF mref,
if ( vol->mft_record_size >= NTFS_BLOCK_SIZE )
mrec->usa_count = cpu_to_le16( vol->mft_record_size /
NTFS_BLOCK_SIZE + 1 );
else {
else
{
mrec->usa_count = cpu_to_le16( 1 );
ntfs_log_error( "Sector size is bigger than MFT record size. "
"Setting usa_count to 1. If Windows chkdsk "
@ -502,16 +522,19 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
data_pos = base_ni->mft_no + 1;
if ( data_pos < RESERVED_MFT_RECORDS )
data_pos = RESERVED_MFT_RECORDS;
if (data_pos >= pass_end) {
if ( data_pos >= pass_end )
{
data_pos = RESERVED_MFT_RECORDS;
pass = 2;
/* This happens on a freshly formatted volume. */
if (data_pos >= pass_end) {
if ( data_pos >= pass_end )
{
errno = ENOSPC;
goto leave;
}
}
if (ntfs_is_mft(base_ni)) {
if ( ntfs_is_mft( base_ni ) )
{
data_pos = 0;
pass = 2;
}
@ -529,21 +552,24 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
b = 0;
#endif
/* Loop until a free mft record is found. */
for (; pass <= 2; size = PAGE_SIZE) {
for ( ; pass <= 2; size = PAGE_SIZE )
{
/* Cap size to pass_end. */
ofs = data_pos >> 3;
ll = ( ( pass_end + 7 ) >> 3 ) - ofs;
if ( size > ll )
size = ll;
ll = ntfs_attr_pread( mftbmp_na, ofs, size, buf );
if (ll < 0) {
if ( ll < 0 )
{
ntfs_log_perror( "Failed to read $MFT bitmap" );
free( buf );
goto leave;
}
ntfs_log_debug( "Read 0x%llx bytes.\n", ( long long )ll );
/* If we read at least one byte, search @buf for a zero bit. */
if (ll) {
if ( ll )
{
size = ll << 3;
bit = data_pos & 7;
data_pos &= ~7ull;
@ -553,7 +579,8 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
( long long )data_pos, ( long long )bit,
byte ? *byte : -1, b );
for ( ; bit < size && data_pos + bit < pass_end;
bit &= ~7ull, bit += 8) {
bit &= ~7ull, bit += 8 )
{
/*
* If we're extending $MFT and running out of the first
* mft record (base record) then give up searching since
@ -568,7 +595,8 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
/* Note: ffz() result must be zero based. */
b = ntfs_ffz( ( unsigned long ) * byte );
if (b < 8 && b >= (bit & 7)) {
if ( b < 8 && b >= ( bit & 7 ) )
{
free( buf );
ret = data_pos + ( bit & ~7ull ) + b;
goto leave;
@ -589,7 +617,8 @@ static int ntfs_mft_bitmap_find_free_rec(ntfs_volume *vol, ntfs_inode *base_ni)
}
/* Do the next pass. */
pass++;
if (pass == 2) {
if ( pass == 2 )
{
/*
* Starting the second pass, in which we scan the first
* part of the zone which we omitted earlier.
@ -617,8 +646,10 @@ static int ntfs_mft_attr_extend(ntfs_attr *na)
int ret = STATUS_ERROR;
ntfs_log_enter( "Entering\n" );
if (!NInoAttrList(na->ni)) {
if (ntfs_inode_add_attrlist(na->ni)) {
if ( !NInoAttrList( na->ni ) )
{
if ( ntfs_inode_add_attrlist( na->ni ) )
{
ntfs_log_perror( "%s: Can not add attrlist #3", __FUNCTION__ );
goto out;
}
@ -627,7 +658,8 @@ static int ntfs_mft_attr_extend(ntfs_attr *na)
goto out;
}
if (ntfs_attr_update_mapping_pairs(na, 0)) {
if ( ntfs_attr_update_mapping_pairs( na, 0 ) )
{
ntfs_log_perror( "%s: MP update failed", __FUNCTION__ );
goto out;
}
@ -663,7 +695,8 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
*/
rl = ntfs_attr_find_vcn( mftbmp_na, ( mftbmp_na->allocated_size - 1 ) >>
vol->cluster_size_bits );
if (!rl || !rl->length || rl->lcn < 0) {
if ( !rl || !rl->length || rl->lcn < 0 )
{
ntfs_log_error( "Failed to determine last allocated "
"cluster of mft bitmap attribute.\n" );
if ( rl )
@ -673,13 +706,15 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
lcn = rl->lcn + rl->length;
rl2 = ntfs_cluster_alloc( vol, rl[1].vcn, 1, lcn, DATA_ZONE );
if (!rl2) {
if ( !rl2 )
{
ntfs_log_error( "Failed to allocate a cluster for "
"the mft bitmap.\n" );
return STATUS_ERROR;
}
rl = ntfs_runlists_merge( mftbmp_na->rl, rl2 );
if (!rl) {
if ( !rl )
{
err = errno;
ntfs_log_error( "Failed to merge runlists for mft "
"bitmap.\n" );
@ -704,7 +739,8 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
goto undo_alloc;
if ( ntfs_attr_lookup( mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, rl[1].vcn, NULL, 0, ctx)) {
mftbmp_na->name_len, 0, rl[1].vcn, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find last attribute extent of "
"mft bitmap attribute.\n" );
goto undo_alloc;
@ -713,7 +749,8 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
a = ctx->attr;
ll = sle64_to_cpu( a->lowest_vcn );
rl2 = ntfs_attr_find_vcn( mftbmp_na, ll );
if (!rl2 || !rl2->length) {
if ( !rl2 || !rl2->length )
{
ntfs_log_error( "Failed to determine previous last "
"allocated cluster of mft bitmap attribute.\n" );
if ( rl2 )
@ -722,7 +759,8 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
}
/* Get the size for the new mapping pairs array for this extent. */
mp_size = ntfs_get_size_for_mapping_pairs( vol, rl2, ll, INT_MAX );
if (mp_size <= 0) {
if ( mp_size <= 0 )
{
ntfs_log_error( "Get size for mapping pairs failed for "
"mft bitmap attribute extent.\n" );
goto undo_alloc;
@ -730,12 +768,14 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
/* Expand the attribute record if necessary. */
old_alen = le32_to_cpu( a->length );
if ( ntfs_attr_record_resize( m, a, mp_size +
le16_to_cpu(a->mapping_pairs_offset))) {
le16_to_cpu( a->mapping_pairs_offset ) ) )
{
ntfs_log_info( "extending $MFT bitmap\n" );
ret = ntfs_mft_attr_extend( vol->mftbmp_na );
if ( ret == STATUS_OK )
goto ok;
if (ret == STATUS_ERROR) {
if ( ret == STATUS_ERROR )
{
ntfs_log_perror( "%s: ntfs_mft_attr_extend failed", __FUNCTION__ );
update_mp = TRUE;
}
@ -745,7 +785,8 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
/* Generate the mapping pairs array directly into the attr record. */
if ( ntfs_mapping_pairs_build( vol, ( u8* )a +
le16_to_cpu( a->mapping_pairs_offset ), mp_size, rl2, ll,
NULL)) {
NULL ) )
{
ntfs_log_error( "Failed to build mapping pairs array for "
"mft bitmap attribute.\n" );
errno = EIO;
@ -757,7 +798,8 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
* We now have extended the mft bitmap allocated_size by one cluster.
* Reflect this in the ntfs_attr structure and the attribute record.
*/
if (a->lowest_vcn) {
if ( a->lowest_vcn )
{
/*
* We are not in the first attribute extent, switch to it, but
* first ensure the changes will make it to disk later.
@ -765,7 +807,8 @@ static int ntfs_mft_bitmap_extend_allocation_i(ntfs_volume *vol)
ntfs_inode_mark_dirty( ctx->ntfs_ino );
ntfs_attr_reinit_search_ctx( ctx );
if ( ntfs_attr_lookup( mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, 0, NULL, 0, ctx)) {
mftbmp_na->name_len, 0, 0, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find first attribute "
"extent of mft bitmap attribute.\n" );
goto restore_undo_alloc;
@ -784,7 +827,8 @@ restore_undo_alloc:
err = errno;
ntfs_attr_reinit_search_ctx( ctx );
if ( ntfs_attr_lookup( mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, rl[1].vcn, NULL, 0, ctx)) {
mftbmp_na->name_len, 0, rl[1].vcn, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find last attribute extent of "
"mft bitmap attribute.%s\n", es );
ntfs_attr_put_search_ctx( ctx );
@ -813,7 +857,8 @@ undo_alloc:
ntfs_log_error( "Failed to free cluster.%s\n", es );
else
vol->free_clusters++;
if (mp_rebuilt) {
if ( mp_rebuilt )
{
if ( ntfs_mapping_pairs_build( vol, ( u8* )a +
le16_to_cpu( a->mapping_pairs_offset ),
old_alen - le16_to_cpu( a->mapping_pairs_offset ),
@ -825,7 +870,8 @@ undo_alloc:
"record.%s\n", es );
ntfs_inode_mark_dirty( ctx->ntfs_ino );
}
if (update_mp) {
if ( update_mp )
{
if ( ntfs_attr_update_mapping_pairs( vol->mftbmp_na, 0 ) )
ntfs_log_perror( "%s: MP update failed", __FUNCTION__ );
}
@ -884,7 +930,8 @@ static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
goto out;
if ( ntfs_attr_lookup( mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, 0, NULL, 0, ctx)) {
mftbmp_na->name_len, 0, 0, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find first attribute extent of "
"mft bitmap attribute.\n" );
err = errno;
@ -895,7 +942,8 @@ static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
old_initialized_size = mftbmp_na->initialized_size;
mftbmp_na->initialized_size += 8;
a->initialized_size = cpu_to_sle64( mftbmp_na->initialized_size );
if (mftbmp_na->initialized_size > mftbmp_na->data_size) {
if ( mftbmp_na->initialized_size > mftbmp_na->data_size )
{
mftbmp_na->data_size = mftbmp_na->initialized_size;
a->data_size = cpu_to_sle64( mftbmp_na->data_size );
}
@ -905,7 +953,8 @@ static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
/* Initialize the mft bitmap attribute value with zeroes. */
ll = 0;
ll = ntfs_attr_pwrite( mftbmp_na, old_initialized_size, 8, &ll );
if (ll == 8) {
if ( ll == 8 )
{
ntfs_log_debug( "Wrote eight initialized bytes to mft bitmap.\n" );
vol->free_mft_records += ( 8 * 8 );
ret = 0;
@ -921,7 +970,8 @@ static int ntfs_mft_bitmap_extend_initialized(ntfs_volume *vol)
goto err_out;
if ( ntfs_attr_lookup( mftbmp_na->type, mftbmp_na->name,
mftbmp_na->name_len, 0, 0, NULL, 0, ctx)) {
mftbmp_na->name_len, 0, 0, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find first attribute extent of "
"mft bitmap attribute.%s\n", es );
put_err_out:
@ -931,7 +981,8 @@ put_err_out:
a = ctx->attr;
mftbmp_na->initialized_size = old_initialized_size;
a->initialized_size = cpu_to_sle64( old_initialized_size );
if (mftbmp_na->data_size != old_data_size) {
if ( mftbmp_na->data_size != old_data_size )
{
mftbmp_na->data_size = old_data_size;
a->data_size = cpu_to_sle64( old_data_size );
}
@ -989,7 +1040,8 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
rl = ntfs_attr_find_vcn( mft_na,
( mft_na->allocated_size - 1 ) >> vol->cluster_size_bits );
if (!rl || !rl->length || rl->lcn < 0) {
if ( !rl || !rl->length || rl->lcn < 0 )
{
ntfs_log_error( "Failed to determine last allocated "
"cluster of mft data attribute.\n" );
if ( rl )
@ -1009,11 +1061,13 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
nr = min_nr;
old_last_vcn = rl[1].vcn;
do {
do
{
rl2 = ntfs_cluster_alloc( vol, old_last_vcn, nr, lcn, MFT_ZONE );
if ( rl2 )
break;
if (errno != ENOSPC || nr == min_nr) {
if ( errno != ENOSPC || nr == min_nr )
{
ntfs_log_perror( "Failed to allocate (%lld) clusters "
"for $MFT", ( long long )nr );
goto out;
@ -1026,12 +1080,14 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
nr = min_nr;
ntfs_log_debug( "Retrying mft data allocation with minimal cluster "
"count %lli.\n", ( long long )nr );
} while (1);
}
while ( 1 );
ntfs_log_debug( "Allocated %lld clusters.\n", ( long long )nr );
rl = ntfs_runlists_merge( mft_na->rl, rl2 );
if (!rl) {
if ( !rl )
{
err = errno;
ntfs_log_error( "Failed to merge runlists for mft data "
"attribute.\n" );
@ -1053,7 +1109,8 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
goto undo_alloc;
if ( ntfs_attr_lookup( mft_na->type, mft_na->name, mft_na->name_len, 0,
rl[1].vcn, NULL, 0, ctx)) {
rl[1].vcn, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find last attribute extent of "
"mft data attribute.\n" );
goto undo_alloc;
@ -1062,7 +1119,8 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
a = ctx->attr;
ll = sle64_to_cpu( a->lowest_vcn );
rl2 = ntfs_attr_find_vcn( mft_na, ll );
if (!rl2 || !rl2->length) {
if ( !rl2 || !rl2->length )
{
ntfs_log_error( "Failed to determine previous last "
"allocated cluster of mft data attribute.\n" );
if ( rl2 )
@ -1071,7 +1129,8 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
}
/* Get the size for the new mapping pairs array for this extent. */
mp_size = ntfs_get_size_for_mapping_pairs( vol, rl2, ll, INT_MAX );
if (mp_size <= 0) {
if ( mp_size <= 0 )
{
ntfs_log_error( "Get size for mapping pairs failed for "
"mft data attribute extent.\n" );
goto undo_alloc;
@ -1079,11 +1138,13 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
/* Expand the attribute record if necessary. */
old_alen = le32_to_cpu( a->length );
if ( ntfs_attr_record_resize( m, a,
mp_size + le16_to_cpu(a->mapping_pairs_offset))) {
mp_size + le16_to_cpu( a->mapping_pairs_offset ) ) )
{
ret = ntfs_mft_attr_extend( vol->mft_na );
if ( ret == STATUS_OK )
goto ok;
if (ret == STATUS_ERROR) {
if ( ret == STATUS_ERROR )
{
ntfs_log_perror( "%s: ntfs_mft_attr_extend failed", __FUNCTION__ );
update_mp = TRUE;
}
@ -1095,7 +1156,8 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
*/
if ( ntfs_mapping_pairs_build( vol,
( u8* )a + le16_to_cpu( a->mapping_pairs_offset ), mp_size,
rl2, ll, NULL)) {
rl2, ll, NULL ) )
{
ntfs_log_error( "Failed to build mapping pairs array of "
"mft data attribute.\n" );
errno = EIO;
@ -1109,7 +1171,8 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
* @rl is the last (non-terminator) runlist element of mft data
* attribute.
*/
if (a->lowest_vcn) {
if ( a->lowest_vcn )
{
/*
* We are not in the first attribute extent, switch to it, but
* first ensure the changes will make it to disk later.
@ -1117,7 +1180,8 @@ static int ntfs_mft_data_extend_allocation(ntfs_volume *vol)
ntfs_inode_mark_dirty( ctx->ntfs_ino );
ntfs_attr_reinit_search_ctx( ctx );
if ( ntfs_attr_lookup( mft_na->type, mft_na->name,
mft_na->name_len, 0, 0, NULL, 0, ctx)) {
mft_na->name_len, 0, 0, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find first attribute "
"extent of mft data attribute.\n" );
goto restore_undo_alloc;
@ -1139,7 +1203,8 @@ restore_undo_alloc:
err = errno;
ntfs_attr_reinit_search_ctx( ctx );
if ( ntfs_attr_lookup( mft_na->type, mft_na->name, mft_na->name_len, 0,
rl[1].vcn, NULL, 0, ctx)) {
rl[1].vcn, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find last attribute extent of "
"mft data attribute.%s\n", es );
ntfs_attr_put_search_ctx( ctx );
@ -1164,7 +1229,8 @@ undo_alloc:
if ( ntfs_rl_truncate( &mft_na->rl, old_last_vcn ) )
ntfs_log_error( "Failed to truncate mft data attribute "
"runlist.%s\n", es );
if (mp_rebuilt) {
if ( mp_rebuilt )
{
if ( ntfs_mapping_pairs_build( vol, ( u8* )a +
le16_to_cpu( a->mapping_pairs_offset ),
old_alen - le16_to_cpu( a->mapping_pairs_offset ),
@ -1176,7 +1242,8 @@ undo_alloc:
"record.%s\n", es );
ntfs_inode_mark_dirty( ctx->ntfs_ino );
}
if (update_mp) {
if ( update_mp )
{
if ( ntfs_attr_update_mapping_pairs( vol->mft_na, 0 ) )
ntfs_log_perror( "%s: MP update failed", __FUNCTION__ );
}
@ -1213,7 +1280,8 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
( long long )mft_na->allocated_size,
( long long )mft_na->data_size,
( long long )mft_na->initialized_size );
while (size > mft_na->allocated_size) {
while ( size > mft_na->allocated_size )
{
if ( ntfs_mft_data_extend_allocation( vol ) == STATUS_ERROR )
goto out;
ntfs_log_debug( "Status of mft data after allocation extension: "
@ -1234,13 +1302,15 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
* needed by ntfs_mft_record_format(). We will update the attribute
* record itself in one fell swoop later on.
*/
while (size > mft_na->initialized_size) {
while ( size > mft_na->initialized_size )
{
s64 ll2 = mft_na->initialized_size >> vol->mft_record_size_bits;
mft_na->initialized_size += vol->mft_record_size;
if ( mft_na->initialized_size > mft_na->data_size )
mft_na->data_size = mft_na->initialized_size;
ntfs_log_debug( "Initializing mft record 0x%llx.\n", ( long long )ll2 );
if (ntfs_mft_record_format(vol, ll2) < 0) {
if ( ntfs_mft_record_format( vol, ll2 ) < 0 )
{
ntfs_log_perror( "Failed to format mft record" );
goto undo_data_init;
}
@ -1252,7 +1322,8 @@ static int ntfs_mft_record_init(ntfs_volume *vol, s64 size)
goto undo_data_init;
if ( ntfs_attr_lookup( mft_na->type, mft_na->name, mft_na->name_len, 0,
0, NULL, 0, ctx)) {
0, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find first attribute extent of "
"mft data attribute.\n" );
ntfs_attr_put_search_ctx( ctx );
@ -1304,7 +1375,8 @@ static int ntfs_mft_rec_init(ntfs_volume *vol, s64 size)
mft_na = vol->mft_na;
mftbmp_na = vol->mftbmp_na;
if (size > mft_na->allocated_size || size > mft_na->initialized_size) {
if ( size > mft_na->allocated_size || size > mft_na->initialized_size )
{
errno = EIO;
ntfs_log_perror( "%s: unexpected $MFT sizes, see below", __FUNCTION__ );
ntfs_log_error( "$MFT: size=%lld allocated_size=%lld "
@ -1325,7 +1397,8 @@ static int ntfs_mft_rec_init(ntfs_volume *vol, s64 size)
goto undo_data_init;
if ( ntfs_attr_lookup( mft_na->type, mft_na->name, mft_na->name_len, 0,
0, NULL, 0, ctx)) {
0, NULL, 0, ctx ) )
{
ntfs_log_error( "Failed to find first attribute extent of "
"mft data attribute.\n" );
ntfs_attr_put_search_ctx( ctx );
@ -1384,7 +1457,8 @@ static ntfs_inode *ntfs_mft_rec_alloc(ntfs_volume *vol)
goto err_out;
found_free_rec:
if (ntfs_bitmap_set_bit(mftbmp_na, bit)) {
if ( ntfs_bitmap_set_bit( mftbmp_na, bit ) )
{
ntfs_log_error( "Failed to allocate bit in mft bitmap #2\n" );
goto err_out;
}
@ -1403,12 +1477,14 @@ found_free_rec:
if ( !m )
goto undo_mftbmp_alloc;
if (ntfs_mft_record_read(vol, bit, m)) {
if ( ntfs_mft_record_read( vol, bit, m ) )
{
free( m );
goto undo_mftbmp_alloc;
}
/* Sanity check that the mft record is really not in use. */
if (ntfs_is_file_record(m->magic) && (m->flags & MFT_RECORD_IN_USE)) {
if ( ntfs_is_file_record( m->magic ) && ( m->flags & MFT_RECORD_IN_USE ) )
{
ntfs_log_error( "Inode %lld is used but it wasn't marked in "
"$MFT bitmap. Fixed.\n", ( long long )bit );
free( m );
@ -1417,7 +1493,8 @@ found_free_rec:
seq_no = m->sequence_number;
usn = *( le16* )( ( u8* )m + le16_to_cpu( m->usa_ofs ) );
if (ntfs_mft_record_layout(vol, bit, m)) {
if ( ntfs_mft_record_layout( vol, bit, m ) )
{
ntfs_log_error( "Failed to re-format mft record.\n" );
free( m );
goto undo_mftbmp_alloc;
@ -1431,7 +1508,8 @@ found_free_rec:
m->flags |= MFT_RECORD_IN_USE;
/* Now need to open an ntfs inode for the mft record. */
ni = ntfs_inode_allocate( vol );
if (!ni) {
if ( !ni )
{
ntfs_log_error( "Failed to allocate buffer for inode.\n" );
free( m );
goto undo_mftbmp_alloc;
@ -1451,18 +1529,21 @@ found_free_rec:
* Attach the extent inode to the base inode, reallocating
* memory if needed.
*/
if (!(base_ni->nr_extents & 3)) {
if ( !( base_ni->nr_extents & 3 ) )
{
ntfs_inode **extent_nis;
int i;
i = ( base_ni->nr_extents + 4 ) * sizeof( ntfs_inode * );
extent_nis = ntfs_malloc( i );
if (!extent_nis) {
if ( !extent_nis )
{
free( m );
free( ni );
goto undo_mftbmp_alloc;
}
if (base_ni->nr_extents) {
if ( base_ni->nr_extents )
{
memcpy( extent_nis, base_ni->extent_nis,
i - 4 * sizeof( ntfs_inode * ) );
free( base_ni->extent_nis );
@ -1599,12 +1680,14 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, ntfs_inode *base_ni)
( long long )base_ni->mft_no );
else
ntfs_log_enter( "Entering (allocating a base mft record)\n" );
if (!vol || !vol->mft_na || !vol->mftbmp_na) {
if ( !vol || !vol->mft_na || !vol->mftbmp_na )
{
errno = EINVAL;
goto out;
}
if (ntfs_is_mft(base_ni)) {
if ( ntfs_is_mft( base_ni ) )
{
ni = ntfs_mft_rec_alloc( vol );
goto out;
}
@ -1613,7 +1696,8 @@ ntfs_inode *ntfs_mft_record_alloc(ntfs_volume *vol, ntfs_inode *base_ni)
mftbmp_na = vol->mftbmp_na;
retry:
bit = ntfs_mft_bitmap_find_free_rec( vol, base_ni );
if (bit >= 0) {
if ( bit >= 0 )
{
ntfs_log_debug( "found free record (#1) at %lld\n",
( long long )bit );
goto found_free_rec;
@ -1630,7 +1714,8 @@ retry:
*/
ll = mft_na->initialized_size >> vol->mft_record_size_bits;
if ( mftbmp_na->initialized_size << 3 > ll &&
mftbmp_na->initialized_size > RESERVED_MFT_RECORDS / 8) {
mftbmp_na->initialized_size > RESERVED_MFT_RECORDS / 8 )
{
bit = ll;
if ( bit < RESERVED_MFT_RECORDS )
bit = RESERVED_MFT_RECORDS;
@ -1648,13 +1733,15 @@ retry:
( long long )mftbmp_na->allocated_size,
( long long )mftbmp_na->data_size,
( long long )mftbmp_na->initialized_size );
if (mftbmp_na->initialized_size + 8 > mftbmp_na->allocated_size) {
if ( mftbmp_na->initialized_size + 8 > mftbmp_na->allocated_size )
{
int ret = ntfs_mft_bitmap_extend_allocation( vol );
if ( ret == STATUS_ERROR )
goto err_out;
if (ret == STATUS_KEEP_SEARCHING) {
if ( ret == STATUS_KEEP_SEARCHING )
{
ret = ntfs_mft_bitmap_extend_allocation( vol );
if ( ret != STATUS_OK )
goto err_out;
@ -1684,7 +1771,8 @@ retry:
ntfs_log_debug( "found free record (#3) at %lld\n", ( long long )bit );
found_free_rec:
/* @bit is the found free mft record, allocate it in the mft bitmap. */
if (ntfs_bitmap_set_bit(mftbmp_na, bit)) {
if ( ntfs_bitmap_set_bit( mftbmp_na, bit ) )
{
ntfs_log_error( "Failed to allocate bit in mft bitmap.\n" );
goto err_out;
}
@ -1705,12 +1793,14 @@ found_free_rec:
if ( !m )
goto undo_mftbmp_alloc;
if (ntfs_mft_record_read(vol, bit, m)) {
if ( ntfs_mft_record_read( vol, bit, m ) )
{
free( m );
goto undo_mftbmp_alloc;
}
/* Sanity check that the mft record is really not in use. */
if (ntfs_is_file_record(m->magic) && (m->flags & MFT_RECORD_IN_USE)) {
if ( ntfs_is_file_record( m->magic ) && ( m->flags & MFT_RECORD_IN_USE ) )
{
ntfs_log_error( "Inode %lld is used but it wasn't marked in "
"$MFT bitmap. Fixed.\n", ( long long )bit );
free( m );
@ -1718,7 +1808,8 @@ found_free_rec:
}
seq_no = m->sequence_number;
usn = *( le16* )( ( u8* )m + le16_to_cpu( m->usa_ofs ) );
if (ntfs_mft_record_layout(vol, bit, m)) {
if ( ntfs_mft_record_layout( vol, bit, m ) )
{
ntfs_log_error( "Failed to re-format mft record.\n" );
free( m );
goto undo_mftbmp_alloc;
@ -1732,7 +1823,8 @@ found_free_rec:
m->flags |= MFT_RECORD_IN_USE;
/* Now need to open an ntfs inode for the mft record. */
ni = ntfs_inode_allocate( vol );
if (!ni) {
if ( !ni )
{
ntfs_log_error( "Failed to allocate buffer for inode.\n" );
free( m );
goto undo_mftbmp_alloc;
@ -1744,7 +1836,8 @@ found_free_rec:
* extent inode and attach it to the base inode. Also, set the base
* mft record reference in the extent inode.
*/
if (base_ni) {
if ( base_ni )
{
ni->nr_extents = -1;
ni->base_ni = base_ni;
m->base_mft_record = MK_LE_MREF( base_ni->mft_no,
@ -1753,18 +1846,21 @@ found_free_rec:
* Attach the extent inode to the base inode, reallocating
* memory if needed.
*/
if (!(base_ni->nr_extents & 3)) {
if ( !( base_ni->nr_extents & 3 ) )
{
ntfs_inode **extent_nis;
int i;
i = ( base_ni->nr_extents + 4 ) * sizeof( ntfs_inode * );
extent_nis = ntfs_malloc( i );
if (!extent_nis) {
if ( !extent_nis )
{
free( m );
free( ni );
goto undo_mftbmp_alloc;
}
if (base_ni->nr_extents) {
if ( base_ni->nr_extents )
{
memcpy( extent_nis, base_ni->extent_nis,
i - 4 * sizeof( ntfs_inode * ) );
free( base_ni->extent_nis );
@ -1824,7 +1920,8 @@ int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni)
ntfs_log_trace( "Entering for inode 0x%llx.\n", ( long long ) ni->mft_no );
if (!vol || !vol->mftbmp_na || !ni) {
if ( !vol || !vol->mftbmp_na || !ni )
{
errno = EINVAL;
return -1;
}
@ -1846,13 +1943,15 @@ int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni)
/* Set the inode dirty and write it out. */
ntfs_inode_mark_dirty( ni );
if (ntfs_inode_sync(ni)) {
if ( ntfs_inode_sync( ni ) )
{
err = errno;
goto sync_rollback;
}
/* Clear the bit in the $MFT/$BITMAP corresponding to this record. */
if (ntfs_bitmap_clear_bit(vol->mftbmp_na, mft_no)) {
if ( ntfs_bitmap_clear_bit( vol->mftbmp_na, mft_no ) )
{
err = errno;
// FIXME: If ntfs_bitmap_clear_run() guarantees rollback on
// error, this could be changed to goto sync_rollback;
@ -1861,9 +1960,11 @@ int ntfs_mft_record_free(ntfs_volume *vol, ntfs_inode *ni)
/* Throw away the now freed inode. */
#if CACHE_NIDATA_SIZE
if (!ntfs_inode_real_close(ni)) {
if ( !ntfs_inode_real_close( ni ) )
{
#else
if (!ntfs_inode_close(ni)) {
if ( !ntfs_inode_close( ni ) )
{
#endif
vol->free_mft_records++;
return 0;
@ -1894,7 +1995,8 @@ int ntfs_mft_usn_dec(MFT_RECORD *mrec)
u16 usn;
le16 *usnp;
if (!mrec) {
if ( !mrec )
{
errno = EINVAL;
return -1;
}

View File

@ -61,7 +61,8 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size)
/* Size and alignment checks. */
if ( size & ( NTFS_BLOCK_SIZE - 1 ) || usa_ofs & 1 ||
( u32 )( usa_ofs + ( usa_count * 2 ) ) > size ||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count) {
( size >> NTFS_BLOCK_SIZE_BITS ) != usa_count )
{
errno = EINVAL;
ntfs_log_perror( "%s: magic: 0x%08x size: %d usa_ofs: %d "
"usa_count: %d", __FUNCTION__, *( le32 * )b,
@ -85,8 +86,10 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size)
/*
* Check for incomplete multi sector transfer(s).
*/
while (usa_count--) {
if (*data_pos != usn) {
while ( usa_count-- )
{
if ( *data_pos != usn )
{
/*
* Incomplete multi sector transfer detected! )-:
* Set the magic to "BAAD" and return failure.
@ -106,7 +109,8 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size)
usa_count = le16_to_cpu( b->usa_count ) - 1;
data_pos = ( u16* )b + NTFS_BLOCK_SIZE / sizeof( u16 ) - 1;
/* Fixup all sectors. */
while (usa_count--) {
while ( usa_count-- )
{
/*
* Increment position in usa and restore original data from
* the usa into the data buffer.
@ -147,7 +151,8 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
/* Sanity check + only fixup if it makes sense. */
if ( !b || ntfs_is_baad_record( b->magic ) ||
ntfs_is_hole_record(b->magic)) {
ntfs_is_hole_record( b->magic ) )
{
errno = EINVAL;
ntfs_log_perror( "%s: bad argument", __FUNCTION__ );
return -1;
@ -159,7 +164,8 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
/* Size and alignment checks. */
if ( size & ( NTFS_BLOCK_SIZE - 1 ) || usa_ofs & 1 ||
( u32 )( usa_ofs + ( usa_count * 2 ) ) > size ||
(size >> NTFS_BLOCK_SIZE_BITS) != usa_count) {
( size >> NTFS_BLOCK_SIZE_BITS ) != usa_count )
{
errno = EINVAL;
ntfs_log_perror( "%s", __FUNCTION__ );
return -1;
@ -178,7 +184,8 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
/* Position in data of first u16 that needs fixing up. */
data_pos = ( u16* )b + NTFS_BLOCK_SIZE / sizeof( u16 ) - 1;
/* Fixup all sectors. */
while (usa_count--) {
while ( usa_count-- )
{
/*
* Increment the position in the usa and save the
* original data from the data buffer into the usa.
@ -217,7 +224,8 @@ void ntfs_mst_post_write_fixup(NTFS_RECORD *b)
data_pos = ( u16* )b + NTFS_BLOCK_SIZE / sizeof( u16 ) - 1;
/* Fixup all sectors. */
while (usa_count--) {
while ( usa_count-- )
{
/*
* Increment position in usa and restore original data from
* the usa into the data buffer.

View File

@ -41,7 +41,8 @@
#include "cache.h"
// NTFS device driver devoptab
static const devoptab_t devops_ntfs = {
static const devoptab_t devops_ntfs =
{
NULL, /* Device name */
sizeof ( ntfs_file_state ),
ntfs_open_r,
@ -72,7 +73,8 @@ void ntfsInit (void)
static bool isInit = false;
// Initialise ntfs-3g (if not already done so)
if (!isInit) {
if ( !isInit )
{
isInit = true;
// Set the log handler
@ -98,7 +100,8 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
sec_t part_lba = 0;
int i;
union {
union
{
u8 buffer[512];
MASTER_BOOT_RECORD mbr;
EXTENDED_BOOT_RECORD ebr;
@ -106,7 +109,8 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
} sector;
// Sanity check
if (!interface) {
if ( !interface )
{
errno = EINVAL;
return -1;
}
@ -117,27 +121,32 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
ntfsInit();
// Start the device and check that it is inserted
if (!interface->startup()) {
if ( !interface->startup() )
{
errno = EIO;
return -1;
}
if (!interface->isInserted()) {
if ( !interface->isInserted() )
{
return 0;
}
// Read the first sector on the device
if (!interface->readSectors(0, 1, &sector.buffer)) {
if ( !interface->readSectors( 0, 1, &sector.buffer ) )
{
errno = EIO;
return -1;
}
// If this is the devices master boot record
if (sector.mbr.signature == MBR_SIGNATURE) {
if ( sector.mbr.signature == MBR_SIGNATURE )
{
memcpy( &mbr, &sector, sizeof( MASTER_BOOT_RECORD ) );
ntfs_log_debug( "Valid Master Boot Record found\n" );
// Search the partition table for all NTFS partitions (max. 4 primary partitions)
for (i = 0; i < 4; i++) {
for ( i = 0; i < 4; i++ )
{
partition = &mbr.partitions[i];
part_lba = le32_to_cpu( mbr.partitions[i].lba_start );
@ -146,25 +155,32 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
part_lba, partition->type );
// Figure out what type of partition this is
switch (partition->type) {
switch ( partition->type )
{
// Ignore empty partitions
case PARTITION_TYPE_EMPTY:
continue;
// NTFS partition
case PARTITION_TYPE_NTFS: {
case PARTITION_TYPE_NTFS:
{
ntfs_log_debug( "Partition %i: Claims to be NTFS\n", i + 1 );
// Read and validate the NTFS partition
if (interface->readSectors(part_lba, 1, &sector)) {
if (sector.boot.oem_id == NTFS_OEM_ID) {
if ( interface->readSectors( part_lba, 1, &sector ) )
{
if ( sector.boot.oem_id == NTFS_OEM_ID )
{
ntfs_log_debug( "Partition %i: Valid NTFS boot sector found\n", i + 1 );
if (partition_count < NTFS_MAX_PARTITIONS) {
if ( partition_count < NTFS_MAX_PARTITIONS )
{
partition_starts[partition_count] = part_lba;
partition_count++;
}
} else {
}
else
{
ntfs_log_debug( "Partition %i: Invalid NTFS boot sector, not actually NTFS\n", i + 1 );
}
}
@ -175,17 +191,21 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
// DOS 3.3+ or Windows 95 extended partition
case PARTITION_TYPE_DOS33_EXTENDED:
case PARTITION_TYPE_WIN95_EXTENDED: {
case PARTITION_TYPE_WIN95_EXTENDED:
{
ntfs_log_debug( "Partition %i: Claims to be Extended\n", i + 1 );
// Walk the extended partition chain, finding all NTFS partitions within it
sec_t ebr_lba = part_lba;
sec_t next_erb_lba = 0;
do {
do
{
// Read and validate the extended boot record
if (interface->readSectors(ebr_lba + next_erb_lba, 1, &sector)) {
if (sector.ebr.signature == EBR_SIGNATURE) {
if ( interface->readSectors( ebr_lba + next_erb_lba, 1, &sector ) )
{
if ( sector.ebr.signature == EBR_SIGNATURE )
{
ntfs_log_debug( "Logical Partition @ %d: type 0x%x\n", ebr_lba + next_erb_lba,
sector.ebr.partition.status == PARTITION_STATUS_BOOTABLE ? "bootable (active)" : "non-bootable",
sector.ebr.partition.type );
@ -196,42 +216,54 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
next_erb_lba = le32_to_cpu( sector.ebr.next_ebr.lba_start );
// Check if this partition has a valid NTFS boot record
if (interface->readSectors(part_lba, 1, &sector)) {
if (sector.boot.oem_id == NTFS_OEM_ID) {
if ( interface->readSectors( part_lba, 1, &sector ) )
{
if ( sector.boot.oem_id == NTFS_OEM_ID )
{
ntfs_log_debug( "Logical Partition @ %d: Valid NTFS boot sector found\n", part_lba );
if(sector.ebr.partition.type != PARTITION_TYPE_NTFS) {
if ( sector.ebr.partition.type != PARTITION_TYPE_NTFS )
{
ntfs_log_warning( "Logical Partition @ %d: Is NTFS but type is 0x%x; 0x%x was expected\n", part_lba, sector.ebr.partition.type, PARTITION_TYPE_NTFS );
}
if (partition_count < NTFS_MAX_PARTITIONS) {
if ( partition_count < NTFS_MAX_PARTITIONS )
{
partition_starts[partition_count] = part_lba;
partition_count++;
}
}
}
} else {
}
else
{
next_erb_lba = 0;
}
}
} while (next_erb_lba);
}
while ( next_erb_lba );
break;
}
// Unknown or unsupported partition type
default: {
default:
{
// Check if this partition has a valid NTFS boot record anyway,
// it might be misrepresented due to a lazy partition editor
if (interface->readSectors(part_lba, 1, &sector)) {
if (sector.boot.oem_id == NTFS_OEM_ID) {
if ( interface->readSectors( part_lba, 1, &sector ) )
{
if ( sector.boot.oem_id == NTFS_OEM_ID )
{
ntfs_log_debug( "Partition %i: Valid NTFS boot sector found\n", i + 1 );
if(partition->type != PARTITION_TYPE_NTFS) {
if ( partition->type != PARTITION_TYPE_NTFS )
{
ntfs_log_warning( "Partition %i: Is NTFS but type is 0x%x; 0x%x was expected\n", i + 1, partition->type, PARTITION_TYPE_NTFS );
}
if (partition_count < NTFS_MAX_PARTITIONS) {
if ( partition_count < NTFS_MAX_PARTITIONS )
{
partition_starts[partition_count] = part_lba;
partition_count++;
}
@ -247,15 +279,21 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
}
// Else it is assumed this device has no master boot record
} else {
}
else
{
ntfs_log_debug( "No Master Boot Record was found!\n" );
// As a last-ditched effort, search the first 64 sectors of the device for stray NTFS partitions
for (i = 0; i < 64; i++) {
if (interface->readSectors(i, 1, &sector)) {
if (sector.boot.oem_id == NTFS_OEM_ID) {
for ( i = 0; i < 64; i++ )
{
if ( interface->readSectors( i, 1, &sector ) )
{
if ( sector.boot.oem_id == NTFS_OEM_ID )
{
ntfs_log_debug( "Valid NTFS boot sector found at sector %d!\n", i );
if (partition_count < NTFS_MAX_PARTITIONS) {
if ( partition_count < NTFS_MAX_PARTITIONS )
{
partition_starts[partition_count] = i;
partition_count++;
}
@ -269,9 +307,11 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
/*interface->shutdown();*/
// Return the found partitions (if any)
if (partition_count > 0) {
if ( partition_count > 0 )
{
*partitions = ( sec_t* )ntfs_alloc( sizeof( sec_t ) * partition_count );
if (*partitions) {
if ( *partitions )
{
memcpy( *partitions, &partition_starts, sizeof( sec_t ) * partition_count );
return partition_count;
}
@ -295,25 +335,33 @@ int ntfsMountAll (ntfs_md **mounts, u32 flags)
ntfsInit();
// Find and mount all NTFS partitions on all known devices
for (i = 0; discs[i].name != NULL && discs[i].interface != NULL; i++) {
for ( i = 0; discs[i].name != NULL && discs[i].interface != NULL; i++ )
{
disc = &discs[i];
partition_count = ntfsFindPartitions( disc->interface, &partitions );
if (partition_count > 0 && partitions) {
for (j = 0, k = 0; j < partition_count; j++) {
if ( partition_count > 0 && partitions )
{
for ( j = 0, k = 0; j < partition_count; j++ )
{
// Find the next unused mount name
do {
do
{
sprintf( name, "%s%i", NTFS_MOUNT_PREFIX, k++ );
if (k >= NTFS_MAX_MOUNTS) {
if ( k >= NTFS_MAX_MOUNTS )
{
ntfs_free( partitions );
errno = EADDRNOTAVAIL;
return -1;
}
} while (ntfsGetDevice(name, false));
}
while ( ntfsGetDevice( name, false ) );
// Mount the partition
if (mount_count < NTFS_MAX_MOUNTS) {
if (ntfsMount(name, disc->interface, partitions[j], CACHE_DEFAULT_PAGE_SIZE, CACHE_DEFAULT_PAGE_COUNT, flags)) {
if ( mount_count < NTFS_MAX_MOUNTS )
{
if ( ntfsMount( name, disc->interface, partitions[j], CACHE_DEFAULT_PAGE_SIZE, CACHE_DEFAULT_PAGE_COUNT, flags ) )
{
strcpy( mount_points[mount_count].name, name );
mount_points[mount_count].interface = disc->interface;
mount_points[mount_count].startSector = partitions[j];
@ -327,9 +375,11 @@ int ntfsMountAll (ntfs_md **mounts, u32 flags)
}
// Return the mounts (if any)
if (mount_count > 0 && mounts) {
if ( mount_count > 0 && mounts )
{
*mounts = ( ntfs_md* )ntfs_alloc( sizeof( ntfs_md ) * mount_count );
if (*mounts) {
if ( *mounts )
{
memcpy( *mounts, &mount_points, sizeof( ntfs_md ) * mount_count );
return mount_count;
}
@ -350,7 +400,8 @@ int ntfsMountDevice (const DISC_INTERFACE *interface, ntfs_md **mounts, u32 flag
int i, j, k;
// Sanity check
if (!interface) {
if ( !interface )
{
errno = EINVAL;
return -1;
}
@ -359,26 +410,35 @@ int ntfsMountDevice (const DISC_INTERFACE *interface, ntfs_md **mounts, u32 flag
ntfsInit();
// Find the specified device then find and mount all NTFS partitions on it
for (i = 0; discs[i].name != NULL && discs[i].interface != NULL; i++) {
if (discs[i].interface == interface) {
for ( i = 0; discs[i].name != NULL && discs[i].interface != NULL; i++ )
{
if ( discs[i].interface == interface )
{
disc = &discs[i];
partition_count = ntfsFindPartitions( disc->interface, &partitions );
if (partition_count > 0 && partitions) {
for (j = 0, k = 0; j < partition_count; j++) {
if ( partition_count > 0 && partitions )
{
for ( j = 0, k = 0; j < partition_count; j++ )
{
// Find the next unused mount name
do {
do
{
sprintf( name, "%s%i", NTFS_MOUNT_PREFIX, k++ );
if (k >= NTFS_MAX_MOUNTS) {
if ( k >= NTFS_MAX_MOUNTS )
{
ntfs_free( partitions );
errno = EADDRNOTAVAIL;
return -1;
}
} while (ntfsGetDevice(name, false));
}
while ( ntfsGetDevice( name, false ) );
// Mount the partition
if (mount_count < NTFS_MAX_MOUNTS) {
if (ntfsMount(name, disc->interface, partitions[j], CACHE_DEFAULT_PAGE_SIZE, CACHE_DEFAULT_PAGE_COUNT, flags)) {
if ( mount_count < NTFS_MAX_MOUNTS )
{
if ( ntfsMount( name, disc->interface, partitions[j], CACHE_DEFAULT_PAGE_SIZE, CACHE_DEFAULT_PAGE_COUNT, flags ) )
{
strcpy( mount_points[mount_count].name, name );
mount_points[mount_count].interface = disc->interface;
mount_points[mount_count].startSector = partitions[j];
@ -394,15 +454,18 @@ int ntfsMountDevice (const DISC_INTERFACE *interface, ntfs_md **mounts, u32 flag
}
// If we couldn't find the device then return with error status
if (!disc) {
if ( !disc )
{
errno = ENODEV;
return -1;
}
// Return the mounts (if any)
if (mount_count > 0 && mounts) {
if ( mount_count > 0 && mounts )
{
*mounts = ( ntfs_md* )ntfs_alloc( sizeof( ntfs_md ) * mount_count );
if (*mounts) {
if ( *mounts )
{
memcpy( *mounts, &mount_points, sizeof( ntfs_md ) * mount_count );
return mount_count;
}
@ -417,7 +480,8 @@ bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSe
gekko_fd *fd = NULL;
// Sanity check
if (!name || !interface) {
if ( !name || !interface )
{
errno = EINVAL;
return false;
}
@ -426,20 +490,23 @@ bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSe
ntfsInit();
// Check that the requested mount name is free
if (ntfsGetDevice(name, false)) {
if ( ntfsGetDevice( name, false ) )
{
errno = EADDRINUSE;
return false;
}
// Check that we can at least read from this device
if (!(interface->features & FEATURE_MEDIUM_CANREAD)) {
if ( !( interface->features & FEATURE_MEDIUM_CANREAD ) )
{
errno = EPERM;
return false;
}
// Allocate the volume descriptor
vd = ( ntfs_vd* )ntfs_alloc( sizeof( ntfs_vd ) );
if (!vd) {
if ( !vd )
{
errno = ENOMEM;
return false;
}
@ -457,7 +524,8 @@ bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSe
// Allocate the device driver descriptor
fd = ( gekko_fd* )ntfs_alloc( sizeof( gekko_fd ) );
if (!fd) {
if ( !fd )
{
ntfs_free( vd );
errno = ENOMEM;
return false;
@ -473,7 +541,8 @@ bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSe
// Allocate the device driver
vd->dev = ntfs_device_alloc( name, 0, &ntfs_device_gekko_io_ops, fd );
if (!vd->dev) {
if ( !vd->dev )
{
ntfs_free( fd );
ntfs_free( vd );
return false;
@ -499,8 +568,10 @@ bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSe
// Mount the device
vd->vol = ntfs_device_mount( vd->dev, vd->flags );
if (!vd->vol) {
switch(ntfs_volume_error(errno)) {
if ( !vd->vol )
{
switch ( ntfs_volume_error( errno ) )
{
case NTFS_VOLUME_NOT_NTFS: errno = EINVALPART; break;
case NTFS_VOLUME_CORRUPT: errno = EINVALPART; break;
case NTFS_VOLUME_HIBERNATED: errno = EHIBERNATED; break;
@ -513,14 +584,16 @@ bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSe
}
// Initialise the volume descriptor
if (ntfsInitVolume(vd)) {
if ( ntfsInitVolume( vd ) )
{
ntfs_umount( vd->vol, true );
ntfs_free( vd );
return false;
}
// Add the device to the devoptab table
if (ntfsAddDevice(name, vd)) {
if ( ntfsAddDevice( name, vd ) )
{
ntfsDeinitVolume( vd );
ntfs_umount( vd->vol, true );
ntfs_free( vd );
@ -562,14 +635,16 @@ const char *ntfsGetVolumeName (const char *name)
//char *volumeName = NULL;
// Sanity check
if (!name) {
if ( !name )
{
errno = EINVAL;
return NULL;
}
// Get the devices volume descriptor
vd = ntfsGetVolume( name );
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return NULL;
}
@ -642,14 +717,16 @@ bool ntfsSetVolumeName (const char *name, const char *volumeName)
int ulabel_len;
// Sanity check
if (!name) {
if ( !name )
{
errno = EINVAL;
return false;
}
// Get the devices volume descriptor
vd = ntfsGetVolume( name );
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return false;
}
@ -659,7 +736,8 @@ bool ntfsSetVolumeName (const char *name, const char *volumeName)
// Convert the new volume name to unicode
ulabel_len = ntfsLocalToUnicode( volumeName, &ulabel ) * sizeof( ntfschar );
if (ulabel_len < 0) {
if ( ulabel_len < 0 )
{
ntfsUnlock( vd );
errno = EINVAL;
return false;
@ -667,26 +745,32 @@ bool ntfsSetVolumeName (const char *name, const char *volumeName)
// Check if the volume name attribute exists
na = ntfs_attr_open( vd->vol->vol_ni, AT_VOLUME_NAME, NULL, 0 );
if (na) {
if ( na )
{
// It does, resize it to match the length of the new volume name
if (ntfs_attr_truncate(na, ulabel_len)) {
if ( ntfs_attr_truncate( na, ulabel_len ) )
{
ntfs_free( ulabel );
ntfsUnlock( vd );
return false;
}
// Write the new volume name
if (ntfs_attr_pwrite(na, 0, ulabel_len, ulabel) != ulabel_len) {
if ( ntfs_attr_pwrite( na, 0, ulabel_len, ulabel ) != ulabel_len )
{
ntfs_free( ulabel );
ntfsUnlock( vd );
return false;
}
} else {
}
else
{
// It doesn't, create it now
if (ntfs_attr_add(vd->vol->vol_ni, AT_VOLUME_NAME, NULL, 0, (u8*)ulabel, ulabel_len)) {
if ( ntfs_attr_add( vd->vol->vol_ni, AT_VOLUME_NAME, NULL, 0, ( u8* )ulabel, ulabel_len ) )
{
ntfs_free( ulabel );
ntfsUnlock( vd );
return false;
@ -702,7 +786,8 @@ bool ntfsSetVolumeName (const char *name, const char *volumeName)
ntfs_attr_close( na );
// Sync the volume node
if (ntfs_inode_sync(vd->vol->vol_ni)) {
if ( ntfs_inode_sync( vd->vol->vol_ni ) )
{
ntfs_free( ulabel );
ntfsUnlock( vd );
return false;

View File

@ -23,7 +23,8 @@
#define _LIBNTFS_H
#ifdef __cplusplus
extern "C" {
extern "C"
{
#endif
#include <gctypes.h>
@ -54,7 +55,8 @@ extern "C" {
/**
* ntfs_md - NTFS mount descriptor
*/
typedef struct _ntfs_md {
typedef struct _ntfs_md
{
char name[32]; /* Mount name (can be accessed as "name:/") */
const DISC_INTERFACE *interface; /* Block device containing the mounted partition */
sec_t startSector; /* Local block address to first sector of partition */

View File

@ -54,7 +54,8 @@ void ntfsCloseDir (ntfs_dir_state *dir)
return;
// Free the directory entries (if any)
while (dir->first) {
while ( dir->first )
{
ntfs_dir_entry *next = dir->first->next;
ntfs_free( dir->first->name );
ntfs_free( dir->first );
@ -86,7 +87,8 @@ int ntfs_stat_r (struct _reent *r, const char *path, struct stat *st)
// Get the volume descriptor for this path
vd = ntfsGetVolume( path );
if (!vd) {
if ( !vd )
{
r->_errno = ENODEV;
return -1;
}
@ -103,7 +105,8 @@ int ntfs_stat_r (struct _reent *r, const char *path, struct stat *st)
// Find the entry
ni = ntfsOpenEntry( vd, path );
if (!ni) {
if ( !ni )
{
r->_errno = errno;
ntfsUnlock( vd );
return -1;
@ -131,7 +134,8 @@ int ntfs_link_r (struct _reent *r, const char *existing, const char *newLink)
// Get the volume descriptor for this path
vd = ntfsGetVolume( existing );
if (!vd) {
if ( !vd )
{
r->_errno = ENODEV;
return -1;
}
@ -141,7 +145,8 @@ int ntfs_link_r (struct _reent *r, const char *existing, const char *newLink)
// Create a symbolic link between the two paths
ni = ntfsCreate( vd, existing, S_IFLNK, newLink );
if (!ni) {
if ( !ni )
{
ntfsUnlock( vd );
r->_errno = errno;
return -1;
@ -177,7 +182,8 @@ int ntfs_chdir_r (struct _reent *r, const char *name)
// Get the volume descriptor for this path
vd = ntfsGetVolume( name );
if (!vd) {
if ( !vd )
{
r->_errno = ENODEV;
return -1;
}
@ -187,14 +193,16 @@ int ntfs_chdir_r (struct _reent *r, const char *name)
// Find the directory
ni = ntfsOpenEntry( vd, name );
if (!ni) {
if ( !ni )
{
ntfsUnlock( vd );
r->_errno = ENOENT;
return -1;
}
// Ensure that this directory is indeed a directory
if (!(ni->mrec->flags && MFT_RECORD_IS_DIRECTORY)) {
if ( !( ni->mrec->flags && MFT_RECORD_IS_DIRECTORY ) )
{
ntfsCloseEntry( vd, ni );
ntfsUnlock( vd );
r->_errno = ENOTDIR;
@ -223,7 +231,8 @@ int ntfs_rename_r (struct _reent *r, const char *oldName, const char *newName)
// Get the volume descriptor for this path
vd = ntfsGetVolume( oldName );
if (!vd) {
if ( !vd )
{
r->_errno = ENODEV;
return -1;
}
@ -232,7 +241,8 @@ int ntfs_rename_r (struct _reent *r, const char *oldName, const char *newName)
ntfsLock( vd );
// You cannot rename between devices
if(vd != ntfsGetVolume(newName)) {
if ( vd != ntfsGetVolume( newName ) )
{
ntfsUnlock( vd );
r->_errno = EXDEV;
return -1;
@ -240,7 +250,8 @@ int ntfs_rename_r (struct _reent *r, const char *oldName, const char *newName)
// Check that there is no existing entry with the new name
ni = ntfsOpenEntry( vd, newName );
if (ni) {
if ( ni )
{
ntfsCloseEntry( vd, ni );
ntfsUnlock( vd );
r->_errno = EEXIST;
@ -248,14 +259,17 @@ int ntfs_rename_r (struct _reent *r, const char *oldName, const char *newName)
}
// Link the old entry with the new one
if (ntfsLink(vd, oldName, newName)) {
if ( ntfsLink( vd, oldName, newName ) )
{
ntfsUnlock( vd );
return -1;
}
// Unlink the old entry
if (ntfsUnlink(vd, oldName)) {
if (ntfsUnlink(vd, newName)) {
if ( ntfsUnlink( vd, oldName ) )
{
if ( ntfsUnlink( vd, newName ) )
{
ntfsUnlock( vd );
return -1;
}
@ -278,7 +292,8 @@ int ntfs_mkdir_r (struct _reent *r, const char *path, int mode)
// Get the volume descriptor for this path
vd = ntfsGetVolume( path );
if (!vd) {
if ( !vd )
{
r->_errno = ENODEV;
return -1;
}
@ -288,7 +303,8 @@ int ntfs_mkdir_r (struct _reent *r, const char *path, int mode)
// Create the directory
ni = ntfsCreate( vd, path, S_IFDIR, NULL );
if (!ni) {
if ( !ni )
{
ntfsUnlock( vd );
r->_errno = errno;
return -1;
@ -313,7 +329,8 @@ int ntfs_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
// Get the volume descriptor for this path
vd = ntfsGetVolume( path );
if (!vd) {
if ( !vd )
{
r->_errno = ENODEV;
return -1;
}
@ -387,21 +404,25 @@ int ntfs_readdir_filler (DIR_ITER *dirState, const ntfschar *name, const int nam
char *entry_name = NULL;
// Sanity check
if (!dir || !dir->vd) {
if ( !dir || !dir->vd )
{
errno = EINVAL;
return -1;
}
// Ignore DOS file names
if (name_type == FILE_NAME_DOS) {
if ( name_type == FILE_NAME_DOS )
{
return 0;
}
// Preliminary check that this entry can be enumerated (as described by the volume descriptor)
if (MREF(mref) == FILE_root || MREF(mref) >= FILE_first_user || dir->vd->showSystemFiles) {
if ( MREF( mref ) == FILE_root || MREF( mref ) >= FILE_first_user || dir->vd->showSystemFiles )
{
// Convert the entry name to our current local
if (ntfsUnicodeToLocal(name, name_len, &entry_name, 0) < 0) {
if ( ntfsUnicodeToLocal( name, name_len, &entry_name, 0 ) < 0 )
{
return -1;
}
@ -412,7 +433,8 @@ int ntfs_readdir_filler (DIR_ITER *dirState, const ntfschar *name, const int nam
}
// If this is not the parent or self directory reference
if ((strcmp(entry_name, ".") != 0) && (strcmp(entry_name, "..") != 0)) {
if ( ( strcmp( entry_name, "." ) != 0 ) && ( strcmp( entry_name, ".." ) != 0 ) )
{
// Open the entry
ntfs_inode *ni = ntfs_pathname_to_inode( dir->vd->vol, dir->ni, entry_name );
@ -421,7 +443,8 @@ int ntfs_readdir_filler (DIR_ITER *dirState, const ntfschar *name, const int nam
// Double check that this entry can be emuerated (as described by the volume descriptor)
if ( ( ( ni->flags & FILE_ATTR_HIDDEN ) && !dir->vd->showHiddenFiles ) ||
((ni->flags & FILE_ATTR_SYSTEM) && !dir->vd->showSystemFiles)) {
( ( ni->flags & FILE_ATTR_SYSTEM ) && !dir->vd->showSystemFiles ) )
{
ntfs_inode_close( ni );
return 0;
}
@ -442,9 +465,12 @@ int ntfs_readdir_filler (DIR_ITER *dirState, const ntfschar *name, const int nam
entry->mref = MREF( mref );
// Link the entry to the directory
if (!dir->first) {
if ( !dir->first )
{
dir->first = entry;
} else {
}
else
{
ntfs_dir_entry *last = dir->first;
while ( last->next ) last = last->next;
last->next = entry;
@ -464,7 +490,8 @@ DIR_ITER *ntfs_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path
// Get the volume descriptor for this path
dir->vd = ntfsGetVolume( path );
if (!dir->vd) {
if ( !dir->vd )
{
r->_errno = ENODEV;
return NULL;
}
@ -474,14 +501,16 @@ DIR_ITER *ntfs_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path
// Find the directory
dir->ni = ntfsOpenEntry( dir->vd, path );
if (!dir->ni) {
if ( !dir->ni )
{
ntfsUnlock( dir->vd );
r->_errno = ENOENT;
return NULL;
}
// Ensure that this directory is indeed a directory
if (!(dir->ni->mrec->flags && MFT_RECORD_IS_DIRECTORY)) {
if ( !( dir->ni->mrec->flags && MFT_RECORD_IS_DIRECTORY ) )
{
ntfsCloseEntry( dir->vd, dir->ni );
ntfsUnlock( dir->vd );
r->_errno = ENOTDIR;
@ -490,7 +519,8 @@ DIR_ITER *ntfs_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path
// Read the directory
dir->first = dir->current = NULL;
if (ntfs_readdir(dir->ni, &position, dirState, (ntfs_filldir_t)ntfs_readdir_filler)) {
if ( ntfs_readdir( dir->ni, &position, dirState, ( ntfs_filldir_t )ntfs_readdir_filler ) )
{
ntfsCloseDir( dir );
ntfsUnlock( dir->vd );
r->_errno = errno;
@ -504,10 +534,13 @@ DIR_ITER *ntfs_diropen_r (struct _reent *r, DIR_ITER *dirState, const char *path
ntfsUpdateTimes( dir->vd, dir->ni, NTFS_UPDATE_ATIME );
// Insert the directory into the double-linked FILO list of open directories
if (dir->vd->firstOpenDir) {
if ( dir->vd->firstOpenDir )
{
dir->nextOpenDir = dir->vd->firstOpenDir;
dir->vd->firstOpenDir->prevOpenDir = dir;
} else {
}
else
{
dir->nextOpenDir = NULL;
}
dir->prevOpenDir = NULL;
@ -528,7 +561,8 @@ int ntfs_dirreset_r (struct _reent *r, DIR_ITER *dirState)
ntfs_dir_state* dir = STATE( dirState );
// Sanity check
if (!dir || !dir->vd || !dir->ni) {
if ( !dir || !dir->vd || !dir->ni )
{
r->_errno = EBADF;
return -1;
}
@ -556,7 +590,8 @@ int ntfs_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
ntfs_inode *ni = NULL;
// Sanity check
if (!dir || !dir->vd || !dir->ni) {
if ( !dir || !dir->vd || !dir->ni )
{
r->_errno = EBADF;
return -1;
}
@ -565,7 +600,8 @@ int ntfs_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
ntfsLock( dir->vd );
// Check that there is a entry waiting to be fetched
if (!dir->current) {
if ( !dir->current )
{
ntfsUnlock( dir->vd );
r->_errno = ENOENT;
return -1;
@ -583,7 +619,8 @@ int ntfs_dirnext_r (struct _reent *r, DIR_ITER *dirState, char *filename, struct
else
{
ni = ntfsOpenEntry( dir->vd, dir->current->name );
if (ni) {
if ( ni )
{
ntfsStat( dir->vd, ni, filestat );
ntfsCloseEntry( dir->vd, ni );
}
@ -609,7 +646,8 @@ int ntfs_dirclose_r (struct _reent *r, DIR_ITER *dirState)
ntfs_dir_state* dir = STATE( dirState );
// Sanity check
if (!dir || !dir->vd) {
if ( !dir || !dir->vd )
{
r->_errno = EBADF;
return -1;
}

View File

@ -28,7 +28,8 @@
/**
* ntfs_dir_entry - Directory entry
*/
typedef struct _ntfs_dir_entry {
typedef struct _ntfs_dir_entry
{
char *name;
u64 mref;
struct _ntfs_dir_entry *next;
@ -37,7 +38,8 @@ typedef struct _ntfs_dir_entry {
/**
* ntfs_dir_state - Directory state
*/
typedef struct _ntfs_dir_state {
typedef struct _ntfs_dir_state
{
ntfs_vd *vd; /* Volume this directory belongs to */
ntfs_inode *ni; /* Directory descriptor */
ntfs_dir_entry *first; /* The first entry in the directory */

View File

@ -97,7 +97,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Get the volume descriptor for this path
file->vd = ntfsGetVolume( path );
if (!file->vd) {
if ( !file->vd )
{
r->_errno = ENODEV;
return -1;
}
@ -107,19 +108,26 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Determine which mode the file is opened for
file->flags = flags;
if ((flags & 0x03) == O_RDONLY) {
if ( ( flags & 0x03 ) == O_RDONLY )
{
file->read = true;
file->write = false;
file->append = false;
} else if ((flags & 0x03) == O_WRONLY) {
}
else if ( ( flags & 0x03 ) == O_WRONLY )
{
file->read = false;
file->write = true;
file->append = ( flags & O_APPEND );
} else if ((flags & 0x03) == O_RDWR) {
}
else if ( ( flags & 0x03 ) == O_RDWR )
{
file->read = true;
file->write = true;
file->append = ( flags & O_APPEND );
} else {
}
else
{
r->_errno = EACCES;
ntfsUnlock( file->vd );
return -1;
@ -127,7 +135,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Try and find the file and (if found) ensure that it is not a directory
file->ni = ntfsOpenEntry( file->vd, path );
if (file->ni && (file->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
if ( file->ni && ( file->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ) )
{
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
r->_errno = EISDIR;
@ -135,10 +144,12 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Are we creating this file?
if (flags & O_CREAT) {
if ( flags & O_CREAT )
{
// The file SHOULD NOT already exist
if (file->ni) {
if ( file->ni )
{
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
r->_errno = EEXIST;
@ -147,7 +158,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Create the file
file->ni = ntfsCreate( file->vd, path, S_IFREG, NULL );
if (!file->ni) {
if ( !file->ni )
{
ntfsUnlock( file->vd );
return -1;
}
@ -155,7 +167,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Sanity check, the file should be open by now
if (!file->ni) {
if ( !file->ni )
{
ntfsUnlock( file->vd );
r->_errno = ENOENT;
return -1;
@ -163,7 +176,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Open the files data attribute
file->data_na = ntfs_attr_open( file->ni, AT_DATA, AT_UNNAMED, 0 );
if(!file->data_na) {
if ( !file->data_na )
{
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
return -1;
@ -174,7 +188,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
file->encrypted = NAttrEncrypted( file->data_na ) || ( file->ni->flags & FILE_ATTR_ENCRYPTED );
// We cannot read/write encrypted files
if (file->encrypted) {
if ( file->encrypted )
{
ntfs_attr_close( file->data_na );
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
@ -183,7 +198,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Make sure we aren't trying to write to a read-only file
if ((file->ni->flags & FILE_ATTR_READONLY) && file->write) {
if ( ( file->ni->flags & FILE_ATTR_READONLY ) && file->write )
{
ntfs_attr_close( file->data_na );
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
@ -192,8 +208,10 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Truncate the file if requested
if ((flags & O_TRUNC) && file->write) {
if (ntfs_attr_truncate(file->data_na, 0)) {
if ( ( flags & O_TRUNC ) && file->write )
{
if ( ntfs_attr_truncate( file->data_na, 0 ) )
{
ntfs_attr_close( file->data_na );
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
@ -212,10 +230,13 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
ntfsUpdateTimes( file->vd, file->ni, NTFS_UPDATE_ATIME );
// Insert the file into the double-linked FILO list of open files
if (file->vd->firstOpenFile) {
if ( file->vd->firstOpenFile )
{
file->nextOpenFile = file->vd->firstOpenFile;
file->vd->firstOpenFile->prevOpenFile = file;
} else {
}
else
{
file->nextOpenFile = NULL;
}
file->prevOpenFile = NULL;
@ -235,7 +256,8 @@ int ntfs_close_r (struct _reent *r, int fd)
ntfs_file_state* file = STATE( fd );
// Sanity check
if (!file || !file->vd) {
if ( !file || !file->vd )
{
r->_errno = EBADF;
return -1;
}
@ -270,13 +292,15 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
off_t old_pos = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
// Short circuit cases where we don't actually have to do anything
if (!ptr || len <= 0) {
if ( !ptr || len <= 0 )
{
return 0;
}
@ -284,22 +308,26 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
ntfsLock( file->vd );
// Check that we are allowed to write to this file
if (!file->write) {
if ( !file->write )
{
ntfsUnlock( file->vd );
r->_errno = EACCES;
return -1;
}
// If we are in append mode, backup the current position and move to the end of the file
if (file->append) {
if ( file->append )
{
old_pos = file->pos;
file->pos = file->len;
}
// Write to the files data atrribute
while (len) {
while ( len )
{
ssize_t ret = ntfs_attr_pwrite( file->data_na, file->pos, len, ptr );
if (ret <= 0) {
if ( ret <= 0 )
{
ntfsUnlock( file->vd );
r->_errno = errno;
return -1;
@ -310,7 +338,8 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
}
// If we are in append mode, restore the current position to were it was prior to this write
if (file->append) {
if ( file->append )
{
file->pos = old_pos;
}
@ -335,13 +364,15 @@ ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len)
ssize_t read = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
// Short circuit cases where we don't actually have to do anything
if (!ptr || len <= 0) {
if ( !ptr || len <= 0 )
{
return 0;
}
@ -349,14 +380,16 @@ ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len)
ntfsLock( file->vd );
// Check that we are allowed to read from this file
if (!file->read) {
if ( !file->read )
{
ntfsUnlock( file->vd );
r->_errno = EACCES;
return -1;
}
// Don't read past the end of file
if (file->pos + len > file->len) {
if ( file->pos + len > file->len )
{
r->_errno = EOVERFLOW;
len = file->len - file->pos;
ntfs_log_trace( "EOVERFLOW" );
@ -365,9 +398,11 @@ ssize_t ntfs_read_r (struct _reent *r, int fd, char *ptr, size_t len)
ntfs_log_trace( "file->pos:%d, len:%d, file->len:%d \n", ( u32 )file->pos, ( u32 )len, ( u32 )file->len );
// Read from the files data attribute
while (len) {
while ( len )
{
ssize_t ret = ntfs_attr_pread( file->data_na, file->pos, len, ptr );
if (ret <= 0 || ret > len) {
if ( ret <= 0 || ret > len )
{
ntfsUnlock( file->vd );
r->_errno = errno;
return -1;
@ -394,7 +429,8 @@ off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir)
off_t position = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
@ -403,7 +439,8 @@ off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir)
ntfsLock( file->vd );
// Set the files current position
switch(dir) {
switch ( dir )
{
case SEEK_SET: position = file->pos = MIN( MAX( pos, 0 ), file->len ); break;
case SEEK_CUR: position = file->pos = MIN( MAX( file->pos + pos, 0 ), file->len ); break;
case SEEK_END: position = file->pos = MIN( MAX( file->len + pos, 0 ), file->len ); break;
@ -422,7 +459,8 @@ int ntfs_fstat_r (struct _reent *r, int fd, struct stat *st)
int ret = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
@ -446,7 +484,8 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
ntfs_file_state* file = STATE( fd );
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
@ -455,7 +494,8 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
ntfsLock( file->vd );
// Check that we are allowed to write to this file
if (!file->write) {
if ( !file->write )
{
ntfsUnlock( file->vd );
r->_errno = EACCES;
return -1;
@ -464,22 +504,28 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
// For compressed files, only deleting and expanding contents are implemented
if ( file->compressed &&
len > 0 &&
len < file->data_na->initialized_size) {
len < file->data_na->initialized_size )
{
ntfsUnlock( file->vd );
r->_errno = EOPNOTSUPP;
return -1;
}
// Resize the files data attribute, either by expanding or truncating
if (file->compressed && len > file->data_na->initialized_size) {
if ( file->compressed && len > file->data_na->initialized_size )
{
char zero = 0;
if (ntfs_attr_pwrite(file->data_na, len - 1, 1, &zero) <= 0) {
if ( ntfs_attr_pwrite( file->data_na, len - 1, 1, &zero ) <= 0 )
{
ntfsUnlock( file->vd );
r->_errno = errno;
return -1;
}
} else {
if (ntfs_attr_truncate(file->data_na, len)) {
}
else
{
if ( ntfs_attr_truncate( file->data_na, len ) )
{
ntfsUnlock( file->vd );
r->_errno = errno;
return -1;
@ -514,7 +560,8 @@ int ntfs_fsync_r (struct _reent *r, int fd)
int ret = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}

View File

@ -32,7 +32,8 @@
/**
* ntfs_file_state - File state
*/
typedef struct _ntfs_file_state {
typedef struct _ntfs_file_state
{
ntfs_vd *vd; /* Volume this file belongs to */
ntfs_inode *ni; /* File descriptor */
ntfs_attr *data_na; /* File data descriptor */

View File

@ -102,7 +102,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Get the volume descriptor for this path
file->vd = ntfsGetVolume( path );
if (!file->vd) {
if ( !file->vd )
{
r->_errno = ENODEV;
return -1;
}
@ -112,19 +113,26 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Determine which mode the file is opened for
file->flags = flags;
if ((flags & 0x03) == O_RDONLY) {
if ( ( flags & 0x03 ) == O_RDONLY )
{
file->read = true;
file->write = false;
file->append = false;
} else if ((flags & 0x03) == O_WRONLY) {
}
else if ( ( flags & 0x03 ) == O_WRONLY )
{
file->read = false;
file->write = true;
file->append = ( flags & O_APPEND );
} else if ((flags & 0x03) == O_RDWR) {
}
else if ( ( flags & 0x03 ) == O_RDWR )
{
file->read = true;
file->write = true;
file->append = ( flags & O_APPEND );
} else {
}
else
{
r->_errno = EACCES;
ntfsUnlock( file->vd );
return -1;
@ -132,7 +140,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Try and find the file and (if found) ensure that it is not a directory
file->ni = ntfsOpenEntry( file->vd, path );
if (file->ni && (file->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY)) {
if ( file->ni && ( file->ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ) )
{
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
r->_errno = EISDIR;
@ -140,10 +149,12 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Are we creating this file?
if (flags & O_CREAT) {
if ( flags & O_CREAT )
{
// The file SHOULD NOT already exist
if (file->ni) {
if ( file->ni )
{
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
r->_errno = EEXIST;
@ -152,7 +163,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Create the file
file->ni = ntfsCreate( file->vd, path, S_IFREG, NULL );
if (!file->ni) {
if ( !file->ni )
{
ntfsUnlock( file->vd );
return -1;
}
@ -160,7 +172,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Sanity check, the file should be open by now
if (!file->ni) {
if ( !file->ni )
{
ntfsUnlock( file->vd );
r->_errno = ENOENT;
return -1;
@ -168,7 +181,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
// Open the files data attribute
file->data_na = ntfs_attr_open( file->ni, AT_DATA, AT_UNNAMED, 0 );
if(!file->data_na) {
if ( !file->data_na )
{
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
return -1;
@ -179,7 +193,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
file->encrypted = NAttrEncrypted( file->data_na ) || ( file->ni->flags & FILE_ATTR_ENCRYPTED );
// We cannot read/write encrypted files
if (file->encrypted) {
if ( file->encrypted )
{
ntfs_attr_close( file->data_na );
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
@ -188,7 +203,8 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Make sure we aren't trying to write to a read-only file
if ((file->ni->flags & FILE_ATTR_READONLY) && file->write) {
if ( ( file->ni->flags & FILE_ATTR_READONLY ) && file->write )
{
ntfs_attr_close( file->data_na );
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
@ -197,8 +213,10 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Truncate the file if requested
if ((flags & O_TRUNC) && file->write) {
if (ntfs_attr_truncate(file->data_na, 0)) {
if ( ( flags & O_TRUNC ) && file->write )
{
if ( ntfs_attr_truncate( file->data_na, 0 ) )
{
ntfs_attr_close( file->data_na );
ntfsCloseEntry( file->vd, file->ni );
ntfsUnlock( file->vd );
@ -217,10 +235,13 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
ntfsUpdateTimes( file->vd, file->ni, NTFS_UPDATE_ATIME );
// Insert the file into the double-linked FILO list of open files
if (file->vd->firstOpenFile) {
if ( file->vd->firstOpenFile )
{
file->nextOpenFile = file->vd->firstOpenFile;
file->vd->firstOpenFile->prevOpenFile = file;
} else {
}
else
{
file->nextOpenFile = NULL;
}
file->prevOpenFile = NULL;
@ -240,7 +261,8 @@ int ntfs_close_r (struct _reent *r, int fd)
ntfs_file_state* file = STATE( fd );
// Sanity check
if (!file || !file->vd) {
if ( !file || !file->vd )
{
r->_errno = EBADF;
return -1;
}
@ -275,13 +297,15 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
off_t old_pos = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
// Short circuit cases where we don't actually have to do anything
if (!ptr || len <= 0) {
if ( !ptr || len <= 0 )
{
return 0;
}
@ -289,22 +313,26 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
ntfsLock( file->vd );
// Check that we are allowed to write to this file
if (!file->write) {
if ( !file->write )
{
ntfsUnlock( file->vd );
r->_errno = EACCES;
return -1;
}
// If we are in append mode, backup the current position and move to the end of the file
if (file->append) {
if ( file->append )
{
old_pos = file->pos;
file->pos = file->len;
}
// Write to the files data atrribute
while (len) {
while ( len )
{
ssize_t ret = ntfs_attr_pwrite( file->data_na, file->pos, len, ptr );
if (ret <= 0) {
if ( ret <= 0 )
{
ntfsUnlock( file->vd );
r->_errno = errno;
return -1;
@ -315,7 +343,8 @@ ssize_t ntfs_write_r (struct _reent *r, int fd, const char *ptr, size_t len)
}
// If we are in append mode, restore the current position to were it was prior to this write
if (file->append) {
if ( file->append )
{
file->pos = old_pos;
}
@ -355,7 +384,8 @@ int _NTFS_get_fragments (const char *path,
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
//r->_errno = EINVAL;
return -13;
}
@ -389,10 +419,12 @@ int _NTFS_get_fragments (const char *path,
u64 len = file->len;
// Read from the files data attribute
while (len) {
while ( len )
{
s64 ret = ntfs_attr_getfragments( file->data_na, file->pos,
len, offset, append_fragment, callback_data );
if (ret <= 0 || ret > len) {
if ( ret <= 0 || ret > len )
{
ntfsUnlock( file->vd );
//r->_errno = errno;
ret_val = -14;
@ -436,7 +468,8 @@ off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir)
off_t position = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
@ -445,7 +478,8 @@ off_t ntfs_seek_r (struct _reent *r, int fd, off_t pos, int dir)
ntfsLock( file->vd );
// Set the files current position
switch(dir) {
switch ( dir )
{
case SEEK_SET: position = file->pos = MIN( MAX( pos, 0 ), file->len ); break;
case SEEK_CUR: position = file->pos = MIN( MAX( file->pos + pos, 0 ), file->len ); break;
case SEEK_END: position = file->pos = MIN( MAX( file->len + pos, 0 ), file->len ); break;
@ -464,7 +498,8 @@ int ntfs_fstat_r (struct _reent *r, int fd, struct stat *st)
int ret = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
@ -488,7 +523,8 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
ntfs_file_state* file = STATE( fd );
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}
@ -497,7 +533,8 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
ntfsLock( file->vd );
// Check that we are allowed to write to this file
if (!file->write) {
if ( !file->write )
{
ntfsUnlock( file->vd );
r->_errno = EACCES;
return -1;
@ -506,22 +543,28 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
// For compressed files, only deleting and expanding contents are implemented
if ( file->compressed &&
len > 0 &&
len < file->data_na->initialized_size) {
len < file->data_na->initialized_size )
{
ntfsUnlock( file->vd );
r->_errno = EOPNOTSUPP;
return -1;
}
// Resize the files data attribute, either by expanding or truncating
if (file->compressed && len > file->data_na->initialized_size) {
if ( file->compressed && len > file->data_na->initialized_size )
{
char zero = 0;
if (ntfs_attr_pwrite(file->data_na, len - 1, 1, &zero) <= 0) {
if ( ntfs_attr_pwrite( file->data_na, len - 1, 1, &zero ) <= 0 )
{
ntfsUnlock( file->vd );
r->_errno = errno;
return -1;
}
} else {
if (ntfs_attr_truncate(file->data_na, len)) {
}
else
{
if ( ntfs_attr_truncate( file->data_na, len ) )
{
ntfsUnlock( file->vd );
r->_errno = errno;
return -1;
@ -556,7 +599,8 @@ int ntfs_fsync_r (struct _reent *r, int fd)
int ret = 0;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na) {
if ( !file || !file->vd || !file->ni || !file->data_na )
{
r->_errno = EINVAL;
return -1;
}

View File

@ -43,7 +43,8 @@
#include <sdcard/gcsd.h>
#include <ogc/usbstorage.h>
const INTERFACE_ID ntfs_disc_interfaces[] = {
const INTERFACE_ID ntfs_disc_interfaces[] =
{
{ "sd", &__io_wiisd },
{ "usb", &__io_usbstorage },
{ "carda", &__io_gcsda },
@ -54,7 +55,8 @@ const INTERFACE_ID ntfs_disc_interfaces[] = {
#elif defined(__gamecube__)
#include <sdcard/gcsd.h>
const INTERFACE_ID ntfs_disc_interfaces[] = {
const INTERFACE_ID ntfs_disc_interfaces[] =
{
{ "carda", &__io_gcsda },
{ "cardb", &__io_gcsdb },
{ NULL, NULL }
@ -70,14 +72,16 @@ int ntfsAddDevice (const char *name, void *deviceData)
int i;
// Sanity check
if (!name || !deviceData || !devoptab_ntfs) {
if ( !name || !deviceData || !devoptab_ntfs )
{
errno = EINVAL;
return -1;
}
// Allocate a devoptab for this device
dev = ( devoptab_t * ) ntfs_alloc( sizeof( devoptab_t ) + strlen( name ) + 1 );
if (!dev) {
if ( !dev )
{
errno = ENOMEM;
return false;
}
@ -92,8 +96,10 @@ int ntfsAddDevice (const char *name, void *deviceData)
dev->deviceData = deviceData;
// Add the device to the devoptab table (if there is a free slot)
for (i = 0; i < STD_MAX; i++) {
if (devoptab_list[i] == devoptab_list[0] && i != 0) {
for ( i = 0; i < STD_MAX; i++ )
{
if ( devoptab_list[i] == devoptab_list[0] && i != 0 )
{
devoptab_list[i] = dev;
return 0;
}
@ -118,10 +124,13 @@ void ntfsRemoveDevice (const char *path)
// NOTE: We do this manually due to a 'bug' in RemoveDevice
// which ignores names with suffixes and causes names
// like "ntfs" and "ntfs1" to be seen as equals
for (i = 0; i < STD_MAX; i++) {
for ( i = 0; i < STD_MAX; i++ )
{
devoptab = devoptab_list[i];
if (devoptab && devoptab->name) {
if (strcmp(name, devoptab->name) == 0) {
if ( devoptab && devoptab->name )
{
if ( strcmp( name, devoptab->name ) == 0 )
{
devoptab_list[i] = devoptab_list[0];
ntfs_free( ( devoptab_t* )devoptab );
break;
@ -146,10 +155,13 @@ const devoptab_t *ntfsGetDevice (const char *path, bool useDefaultDevice)
// NOTE: We do this manually due to a 'bug' in GetDeviceOpTab
// which ignores names with suffixes and causes names
// like "ntfs" and "ntfs1" to be seen as equals
for (i = 0; i < STD_MAX; i++) {
for ( i = 0; i < STD_MAX; i++ )
{
devoptab = devoptab_list[i];
if (devoptab && devoptab->name) {
if (strcmp(name, devoptab->name) == 0) {
if ( devoptab && devoptab->name )
{
if ( strcmp( name, devoptab->name ) == 0 )
{
return devoptab;
}
}
@ -184,7 +196,8 @@ ntfs_vd *ntfsGetVolume (const char *path)
int ntfsInitVolume ( ntfs_vd *vd )
{
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return -1;
}
@ -210,7 +223,8 @@ int ntfsInitVolume (ntfs_vd *vd)
void ntfsDeinitVolume ( ntfs_vd *vd )
{
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return;
}
@ -220,7 +234,8 @@ void ntfsDeinitVolume (ntfs_vd *vd)
// Close any directories which are still open (lazy programmers!)
ntfs_dir_state *nextDir = vd->firstOpenDir;
while (nextDir) {
while ( nextDir )
{
ntfs_log_warning( "Cleaning up orphaned directory @ %p\n", nextDir );
ntfsCloseDir( nextDir );
nextDir = nextDir->nextOpenDir;
@ -228,7 +243,8 @@ void ntfsDeinitVolume (ntfs_vd *vd)
// Close any files which are still open (lazy programmers!)
ntfs_file_state *nextFile = vd->firstOpenFile;
while (nextFile) {
while ( nextFile )
{
ntfs_log_warning( "Cleaning up orphaned file @ %p\n", nextFile );
ntfsCloseFile( nextFile );
nextFile = nextFile->nextOpenFile;
@ -270,17 +286,21 @@ ntfs_inode *ntfsParseEntry (ntfs_vd *vd, const char *path, int reparseLevel)
int attr_size;
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return NULL;
}
// Get the actual path of the entry
path = ntfsRealPath( path );
if (!path) {
if ( !path )
{
errno = EINVAL;
return NULL;
} else if (path[0] == '\0') {
}
else if ( path[0] == '\0' )
{
path = ".";
}
@ -292,11 +312,14 @@ ntfs_inode *ntfsParseEntry (ntfs_vd *vd, const char *path, int reparseLevel)
// If the entry was found and it has reparse data then parse its true path;
// this resolves the true location of symbolic links and directory junctions
if (ni && (ni->flags & FILE_ATTR_REPARSE_POINT)) {
if (ntfs_possible_symlink(ni)) {
if ( ni && ( ni->flags & FILE_ATTR_REPARSE_POINT ) )
{
if ( ntfs_possible_symlink( ni ) )
{
// Sanity check, give up if we are parsing to deep
if (reparseLevel > NTFS_MAX_SYMLINK_DEPTH) {
if ( reparseLevel > NTFS_MAX_SYMLINK_DEPTH )
{
ntfsCloseEntry( vd, ni );
errno = ELOOP;
return NULL;
@ -304,7 +327,8 @@ ntfs_inode *ntfsParseEntry (ntfs_vd *vd, const char *path, int reparseLevel)
// Get the target path of this entry
target = ntfs_make_symlink( ni, path, &attr_size );
if (!target) {
if ( !target )
{
ntfsCloseEntry( vd, ni );
return NULL;
}
@ -327,7 +351,8 @@ ntfs_inode *ntfsParseEntry (ntfs_vd *vd, const char *path, int reparseLevel)
void ntfsCloseEntry ( ntfs_vd *vd, ntfs_inode *ni )
{
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return;
}
@ -358,14 +383,17 @@ ntfs_inode *ntfsCreate (ntfs_vd *vd, const char *path, mode_t type, const char *
int uname_len, utarget_len;
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return NULL;
}
// You cannot link between devices
if(target) {
if(vd != ntfsGetVolume(target)) {
if ( target )
{
if ( vd != ntfsGetVolume( target ) )
{
errno = EXDEV;
return NULL;
}
@ -374,7 +402,8 @@ ntfs_inode *ntfsCreate (ntfs_vd *vd, const char *path, mode_t type, const char *
// Get the actual paths of the entry
path = ntfsRealPath( path );
target = ntfsRealPath( target );
if (!path) {
if ( !path )
{
errno = EINVAL;
return NULL;
}
@ -385,7 +414,8 @@ ntfs_inode *ntfsCreate (ntfs_vd *vd, const char *path, mode_t type, const char *
// Get the unicode name for the entry and find its parent directory
// TODO: This looks horrible, clean it up
dir = strdup( path );
if (!dir) {
if ( !dir )
{
errno = EINVAL;
goto cleanup;
}
@ -395,7 +425,8 @@ ntfs_inode *ntfsCreate (ntfs_vd *vd, const char *path, mode_t type, const char *
else
name = dir;
uname_len = ntfsLocalToUnicode( name, &uname );
if (uname_len < 0) {
if ( uname_len < 0 )
{
errno = EINVAL;
goto cleanup;
}
@ -408,21 +439,25 @@ ntfs_inode *ntfsCreate (ntfs_vd *vd, const char *path, mode_t type, const char *
// Open the entries parent directory
dir_ni = ntfsOpenEntry( vd, dir );
if (!dir_ni) {
if ( !dir_ni )
{
goto cleanup;
}
// Create the entry
switch (type) {
switch ( type )
{
// Symbolic link
case S_IFLNK:
if (!target) {
if ( !target )
{
errno = EINVAL;
goto cleanup;
}
utarget_len = ntfsLocalToUnicode( target, &utarget );
if (utarget_len < 0) {
if ( utarget_len < 0 )
{
errno = EINVAL;
goto cleanup;
}
@ -438,7 +473,8 @@ ntfs_inode *ntfsCreate (ntfs_vd *vd, const char *path, mode_t type, const char *
}
// If the entry was created
if (ni) {
if ( ni )
{
// Mark the entry for archiving
ni->flags |= FILE_ATTR_ARCHIVE;
@ -484,13 +520,15 @@ int ntfsLink (ntfs_vd *vd, const char *old_path, const char *new_path)
int res = 0;
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return -1;
}
// You cannot link between devices
if(vd != ntfsGetVolume(new_path)) {
if ( vd != ntfsGetVolume( new_path ) )
{
errno = EXDEV;
return -1;
}
@ -498,7 +536,8 @@ int ntfsLink (ntfs_vd *vd, const char *old_path, const char *new_path)
// Get the actual paths of the entry
old_path = ntfsRealPath( old_path );
new_path = ntfsRealPath( new_path );
if (!old_path || !new_path) {
if ( !old_path || !new_path )
{
errno = EINVAL;
return -1;
}
@ -509,7 +548,8 @@ int ntfsLink (ntfs_vd *vd, const char *old_path, const char *new_path)
// Get the unicode name for the entry and find its parent directory
// TODO: This looks horrible, clean it up
dir = strdup( new_path );
if (!dir) {
if ( !dir )
{
errno = EINVAL;
goto cleanup;
}
@ -519,7 +559,8 @@ int ntfsLink (ntfs_vd *vd, const char *old_path, const char *new_path)
else
name = dir;
uname_len = ntfsLocalToUnicode( name, &uname );
if (uname_len < 0) {
if ( uname_len < 0 )
{
errno = EINVAL;
goto cleanup;
}
@ -527,7 +568,8 @@ int ntfsLink (ntfs_vd *vd, const char *old_path, const char *new_path)
// Find the entry
ni = ntfsOpenEntry( vd, old_path );
if (!ni) {
if ( !ni )
{
errno = ENOENT;
res = -1;
goto cleanup;
@ -535,14 +577,16 @@ int ntfsLink (ntfs_vd *vd, const char *old_path, const char *new_path)
// Open the entries new parent directory
dir_ni = ntfsOpenEntry( vd, dir );
if (!dir_ni) {
if ( !dir_ni )
{
errno = ENOENT;
res = -1;
goto cleanup;
}
// Link the entry to its new parent
if (ntfs_link(ni, dir_ni, uname, uname_len)) {
if ( ntfs_link( ni, dir_ni, uname, uname_len ) )
{
res = -1;
goto cleanup;
}
@ -583,14 +627,16 @@ int ntfsUnlink (ntfs_vd *vd, const char *path)
int res = 0;
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return -1;
}
// Get the actual path of the entry
path = ntfsRealPath( path );
if (!path) {
if ( !path )
{
errno = EINVAL;
return -1;
}
@ -601,7 +647,8 @@ int ntfsUnlink (ntfs_vd *vd, const char *path)
// Get the unicode name for the entry and find its parent directory
// TODO: This looks horrible
dir = strdup( path );
if (!dir) {
if ( !dir )
{
errno = EINVAL;
goto cleanup;
}
@ -611,7 +658,8 @@ int ntfsUnlink (ntfs_vd *vd, const char *path)
else
name = dir;
uname_len = ntfsLocalToUnicode( name, &uname );
if (uname_len < 0) {
if ( uname_len < 0 )
{
errno = EINVAL;
goto cleanup;
}
@ -624,7 +672,8 @@ int ntfsUnlink (ntfs_vd *vd, const char *path)
// Find the entry
ni = ntfsOpenEntry( vd, path );
if (!ni) {
if ( !ni )
{
errno = ENOENT;
res = -1;
goto cleanup;
@ -632,14 +681,16 @@ int ntfsUnlink (ntfs_vd *vd, const char *path)
// Open the entries parent directory
dir_ni = ntfsOpenEntry( vd, dir );
if (!dir_ni) {
if ( !dir_ni )
{
errno = ENOENT;
res = -1;
goto cleanup;
}
// Unlink the entry from its parent
if (ntfs_delete(vd->vol, path, ni, dir_ni, uname, uname_len)) {
if ( ntfs_delete( vd->vol, path, ni, dir_ni, uname, uname_len ) )
{
res = -1;
}
@ -674,13 +725,15 @@ int ntfsSync (ntfs_vd *vd, ntfs_inode *ni)
int res = 0;
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return -1;
}
// Sanity check
if (!ni) {
if ( !ni )
{
errno = ENOENT;
return -1;
}
@ -707,13 +760,15 @@ int ntfsStat (ntfs_vd *vd, ntfs_inode *ni, struct stat *st)
int res = 0;
// Sanity check
if (!vd) {
if ( !vd )
{
errno = ENODEV;
return -1;
}
// Sanity check
if (!ni) {
if ( !ni )
{
errno = ENOENT;
return -1;
}
@ -729,20 +784,24 @@ int ntfsStat (ntfs_vd *vd, ntfs_inode *ni, struct stat *st)
memset( st, 0, sizeof( struct stat ) );
// Is this entry a directory
if (ni->mrec->flags & MFT_RECORD_IS_DIRECTORY) {
if ( ni->mrec->flags & MFT_RECORD_IS_DIRECTORY )
{
st->st_mode = S_IFDIR | ( 0777 & ~vd->dmask );
st->st_nlink = 1;
// Open the directories index allocation table attribute
na = ntfs_attr_open( ni, AT_INDEX_ALLOCATION, NTFS_INDEX_I30, 4 );
if (na) {
if ( na )
{
st->st_size = na->data_size;
st->st_blocks = na->allocated_size >> 9;
ntfs_attr_close( na );
}
// Else it must be a file
} else {
}
else
{
st->st_mode = S_IFREG | ( 0777 & ~vd->fmask );
st->st_size = ni->data_size;
st->st_blocks = ( ni->allocated_size + 511 ) >> 9;
@ -787,10 +846,12 @@ const char *ntfsRealPath (const char *path)
return NULL;
// Move the path pointer to the start of the actual path
if (strchr(path, ':') != NULL) {
if ( strchr( path, ':' ) != NULL )
{
path = strchr( path, ':' ) + 1;
}
if (strchr(path, ':') != NULL) {
if ( strchr( path, ':' ) != NULL )
{
return NULL;
}
@ -808,19 +869,24 @@ int ntfsUnicodeToLocal (const ntfschar *ins, const int ins_len, char **outs, int
// Convert the unicode string to our current local
len = ntfs_ucstombs( ins, ins_len, outs, outs_len );
if (len == -1 && errno == EILSEQ) {
if ( len == -1 && errno == EILSEQ )
{
// The string could not be converted to the current local,
// do it manually by replacing non-ASCII characters with underscores
if (!*outs || outs_len >= ins_len) {
if (!*outs) {
if ( !*outs || outs_len >= ins_len )
{
if ( !*outs )
{
*outs = ( char * ) ntfs_alloc( ins_len + 1 );
if (!*outs) {
if ( !*outs )
{
errno = ENOMEM;
return -1;
}
}
for (i = 0; i < ins_len; i++) {
for ( i = 0; i < ins_len; i++ )
{
ntfschar uc = le16_to_cpu( ins[i] );
if ( uc > 0xff )
uc = ( ntfschar )'_';

View File

@ -69,7 +69,8 @@ struct _ntfs_dir_state;
/**
* PRIMARY_PARTITION - Block device partition record
*/
typedef struct _PARTITION_RECORD {
typedef struct _PARTITION_RECORD
{
u8 status; /* Partition status; see above */
u8 chs_start[3]; /* Cylinder-head-sector address to first block of partition */
u8 type; /* Partition type; see above */
@ -81,7 +82,8 @@ typedef struct _PARTITION_RECORD {
/**
* MASTER_BOOT_RECORD - Block device master boot record
*/
typedef struct _MASTER_BOOT_RECORD {
typedef struct _MASTER_BOOT_RECORD
{
u8 code_area[446]; /* Code area; normally empty */
PARTITION_RECORD partitions[4]; /* 4 primary partitions */
u16 signature; /* MBR signature; 0xAA55 */
@ -90,7 +92,8 @@ typedef struct _MASTER_BOOT_RECORD {
/**
* EXTENDED_PARTITION - Block device extended boot record
*/
typedef struct _EXTENDED_BOOT_RECORD {
typedef struct _EXTENDED_BOOT_RECORD
{
u8 code_area[446]; /* Code area; normally empty */
PARTITION_RECORD partition; /* Primary partition */
PARTITION_RECORD next_ebr; /* Next extended boot record in the chain */
@ -101,7 +104,8 @@ typedef struct _EXTENDED_BOOT_RECORD {
/**
* INTERFACE_ID - Disc interface identifier
*/
typedef struct _INTERFACE_ID {
typedef struct _INTERFACE_ID
{
const char *name; /* Interface name */
const DISC_INTERFACE *interface; /* Disc interface */
} INTERFACE_ID;
@ -109,7 +113,8 @@ typedef struct _INTERFACE_ID {
/**
* ntfs_atime_t - File access time update strategies
*/
typedef enum {
typedef enum
{
ATIME_ENABLED, /* Update access times */
ATIME_DISABLED /* Don't update access times */
} ntfs_atime_t;
@ -117,7 +122,8 @@ typedef enum {
/**
* ntfs_vd - NTFS volume descriptor
*/
typedef struct _ntfs_vd {
typedef struct _ntfs_vd
{
struct ntfs_device *dev; /* NTFS device handle */
ntfs_volume *vol; /* NTFS volume handle */
mutex_t lock; /* Volume lock mutex */

View File

@ -106,25 +106,29 @@
* ---------------------- end from RFC 4122 -----------------------
*/
typedef struct {
typedef struct
{
GUID object_id;
} OBJECT_ID_INDEX_KEY;
typedef struct {
typedef struct
{
le64 file_id;
GUID birth_volume_id;
GUID birth_object_id;
GUID domain_id;
} OBJECT_ID_INDEX_DATA; // known as OBJ_ID_INDEX_DATA
struct OBJECT_ID_INDEX { /* index entry in $Extend/$ObjId */
struct OBJECT_ID_INDEX /* index entry in $Extend/$ObjId */
{
INDEX_ENTRY_HEADER header;
OBJECT_ID_INDEX_KEY key;
OBJECT_ID_INDEX_DATA data;
} ;
static ntfschar objid_index_name[] = { const_cpu_to_le16( '$' ),
const_cpu_to_le16('O') };
const_cpu_to_le16( 'O' )
};
#ifdef HAVE_SETXATTR /* extended attributes interface required */
/*
@ -192,18 +196,22 @@ static ntfs_index_context *open_object_id_index(ntfs_volume *vol)
/* do not use path_name_to inode - could reopen root */
dir_ni = ntfs_inode_open( vol, FILE_Extend );
ni = ( ntfs_inode* )NULL;
if (dir_ni) {
if ( dir_ni )
{
inum = ntfs_inode_lookup_by_mbsname( dir_ni, "$ObjId" );
if ( inum != ( u64 ) - 1 )
ni = ntfs_inode_open( vol, inum );
ntfs_inode_close( dir_ni );
}
if (ni) {
if ( ni )
{
xo = ntfs_index_ctx_get( ni, objid_index_name, 2 );
if (!xo) {
if ( !xo )
{
ntfs_inode_close( ni );
}
} else
}
else
xo = ( ntfs_index_context* )NULL;
return ( xo );
}
@ -230,15 +238,18 @@ static int merge_index_data(ntfs_inode *ni,
res = -1;
xo = open_object_id_index( ni->vol );
if (xo) {
if ( xo )
{
memcpy( &key.object_id, objectid_attr, sizeof( GUID ) );
if ( !ntfs_index_lookup( &key,
sizeof(OBJECT_ID_INDEX_KEY), xo)) {
sizeof( OBJECT_ID_INDEX_KEY ), xo ) )
{
entry = ( struct OBJECT_ID_INDEX* )xo->entry;
/* make sure inode numbers match */
if ( entry
&& ( MREF( le64_to_cpu( entry->data.file_id ) )
== ni->mft_no)) {
== ni->mft_no ) )
{
memcpy( &full_objectid->birth_volume_id,
&entry->data.birth_volume_id,
sizeof( GUID ) );
@ -277,15 +288,18 @@ static int remove_object_id_index(ntfs_attr *na, ntfs_index_context *xo,
int ret;
ret = na->data_size;
if (ret) {
if ( ret )
{
/* read the existing object id attribute */
size = ntfs_attr_pread( na, 0, sizeof( GUID ), old_attr );
if (size >= (s64)sizeof(GUID)) {
if ( size >= ( s64 )sizeof( GUID ) )
{
memcpy( &key.object_id,
&old_attr->object_id, sizeof( GUID ) );
size = sizeof( GUID );
if ( !ntfs_index_lookup( &key,
sizeof(OBJECT_ID_INDEX_KEY), xo)) {
sizeof( OBJECT_ID_INDEX_KEY ), xo ) )
{
entry = ( struct OBJECT_ID_INDEX* )xo->entry;
memcpy( &old_attr->birth_volume_id,
&entry->data.birth_volume_id,
@ -300,7 +314,9 @@ static int remove_object_id_index(ntfs_attr *na, ntfs_index_context *xo,
if ( ntfs_index_rm( xo ) )
ret = -1;
}
} else {
}
else
{
ret = -1;
errno = ENODATA;
}
@ -335,21 +351,25 @@ static int update_object_id(ntfs_inode *ni, ntfs_index_context *xo,
res = 0;
na = ntfs_attr_open( ni, AT_OBJECT_ID, AT_UNNAMED, 0 );
if (na) {
if ( na )
{
/* remove the existing index entry */
oldsize = remove_object_id_index( na, xo, &old_attr );
if ( oldsize < 0 )
res = -1;
else {
else
{
/* resize attribute */
res = ntfs_attr_truncate( na, ( s64 )sizeof( GUID ) );
/* write the object_id in attribute */
if (!res && value) {
if ( !res && value )
{
written = ( int )ntfs_attr_pwrite( na,
( s64 )0, ( s64 )sizeof( GUID ),
&value->object_id );
if (written != (s64)sizeof(GUID)) {
if ( written != ( s64 )sizeof( GUID ) )
{
ntfs_log_error( "Failed to update "
"object id\n" );
errno = EIO;
@ -359,7 +379,8 @@ static int update_object_id(ntfs_inode *ni, ntfs_index_context *xo,
/* write index part if provided */
if ( !res
&& ( ( size < sizeof( OBJECT_ID_ATTR ) )
|| set_object_id_index(ni,xo,value))) {
|| set_object_id_index( ni, xo, value ) ) )
{
/*
* If cannot index, try to remove the object
* id and log the error. There will be an
@ -372,7 +393,8 @@ static int update_object_id(ntfs_inode *ni, ntfs_index_context *xo,
}
ntfs_attr_close( na );
NInoSetDirty( ni );
} else
}
else
res = -1;
return ( res );
}
@ -390,22 +412,29 @@ static int add_object_id(ntfs_inode *ni, int flags)
u8 dummy;
res = -1; /* default return */
if (!ntfs_attr_exist(ni,AT_OBJECT_ID, AT_UNNAMED,0)) {
if (!(flags & XATTR_REPLACE)) {
if ( !ntfs_attr_exist( ni, AT_OBJECT_ID, AT_UNNAMED, 0 ) )
{
if ( !( flags & XATTR_REPLACE ) )
{
/*
* no object id attribute : add one,
* apparently, this does not feed the new value in
* Note : NTFS version must be >= 3
*/
if (ni->vol->major_ver >= 3) {
if ( ni->vol->major_ver >= 3 )
{
res = ntfs_attr_add( ni, AT_OBJECT_ID,
AT_UNNAMED, 0, &dummy, ( s64 )0 );
NInoSetDirty( ni );
} else
}
else
errno = EOPNOTSUPP;
} else
}
else
errno = ENODATA;
} else {
}
else
{
if ( flags & XATTR_CREATE )
errno = EEXIST;
else
@ -433,13 +462,15 @@ int ntfs_delete_object_id_index(ntfs_inode *ni)
res = 0;
na = ntfs_attr_open( ni, AT_OBJECT_ID, AT_UNNAMED, 0 );
if (na) {
if ( na )
{
/*
* read the existing object id
* and un-index it
*/
xo = open_object_id_index( ni->vol );
if (xo) {
if ( xo )
{
if ( remove_object_id_index( na, xo, &old_attr ) < 0 )
res = -1;
xoni = xo->ni;
@ -473,34 +504,42 @@ int ntfs_get_ntfs_object_id(ntfs_inode *ni, char *value, size_t size)
int full_size;
full_size = 0; /* default to no data and some error to be defined */
if (ni) {
if ( ni )
{
objectid_attr = ( OBJECT_ID_ATTR* )ntfs_attr_readall( ni,
AT_OBJECT_ID, ( ntfschar* )NULL, 0, &attr_size );
if (objectid_attr) {
if ( objectid_attr )
{
/* restrict to only GUID present in attr */
if (attr_size == sizeof(GUID)) {
if ( attr_size == sizeof( GUID ) )
{
memcpy( &full_objectid.object_id,
objectid_attr, sizeof( GUID ) );
full_size = sizeof( GUID );
/* get data from index, if any */
if ( !merge_index_data( ni, objectid_attr,
&full_objectid)) {
&full_objectid ) )
{
full_size = sizeof( OBJECT_ID_ATTR );
}
if (full_size <= (s64)size) {
if ( full_size <= ( s64 )size )
{
if ( value )
memcpy( value, &full_objectid,
full_size );
else
errno = EINVAL;
}
} else {
}
else
{
/* unexpected size, better return unsupported */
errno = EOPNOTSUPP;
full_size = 0;
}
free( objectid_attr );
} else
}
else
errno = ENODATA;
}
return ( full_size ? ( int )full_size : -errno );
@ -525,22 +564,28 @@ int ntfs_set_ntfs_object_id(ntfs_inode *ni,
int res;
res = 0;
if (ni && value && (size >= sizeof(GUID))) {
if ( ni && value && ( size >= sizeof( GUID ) ) )
{
xo = open_object_id_index( ni->vol );
if (xo) {
if ( xo )
{
/* make sure the GUID was not used somewhere */
memcpy( &key.object_id, value, sizeof( GUID ) );
if ( ntfs_index_lookup( &key,
sizeof(OBJECT_ID_INDEX_KEY), xo)) {
sizeof( OBJECT_ID_INDEX_KEY ), xo ) )
{
ntfs_index_ctx_reinit( xo );
res = add_object_id( ni, flags );
if (!res) {
if ( !res )
{
/* update value and index */
res = update_object_id( ni, xo,
( const OBJECT_ID_ATTR* )value,
size );
}
} else {
}
else
{
/* GUID is present elsewhere */
res = -1;
errno = EEXIST;
@ -550,10 +595,14 @@ int ntfs_set_ntfs_object_id(ntfs_inode *ni,
NInoSetDirty( xoni );
ntfs_index_ctx_put( xo );
ntfs_inode_close( xoni );
} else {
}
else
{
res = -1;
}
} else {
}
else
{
errno = EINVAL;
res = -1;
}
@ -577,25 +626,32 @@ int ntfs_remove_ntfs_object_id(ntfs_inode *ni)
OBJECT_ID_ATTR old_attr;
res = 0;
if (ni) {
if ( ni )
{
/*
* open and delete the object id
*/
na = ntfs_attr_open( ni, AT_OBJECT_ID,
AT_UNNAMED, 0 );
if (na) {
if ( na )
{
/* first remove index (old object id needed) */
xo = open_object_id_index( ni->vol );
if (xo) {
if ( xo )
{
oldsize = remove_object_id_index( na, xo,
&old_attr );
if (oldsize < 0) {
if ( oldsize < 0 )
{
res = -1;
} else {
}
else
{
/* now remove attribute */
res = ntfs_attr_rm( na );
if ( res
&& (oldsize > (int)sizeof(GUID))) {
&& ( oldsize > ( int )sizeof( GUID ) ) )
{
/*
* If we could not remove the
* attribute, try to restore the
@ -622,12 +678,16 @@ int ntfs_remove_ntfs_object_id(ntfs_inode *ni)
/* avoid errno pollution */
if ( errno == ENOENT )
errno = olderrno;
} else {
}
else
{
errno = ENODATA;
res = -1;
}
NInoSetDirty( ni );
} else {
}
else
{
errno = EINVAL;
res = -1;
}

View File

@ -32,7 +32,8 @@
#define OWNERFROMACL 1 /* Get the owner from ACL (not Windows owner) */
/* default security sub-authorities */
enum {
enum
{
DEFSECAUTH1 = -1153374643, /* 3141592653 */
DEFSECAUTH2 = 589793238,
DEFSECAUTH3 = 462843383,

View File

@ -71,7 +71,8 @@
#define IO_REPARSE_TAG_SIS const_cpu_to_le32(0x80000007)
#define IO_REPARSE_TAG_SYMLINK const_cpu_to_le32(0xA000000C)
struct MOUNT_POINT_REPARSE_DATA { /* reparse data for junctions */
struct MOUNT_POINT_REPARSE_DATA /* reparse data for junctions */
{
le16 subst_name_offset;
le16 subst_name_length;
le16 print_name_offset;
@ -79,7 +80,8 @@ struct MOUNT_POINT_REPARSE_DATA { /* reparse data for junctions */
char path_buffer[0]; /* above data assume this is char array */
} ;
struct SYMLINK_REPARSE_DATA { /* reparse data for symlinks */
struct SYMLINK_REPARSE_DATA /* reparse data for symlinks */
{
le16 subst_name_offset;
le16 subst_name_length;
le16 print_name_offset;
@ -88,20 +90,23 @@ struct SYMLINK_REPARSE_DATA { /* reparse data for symlinks */
char path_buffer[0]; /* above data assume this is char array */
} ;
struct REPARSE_INDEX { /* index entry in $Extend/$Reparse */
struct REPARSE_INDEX /* index entry in $Extend/$Reparse */
{
INDEX_ENTRY_HEADER header;
REPARSE_INDEX_KEY key;
le32 filling;
} ;
static const ntfschar dir_junction_head[] = {
static const ntfschar dir_junction_head[] =
{
const_cpu_to_le16( '\\' ),
const_cpu_to_le16( '?' ),
const_cpu_to_le16( '?' ),
const_cpu_to_le16( '\\' )
} ;
static const ntfschar vol_junction_head[] = {
static const ntfschar vol_junction_head[] =
{
const_cpu_to_le16( '\\' ),
const_cpu_to_le16( '?' ),
const_cpu_to_le16( '?' ),
@ -116,7 +121,8 @@ static const ntfschar vol_junction_head[] = {
} ;
static ntfschar reparse_index_name[] = { const_cpu_to_le16( '$' ),
const_cpu_to_le16('R') };
const_cpu_to_le16( 'R' )
};
static const char mappingdir[] = ".NTFS-3G/";
@ -146,18 +152,21 @@ static u64 ntfs_fix_file_name(ntfs_inode *dir_ni, ntfschar *uname,
u32 cpuchar;
INDEX_ENTRY *entry;
FILE_NAME_ATTR *found;
struct {
struct
{
FILE_NAME_ATTR attr;
ntfschar file_name[NTFS_MAX_NAME_LEN + 1];
} find;
mref = ( u64 ) - 1; /* default return (not found) */
icx = ntfs_index_ctx_get( dir_ni, NTFS_INDEX_I30, 4 );
if (icx) {
if ( icx )
{
if ( uname_len > NTFS_MAX_NAME_LEN )
uname_len = NTFS_MAX_NAME_LEN;
find.attr.file_name_length = uname_len;
for (i=0; i<uname_len; i++) {
for ( i = 0; i < uname_len; i++ )
{
cpuchar = le16_to_cpu( uname[i] );
/*
* We need upper or lower value, whichever is smaller,
@ -184,7 +193,8 @@ static u64 ntfs_fix_file_name(ntfs_inode *dir_ni, ntfschar *uname,
entry = ntfs_index_next( icx->entry, icx );
else
entry = icx->entry;
if (entry) {
if ( entry )
{
found = &entry->key.file_name;
if ( lkup
&& ntfs_names_are_equal( find.attr.file_name,
@ -193,7 +203,8 @@ static u64 ntfs_fix_file_name(ntfs_inode *dir_ni, ntfschar *uname,
IGNORE_CASE,
vol->upcase, vol->upcase_len ) )
lkup = 0;
if (!lkup) {
if ( !lkup )
{
/*
* name found :
* fix original name and return inode
@ -228,9 +239,11 @@ static char *search_absolute(ntfs_volume *vol, ntfschar *path,
target = ( char* )NULL; /* default return */
ni = ntfs_inode_open( vol, ( MFT_REF )FILE_root );
if (ni) {
if ( ni )
{
start = 0;
do {
do
{
len = 0;
while ( ( ( start + len ) < count )
&& ( path[start + len] != const_cpu_to_le16( '\\' ) ) )
@ -238,20 +251,24 @@ static char *search_absolute(ntfs_volume *vol, ntfschar *path,
inum = ntfs_fix_file_name( ni, &path[start], len );
ntfs_inode_close( ni );
ni = ( ntfs_inode* )NULL;
if (inum != (u64)-1) {
if ( inum != ( u64 ) - 1 )
{
inum = MREF( inum );
ni = ntfs_inode_open( vol, inum );
start += len;
if ( start < count )
path[start++] = const_cpu_to_le16( '/' );
}
} while (ni
}
while ( ni
&& ( ni->mrec->flags & MFT_RECORD_IS_DIRECTORY )
&& ( start < count ) );
if ( ni
&& ( ni->mrec->flags & MFT_RECORD_IS_DIRECTORY ? isdir : !isdir ) )
if (ntfs_ucstombs(path, count, &target, 0) < 0) {
if (target) {
if ( ntfs_ucstombs( path, count, &target, 0 ) < 0 )
{
if ( target )
{
free( target );
target = ( char* )NULL;
}
@ -288,17 +305,22 @@ static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
pos = 0;
ok = TRUE;
curni = ntfs_dir_parent_inode( ni );
while (curni && ok && (pos < (count - 1)) && --max) {
while ( curni && ok && ( pos < ( count - 1 ) ) && --max )
{
if ( ( count >= ( pos + 2 ) )
&& ( path[pos] == const_cpu_to_le16( '.' ) )
&& (path[pos+1] == const_cpu_to_le16('\\'))) {
&& ( path[pos+1] == const_cpu_to_le16( '\\' ) ) )
{
path[1] = const_cpu_to_le16( '/' );
pos += 2;
} else {
}
else
{
if ( ( count >= ( pos + 3 ) )
&& ( path[pos] == const_cpu_to_le16( '.' ) )
&& ( path[pos+1] == const_cpu_to_le16( '.' ) )
&& (path[pos+2] == const_cpu_to_le16('\\'))) {
&& ( path[pos+2] == const_cpu_to_le16( '\\' ) ) )
{
path[2] = const_cpu_to_le16( '/' );
pos += 3;
newni = ntfs_dir_parent_inode( curni );
@ -307,7 +329,9 @@ static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
curni = newni;
if ( !curni )
ok = FALSE;
} else {
}
else
{
lth = 0;
while ( ( ( pos + lth ) < count )
&& ( path[pos + lth] != const_cpu_to_le16( '\\' ) ) )
@ -321,15 +345,20 @@ static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
&& ntfs_inode_close( curni ) )
|| ( inum == ( u64 ) - 1 ) )
ok = FALSE;
else {
else
{
curni = ntfs_inode_open( ni->vol, MREF( inum ) );
if ( !curni )
ok = FALSE;
else {
if (ok && ((pos + lth) < count)) {
else
{
if ( ok && ( ( pos + lth ) < count ) )
{
path[pos + lth] = const_cpu_to_le16( '/' );
pos += lth + 1;
} else {
}
else
{
pos += lth;
if ( ( ni->mrec->flags ^ curni->mrec->flags )
& MFT_RECORD_IS_DIRECTORY )
@ -343,7 +372,8 @@ static char *search_relative(ntfs_inode *ni, ntfschar *path, int count)
}
}
if (ok && (ntfs_ucstombs(path, count, &target, 0) < 0)) {
if ( ok && ( ntfs_ucstombs( path, count, &target, 0 ) < 0 ) )
{
free( target ); // needed ?
target = ( char* )NULL;
}
@ -370,7 +400,8 @@ static int ntfs_drive_letter(ntfs_volume *vol, ntfschar letter)
ret = -1;
drive = ( char* )NULL;
sz = ntfs_ucstombs( &letter, 1, &drive, 0 );
if (sz > 0) {
if ( sz > 0 )
{
strcpy( defines, mappingdir );
if ( ( *drive >= 'a' ) && ( *drive <= 'z' ) )
*drive += 'A' - 'a';
@ -380,8 +411,8 @@ static int ntfs_drive_letter(ntfs_volume *vol, ntfschar letter)
ni = ntfs_pathname_to_inode( vol, NULL, defines );
if ( ni && !ntfs_inode_close( ni ) )
ret = 1;
else
if (errno == ENOENT) {
else if ( errno == ENOENT )
{
ret = 0;
/* avoid errno pollution */
errno = olderrno;
@ -415,8 +446,10 @@ static BOOL valid_reparse_data(ntfs_inode *ni,
&& ( size >= sizeof( REPARSE_POINT ) )
&& ( ( ( size_t )le16_to_cpu( reparse_attr->reparse_data_length )
+ sizeof( REPARSE_POINT ) ) == size );
if (ok) {
switch (reparse_attr->reparse_tag) {
if ( ok )
{
switch ( reparse_attr->reparse_tag )
{
case IO_REPARSE_TAG_MOUNT_POINT :
mount_point_data = ( const struct MOUNT_POINT_REPARSE_DATA* )
reparse_attr->reparse_data;
@ -503,12 +536,15 @@ static char *ntfs_get_fulllink(ntfs_volume *vol, ntfschar *junction,
if ( ( kind == DIR_JUNCTION )
&& ( count >= 7 )
&& junction[7]
&& !ntfs_drive_letter(vol, junction[4])) {
&& !ntfs_drive_letter( vol, junction[4] ) )
{
target = search_absolute( vol, &junction[7], count - 7, isdir );
if (target) {
if ( target )
{
fulltarget = ( char* )ntfs_malloc( strlen( mnt_point )
+ strlen( target ) + 2 );
if (fulltarget) {
if ( fulltarget )
{
strcpy( fulltarget, mnt_point );
strcat( fulltarget, "/" );
strcat( fulltarget, target );
@ -523,11 +559,13 @@ static char *ntfs_get_fulllink(ntfs_volume *vol, ntfschar *junction,
* define as a symbolic link to the real target
*/
if ( ( ( kind == DIR_JUNCTION ) && !fulltarget )
|| (kind == VOL_JUNCTION)) {
|| ( kind == VOL_JUNCTION ) )
{
sz = ntfs_ucstombs( &junction[4],
( kind == VOL_JUNCTION ? count - 5 : count - 4 ),
&target, 0 );
if ((sz > 0) && target) {
if ( ( sz > 0 ) && target )
{
/* reverse slashes */
for ( q = target; *q; q++ )
if ( *q == '\\' )
@ -539,7 +577,8 @@ static char *ntfs_get_fulllink(ntfs_volume *vol, ntfschar *junction,
target[0] += 'A' - 'a';
fulltarget = ( char* )ntfs_malloc( strlen( mnt_point )
+ sizeof( mappingdir ) + strlen( target ) + 1 );
if (fulltarget) {
if ( fulltarget )
{
strcpy( fulltarget, mnt_point );
strcat( fulltarget, "/" );
strcat( fulltarget, mappingdir );
@ -605,17 +644,20 @@ static char *ntfs_get_abslink(ntfs_volume *vol, ntfschar *junction,
&& ( count >= 3 )
&& junction[3]
&& !ntfs_drive_letter( vol, junction[0] ) )
|| (kind == ABS_PATH)) {
|| ( kind == ABS_PATH ) )
{
if ( kind == ABS_PATH )
target = search_absolute( vol, &junction[1],
count - 1, isdir );
else
target = search_absolute( vol, &junction[3],
count - 3, isdir );
if (target) {
if ( target )
{
fulltarget = ( char* )ntfs_malloc( strlen( mnt_point )
+ strlen( target ) + 2 );
if (fulltarget) {
if ( fulltarget )
{
strcpy( fulltarget, mnt_point );
strcat( fulltarget, "/" );
strcat( fulltarget, target );
@ -628,10 +670,12 @@ static char *ntfs_get_abslink(ntfs_volume *vol, ntfschar *junction,
* link to /.NTFS-3G/target which the user can
* define as a symbolic link to the real target
*/
if ((kind == FULL_PATH) && !fulltarget) {
if ( ( kind == FULL_PATH ) && !fulltarget )
{
sz = ntfs_ucstombs( &junction[0],
count, &target, 0 );
if ((sz > 0) && target) {
if ( ( sz > 0 ) && target )
{
/* reverse slashes */
for ( q = target; *q; q++ )
if ( *q == '\\' )
@ -643,7 +687,8 @@ static char *ntfs_get_abslink(ntfs_volume *vol, ntfschar *junction,
target[0] += 'A' - 'a';
fulltarget = ( char* )ntfs_malloc( strlen( mnt_point )
+ sizeof( mappingdir ) + strlen( target ) + 1 );
if (fulltarget) {
if ( fulltarget )
{
strcpy( fulltarget, mnt_point );
strcat( fulltarget, "/" );
strcat( fulltarget, mappingdir );
@ -710,8 +755,10 @@ char *ntfs_make_symlink(ntfs_inode *ni, const char *mnt_point,
reparse_attr = ( REPARSE_POINT* )ntfs_attr_readall( ni,
AT_REPARSE_POINT, ( ntfschar* )NULL, 0, &attr_size );
if ( reparse_attr && attr_size
&& valid_reparse_data(ni, reparse_attr, attr_size)) {
switch (reparse_attr->reparse_tag) {
&& valid_reparse_data( ni, reparse_attr, attr_size ) )
{
switch ( reparse_attr->reparse_tag )
{
case IO_REPARSE_TAG_MOUNT_POINT :
mount_point_data = ( struct MOUNT_POINT_REPARSE_DATA* )
reparse_attr->reparse_data;
@ -734,23 +781,26 @@ char *ntfs_make_symlink(ntfs_inode *ni, const char *mnt_point,
* Predetermine the kind of target,
* the called function has to make a full check
*/
if (*p++ == const_cpu_to_le16('\\')) {
if ( *p++ == const_cpu_to_le16( '\\' ) )
{
if ( ( *p == const_cpu_to_le16( '?' ) )
|| ( *p == const_cpu_to_le16( '\\' ) ) )
kind = FULL_TARGET;
else
kind = ABS_TARGET;
} else
if (*p == const_cpu_to_le16(':'))
}
else if ( *p == const_cpu_to_le16( ':' ) )
kind = ABS_TARGET;
else
kind = REL_TARGET;
p--;
/* reparse data consistency has been checked */
switch (kind) {
switch ( kind )
{
case FULL_TARGET :
if ( !( symlink_data->flags
& const_cpu_to_le32(1))) {
& const_cpu_to_le32( 1 ) ) )
{
target = ntfs_get_fulllink( vol,
p, lth / 2,
mnt_point, isdir );
@ -760,7 +810,8 @@ char *ntfs_make_symlink(ntfs_inode *ni, const char *mnt_point,
break;
case ABS_TARGET :
if ( symlink_data->flags
& const_cpu_to_le32(1)) {
& const_cpu_to_le32( 1 ) )
{
target = ntfs_get_abslink( vol,
p, lth / 2,
mnt_point, isdir );
@ -770,7 +821,8 @@ char *ntfs_make_symlink(ntfs_inode *ni, const char *mnt_point,
break;
case REL_TARGET :
if ( symlink_data->flags
& const_cpu_to_le32(1)) {
& const_cpu_to_le32( 1 ) )
{
target = ntfs_get_rellink( ni,
p, lth / 2 );
if ( target )
@ -805,8 +857,10 @@ BOOL ntfs_possible_symlink(ntfs_inode *ni)
possible = FALSE;
reparse_attr = ( REPARSE_POINT* )ntfs_attr_readall( ni,
AT_REPARSE_POINT, ( ntfschar* )NULL, 0, &attr_size );
if (reparse_attr && attr_size) {
switch (reparse_attr->reparse_tag) {
if ( reparse_attr && attr_size )
{
switch ( reparse_attr->reparse_tag )
{
case IO_REPARSE_TAG_MOUNT_POINT :
case IO_REPARSE_TAG_SYMLINK :
possible = TRUE;
@ -877,10 +931,12 @@ static int remove_reparse_index(ntfs_attr *na, ntfs_index_context *xr,
int ret;
ret = na->data_size;
if (ret) {
if ( ret )
{
/* read the existing reparse_tag */
size = ntfs_attr_pread( na, 0, 4, preparse_tag );
if (size == 4) {
if ( size == 4 )
{
seqn = na->ni->mrec->sequence_number;
file_id_cpu = MK_MREF( na->ni->mft_no, le16_to_cpu( seqn ) );
file_id = cpu_to_le64( file_id_cpu );
@ -890,7 +946,9 @@ static int remove_reparse_index(ntfs_attr *na, ntfs_index_context *xr,
if ( !ntfs_index_lookup( &key, sizeof( REPARSE_INDEX_KEY ), xr )
&& ntfs_index_rm( xr ) )
ret = -1;
} else {
}
else
{
ret = -1;
errno = ENODATA;
}
@ -917,18 +975,22 @@ static ntfs_index_context *open_reparse_index(ntfs_volume *vol)
/* do not use path_name_to inode - could reopen root */
dir_ni = ntfs_inode_open( vol, FILE_Extend );
ni = ( ntfs_inode* )NULL;
if (dir_ni) {
if ( dir_ni )
{
inum = ntfs_inode_lookup_by_mbsname( dir_ni, "$Reparse" );
if ( inum != ( u64 ) - 1 )
ni = ntfs_inode_open( vol, inum );
ntfs_inode_close( dir_ni );
}
if (ni) {
if ( ni )
{
xr = ntfs_index_ctx_get( ni, reparse_index_name, 2 );
if (!xr) {
if ( !xr )
{
ntfs_inode_close( ni );
}
} else
}
else
xr = ( ntfs_index_context* )NULL;
return ( xr );
}
@ -959,19 +1021,23 @@ static int update_reparse_data(ntfs_inode *ni, ntfs_index_context *xr,
res = 0;
na = ntfs_attr_open( ni, AT_REPARSE_POINT, AT_UNNAMED, 0 );
if (na) {
if ( na )
{
/* remove the existing reparse data */
oldsize = remove_reparse_index( na, xr, &reparse_tag );
if ( oldsize < 0 )
res = -1;
else {
else
{
/* resize attribute */
res = ntfs_attr_truncate( na, ( s64 )size );
/* overwrite value if any */
if (!res && value) {
if ( !res && value )
{
written = ( int )ntfs_attr_pwrite( na,
( s64 )0, ( s64 )size, value );
if (written != (s64)size) {
if ( written != ( s64 )size )
{
ntfs_log_error( "Failed to update "
"reparse data\n" );
errno = EIO;
@ -981,7 +1047,8 @@ static int update_reparse_data(ntfs_inode *ni, ntfs_index_context *xr,
if ( !res
&& set_reparse_index( ni, xr,
( ( const REPARSE_POINT* )value )->reparse_tag )
&& (oldsize > 0)) {
&& ( oldsize > 0 ) )
{
/*
* If cannot index, try to remove the reparse
* data and log the error. There will be an
@ -994,7 +1061,8 @@ static int update_reparse_data(ntfs_inode *ni, ntfs_index_context *xr,
}
ntfs_attr_close( na );
NInoSetDirty( ni );
} else
}
else
res = -1;
return ( res );
}
@ -1018,13 +1086,15 @@ int ntfs_delete_reparse_index(ntfs_inode *ni)
res = 0;
na = ntfs_attr_open( ni, AT_REPARSE_POINT, AT_UNNAMED, 0 );
if (na) {
if ( na )
{
/*
* read the existing reparse data (the tag is enough)
* and un-index it
*/
xr = open_reparse_index( ni->vol );
if (xr) {
if ( xr )
{
if ( remove_reparse_index( na, xr, &reparse_tag ) < 0 )
res = -1;
xrni = xr->ni;
@ -1053,12 +1123,16 @@ int ntfs_get_ntfs_reparse_data(ntfs_inode *ni, char *value, size_t size)
s64 attr_size;
attr_size = 0; /* default to no data and no error */
if (ni) {
if (ni->flags & FILE_ATTR_REPARSE_POINT) {
if ( ni )
{
if ( ni->flags & FILE_ATTR_REPARSE_POINT )
{
reparse_attr = ( REPARSE_POINT* )ntfs_attr_readall( ni,
AT_REPARSE_POINT, ( ntfschar* )NULL, 0, &attr_size );
if (reparse_attr) {
if (attr_size <= (s64)size) {
if ( reparse_attr )
{
if ( attr_size <= ( s64 )size )
{
if ( value )
memcpy( value, reparse_attr,
attr_size );
@ -1067,7 +1141,8 @@ int ntfs_get_ntfs_reparse_data(ntfs_inode *ni, char *value, size_t size)
}
free( reparse_attr );
}
} else
}
else
errno = ENODATA;
}
return ( attr_size ? ( int )attr_size : -errno );
@ -1090,43 +1165,57 @@ int ntfs_set_ntfs_reparse_data(ntfs_inode *ni,
ntfs_index_context *xr;
res = 0;
if (ni && valid_reparse_data(ni, (const REPARSE_POINT*)value, size)) {
if ( ni && valid_reparse_data( ni, ( const REPARSE_POINT* )value, size ) )
{
xr = open_reparse_index( ni->vol );
if (xr) {
if ( xr )
{
if ( !ntfs_attr_exist( ni, AT_REPARSE_POINT,
AT_UNNAMED,0)) {
if (!(flags & XATTR_REPLACE)) {
AT_UNNAMED, 0 ) )
{
if ( !( flags & XATTR_REPLACE ) )
{
/*
* no reparse data attribute : add one,
* apparently, this does not feed the new value in
* Note : NTFS version must be >= 3
*/
if (ni->vol->major_ver >= 3) {
if ( ni->vol->major_ver >= 3 )
{
res = ntfs_attr_add( ni,
AT_REPARSE_POINT,
AT_UNNAMED, 0, &dummy,
( s64 )0 );
if (!res) {
if ( !res )
{
ni->flags |=
FILE_ATTR_REPARSE_POINT;
NInoFileNameSetDirty( ni );
}
NInoSetDirty( ni );
} else {
}
else
{
errno = EOPNOTSUPP;
res = -1;
}
} else {
}
else
{
errno = ENODATA;
res = -1;
}
} else {
if (flags & XATTR_CREATE) {
}
else
{
if ( flags & XATTR_CREATE )
{
errno = EEXIST;
res = -1;
}
}
if (!res) {
if ( !res )
{
/* update value and index */
res = update_reparse_data( ni, xr, value, size );
}
@ -1135,10 +1224,14 @@ int ntfs_set_ntfs_reparse_data(ntfs_inode *ni,
NInoSetDirty( xrni );
ntfs_index_ctx_put( xr );
ntfs_inode_close( xrni );
} else {
}
else
{
res = -1;
}
} else {
}
else
{
errno = EINVAL;
res = -1;
}
@ -1161,27 +1254,36 @@ int ntfs_remove_ntfs_reparse_data(ntfs_inode *ni)
le32 reparse_tag;
res = 0;
if (ni) {
if ( ni )
{
/*
* open and delete the reparse data
*/
na = ntfs_attr_open( ni, AT_REPARSE_POINT,
AT_UNNAMED, 0 );
if (na) {
if ( na )
{
/* first remove index (reparse data needed) */
xr = open_reparse_index( ni->vol );
if (xr) {
if ( xr )
{
if ( remove_reparse_index( na, xr,
&reparse_tag) < 0) {
&reparse_tag ) < 0 )
{
res = -1;
} else {
}
else
{
/* now remove attribute */
res = ntfs_attr_rm( na );
if (!res) {
if ( !res )
{
ni->flags &=
~FILE_ATTR_REPARSE_POINT;
NInoFileNameSetDirty( ni );
} else {
}
else
{
/*
* If we could not remove the
* attribute, try to restore the
@ -1207,12 +1309,16 @@ int ntfs_remove_ntfs_reparse_data(ntfs_inode *ni)
/* avoid errno pollution */
if ( errno == ENOENT )
errno = olderrno;
} else {
}
else
{
errno = ENODATA;
res = -1;
}
NInoSetDirty( ni );
} else {
}
else
{
errno = EINVAL;
res = -1;
}

View File

@ -127,19 +127,24 @@ runlist_element *ntfs_rl_extend(ntfs_attr *na, runlist_element *rl,
int last;
int irl;
if (na->rl && rl) {
if ( na->rl && rl )
{
irl = ( int )( rl - na->rl );
last = irl;
while ( na->rl[last].length )
last++;
newrl = ntfs_rl_realloc( na->rl, last + 1, last + more_entries + 1 );
if (!newrl) {
if ( !newrl )
{
errno = ENOMEM;
rl = ( runlist_element* )NULL;
} else
}
else
na->rl = newrl;
rl = &newrl[irl];
} else {
}
else
{
ntfs_log_error( "Cannot extend unmapped runlist" );
errno = EIO;
rl = ( runlist_element* )NULL;
@ -160,7 +165,8 @@ runlist_element *ntfs_rl_extend(ntfs_attr *na, runlist_element *rl,
*/
static BOOL ntfs_rl_are_mergeable( runlist_element *dst, runlist_element *src )
{
if (!dst || !src) {
if ( !dst || !src )
{
ntfs_log_debug( "Eeek. ntfs_rl_are_mergeable() invoked with NULL "
"pointer!\n" );
return FALSE;
@ -223,7 +229,8 @@ static runlist_element *ntfs_rl_append(runlist_element *dst, int dsize,
BOOL right = FALSE; /* Right end of @src needs merging */
int marker; /* End of the inserted runs */
if (!dst || !src) {
if ( !dst || !src )
{
ntfs_log_debug( "Eeek. ntfs_rl_append() invoked with NULL "
"pointer!\n" );
errno = EINVAL;
@ -291,7 +298,8 @@ static runlist_element *ntfs_rl_insert(runlist_element *dst, int dsize,
BOOL disc = FALSE; /* Discontinuity between @dst and @src */
int marker; /* End of the inserted runs */
if (!dst || !src) {
if ( !dst || !src )
{
ntfs_log_debug( "Eeek. ntfs_rl_insert() invoked with NULL "
"pointer!\n" );
errno = EINVAL;
@ -303,7 +311,8 @@ static runlist_element *ntfs_rl_insert(runlist_element *dst, int dsize,
*/
if ( loc == 0 )
disc = ( src[0].vcn > 0 );
else {
else
{
s64 merged_length;
left = ntfs_rl_are_mergeable( dst + loc - 1, src );
@ -348,11 +357,15 @@ static runlist_element *ntfs_rl_insert(runlist_element *dst, int dsize,
dst[marker].length = dst[marker + 1].vcn - dst[marker].vcn;
/* Writing beyond the end of the file and there's a discontinuity. */
if (disc) {
if (loc > 0) {
if ( disc )
{
if ( loc > 0 )
{
dst[loc].vcn = dst[loc - 1].vcn + dst[loc - 1].length;
dst[loc].length = dst[loc + 1].vcn - dst[loc].vcn;
} else {
}
else
{
dst[loc].vcn = 0;
dst[loc].length = dst[loc + 1].vcn;
}
@ -390,7 +403,8 @@ static runlist_element *ntfs_rl_replace(runlist_element *dst, int dsize,
int tail; /* Start of tail of @dst */
int marker; /* End of the inserted runs */
if (!dst || !src) {
if ( !dst || !src )
{
ntfs_log_debug( "Eeek. ntfs_rl_replace() invoked with NULL "
"pointer!\n" );
errno = EINVAL;
@ -407,7 +421,8 @@ static runlist_element *ntfs_rl_replace(runlist_element *dst, int dsize,
* ends get merged. The -1 accounts for the run being replaced.
*/
delta = ssize - 1 - left - right;
if (delta > 0) {
if ( delta > 0 )
{
dst = ntfs_rl_realloc( dst, dsize, dsize + delta );
if ( !dst )
return NULL;
@ -471,7 +486,8 @@ static runlist_element *ntfs_rl_replace(runlist_element *dst, int dsize,
static runlist_element *ntfs_rl_split( runlist_element *dst, int dsize,
runlist_element *src, int ssize, int loc )
{
if (!dst || !src) {
if ( !dst || !src )
{
ntfs_log_debug( "Eeek. ntfs_rl_split() invoked with NULL pointer!\n" );
errno = EINVAL;
return NULL;
@ -524,10 +540,12 @@ static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
return drl;
/* Check for the case where the first mapping is being done now. */
if (!drl) {
if ( !drl )
{
drl = srl;
/* Complete the source runlist if necessary. */
if (drl[0].vcn) {
if ( drl[0].vcn )
{
/* Scan to the end of the source runlist. */
for ( dend = 0; drl[dend].length; dend++ )
;
@ -551,7 +569,8 @@ static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
si++;
/* Can't have an entirely unmapped source runlist. */
if (!srl[si].length) {
if ( !srl[si].length )
{
errno = EINVAL;
ntfs_log_perror( "%s: unmapped source runlist", __FUNCTION__ );
return NULL;
@ -565,7 +584,8 @@ static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
* be inserted. If we reach the end of @drl, @srl just needs to be
* appended to @drl.
*/
for (; drl[di].length; di++) {
for ( ; drl[di].length; di++ )
{
if ( drl[di].vcn + drl[di].length > srl[sstart].vcn )
break;
}
@ -573,7 +593,8 @@ static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
/* Sanity check for illegal overlaps. */
if ( ( drl[di].vcn == srl[si].vcn ) && ( drl[di].lcn >= 0 ) &&
(srl[si].lcn >= 0)) {
( srl[si].lcn >= 0 ) )
{
errno = ERANGE;
ntfs_log_perror( "Run lists overlap. Cannot merge" );
return NULL;
@ -617,31 +638,38 @@ static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
ntfs_log_debug( "start = %i, finish = %i\n", start, finish );
ntfs_log_debug( "ds = %i, ss = %i, dins = %i\n", ds, ss, dins );
if (start) {
if ( start )
{
if ( finish )
drl = ntfs_rl_replace( drl, ds, srl + sstart, ss, dins );
else
drl = ntfs_rl_insert( drl, ds, srl + sstart, ss, dins );
} else {
}
else
{
if ( finish )
drl = ntfs_rl_append( drl, ds, srl + sstart, ss, dins );
else
drl = ntfs_rl_split( drl, ds, srl + sstart, ss, dins );
}
if (!drl) {
if ( !drl )
{
ntfs_log_perror( "Merge failed" );
return drl;
}
free( srl );
if (marker) {
if ( marker )
{
ntfs_log_debug( "Triggering marker code.\n" );
for ( ds = dend; drl[ds].length; ds++ )
;
/* We only need to care if @srl ended after @drl. */
if (drl[ds].vcn <= marker_vcn) {
if ( drl[ds].vcn <= marker_vcn )
{
int slots = 0;
if (drl[ds].vcn == marker_vcn) {
if ( drl[ds].vcn == marker_vcn )
{
ntfs_log_debug( "Old marker = %lli, replacing with "
"LCN_ENOENT.\n",
( long long )drl[ds].lcn );
@ -653,13 +681,16 @@ static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
* @drl or extend an existing one before adding the
* ENOENT terminator.
*/
if (drl[ds].lcn == (LCN)LCN_ENOENT) {
if ( drl[ds].lcn == ( LCN )LCN_ENOENT )
{
ds--;
slots = 1;
}
if (drl[ds].lcn != (LCN)LCN_RL_NOT_MAPPED) {
if ( drl[ds].lcn != ( LCN )LCN_RL_NOT_MAPPED )
{
/* Add an unmapped runlist element. */
if (!slots) {
if ( !slots )
{
/* FIXME/TODO: We need to have the
* extra memory already! (AIA)
*/
@ -680,7 +711,8 @@ static runlist_element *ntfs_runlists_merge_i(runlist_element *drl,
drl[ds].length = marker_vcn - drl[ds].vcn;
/* Finally add the ENOENT terminator. */
ds++;
if (!slots) {
if ( !slots )
{
/* FIXME/TODO: We need to have the extra
* memory already! (AIA)
*/
@ -797,7 +829,8 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
( unsigned )le32_to_cpu( attr->type ) );
/* Make sure attr exists and is non-resident. */
if ( !attr || !attr->non_resident ||
sle64_to_cpu(attr->lowest_vcn) < (VCN)0) {
sle64_to_cpu( attr->lowest_vcn ) < ( VCN )0 )
{
errno = EINVAL;
return NULL;
}
@ -807,7 +840,8 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
/* Get start of the mapping pairs array. */
buf = ( const u8* )attr + le16_to_cpu( attr->mapping_pairs_offset );
attr_end = ( const u8* )attr + le32_to_cpu( attr->length );
if (buf < (const u8*)attr || buf > attr_end) {
if ( buf < ( const u8* )attr || buf > attr_end )
{
ntfs_log_debug( "Corrupt attribute.\n" );
errno = EIO;
return NULL;
@ -820,23 +854,27 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
if ( !rl )
return NULL;
/* Insert unmapped starting element if necessary. */
if (vcn) {
if ( vcn )
{
rl->vcn = ( VCN )0;
rl->lcn = ( LCN )LCN_RL_NOT_MAPPED;
rl->length = vcn;
rlpos++;
}
while (buf < attr_end && *buf) {
while ( buf < attr_end && *buf )
{
/*
* Allocate more memory if needed, including space for the
* not-mapped and terminator elements.
*/
if ((int)((rlpos + 3) * sizeof(*old_rl)) > rlsize) {
if ( ( int )( ( rlpos + 3 ) * sizeof( *old_rl ) ) > rlsize )
{
runlist_element *rl2;
rlsize += 0x1000;
rl2 = realloc( rl, rlsize );
if (!rl2) {
if ( !rl2 )
{
int eo = errno;
free( rl );
errno = eo;
@ -854,12 +892,15 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
* length as a signed value so that's how it is...
*/
b = *buf & 0xf;
if (b) {
if ( b )
{
if ( buf + b > attr_end )
goto io_error;
for ( deltaxcn = ( s8 )buf[b--]; b; b-- )
deltaxcn = ( deltaxcn << 8 ) + buf[b];
} else { /* The length entry is compulsory. */
}
else /* The length entry is compulsory. */
{
ntfs_log_debug( "Missing length entry in mapping pairs "
"array.\n" );
deltaxcn = ( s64 ) - 1;
@ -868,7 +909,8 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
* Assume a negative length to indicate data corruption and
* hence clean-up and return NULL.
*/
if (deltaxcn < 0) {
if ( deltaxcn < 0 )
{
ntfs_log_debug( "Invalid length in mapping pairs array.\n" );
goto err_out;
}
@ -886,7 +928,8 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
*/
if ( !( *buf & 0xf0 ) )
rl[rlpos].lcn = ( LCN )LCN_HOLE;
else {
else
{
/* Get the lcn change which really can be negative. */
u8 b2 = *buf & 0xf;
b = b2 + ( ( *buf >> 4 ) & 0xf );
@ -904,7 +947,8 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
* -1. So if either is found give us a message so we
* can investigate it further!
*/
if (vol->major_ver < 3) {
if ( vol->major_ver < 3 )
{
if ( deltaxcn == ( LCN ) - 1 )
ntfs_log_debug( "lcn delta == -1\n" );
if ( lcn == ( LCN ) - 1 )
@ -912,7 +956,8 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
}
#endif
/* Check lcn is not below -1. */
if (lcn < (LCN)-1) {
if ( lcn < ( LCN ) - 1 )
{
ntfs_log_debug( "Invalid LCN < -1 in mapping pairs "
"array.\n" );
goto err_out;
@ -932,14 +977,16 @@ static runlist_element *ntfs_mapping_pairs_decompress_i(const ntfs_volume *vol,
* vcn in the runlist - 1, or something has gone badly wrong.
*/
deltaxcn = sle64_to_cpu( attr->highest_vcn );
if (deltaxcn && vcn - 1 != deltaxcn) {
if ( deltaxcn && vcn - 1 != deltaxcn )
{
mpa_err:
ntfs_log_debug( "Corrupt mapping pairs array in non-resident "
"attribute.\n" );
goto err_out;
}
/* Setup not mapped runlist element if this is the base extent. */
if (!attr->lowest_vcn) {
if ( !attr->lowest_vcn )
{
VCN max_cluster;
max_cluster = ( ( sle64_to_cpu( attr->allocated_size ) +
@ -949,14 +996,16 @@ mpa_err:
* A highest_vcn of zero means this is a single extent
* attribute so simply terminate the runlist with LCN_ENOENT).
*/
if (deltaxcn) {
if ( deltaxcn )
{
/*
* If there is a difference between the highest_vcn and
* the highest cluster, the runlist is either corrupt
* or, more likely, there are more extents following
* this one.
*/
if (deltaxcn < max_cluster) {
if ( deltaxcn < max_cluster )
{
ntfs_log_debug( "More extents to follow; deltaxcn = "
"0x%llx, max_cluster = 0x%llx\n",
( long long )deltaxcn,
@ -965,7 +1014,9 @@ mpa_err:
vcn += rl[rlpos].length = max_cluster - deltaxcn;
rl[rlpos].lcn = ( LCN )LCN_RL_NOT_MAPPED;
rlpos++;
} else if (deltaxcn > max_cluster) {
}
else if ( deltaxcn > max_cluster )
{
ntfs_log_debug( "Corrupt attribute. deltaxcn = "
"0x%llx, max_cluster = 0x%llx\n",
( long long )deltaxcn,
@ -974,14 +1025,16 @@ mpa_err:
}
}
rl[rlpos].lcn = ( LCN )LCN_ENOENT;
} else /* Not the base extent. There may be more extents to follow. */
}
else /* Not the base extent. There may be more extents to follow. */
rl[rlpos].lcn = ( LCN )LCN_RL_NOT_MAPPED;
/* Setup terminating runlist element. */
rl[rlpos].vcn = vcn;
rl[rlpos].length = ( s64 )0;
/* If no existing runlist was specified, we are done. */
if (!old_rl) {
if ( !old_rl )
{
ntfs_log_debug( "Mapping pairs array successfully decompressed:\n" );
ntfs_debug_runlist_dump( rl );
return rl;
@ -1051,8 +1104,10 @@ LCN ntfs_rl_vcn_to_lcn(const runlist_element *rl, const VCN vcn)
if ( vcn < rl[0].vcn )
return ( LCN )LCN_ENOENT;
for (i = 0; rl[i].length; i++) {
if (vcn < rl[i+1].vcn) {
for ( i = 0; rl[i].length; i++ )
{
if ( vcn < rl[i+1].vcn )
{
if ( rl[i].lcn >= ( LCN )0 )
return rl[i].lcn + ( vcn - rl[i].vcn );
return rl[i].lcn;
@ -1098,7 +1153,8 @@ s64 ntfs_rl_pread(const ntfs_volume *vol, const runlist_element *rl,
s64 bytes_read, to_read, ofs, total;
int err = EIO;
if (!vol || !rl || pos < 0 || count < 0) {
if ( !vol || !rl || pos < 0 || count < 0 )
{
errno = EINVAL;
ntfs_log_perror( "Failed to read runlist [vol: %p rl: %p "
"pos: %lld count: %lld]", vol, rl,
@ -1113,10 +1169,12 @@ s64 ntfs_rl_pread(const ntfs_volume *vol, const runlist_element *rl,
ofs += ( rl->length << vol->cluster_size_bits );
/* Offset in the run at which to begin reading. */
ofs = pos - ofs;
for (total = 0LL; count; rl++, ofs = 0) {
for ( total = 0LL; count; rl++, ofs = 0 )
{
if ( !rl->length )
goto rl_err_out;
if (rl->lcn < (LCN)0) {
if ( rl->lcn < ( LCN )0 )
{
if ( rl->lcn != ( LCN )LCN_HOLE )
goto rl_err_out;
/* It is a hole. Just fill buffer @b with zeroes. */
@ -1136,7 +1194,8 @@ retry:
bytes_read = ntfs_pread( vol->dev, ( rl->lcn <<
vol->cluster_size_bits ) + ofs, to_read, b );
/* If everything ok, update progress counters and continue. */
if (bytes_read > 0) {
if ( bytes_read > 0 )
{
total += bytes_read;
count -= bytes_read;
b = ( u8* )b + bytes_read;
@ -1187,7 +1246,8 @@ s64 ntfs_rl_pwrite(const ntfs_volume *vol, const runlist_element *rl,
s64 written, to_write, total = 0;
int err = EIO;
if (!vol || !rl || pos < 0 || count < 0) {
if ( !vol || !rl || pos < 0 || count < 0 )
{
errno = EINVAL;
ntfs_log_perror( "Failed to write runlist [vol: %p rl: %p "
"pos: %lld count: %lld]", vol, rl,
@ -1198,16 +1258,19 @@ s64 ntfs_rl_pwrite(const ntfs_volume *vol, const runlist_element *rl,
goto out;
/* Seek in @rl to the run containing @pos. */
while ( rl->length && ( ofs + ( rl->length <<
vol->cluster_size_bits) <= pos)) {
vol->cluster_size_bits ) <= pos ) )
{
ofs += ( rl->length << vol->cluster_size_bits );
rl++;
}
/* Offset in the run at which to begin writing. */
ofs = pos - ofs;
for (total = 0LL; count; rl++, ofs = 0) {
for ( total = 0LL; count; rl++, ofs = 0 )
{
if ( !rl->length )
goto rl_err_out;
if (rl->lcn < (LCN)0) {
if ( rl->lcn < ( LCN )0 )
{
if ( rl->lcn != ( LCN )LCN_HOLE )
goto rl_err_out;
@ -1231,7 +1294,8 @@ retry:
else
written = to_write;
/* If everything ok, update progress counters and continue. */
if (written > 0) {
if ( written > 0 )
{
total += written;
count -= written;
b = ( u8* )b + written;
@ -1275,12 +1339,15 @@ int ntfs_get_nr_significant_bytes(const s64 n)
l = ( n < 0 ? ~n : n );
i = 1;
if (l >= 128) {
if ( l >= 128 )
{
l >>= 7;
do {
do
{
i++;
l >>= 8;
} while (l);
}
while ( l );
}
return i;
}
@ -1311,14 +1378,17 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
LCN prev_lcn;
int rls;
if (start_vcn < 0) {
if ( start_vcn < 0 )
{
ntfs_log_trace( "start_vcn %lld (should be >= 0)\n",
( long long ) start_vcn );
errno = EINVAL;
goto errno_set;
}
if (!rl) {
if (start_vcn) {
if ( !rl )
{
if ( start_vcn )
{
ntfs_log_trace( "rl NULL, start_vcn %lld (should be > 0)\n",
( long long ) start_vcn );
errno = EINVAL;
@ -1330,7 +1400,8 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
/* Skip to runlist element containing @start_vcn. */
while ( rl->length && start_vcn >= rl[1].vcn )
rl++;
if ((!rl->length && start_vcn > rl->vcn) || start_vcn < rl->vcn) {
if ( ( !rl->length && start_vcn > rl->vcn ) || start_vcn < rl->vcn )
{
errno = EINVAL;
goto errno_set;
}
@ -1338,7 +1409,8 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
/* Always need the terminating zero byte. */
rls = 1;
/* Do the first partial run if present. */
if (start_vcn > rl->vcn) {
if ( start_vcn > rl->vcn )
{
s64 delta;
/* We know rl->length != 0 already. */
@ -1354,7 +1426,8 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
* Note: this assumes that on NTFS 1.2-, holes are stored with
* an lcn of -1 and not a delta_lcn of -1 (unless both are -1).
*/
if (rl->lcn >= 0 || vol->major_ver < 3) {
if ( rl->lcn >= 0 || vol->major_ver < 3 )
{
prev_lcn = rl->lcn;
if ( rl->lcn >= 0 )
prev_lcn += delta;
@ -1365,7 +1438,8 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
rl++;
}
/* Do the full runs. */
for (; rl->length && (rls <= max_size); rl++) {
for ( ; rl->length && ( rls <= max_size ); rl++ )
{
if ( rl->length < 0 || rl->lcn < LCN_HOLE )
goto err_out;
/* Header byte + length. */
@ -1377,7 +1451,8 @@ int ntfs_get_size_for_mapping_pairs(const ntfs_volume *vol,
* Note: this assumes that on NTFS 1.2-, holes are stored with
* an lcn of -1 and not a delta_lcn of -1 (unless both are -1).
*/
if (rl->lcn >= 0 || vol->major_ver < 3) {
if ( rl->lcn >= 0 || vol->major_ver < 3 )
{
/* Change in lcn. */
rls += ntfs_get_nr_significant_bytes( rl->lcn -
prev_lcn );
@ -1421,21 +1496,26 @@ int ntfs_write_significant_bytes(u8 *dst, const u8 *dst_max, const s64 n)
s8 j;
i = 0;
do {
do
{
if ( dst > dst_max )
goto err_out;
*dst++ = l & 0xffLL;
l >>= 8;
i++;
} while (l != 0LL && l != -1LL);
}
while ( l != 0LL && l != -1LL );
j = ( n >> 8 * ( i - 1 ) ) & 0xff;
/* If the sign bit is wrong, we need an extra byte. */
if (n < 0LL && j >= 0) {
if ( n < 0LL && j >= 0 )
{
if ( dst > dst_max )
goto err_out;
i++;
*dst = ( u8 ) - 1;
} else if (n > 0LL && j < 0) {
}
else if ( n > 0LL && j < 0 )
{
if ( dst > dst_max )
goto err_out;
i++;
@ -1489,7 +1569,8 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, u8 *dst,
if ( start_vcn < 0 )
goto val_err;
if (!rl) {
if ( !rl )
{
if ( start_vcn )
goto val_err;
if ( stop_rl )
@ -1510,7 +1591,8 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, u8 *dst,
dst_max = dst + dst_len - 1;
prev_lcn = 0;
/* Do the first partial run if present. */
if (start_vcn > rl->vcn) {
if ( start_vcn > rl->vcn )
{
s64 delta;
/* We know rl->length != 0 already. */
@ -1531,7 +1613,8 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, u8 *dst,
* case on NT4. - We assume that we just need to write the lcn
* change until someone tells us otherwise... (AIA)
*/
if (rl->lcn >= 0 || vol->major_ver < 3) {
if ( rl->lcn >= 0 || vol->major_ver < 3 )
{
prev_lcn = rl->lcn;
if ( rl->lcn >= 0 )
prev_lcn += delta;
@ -1540,7 +1623,8 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, u8 *dst,
len_len, dst_max, prev_lcn );
if ( lcn_len < 0 )
goto size_err;
} else
}
else
lcn_len = 0;
dst_next = dst + len_len + lcn_len + 1;
if ( dst_next > dst_max )
@ -1553,7 +1637,8 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, u8 *dst,
rl++;
}
/* Do the full runs. */
for (; rl->length; rl++) {
for ( ; rl->length; rl++ )
{
if ( rl->length < 0 || rl->lcn < LCN_HOLE )
goto err_out;
/* Write length. */
@ -1570,14 +1655,16 @@ int ntfs_mapping_pairs_build(const ntfs_volume *vol, u8 *dst,
* case on NT4. - We assume that we just need to write the lcn
* change until someone tells us otherwise... (AIA)
*/
if (rl->lcn >= 0 || vol->major_ver < 3) {
if ( rl->lcn >= 0 || vol->major_ver < 3 )
{
/* Write change in lcn. */
lcn_len = ntfs_write_significant_bytes( dst + 1 +
len_len, dst_max, rl->lcn - prev_lcn );
if ( lcn_len < 0 )
goto size_err;
prev_lcn = rl->lcn;
} else
}
else
lcn_len = 0;
dst_next = dst + len_len + lcn_len + 1;
if ( dst_next > dst_max )
@ -1635,7 +1722,8 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
runlist *rl;
BOOL is_end = FALSE;
if (!arl || !*arl) {
if ( !arl || !*arl )
{
errno = EINVAL;
if ( !arl )
ntfs_log_perror( "rl_truncate error: arl: %p", arl );
@ -1647,20 +1735,23 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
rl = *arl;
if (start_vcn < rl->vcn) {
if ( start_vcn < rl->vcn )
{
errno = EINVAL;
ntfs_log_perror( "Start_vcn lies outside front of runlist" );
return -1;
}
/* Find the starting vcn in the run list. */
while (rl->length) {
while ( rl->length )
{
if ( start_vcn < rl[1].vcn )
break;
rl++;
}
if (!rl->length) {
if ( !rl->length )
{
errno = EIO;
ntfs_log_trace( "Truncating already truncated runlist?\n" );
return -1;
@ -1674,7 +1765,8 @@ int ntfs_rl_truncate(runlist **arl, const VCN start_vcn)
* element a terminator instead of the truncated runlist
* element itself.
*/
if (rl->length) {
if ( rl->length )
{
++rl;
if ( !rl->length )
is_end = TRUE;
@ -1708,15 +1800,18 @@ int ntfs_rl_sparse(runlist *rl)
{
runlist *rlc;
if (!rl) {
if ( !rl )
{
errno = EINVAL;
ntfs_log_perror( "%s: ", __FUNCTION__ );
return -1;
}
for ( rlc = rl; rlc->length; rlc++ )
if (rlc->lcn < 0) {
if (rlc->lcn != LCN_HOLE) {
if ( rlc->lcn < 0 )
{
if ( rlc->lcn != LCN_HOLE )
{
errno = EINVAL;
ntfs_log_perror( "%s: bad runlist", __FUNCTION__ );
return -1;
@ -1738,20 +1833,25 @@ s64 ntfs_rl_get_compressed_size(ntfs_volume *vol, runlist *rl)
runlist *rlc;
s64 ret = 0;
if (!rl) {
if ( !rl )
{
errno = EINVAL;
ntfs_log_perror( "%s: ", __FUNCTION__ );
return -1;
}
for (rlc = rl; rlc->length; rlc++) {
if (rlc->lcn < 0) {
if (rlc->lcn != LCN_HOLE) {
for ( rlc = rl; rlc->length; rlc++ )
{
if ( rlc->lcn < 0 )
{
if ( rlc->lcn != LCN_HOLE )
{
errno = EINVAL;
ntfs_log_perror( "%s: bad runlist", __FUNCTION__ );
return -1;
}
} else
}
else
ret += rlc->length;
}
return ret << vol->cluster_size_bits;
@ -1784,7 +1884,8 @@ static void test_rl_dump_runlist(const runlist_element *rl)
int i;
const char *lcn_str[5] = { "HOLE", "NOTMAP", "ENOENT", "XXXX" };
if (!rl) {
if ( !rl )
{
printf( " Run list not present.\n" );
return;
}
@ -1793,24 +1894,28 @@ static void test_rl_dump_runlist(const runlist_element *rl)
for ( len = 0; rl[len].length; len++ ) ;
printf( " VCN LCN len\n" );
for (i = 0; ; i++, rl++) {
for ( i = 0; ; i++, rl++ )
{
LCN lcn = rl->lcn;
if ((abbr) && (len > 20)) {
if ( ( abbr ) && ( len > 20 ) )
{
if ( i == 4 )
printf( " ...\n" );
if ( ( i > 3 ) && ( i < ( len - 3 ) ) )
continue;
}
if (lcn < (LCN)0) {
if ( lcn < ( LCN )0 )
{
int ind = -lcn - 1;
if ( ind > -LCN_ENOENT - 1 )
ind = 3;
printf( "%8lld %8s %8lld\n",
rl->vcn, lcn_str[ind], rl->length );
} else
}
else
printf( "%8lld %8lld %8lld\n",
rl->vcn, rl->lcn, rl->length );
if ( !rl->length )
@ -1862,12 +1967,14 @@ static int test_rl_read_buffer(const char *file, u8 *buf, int bufsize)
FILE *fptr;
fptr = fopen( file, "r" );
if (!fptr) {
if ( !fptr )
{
printf( "open %s\n", file );
return 0;
}
if (fread(buf, bufsize, 1, fptr) == 99) {
if ( fread( buf, bufsize, 1, fptr ) == 99 )
{
printf( "read %s\n", file );
return 0;
}
@ -1901,13 +2008,16 @@ static runlist_element * test_rl_pure_src(BOOL contig, BOOL multi, int vcn, int
if ( !result )
return NULL;
if (multi) {
if ( multi )
{
MKRL( result + 0, vcn + ( 0*len / 4 ), fudge + vcn + 1000 + ( 0*len / 4 ), len / 4 )
MKRL( result + 1, vcn + ( 1*len / 4 ), fudge + vcn + 1000 + ( 1*len / 4 ), len / 4 )
MKRL( result + 2, vcn + ( 2*len / 4 ), fudge + vcn + 1000 + ( 2*len / 4 ), len / 4 )
MKRL( result + 3, vcn + ( 3*len / 4 ), fudge + vcn + 1000 + ( 3*len / 4 ), len / 4 )
MKRL( result + 4, vcn + ( 4*len / 4 ), LCN_RL_NOT_MAPPED, 0 )
} else {
}
else
{
MKRL( result + 0, vcn, fudge + vcn + 1000, len )
MKRL( result + 1, vcn + len, LCN_RL_NOT_MAPPED, 0 )
}
@ -1936,7 +2046,8 @@ static void test_rl_pure_test(int test, BOOL contig, BOOL multi, int vcn, int le
src = test_rl_pure_src( contig, multi, vcn, len );
dst = ntfs_malloc( 4096 );
if (!src || !dst) {
if ( !src || !dst )
{
printf( "Test %2d ---------- FAILED! (no free memory?)\n", test );
return;
}
@ -1961,7 +2072,8 @@ static void test_rl_pure_test(int test, BOOL contig, BOOL multi, int vcn, int le
static void test_rl_pure( char *contig, char *multi )
{
/* VCN, LCN, len */
static runlist_element file1[] = {
static runlist_element file1[] =
{
{ 0, -1, 100 }, /* HOLE */
{ 100, 1100, 100 }, /* DATA */
{ 200, -1, 100 }, /* HOLE */
@ -1969,19 +2081,23 @@ static void test_rl_pure(char *contig, char *multi)
{ 400, -1, 100 }, /* HOLE */
{ 500, -3, 0 } /* NOENT */
};
static runlist_element file2[] = {
static runlist_element file2[] =
{
{ 0, 1000, 100 }, /* DATA */
{ 100, -1, 100 }, /* HOLE */
{ 200, -3, 0 } /* NOENT */
};
static runlist_element file3[] = {
static runlist_element file3[] =
{
{ 0, 1000, 100 }, /* DATA */
{ 100, -3, 0 } /* NOENT */
};
static runlist_element file4[] = {
static runlist_element file4[] =
{
{ 0, -3, 0 } /* NOENT */
};
static runlist_element file5[] = {
static runlist_element file5[] =
{
{ 0, -2, 100 }, /* NOTMAP */
{ 100, 1100, 100 }, /* DATA */
{ 200, -2, 100 }, /* NOTMAP */
@ -1989,7 +2105,8 @@ static void test_rl_pure(char *contig, char *multi)
{ 400, -2, 100 }, /* NOTMAP */
{ 500, -3, 0 } /* NOENT */
};
static runlist_element file6[] = {
static runlist_element file6[] =
{
{ 0, 1000, 100 }, /* DATA */
{ 100, -2, 100 }, /* NOTMAP */
{ 200, -3, 0 } /* NOENT */
@ -2000,7 +2117,8 @@ static void test_rl_pure(char *contig, char *multi)
c = TRUE;
else if ( strcmp( contig, "noncontig" ) == 0 )
c = FALSE;
else {
else
{
printf( "rl pure [contig|noncontig] [single|multi]\n" );
return;
}
@ -2008,7 +2126,8 @@ static void test_rl_pure(char *contig, char *multi)
m = TRUE;
else if ( strcmp( multi, "single" ) == 0 )
m = FALSE;
else {
else
{
printf( "rl pure [contig|noncontig] [single|multi]\n" );
return;
}

View File

@ -43,7 +43,8 @@ typedef runlist_element runlist;
* When lcn == -1 this means that the count vcns starting at vcn are not
* physically allocated (i.e. this is a hole / data is sparse).
*/
struct _runlist_element {/* In memory vcn to lcn mapping structure element. */
struct _runlist_element /* In memory vcn to lcn mapping structure element. */
{
VCN vcn; /* vcn = Starting virtual cluster number. */
LCN lcn; /* lcn = Starting logical cluster number. */
s64 length; /* Run length in clusters. */

File diff suppressed because it is too large Load Diff

View File

@ -50,7 +50,8 @@ typedef u32 be32;
* item in the mapping list
*/
struct MAPPING {
struct MAPPING
{
struct MAPPING *next;
int xid; /* linux id : uid or gid */
SID *sid; /* Windows id : usid or gsid */
@ -63,7 +64,8 @@ struct MAPPING {
* Note : this cache is not organized as a generic cache
*/
struct CACHED_PERMISSIONS {
struct CACHED_PERMISSIONS
{
uid_t uid;
gid_t gid;
le32 inh_fileid;
@ -80,7 +82,8 @@ struct CACHED_PERMISSIONS {
* Entry in the permissions cache for directories with no security_id
*/
struct CACHED_PERMISSIONS_LEGACY {
struct CACHED_PERMISSIONS_LEGACY
{
struct CACHED_PERMISSIONS_LEGACY *next;
struct CACHED_PERMISSIONS_LEGACY *previous;
void *variable;
@ -94,7 +97,8 @@ struct CACHED_PERMISSIONS_LEGACY {
* Entry in the securid cache
*/
struct CACHED_SECURID {
struct CACHED_SECURID
{
struct CACHED_SECURID *next;
struct CACHED_SECURID *previous;
void *variable;
@ -111,7 +115,8 @@ struct CACHED_SECURID {
* (has no cache structure by itself)
*/
struct CACHED_PERMISSIONS_HEADER {
struct CACHED_PERMISSIONS_HEADER
{
unsigned int last;
/* statistics for permissions */
unsigned long p_writes;
@ -123,7 +128,8 @@ struct CACHED_PERMISSIONS_HEADER {
* The whole permissions cache
*/
struct PERMISSIONS_CACHE {
struct PERMISSIONS_CACHE
{
struct CACHED_PERMISSIONS_HEADER head;
struct CACHED_PERMISSIONS *cachetable[1]; /* array of variable size */
} ;
@ -132,7 +138,8 @@ struct PERMISSIONS_CACHE {
* Security flags values
*/
enum {
enum
{
SECURITY_DEFAULT, /* rely on fuse for permissions checking */
SECURITY_RAW, /* force same ownership/permissions on files */
SECURITY_ADDSECURIDS, /* upgrade old security descriptors */
@ -146,7 +153,8 @@ enum {
enum { MAPUSERS, MAPGROUPS, MAPCOUNT } ;
struct SECURITY_CONTEXT {
struct SECURITY_CONTEXT
{
ntfs_volume *vol;
struct MAPPING *mapping[MAPCOUNT];
struct PERMISSIONS_CACHE **pseccache;
@ -162,20 +170,23 @@ struct SECURITY_CONTEXT {
* Posix ACL structures
*/
struct POSIX_ACE {
struct POSIX_ACE
{
u16 tag;
u16 perms;
s32 id;
} ;
struct POSIX_ACL {
struct POSIX_ACL
{
u8 version;
u8 flags;
u16 filler;
struct POSIX_ACE ace[0];
} ;
struct POSIX_SECURITY {
struct POSIX_SECURITY
{
mode_t mode;
int acccnt;
int defcnt;
@ -188,7 +199,8 @@ struct POSIX_SECURITY {
* Posix tags, cpu-endian 16 bits
*/
enum {
enum
{
POSIX_ACL_USER_OBJ = 1,
POSIX_ACL_USER = 2,
POSIX_ACL_GROUP_OBJ = 4,
@ -204,7 +216,8 @@ enum {
* Posix permissions, cpu-endian 16 bits
*/
enum {
enum
{
POSIX_PERM_X = 1,
POSIX_PERM_W = 2,
POSIX_PERM_R = 4,
@ -310,7 +323,8 @@ int ntfs_set_ntfs_attrib(ntfs_inode *ni,
#define MAGIC_API 0x09042009
struct SECURITY_API {
struct SECURITY_API
{
u32 magic;
struct SECURITY_CONTEXT security;
struct PERMISSIONS_CACHE *seccache;

View File

@ -92,7 +92,8 @@ typedef sle64 leLSN;
/**
* enum BOOL - These are just to make the code more readable...
*/
typedef enum {
typedef enum
{
#ifndef FALSE
FALSE = 0,
#endif
@ -118,7 +119,8 @@ typedef enum {
/**
* enum IGNORE_CASE_BOOL -
*/
typedef enum {
typedef enum
{
CASE_SENSITIVE = 0,
IGNORE_CASE = 1,
} IGNORE_CASE_BOOL;

View File

@ -88,7 +88,8 @@ static int nfconvert_utf8 = 1;
* characters are (in)valid.
*/
#if 0
static const u8 legal_ansi_char_array[0x40] = {
static const u8 legal_ansi_char_array[0x40] =
{
0x00, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10,
@ -158,20 +159,25 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
u16 u1, u2;
#ifdef DEBUG
if (!name1 || !name2 || (ic && (!upcase || !upcase_len))) {
if ( !name1 || !name2 || ( ic && ( !upcase || !upcase_len ) ) )
{
ntfs_log_debug( "ntfs_names_collate received NULL pointer!\n" );
exit( 1 );
}
#endif
cnt = min( name1_len, name2_len );
if (cnt > 0) {
if (ic == CASE_SENSITIVE) {
do {
if ( cnt > 0 )
{
if ( ic == CASE_SENSITIVE )
{
do
{
c1 = le16_to_cpu( *name1 );
name1++;
c2 = le16_to_cpu( *name2 );
name2++;
} while (--cnt && (c1 == c2));
}
while ( --cnt && ( c1 == c2 ) );
u1 = c1;
u2 = c2;
if ( u1 < upcase_len )
@ -179,7 +185,8 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
if ( u2 < upcase_len )
u2 = le16_to_cpu( upcase[u2] );
if ( ( u1 == u2 ) && cnt )
do {
do
{
u1 = le16_to_cpu( *name1 );
name1++;
u2 = le16_to_cpu( *name2 );
@ -188,7 +195,8 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
u1 = le16_to_cpu( upcase[u1] );
if ( u2 < upcase_len )
u2 = le16_to_cpu( upcase[u2] );
} while ((u1 == u2) && --cnt);
}
while ( ( u1 == u2 ) && --cnt );
if ( u1 < u2 )
return -1;
if ( u1 > u2 )
@ -201,8 +209,11 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
return -1;
if ( c1 > c2 )
return 1;
} else {
do {
}
else
{
do
{
u1 = c1 = le16_to_cpu( *name1 );
name1++;
u2 = c2 = le16_to_cpu( *name2 );
@ -211,7 +222,8 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
u1 = le16_to_cpu( upcase[u1] );
if ( u2 < upcase_len )
u2 = le16_to_cpu( upcase[u2] );
} while ((u1 == u2) && --cnt);
}
while ( ( u1 == u2 ) && --cnt );
if ( u1 < u2 )
return -1;
if ( u1 > u2 )
@ -221,7 +233,9 @@ int ntfs_names_full_collate(const ntfschar *name1, const u32 name1_len,
if ( name1_len > name2_len )
return 1;
}
} else {
}
else
{
if ( name1_len < name2_len )
return -1;
if ( name1_len > name2_len )
@ -250,12 +264,14 @@ int ntfs_ucsncmp(const ntfschar *s1, const ntfschar *s2, size_t n)
size_t i;
#ifdef DEBUG
if (!s1 || !s2) {
if ( !s1 || !s2 )
{
ntfs_log_debug( "ntfs_wcsncmp() received NULL pointer!\n" );
exit( 1 );
}
#endif
for (i = 0; i < n; ++i) {
for ( i = 0; i < n; ++i )
{
c1 = le16_to_cpu( s1[i] );
c2 = le16_to_cpu( s2[i] );
if ( c1 < c2 )
@ -293,12 +309,14 @@ int ntfs_ucsncasecmp(const ntfschar *s1, const ntfschar *s2, size_t n,
size_t i;
#ifdef DEBUG
if (!s1 || !s2 || !upcase) {
if ( !s1 || !s2 || !upcase )
{
ntfs_log_debug( "ntfs_wcsncasecmp() received NULL pointer!\n" );
exit( 1 );
}
#endif
for (i = 0; i < n; ++i) {
for ( i = 0; i < n; ++i )
{
if ( ( c1 = le16_to_cpu( s1[i] ) ) < upcase_size )
c1 = le16_to_cpu( upcase[c1] );
if ( ( c2 = le16_to_cpu( s2[i] ) ) < upcase_size )
@ -329,7 +347,8 @@ u32 ntfs_ucsnlen(const ntfschar *s, u32 maxlen)
{
u32 i;
for (i = 0; i < maxlen; i++) {
for ( i = 0; i < maxlen; i++ )
{
if ( !le16_to_cpu( s[i] ) )
break;
}
@ -360,7 +379,8 @@ ntfschar *ntfs_ucsndup(const ntfschar *s, u32 maxlen)
len = ntfs_ucsnlen( s, maxlen );
dst = ntfs_malloc( ( len + 1 ) * sizeof( ntfschar ) );
if (dst) {
if ( dst )
{
memcpy( dst, s, len * sizeof( ntfschar ) );
dst[len] = cpu_to_le16( L'\0' );
}
@ -458,16 +478,20 @@ static int utf16_to_utf8_size(const ntfschar *ins, const int ins_len, int outs_l
BOOL surrog;
surrog = FALSE;
for (i = 0; i < ins_len && ins[i]; i++) {
for ( i = 0; i < ins_len && ins[i]; i++ )
{
unsigned short c = le16_to_cpu( ins[i] );
if (surrog) {
if ((c >= 0xdc00) && (c < 0xe000)) {
if ( surrog )
{
if ( ( c >= 0xdc00 ) && ( c < 0xe000 ) )
{
surrog = FALSE;
count += 4;
} else
}
else
goto fail;
} else
if (c < 0x80)
}
else if ( c < 0x80 )
count++;
else if ( c < 0x800 )
count += 2;
@ -483,7 +507,8 @@ static int utf16_to_utf8_size(const ntfschar *ins, const int ins_len, int outs_l
count += 3;
else
goto fail;
if (count > outs_len) {
if ( count > outs_len )
{
errno = ENAMETOOLONG;
goto out;
}
@ -531,7 +556,8 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len,
if ( size < 0 )
goto out;
if (!*outs) {
if ( !*outs )
{
outs_len = size + 1;
*outs = ntfs_malloc( outs_len );
if ( !*outs )
@ -540,35 +566,49 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len,
t = *outs;
for (i = 0; i < ins_len && ins[i]; i++) {
for ( i = 0; i < ins_len && ins[i]; i++ )
{
unsigned short c = le16_to_cpu( ins[i] );
/* size not double-checked */
if (halfpair) {
if ((c >= 0xdc00) && (c < 0xe000)) {
if ( halfpair )
{
if ( ( c >= 0xdc00 ) && ( c < 0xe000 ) )
{
*t++ = 0xf0 + ( ( ( halfpair + 64 ) >> 8 ) & 7 );
*t++ = 0x80 + ( ( ( halfpair + 64 ) >> 2 ) & 63 );
*t++ = 0x80 + ( ( c >> 6 ) & 15 ) + ( ( halfpair & 3 ) << 4 );
*t++ = 0x80 + ( c & 63 );
halfpair = 0;
} else
}
else
goto fail;
} else if (c < 0x80) {
}
else if ( c < 0x80 )
{
*t++ = c;
} else {
if (c < 0x800) {
}
else
{
if ( c < 0x800 )
{
*t++ = ( 0xc0 | ( ( c >> 6 ) & 0x3f ) );
*t++ = 0x80 | ( c & 0x3f );
} else if (c < 0xd800) {
}
else if ( c < 0xd800 )
{
*t++ = 0xe0 | ( c >> 12 );
*t++ = 0x80 | ( ( c >> 6 ) & 0x3f );
*t++ = 0x80 | ( c & 0x3f );
} else if (c < 0xdc00)
}
else if ( c < 0xdc00 )
halfpair = c;
else if (c >= 0xe000) {
else if ( c >= 0xe000 )
{
*t++ = 0xe0 | ( c >> 12 );
*t++ = 0x80 | ( ( c >> 6 ) & 0x3f );
*t++ = 0x80 | ( c & 0x3f );
} else
}
else
goto fail;
}
}
@ -576,17 +616,21 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len,
#if defined(__APPLE__) || defined(__DARWIN__)
#ifdef ENABLE_NFCONV
if(nfconvert_utf8 && (t - *outs) > 0) {
if ( nfconvert_utf8 && ( t - *outs ) > 0 )
{
char *new_outs = NULL;
int new_outs_len = ntfs_macosx_normalize_utf8( *outs, &new_outs, 0 ); // Normalize to decomposed form
if(new_outs_len >= 0 && new_outs != NULL) {
if(original_outs_value != *outs) {
if ( new_outs_len >= 0 && new_outs != NULL )
{
if ( original_outs_value != *outs )
{
// We have allocated outs ourselves.
free( *outs );
*outs = new_outs;
t = *outs + new_outs_len;
}
else {
else
{
// We need to copy new_outs into the fixed outs buffer.
memset( *outs, 0, original_outs_len );
strncpy( *outs, new_outs, original_outs_len - 1 );
@ -594,7 +638,8 @@ static int ntfs_utf16_to_utf8(const ntfschar *ins, const int ins_len,
free( new_outs );
}
}
else {
else
{
ntfs_log_error( "Failed to normalize NTFS string to UTF-8 NFD: %s\n", *outs );
ntfs_log_error( " new_outs=0x%p\n", new_outs );
ntfs_log_error( " new_outs_len=%d\n", new_outs_len );
@ -626,11 +671,14 @@ static int utf8_to_utf16_size(const char *s)
unsigned int byte;
size_t count = 0;
while ((byte = *((const unsigned char *)s++))) {
while ( ( byte = *( ( const unsigned char * )s++ ) ) )
{
if ( ++count >= PATH_MAX )
goto fail;
if (byte >= 0xc0) {
if (byte >= 0xF5) {
if ( byte >= 0xc0 )
{
if ( byte >= 0xF5 )
{
errno = EILSEQ;
goto out;
}
@ -644,7 +692,8 @@ static int utf8_to_utf16_size(const char *s)
s++;
if ( !*s )
break;
if (byte >= 0xF0) {
if ( byte >= 0xF0 )
{
s++;
if ( ++count >= PATH_MAX )
goto fail;
@ -670,25 +719,37 @@ static int utf8_to_unicode(u32 *wc, const char *s)
unsigned int byte = *( ( const unsigned char * )s );
/* single byte */
if (byte == 0) {
if ( byte == 0 )
{
*wc = ( u32 ) 0;
return 0;
} else if (byte < 0x80) {
}
else if ( byte < 0x80 )
{
*wc = ( u32 ) byte;
return 1;
/* double byte */
} else if (byte < 0xc2) {
}
else if ( byte < 0xc2 )
{
goto fail;
} else if (byte < 0xE0) {
if ((s[1] & 0xC0) == 0x80) {
}
else if ( byte < 0xE0 )
{
if ( ( s[1] & 0xC0 ) == 0x80 )
{
*wc = ( ( u32 )( byte & 0x1F ) << 6 )
| ( ( u32 )( s[1] & 0x3F ) );
return 2;
} else
}
else
goto fail;
/* three-byte */
} else if (byte < 0xF0) {
if (((s[1] & 0xC0) == 0x80) && ((s[2] & 0xC0) == 0x80)) {
}
else if ( byte < 0xF0 )
{
if ( ( ( s[1] & 0xC0 ) == 0x80 ) && ( ( s[2] & 0xC0 ) == 0x80 ) )
{
*wc = ( ( u32 )( byte & 0x0F ) << 12 )
| ( ( u32 )( s[1] & 0x3F ) << 6 )
| ( ( u32 )( s[2] & 0x3F ) );
@ -705,9 +766,12 @@ static int utf8_to_unicode(u32 *wc, const char *s)
}
goto fail;
/* four-byte */
} else if (byte < 0xF5) {
}
else if ( byte < 0xF5 )
{
if ( ( ( s[1] & 0xC0 ) == 0x80 ) && ( ( s[2] & 0xC0 ) == 0x80 )
&& ((s[3] & 0xC0) == 0x80)) {
&& ( ( s[3] & 0xC0 ) == 0x80 ) )
{
*wc = ( ( u32 )( byte & 0x07 ) << 18 )
| ( ( u32 )( s[1] & 0x3F ) << 12 )
| ( ( u32 )( s[2] & 0x3F ) << 6 )
@ -736,7 +800,8 @@ static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs)
#if defined(__APPLE__) || defined(__DARWIN__)
#ifdef ENABLE_NFCONV
char *new_ins = NULL;
if(nfconvert_utf8) {
if ( nfconvert_utf8 )
{
int new_ins_len;
new_ins_len = ntfs_macosx_normalize_utf8( ins, &new_ins, 1 ); // Normalize to composed form
if ( new_ins_len >= 0 )
@ -757,7 +822,8 @@ static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs)
goto fail;
allocated = FALSE;
if (!*outs) {
if ( !*outs )
{
*outs = ntfs_malloc( ( shorts + 1 ) * sizeof( ntfschar ) );
if ( !*outs )
goto fail;
@ -766,12 +832,16 @@ static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs)
outpos = *outs;
while(1) {
while ( 1 )
{
int m = utf8_to_unicode( &wc, t );
if (m <= 0) {
if (m < 0) {
if ( m <= 0 )
{
if ( m < 0 )
{
/* do not leave space allocated if failed */
if (allocated) {
if ( allocated )
{
free( *outs );
*outs = ( ntfschar* )NULL;
}
@ -782,7 +852,8 @@ static int ntfs_utf8_to_utf16(const char *ins, ntfschar **outs)
}
if ( wc < 0x10000 )
*outpos++ = cpu_to_le16( wc );
else {
else
{
wc -= 0x10000;
*outpos++ = cpu_to_le16( ( wc >> 10 ) + 0xd800 );
*outpos++ = cpu_to_le16( ( wc & 0x3ff ) + 0xdc00 );
@ -837,19 +908,22 @@ int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
mbstate_t mbstate;
#endif
if (!ins || !outs) {
if ( !ins || !outs )
{
errno = EINVAL;
return -1;
}
mbs = *outs;
mbs_len = outs_len;
if (mbs && !mbs_len) {
if ( mbs && !mbs_len )
{
errno = ENAMETOOLONG;
return -1;
}
if ( use_utf8 )
return ntfs_utf16_to_utf8( ins, ins_len, outs, outs_len );
if (!mbs) {
if ( !mbs )
{
mbs_len = ( ins_len + 1 ) * MB_CUR_MAX;
mbs = ntfs_malloc( mbs_len );
if ( !mbs )
@ -860,11 +934,14 @@ int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
#else
wctomb( NULL, 0 );
#endif
for (i = o = 0; i < ins_len; i++) {
for ( i = o = 0; i < ins_len; i++ )
{
/* Reallocate memory if necessary or abort. */
if ((int)(o + MB_CUR_MAX) > mbs_len) {
if ( ( int )( o + MB_CUR_MAX ) > mbs_len )
{
char *tc;
if (mbs == *outs) {
if ( mbs == *outs )
{
errno = ENAMETOOLONG;
return -1;
}
@ -888,7 +965,8 @@ int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
#endif
if ( cnt == -1 )
goto err_out;
if (cnt <= 0) {
if ( cnt <= 0 )
{
ntfs_log_debug( "Eeek. cnt <= 0, cnt = %i\n", cnt );
errno = EINVAL;
goto err_out;
@ -897,7 +975,8 @@ int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
}
#ifdef HAVE_MBSINIT
/* Make sure we are back in the initial state. */
if (!mbsinit(&mbstate)) {
if ( !mbsinit( &mbstate ) )
{
ntfs_log_debug( "Eeek. mbstate not in initial state!\n" );
errno = EILSEQ;
goto err_out;
@ -909,7 +988,8 @@ int ntfs_ucstombs(const ntfschar *ins, const int ins_len, char **outs,
*outs = mbs;
return o;
err_out:
if (mbs != *outs) {
if ( mbs != *outs )
{
int eo = errno;
free( mbs );
errno = eo;
@ -950,7 +1030,8 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
mbstate_t mbstate;
#endif
if (!ins || !outs) {
if ( !ins || !outs )
{
errno = EINVAL;
return -1;
}
@ -966,7 +1047,8 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
memset( &mbstate, 0, sizeof( mbstate ) );
ins_len = mbsrtowcs( NULL, ( const char ** ) & s, 0, &mbstate );
#ifdef __CYGWIN32__
if (!ins_len && *ins) {
if ( !ins_len && *ins )
{
/* Older Cygwin had broken mbsrtowcs() implementation. */
ins_len = strlen( ins );
}
@ -980,9 +1062,11 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
if ( ins_len == -1 )
return ins_len;
#ifdef HAVE_MBSINIT
if ((s != ins) || !mbsinit(&mbstate)) {
if ( ( s != ins ) || !mbsinit( &mbstate ) )
{
#else
if (s != ins) {
if ( s != ins )
{
#endif
errno = EILSEQ;
return -1;
@ -998,9 +1082,11 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
#else
mbtowc( NULL, NULL, 0 );
#endif
for (i = o = cnt = 0; i < ins_size; i += cnt, o++) {
for ( i = o = cnt = 0; i < ins_size; i += cnt, o++ )
{
/* Reallocate memory if necessary. */
if (o >= ucs_len) {
if ( o >= ucs_len )
{
ntfschar *tc;
ucs_len = ( ucs_len * sizeof( ntfschar ) + 64 ) & ~63;
tc = realloc( ucs, ucs_len );
@ -1019,14 +1105,16 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
break;
if ( cnt == -1 )
goto err_out;
if (cnt < -1) {
if ( cnt < -1 )
{
ntfs_log_trace( "Eeek. cnt = %i\n", cnt );
errno = EINVAL;
goto err_out;
}
/* Make sure we are not overflowing the NTFS Unicode set. */
if ( ( unsigned long )wc >= ( unsigned long )( 1 <<
(8 * sizeof(ntfschar)))) {
( 8 * sizeof( ntfschar ) ) ) )
{
errno = EILSEQ;
goto err_out;
}
@ -1035,7 +1123,8 @@ int ntfs_mbstoucs(const char *ins, ntfschar **outs)
}
#ifdef HAVE_MBSINIT
/* Make sure we are back in the initial state. */
if (!mbsinit(&mbstate)) {
if ( !mbsinit( &mbstate ) )
{
ntfs_log_trace( "Eeek. mbstate not in initial state!\n" );
errno = EILSEQ;
goto err_out;
@ -1069,24 +1158,32 @@ char *ntfs_uppercase_mbs(const char *low,
size = strlen( low );
upp = ( char* )ntfs_malloc( 3 * size + 1 );
if (upp) {
if ( upp )
{
s = low;
t = upp;
do {
do
{
n = utf8_to_unicode( &wc, s );
if (n > 0) {
if ( n > 0 )
{
if ( wc < upcase_size )
wc = le16_to_cpu( upcase[wc] );
if ( wc < 0x80 )
*t++ = wc;
else if (wc < 0x800) {
else if ( wc < 0x800 )
{
*t++ = ( 0xc0 | ( ( wc >> 6 ) & 0x3f ) );
*t++ = 0x80 | ( wc & 0x3f );
} else if (wc < 0x10000) {
}
else if ( wc < 0x10000 )
{
*t++ = 0xe0 | ( wc >> 12 );
*t++ = 0x80 | ( ( wc >> 6 ) & 0x3f );
*t++ = 0x80 | ( wc & 0x3f );
} else {
}
else
{
*t++ = 0xf0 | ( ( wc >> 18 ) & 7 );
*t++ = 0x80 | ( ( wc >> 12 ) & 63 );
*t++ = 0x80 | ( ( wc >> 6 ) & 0x3f );
@ -1094,8 +1191,10 @@ char *ntfs_uppercase_mbs(const char *low,
}
s += n;
}
} while (n > 0);
if (n < 0) {
}
while ( n > 0 );
if ( n < 0 )
{
free( upp );
upp = ( char* )NULL;
errno = EILSEQ;
@ -1117,7 +1216,8 @@ char *ntfs_uppercase_mbs(const char *low,
*/
void ntfs_upcase_table_build( ntfschar *uc, u32 uc_len )
{
static int uc_run_table[][3] = { /* Start, End, Add */
static int uc_run_table[][3] = /* Start, End, Add */
{
{0x0061, 0x007B, -32}, {0x0451, 0x045D, -80}, {0x1F70, 0x1F72, 74},
{0x00E0, 0x00F7, -32}, {0x045E, 0x0460, -80}, {0x1F72, 0x1F76, 86},
{0x00F8, 0x00FF, -32}, {0x0561, 0x0587, -48}, {0x1F76, 0x1F78, 100},
@ -1133,7 +1233,8 @@ void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len)
{0x0430, 0x0450, -32}, {0x1F60, 0x1F68, 8}, {0xFF41, 0xFF5B, -32},
{0}
};
static int uc_dup_table[][2] = { /* Start, End */
static int uc_dup_table[][2] = /* Start, End */
{
{0x0100, 0x012F}, {0x01A0, 0x01A6}, {0x03E2, 0x03EF}, {0x04CB, 0x04CC},
{0x0132, 0x0137}, {0x01B3, 0x01B7}, {0x0460, 0x0481}, {0x04D0, 0x04EB},
{0x0139, 0x0149}, {0x01CD, 0x01DD}, {0x0490, 0x04BF}, {0x04EE, 0x04F5},
@ -1142,7 +1243,8 @@ void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len)
{0x018B, 0x018B}, {0x01FA, 0x0218}, {0x04C7, 0x04C8}, {0x1EA0, 0x1EF9},
{0}
};
static int uc_byte_table[][2] = { /* Offset, Value */
static int uc_byte_table[][2] = /* Offset, Value */
{
{0x00FF, 0x0178}, {0x01AD, 0x01AC}, {0x01F3, 0x01F1}, {0x0269, 0x0196},
{0x0183, 0x0182}, {0x01B0, 0x01AF}, {0x0253, 0x0181}, {0x026F, 0x019C},
{0x0185, 0x0184}, {0x01B9, 0x01B8}, {0x0254, 0x0186}, {0x0272, 0x019D},
@ -1162,7 +1264,8 @@ void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len)
uc_len = 65536;
for ( i = 0; ( u32 )i < uc_len; i++ )
uc[i] = cpu_to_le16( i );
for (r = 0; uc_run_table[r][0]; r++) {
for ( r = 0; uc_run_table[r][0]; r++ )
{
off = uc_run_table[r][2];
for ( i = uc_run_table[r][0]; i < uc_run_table[r][1]; i++ )
uc[i] = cpu_to_le16( i + off );
@ -1170,7 +1273,8 @@ void ntfs_upcase_table_build(ntfschar *uc, u32 uc_len)
for ( r = 0; uc_dup_table[r][0]; r++ )
for ( i = uc_dup_table[r][0]; i < uc_dup_table[r][1]; i += 2 )
uc[i + 1] = cpu_to_le16( i );
for (r = 0; uc_byte_table[r][0]; r++) {
for ( r = 0; uc_byte_table[r][0]; r++ )
{
k = uc_byte_table[r][1];
uc[uc_byte_table[r][0]] = cpu_to_le16( k );
}
@ -1195,15 +1299,18 @@ ntfschar *ntfs_locase_table_build(const ntfschar *uc, u32 uc_cnt)
u32 i;
lc = ( ntfschar* )ntfs_malloc( uc_cnt * sizeof( ntfschar ) );
if (lc) {
if ( lc )
{
for ( i = 0; i < uc_cnt; i++ )
lc[i] = cpu_to_le16( i );
for (i=0; i<uc_cnt; i++) {
for ( i = 0; i < uc_cnt; i++ )
{
upp = le16_to_cpu( uc[i] );
if ( ( upp != i ) && ( upp < uc_cnt ) )
lc[upp] = cpu_to_le16( i );
}
} else
}
else
ntfs_log_error( "Could not build the locase table\n" );
return ( lc );
}
@ -1229,16 +1336,19 @@ ntfschar *ntfs_str2ucs(const char *s, int *len)
{
ntfschar *ucs = NULL;
if (s && ((*len = ntfs_mbstoucs(s, &ucs)) == -1)) {
if ( s && ( ( *len = ntfs_mbstoucs( s, &ucs ) ) == -1 ) )
{
ntfs_log_perror( "Couldn't convert '%s' to Unicode", s );
return NULL;
}
if (*len > NTFS_MAX_NAME_LEN) {
if ( *len > NTFS_MAX_NAME_LEN )
{
free( ucs );
errno = ENAMETOOLONG;
return NULL;
}
if (!ucs || !*len) {
if ( !ucs || !*len )
{
ucs = AT_UNNAMED;
*len = 0;
}
@ -1282,7 +1392,8 @@ BOOL ntfs_forbidden_chars(const ntfschar *name, int len)
forbidden = ( len == 0 )
|| ( le16_to_cpu( name[len-1] ) == ' ' )
|| ( le16_to_cpu( name[len-1] ) == '.' );
for (i=0; i<len; i++) {
for ( i = 0; i < len; i++ )
{
ch = le16_to_cpu( name[i] );
if ( ( ch < 0x20 )
|| ( ( ch < 0x40 )
@ -1314,7 +1425,8 @@ BOOL ntfs_collapsible_chars(ntfs_volume *vol,
collapsible = shortlen == longlen;
if ( collapsible )
for (i=0; i<shortlen; i++) {
for ( i = 0; i < shortlen; i++ )
{
ch = le16_to_cpu( longname[i] );
if ( ( ch >= vol->upcase_len )
|| ( ( shortname[i] != longname[i] )
@ -1335,10 +1447,10 @@ int ntfs_set_char_encoding(const char *locale)
if ( !locale || strstr( locale, "utf8" ) || strstr( locale, "UTF8" )
|| strstr( locale, "utf-8" ) || strstr( locale, "UTF-8" ) )
use_utf8 = 1;
else
if (setlocale(LC_ALL, locale))
else if ( setlocale( LC_ALL, locale ) )
use_utf8 = 0;
else {
else
{
ntfs_log_error( "Invalid locale, encoding to UTF-8\n" );
use_utf8 = 1;
}
@ -1347,9 +1459,11 @@ int ntfs_set_char_encoding(const char *locale)
#if defined(__APPLE__) || defined(__DARWIN__)
int ntfs_macosx_normalize_filenames(int normalize) {
int ntfs_macosx_normalize_filenames( int normalize )
{
#ifdef ENABLE_NFCONV
if(normalize == 0 || normalize == 1) {
if ( normalize == 0 || normalize == 1 )
{
nfconvert_utf8 = normalize;
return 0;
}
@ -1361,7 +1475,8 @@ int ntfs_macosx_normalize_filenames(int normalize) {
}
int ntfs_macosx_normalize_utf8( const char *utf8_string, char **target,
int composed) {
int composed )
{
#ifdef ENABLE_NFCONV
/* For this code to compile, the CoreFoundation framework must be fed to the linker. */
CFStringRef cfSourceString;
@ -1373,7 +1488,8 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
/* Convert the UTF-8 string to a CFString. */
cfSourceString = CFStringCreateWithCString( kCFAllocatorDefault, utf8_string, kCFStringEncodingUTF8 );
if(cfSourceString == NULL) {
if ( cfSourceString == NULL )
{
ntfs_log_error( "CFStringCreateWithCString failed!\n" );
return -2;
}
@ -1381,7 +1497,8 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
/* Create a mutable string from cfSourceString that we are free to modify. */
cfMutableString = CFStringCreateMutableCopy( kCFAllocatorDefault, 0, cfSourceString );
CFRelease( cfSourceString ); /* End-of-life. */
if(cfMutableString == NULL) {
if ( cfMutableString == NULL )
{
ntfs_log_error( "CFStringCreateMutableCopy failed!\n" );
return -3;
}
@ -1391,13 +1508,16 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
/* Store the resulting string in a '\0'-terminated UTF-8 encoded char* buffer. */
rangeToProcess = CFRangeMake( 0, CFStringGetLength( cfMutableString ) );
if(CFStringGetBytes(cfMutableString, rangeToProcess, kCFStringEncodingUTF8, 0, false, NULL, 0, &requiredBufferLength) > 0) {
if ( CFStringGetBytes( cfMutableString, rangeToProcess, kCFStringEncodingUTF8, 0, false, NULL, 0, &requiredBufferLength ) > 0 )
{
resultLength = sizeof( char ) * ( requiredBufferLength + 1 );
result = ntfs_calloc( resultLength );
if(result != NULL) {
if ( result != NULL )
{
if ( CFStringGetBytes( cfMutableString, rangeToProcess, kCFStringEncodingUTF8,
0, false, (UInt8*)result, resultLength-1, &requiredBufferLength) <= 0) {
0, false, ( UInt8* )result, resultLength - 1, &requiredBufferLength ) <= 0 )
{
ntfs_log_error( "Could not perform UTF-8 conversion of normalized CFMutableString.\n" );
free( result );
result = NULL;
@ -1412,7 +1532,8 @@ int ntfs_macosx_normalize_utf8(const char *utf8_string, char **target,
CFRelease( cfMutableString );
if(result != NULL) {
if ( result != NULL )
{
*target = result;
return resultLength - 1;
}

Some files were not shown because too many files have changed in this diff Show More