* Unified formating of source files.

This commit is contained in:
eraserxl 2010-09-24 00:48:03 +00:00
parent 05825a3231
commit 772859ecbc
324 changed files with 59223 additions and 59941 deletions

View File

@ -2,8 +2,8 @@
<app version="1">
<name> USB Loader GX</name>
<coder>USB Loader GX Team</coder>
<version>1.0 r961</version>
<release_date>201009222057</release_date>
<version>1.0 r962</version>
<release_date>201009232353</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.

View File

@ -32,14 +32,12 @@ static u32 MainFontSize = font_ttf_size;
void ClearFontData()
{
if ( fontSystem )
delete fontSystem;
if (fontSystem) delete fontSystem;
fontSystem = NULL;
if (MainFont != (FT_Byte *) font_ttf)
{
if ( MainFont != NULL )
delete [] MainFont;
if (MainFont != NULL) delete[] MainFont;
MainFont = (FT_Byte *) font_ttf;
MainFontSize = font_ttf_size;
}
@ -52,8 +50,7 @@ bool SetupDefaultFont( const char *path )
ClearFontData();
if ( path )
pfile = fopen( path, "rb" );
if (path) pfile = fopen(path, "rb");
if (pfile)
{

View File

@ -36,12 +36,10 @@ using namespace std;
wchar_t* charToWideChar(const char* strChar)
{
if ( !strChar )
return NULL;
if (!strChar) return NULL;
wchar_t *strWChar = new (std::nothrow) wchar_t[strlen(strChar) + 1];
if ( !strWChar )
return NULL;
if (!strWChar) return NULL;
int bt = mbstowcs(strWChar, strChar, strlen(strChar));
if (bt > 0)
@ -51,7 +49,8 @@ wchar_t* charToWideChar( const char* strChar )
}
wchar_t *tempDest = strWChar;
while ( ( *tempDest++ = *strChar++ ) );
while ((*tempDest++ = *strChar++))
;
return strWChar;
}
@ -104,8 +103,7 @@ void FreeTypeGX::setVertexFormat( uint8_t vertexInd )
*/
void FreeTypeGX::unloadFont()
{
if ( this->fontData.size() == 0 )
return;
if (this->fontData.size() == 0) return;
map<int16_t, map<wchar_t, ftgxCharData> >::iterator itr;
map<wchar_t, ftgxCharData>::iterator itr2;
@ -208,8 +206,7 @@ uint16_t FreeTypeGX::cacheGlyphDataComplete( int16_t pixelSize )
FT_ULong charCode = FT_Get_First_Char(ftFace, &gIndex);
while (gIndex != 0)
{
if ( cacheGlyphData( charCode, pixelSize ) != NULL )
++i;
if (cacheGlyphData(charCode, pixelSize) != NULL) ++i;
charCode = FT_Get_Next_Char(ftFace, charCode, &gIndex);
}
return (uint16_t) (i);
@ -232,8 +229,7 @@ void FreeTypeGX::loadGlyphData( FT_Bitmap *bmp, ftgxCharData *charData )
int length = ((((charData->textureWidth + 3) >> 2) * ((charData->textureHeight + 3) >> 2) * 32 * 2 + 31) & ~31);
uint8_t * glyphData = (uint8_t *) memalign(32, length);
if ( !glyphData )
return;
if (!glyphData) return;
memset(glyphData, 0x00, length);
@ -244,7 +240,8 @@ void FreeTypeGX::loadGlyphData( FT_Bitmap *bmp, ftgxCharData *charData )
{
for (int imagePosX = 0; imagePosX < bmp->width; ++imagePosX)
{
offset = ( ( ( ( imagePosY >> 2 ) * ( charData->textureWidth >> 2 ) + ( imagePosX >> 2 ) ) << 5 ) + ( ( imagePosY & 3 ) << 2 ) + ( imagePosX & 3 ) ) << 1;
offset = ((((imagePosY >> 2) * (charData->textureWidth >> 2) + (imagePosX >> 2)) << 5) + ((imagePosY & 3)
<< 2) + (imagePosX & 3)) << 1;
glyphData[offset] = *src;
glyphData[offset + 1] = *src;
glyphData[offset + 32] = *src;
@ -271,8 +268,7 @@ int16_t FreeTypeGX::getStyleOffsetWidth( uint16_t width, uint16_t format )
return 0;
else if (format & FTGX_JUSTIFY_CENTER)
return -(width >> 1);
else if ( format & FTGX_JUSTIFY_RIGHT )
return -width;
else if (format & FTGX_JUSTIFY_RIGHT) return -width;
return 0;
}
@ -287,8 +283,7 @@ int16_t FreeTypeGX::getStyleOffsetWidth( uint16_t width, uint16_t format )
int16_t FreeTypeGX::getStyleOffsetHeight(int16_t format, uint16_t pixelSize)
{
map<int16_t, ftgxDataOffset>::iterator itrAlign = ftgxAlign.find(pixelSize);
if ( itrAlign == ftgxAlign.end() )
return 0;
if (itrAlign == ftgxAlign.end()) return 0;
switch (format & FTGX_ALIGN_MASK)
{
@ -330,10 +325,10 @@ int16_t FreeTypeGX::getStyleOffsetHeight( int16_t format, uint16_t pixelSize )
* @param textStyle Flags which specify any styling which should be applied to the rendered string.
* @return The number of characters printed.
*/
uint16_t FreeTypeGX::drawText( int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, GXColor color, uint16_t textStyle, uint16_t textWidth, uint16_t widthLimit )
uint16_t FreeTypeGX::drawText(int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, GXColor color,
uint16_t textStyle, uint16_t textWidth, uint16_t widthLimit)
{
if ( !text )
return 0;
if (!text) return 0;
uint16_t fullTextWidth = textWidth > 0 ? textWidth : getWidth(text, pixelSize);
uint16_t x_pos = x, printed = 0;
@ -354,8 +349,7 @@ uint16_t FreeTypeGX::drawText( int16_t x, int16_t y, int16_t z, const wchar_t *t
while (text[i])
{
if ( widthLimit > 0 && ( x_pos - x ) > widthLimit )
break;
if (widthLimit > 0 && (x_pos - x) > widthLimit) break;
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
@ -363,12 +357,15 @@ uint16_t FreeTypeGX::drawText( int16_t x, int16_t y, int16_t z, const wchar_t *t
{
if (ftKerningEnabled && i > 0)
{
FT_Get_Kerning( ftFace, fontData[pixelSize][text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta );
FT_Get_Kerning(ftFace, fontData[pixelSize][text[i - 1]].glyphIndex, glyphData->glyphIndex,
FT_KERNING_DEFAULT, &pairDelta);
x_pos += pairDelta.x >> 6;
}
GX_InitTexObj( &glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth, glyphData->textureHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE );
copyTextureToFramebuffer( &glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos + glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, z, color );
GX_InitTexObj(&glyphTexture, glyphData->glyphDataTexture, glyphData->textureWidth,
glyphData->textureHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
copyTextureToFramebuffer(&glyphTexture, glyphData->textureWidth, glyphData->textureHeight, x_pos
+ glyphData->renderOffsetX + x_offset, y - glyphData->renderOffsetY + y_offset, z, color);
x_pos += glyphData->glyphAdvanceX;
++printed;
@ -379,21 +376,22 @@ uint16_t FreeTypeGX::drawText( int16_t x, int16_t y, int16_t z, const wchar_t *t
if (textStyle & FTGX_STYLE_MASK)
{
getOffset(text, pixelSize, widthLimit);
drawTextFeature( x + x_offset, y + y_offset, z, pixelSize, fullTextWidth, &ftgxAlign[pixelSize], textStyle, color );
drawTextFeature(x + x_offset, y + y_offset, z, pixelSize, fullTextWidth, &ftgxAlign[pixelSize], textStyle,
color);
}
return printed;
}
void FreeTypeGX::drawTextFeature( int16_t x, int16_t y, int16_t z, int16_t pixelSize, uint16_t width, ftgxDataOffset *offsetData, uint16_t format, GXColor color )
void FreeTypeGX::drawTextFeature(int16_t x, int16_t y, int16_t z, int16_t pixelSize, uint16_t width,
ftgxDataOffset *offsetData, uint16_t format, GXColor color)
{
uint16_t featureHeight = pixelSize >> 4 > 0 ? pixelSize >> 4 : 1;
if ( format & FTGX_STYLE_UNDERLINE )
this->copyFeatureToFramebuffer( width, featureHeight, x, y + 1, z, color );
if (format & FTGX_STYLE_UNDERLINE) this->copyFeatureToFramebuffer(width, featureHeight, x, y + 1, z, color);
if ( format & FTGX_STYLE_STRIKE )
this->copyFeatureToFramebuffer( width, featureHeight, x, y - ( ( offsetData->max ) >> 1 ), z, color );
if (format & FTGX_STYLE_STRIKE) this->copyFeatureToFramebuffer(width, featureHeight, x, y
- ((offsetData->max) >> 1), z, color);
}
/**
@ -407,8 +405,7 @@ void FreeTypeGX::drawTextFeature( int16_t x, int16_t y, int16_t z, int16_t pixel
*/
uint16_t FreeTypeGX::getWidth(const wchar_t *text, int16_t pixelSize)
{
if ( !text )
return 0;
if (!text) return 0;
uint16_t strWidth = 0;
FT_Vector pairDelta;
@ -422,7 +419,8 @@ uint16_t FreeTypeGX::getWidth( const wchar_t *text, int16_t pixelSize )
{
if (ftKerningEnabled && (i > 0))
{
FT_Get_Kerning( ftFace, fontData[pixelSize][text[i - 1]].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta );
FT_Get_Kerning(ftFace, fontData[pixelSize][text[i - 1]].glyphIndex, glyphData->glyphIndex,
FT_KERNING_DEFAULT, &pairDelta);
strWidth += pairDelta.x >> 6;
}
@ -446,7 +444,8 @@ uint16_t FreeTypeGX::getCharWidth( const wchar_t wChar, int16_t pixelSize, const
if (ftKerningEnabled && prevChar != 0x0000)
{
FT_Vector pairDelta;
FT_Get_Kerning( ftFace, fontData[pixelSize][prevChar].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT, &pairDelta );
FT_Get_Kerning(ftFace, fontData[pixelSize][prevChar].glyphIndex, glyphData->glyphIndex, FT_KERNING_DEFAULT,
&pairDelta);
strWidth += pairDelta.x >> 6;
}
strWidth += glyphData->glyphAdvanceX;
@ -483,8 +482,7 @@ uint16_t FreeTypeGX::getHeight( const wchar_t *text, int16_t pixelSize )
*/
void FreeTypeGX::getOffset(const wchar_t *text, int16_t pixelSize, uint16_t widthLimit)
{
if ( ftgxAlign.find( pixelSize ) != ftgxAlign.end() )
return;
if (ftgxAlign.find(pixelSize) != ftgxAlign.end()) return;
int16_t strMax = 0, strMin = 9999;
uint16_t currWidth = 0;
@ -493,8 +491,7 @@ void FreeTypeGX::getOffset( const wchar_t *text, int16_t pixelSize, uint16_t wid
while (text[i])
{
if ( widthLimit > 0 && currWidth >= widthLimit )
break;
if (widthLimit > 0 && currWidth >= widthLimit) break;
ftgxCharData* glyphData = cacheGlyphData(text[i], pixelSize);
@ -532,7 +529,8 @@ void FreeTypeGX::getOffset( const wchar_t *text, int16_t pixelSize, uint16_t wid
* @param screenY The screen Y coordinate at which to output the rendered texture.
* @param color Color to apply to the texture.
*/
void FreeTypeGX::copyTextureToFramebuffer( GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY, int16_t screenZ, GXColor color )
void FreeTypeGX::copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX,
int16_t screenY, int16_t screenZ, GXColor color)
{
GX_LoadTexObj(texObj, GX_TEXMAP0);
GX_InvalidateTexAll();
@ -573,7 +571,8 @@ void FreeTypeGX::copyTextureToFramebuffer( GXTexObj *texObj, f32 texWidth, f32 t
* @param screenY The screen Y coordinate at which to output the quad.
* @param color Color to apply to the texture.
*/
void FreeTypeGX::copyFeatureToFramebuffer( f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY, int16_t screenZ, GXColor color )
void FreeTypeGX::copyFeatureToFramebuffer(f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY,
int16_t screenZ, GXColor color)
{
GX_SetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
GX_SetVtxDesc(GX_VA_TEX0, GX_NONE);

View File

@ -89,7 +89,8 @@ typedef struct ftgxDataOffset_ ftgxDataOffset;
#define FTGX_STYLE_STRIKE 0x2000
#define FTGX_STYLE_MASK 0xf000
const GXColor ftgxWhite = ( GXColor ) {0xff, 0xff, 0xff, 0xff}; /**< Constant color value used only to sanitize Doxygen documentation. */
const GXColor ftgxWhite = ( GXColor )
{ 0xff, 0xff, 0xff, 0xff}; /**< Constant color value used only to sanitize Doxygen documentation. */
wchar_t* charToWideChar(const char* p);
@ -123,9 +124,12 @@ class FreeTypeGX
void setDefaultMode();
void drawTextFeature( int16_t x, int16_t y, int16_t z, int16_t pixelSize, uint16_t width, ftgxDataOffset *offsetData, uint16_t format, GXColor color );
void copyTextureToFramebuffer( GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY, int16_t screenZ, GXColor color );
void copyFeatureToFramebuffer( f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY, int16_t screenZ, GXColor color );
void drawTextFeature(int16_t x, int16_t y, int16_t z, int16_t pixelSize, uint16_t width,
ftgxDataOffset *offsetData, uint16_t format, GXColor color);
void copyTextureToFramebuffer(GXTexObj *texObj, f32 texWidth, f32 texHeight, int16_t screenX, int16_t screenY,
int16_t screenZ, GXColor color);
void copyFeatureToFramebuffer(f32 featureWidth, f32 featureHeight, int16_t screenX, int16_t screenY,
int16_t screenZ, GXColor color);
public:
FreeTypeGX(const uint8_t* fontBuffer, FT_Long bufferSize);
@ -133,7 +137,8 @@ class FreeTypeGX
void setVertexFormat(uint8_t vertexIndex);
uint16_t drawText( int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, GXColor color = ftgxWhite, uint16_t textStyling = FTGX_NULL, uint16_t textWidth = 0, uint16_t widthLimit = 0 );
uint16_t drawText(int16_t x, int16_t y, int16_t z, const wchar_t *text, int16_t pixelSize, GXColor color =
ftgxWhite, uint16_t textStyling = FTGX_NULL, uint16_t textWidth = 0, uint16_t widthLimit = 0);
uint16_t getWidth(const wchar_t *text, int16_t pixelSize);
uint16_t getCharWidth(const wchar_t wChar, int16_t pixelSize, const wchar_t prevChar = 0x0000);

View File

@ -42,8 +42,7 @@
ZipFile::ZipFile(const char *filepath)
{
File = unzOpen(filepath);
if ( File )
this->LoadList();
if (File) this->LoadList();
}
ZipFile::~ZipFile()
@ -58,29 +57,26 @@ bool ZipFile::LoadList()
bool ZipFile::ExtractAll(const char *dest)
{
if ( !File )
return false;
if (!File) return false;
bool Stop = false;
u32 blocksize = 1024 * 50;
u8 *buffer = new u8[blocksize];
if ( !buffer )
return false;
if (!buffer) return false;
char writepath[MAXPATHLEN];
char filename[MAXPATHLEN];
memset(filename, 0, sizeof(filename));
int ret = unzGoToFirstFile(File);
if ( ret != UNZ_OK )
Stop = true;
if (ret != UNZ_OK) Stop = true;
while (!Stop)
{
if ( unzGetCurrentFileInfo( File, &cur_file_info, filename, sizeof( filename ), NULL, NULL, NULL, NULL ) != UNZ_OK )
Stop = true;
if (unzGetCurrentFileInfo(File, &cur_file_info, filename, sizeof(filename), NULL, NULL, NULL, NULL) != UNZ_OK) Stop
= true;
if (!Stop && filename[strlen(filename) - 1] != '/')
{
@ -109,27 +105,23 @@ bool ZipFile::ExtractAll( const char *dest )
{
ShowProgress(tr( "Extracting files..." ), 0, pointer + 1, done, uncompressed_size);
if ( uncompressed_size - done < blocksize )
blocksize = uncompressed_size - done;
if (uncompressed_size - done < blocksize) blocksize = uncompressed_size - done;
ret = unzReadCurrentFile(File, buffer, blocksize);
if ( ret == 0 )
break;
if (ret == 0) break;
fwrite(buffer, 1, blocksize, pfile);
done += ret;
}
while ( done < uncompressed_size );
} while (done < uncompressed_size);
fclose(pfile);
unzCloseCurrentFile(File);
}
}
if ( unzGoToNextFile( File ) != UNZ_OK )
Stop = true;
if (unzGoToNextFile(File) != UNZ_OK) Stop = true;
}
delete[] buffer;

View File

@ -86,7 +86,6 @@
#include "MD5.h"
/* -------------------------------------------------------------------------- **
* Static Constants:
*
@ -110,46 +109,34 @@
* array. They're divided up into four groups of 16.
*/
static const uint8_t K[3][16] =
{
static const uint8_t K[3][16] = {
/* Round 1: skipped (since it is simply sequential). */
{ 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12 }, /* R2 */
{ 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2 }, /* R3 */
{ 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9 } /* R4 */
};
static const uint8_t S[4][4] =
{
{ 7, 12, 17, 22 }, /* Round 1 */
static const uint8_t S[4][4] = { { 7, 12, 17, 22 }, /* Round 1 */
{ 5, 9, 14, 20 }, /* Round 2 */
{ 4, 11, 16, 23 }, /* Round 3 */
{ 6, 10, 15, 21 } /* Round 4 */
};
static const uint32_t T[4][16] =
{
{ 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* Round 1 */
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 },
static const uint32_t T[4][16] = { { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, /* Round 1 */
0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193,
0xa679438e, 0x49b40821 },
{ 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, /* Round 2 */
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a },
0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8,
0x676f02d9, 0x8d2a4c8a },
{ 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, /* Round 3 */
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 },
0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5,
0x1fa27cf8, 0xc4ac5665 },
{ 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, /* Round 4 */
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 },
};
0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235,
0x2ad7d2bb, 0xeb86d391 }, };
/* -------------------------------------------------------------------------- **
* Macros:
@ -172,7 +159,6 @@ static const uint32_t T[4][16] =
#define STR2HEX(x) ((x >= 0x30) && (x <= 0x39)) ? x - 0x30 : toupper((int)x)-0x37
/* -------------------------------------------------------------------------- **
* Static Functions:
*/
@ -295,7 +281,6 @@ static void Permute( uint32_t ABCD[4], const unsigned char block[64] )
} /* Permute */
/* -------------------------------------------------------------------------- **
* Functions:
*/
@ -347,10 +332,7 @@ auth_md5Ctx *auth_md5InitCtx( auth_md5Ctx *ctx )
return (ctx);
} /* auth_md5InitCtx */
auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx,
const unsigned char *src,
const int len )
auth_md5Ctx *auth_md5SumCtx(auth_md5Ctx *ctx, const unsigned char *src, const int len)
/* ------------------------------------------------------------------------ **
* Build an MD5 Message Digest within the given context.
*
@ -392,7 +374,6 @@ auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx,
return (ctx);
} /* auth_md5SumCtx */
auth_md5Ctx *auth_md5CloseCtx(auth_md5Ctx *ctx, unsigned char *dst)
/* ------------------------------------------------------------------------ **
* Close an MD5 Message Digest context and generate the final MD5 sum.
@ -466,7 +447,6 @@ auth_md5Ctx *auth_md5CloseCtx( auth_md5Ctx *ctx, unsigned char *dst )
return (ctx);
} /* auth_md5CloseCtx */
unsigned char * MD5(unsigned char *dst, const unsigned char *src, const int len)
/* ------------------------------------------------------------------------ **
* Compute an MD5 message digest.
@ -510,8 +490,6 @@ unsigned char * MD5( unsigned char *dst, const unsigned char *src, const int len
return (dst); /* Makes life easy. */
} /* auth_md5Sum */
unsigned char * MD5fromFile(unsigned char *dst, const char *src)
/* ------------------------------------------------------------------------ **
* Compute an MD5 message digest.
@ -565,8 +543,7 @@ unsigned char * MD5fromFile( unsigned char *dst, const char *src )
if (filesize < 1048576) //1MB cache for files bigger than 1 MB
blksize = filesize;
else
blksize = 1048576;
else blksize = 1048576;
unsigned char * buffer = malloc(blksize);
@ -582,8 +559,7 @@ 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);
@ -593,7 +569,6 @@ unsigned char * MD5fromFile( unsigned char *dst, const char *src )
return (dst); /* Makes life easy. */
} /* auth_md5Sum */
const char * MD5ToString(const unsigned char * hash, char * dst)
{
char hexchar[3];
@ -630,5 +605,4 @@ unsigned char * StringToMD5( const char * hash, unsigned char * dst )
return dst;
}
/* ========================================================================== */

View File

@ -5,6 +5,7 @@
extern "C"
{
#endif
/* ========================================================================== **
*
* MD5.h
@ -93,7 +94,6 @@ extern "C"
unsigned char block[64];
} auth_md5Ctx;
/* -------------------------------------------------------------------------- **
* Functions:
*/
@ -127,10 +127,7 @@ extern "C"
* ------------------------------------------------------------------------ **
*/
auth_md5Ctx *auth_md5SumCtx( auth_md5Ctx *ctx,
const unsigned char *src,
const int len );
auth_md5Ctx *auth_md5SumCtx(auth_md5Ctx *ctx, const unsigned char *src, const int len);
/* ------------------------------------------------------------------------ **
* Build an MD5 Message Digest within the given context.
*
@ -147,7 +144,6 @@ extern "C"
* ------------------------------------------------------------------------ **
*/
auth_md5Ctx *auth_md5CloseCtx(auth_md5Ctx *ctx, unsigned char *dst);
/* ------------------------------------------------------------------------ **
* Close an MD5 Message Digest context and generate the final MD5 sum.
@ -168,7 +164,6 @@ extern "C"
* ------------------------------------------------------------------------ **
*/
unsigned char * MD5(unsigned char * hash, const unsigned char *src, const int len);
/* ------------------------------------------------------------------------ **
* Compute an MD5 message digest.

View File

@ -34,8 +34,7 @@ s32 dump_banner( const u8* discid, const char * dest )
s32 ret;
ret = __Disc_FindPartition(&offset);
if ( ret < 0 )
return ret;
if (ret < 0) return ret;
ret = WDVD_OpenPartition(offset);
@ -55,8 +54,7 @@ s32 dump_banner( const u8* discid, const char * dest )
}
ret = WDVD_Read(buffer, 0x20, 0x420);
if ( ret < 0 )
return ret;
if (ret < 0) return ret;
// Read fst.bin
void *fstbuffer = memalign(32, buffer[2] * 4);
@ -70,8 +68,7 @@ s32 dump_banner( const u8* discid, const char * dest )
}
ret = WDVD_Read(fstbuffer, buffer[2] * 4, buffer[1] * 4);
if ( ret < 0 )
return ret;
if (ret < 0) return ret;
free(buffer);
@ -106,8 +103,7 @@ s32 dump_banner( const u8* discid, const char * dest )
}
ret = WDVD_Read((void *) banner, fst[index].filelen, fst[index].fileoffset * 4);
if ( ret < 0 )
return ret;
if (ret < 0) return ret;
WDVD_Reset();
WDVD_ClosePartition();

View File

@ -70,8 +70,7 @@ GuiBanner::GuiBanner( const char *tplfilepath )
GuiBanner::GuiBanner(void *mem, u32 len, int w, int h)
{
if ( !mem || !len )
return;
if (!mem || !len) return;
memory = mem;
tplfilesize = len;
width = w;
@ -112,12 +111,12 @@ GuiBanner::~GuiBanner()
void GuiBanner::Draw()
{
LOCK( this );
if ( !filecheck || !this->IsVisible() )
return;
if (!filecheck || !this->IsVisible()) return;
float currScale = this->GetScale();
Menu_DrawTPLImg( this->GetLeft(), this->GetTop(), 0, width, height, &texObj, imageangle, widescreen ? currScale*0.80 : currScale, currScale, this->GetAlpha(), xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4 );
Menu_DrawTPLImg(this->GetLeft(), this->GetTop(), 0, width, height, &texObj, imageangle, widescreen ? currScale
* 0.80 : currScale, currScale, this->GetAlpha(), xx1, yy1, xx2, yy2, xx3, yy3, xx4, yy4);
this->UpdateEffects();
}

View File

@ -71,7 +71,6 @@ void md5( u8 *data, u32 len, u8 *hash )
MD5(hash, data, len);
}
typedef struct
{
u8 zeroes[0x40];
@ -241,9 +240,9 @@ static int write_imd5_lz77( u8* data, size_t size, char* outname )
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 )
return -7;
decompressed_data = decompress_lz77(data + sizeof(imd5_header_t), size - sizeof(imd5_header_t),
&decompressed_size);
if (decompressed_data == NULL) return -7;
write_file(decompressed_data, decompressed_size, outname);
//printf(", uncompressed %d bytes, md5 ok", decompressed_size);
@ -467,7 +466,8 @@ int extractbnrfile( const char * filepath, const char * destpath )
int unpackBin(const char * filename, const char * outdir)
{
FILE *fp = fopen( filename, "rb" );;
FILE *fp = fopen(filename, "rb");
;
if (fp)
{
subfoldercreate(outdir);
@ -556,8 +556,6 @@ int unpackBanner( const u8 *gameid, int what, const char *outdir )
error: fclose(fp);
}
ramdiskUnmount("BANNER");
error2:
if ( ret < 0 )
return ret;
error2: if (ret < 0) return ret;
return 1;
}

View File

@ -10,7 +10,6 @@
#include "language/gettext.h"
#include "bannersound.h"
struct IMD5Header
{
u32 fcc;
@ -81,15 +80,13 @@ inline u16 le16( u16 i )
static u8 *uncompressLZ77(const u8 *inBuf, u32 inLength, u32 &size)
{
u8 *buffer = NULL;
if ( inLength <= 0x8 || *( ( const u32 * )inBuf ) != 0x4C5A3737 /*"LZ77"*/ || inBuf[4] != 0x10 )
return NULL;
if (inLength <= 0x8 || *((const u32 *) inBuf) != 0x4C5A3737 /*"LZ77"*/|| inBuf[4] != 0x10) return NULL;
u32 uncSize = le32(((const u32 *) inBuf)[1] << 8);
const u8 *inBufEnd = inBuf + inLength;
inBuf += 8;
buffer = new (std::nothrow) u8[uncSize];
if ( !buffer )
return buffer;
if (!buffer) return buffer;
u8 *bufCur = buffer;
u8 *bufEnd = buffer + uncSize;
@ -105,8 +102,7 @@ static u8 *uncompressLZ77( const u8 *inBuf, u32 inLength, u32 &size )
const LZ77Info &info = *(const LZ77Info *) inBuf;
inBuf += sizeof(LZ77Info);
int length = info.length + 3;
if ( bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd )
return buffer;
if (bufCur - info.offset - 1 < buffer || bufCur + length > bufEnd) return buffer;
memcpy(bufCur, bufCur - info.offset - 1, length);
bufCur += length;
}
@ -125,8 +121,7 @@ static u8 *uncompressLZ77( const u8 *inBuf, u32 inLength, u32 &size )
const u8 *LoadBannerSound(const u8 *discid, u32 *size)
{
if ( !discid )
return NULL;
if (!discid) return NULL;
Disc_SetUSB(NULL);
wbfs_disc_t *disc = WBFS_OpenDisc((u8 *) discid);
@ -165,8 +160,7 @@ const u8 *LoadBannerSound( const u8 *discid, u32 *size )
fst = (const U8Entry *) (((const u8 *) bnrArcHdr) + bnrArcHdr->rootNodeOffset);
u32 i;
for (i = 1; i < fst[0].numEntries; ++i)
if ( fst[i].fileType == 0 && strcasecmp( u8Filename( fst, i ), "sound.bin" ) == 0 )
break;
if (fst[i].fileType == 0 && strcasecmp(u8Filename(fst, i), "sound.bin") == 0) break;
if (i >= fst[0].numEntries)
{
/* Not all games have a sound.bin and this message is annoying **/
@ -181,7 +175,8 @@ const u8 *LoadBannerSound( const u8 *discid, u32 *size )
free(opening_bnr);
return NULL;
}
const u8 *soundChunk = sound_bin + sizeof ( IMD5Header );;
const u8 *soundChunk = sound_bin + sizeof(IMD5Header);
;
u32 soundChunkSize = fst[i].fileLength - sizeof(IMD5Header);
if (*((u32*) soundChunk) == 0x4C5A3737 /*"LZ77"*/)

View File

@ -76,20 +76,20 @@ int CheatMenu( const char * gameID )
if (download == 1)
{
download = CodeDownload(gameID);
if ( download < 0 || c.openTxtfile( txtfilename ) != 1 )
break;
if (download < 0 || c.openTxtfile(txtfilename) != 1) break;
}
else
break;
else break;
case 1:
int cntcheats = c.getCnt();
customOptionList cheatslst(cntcheats);
GuiCustomOptionBrowser chtBrowser( 400, 280, &cheatslst, Settings.theme_path, "bg_options_settings.png", bg_options_settings_png, 1, 90 );
GuiCustomOptionBrowser chtBrowser(400, 280, &cheatslst, Settings.theme_path, "bg_options_settings.png",
bg_options_settings_png, 1, 90);
chtBrowser.SetPosition(0, 90);
chtBrowser.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
chtBrowser.SetClickable(true);
GuiText titleTxt( c.getGameName().c_str(), 28, ( GXColor ) {0, 0, 0, 255} );
GuiText titleTxt(c.getGameName().c_str(), 28, ( GXColor )
{ 0, 0, 0, 255});
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
titleTxt.SetMaxWidth(350, SCROLL_HORIZONTAL);
titleTxt.SetPosition(12, 40);

View File

@ -81,14 +81,12 @@ string GCTCheats::getCheatComment( int nr )
int GCTCheats::createGCT(int nr, const char * filename)
{
if ( nr == 0 )
return 0;
if (nr == 0) return 0;
ofstream filestr;
filestr.open(filename);
if ( filestr.fail() )
return 0;
if (filestr.fail()) return 0;
//Header and Footer
char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde };
@ -121,8 +119,7 @@ int GCTCheats::createGCT( const char * chtbuffer, const char * filename )
ofstream filestr;
filestr.open(filename);
if ( filestr.fail() )
return 0;
if (filestr.fail()) return 0;
//Header and Footer
char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde };
@ -154,14 +151,12 @@ int GCTCheats::createGCT( const char * chtbuffer, const char * filename )
int GCTCheats::createGCT(int nr[], int cnt, const char * filename)
{
if ( cnt == 0 )
return 0;
if (cnt == 0) return 0;
ofstream filestr;
filestr.open(filename);
if ( filestr.fail() )
return 0;
if (filestr.fail()) return 0;
//Header and Footer
char header[] = { 0x00, 0xd0, 0xc0, 0xde, 0x00, 0xd0, 0xc0, 0xde };
@ -201,8 +196,7 @@ int GCTCheats::openTxtfile( const char * filename )
string str;
filestr.open(filename);
if ( filestr.fail() )
return 0;
if (filestr.fail()) return 0;
filestr.seekg(0, ios_base::end);
int size = filestr.tellg();
@ -210,22 +204,18 @@ int GCTCheats::openTxtfile( const char * filename )
filestr.seekg(0, ios_base::beg);
getline(filestr, sGameID);
if ( sGameID[sGameID.length() - 1] == '\r' )
sGameID.erase( sGameID.length() - 1 );
if (sGameID[sGameID.length() - 1] == '\r') sGameID.erase(sGameID.length() - 1);
getline(filestr, sGameTitle);
if ( sGameTitle[sGameTitle.length() - 1] == '\r' )
sGameTitle.erase( sGameTitle.length() - 1 );
if (sGameTitle[sGameTitle.length() - 1] == '\r') sGameTitle.erase(sGameTitle.length() - 1);
getline(filestr, sCheatName[i]); // skip first line if file uses CRLF
if ( !sGameTitle[sGameTitle.length() - 1] == '\r' )
filestr.seekg( 0, ios_base::beg );
if (!sGameTitle[sGameTitle.length() - 1] == '\r') filestr.seekg(0, ios_base::beg);
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 );
if (sCheatName[i][sCheatName[i].length() - 1] == '\r') sCheatName[i].erase(sCheatName[i].length() - 1);
string cheatdata;
bool emptyline = false;
@ -233,8 +223,7 @@ int GCTCheats::openTxtfile( const char * filename )
do
{
getline(filestr, str);
if ( str[str.length() - 1] == '\r' )
str.erase( str.length() - 1 );
if (str[str.length() - 1] == '\r') str.erase(str.length() - 1);
if (str == "" || str[0] == '\r' || str[0] == '\n')
{
@ -260,8 +249,7 @@ int GCTCheats::openTxtfile( const char * filename )
}
if (filestr.eof()) break;
}
while ( !emptyline );
} while (!emptyline);
sCheats[i] = cheatdata;
i++;
@ -279,8 +267,10 @@ bool GCTCheats::IsCode( const std::string& str )
// 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] );
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))
{
return true;

View File

@ -124,8 +124,7 @@ void WBFSDevice_deInit()
int isInserted(const char *path)
{
if ( !strncmp( path, "USB:", 4 ) )
return 1;
if (!strncmp(path, "USB:", 4)) return 1;
return __io_sdhc.isInserted() || __io_wiisd.isInserted();
}

View File

@ -41,10 +41,8 @@ bool InitGecko()
char ascii(char s)
{
if ( s < 0x20 )
return '.';
if ( s > 0x7E )
return '.';
if (s < 0x20) return '.';
if (s > 0x7E) return '.';
return s;
}
@ -63,19 +61,15 @@ void hexdump( void *d, int len )
for (i = 0; i < 16; i++)
if ((i + off) >= len)
gprintf(" ");
else
gprintf( "%02x ", data[off+i] );
else gprintf("%02x ", data[off + i]);
gprintf(" ");
for (i = 0; i < 16; i++)
if ((i + off) >= len)
gprintf(" ");
else
gprintf( "%c", ascii( data[off+i] ) );
else gprintf("%c", ascii(data[off + i]));
gprintf("\n");
}
}
#endif /* NO_DEBUG */

View File

@ -1,5 +1,4 @@
#ifndef _GECKO_H_
#define _GECKO_H_
@ -21,8 +20,6 @@ extern "C"
#define hexdump( x, y )
#endif /* NO_DEBUG */
#ifdef __cplusplus
}
#endif

View File

@ -153,7 +153,6 @@ int BootHomebrew( const char * filepath )
#include "fatmounter.h"
#include "dolloader.h"
void *innetbuffer = NULL;
static u8 *homebrewbuffer = (u8 *) 0x92000000;
u32 homebrewsize = 0;
@ -166,8 +165,7 @@ int AllocHomebrewMemory( u32 filesize )
innetbuffer = malloc(filesize);
if ( !innetbuffer )
return -1;
if (!innetbuffer) return -1;
homebrewsize = filesize;
return 1;
@ -203,8 +201,7 @@ void FreeHomebrewBuffer()
static int SetupARGV(struct __argv * args)
{
if ( !args )
return -1;
if (!args) return -1;
bzero(args, sizeof(struct __argv));
args->argvMagic = ARGV_MAGIC;
@ -220,8 +217,7 @@ static int SetupARGV( struct __argv * args )
args->length = stringlength;
args->commandLine = (char*) malloc(args->length);
if ( !args->commandLine )
return -1;
if (!args->commandLine) return -1;
u32 argc = 0;
u32 position = 0;
@ -247,8 +243,7 @@ static int SetupARGV( struct __argv * args )
static int RunAppbooter()
{
if ( homebrewsize == 0 )
return -1;
if (homebrewsize == 0) return -1;
struct __argv args;
SetupARGV(&args);
@ -270,8 +265,7 @@ static int RunAppbooter()
{
if (Set_Stub_Split(0x00010001, "ULNR") < 0)
{
if ( !currentStub )
currentStub = 0x100000002ULL;
if (!currentStub) currentStub = 0x100000002ULL;
Set_Stub(currentStub);
}
@ -300,8 +294,7 @@ int BootHomebrew( char * filepath )
FILE *file = fopen(filepath, "rb");
if ( !file )
Sys_BackToLoader();
if (!file) Sys_BackToLoader();
fseek(file, 0, SEEK_END);
filesize = ftell(file);

View File

@ -51,8 +51,7 @@ int roundup( float number )
{
if (number == (int) number)
return (int) number;
else
return ( int ) ( number + 1 );
else return (int) (number + 1);
}
/****************************************************************************
@ -75,13 +74,10 @@ int MenuHomebrewBrowse()
enum
{
FADE,
LEFT,
RIGHT
FADE, LEFT, RIGHT
};
if ( IsNetworkInit() )
ResumeNetworkWait();
if (IsNetworkInit()) ResumeNetworkWait();
int slidedirection = FADE;
@ -118,7 +114,6 @@ int MenuHomebrewBrowse()
snprintf(imgPath, sizeof(imgPath), "%sChannel_btn.png", Settings.theme_path);
GuiImageData channelImgData(imgPath, Channel_btn_png);
GuiImage background(&bgData);
/*** Trigger Variables ***/
@ -137,7 +132,8 @@ int MenuHomebrewBrowse()
GuiTrigger trigPlus;
trigPlus.SetButtonOnlyTrigger(-1, WPAD_BUTTON_PLUS | WPAD_CLASSIC_BUTTON_PLUS, 0);
GuiText titleTxt( tr( "Homebrew Launcher" ), 28, ( GXColor ) {0, 0, 0, 255} );
GuiText titleTxt(tr( "Homebrew Launcher" ), 28, ( GXColor )
{ 0, 0, 0, 255});
titleTxt.SetAlignment(ALIGN_CENTRE, ALIGN_TOP);
titleTxt.SetPosition(0, 40);
@ -195,15 +191,18 @@ int MenuHomebrewBrowse()
GuiImage MainButton1Img(&MainButtonImgData);
GuiImage MainButton1ImgOver(&MainButtonImgOverData);
GuiText MainButton1Txt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255} );
GuiText MainButton1Txt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton1Txt.SetMaxWidth(MainButton1Img.GetWidth() - 150, DOTTED);
MainButton1Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton1Txt.SetPosition(148, -12);
GuiText MainButton1DescTxt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255} );
GuiText MainButton1DescTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton1DescTxt.SetMaxWidth(MainButton1Img.GetWidth() - 150, DOTTED);
MainButton1DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton1DescTxt.SetPosition(148, 15);
GuiText MainButton1DescOverTxt( MainButtonText, 18, ( GXColor ) { 0, 0, 0, 255} );
GuiText MainButton1DescOverTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton1DescOverTxt.SetMaxWidth(MainButton1Img.GetWidth() - 150, SCROLL_HORIZONTAL);
MainButton1DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton1DescOverTxt.SetPosition(148, 15);
@ -222,15 +221,18 @@ int MenuHomebrewBrowse()
GuiImage MainButton2Img(&MainButtonImgData);
GuiImage MainButton2ImgOver(&MainButtonImgOverData);
GuiText MainButton2Txt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255 } );
GuiText MainButton2Txt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton2Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton2Txt.SetPosition(148, -12);
MainButton2Txt.SetMaxWidth(MainButton2Img.GetWidth() - 150, DOTTED);
GuiText MainButton2DescTxt( MainButtonText, 18, ( GXColor ) { 0, 0, 0, 255} );
GuiText MainButton2DescTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton2DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton2DescTxt.SetPosition(148, 15);
MainButton2DescTxt.SetMaxWidth(MainButton2Img.GetWidth() - 150, DOTTED);
GuiText MainButton2DescOverTxt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255} );
GuiText MainButton2DescOverTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton2DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton2DescOverTxt.SetPosition(148, 15);
MainButton2DescOverTxt.SetMaxWidth(MainButton2Img.GetWidth() - 150, SCROLL_HORIZONTAL);
@ -249,15 +251,18 @@ int MenuHomebrewBrowse()
GuiImage MainButton3Img(&MainButtonImgData);
GuiImage MainButton3ImgOver(&MainButtonImgOverData);
GuiText MainButton3Txt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255} );
GuiText MainButton3Txt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton3Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton3Txt.SetPosition(148, -12);
MainButton3Txt.SetMaxWidth(MainButton3Img.GetWidth() - 150, DOTTED);
GuiText MainButton3DescTxt( MainButtonText, 18, ( GXColor ) { 0, 0, 0, 255} );
GuiText MainButton3DescTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton3DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton3DescTxt.SetPosition(148, 15);
MainButton3DescTxt.SetMaxWidth(MainButton3Img.GetWidth() - 150, DOTTED);
GuiText MainButton3DescOverTxt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255 } );
GuiText MainButton3DescOverTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton3DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton3DescOverTxt.SetPosition(148, 15);
MainButton3DescOverTxt.SetMaxWidth(MainButton3Img.GetWidth() - 150, SCROLL_HORIZONTAL);
@ -276,15 +281,18 @@ int MenuHomebrewBrowse()
GuiImage MainButton4Img(&MainButtonImgData);
GuiImage MainButton4ImgOver(&MainButtonImgOverData);
GuiText MainButton4Txt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255} );
GuiText MainButton4Txt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton4Txt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton4Txt.SetPosition(148, -12);
MainButton4Txt.SetMaxWidth(MainButton4Img.GetWidth() - 150, DOTTED);
GuiText MainButton4DescTxt( MainButtonText, 18, ( GXColor ) {0, 0, 0, 255} );
GuiText MainButton4DescTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton4DescTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton4DescTxt.SetPosition(148, 15);
MainButton4DescTxt.SetMaxWidth(MainButton4Img.GetWidth() - 150, DOTTED);
GuiText MainButton4DescOverTxt( MainButtonText, 18, ( GXColor ) { 0, 0, 0, 255} );
GuiText MainButton4DescOverTxt(MainButtonText, 18, ( GXColor )
{ 0, 0, 0, 255});
MainButton4DescOverTxt.SetAlignment(ALIGN_LEFT, ALIGN_MIDDLE);
MainButton4DescOverTxt.SetPosition(148, 15);
MainButton4DescOverTxt.SetMaxWidth(MainButton4Img.GetWidth() - 150, SCROLL_HORIZONTAL);
@ -328,7 +336,6 @@ int MenuHomebrewBrowse()
GuiTooltip * titleTT = NULL;
GuiWindow w(screenwidth, screenheight);
/*** XML Variables ***/
@ -358,7 +365,8 @@ int MenuHomebrewBrowse()
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 );
while (MainButton1.GetEffect() > 0)
usleep(50);
}
else if (slidedirection == LEFT)
{
@ -366,7 +374,8 @@ int MenuHomebrewBrowse()
MainButton2.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 60);
MainButton3.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 60);
MainButton4.SetEffect(EFFECT_SLIDE_RIGHT | EFFECT_SLIDE_OUT, 60);
while ( MainButton1.GetEffect() > 0 ) usleep( 50 );
while (MainButton1.GetEffect() > 0)
usleep(50);
}
HaltGui();
@ -403,20 +412,16 @@ int MenuHomebrewBrowse()
if (IconImg[0] != 0)
MainButton1.SetIcon(IconImg[0]);
else
MainButton1.SetIcon( NULL );
else MainButton1.SetIcon(NULL);
if (IconImg[1] != 0)
MainButton2.SetIcon(IconImg[1]);
else
MainButton2.SetIcon( NULL );
else MainButton2.SetIcon(NULL);
if (IconImg[2] != 0)
MainButton3.SetIcon(IconImg[2]);
else
MainButton3.SetIcon( NULL );
else MainButton3.SetIcon(NULL);
if (IconImg[3] != 0)
MainButton4.SetIcon(IconImg[3]);
else
MainButton4.SetIcon( NULL );
else MainButton4.SetIcon(NULL);
mainWindow->Append(&w);
w.RemoveAll();
@ -448,9 +453,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset ) ), "%s", HomebrewFiles.GetFilepath( fileoffset ) );
snprintf(temp, strlen(HomebrewFiles.GetFilepath(fileoffset)), "%s", HomebrewFiles.GetFilepath(
fileoffset));
shortpath = strrchr(temp, '/');
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset));
XMLInfo[0].SetName(MainButtonText);
MainButton1Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -472,9 +479,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 1 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 1 ) );
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 ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset + 1));
XMLInfo[1].SetName(MainButtonText);
MainButton2Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -496,9 +505,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 2 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 2 ) );
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 ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset + 2));
XMLInfo[2].SetName(MainButtonText);
MainButton3Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -520,9 +531,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 3 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 3 ) );
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 ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset + 3));
XMLInfo[3].SetName(MainButtonText);
MainButton4Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -548,9 +561,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset ) ), "%s", HomebrewFiles.GetFilepath( fileoffset ) );
snprintf(temp, strlen(HomebrewFiles.GetFilepath(fileoffset)), "%s", HomebrewFiles.GetFilepath(
fileoffset));
shortpath = strrchr(temp, '/');
snprintf( MainButtonText, sizeof( MainButtonText ), "%s/%s", shortpath, HomebrewFiles.GetFilename( fileoffset ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset));
XMLInfo[0].SetName(MainButtonText);
MainButton1Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -571,9 +586,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 1 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 1 ) );
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 ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset + 1));
XMLInfo[1].SetName(MainButtonText);
MainButton2Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -594,9 +611,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 2 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 2 ) );
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 ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset + 2));
XMLInfo[2].SetName(MainButtonText);
MainButton3Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -616,9 +635,11 @@ int MenuHomebrewBrowse()
}
else
{
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 3 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 3 ) );
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 ) );
snprintf(MainButtonText, sizeof(MainButtonText), "%s/%s", shortpath, HomebrewFiles.GetFilename(
fileoffset + 3));
XMLInfo[3].SetName(MainButtonText);
MainButton4Txt.SetText(MainButtonText);
snprintf(MainButtonText, sizeof(MainButtonText), " ");
@ -665,7 +686,8 @@ int MenuHomebrewBrowse()
ResumeGui();
while ( MainButton1.GetEffect() > 0 ) usleep( 50 );
while (MainButton1.GetEffect() > 0)
usleep(50);
while (!changed)
{
@ -687,16 +709,19 @@ int MenuHomebrewBrowse()
//get filesize
u64 filesize = HomebrewFiles.GetFilesize(fileoffset);
//write short filename
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset ) ), "%s", HomebrewFiles.GetFilepath( fileoffset ) );
snprintf(temp, strlen(HomebrewFiles.GetFilepath(fileoffset)), "%s", HomebrewFiles.GetFilepath(
fileoffset));
shortpath = strrchr(temp, '/');
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 );
int choice = HBCWindowPrompt(XMLInfo[0].GetName(), XMLInfo[0].GetCoder(), XMLInfo[0].GetVersion(),
XMLInfo[0].GetReleasedate(), XMLInfo[0].GetLongDescription(), iconpath, filesize);
if (choice == 1)
{
boothomebrew = 1;
menu = MENU_EXIT;
snprintf( Settings.selected_homebrew, sizeof( Settings.selected_homebrew ), "%s%s", HomebrewFiles.GetFilepath( fileoffset ), HomebrewFiles.GetFilename( fileoffset ) );
snprintf(Settings.selected_homebrew, sizeof(Settings.selected_homebrew), "%s%s",
HomebrewFiles.GetFilepath(fileoffset), HomebrewFiles.GetFilename(fileoffset));
break;
}
MainButton1.ResetState();
@ -717,16 +742,19 @@ int MenuHomebrewBrowse()
//get filesize
u64 filesize = HomebrewFiles.GetFilesize(fileoffset + 1);
//write short filename
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 1 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 1 ) );
snprintf(temp, strlen(HomebrewFiles.GetFilepath(fileoffset + 1)), "%s", HomebrewFiles.GetFilepath(
fileoffset + 1));
shortpath = strrchr(temp, '/');
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 );
int choice = HBCWindowPrompt(XMLInfo[1].GetName(), XMLInfo[1].GetCoder(), XMLInfo[1].GetVersion(),
XMLInfo[1].GetReleasedate(), XMLInfo[1].GetLongDescription(), iconpath, filesize);
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 ) );
snprintf(Settings.selected_homebrew, sizeof(Settings.selected_homebrew), "%s%s",
HomebrewFiles.GetFilepath(fileoffset + 1), HomebrewFiles.GetFilename(fileoffset + 1));
break;
}
MainButton2.ResetState();
@ -747,16 +775,19 @@ int MenuHomebrewBrowse()
//get filesize
u64 filesize = HomebrewFiles.GetFilesize(fileoffset + 2);
//write short filename
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 2 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 2 ) );
snprintf(temp, strlen(HomebrewFiles.GetFilepath(fileoffset + 2)), "%s", HomebrewFiles.GetFilepath(
fileoffset + 2));
shortpath = strrchr(temp, '/');
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 );
int choice = HBCWindowPrompt(XMLInfo[2].GetName(), XMLInfo[2].GetCoder(), XMLInfo[2].GetVersion(),
XMLInfo[2].GetReleasedate(), XMLInfo[2].GetLongDescription(), iconpath, filesize);
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 ) );
snprintf(Settings.selected_homebrew, sizeof(Settings.selected_homebrew), "%s%s",
HomebrewFiles.GetFilepath(fileoffset + 2), HomebrewFiles.GetFilename(fileoffset + 2));
break;
}
MainButton3.ResetState();
@ -777,16 +808,19 @@ int MenuHomebrewBrowse()
//get filesize
u64 filesize = HomebrewFiles.GetFilesize(fileoffset + 3);
//write short filename
snprintf( temp, strlen( HomebrewFiles.GetFilepath( fileoffset + 3 ) ), "%s", HomebrewFiles.GetFilepath( fileoffset + 3 ) );
snprintf(temp, strlen(HomebrewFiles.GetFilepath(fileoffset + 3)), "%s", HomebrewFiles.GetFilepath(
fileoffset + 3));
shortpath = strrchr(temp, '/');
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 );
int choice = HBCWindowPrompt(XMLInfo[3].GetName(), XMLInfo[3].GetCoder(), XMLInfo[3].GetVersion(),
XMLInfo[3].GetReleasedate(), XMLInfo[3].GetLongDescription(), iconpath, filesize);
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 ) );
snprintf(Settings.selected_homebrew, sizeof(Settings.selected_homebrew), "%s%s",
HomebrewFiles.GetFilepath(fileoffset + 3), HomebrewFiles.GetFilename(fileoffset + 3));
break;
}
MainButton4.ResetState();
@ -807,8 +841,7 @@ int MenuHomebrewBrowse()
{
pageToDisplay--;
/** Change direction of the flying buttons **/
if ( pageToDisplay < 1 )
pageToDisplay = pages;
if (pageToDisplay < 1) pageToDisplay = pages;
slidedirection = LEFT;
changed = true;
GoLeftBtn.ResetState();
@ -818,8 +851,7 @@ int MenuHomebrewBrowse()
{
pageToDisplay++;
/** Change direction of the flying buttons **/
if ( pageToDisplay > pages )
pageToDisplay = 1;
if (pageToDisplay > pages) pageToDisplay = 1;
slidedirection = RIGHT;
changed = true;
GoRightBtn.ResetState();
@ -860,8 +892,7 @@ int MenuHomebrewBrowse()
if (infilesize < MB_SIZE)
snprintf(filesizetxt, sizeof(filesizetxt), tr( "Incoming file %0.2fKB" ), infilesize / KB_SIZE);
else
snprintf( filesizetxt, sizeof( filesizetxt ), tr( "Incoming file %0.2fMB" ), infilesize / MB_SIZE );
else snprintf(filesizetxt, sizeof(filesizetxt), tr( "Incoming file %0.2fMB" ), infilesize / MB_SIZE);
snprintf(temp, sizeof(temp), tr( "Load file from: %s ?" ), GetIncommingIP());
@ -893,8 +924,7 @@ int MenuHomebrewBrowse()
if (infilesize - read < (u32) len)
len = infilesize - read;
else
len = NETWORKBLOCKSIZE;
else len = NETWORKBLOCKSIZE;
int result = network_read(ptr, len);
@ -992,8 +1022,8 @@ int MenuHomebrewBrowse()
}
else
{
if ( strstr( filename, ".dol" ) || strstr( filename, ".DOL" )
|| strstr( filename, ".elf" ) || strstr( filename, ".ELF" ) )
if (strstr(filename, ".dol") || strstr(filename, ".DOL") || strstr(filename, ".elf")
|| strstr(filename, ".ELF"))
{
boothomebrew = 2;
AddBootArgument(filename);
@ -1003,7 +1033,8 @@ int MenuHomebrewBrowse()
}
else if (strstr(filename, ".zip"))
{
WindowPrompt( tr( "Success:" ), tr( "Uploaded ZIP file installed to homebrew directory." ), tr( "OK" ) );
WindowPrompt(tr( "Success:" ),
tr( "Uploaded ZIP file installed to homebrew directory." ), tr( "OK" ));
CloseConnection();
}
else
@ -1027,7 +1058,6 @@ int MenuHomebrewBrowse()
w.SetState(STATE_DEFAULT);
channelBtn.ResetState();
}
if (IsNetworkInit())
@ -1046,7 +1076,8 @@ int MenuHomebrewBrowse()
}
w.SetEffect(EFFECT_FADE, -20);
while ( w.GetEffect() > 0 ) usleep( 50 );
while (w.GetEffect() > 0)
usleep(50);
HaltGui();
@ -1067,8 +1098,7 @@ int MenuHomebrewBrowse()
delete titleTT;
titleTT = NULL;
if ( IsNetworkInit() )
HaltNetworkThread();
if (IsNetworkInit()) HaltNetworkThread();
mainWindow->RemoveAll();
mainWindow->Append(bgImg);

View File

@ -65,8 +65,8 @@ bool HomebrewFiles::LoadPath( const char * folderpath )
temp[i] = filename[strlen(filename) - 4 + i];
}
if ( ( strncasecmp( temp, ".dol", 4 ) == 0 || strncasecmp( temp, ".elf", 4 ) == 0 )
&& filecount < MAXHOMEBREWS && filename[0] != '.' )
if ((strncasecmp(temp, ".dol", 4) == 0 || strncasecmp(temp, ".elf", 4) == 0) && filecount < MAXHOMEBREWS
&& filename[0] != '.')
{
FileInfo = (FileInfos *) realloc(FileInfo, (filecount + 1) * sizeof(FileInfos));
@ -98,24 +98,21 @@ char * HomebrewFiles::GetFilename( int ind )
{
if (ind > filecount)
return NULL;
else
return FileInfo[ind].FileName;
else return FileInfo[ind].FileName;
}
char * HomebrewFiles::GetFilepath(int ind)
{
if (ind > filecount)
return NULL;
else
return FileInfo[ind].FilePath;
else return FileInfo[ind].FilePath;
}
unsigned int HomebrewFiles::GetFilesize(int ind)
{
if (ind > filecount || !filecount || !FileInfo)
return NULL;
else
return FileInfo[ind].FileSize;
else return FileInfo[ind].FileSize;
}
int HomebrewFiles::GetFilecount()

View File

@ -11,6 +11,17 @@
#define ENTRIE_SIZE 8192
/* Initializes a new instance of the HomebrewXML class. */
HomebrewXML::HomebrewXML()
{
}
/* Finalizes an instance of the HomebrewXML class. */
HomebrewXML::~HomebrewXML()
{
}
/* qparam filename Filepath of the XML file */
int HomebrewXML::LoadHomebrewXMLData(const char* filename)
{
mxml_node_t *nodedataHB = NULL;
@ -19,18 +30,15 @@ int HomebrewXML::LoadHomebrewXMLData( const char* filename )
/* Load XML file */
FILE *filexml;
filexml = fopen(filename, "rb");
if ( !filexml )
return -1;
if (!filexml) return -1;
nodetreeHB = mxmlLoadFile(NULL, filexml, MXML_OPAQUE_CALLBACK);
fclose(filexml);
if ( nodetreeHB == NULL )
return -2;
if (nodetreeHB == NULL) return -2;
nodedataHB = mxmlFindElement(nodetreeHB, nodetreeHB, "app", NULL, NULL, MXML_DESCEND);
if ( nodedataHB == NULL )
return -5;
if (nodedataHB == NULL) return -5;
char * Entrie = new char[ENTRIE_SIZE];
@ -53,11 +61,11 @@ int HomebrewXML::LoadHomebrewXMLData( const char* filename )
int len = (strlen(Entrie) - 6); //length of the date string without the 200000 at the end
if (len == 8)
snprintf( Entrie, ENTRIE_SIZE, "%c%c/%c%c/%c%c%c%c", Entrie[4], Entrie[5], Entrie[6], Entrie[7], Entrie[0], Entrie[1], Entrie[2], Entrie[3] );
snprintf(Entrie, ENTRIE_SIZE, "%c%c/%c%c/%c%c%c%c", Entrie[4], Entrie[5], Entrie[6], Entrie[7], Entrie[0],
Entrie[1], Entrie[2], Entrie[3]);
else if (len == 6)
snprintf(Entrie, ENTRIE_SIZE, "%c%c/%c%c%c%c", Entrie[4], Entrie[5], Entrie[0], Entrie[1], Entrie[2], Entrie[3]);
else
snprintf( Entrie, ENTRIE_SIZE, "%s", Entrie );
else snprintf(Entrie, ENTRIE_SIZE, "%s", Entrie);
Releasedate = Entrie;
@ -68,3 +76,45 @@ int HomebrewXML::LoadHomebrewXMLData( const char* filename )
return 1;
}
/* Get name */
const char * HomebrewXML::GetName()
{
return Name.c_str();
}
/* Set Name */
void HomebrewXML::SetName(char * newName)
{
Name = newName;
}
/* Get coder */
const char * HomebrewXML::GetCoder()
{
return Coder.c_str();
}
/* Get version */
const char * HomebrewXML::GetVersion()
{
return Version.c_str();
}
/* Get releasedate */
const char * HomebrewXML::GetReleasedate()
{
return Releasedate.c_str();
}
/* Get shortdescription */
const char * HomebrewXML::GetShortDescription()
{
return ShortDescription.c_str();
}
/* Get longdescription */
const char * HomebrewXML::GetLongDescription()
{
return LongDescription.c_str();
}

View File

@ -10,27 +10,19 @@
class HomebrewXML
{
public:
//!Constructor
//!\param path Path for the xml file
HomebrewXML() { };
//!Destructor
~HomebrewXML() { };
//!\param filename Filepath of the XML file
HomebrewXML();
~HomebrewXML();
int LoadHomebrewXMLData(const char* filename);
//! Get name
const char * GetName() { return Name.c_str(); };
//! Get coder
const char * GetCoder() { return Coder.c_str(); };
//! Get version
const char * GetVersion() { return Version.c_str(); };
//! Get releasedate
const char * GetReleasedate() { return Releasedate.c_str(); };
//! Get shortdescription
const char * GetShortDescription() { return ShortDescription.c_str(); };
//! Get longdescription
const char * GetLongDescription() { return LongDescription.c_str(); };
//! Set Name
void SetName( char * newName ) { Name = newName; };
const char * GetName();
void SetName(char * newName);
const char * GetCoder();
const char * GetVersion();
const char * GetReleasedate();
const char * GetShortDescription();
const char * GetLongDescription();
protected:
std::string Name;
std::string Coder;

View File

@ -11,7 +11,6 @@ extern "C"
u32 load_dol(const void *dolstart, struct __argv *argv);
#ifdef __cplusplus
}
#endif

View File

@ -48,8 +48,7 @@ void UpdatePads()
userInput[i].pad.triggerL = PAD_TriggerL(i);
userInput[i].pad.triggerR = PAD_TriggerR(i);
if ( Settings.rumble == RumbleOn )
DoRumble( i );
if (Settings.rumble == RumbleOn) DoRumble(i);
}
}
@ -104,8 +103,7 @@ void DoRumble( int i )
}
else
{
if ( rumbleCount[i] )
rumbleCount[i]--;
if (rumbleCount[i]) rumbleCount[i]--;
WPAD_Rumble(i, 0); // rumble off
}
}
@ -151,7 +149,8 @@ s8 WPAD_Stick( u8 chan, u8 right, int axis )
}
/* calculate x/y value (angle need to be converted into radian) */
if ( mag > 1.0 ) mag = 1.0;
if (mag > 1.0)
mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;

View File

@ -46,7 +46,8 @@ int updateLanguageFiles()
{
char savepath[150];
char codeurl[200];
snprintf( codeurl, sizeof( codeurl ), "http://usbloader-gui.googlecode.com/svn/trunk/Languages/%s", languageFiles[j] );
snprintf(codeurl, sizeof(codeurl), "http://usbloader-gui.googlecode.com/svn/trunk/Languages/%s",
languageFiles[j]);
snprintf(savepath, sizeof(savepath), "%s%s", Settings.languagefiles_path, languageFiles[j]);
struct block file = downloadfile(codeurl);
@ -75,5 +76,3 @@ int updateLanguageFiles()
return done;
}

View File

@ -12,14 +12,12 @@ typedef struct _MSG
} MSG;
static MSG *baseMSG = 0;
#define HASHWORDBITS 32
/* Defines the so called `hashpjw' function by P.J. Weinberger
[see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools,
1986, 1987 Bell Telephone Laboratories, Inc.] */
static inline u32
hash_string ( const char *str_param )
static inline u32 hash_string(const char *str_param)
{
u32 hval, g;
const char *str = str_param;
@ -53,8 +51,7 @@ expand_escape ( const char *str )
while (cp[0] != '\0' && cp[0] != '\\')
*rp++ = *cp++;
if ( cp[0] == '\0' )
goto terminate;
if (cp[0] == '\0') goto terminate;
do
{
@ -129,12 +126,10 @@ expand_escape ( const char *str )
while (cp[0] != '\0' && cp[0] != '\\')
*rp++ = *cp++;
}
while ( cp[0] != '\0' );
} while (cp[0] != '\0');
/* Terminate string. */
terminate:
*rp = '\0';
terminate: *rp = '\0';
return retval;
}
@ -143,8 +138,7 @@ static MSG *findMSG( u32 id )
MSG *msg;
for (msg = baseMSG; msg; msg = msg->next)
{
if ( msg->id == id )
return msg;
if (msg->id == id) return msg;
}
return NULL;
}
@ -184,7 +178,6 @@ void gettextCleanUp( void )
}
}
bool gettextLoadLanguage(const char* langFile)
{
FILE *f;
@ -193,8 +186,7 @@ bool gettextLoadLanguage( const char* langFile )
gettextCleanUp();
f = fopen(langFile, "r");
if ( !f )
return false;
if (!f) return false;
while (fgets(line, sizeof(line), f))
{
@ -221,8 +213,7 @@ bool gettextLoadLanguage( const char* langFile )
{
char *msgstr, *end;
if ( lastID == NULL )
continue;
if (lastID == NULL) continue;
msgstr = &line[8];
end = strrchr(msgstr, '"');
@ -247,5 +238,3 @@ const char *gettext( const char *msgid )
return msgid;
}

View File

@ -6,7 +6,6 @@ extern "C"
{
#endif
bool gettextLoadLanguage(const char* langFile);
void gettextCleanUp(void);
/*
@ -17,7 +16,6 @@ extern "C"
#define tr(s) gettext(s)
#define trNOOP(s) (s)
#ifdef __cplusplus
}
#endif

View File

@ -81,7 +81,8 @@ Precondition: offset + size <= BYTES_PER_READ
*/
bool _FAT_cache_writePartialSector(CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size);
bool _FAT_cache_writeLittleEndianValue ( CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int num_bytes );
bool _FAT_cache_writeLittleEndianValue(CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset,
int num_bytes);
/*
Write data to a sector in the cache, zeroing the sector first
@ -91,7 +92,8 @@ offset is the position to start writing to
size is the amount of data to write
Precondition: offset + size <= BYTES_PER_READ
*/
bool _FAT_cache_eraseWritePartialSector ( CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size );
bool _FAT_cache_eraseWritePartialSector(CACHE* cache, const void* buffer, sec_t sector, unsigned int offset,
size_t size);
/*
Read several sectors from the cache
@ -126,9 +128,9 @@ Clear out the contents of the cache without writing any dirty sectors first
*/
void _FAT_cache_invalidate(CACHE* cache);
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);
void _FAT_cache_destructor(CACHE* cache);
#endif // _CACHE_H

View File

@ -34,7 +34,6 @@
#include <stddef.h>
#include <stdint.h>
// Platform specific includes
#include <gctypes.h>
#include <ogc/disc_io.h>

View File

@ -72,7 +72,8 @@ enum LFN_offset
LFN_offset_char11 = 0x1C,
LFN_offset_char12 = 0x1E
};
static const int LFN_offset_table[13] = {0x01, 0x03, 0x05, 0x07, 0x09, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1C, 0x1E};
static const int LFN_offset_table[13] =
{ 0x01, 0x03, 0x05, 0x07, 0x09, 0x0E, 0x10, 0x12, 0x14, 0x16, 0x18, 0x1C, 0x1E };
#define LFN_END 0x40
#define LFN_DEL 0x80
@ -222,13 +223,11 @@ static int _FAT_directory_mbsncasecmp ( const char* s1, const char* s2, size_t l
break;
}
len1 -= b1;
}
while ( len1 > 0 && towlower( wc1 ) == towlower( wc2 ) && wc1 != 0 );
} while (len1 > 0 && towlower(wc1) == towlower(wc2) && wc1 != 0);
return towlower(wc1) - towlower(wc2);
}
static bool _FAT_directory_entryGetAlias(const u8* entryData, char* destName)
{
int i = 0;
@ -286,7 +285,8 @@ uint32_t _FAT_directory_entryGetCluster ( PARTITION* partition, const uint8_t* e
}
}
static bool _FAT_directory_incrementDirEntryPosition ( PARTITION* partition, DIR_ENTRY_POSITION* entryPosition, bool extendDirectory )
static bool _FAT_directory_incrementDirEntryPosition(PARTITION* partition, DIR_ENTRY_POSITION* entryPosition,
bool extendDirectory)
{
DIR_ENTRY_POSITION position = *entryPosition;
uint32_t tempCluster;
@ -321,7 +321,8 @@ static bool _FAT_directory_incrementDirEntryPosition ( PARTITION* partition, DIR
}
position.cluster = tempCluster;
}
else if ( ( position.cluster == FAT16_ROOT_DIR_CLUSTER ) && ( position.sector == ( partition->dataStart - partition->rootDirStart ) ) )
else if ((position.cluster == FAT16_ROOT_DIR_CLUSTER) && (position.sector == (partition->dataStart
- partition->rootDirStart)))
{
return false; // Got to end of root directory, can't extend it
}
@ -366,9 +367,8 @@ bool _FAT_directory_getNextEntry ( PARTITION* partition, DIR_ENTRY* entry )
notFound = true;
}
_FAT_cache_readPartialSector ( partition->cache, entryData,
_FAT_fat_clusterToSector( partition, entryEnd.cluster ) + entryEnd.sector,
entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_readPartialSector(partition->cache, entryData, _FAT_fat_clusterToSector(partition, entryEnd.cluster)
+ entryEnd.sector, entryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
if (entryData[DIR_ENTRY_attributes] == ATTRIB_LFN)
{
@ -389,7 +389,8 @@ bool _FAT_directory_getNextEntry ( PARTITION* partition, DIR_ENTRY* entry )
}
lfn[lfnPos] = '\0'; // Set end of lfn to null character
lfnChkSum = entryData[LFN_offset_checkSum];
} if ( lfnChkSum != entryData[LFN_offset_checkSum] )
}
if (lfnChkSum != entryData[LFN_offset_checkSum])
{
lfnExists = false;
}
@ -415,7 +416,8 @@ bool _FAT_directory_getNextEntry ( PARTITION* partition, DIR_ENTRY* entry )
{
notFound = true;
}
else if ( ( entryData[0] != DIR_ENTRY_FREE ) && ( entryData[0] > 0x20 ) && !( entryData[DIR_ENTRY_attributes] & ATTRIB_VOL ) )
else if ((entryData[0] != DIR_ENTRY_FREE) && (entryData[0] > 0x20) && !(entryData[DIR_ENTRY_attributes]
& ATTRIB_VOL))
{
if (lfnExists)
{
@ -513,17 +515,14 @@ bool _FAT_directory_entryFromPosition ( PARTITION* partition, DIR_ENTRY* entry )
memset(entry->filename, '\0', MAX_FILENAME_LENGTH);
// Create an empty directory entry to overwrite the old ones with
for ( entryStillValid = true, finished = false;
entryStillValid && !finished;
entryStillValid = _FAT_directory_incrementDirEntryPosition ( partition, &entryStart, false ) )
for (entryStillValid = true, finished = false; entryStillValid && !finished; entryStillValid
= _FAT_directory_incrementDirEntryPosition(partition, &entryStart, false))
{
_FAT_cache_readPartialSector ( partition->cache, entryData,
_FAT_fat_clusterToSector( partition, entryStart.cluster ) + entryStart.sector,
entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_readPartialSector(partition->cache, entryData, _FAT_fat_clusterToSector(partition,
entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
if ( ( entryStart.cluster == entryEnd.cluster )
&& ( entryStart.sector == entryEnd.sector )
&& ( entryStart.offset == entryEnd.offset ) )
if ((entryStart.cluster == entryEnd.cluster) && (entryStart.sector == entryEnd.sector) && (entryStart.offset
== entryEnd.offset))
{
// Copy the entry data and stop, since this is the last section of the directory entry
memcpy(entry->entryData, entryData, DIR_ENTRY_DATA_SIZE);
@ -549,9 +548,8 @@ bool _FAT_directory_entryFromPosition ( PARTITION* partition, DIR_ENTRY* entry )
return false;
}
if ( ( entryStart.cluster == entryEnd.cluster )
&& ( entryStart.sector == entryEnd.sector )
&& ( entryStart.offset == entryEnd.offset ) )
if ((entryStart.cluster == entryEnd.cluster) && (entryStart.sector == entryEnd.sector) && (entryStart.offset
== entryEnd.offset))
{
// Since the entry doesn't have a long file name, extract the short filename
if (!_FAT_directory_entryGetAlias(entry->entryData, entry->filename))
@ -571,8 +569,6 @@ bool _FAT_directory_entryFromPosition ( PARTITION* partition, DIR_ENTRY* entry )
return true;
}
bool _FAT_directory_entryFromPath(PARTITION* partition, DIR_ENTRY* entry, const char* path, const char* pathEnd)
{
size_t dirnameLength;
@ -649,16 +645,16 @@ bool _FAT_directory_entryFromPath ( PARTITION* partition, DIR_ENTRY* entry, cons
while (foundFile && !found && !notFound) // It hasn't already found the file
{
// Check if the filename matches
if ( ( dirnameLength == strnlen( entry->filename, MAX_FILENAME_LENGTH ) )
&& ( _FAT_directory_mbsncasecmp( pathPosition, entry->filename, dirnameLength ) == 0 ) )
if ((dirnameLength == strnlen(entry->filename, MAX_FILENAME_LENGTH)) && (_FAT_directory_mbsncasecmp(
pathPosition, entry->filename, dirnameLength) == 0))
{
found = true;
}
// Check if the alias matches
_FAT_directory_entryGetAlias(entry->entryData, alias);
if ( ( dirnameLength == strnlen( alias, MAX_ALIAS_LENGTH ) )
&& ( strncasecmp( pathPosition, alias, dirnameLength ) == 0 ) )
if ((dirnameLength == strnlen(alias, MAX_ALIAS_LENGTH)) && (strncasecmp(pathPosition, alias, dirnameLength)
== 0))
{
found = true;
}
@ -709,8 +705,8 @@ bool _FAT_directory_entryFromPath ( PARTITION* partition, DIR_ENTRY* entry, cons
if (found && !notFound)
{
if ( partition->filesysType == FS_FAT32 && ( entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR ) &&
_FAT_directory_entryGetCluster ( partition, entry->entryData ) == CLUSTER_ROOT )
if (partition->filesysType == FS_FAT32 && (entry->entryData[DIR_ENTRY_attributes] & ATTRIB_DIR)
&& _FAT_directory_entryGetCluster(partition, entry->entryData) == CLUSTER_ROOT)
{
// On FAT32 it should specify an actual cluster for the root entry,
// not cluster 0 as on FAT16
@ -733,14 +729,16 @@ bool _FAT_directory_removeEntry ( PARTITION* partition, DIR_ENTRY* entry )
uint8_t entryData[DIR_ENTRY_DATA_SIZE];
// Create an empty directory entry to overwrite the old ones with
for ( entryStillValid = true, finished = false;
entryStillValid && !finished;
entryStillValid = _FAT_directory_incrementDirEntryPosition ( partition, &entryStart, false ) )
for (entryStillValid = true, finished = false; entryStillValid && !finished; entryStillValid
= _FAT_directory_incrementDirEntryPosition(partition, &entryStart, false))
{
_FAT_cache_readPartialSector ( partition->cache, entryData, _FAT_fat_clusterToSector( partition, entryStart.cluster ) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_readPartialSector(partition->cache, entryData, _FAT_fat_clusterToSector(partition,
entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
entryData[0] = DIR_ENTRY_FREE;
_FAT_cache_writePartialSector ( partition->cache, entryData, _FAT_fat_clusterToSector( partition, entryStart.cluster ) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
if ( ( entryStart.cluster == entryEnd.cluster ) && ( entryStart.sector == entryEnd.sector ) && ( entryStart.offset == entryEnd.offset ) )
_FAT_cache_writePartialSector(partition->cache, entryData, _FAT_fat_clusterToSector(partition,
entryStart.cluster) + entryStart.sector, entryStart.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
if ((entryStart.cluster == entryEnd.cluster) && (entryStart.sector == entryEnd.sector) && (entryStart.offset
== entryEnd.offset))
{
finished = true;
}
@ -775,9 +773,8 @@ static bool _FAT_directory_findEntryGap ( PARTITION* partition, DIR_ENTRY* entry
while (entryStillValid && !endOfDirectory && (dirEntryRemain > 0))
{
_FAT_cache_readPartialSector ( partition->cache, entryData,
_FAT_fat_clusterToSector( partition, gapEnd.cluster ) + gapEnd.sector,
gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_readPartialSector(partition->cache, entryData, _FAT_fat_clusterToSector(partition, gapEnd.cluster)
+ gapEnd.sector, gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
if (entryData[0] == DIR_ENTRY_LAST)
{
gapStart = gapEnd;
@ -824,9 +821,8 @@ static bool _FAT_directory_findEntryGap ( PARTITION* partition, DIR_ENTRY* entry
entryStillValid = _FAT_directory_incrementDirEntryPosition(partition, &gapEnd, true);
--dirEntryRemain;
// Fill the entry with blanks
_FAT_cache_writePartialSector ( partition->cache, entryData,
_FAT_fat_clusterToSector( partition, gapEnd.cluster ) + gapEnd.sector,
gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_writePartialSector(partition->cache, entryData, _FAT_fat_clusterToSector(partition,
gapEnd.cluster) + gapEnd.sector, gapEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE);
}
if (!entryStillValid)
{
@ -861,8 +857,8 @@ static bool _FAT_directory_entryExists ( PARTITION* partition, const char* name,
while (foundFile) // It hasn't already found the file
{
// Check if the filename matches
if ( ( dirnameLength == strnlen( tempEntry.filename, MAX_FILENAME_LENGTH ) )
&& ( _FAT_directory_mbsncasecmp( name, tempEntry.filename, dirnameLength ) == 0 ) )
if ((dirnameLength == strnlen(tempEntry.filename, MAX_FILENAME_LENGTH)) && (_FAT_directory_mbsncasecmp(name,
tempEntry.filename, dirnameLength) == 0))
{
return true;
}
@ -1045,7 +1041,8 @@ bool _FAT_directory_addEntry ( PARTITION* partition, DIR_ENTRY* entry, uint32_t
entry->filename[i] = '\0';
}
// Remove leading spaces
for ( i = 0; ( i < ( int )strlen ( entry->filename ) ) && ( entry->filename[i] == ' ' ); ++i ) ;
for (i = 0; (i < (int) strlen(entry->filename)) && (entry->filename[i] == ' '); ++i)
;
if (i > 0)
{
memmove(entry->filename, entry->filename + i, strlen(entry->filename + i));
@ -1097,13 +1094,14 @@ bool _FAT_directory_addEntry ( PARTITION* partition, DIR_ENTRY* entry, uint32_t
// Generate full alias for all cases except when the alias is simply an upper case version of the LFN
// and there isn't already a file with that name
if ( strncasecmp ( alias, entry->filename, MAX_ALIAS_LENGTH ) != 0 ||
_FAT_directory_entryExists ( partition, alias, dirCluster ) )
if (strncasecmp(alias, entry->filename, MAX_ALIAS_LENGTH) != 0 || _FAT_directory_entryExists(partition,
alias, dirCluster))
{
// expand primary part to 8 characters long by padding the end with underscores
i = MAX_ALIAS_PRI_LENGTH - 1;
// Move extension to last 3 characters
while ( alias[i] != '.' && i > 0 ) i--;
while (alias[i] != '.' && i > 0)
i--;
if (i > 0)
{
j = MAX_ALIAS_LENGTH - MAX_ALIAS_EXT_LENGTH - 2; // 1 char for '.', one for NUL, 3 for extension
@ -1187,8 +1185,8 @@ bool _FAT_directory_addEntry ( PARTITION* partition, DIR_ENTRY* entry, uint32_t
ucs2_t lfn[MAX_LFN_LENGTH] = { 0 };
_FAT_directory_mbstoucs2(lfn, entry->filename, MAX_LFN_LENGTH);
for ( entryStillValid = true, i = entrySize; entryStillValid && i > 0;
entryStillValid = _FAT_directory_incrementDirEntryPosition ( partition, &curEntryPos, false ), -- i )
for (entryStillValid = true, i = entrySize; entryStillValid && i > 0; entryStillValid
= _FAT_directory_incrementDirEntryPosition(partition, &curEntryPos, false), --i)
{
if (i > 1)
{
@ -1217,12 +1215,16 @@ bool _FAT_directory_addEntry ( PARTITION* partition, DIR_ENTRY* entry, uint32_t
lfnEntry[LFN_offset_flag] = ATTRIB_LFN;
lfnEntry[LFN_offset_reserved1] = 0;
u16_to_u8array(lfnEntry, LFN_offset_reserved2, 0);
_FAT_cache_writePartialSector ( partition->cache, lfnEntry, _FAT_fat_clusterToSector( partition, curEntryPos.cluster ) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_writePartialSector(partition->cache, lfnEntry, _FAT_fat_clusterToSector(partition,
curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE,
DIR_ENTRY_DATA_SIZE);
}
else
{
// Alias & file data
_FAT_cache_writePartialSector ( partition->cache, entry->entryData, _FAT_fat_clusterToSector( partition, curEntryPos.cluster ) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_writePartialSector(partition->cache, entry->entryData, _FAT_fat_clusterToSector(partition,
curEntryPos.cluster) + curEntryPos.sector, curEntryPos.offset * DIR_ENTRY_DATA_SIZE,
DIR_ENTRY_DATA_SIZE);
}
}
}
@ -1255,28 +1257,20 @@ void _FAT_directory_entryStat ( PARTITION* partition, DIR_ENTRY* entry, struct s
// Some of the values are faked for the sake of compatibility
st->st_dev = _FAT_disc_hostType(partition->disc); // The device is the 32bit ioType value
st->st_ino = (ino_t) (_FAT_directory_entryGetCluster(partition, entry->entryData)); // The file serial number is the start cluster
st->st_mode = ( _FAT_directory_isDirectory( entry ) ? S_IFDIR : S_IFREG ) |
( S_IRUSR | S_IRGRP | S_IROTH ) |
( _FAT_directory_isWritable ( entry ) ? ( S_IWUSR | S_IWGRP | S_IWOTH ) : 0 ); // Mode bits based on dirEntry ATTRIB byte
st->st_mode = (_FAT_directory_isDirectory(entry) ? S_IFDIR : S_IFREG) | (S_IRUSR | S_IRGRP | S_IROTH)
| (_FAT_directory_isWritable(entry) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0); // Mode bits based on dirEntry ATTRIB byte
st->st_nlink = 1; // Always one hard link on a FAT file
st->st_uid = 1; // Faked for FAT
st->st_gid = 2; // Faked for FAT
st->st_rdev = st->st_dev;
st->st_size = u8array_to_u32(entry->entryData, DIR_ENTRY_fileSize); // File size
st->st_atime = _FAT_filetime_to_time_t (
0,
u8array_to_u16 ( entry->entryData, DIR_ENTRY_aDate )
);
st->st_atime = _FAT_filetime_to_time_t(0, u8array_to_u16(entry->entryData, DIR_ENTRY_aDate));
st->st_spare1 = 0;
st->st_mtime = _FAT_filetime_to_time_t (
u8array_to_u16 ( entry->entryData, DIR_ENTRY_mTime ),
u8array_to_u16 ( entry->entryData, DIR_ENTRY_mDate )
);
st->st_mtime = _FAT_filetime_to_time_t(u8array_to_u16(entry->entryData, DIR_ENTRY_mTime), u8array_to_u16(
entry->entryData, DIR_ENTRY_mDate));
st->st_spare2 = 0;
st->st_ctime = _FAT_filetime_to_time_t (
u8array_to_u16 ( entry->entryData, DIR_ENTRY_cTime ),
u8array_to_u16 ( entry->entryData, DIR_ENTRY_cDate )
);
st->st_ctime = _FAT_filetime_to_time_t(u8array_to_u16(entry->entryData, DIR_ENTRY_cTime), u8array_to_u16(
entry->entryData, DIR_ENTRY_cDate));
st->st_spare3 = 0;
st->st_blksize = BYTES_PER_READ; // Prefered file I/O block size
st->st_blocks = (st->st_size + BYTES_PER_READ - 1) / BYTES_PER_READ; // File size in blocks

View File

@ -56,8 +56,10 @@
#define ATTRIB_SYS 0x04 // System
#define ATTRIB_HID 0x02 // Hidden
#define ATTRIB_RO 0x01 // Read only
typedef enum {FT_DIRECTORY, FT_FILE} FILE_TYPE;
typedef enum
{
FT_DIRECTORY, FT_FILE
} FILE_TYPE;
typedef struct
{
@ -107,8 +109,8 @@ static inline bool _FAT_directory_isWritable ( 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' ) ) );
return ((entry->filename[0] == '.') && ((entry->filename[1] == '\0') || ((entry->filename[1] == '.')
&& entry->filename[2] == '\0')));
}
/*

View File

@ -70,7 +70,8 @@ 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);
}

View File

@ -61,12 +61,6 @@ static const DISC_INTERFACE* get_io_gcsdb ( void )
return &__io_gcsdb;
}
const INTERFACE_ID _FAT_disc_interfaces[] =
{
{"sd", get_io_wiisd},
{"usb", get_io_usbstorage},
{"carda", get_io_gcsda},
{"cardb", get_io_gcsdb},
{NULL, NULL}
};
const INTERFACE_ID _FAT_disc_interfaces[] = { { "sd", get_io_wiisd }, { "usb", get_io_usbstorage }, { "carda",
get_io_gcsda }, { "cardb", get_io_gcsdb }, { NULL, NULL } };

View File

@ -70,7 +70,8 @@ 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);
}

View File

@ -26,7 +26,6 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LIBFAT_H
#define _LIBFAT_H
@ -67,7 +66,8 @@ extern "C"
cacheSize specifies the number of pages to allocate for the cache.
This will not startup the disc, so you need to call interface->startup(); first.
*/
extern bool fatMount ( const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize, uint32_t SectorsPerPage );
extern bool fatMount(const char* name, const DISC_INTERFACE* interface, sec_t startSector, uint32_t cacheSize,
uint32_t SectorsPerPage);
/*
Unmount the partition specified by name.
If there are open files, it will attempt to synchronise them to disc.

View File

@ -46,7 +46,8 @@
#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;
@ -73,7 +74,6 @@ CACHE* _FAT_cache_constructor ( unsigned int numberOfPages, unsigned int sectors
cache->numberOfPages = numberOfPages;
cache->sectorsPerPage = sectorsPerPage;
cacheEntries = (CACHE_ENTRY*) _FAT_mem_allocate(sizeof(CACHE_ENTRY) * numberOfPages);
if (cacheEntries == NULL)
{
@ -110,7 +110,6 @@ void _FAT_cache_destructor ( CACHE* cache )
_FAT_mem_free(cache);
}
static u32 accessCounter = 0;
static u32 accessTime()
@ -119,7 +118,6 @@ static u32 accessTime()
return accessCounter;
}
static CACHE_ENTRY* _FAT_cache_getPage(CACHE *cache, sec_t sector)
{
unsigned int i;
@ -149,7 +147,8 @@ static CACHE_ENTRY* _FAT_cache_getPage( CACHE *cache, sec_t sector )
if (foundFree == false && cacheEntries[oldUsed].dirty == true)
{
if ( !_FAT_disc_writeSectors( cache->disc, cacheEntries[oldUsed].sector, cacheEntries[oldUsed].count, cacheEntries[oldUsed].cache ) ) return NULL;
if (!_FAT_disc_writeSectors(cache->disc, cacheEntries[oldUsed].sector, cacheEntries[oldUsed].count,
cacheEntries[oldUsed].cache)) return NULL;
cacheEntries[oldUsed].dirty = false;
}
@ -218,10 +217,17 @@ bool _FAT_cache_readLittleEndianValue ( CACHE* cache, uint32_t *value, sec_t sec
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;
default: return false;
case 1:
*value = buf[0];
break;
case 2:
*value = u8array_to_u16(buf, 0);
break;
case 4:
*value = u8array_to_u32(buf, 0);
break;
default:
return false;
}
return true;
}
@ -252,10 +258,17 @@ bool _FAT_cache_writeLittleEndianValue ( CACHE* cache, const uint32_t value, sec
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;
default: return false;
case 1:
buf[0] = value;
break;
case 2:
u16_to_u8array(buf, 0, value);
break;
case 4:
u32_to_u8array(buf, 0, value);
break;
default:
return false;
}
return _FAT_cache_writePartialSector(cache, buf, sector, offset, size);
@ -264,7 +277,8 @@ bool _FAT_cache_writeLittleEndianValue ( CACHE* cache, const uint32_t value, sec
/*
Writes some data to a cache page, zeroing out the page first
*/
bool _FAT_cache_eraseWritePartialSector ( CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size )
bool _FAT_cache_eraseWritePartialSector(CACHE* cache, const void* buffer, sec_t sector, unsigned int offset,
size_t size)
{
sec_t sec;
CACHE_ENTRY *entry;
@ -282,7 +296,6 @@ bool _FAT_cache_eraseWritePartialSector ( CACHE* cache, const void* buffer, sec_
return true;
}
static CACHE_ENTRY* _FAT_cache_findPage(CACHE *cache, sec_t sector, sec_t count)
{
@ -376,7 +389,8 @@ bool _FAT_cache_flush ( CACHE* cache )
{
if (cache->cacheEntries[i].dirty)
{
if ( !_FAT_disc_writeSectors ( cache->disc, cache->cacheEntries[i].sector, cache->cacheEntries[i].count, cache->cacheEntries[i].cache ) )
if (!_FAT_disc_writeSectors(cache->disc, cache->cacheEntries[i].sector, cache->cacheEntries[i].count,
cache->cacheEntries[i].cache))
{
return false;
}

View File

@ -81,7 +81,8 @@ Precondition: offset + size <= BYTES_PER_READ
*/
bool _FAT_cache_writePartialSector(CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size);
bool _FAT_cache_writeLittleEndianValue ( CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset, int num_bytes );
bool _FAT_cache_writeLittleEndianValue(CACHE* cache, const uint32_t value, sec_t sector, unsigned int offset,
int num_bytes);
/*
Write data to a sector in the cache, zeroing the sector first
@ -91,7 +92,8 @@ offset is the position to start writing to
size is the amount of data to write
Precondition: offset + size <= BYTES_PER_READ
*/
bool _FAT_cache_eraseWritePartialSector ( CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size );
bool _FAT_cache_eraseWritePartialSector(CACHE* cache, const void* buffer, sec_t sector, unsigned int offset,
size_t size);
/*
Read several sectors from the cache
@ -126,9 +128,9 @@ Clear out the contents of the cache without writing any dirty sectors first
*/
void _FAT_cache_invalidate(CACHE* cache);
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);
void _FAT_cache_destructor(CACHE* cache);
#endif // _CACHE_H

View File

@ -44,7 +44,6 @@
#include "filetime.h"
#include "lock.h"
int _FAT_stat_r(struct _reent *r, const char *path, struct stat *st)
{
PARTITION* partition = NULL;
@ -139,7 +138,6 @@ int _FAT_unlink_r ( struct _reent *r, const char *path )
cluster = _FAT_directory_entryGetCluster(partition, dirEntry.entryData);
// If this is a directory, make sure it is empty
if (_FAT_directory_isDirectory(&dirEntry))
{
@ -319,8 +317,8 @@ int _FAT_rename_r ( struct _reent *r, const char *oldName, const char *newName )
{
// 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 ) )
if (!_FAT_directory_entryFromPath(partition, &newDirEntry, newName, pathEnd) || !_FAT_directory_isDirectory(
&newDirEntry))
{
_FAT_unlock(&partition->lock);
r->_errno = ENOTDIR;
@ -425,8 +423,8 @@ int _FAT_mkdir_r ( struct _reent *r, const char *path, int mode )
{
// 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 ) )
if (!_FAT_directory_entryFromPath(partition, &dirEntry, path, pathEnd)
|| !_FAT_directory_isDirectory(&dirEntry))
{
_FAT_unlock(&partition->lock);
r->_errno = ENOTDIR;
@ -480,23 +478,21 @@ int _FAT_mkdir_r ( struct _reent *r, const char *path, int mode )
u16_to_u8array(newEntryData, DIR_ENTRY_clusterHigh, dirCluster >> 16);
// Write it to the directory, erasing that sector in the process
_FAT_cache_eraseWritePartialSector ( partition->cache, newEntryData,
_FAT_fat_clusterToSector ( partition, dirCluster ), 0, DIR_ENTRY_DATA_SIZE );
_FAT_cache_eraseWritePartialSector(partition->cache, newEntryData, _FAT_fat_clusterToSector(partition, dirCluster),
0, DIR_ENTRY_DATA_SIZE);
// Create the double dot entry within the directory
// if ParentDir == Rootdir then ".."" always link to Cluster 0
if ( parentCluster == partition->rootDirCluster )
parentCluster = FAT16_ROOT_DIR_CLUSTER;
if (parentCluster == partition->rootDirCluster) parentCluster = FAT16_ROOT_DIR_CLUSTER;
newEntryData[DIR_ENTRY_name + 1] = '.';
u16_to_u8array(newEntryData, DIR_ENTRY_cluster, parentCluster);
u16_to_u8array(newEntryData, DIR_ENTRY_clusterHigh, parentCluster >> 16);
// Write it to the directory
_FAT_cache_writePartialSector ( partition->cache, newEntryData,
_FAT_fat_clusterToSector ( partition, dirCluster ), DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_writePartialSector(partition->cache, newEntryData, _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))
@ -601,8 +597,7 @@ DIR_ITER* _FAT_diropen_r( struct _reent *r, DIR_ITER *dirState, const char *path
state->startCluster = _FAT_directory_entryGetCluster(state->partition, dirEntry.entryData);
// Get the first entry for use with a call to dirnext
state->validEntry =
_FAT_directory_getFirstEntry ( state->partition, &( state->currentEntry ), state->startCluster );
state->validEntry = _FAT_directory_getFirstEntry(state->partition, &(state->currentEntry), state->startCluster);
// We are now using this entry
state->inUse = true;
@ -625,8 +620,7 @@ int _FAT_dirreset_r ( struct _reent *r, DIR_ITER *dirState )
}
// Get the first entry for use with a call to dirnext
state->validEntry =
_FAT_directory_getFirstEntry ( state->partition, &( state->currentEntry ), state->startCluster );
state->validEntry = _FAT_directory_getFirstEntry(state->partition, &(state->currentEntry), state->startCluster);
_FAT_unlock(&state->partition->lock);
return 0;
@ -663,8 +657,7 @@ int _FAT_dirnext_r ( struct _reent *r, DIR_ITER *dirState, char *filename, struc
}
// Look for the next entry for use next time
state->validEntry =
_FAT_directory_getNextEntry ( state->partition, &( state->currentEntry ) );
state->validEntry = _FAT_directory_getNextEntry(state->partition, &(state->currentEntry));
_FAT_unlock(&state->partition->lock);
return 0;

View File

@ -28,7 +28,6 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __FATDIR_H
#define __FATDIR_H
@ -70,5 +69,4 @@ extern int _FAT_dirreset_r ( struct _reent *r, DIR_ITER *dirState );
extern int _FAT_dirnext_r(struct _reent *r, DIR_ITER *dirState, char *filename, struct stat *filestat);
extern int _FAT_dirclose_r(struct _reent *r, DIR_ITER *dirState);
#endif // _FATDIR_H

View File

@ -30,7 +30,6 @@
2009-10-23 oggzee: fixes for cluster aligned file size (write, truncate, seek)
*/
#include "fatfile.h"
#include <fcntl.h>
@ -155,8 +154,8 @@ int _FAT_open_r ( struct _reent *r, void *fileStruct, const char *path, int flag
{
// Path was specified -- get the right dirCluster
// Recycling dirEntry, since it needs to be recreated anyway
if ( !_FAT_directory_entryFromPath ( partition, &dirEntry, path, pathEnd ) ||
!_FAT_directory_isDirectory( &dirEntry ) )
if (!_FAT_directory_entryFromPath(partition, &dirEntry, path, pathEnd) || !_FAT_directory_isDirectory(
&dirEntry))
{
_FAT_unlock(&partition->lock);
r->_errno = ENOTDIR;
@ -299,9 +298,9 @@ int _FAT_syncToDisc ( FILE_STRUCT* file )
if (file->write && file->modified)
{
// Load the old entry
_FAT_cache_readPartialSector ( file->partition->cache, dirEntryData,
_FAT_fat_clusterToSector( file->partition, file->dirEntryEnd.cluster ) + file->dirEntryEnd.sector,
file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_readPartialSector(file->partition->cache, dirEntryData, _FAT_fat_clusterToSector(file->partition,
file->dirEntryEnd.cluster) + file->dirEntryEnd.sector, file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE,
DIR_ENTRY_DATA_SIZE);
// Write new data to the directory entry
// File size
@ -322,9 +321,9 @@ int _FAT_syncToDisc ( FILE_STRUCT* file )
dirEntryData[DIR_ENTRY_attributes] |= ATTRIB_ARCH;
// Write the new entry
_FAT_cache_writePartialSector ( file->partition->cache, dirEntryData,
_FAT_fat_clusterToSector( file->partition, file->dirEntryEnd.cluster ) + file->dirEntryEnd.sector,
file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE, DIR_ENTRY_DATA_SIZE );
_FAT_cache_writePartialSector(file->partition->cache, dirEntryData, _FAT_fat_clusterToSector(file->partition,
file->dirEntryEnd.cluster) + file->dirEntryEnd.sector, file->dirEntryEnd.offset * DIR_ENTRY_DATA_SIZE,
DIR_ENTRY_DATA_SIZE);
// Flush any sectors in the disc cache
if (!_FAT_cache_flush(file->partition->cache))
@ -338,7 +337,6 @@ int _FAT_syncToDisc ( FILE_STRUCT* file )
return 0;
}
int _FAT_close_r(struct _reent *r, int fd)
{
FILE_STRUCT* file = (FILE_STRUCT*) fd;
@ -439,8 +437,8 @@ ssize_t _FAT_read_r ( struct _reent *r, int fd, char *ptr, size_t len )
if ((tempVar < BYTES_PER_READ) && flagNoError)
{
_FAT_cache_readPartialSector ( cache, ptr, _FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector,
position.byte, tempVar );
_FAT_cache_readPartialSector(cache, ptr, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, position.byte, tempVar);
remain -= tempVar;
ptr += tempVar;
@ -513,15 +511,14 @@ ssize_t _FAT_read_r ( struct _reent *r, int fd, char *ptr, size_t len )
chunkEnd = nextChunkStart;
nextChunkStart = _FAT_fat_nextCluster(partition, chunkEnd);
chunkSize += partition->bytesPerCluster;
}
while ( ( nextChunkStart == chunkEnd + 1 ) &&
} while ((nextChunkStart == chunkEnd + 1) &&
#ifdef LIMIT_SECTORS
( chunkSize + partition->bytesPerCluster <= LIMIT_SECTORS * BYTES_PER_READ ) &&
#endif
(chunkSize + partition->bytesPerCluster <= remain));
if ( !_FAT_cache_readSectors ( cache, _FAT_fat_clusterToSector ( partition, position.cluster ),
chunkSize / BYTES_PER_READ, ptr ) )
if (!_FAT_cache_readSectors(cache, _FAT_fat_clusterToSector(partition, position.cluster), chunkSize
/ BYTES_PER_READ, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -552,8 +549,7 @@ ssize_t _FAT_read_r ( struct _reent *r, int fd, char *ptr, size_t len )
tempVar = remain / BYTES_PER_READ; // Number of sectors left
if ((tempVar > 0) && flagNoError)
{
if ( !_FAT_cache_readSectors ( cache, _FAT_fat_clusterToSector ( partition, position.cluster ),
tempVar, ptr ) )
if (!_FAT_cache_readSectors(cache, _FAT_fat_clusterToSector(partition, position.cluster), tempVar, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -570,8 +566,8 @@ ssize_t _FAT_read_r ( struct _reent *r, int fd, char *ptr, size_t len )
// Check if anything is left
if ((remain > 0) && flagNoError)
{
_FAT_cache_readPartialSector ( cache, ptr,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, 0, remain );
_FAT_cache_readPartialSector(cache, ptr, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, 0, remain);
position.byte += remain;
remain = 0;
}
@ -591,8 +587,8 @@ ssize_t _FAT_read_r ( struct _reent *r, int fd, char *ptr, size_t len )
// then get next cluster or allocate next cluster
// this solves the over-allocation problems when file size is aligned to cluster size
// return true on succes, false on error
static bool _FAT_check_position_for_next_cluster( struct _reent *r,
FILE_POSITION *position, PARTITION* partition, size_t remain, bool *flagNoError )
static bool _FAT_check_position_for_next_cluster(struct _reent *r, FILE_POSITION *position, PARTITION* partition,
size_t remain, bool *flagNoError)
{
uint32_t tempNextCluster;
// do nothing if no more data to write
@ -623,8 +619,7 @@ static bool _FAT_check_position_for_next_cluster( struct _reent *r,
position->cluster = tempNextCluster;
}
return true;
err:
if ( flagNoError ) *flagNoError = false;
err: if (flagNoError) *flagNoError = false;
return false;
}
@ -666,17 +661,16 @@ static bool _FAT_file_extend_r ( struct _reent *r, FILE_STRUCT* file )
if (remain + position.byte < BYTES_PER_READ)
{
// Only need to clear to the end of the sector
_FAT_cache_writePartialSector ( cache, zeroBuffer,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, position.byte, remain );
_FAT_cache_writePartialSector(cache, zeroBuffer, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, position.byte, remain);
position.byte += remain;
}
else
{
if (position.byte > 0)
{
_FAT_cache_writePartialSector ( cache, zeroBuffer,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, position.byte,
BYTES_PER_READ - position.byte );
_FAT_cache_writePartialSector(cache, zeroBuffer, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, position.byte, BYTES_PER_READ - position.byte);
remain -= (BYTES_PER_READ - position.byte);
position.byte = 0;
position.sector++;
@ -713,8 +707,8 @@ static bool _FAT_file_extend_r ( struct _reent *r, FILE_STRUCT* file )
if (remain > 0)
{
_FAT_cache_writePartialSector ( cache, zeroBuffer,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, 0, remain );
_FAT_cache_writePartialSector(cache, zeroBuffer, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, 0, remain);
position.byte = remain;
}
}
@ -824,14 +818,13 @@ ssize_t _FAT_write_r ( struct _reent *r, int fd, const char *ptr, size_t len )
if ((tempVar < BYTES_PER_READ) && flagNoError)
{
// Write partial sector to disk
_FAT_cache_writePartialSector ( cache, ptr,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, position.byte, tempVar );
_FAT_cache_writePartialSector(cache, ptr, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, position.byte, tempVar);
remain -= tempVar;
ptr += tempVar;
position.byte += tempVar;
// Move onto next sector
if (position.byte >= BYTES_PER_READ)
{
@ -853,8 +846,8 @@ ssize_t _FAT_write_r ( struct _reent *r, int fd, const char *ptr, size_t len )
if ((tempVar > 0 && tempVar < partition->sectorsPerCluster) && flagNoError)
{
if ( !_FAT_cache_writeSectors ( cache,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, tempVar, ptr ) )
if (!_FAT_cache_writeSectors(cache, _FAT_fat_clusterToSector(partition, position.cluster) + position.sector,
tempVar, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -889,8 +882,7 @@ ssize_t _FAT_write_r ( struct _reent *r, int fd, const char *ptr, size_t len )
// pretend to use up all sectors in next_position
next_position.sector = partition->sectorsPerCluster;
// get or allocate next cluster
_FAT_check_position_for_next_cluster( r, &next_position, partition,
remain - chunkSize, &flagNoError );
_FAT_check_position_for_next_cluster(r, &next_position, partition, remain - chunkSize, &flagNoError);
if (!flagNoError) break; // exit loop on error
nextChunkStart = next_position.cluster;
if (nextChunkStart != chunkEnd + 1) break; // exit loop if not consecutive
@ -898,8 +890,8 @@ ssize_t _FAT_write_r ( struct _reent *r, int fd, const char *ptr, size_t len )
chunkSize += partition->bytesPerCluster;
}
if ( !_FAT_cache_writeSectors ( cache,
_FAT_fat_clusterToSector( partition, position.cluster ), chunkSize / BYTES_PER_READ, ptr ) )
if (!_FAT_cache_writeSectors(cache, _FAT_fat_clusterToSector(partition, position.cluster), chunkSize
/ BYTES_PER_READ, ptr))
{
flagNoError = false;
r->_errno = EIO;
@ -947,19 +939,18 @@ ssize_t _FAT_write_r ( struct _reent *r, int fd, const char *ptr, size_t len )
{
if (flagAppending)
{
_FAT_cache_eraseWritePartialSector ( cache, ptr,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, 0, remain );
_FAT_cache_eraseWritePartialSector(cache, ptr, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, 0, remain);
}
else
{
_FAT_cache_writePartialSector ( cache, ptr,
_FAT_fat_clusterToSector ( partition, position.cluster ) + position.sector, 0, remain );
_FAT_cache_writePartialSector(cache, ptr, _FAT_fat_clusterToSector(partition, position.cluster)
+ position.sector, 0, remain);
}
position.byte += remain;
remain = 0;
}
// Amount written is the originally requested amount minus stuff remaining
len = len - remain;
@ -986,7 +977,6 @@ ssize_t _FAT_write_r ( struct _reent *r, int fd, const char *ptr, size_t len )
return len;
}
off_t _FAT_seek_r(struct _reent *r, int fd, off_t pos, int dir)
{
FILE_STRUCT* file = (FILE_STRUCT*) fd;
@ -1100,8 +1090,6 @@ off_t _FAT_seek_r ( struct _reent *r, int fd, off_t pos, int dir )
return position;
}
int _FAT_fstat_r(struct _reent *r, int fd, struct stat *st)
{
FILE_STRUCT* file = (FILE_STRUCT*) fd;
@ -1339,16 +1327,14 @@ int _FAT_get_fragments ( const char *path, _frag_append_t append_fragment, void
}
offset += partition->sectorsPerCluster;
cluster = _FAT_fat_nextCluster(partition, cluster);
}
while ( offset < size );
} while (offset < size);
// set size
append_fragment(callback_data, size, 0, 0);
// success
ret = 0;
out:
_FAT_unlock( &partition->lock );
out: _FAT_unlock(&partition->lock);
_FAT_close_r(&r, fd);
return ret;
}

View File

@ -28,7 +28,6 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FATFILE_H
#define _FATFILE_H
@ -40,7 +39,6 @@
#include "directory.h"
#define FILE_MAX_SIZE ((uint32_t)0xFFFFFFFF) // 4GiB - 1B
typedef struct
{
u32 cluster;

View File

@ -27,7 +27,6 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "file_allocation_table.h"
#include "partition.h"
#include <string.h>
@ -58,7 +57,6 @@ uint32_t _FAT_fat_nextCluster( PARTITION* partition, uint32_t cluster )
sector = partition->fat.fatStart + (((cluster * 3) / 2) / BYTES_PER_READ);
offset = ((cluster * 3) / 2) % BYTES_PER_READ;
_FAT_cache_readLittleEndianValue(partition->cache, &nextCluster, sector, offset, sizeof(u8));
offset++;
@ -303,15 +301,12 @@ uint32_t _FAT_fat_linkFreeClusterCleared ( PARTITION* partition, uint32_t cluste
memset(emptySector, 0, BYTES_PER_READ);
for (i = 0; i < partition->sectorsPerCluster; i++)
{
_FAT_cache_writeSectors ( partition->cache,
_FAT_fat_clusterToSector ( partition, newCluster ) + i,
1, emptySector );
_FAT_cache_writeSectors(partition->cache, _FAT_fat_clusterToSector(partition, newCluster) + i, 1, emptySector);
}
return newCluster;
}
/*-----------------------------------------------------------------
_FAT_fat_clearLinks
frees any cluster used by a file
@ -320,8 +315,7 @@ 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 ((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)
@ -393,7 +387,8 @@ 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 ) )
while ((_FAT_fat_nextCluster(partition, cluster) != CLUSTER_FREE) && (_FAT_fat_nextCluster(partition, cluster)
!= CLUSTER_EOF))
{
cluster = _FAT_fat_nextCluster(partition, cluster);
}

View File

@ -43,7 +43,6 @@
#define CLUSTERS_PER_FAT12 4085
#define CLUSTERS_PER_FAT16 65525
uint32_t _FAT_fat_nextCluster(PARTITION* partition, uint32_t cluster);
uint32_t _FAT_fat_linkFreeCluster(PARTITION* partition, uint32_t cluster);
@ -59,9 +58,8 @@ unsigned int _FAT_fat_freeClusterCount ( PARTITION* partition );
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;
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)

View File

@ -26,7 +26,6 @@
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <time.h>
#include "filetime.h"
#include "common.h"
@ -58,17 +57,12 @@ uint16_t _FAT_filetime_getTimeFromRTC ( void )
if ((timeParts.tm_min < 0) || (timeParts.tm_min > MAX_MINUTE)) return 0;
if ((timeParts.tm_sec < 0) || (timeParts.tm_sec > MAX_SECOND)) return 0;
return (
( ( timeParts.tm_hour & 0x1F ) << 11 ) |
( ( timeParts.tm_min & 0x3F ) << 5 ) |
( ( timeParts.tm_sec >> 1 ) & 0x1F )
);
return (((timeParts.tm_hour & 0x1F) << 11) | ((timeParts.tm_min & 0x3F) << 5) | ((timeParts.tm_sec >> 1) & 0x1F));
#else
return 0;
#endif
}
uint16_t _FAT_filetime_getDateFromRTC(void)
{
#ifdef USE_RTC_TIME
@ -84,11 +78,8 @@ uint16_t _FAT_filetime_getDateFromRTC ( void )
if ((timeParts.tm_mon < MIN_MONTH) || (timeParts.tm_mon > MAX_MONTH)) return 0;
if ((timeParts.tm_mday < MIN_DAY) || (timeParts.tm_mday > MAX_DAY)) return 0;
return (
( ( ( timeParts.tm_year - 80 ) & 0x7F ) << 9 ) | // Adjust for MS-FAT base year (1980 vs 1900 for tm_year)
( ( ( timeParts.tm_mon + 1 ) & 0xF ) << 5 ) |
( timeParts.tm_mday & 0x1F )
);
return ((((timeParts.tm_year - 80) & 0x7F) << 9) | // Adjust for MS-FAT base year (1980 vs 1900 for tm_year)
(((timeParts.tm_mon + 1) & 0xF) << 5) | (timeParts.tm_mday & 0x1F));
#else
return 0;
#endif

View File

@ -37,5 +37,4 @@ uint16_t _FAT_filetime_getDateFromRTC ( void );
time_t _FAT_filetime_to_time_t(uint16_t t, uint16_t d);
#endif // _FILETIME_H

View File

@ -38,41 +38,20 @@
#include "mem_allocate.h"
#include "disc_fat.h"
static const devoptab_t dotab_fat =
{
"fat",
sizeof ( FILE_STRUCT ),
_FAT_open_r,
_FAT_close_r,
_FAT_write_r,
_FAT_read_r,
_FAT_seek_r,
_FAT_fstat_r,
_FAT_stat_r,
_FAT_link_r,
_FAT_unlink_r,
_FAT_chdir_r,
_FAT_rename_r,
_FAT_mkdir_r,
sizeof ( DIR_STATE_STRUCT ),
_FAT_diropen_r,
_FAT_dirreset_r,
_FAT_dirnext_r,
_FAT_dirclose_r,
_FAT_statvfs_r,
_FAT_ftruncate_r,
_FAT_fsync_r,
NULL /* Device data */
static const devoptab_t dotab_fat = { "fat", sizeof(FILE_STRUCT), _FAT_open_r, _FAT_close_r, _FAT_write_r, _FAT_read_r,
_FAT_seek_r, _FAT_fstat_r, _FAT_stat_r, _FAT_link_r, _FAT_unlink_r, _FAT_chdir_r, _FAT_rename_r, _FAT_mkdir_r,
sizeof(DIR_STATE_STRUCT), _FAT_diropen_r, _FAT_dirreset_r, _FAT_dirnext_r, _FAT_dirclose_r, _FAT_statvfs_r,
_FAT_ftruncate_r, _FAT_fsync_r, 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;
if ( !interface->startup() )
return false;
if (!interface->startup()) return false;
if (!interface->isInserted())
{
@ -150,9 +129,7 @@ bool fatInit ( uint32_t cacheSize, bool setAsDefaultDevice )
int defaultDevice = -1;
const DISC_INTERFACE *disc;
for ( i = 0;
_FAT_disc_interfaces[i].name != NULL && _FAT_disc_interfaces[i].getInterface != NULL;
i++ )
for (i = 0; _FAT_disc_interfaces[i].name != NULL && _FAT_disc_interfaces[i].getInterface != NULL; i++)
{
disc = _FAT_disc_interfaces[i].getInterface();
if (fatMount(_FAT_disc_interfaces[i].name, disc, 0, cacheSize, DEFAULT_SECTORS_PAGE))
@ -177,16 +154,15 @@ bool fatInit ( uint32_t cacheSize, bool setAsDefaultDevice )
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;
_FAT_disc_interfaces[i].name != NULL && _FAT_disc_interfaces[i].getInterface != NULL;
i++ )
for (i = 0; _FAT_disc_interfaces[i].name != NULL && _FAT_disc_interfaces[i].getInterface != NULL; i++)
{
if ( !strncasecmp( __system_argv->argv[0], _FAT_disc_interfaces[i].name,
strlen( _FAT_disc_interfaces[i].name ) ) )
if (!strncasecmp(__system_argv->argv[0], _FAT_disc_interfaces[i].name, strlen(
_FAT_disc_interfaces[i].name)))
{
char *lastSlash;
strcpy(filePath, __system_argv->argv[0]);
@ -212,4 +188,3 @@ bool fatInitDefault ( void )
return fatInit(DEFAULT_CACHE_PAGES, true);
}

View File

@ -82,6 +82,4 @@ static inline void _FAT_unlock( mutex_t *mutex )
#endif // USE_LWP_LOCK
#endif // _LOCK_H

View File

@ -52,8 +52,7 @@ Data offsets
// BIOS Parameter Block offsets
enum BPB
{
BPB_jmpBoot = 0x00,
BPB_OEMName = 0x03,
BPB_jmpBoot = 0x00, BPB_OEMName = 0x03,
// BIOS Parameter Block
BPB_bytesPerSector = 0x0B,
BPB_sectorsPerCluster = 0x0D,
@ -98,7 +97,6 @@ enum BPB
static const char FAT_SIG[3] = { 'F', 'A', 'T' };
sec_t FindFirstValidPartition(const DISC_INTERFACE* disc)
{
uint8_t part_table[16 * 4];
@ -120,8 +118,8 @@ sec_t FindFirstValidPartition( const DISC_INTERFACE* disc )
{
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 ) ) )
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || !memcmp(sectorBuffer
+ BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
return part_lba;
}
@ -143,8 +141,8 @@ sec_t FindFirstValidPartition( const DISC_INTERFACE* disc )
if (!_FAT_disc_readSectors(disc, part_lba2, 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 ) ) )
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || !memcmp(sectorBuffer
+ BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
return part_lba2;
}
@ -155,8 +153,8 @@ sec_t FindFirstValidPartition( const DISC_INTERFACE* disc )
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 ) ) )
if (!memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) || !memcmp(sectorBuffer
+ BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
return part_lba;
}
@ -165,7 +163,8 @@ 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 };
@ -206,15 +205,16 @@ PARTITION* _FAT_partition_constructor ( const DISC_INTERFACE* disc, uint32_t cac
}
// Now verify that this is indeed a FAT partition
if ( memcmp( sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) &&
memcmp( sectorBuffer + BPB_FAT32_fileSysType, FAT_SIG, sizeof( FAT_SIG ) ) )
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, FAT_SIG, sizeof(FAT_SIG)) && memcmp(sectorBuffer
+ BPB_FAT32_fileSysType, FAT_SIG, sizeof(FAT_SIG)))
{
return NULL;
}
// check again for the last two cases to make sure that we really have a FAT filesystem here
// and won't corrupt any data
if ( memcmp( sectorBuffer + BPB_FAT16_fileSysType, "FAT", 3 ) != 0 && memcmp( sectorBuffer + BPB_FAT32_fileSysType, "FAT32", 5 ) != 0 )
if (memcmp(sectorBuffer + BPB_FAT16_fileSysType, "FAT", 3) != 0 && memcmp(sectorBuffer + BPB_FAT32_fileSysType,
"FAT32", 5) != 0)
{
return NULL;
}
@ -247,18 +247,21 @@ PARTITION* _FAT_partition_constructor ( const DISC_INTERFACE* disc, uint32_t cac
}
partition->bytesPerSector = BYTES_PER_READ; // Sector size is redefined to be 512 bytes
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16( sectorBuffer, BPB_bytesPerSector ) / BYTES_PER_READ;
partition->sectorsPerCluster = sectorBuffer[BPB_sectorsPerCluster] * u8array_to_u16(sectorBuffer,
BPB_bytesPerSector) / BYTES_PER_READ;
partition->bytesPerCluster = partition->bytesPerSector * partition->sectorsPerCluster;
partition->fat.fatStart = startSector + u8array_to_u16(sectorBuffer, BPB_reservedSectors);
partition->rootDirStart = partition->fat.fatStart + (sectorBuffer[BPB_numFATs] * partition->fat.sectorsPerFat);
partition->dataStart = partition->rootDirStart +
( ( u8array_to_u16( sectorBuffer, BPB_rootEntries ) * DIR_ENTRY_DATA_SIZE ) / partition->bytesPerSector );
partition->dataStart = partition->rootDirStart + ((u8array_to_u16(sectorBuffer, BPB_rootEntries)
* DIR_ENTRY_DATA_SIZE) / partition->bytesPerSector);
partition->totalSize = ( ( uint64_t )partition->numberOfSectors - ( partition->dataStart - startSector ) ) * ( uint64_t )partition->bytesPerSector;
partition->totalSize = ((uint64_t) partition->numberOfSectors - (partition->dataStart - startSector))
* (uint64_t) partition->bytesPerSector;
// Store info about FAT
uint32_t clusterCount = ( partition->numberOfSectors - ( uint32_t )( partition->dataStart - startSector ) ) / partition->sectorsPerCluster;
uint32_t clusterCount = (partition->numberOfSectors - (uint32_t) (partition->dataStart - startSector))
/ partition->sectorsPerCluster;
partition->fat.lastCluster = clusterCount + CLUSTER_FIRST - 1;
partition->fat.firstFree = CLUSTER_FIRST;
@ -287,12 +290,14 @@ PARTITION* _FAT_partition_constructor ( const DISC_INTERFACE* disc, uint32_t cac
if (!(sectorBuffer[BPB_FAT32_extFlags] & 0x80))
{
// Use the active FAT
partition->fat.fatStart = partition->fat.fatStart + ( partition->fat.sectorsPerFat * ( sectorBuffer[BPB_FAT32_extFlags] & 0x0F ) );
partition->fat.fatStart = partition->fat.fatStart + (partition->fat.sectorsPerFat
* (sectorBuffer[BPB_FAT32_extFlags] & 0x0F));
}
}
// Create a cache to use
partition->cache = _FAT_cache_constructor ( cacheSize, sectorsPerPage, partition->disc, startSector + partition->numberOfSectors );
partition->cache = _FAT_cache_constructor(cacheSize, sectorsPerPage, partition->disc, startSector
+ partition->numberOfSectors);
// Set current directory to the root
partition->cwdCluster = partition->rootDirCluster;

View File

@ -38,7 +38,10 @@
extern const char* DEVICE_NAME;
// Filesystem type
typedef enum {FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32} FS_TYPE;
typedef enum
{
FS_UNKNOWN, FS_FAT12, FS_FAT16, FS_FAT32
} FS_TYPE;
typedef struct
{
@ -74,7 +77,8 @@ typedef struct
/*
Mount the supplied device and return a pointer to the struct necessary to use it
*/
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);
/*
Dismount the device and free all structures used.

File diff suppressed because it is too large Load Diff

View File

@ -56,7 +56,6 @@
#define NTFS_FIND_USER(map,usid) ntfs_find_user(map,usid)
#define NTFS_FIND_GROUP(map,gsid) ntfs_find_group(map,gsid)
/*
* Matching of ntfs permissions to Linux permissions
* these constants are adapted to endianness
@ -122,7 +121,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 */
@ -150,14 +150,11 @@ BOOL ntfs_same_sid(const SID *first, const SID *second);
BOOL ntfs_is_user_sid(const SID *usid);
int ntfs_sid_size(const SID * sid);
unsigned int ntfs_attr_size(const char *attr);
const SID *ntfs_find_usid(const struct MAPPING *usermapping,
uid_t uid, SID *pdefsid);
const SID *ntfs_find_gsid(const struct MAPPING *groupmapping,
gid_t gid, SID *pdefsid);
const SID *ntfs_find_usid(const struct MAPPING *usermapping, uid_t uid, SID *pdefsid);
const SID *ntfs_find_gsid(const struct MAPPING *groupmapping, gid_t gid, SID *pdefsid);
uid_t ntfs_find_user(const struct MAPPING *usermapping, const SID *usid);
gid_t ntfs_find_group(const struct MAPPING *groupmapping, const SID * gsid);
const SID *ntfs_acl_owner(const char *secattr);
@ -184,12 +181,9 @@ char *ntfs_build_descr_posix(struct MAPPING* const mapping[],
#endif /* POSIXACLS */
int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl,
const SID *usid, const SID *gsid, BOOL fordir);
int ntfs_build_permissions(const char *securattr,
const SID *usid, const SID *gsid, BOOL isdir);
char *ntfs_build_descr(mode_t mode,
int isdir, const SID * usid, const SID * gsid);
int ntfs_inherit_acl(const ACL *oldacl, ACL *newacl, const SID *usid, const SID *gsid, BOOL fordir);
int ntfs_build_permissions(const char *securattr, const SID *usid, const SID *gsid, BOOL isdir);
char *ntfs_build_descr(mode_t mode, int isdir, const SID * usid, const SID * gsid);
struct MAPLIST *ntfs_read_mapping(FILEREADER reader, void *fileid);
struct MAPPING *ntfs_do_user_mapping(struct MAPLIST *firstitem);
struct MAPPING *ntfs_do_group_mapping(struct MAPLIST *firstitem);

File diff suppressed because it is too large Load Diff

View File

@ -49,12 +49,10 @@ 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,
LCN_EINVAL = -4,
LCN_EIO = -5,
LCN_RL_NOT_MAPPED = -2, LCN_ENOENT = -3, LCN_EINVAL = -4, LCN_EIO = -5,
} ntfs_lcn_special_values;
/**
@ -75,7 +73,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;
@ -87,19 +86,15 @@ struct _ntfs_attr_search_ctx {
};
extern void ntfs_attr_reinit_search_ctx(ntfs_attr_search_ctx *ctx);
extern ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni,
MFT_RECORD *mrec);
extern ntfs_attr_search_ctx *ntfs_attr_get_search_ctx(ntfs_inode *ni, MFT_RECORD *mrec);
extern void ntfs_attr_put_search_ctx(ntfs_attr_search_ctx *ctx);
extern int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name,
const u32 name_len, const IGNORE_CASE_BOOL ic,
const VCN lowest_vcn, const u8 *val, const u32 val_len,
ntfs_attr_search_ctx *ctx);
extern int ntfs_attr_lookup(const ATTR_TYPES type, const ntfschar *name, const u32 name_len, const IGNORE_CASE_BOOL ic,
const VCN lowest_vcn, const u8 *val, const u32 val_len, ntfs_attr_search_ctx *ctx);
extern int ntfs_attr_position(const ATTR_TYPES type, ntfs_attr_search_ctx *ctx);
extern ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol,
const ATTR_TYPES type);
extern ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol, const ATTR_TYPES type);
/**
* ntfs_attrs_walk - syntactic sugar for walking all attributes in an inode
@ -128,8 +123,7 @@ extern ATTR_DEF *ntfs_attr_find_in_attrdef(const ntfs_volume *vol,
*/
static __inline__ int ntfs_attrs_walk(ntfs_attr_search_ctx *ctx)
{
return ntfs_attr_lookup(AT_UNUSED, NULL, 0, CASE_SENSITIVE, 0,
NULL, 0, ctx);
return ntfs_attr_lookup(AT_UNUSED, NULL, 0, CASE_SENSITIVE, 0, NULL, 0, ctx);
}
/**
@ -174,7 +168,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,12 +191,14 @@ 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. */
NA_FullyMapped, /* 1: Attribute has been fully mapped */
NA_ComprClosing, /* 1: Compressed attribute is being closed */
NA_ComprClosing,
/* 1: Compressed attribute is being closed */
} ntfs_attr_state_bits;
#define test_nattr_flag(na, flag) test_bit(NA_##flag, (na)->state)
@ -243,7 +240,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;
@ -265,32 +263,23 @@ typedef union {
EFS_ATTR_HEADER efs;
} attr_val;
extern void ntfs_attr_init(ntfs_attr *na, const BOOL non_resident,
const ATTR_FLAGS data_flags, const BOOL encrypted,
const BOOL sparse,
const s64 allocated_size, const s64 data_size,
const s64 initialized_size, const s64 compressed_size,
const u8 compression_unit);
extern void ntfs_attr_init(ntfs_attr *na, const BOOL non_resident, const ATTR_FLAGS data_flags, const BOOL encrypted,
const BOOL sparse, const s64 allocated_size, const s64 data_size, const s64 initialized_size,
const s64 compressed_size, const u8 compression_unit);
/* warning : in the following "name" has to be freeable */
/* or one of constants AT_UNNAMED, NTFS_INDEX_I30 or STREAM_SDS */
extern ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type,
ntfschar *name, u32 name_len);
extern ntfs_attr *ntfs_attr_open(ntfs_inode *ni, const ATTR_TYPES type, ntfschar *name, u32 name_len);
extern void ntfs_attr_close(ntfs_attr *na);
extern s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count,
void *b);
extern s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count,
const void *b);
extern s64 ntfs_attr_pread(ntfs_attr *na, const s64 pos, s64 count, void *b);
extern s64 ntfs_attr_pwrite(ntfs_attr *na, const s64 pos, s64 count, const void *b);
extern int ntfs_attr_pclose(ntfs_attr *na);
extern void *ntfs_attr_readall(ntfs_inode *ni, const ATTR_TYPES type,
ntfschar *name, u32 name_len, s64 *data_size);
extern void *ntfs_attr_readall(ntfs_inode *ni, const ATTR_TYPES type, ntfschar *name, u32 name_len, s64 *data_size);
extern s64 ntfs_attr_mst_pread(ntfs_attr *na, const s64 pos,
const s64 bk_cnt, const u32 bk_size, void *dst);
extern s64 ntfs_attr_mst_pwrite(ntfs_attr *na, const s64 pos,
s64 bk_cnt, const u32 bk_size, void *src);
extern s64 ntfs_attr_mst_pread(ntfs_attr *na, const s64 pos, const s64 bk_cnt, const u32 bk_size, void *dst);
extern s64 ntfs_attr_mst_pwrite(ntfs_attr *na, const s64 pos, s64 bk_cnt, const u32 bk_size, void *src);
extern int ntfs_attr_map_runlist(ntfs_attr *na, VCN vcn);
extern int ntfs_attr_map_whole_runlist(ntfs_attr *na);
@ -298,33 +287,26 @@ extern int ntfs_attr_map_whole_runlist(ntfs_attr *na);
extern LCN ntfs_attr_vcn_to_lcn(ntfs_attr *na, const VCN vcn);
extern runlist_element *ntfs_attr_find_vcn(ntfs_attr *na, const VCN vcn);
extern int ntfs_attr_size_bounds_check(const ntfs_volume *vol,
const ATTR_TYPES type, const s64 size);
extern int ntfs_attr_can_be_resident(const ntfs_volume *vol,
const ATTR_TYPES type);
int ntfs_attr_make_non_resident(ntfs_attr *na,
ntfs_attr_search_ctx *ctx);
extern int ntfs_attr_size_bounds_check(const ntfs_volume *vol, const ATTR_TYPES type, const s64 size);
extern int ntfs_attr_can_be_resident(const ntfs_volume *vol, const ATTR_TYPES type);
int ntfs_attr_make_non_resident(ntfs_attr *na, ntfs_attr_search_ctx *ctx);
int ntfs_attr_force_non_resident(ntfs_attr *na);
extern int ntfs_make_room_for_attr(MFT_RECORD *m, u8 *pos, u32 size);
extern int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
ntfschar *name, u8 name_len, u8 *val, u32 size,
ATTR_FLAGS flags);
extern int ntfs_non_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type,
ntfschar *name, u8 name_len, VCN lowest_vcn, int dataruns_size,
ATTR_FLAGS flags);
extern int ntfs_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type, ntfschar *name, u8 name_len, u8 *val,
u32 size, ATTR_FLAGS flags);
extern int ntfs_non_resident_attr_record_add(ntfs_inode *ni, ATTR_TYPES type, ntfschar *name, u8 name_len,
VCN lowest_vcn, int dataruns_size, ATTR_FLAGS flags);
extern int ntfs_attr_record_rm(ntfs_attr_search_ctx *ctx);
extern int ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type,
ntfschar *name, u8 name_len, u8 *val, s64 size);
extern int ntfs_attr_set_flags(ntfs_inode *ni, ATTR_TYPES type,
ntfschar *name, u8 name_len, ATTR_FLAGS flags, ATTR_FLAGS mask);
extern int ntfs_attr_add(ntfs_inode *ni, ATTR_TYPES type, ntfschar *name, u8 name_len, u8 *val, s64 size);
extern int ntfs_attr_set_flags(ntfs_inode *ni, ATTR_TYPES type, ntfschar *name, u8 name_len, ATTR_FLAGS flags,
ATTR_FLAGS mask);
extern int ntfs_attr_rm(ntfs_attr *na);
extern int ntfs_attr_record_resize(MFT_RECORD *m, ATTR_RECORD *a, u32 new_size);
extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a,
const u32 new_size);
extern int ntfs_resident_attr_value_resize(MFT_RECORD *m, ATTR_RECORD *a, const u32 new_size);
extern int ntfs_attr_record_move_to(ntfs_attr_search_ctx *ctx, ntfs_inode *ni);
extern int ntfs_attr_record_move_away(ntfs_attr_search_ctx *ctx, int extra);
@ -360,15 +342,12 @@ extern s64 ntfs_get_attribute_value_length(const ATTR_RECORD *a);
* then nothing was read due to a zero-length attribute value, otherwise
* errno describes the error.
*/
extern s64 ntfs_get_attribute_value(const ntfs_volume *vol,
const ATTR_RECORD *a, u8 *b);
extern s64 ntfs_get_attribute_value(const ntfs_volume *vol, const ATTR_RECORD *a, u8 *b);
extern void ntfs_attr_name_free(char **name);
extern char *ntfs_attr_name_get(const ntfschar *uname, const int uname_len);
extern int ntfs_attr_exist(ntfs_inode *ni, const ATTR_TYPES type,
ntfschar *name, u32 name_len);
extern int ntfs_attr_remove(ntfs_inode *ni, const ATTR_TYPES type,
ntfschar *name, u32 name_len);
extern int ntfs_attr_exist(ntfs_inode *ni, const ATTR_TYPES type, ntfschar *name, u32 name_len);
extern int ntfs_attr_remove(ntfs_inode *ni, const ATTR_TYPES type, ntfschar *name, u32 name_len);
extern s64 ntfs_attr_get_free_bits(ntfs_attr *na);
#endif /* defined _NTFS_ATTRIB_H */

View File

@ -65,8 +65,10 @@
#define STANDARD_COMPRESSION_UNIT 4
ntfschar AT_UNNAMED[] = { const_cpu_to_le16( '\0' ) };
ntfschar STREAM_SDS[] = { const_cpu_to_le16( '$' ),
ntfschar AT_UNNAMED[] =
{ const_cpu_to_le16( '\0' )};
ntfschar STREAM_SDS[] =
{ const_cpu_to_le16( '$' ),
const_cpu_to_le16( 'S' ),
const_cpu_to_le16( 'D' ),
const_cpu_to_le16( 'S' ),
@ -854,7 +856,6 @@ map_rl:
return NULL;
}
#endif
/**
@ -899,8 +900,7 @@ static s64 ntfs_attr_getfragments_i( ntfs_attr *na, const s64 pos, s64 count, u6
return -32;
}
if ( !count )
return 0;
if (!count) return 0;
/*
* Truncate reads beyond end of attribute,
* but round to next 512 byte boundary for encrypted
@ -908,9 +908,7 @@ static s64 ntfs_attr_getfragments_i( ntfs_attr *na, const s64 pos, s64 count, u6
*/
max_read = na->data_size;
max_init = na->initialized_size;
if ( na->ni->vol->efs_raw
&& ( na->data_flags & ATTR_IS_ENCRYPTED )
&& NAttrNonResident( na ) )
if (na->ni->vol->efs_raw && (na->data_flags & ATTR_IS_ENCRYPTED) && NAttrNonResident( na ))
{
if (na->data_size != na->initialized_size)
{
@ -923,8 +921,7 @@ static s64 ntfs_attr_getfragments_i( ntfs_attr *na, const s64 pos, s64 count, u6
}
if (pos + count > max_read)
{
if ( pos >= max_read )
return 0;
if (pos >= max_read) return 0;
count = max_read - pos;
}
/* If it is a resident attribute, get the value from the mft record. */
@ -976,9 +973,7 @@ static s64 ntfs_attr_getfragments_i( ntfs_attr *na, const s64 pos, s64 count, u6
* the number of padding bytes so original size can be
* restored
*/
if ( na->ni->vol->efs_raw &&
( na->data_flags & ATTR_IS_ENCRYPTED ) &&
( ( pos + count ) > max_init - 2 ) )
if (na->ni->vol->efs_raw && (na->data_flags & ATTR_IS_ENCRYPTED) && ((pos + count) > max_init - 2))
{
return -35; //No encrypted files
/*
@ -1097,30 +1092,23 @@ retry:
count -= br;
b = b + br;
}
if ( br == to_read )
continue;
if (br == to_read) continue;
/* If the syscall was interrupted, try again. */
if ( br == ( s64 ) - 1 && errno == EINTR )
goto retry;
if ( total )
return total;
if ( !br )
errno = EIO;
if (br == (s64) -1 && errno == EINTR) goto retry;
if (total) return total;
if (!br) errno = EIO;
ntfs_log_perror( "%s: ntfs_pread failed", __FUNCTION__ );
//return -1;
return -38;
}
/* Finally, return the number of bytes read. */
return total + total2;
rl_err_out:
if ( total )
return total;
rl_err_out: if (total) return total;
errno = EIO;
//return -1;
return -39;
}
/**
* ntfs_attr_pread - read from an attribute specified by an ntfs_attr structure
* @na: ntfs attribute to read from
@ -1140,8 +1128,8 @@ rl_err_out:
* to the return code of ntfs_pread(), or to EINVAL in case of invalid
* arguments.
*/
s64 ntfs_attr_getfragments( ntfs_attr *na, const s64 pos, s64 count, u64 offset,
_ntfs_frag_append_t append_fragment, void *callback_data )
s64 ntfs_attr_getfragments(ntfs_attr *na, const s64 pos, s64 count, u64 offset, _ntfs_frag_append_t append_fragment,
void *callback_data)
{
s64 ret;
@ -1161,8 +1149,7 @@ s64 ntfs_attr_getfragments( ntfs_attr *na, const s64 pos, s64 count, u64 offset,
na->type, (long long)pos, (long long)count);
*/
ret = ntfs_attr_getfragments_i( na, pos, count, offset,
append_fragment, callback_data );
ret = ntfs_attr_getfragments_i(na, pos, count, offset, append_fragment, callback_data);
//ntfs_log_leave("\n");
return ret;
@ -1419,7 +1406,8 @@ s64 ntfs_attr_pwrite( ntfs_attr *na, const s64 pos, s64 count, const void *b )
{
unsigned int undo_initialized_size : 1;
unsigned int undo_data_size : 1;
} need_to = { 0, 0 };
}need_to =
{ 0, 0};
BOOL makingnonresident = FALSE;
BOOL wasnonresident = FALSE;
BOOL compressed;
@ -4090,7 +4078,6 @@ int ntfs_attr_set_flags( ntfs_inode *ni, ATTR_TYPES type,
return ( res );
}
/**
* ntfs_attr_rm - remove attribute from ntfs inode
* @na: opened ntfs attribute to delete
@ -4647,7 +4634,6 @@ cluster_free_err_out:
return -1;
}
static int ntfs_resident_attr_resize( ntfs_attr *na, const s64 newsize );
/**
@ -5951,7 +5937,6 @@ put_err_out:
return -1;
}
static int ntfs_non_resident_attr_expand( ntfs_attr *na, const s64 newsize )
{
int ret;
@ -6214,8 +6199,6 @@ err_exit:
return ret;
}
int ntfs_attr_exist( ntfs_inode *ni, const ATTR_TYPES type, ntfschar *name,
u32 name_len )
{

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,9 +87,9 @@ 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) {
if (MREF_LE(ale->mft_reference) != ni->mft_no)
return 1;
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));
}
return 0;
@ -117,7 +120,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;
@ -125,37 +129,36 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
mref = MK_LE_MREF(ni->mft_no, le16_to_cpu(ni->mrec->sequence_number));
if (ni->nr_extents == -1)
ni = ni->base_ni;
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;
}
/* Determine size and allocate memory for new attribute list. */
entry_len = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) *
attr->name_length + 7) & ~7;
entry_len = (sizeof(ATTR_LIST_ENTRY) + sizeof(ntfschar) * attr->name_length + 7) & ~7;
new_al = ntfs_calloc(ni->attr_list_size + entry_len);
if (!new_al)
return -1;
if (!new_al) return -1;
/* Find place for the new entry. */
ctx = ntfs_attr_get_search_ctx(ni, NULL);
if (!ctx) {
if (!ctx)
{
err = errno;
goto err_out;
}
if (!ntfs_attr_lookup(attr->type, (attr->name_length) ? (ntfschar*)
((u8*)attr + le16_to_cpu(attr->name_offset)) :
AT_UNNAMED, attr->name_length, CASE_SENSITIVE,
(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)) {
if (!ntfs_attr_lookup(attr->type, (attr->name_length) ? (ntfschar*) ((u8*) attr + le16_to_cpu(attr->name_offset))
: AT_UNNAMED, attr->name_length, CASE_SENSITIVE, (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))
{
/* 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");
@ -163,11 +166,13 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
goto err_out;
}
/* Add new entry after this extent. */
ale = (ATTR_LIST_ENTRY*)((u8*)ctx->al_entry +
le16_to_cpu(ctx->al_entry->length));
} else {
ale = (ATTR_LIST_ENTRY*) ((u8*) ctx->al_entry + le16_to_cpu(ctx->al_entry->length));
}
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);
@ -192,21 +197,21 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
ale->name_offset = offsetof(ATTR_LIST_ENTRY, name);
if (attr->non_resident)
ale->lowest_vcn = attr->lowest_vcn;
else
ale->lowest_vcn = 0;
else ale->lowest_vcn = 0;
ale->mft_reference = mref;
ale->instance = attr->instance;
memcpy(ale->name, (u8 *)attr + le16_to_cpu(attr->name_offset),
attr->name_length * sizeof(ntfschar));
memcpy(ale->name, (u8 *) attr + le16_to_cpu(attr->name_offset), attr->name_length * sizeof(ntfschar));
/* 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;
@ -214,8 +219,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
/* Copy entries from old attribute list to new. */
memcpy(new_al, ni->attr_list, entry_offset);
memcpy(new_al + entry_offset + entry_len, ni->attr_list +
entry_offset, ni->attr_list_size - entry_offset);
memcpy(new_al + entry_offset + entry_len, ni->attr_list + entry_offset, ni->attr_list_size - entry_offset);
/* Set new runlist. */
free(ni->attr_list);
@ -225,9 +229,7 @@ int ntfs_attrlist_entry_add(ntfs_inode *ni, ATTR_RECORD *attr)
/* Done! */
ntfs_attr_close(na);
return 0;
err_out:
if (na)
ntfs_attr_close(na);
err_out: if (na) ntfs_attr_close(na);
free(new_al);
errno = err;
return -1;
@ -250,7 +252,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;
@ -258,8 +261,7 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
if (ctx->base_ntfs_ino)
base_ni = ctx->base_ntfs_ino;
else
base_ni = ctx->ntfs_ino;
else base_ni = ctx->ntfs_ino;
ale = ctx->al_entry;
ntfs_log_trace("Entering for inode 0x%llx, attr 0x%x, lowest_vcn %lld.\n",
@ -267,7 +269,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;
@ -276,17 +279,18 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
/* Allocate memory for new attribute list. */
new_al_len = base_ni->attr_list_size - le16_to_cpu(ale->length);
new_al = ntfs_calloc(new_al_len);
if (!new_al)
return -1;
if (!new_al) return -1;
/* 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;
@ -305,9 +309,7 @@ int ntfs_attrlist_entry_rm(ntfs_attr_search_ctx *ctx)
/* Done! */
ntfs_attr_close(na);
return 0;
err_out:
if (na)
ntfs_attr_close(na);
err_out: if (na) ntfs_attr_close(na);
free(new_al);
errno = err;
return -1;

View File

@ -44,8 +44,7 @@ static __inline__ void ntfs_attrlist_mark_dirty(ntfs_inode *ni)
{
if (ni->nr_extents == -1)
NInoAttrListSetDirty(ni->base_ni);
else
NInoAttrListSetDirty(ni);
else NInoAttrListSetDirty(ni);
}
#endif /* defined _NTFS_ATTRLIST_H */

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

@ -55,12 +55,10 @@
*/
void ntfs_bit_set(u8 *bitmap, const u64 bit, const u8 new_value)
{
if (!bitmap || new_value > 1)
return;
if (!bitmap || new_value > 1) return;
if (!new_value)
bitmap[bit >> 3] &= ~(1 << (bit & 7));
else
bitmap[bit >> 3] |= (1 << (bit & 7));
else bitmap[bit >> 3] |= (1 << (bit & 7));
}
/**
@ -73,8 +71,7 @@ void ntfs_bit_set(u8 *bitmap, const u64 bit, const u8 new_value)
*/
char ntfs_bit_get(const u8 *bitmap, const u64 bit)
{
if (!bitmap)
return -1;
if (!bitmap) return -1;
return (bitmap[bit >> 3] >> (bit & 7)) & 1;
}
@ -91,12 +88,10 @@ char ntfs_bit_get_and_set(u8 *bitmap, const u64 bit, const u8 new_value)
{
register u8 old_bit, shift;
if (!bitmap || new_value > 1)
return -1;
if (!bitmap || new_value > 1) return -1;
shift = bit & 7;
old_bit = (bitmap[bit >> 3] >> shift) & 1;
if (new_value != old_bit)
bitmap[bit >> 3] ^= 1 << shift;
if (new_value != old_bit) bitmap[bit >> 3] ^= 1 << shift;
return old_bit;
}
@ -112,14 +107,14 @@ char ntfs_bit_get_and_set(u8 *bitmap, const u64 bit, const u8 new_value)
*
* On success return 0 and on error return -1 with errno set to the error code.
*/
static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
s64 count, int value)
static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit, s64 count, int value)
{
s64 bufsize, br;
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);
@ -129,36 +124,34 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
bit = start_bit & 7;
if (bit)
firstbyte = 1;
else
firstbyte = 0;
else firstbyte = 0;
/* Calculate the required buffer size in bytes, capping it at 8kiB. */
bufsize = ((count - (bit ? 8 - bit : 0) + 7) >> 3) + firstbyte;
if (bufsize > 8192)
bufsize = 8192;
if (bufsize > 8192) bufsize = 8192;
buf = ntfs_malloc(bufsize);
if (!buf)
return -1;
if (!buf) return -1;
/* Depending on @value, zero or set all bits in the allocated buffer. */
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 >= 0)
errno = EIO;
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
*buf &= ~(1 << bit++);
else *buf &= ~(1 << bit++);
}
/* Update @start_bit to the new position. */
start_bit = (start_bit + 7) & ~7;
@ -168,11 +161,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,27 +176,27 @@ 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) {
br = ntfs_attr_pread(na, (start_bit + count) >> 3, 1, lastbyte_buf);
if (br != 1)
{
// FIXME: Eeek! We need rollback! (AIA)
if (br >= 0)
errno = EIO;
if (br >= 0) errno = EIO;
ntfs_log_perror("Reading of last byte "
"failed (%lld). Leaving inconsistent "
"metadata", (long long)br);
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
*lastbyte_buf &= ~(1 << --bit);
else *lastbyte_buf &= ~(1 << --bit);
}
/* We don't want to come back here... */
bit = 0;
@ -212,10 +208,10 @@ 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;
if (br >= 0) errno = EIO;
ntfs_log_perror("Failed to write buffer to bitmap "
"(%lld != %lld). Leaving inconsistent metadata",
(long long)br, (long long)bufsize);
@ -224,7 +220,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
@ -234,10 +231,10 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
}
start_bit += tmp;
count -= tmp;
if (bufsize > (tmp = (count + 7) >> 3))
bufsize = tmp;
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",
@ -249,8 +246,7 @@ static int ntfs_bitmap_set_bits_in_run(ntfs_attr *na, s64 start_bit,
ret = 0;
free_err_out:
free(buf);
free_err_out: free(buf);
return ret;
}

View File

@ -65,22 +65,31 @@ 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) {
if (le16_to_cpu(b->bpb.bytes_per_sector) < 256 || 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) {
case 1: case 2: case 4: case 8: case 16: case 32: case 64: case 128:
switch (b->bpb.sectors_per_cluster)
{
case 1:
case 2:
case 4:
case 8:
case 16:
case 32:
case 64:
case 128:
break;
default:
ntfs_log_error("Unexpected sectors per cluster value (%d).\n",
@ -89,20 +98,17 @@ 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) {
i = (u32) le16_to_cpu(b->bpb.bytes_per_sector) * b->bpb.sectors_per_cluster;
if (i > 65536)
{
ntfs_log_error("Unexpected cluster size (%d).\n", i);
goto not_ntfs;
}
ntfs_log_debug("Checking reserved fields are zero.\n");
if (le16_to_cpu(b->bpb.reserved_sectors) ||
le16_to_cpu(b->bpb.root_entries) ||
le16_to_cpu(b->bpb.sectors) ||
le16_to_cpu(b->bpb.sectors_per_fat) ||
le32_to_cpu(b->bpb.large_sectors) ||
b->bpb.fats) {
if (le16_to_cpu(b->bpb.reserved_sectors) || le16_to_cpu(b->bpb.root_entries) || le16_to_cpu(b->bpb.sectors)
|| le16_to_cpu(b->bpb.sectors_per_fat) || le32_to_cpu(b->bpb.large_sectors) || 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),
@ -115,10 +121,17 @@ 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) {
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
if ((u8) b->clusters_per_mft_record < 0xe1 || (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:
ntfs_log_error("Unexpected clusters per mft record "
@ -128,10 +141,17 @@ 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) {
case 1: case 2: case 4: case 8: case 0x10: case 0x20: case 0x40:
if ((u8) b->clusters_per_index_record < 0xe1 || (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:
ntfs_log_error("Unexpected clusters per index record "
@ -147,12 +167,10 @@ BOOL ntfs_boot_sector_is_ntfs(NTFS_BOOT_SECTOR *b)
ntfs_log_debug("Bootsector check completed successfully.\n");
ret = TRUE;
not_ntfs:
return ret;
not_ntfs: return ret;
}
static const char *last_sector_error =
"HINTS: Either the volume is a RAID/LDM but it wasn't setup yet,\n"
static const char *last_sector_error = "HINTS: Either the volume is a RAID/LDM but it wasn't setup yet,\n"
" or it was not setup correctly (e.g. by not using mdadm --build ...),\n"
" or a wrong device is tried to be mounted,\n"
" or the partition table is corrupt (partition is smaller than NTFS),\n"
@ -188,7 +206,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 +215,13 @@ 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) {
if (vol->dev->d_ops->seek(vol->dev, (sectors - 1) << vol->sector_size_bits, SEEK_SET) == -1)
{
ntfs_log_perror("Failed to read last sector (%lld)",
(long long)sectors);
ntfs_log_error("%s", last_sector_error);
@ -215,8 +234,8 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
vol->mftmirr_lcn = sle64_to_cpu(bs->mftmirr_lcn);
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) {
if (vol->mft_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 +244,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;
@ -248,9 +268,9 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
*/
if (c < 0)
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)) {
else vol->mft_record_size = c << vol->cluster_size_bits;
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;
@ -263,8 +283,7 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
ntfs_log_debug("ClustersPerINDXRecord = 0x%x\n", c);
if (c < 0)
vol->indx_record_size = 1 << -c;
else
vol->indx_record_size = c << vol->cluster_size_bits;
else vol->indx_record_size = c << vol->cluster_size_bits;
vol->indx_record_size_bits = ffs(vol->indx_record_size) - 1;
ntfs_log_debug("INDXRecordSize = 0x%x\n", (unsigned)vol->indx_record_size);
ntfs_log_debug("INDXRecordSizeBits = %u\n", vol->indx_record_size_bits);
@ -278,8 +297,7 @@ int ntfs_boot_sector_parse(ntfs_volume *vol, const NTFS_BOOT_SECTOR *bs)
*/
if (vol->cluster_size <= 4 * vol->mft_record_size)
vol->mftmirr_size = 4;
else
vol->mftmirr_size = vol->cluster_size / vol->mft_record_size;
else vol->mftmirr_size = vol->cluster_size / vol->mft_record_size;
return 0;
}

View File

@ -60,34 +60,39 @@
* Do not call when a record has been modified (with no key change)
*/
static void inserthashindex(struct CACHE_HEADER *cache,
struct CACHED_GENERIC *current)
static void inserthashindex(struct CACHE_HEADER *cache, struct CACHED_GENERIC *current)
{
int h;
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)
link->next = first;
else
link->next = NULL;
else 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);
@ -100,35 +105,41 @@ static void inserthashindex(struct CACHE_HEADER *cache,
* Drop a hash index when a record is about to be deleted
*/
static void drophashindex(struct CACHE_HEADER *cache,
const struct CACHED_GENERIC *current, int hash)
static void drophashindex(struct CACHE_HEADER *cache, const struct CACHED_GENERIC *current, int hash)
{
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;
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);
@ -144,8 +155,8 @@ static void drophashindex(struct CACHE_HEADER *cache,
* The returned entry may be modified, but not freed
*/
struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache,
const struct CACHED_GENERIC *wanted, cache_compare compare)
struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache, const struct CACHED_GENERIC *wanted,
cache_compare compare)
{
struct CACHED_GENERIC *current;
struct CACHED_GENERIC *previous;
@ -153,8 +164,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
@ -163,38 +176,36 @@ struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache,
link = cache->first_hash[h];
while (link && compare(link->entry, wanted))
link = link->next;
if (link)
current = link->entry;
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)) {
while (current && 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
*/
previous->next = current->next;
if (current->next)
current->next->previous
= current->previous;
else
cache->oldest_entry
= current->previous;
current->next->previous = current->previous;
else cache->oldest_entry = current->previous;
current->next = cache->most_recent_entry;
current->previous
= (struct CACHED_GENERIC*)NULL;
current->previous = (struct CACHED_GENERIC*) NULL;
cache->most_recent_entry->previous = current;
cache->most_recent_entry = current;
}
@ -209,8 +220,7 @@ struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache,
* returns the cache entry or NULL if not possible
*/
struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
const struct CACHED_GENERIC *item,
struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache, const struct CACHED_GENERIC *item,
cache_compare compare)
{
struct CACHED_GENERIC *current;
@ -219,8 +229,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 +241,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
@ -241,13 +255,14 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
* kept.
*/
current = cache->most_recent_entry;
while (current
&& compare(current, item)) {
while (current && 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,54 +271,53 @@ 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) {
current->variable = ntfs_malloc(
item->varsize);
} else
current->variable = (void*)NULL;
if (item->varsize)
{
current->variable = ntfs_malloc(item->varsize);
}
else current->variable = (void*) NULL;
current->varsize = item->varsize;
if (!cache->oldest_entry)
cache->oldest_entry = current;
} else {
if (!cache->oldest_entry) cache->oldest_entry = current;
}
else
{
/* reusing the oldest entry */
current = cache->oldest_entry;
before = current->previous;
before->next = (struct CACHED_GENERIC*) NULL;
if (cache->dohash)
drophashindex(cache,current,
cache->dohash(current));
if (cache->dofree)
cache->dofree(current);
if (cache->dohash) drophashindex(cache, current, cache->dohash(current));
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,
item->varsize);
current->variable = realloc(current->variable, item->varsize);
else current->variable = ntfs_malloc(item->varsize);
}
else
current->variable = ntfs_malloc(
item->varsize);
} else {
if (current->varsize)
free(current->variable);
{
if (current->varsize) free(current->variable);
current->variable = (void*) NULL;
}
current->varsize = item->varsize;
}
current->next = cache->most_recent_entry;
current->previous = (struct CACHED_GENERIC*) NULL;
if (cache->most_recent_entry)
cache->most_recent_entry->previous = current;
if (cache->most_recent_entry) 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) {
memcpy(current->variable,
item->variable, item->varsize);
} else {
if (item->varsize)
{
if (current->variable)
{
memcpy(current->variable, item->variable, item->varsize);
}
else
{
/*
* no more memory for variable part
* recycle entry in free list
@ -314,12 +328,13 @@ 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;
}
if (cache->dohash && current)
inserthashindex(cache,current);
if (cache->dohash && current) inserthashindex(cache, current);
}
cache->writes++;
}
@ -332,33 +347,27 @@ struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
* A specific function may be called for entry deletion
*/
static void do_invalidate(struct CACHE_HEADER *cache,
struct CACHED_GENERIC *current, int flags)
static void do_invalidate(struct CACHE_HEADER *cache, struct CACHED_GENERIC *current, int flags)
{
struct CACHED_GENERIC *previous;
previous = current->previous;
if ((flags & CACHE_FREE) && cache->dofree)
cache->dofree(current);
if ((flags & CACHE_FREE) && cache->dofree) cache->dofree(current);
/*
* Relink into free list
*/
if (current->next)
current->next->previous = current->previous;
else
cache->oldest_entry = current->previous;
else cache->oldest_entry = current->previous;
if (previous)
previous->next = current->next;
else
cache->most_recent_entry = current->next;
else cache->most_recent_entry = current->next;
current->next = cache->free_entry;
cache->free_entry = current;
if (current->variable)
free(current->variable);
if (current->variable) free(current->variable);
current->varsize = 0;
}
/*
* Invalidate entries in cache
*
@ -371,8 +380,7 @@ static void do_invalidate(struct CACHE_HEADER *cache,
* supposed to be found.
*/
int ntfs_invalidate_cache(struct CACHE_HEADER *cache,
const struct CACHED_GENERIC *item, cache_compare compare,
int ntfs_invalidate_cache(struct CACHE_HEADER *cache, const struct CACHED_GENERIC *item, cache_compare compare,
int flags)
{
struct CACHED_GENERIC *current;
@ -384,45 +392,52 @@ 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);
do_invalidate(cache, current, flags);
count++;
}
}
}
}
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,
cache->dohash(current));
if (cache->dohash) drophashindex(cache, current, cache->dohash(current));
do_invalidate(cache, current, flags);
current = next;
count++;
} else {
}
else
{
previous = current;
current = current->next;
}
@ -432,15 +447,14 @@ int ntfs_invalidate_cache(struct CACHE_HEADER *cache,
return (count);
}
int ntfs_remove_cache(struct CACHE_HEADER *cache,
struct CACHED_GENERIC *item, int flags)
int ntfs_remove_cache(struct CACHE_HEADER *cache, struct CACHED_GENERIC *item, int flags)
{
int count;
count = 0;
if (cache) {
if (cache->dohash)
drophashindex(cache,item,cache->dohash(item));
if (cache)
{
if (cache->dohash) drophashindex(cache, item, cache->dohash(item));
do_invalidate(cache, item, flags);
count++;
}
@ -455,12 +469,12 @@ 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->dofree)
cache->dofree(entry);
if (entry->variable)
free(entry->variable);
if (cache)
{
for (entry = cache->most_recent_entry; entry; entry = entry->next)
{
if (cache->dofree) cache->dofree(entry);
if (entry->variable) free(entry->variable);
}
free(cache);
}
@ -472,10 +486,8 @@ static void ntfs_free_cache(struct CACHE_HEADER *cache)
* Returns the cache header, or NULL if the cache could not be created
*/
static struct CACHE_HEADER *ntfs_create_cache(const char *name,
cache_free dofree, cache_hash dohash,
int full_item_size,
int item_count, int max_hash)
static struct CACHE_HEADER *ntfs_create_cache(const char *name, cache_free dofree, cache_hash dohash,
int full_item_size, int item_count, int max_hash)
{
struct CACHE_HEADER *cache;
struct CACHED_GENERIC *pc;
@ -487,18 +499,20 @@ static struct CACHE_HEADER *ntfs_create_cache(const char *name,
int i;
size = sizeof(struct CACHE_HEADER) + item_count * full_item_size;
if (max_hash)
size += item_count*sizeof(struct HASH_ENTRY)
+ max_hash*sizeof(struct HASH_ENTRY*);
if (max_hash) 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,9 +525,9 @@ 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++) {
qc = (struct CACHED_GENERIC*)((char*)pc
+ full_item_size);
for (i = 0; i < (item_count - 1); i++)
{
qc = (struct CACHED_GENERIC*) ((char*) pc + full_item_size);
pc->next = qc;
pc->variable = (void*) NULL;
pc->varsize = 0;
@ -524,17 +538,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 +559,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;
}
@ -561,29 +580,24 @@ void ntfs_create_lru_caches(ntfs_volume *vol)
{
#if CACHE_INODE_SIZE
/* inode cache */
vol->xinode_cache = ntfs_create_cache("inode",(cache_free)NULL,
ntfs_dir_inode_hash, sizeof(struct CACHED_INODE),
vol->xinode_cache = ntfs_create_cache("inode", (cache_free) NULL, ntfs_dir_inode_hash, sizeof(struct CACHED_INODE),
CACHE_INODE_SIZE, 2 * CACHE_INODE_SIZE);
#endif
#if CACHE_NIDATA_SIZE
/* idata cache */
vol->nidata_cache = ntfs_create_cache("nidata",
ntfs_inode_nidata_free, ntfs_inode_nidata_hash,
sizeof(struct CACHED_NIDATA),
CACHE_NIDATA_SIZE, 2*CACHE_NIDATA_SIZE);
vol->nidata_cache = ntfs_create_cache("nidata", ntfs_inode_nidata_free, ntfs_inode_nidata_hash,
sizeof(struct CACHED_NIDATA), CACHE_NIDATA_SIZE, 2 * CACHE_NIDATA_SIZE);
#endif
#if CACHE_LOOKUP_SIZE
/* lookup cache */
vol->lookup_cache = ntfs_create_cache("lookup",
(cache_free)NULL, ntfs_dir_lookup_hash,
sizeof(struct CACHED_LOOKUP),
CACHE_LOOKUP_SIZE, 2*CACHE_LOOKUP_SIZE);
vol->lookup_cache = ntfs_create_cache("lookup", (cache_free) NULL, ntfs_dir_lookup_hash,
sizeof(struct CACHED_LOOKUP), CACHE_LOOKUP_SIZE, 2 * CACHE_LOOKUP_SIZE);
#endif
vol->securid_cache = ntfs_create_cache("securid",(cache_free)NULL,
(cache_hash)NULL,sizeof(struct CACHED_SECURID), CACHE_SECURID_SIZE, 0);
vol->securid_cache = ntfs_create_cache("securid", (cache_free) NULL, (cache_hash) NULL,
sizeof(struct CACHED_SECURID), CACHE_SECURID_SIZE, 0);
#if CACHE_LEGACY_SIZE
vol->legacy_cache = ntfs_create_cache("legacy",(cache_free)NULL,
(cache_hash)NULL, sizeof(struct CACHED_PERMISSIONS_LEGACY), CACHE_LEGACY_SIZE, 0);
vol->legacy_cache = ntfs_create_cache("legacy", (cache_free) NULL, (cache_hash) NULL,
sizeof(struct CACHED_PERMISSIONS_LEGACY), CACHE_LEGACY_SIZE, 0);
#endif
}

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,22 +70,23 @@ struct CACHED_LOOKUP {
u64 inum;
};
enum {
CACHE_FREE = 1,
CACHE_NOHASH = 2
enum
{
CACHE_FREE = 1, CACHE_NOHASH = 2
};
typedef int (*cache_compare)(const struct CACHED_GENERIC *cached,
const struct CACHED_GENERIC *item);
typedef int (*cache_compare)(const struct CACHED_GENERIC *cached, const struct CACHED_GENERIC *item);
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;
@ -100,17 +106,13 @@ struct CACHE_HEADER {
/* cast to generic, avoiding gcc warnings */
#define GENERIC(pstr) ((const struct CACHED_GENERIC*)(const void*)(pstr))
struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache,
const struct CACHED_GENERIC *wanted,
struct CACHED_GENERIC *ntfs_fetch_cache(struct CACHE_HEADER *cache, const struct CACHED_GENERIC *wanted,
cache_compare compare);
struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache,
const struct CACHED_GENERIC *item,
struct CACHED_GENERIC *ntfs_enter_cache(struct CACHE_HEADER *cache, const struct CACHED_GENERIC *item,
cache_compare compare);
int ntfs_invalidate_cache(struct CACHE_HEADER *cache,
const struct CACHED_GENERIC *item,
cache_compare compare, int flags);
int ntfs_remove_cache(struct CACHE_HEADER *cache,
struct CACHED_GENERIC *item, int flags);
int ntfs_invalidate_cache(struct CACHE_HEADER *cache, const struct CACHED_GENERIC *item, cache_compare compare,
int flags);
int ntfs_remove_cache(struct CACHE_HEADER *cache, struct CACHED_GENERIC *item, int flags);
void ntfs_create_lru_caches(ntfs_volume *vol);
void ntfs_free_lru_caches(ntfs_volume *vol);

View File

@ -45,23 +45,28 @@
#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;
}
@ -71,14 +76,15 @@ NTFS_CACHE* _NTFS_cache_constructor (unsigned int numberOfPages, unsigned int se
cache->sectorsPerPage = sectorsPerPage;
cache->sectorSize = sectorSize;
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,21 +134,26 @@ 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(!cache->disc->writeSectors(cacheEntries[oldUsed].sector,cacheEntries[oldUsed].count,cacheEntries[oldUsed].cache)) return NULL;
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;
}
sector = (sector / sectorsPerPage) * sectorsPerPage; // align base sector to page size
@ -155,7 +169,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 +178,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 +210,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,15 +249,25 @@ 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) {
case 1: *value = buf[0]; break;
case 2: *value = u8array_to_u16(buf,0); break;
case 4: *value = u8array_to_u32(buf,0); break;
default: return false;
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;
default:
return false;
}
return true;
}
@ -244,7 +276,8 @@ bool _NTFS_cache_readLittleEndianValue (NTFS_CACHE* cache, uint32_t *value, sec_
Writes some data to a cache page, making sure it is loaded into memory first.
*/
bool _NTFS_cache_writePartialSector (NTFS_CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size)
bool _NTFS_cache_writePartialSector(NTFS_CACHE* cache, const void* buffer, sec_t sector, unsigned int offset,
size_t size)
{
sec_t sec;
NTFS_CACHE_ENTRY *entry;
@ -261,14 +294,24 @@ 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) {
case 1: buf[0] = value; break;
case 2: u16_to_u8array(buf, 0, value); break;
case 4: u32_to_u8array(buf, 0, value); break;
default: return false;
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;
default:
return false;
}
return _NTFS_cache_writePartialSector(cache, buf, sector, offset, size);
@ -278,7 +321,8 @@ bool _NTFS_cache_writeLittleEndianValue (NTFS_CACHE* cache, const uint32_t value
Writes some data to a cache page, zeroing out the page first
*/
bool _NTFS_cache_eraseWritePartialSector (NTFS_CACHE* cache, const void* buffer, sec_t sector, unsigned int offset, size_t size)
bool _NTFS_cache_eraseWritePartialSector(NTFS_CACHE* cache, const void* buffer, sec_t sector, unsigned int offset,
size_t size)
{
sec_t sec;
NTFS_CACHE_ENTRY *entry;
@ -307,9 +351,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 +378,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 +391,18 @@ 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 +412,14 @@ 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;
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;
@ -127,9 +129,9 @@ Clear out the contents of the NTFS_CACHE without writing any dirty sectors first
*/
void _NTFS_cache_invalidate(NTFS_CACHE* NTFS_CACHE);
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);
void _NTFS_cache_destructor(NTFS_CACHE* NTFS_CACHE);
#endif // _CACHE_H

View File

@ -52,19 +52,18 @@
*
* Returns:
*/
static int ntfs_collate_binary(ntfs_volume *vol __attribute__((unused)),
const void *data1, const int data1_len,
const void *data2, const int data2_len)
static int ntfs_collate_binary(ntfs_volume *vol __attribute__((unused)), const void *data1, const int data1_len, const void *data2,
const int data2_len)
{
int rc;
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
rc = 1;
else rc = 1;
}
ntfs_log_trace("Done, returning %i.\n", rc);
return rc;
@ -82,15 +81,15 @@ static int ntfs_collate_binary(ntfs_volume *vol __attribute__((unused)),
*
* Returns:
*/
static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)),
const void *data1, const int data1_len,
const void *data2, const int data2_len)
static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)), const void *data1, const int data1_len, const void *data2,
const int data2_len)
{
int rc;
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,11 +97,11 @@ 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
rc = 1;
else rc = 1;
}
ntfs_log_trace("Done, returning %i.\n", rc);
return rc;
@ -114,9 +113,8 @@ static int ntfs_collate_ntofs_ulong(ntfs_volume *vol __attribute__((unused)),
* Returns: -1, 0 or 1 depending of how the arrays compare
*/
static int ntfs_collate_ntofs_ulongs(ntfs_volume *vol __attribute__((unused)),
const void *data1, const int data1_len,
const void *data2, const int data2_len)
static int ntfs_collate_ntofs_ulongs(ntfs_volume *vol __attribute__((unused)), const void *data1, const int data1_len, const void *data2,
const int data2_len)
{
int rc;
int len;
@ -124,14 +122,16 @@ 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);
@ -139,11 +139,11 @@ static int ntfs_collate_ntofs_ulongs(ntfs_volume *vol __attribute__((unused)),
} while ((d1 == d2) && ((len -= 4) > 0));
if (d1 < d2)
rc = -1;
else {
else
{
if (d1 == d2)
rc = 0;
else
rc = 1;
else rc = 1;
}
ntfs_log_trace("Done, returning %i.\n", rc);
return rc;
@ -162,8 +162,7 @@ static int ntfs_collate_ntofs_ulongs(ntfs_volume *vol __attribute__((unused)),
*
* Returns: -1, 0 or 1 depending of how the keys compare
*/
static int ntfs_collate_ntofs_security_hash(ntfs_volume *vol __attribute__((unused)),
const void *data1, const int data1_len,
static int ntfs_collate_ntofs_security_hash(ntfs_volume *vol __attribute__((unused)), const void *data1, const int data1_len,
const void *data2, const int data2_len)
{
int rc;
@ -171,7 +170,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,21 +181,23 @@ 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
rc = 0;
else rc = 0;
}
}
}
@ -215,9 +217,8 @@ static int ntfs_collate_ntofs_security_hash(ntfs_volume *vol __attribute__((unus
*
* Returns:
*/
static int ntfs_collate_file_name(ntfs_volume *vol,
const void *data1, const int data1_len __attribute__((unused)),
const void *data2, const int data2_len __attribute__((unused)))
static int ntfs_collate_file_name(ntfs_volume *vol, const void *data1, const int data1_len __attribute__((unused)), const void *data2,
const int data2_len __attribute__((unused)))
{
const FILE_NAME_ATTR *file_name_attr1;
const FILE_NAME_ATTR *file_name_attr2;
@ -226,12 +227,9 @@ static int ntfs_collate_file_name(ntfs_volume *vol,
ntfs_log_trace("Entering.\n");
file_name_attr1 = (const FILE_NAME_ATTR*) data1;
file_name_attr2 = (const FILE_NAME_ATTR*) data2;
rc = ntfs_names_full_collate(
(ntfschar*)&file_name_attr1->file_name,
file_name_attr1->file_name_length,
(ntfschar*)&file_name_attr2->file_name,
file_name_attr2->file_name_length,
CASE_SENSITIVE, vol->upcase, vol->upcase_len);
rc = ntfs_names_full_collate((ntfschar*) &file_name_attr1->file_name, file_name_attr1->file_name_length,
(ntfschar*) &file_name_attr2->file_name, file_name_attr2->file_name_length, CASE_SENSITIVE, vol->upcase,
vol->upcase_len);
ntfs_log_trace("Done, returning %i.\n", rc);
return rc;
}
@ -246,7 +244,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

@ -39,25 +39,29 @@ int ffs(int x)
{
int r = 1;
if (!x)
return 0;
if (!(x & 0xffff)) {
if (!x) return 0;
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 +124,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:
@ -132,18 +138,16 @@ int daemon(int nochdir, int noclose) {
_exit(0);
}
if (setsid() == -1)
return (-1);
if (setsid() == -1) return (-1);
if (!nochdir)
(void)chdir("/");
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);
if (fd > 2)
(void)close (fd);
if (fd > 2) (void) close(fd);
}
return (0);
}
@ -218,23 +222,25 @@ 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;
char *tok;
if ((s = *stringp) == NULL)
return (NULL);
for (tok = s;;) {
if ((s = *stringp) == NULL) return (NULL);
for (tok = s;;)
{
c = *s++;
spanp = delim;
do {
if ((sc = *spanp++) == c) {
do
{
if ((sc = *spanp++) == c)
{
if (c == 0)
s = NULL;
else
s[-1] = 0;
else s[-1] = 0;
*stringp = s;
return (tok);
}

File diff suppressed because it is too large Load Diff

View File

@ -26,16 +26,12 @@
#include "types.h"
#include "attrib.h"
extern s64 ntfs_compressed_attr_pread(ntfs_attr *na, s64 pos, s64 count,
void *b);
extern s64 ntfs_compressed_attr_pread(ntfs_attr *na, s64 pos, s64 count, void *b);
extern s64 ntfs_compressed_pwrite(ntfs_attr *na, runlist_element *brl, s64 wpos,
s64 offs, s64 to_write, s64 rounded,
const void *b, int compressed_part,
VCN *update_from);
extern s64 ntfs_compressed_pwrite(ntfs_attr *na, runlist_element *brl, s64 wpos, s64 offs, s64 to_write, s64 rounded,
const void *b, int compressed_part, VCN *update_from);
extern int ntfs_compressed_close(ntfs_attr *na, runlist_element *brl,
s64 offs, VCN *update_from);
extern int ntfs_compressed_close(ntfs_attr *na, runlist_element *brl, s64 offs, VCN *update_from);
#endif /* defined _NTFS_COMPRESS_H */

View File

@ -45,20 +45,24 @@
void ntfs_debug_runlist_dump(const runlist_element *rl)
{
int i = 0;
const char *lcn_str[5] = { "LCN_HOLE ", "LCN_RL_NOT_MAPPED",
const char *lcn_str[5] =
{ "LCN_HOLE ", "LCN_RL_NOT_MAPPED",
"LCN_ENOENT ", "LCN_EINVAL ",
"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,7 +71,8 @@ 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,

View File

@ -33,7 +33,9 @@ struct _runlist_element;
#ifdef DEBUG
extern void ntfs_debug_runlist_dump(const struct _runlist_element *rl);
#else
static __inline__ void ntfs_debug_runlist_dump(const struct _runlist_element *rl __attribute__((unused))) {}
static __inline__ void ntfs_debug_runlist_dump(const struct _runlist_element *rl __attribute__((unused)))
{
}
#endif
#define NTFS_BUG(msg) \

View File

@ -103,19 +103,22 @@
* On success return a pointer to the allocated ntfs device structure and on
* error return NULL with errno set to the error code returned by ntfs_malloc().
*/
struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
struct ntfs_device_operations *dops, void *priv_data)
struct ntfs_device *ntfs_device_alloc(const char *name, const long state, struct ntfs_device_operations *dops,
void *priv_data)
{
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,23 +185,22 @@ 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;
}
if (!count)
return 0;
if (!count) return 0;
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)
continue;
if (br > 0) continue;
/* If EOF or error return number of bytes read. */
if (!br || total)
return total;
if (!br || total) return total;
/* Nothing read and error, return error status. */
return br;
}
@ -223,21 +227,21 @@ s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b)
* appropriately to the return code of either seek, write, or set
* to EINVAL in case of invalid arguments.
*/
s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
const void *b)
s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count, const void *b)
{
s64 written, total, ret = -1;
struct ntfs_device_operations *dops;
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 (!count) return 0;
if (NDevReadOnly(dev))
{
errno = EROFS;
goto out;
}
@ -245,24 +249,21 @@ 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) {
written = dops->pwrite(dev, (const char*)b + total, count,
pos + total);
for (total = 0; count; count -= written, total += written)
{
written = dops->pwrite(dev, (const char*) b + total, count, pos + total);
/* If everything ok, continue. */
if (written > 0)
continue;
if (written > 0) continue;
/*
* If nothing written or error return number of bytes written.
*/
if (!written || total)
break;
if (!written || total) break;
/* Nothing written and error, return error status. */
total = written;
break;
}
ret = total;
out:
return ret;
out: return ret;
}
/**
@ -294,19 +295,18 @@ out:
* sector transfer error. This should be detected by the caller by checking for
* the magic being "BAAD".
*/
s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count,
const u32 bksize, void *b)
s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count, const u32 bksize, void *b)
{
s64 br, i;
if (bksize & (bksize - 1) || bksize % NTFS_BLOCK_SIZE) {
if (bksize & (bksize - 1) || bksize % NTFS_BLOCK_SIZE)
{
errno = EINVAL;
return -1;
}
/* Do the read. */
br = ntfs_pread(dev, pos, count * bksize, b);
if (br < 0)
return br;
if (br < 0) return br;
/*
* Apply fixups to successfully read data, disregarding any errors
* returned from the MST fixup function. This is because we want to
@ -315,8 +315,7 @@ s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count,
*/
count = br / bksize;
for (i = 0; i < count; ++i)
ntfs_mst_post_read_fixup((NTFS_RECORD*)
((u8*)b + i * bksize), bksize);
ntfs_mst_post_read_fixup((NTFS_RECORD*) ((u8*) b + i * bksize), bksize);
/* Finally, return the number of complete blocks read. */
return count;
}
@ -351,27 +350,26 @@ s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count,
* simulating an mst read on the written data. This way cache coherency is
* achieved.
*/
s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
const u32 bksize, void *b)
s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count, const u32 bksize, void *b)
{
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;
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) {
err = ntfs_mst_pre_write_fixup((NTFS_RECORD*) ((u8*) b + i * bksize), bksize);
if (err < 0)
{
/* Abort write at this position. */
if (!i)
return err;
if (!i) return err;
count = i;
break;
}
@ -381,8 +379,7 @@ s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
/* Quickly deprotect the data again. */
for (i = 0; i < count; ++i)
ntfs_mst_post_write_fixup((NTFS_RECORD*) ((u8*) b + i * bksize));
if (written <= 0)
return written;
if (written <= 0) return written;
/* Finally, return the number of complete blocks written. */
return written / bksize;
}
@ -398,25 +395,26 @@ s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
* volume @vol into buffer @b. Return number of clusters read or -1 on error,
* with errno set to the error code.
*/
s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count,
void *b)
s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count, void *b)
{
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,
(long long)lcn + count);
return -1;
}
br = ntfs_pread(vol->dev, lcn << vol->cluster_size_bits,
count << vol->cluster_size_bits, b);
if (br < 0) {
br = ntfs_pread(vol->dev, lcn << vol->cluster_size_bits, count << vol->cluster_size_bits, b);
if (br < 0)
{
ntfs_log_perror("Error reading cluster(s)");
return br;
}
@ -434,16 +432,17 @@ s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count,
* buffer @b to volume @vol. Return the number of clusters written or -1 on
* error, with errno set to the error code.
*/
s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
const s64 count, const void *b)
s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn, const s64 count, const void *b)
{
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,
@ -451,11 +450,10 @@ s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
return -1;
}
if (!NVolReadOnly(vol))
bw = ntfs_pwrite(vol->dev, lcn << vol->cluster_size_bits,
count << vol->cluster_size_bits, b);
else
bw = count << vol->cluster_size_bits;
if (bw < 0) {
bw = ntfs_pwrite(vol->dev, lcn << vol->cluster_size_bits, count << vol->cluster_size_bits, b);
else bw = count << vol->cluster_size_bits;
if (bw < 0)
{
ntfs_log_perror("Error writing cluster(s)");
return bw;
}
@ -476,9 +474,7 @@ static int ntfs_device_offset_valid(struct ntfs_device *dev, s64 ofs)
{
char ch;
if (dev->d_ops->seek(dev, ofs, SEEK_SET) >= 0 &&
dev->d_ops->read(dev, &ch, 1) == 1)
return 0;
if (dev->d_ops->seek(dev, ofs, SEEK_SET) >= 0 && dev->d_ops->read(dev, &ch, 1) == 1) return 0;
return -1;
}
@ -498,14 +494,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 +514,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 +525,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,13 +541,13 @@ 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))
low = mid;
else
high = mid;
else high = mid;
}
dev->d_ops->seek(dev, 0LL, SEEK_SET);
return (low + 1LL) / block_size;
@ -567,14 +567,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 +602,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 +638,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 +674,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 +683,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;
@ -701,17 +709,18 @@ int ntfs_device_sector_size_get(struct ntfs_device *dev)
* EOPNOTSUPP System does not support BLKBSZSET ioctl
* ENOTTY @dev is a file or a device not supporting BLKBSZSET
*/
int ntfs_device_block_size_set(struct ntfs_device *dev,
int block_size __attribute__((unused)))
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;
@ -722,8 +731,7 @@ int ntfs_device_block_size_set(struct ntfs_device *dev,
}
#else
/* If not a block device, pretend it was successful. */
if (!NDevBlock(dev))
return 0;
if (!NDevBlock(dev)) return 0;
errno = EOPNOTSUPP;
#endif
return -1;

View File

@ -36,11 +36,13 @@
*
* 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. */
ND_Block, /* 1: Device is a block device. */
ND_Block,
/* 1: Device is a block device. */
} ntfs_device_state_bits;
#define test_ndev_flag(nd, flag) test_bit(ND_##flag, (nd)->d_state)
@ -69,7 +71,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,38 +88,32 @@ 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);
s64 (*read)(struct ntfs_device *dev, void *buf, s64 count);
s64 (*write)(struct ntfs_device *dev, const void *buf, s64 count);
s64 (*pread)(struct ntfs_device *dev, void *buf, s64 count, s64 offset);
s64 (*pwrite)(struct ntfs_device *dev, const void *buf, s64 count,
s64 offset);
s64 (*pwrite)(struct ntfs_device *dev, const void *buf, s64 count, s64 offset);
int (*sync)(struct ntfs_device *dev);
int (*stat)(struct ntfs_device *dev, struct stat *buf);
int (*ioctl)(struct ntfs_device *dev, int request, void *argp);
};
extern struct ntfs_device *ntfs_device_alloc(const char *name, const long state,
struct ntfs_device_operations *dops, void *priv_data);
extern struct ntfs_device *ntfs_device_alloc(const char *name, const long state, struct ntfs_device_operations *dops,
void *priv_data);
extern int ntfs_device_free(struct ntfs_device *dev);
extern s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count,
void *b);
extern s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
const void *b);
extern s64 ntfs_pread(struct ntfs_device *dev, const s64 pos, s64 count, void *b);
extern s64 ntfs_pwrite(struct ntfs_device *dev, const s64 pos, s64 count, const void *b);
extern s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count,
const u32 bksize, void *b);
extern s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count,
const u32 bksize, void *b);
extern s64 ntfs_mst_pread(struct ntfs_device *dev, const s64 pos, s64 count, const u32 bksize, void *b);
extern s64 ntfs_mst_pwrite(struct ntfs_device *dev, const s64 pos, s64 count, const u32 bksize, void *b);
extern s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn,
const s64 count, void *b);
extern s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn,
const s64 count, const void *b);
extern s64 ntfs_cluster_read(const ntfs_volume *vol, const s64 lcn, const s64 count, void *b);
extern s64 ntfs_cluster_write(const ntfs_volume *vol, const s64 lcn, const s64 count, const void *b);
extern s64 ntfs_device_size_get(struct ntfs_device *dev, int block_size);
extern s64 ntfs_device_partition_start_sector_get(struct ntfs_device *dev);

View File

@ -45,7 +45,8 @@
/**
* struct hd_geometry -
*/
struct hd_geometry {
struct hd_geometry
{
unsigned char heads;
unsigned char sectors;
unsigned short cylinders;
@ -70,7 +71,6 @@ struct hd_geometry {
#endif /* __CYGWIN32__ */
/* Forward declaration. */
struct ntfs_device_operations;

File diff suppressed because it is too large Load Diff

View File

@ -59,27 +59,21 @@ extern ntfschar NTFS_INDEX_O[3];
extern ntfschar NTFS_INDEX_Q[3];
extern ntfschar NTFS_INDEX_R[3];
extern u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni,
const ntfschar *uname, const int uname_len);
extern u64 ntfs_inode_lookup_by_name(ntfs_inode *dir_ni, const ntfschar *uname, const int uname_len);
extern u64 ntfs_inode_lookup_by_mbsname(ntfs_inode *dir_ni, const char *name);
extern void ntfs_inode_update_mbsname(ntfs_inode *dir_ni, const char *name,
u64 inum);
extern void ntfs_inode_update_mbsname(ntfs_inode *dir_ni, const char *name, u64 inum);
extern ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent,
const char *pathname);
extern ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid,
ntfschar *name, u8 name_len, mode_t type);
extern ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid,
ntfschar *name, u8 name_len, mode_t type, dev_t dev);
extern ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid,
ntfschar *name, u8 name_len, ntfschar *target, int target_len);
extern ntfs_inode *ntfs_pathname_to_inode(ntfs_volume *vol, ntfs_inode *parent, const char *pathname);
extern ntfs_inode *ntfs_create(ntfs_inode *dir_ni, le32 securid, ntfschar *name, u8 name_len, mode_t type);
extern ntfs_inode *ntfs_create_device(ntfs_inode *dir_ni, le32 securid, ntfschar *name, u8 name_len, mode_t type,
dev_t dev);
extern ntfs_inode *ntfs_create_symlink(ntfs_inode *dir_ni, le32 securid, ntfschar *name, u8 name_len, ntfschar *target,
int target_len);
extern int ntfs_check_empty_dir(ntfs_inode *ni);
extern int ntfs_delete(ntfs_volume *vol, const char *path,
ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name,
extern int ntfs_delete(ntfs_volume *vol, const char *path, ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name,
u8 name_len);
extern int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name,
u8 name_len);
extern int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name, u8 name_len);
/*
* File types (adapted from include <linux/fs.h>)
@ -100,19 +94,15 @@ extern int ntfs_link(ntfs_inode *ni, ntfs_inode *dir_ni, ntfschar *name,
* This allows the caller to read directories into their application or
* to have different dirent layouts depending on the binary type.
*/
typedef int (*ntfs_filldir_t)(void *dirent, const ntfschar *name,
const int name_len, const int name_type, const s64 pos,
const MFT_REF mref, const unsigned dt_type);
typedef int (*ntfs_filldir_t)(void *dirent, const ntfschar *name, const int name_len, const int name_type,
const s64 pos, const MFT_REF mref, const unsigned dt_type);
extern int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos,
void *dirent, ntfs_filldir_t filldir);
extern int ntfs_readdir(ntfs_inode *dir_ni, s64 *pos, void *dirent, ntfs_filldir_t filldir);
ntfs_inode *ntfs_dir_parent_inode(ntfs_inode *ni);
int ntfs_get_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
char *value, size_t size);
int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni,
const char *value, size_t size, int flags);
int ntfs_get_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, char *value, size_t size);
int ntfs_set_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni, const char *value, size_t size, int flags);
int ntfs_remove_ntfs_dos_name(ntfs_inode *ni, ntfs_inode *dir_ni);
#if CACHE_INODE_SIZE

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'),
@ -68,7 +69,6 @@ static ntfschar logged_utility_stream_name[] = {
const_cpu_to_le16(0)
};
/*
* Get the ntfs EFS info into an extended attribute
*/
@ -78,32 +78,44 @@ 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;
}
@ -223,13 +250,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 +276,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 +293,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 +330,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 +349,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 +378,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 +411,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 +439,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 +455,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 +473,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

@ -23,8 +23,7 @@
int ntfs_get_efs_info(ntfs_inode *ni, char *value, size_t size);
int ntfs_set_efs_info(ntfs_inode *ni,
const char *value, size_t size, int flags);
int ntfs_set_efs_info(ntfs_inode *ni, const char *value, size_t size, int flags);
int ntfs_efs_fixup_attribute(ntfs_attr_search_ctx *ctx, ntfs_attr *na);
#endif /* EFS_H */

View File

@ -69,7 +69,8 @@
static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s64 count, void *buf);
static bool ntfs_device_gekko_io_readsectors(struct ntfs_device *dev, sec_t sector, sec_t numSectors, void* buffer);
static s64 ntfs_device_gekko_io_writebytes(struct ntfs_device *dev, s64 offset, s64 count, const void *buf);
static bool ntfs_device_gekko_io_writesectors(struct ntfs_device *dev, sec_t sector, sec_t numSectors, const void* buffer);
static bool ntfs_device_gekko_io_writesectors(struct ntfs_device *dev, sec_t sector, sec_t numSectors,
const void* buffer);
/**
*
@ -80,32 +81,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 +119,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,12 +143,14 @@ 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);
}
// Create the cache
fd->cache = _NTFS_cache_constructor(fd->cachePageCount, fd->cachePageSize, interface, fd->startSector + fd->sectorCount, fd->sectorSize);
fd->cache = _NTFS_cache_constructor(fd->cachePageCount, fd->cachePageSize, interface, fd->startSector
+ fd->sectorCount, fd->sectorSize);
// Mark the device as open
NDevSetBlock(dev);
@ -156,13 +168,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 +187,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 +199,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,16 +227,24 @@ 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) {
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;
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;
}
return 0;
@ -267,14 +291,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;
}
@ -285,8 +311,7 @@ static s64 ntfs_device_gekko_io_readbytes(struct ntfs_device *dev, s64 offset, s
return -1;
}
if(!count)
return 0;
if (!count) return 0;
sec_t sec_start = (sec_t) fd->startSector;
sec_t sec_count = 1;
@ -294,20 +319,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 +349,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 +358,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,31 +384,34 @@ 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;
}
if(count == 0)
return 0;
if (count == 0) return 0;
sec_t sec_start = (sec_t) fd->startSector;
sec_t sec_count = 1;
@ -385,10 +419,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 +433,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 +445,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 +455,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 +465,9 @@ 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 +480,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,24 +502,26 @@ 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;
}
// Read the sectors from disc (or cache, if enabled)
if (fd->cache)
return _NTFS_cache_readSectors(fd->cache, sector, numSectors, buffer);
else
return fd->interface->readSectors(sector, numSectors, buffer);
else return fd->interface->readSectors(sector, numSectors, buffer);
return false;
}
static bool ntfs_device_gekko_io_writesectors(struct ntfs_device *dev, sec_t sector, sec_t numSectors, const void* buffer)
static bool ntfs_device_gekko_io_writesectors(struct ntfs_device *dev, sec_t sector, sec_t numSectors,
const void* buffer)
{
// Get the device driver descriptor
gekko_fd *fd = DEV_FD(dev);
if (!fd) {
if (!fd)
{
errno = EBADF;
return false;
}
@ -485,8 +529,7 @@ static bool ntfs_device_gekko_io_writesectors(struct ntfs_device *dev, sec_t sec
// Write the sectors to disc (or cache, if enabled)
if (fd->cache)
return _NTFS_cache_writeSectors(fd->cache, sector, numSectors, buffer);
else
return fd->interface->writeSectors(sector, numSectors, buffer);
else return fd->interface->writeSectors(sector, numSectors, buffer);
return false;
}
@ -500,7 +543,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 +553,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,19 +574,18 @@ 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;
}
// Short circuit cases were we don't actually have to do anything
if (!buf)
return 0;
if (!buf) return 0;
// Build the device mode
mode_t mode = (S_IFBLK) |
(S_IRUSR | S_IRGRP | S_IROTH) |
((!NDevReadOnly(dev)) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0);
mode_t mode = (S_IFBLK) | (S_IRUSR | S_IRGRP | S_IROTH)
| ((!NDevReadOnly(dev)) ? (S_IWUSR | S_IWGRP | S_IWOTH) : 0);
// Zero out the stat buffer
memset(buf, 0, sizeof(struct stat));
@ -565,17 +610,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 +631,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 +640,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 +653,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 +662,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 +671,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,15 +686,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 = {
.open = ntfs_device_gekko_io_open,
.close = ntfs_device_gekko_io_close,
.seek = ntfs_device_gekko_io_seek,
.read = ntfs_device_gekko_io_read,
.write = ntfs_device_gekko_io_write,
.pread = ntfs_device_gekko_io_pread,
.pwrite = ntfs_device_gekko_io_pwrite,
.sync = ntfs_device_gekko_io_sync,
.stat = ntfs_device_gekko_io_stat,
.ioctl = ntfs_device_gekko_io_ioctl,
};
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, .read = ntfs_device_gekko_io_read,
.write = ntfs_device_gekko_io_write, .pread = ntfs_device_gekko_io_pread,
.pwrite = ntfs_device_gekko_io_pwrite, .sync = ntfs_device_gekko_io_sync, .stat = ntfs_device_gekko_io_stat,
.ioctl = ntfs_device_gekko_io_ioctl, };

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) */

File diff suppressed because it is too large Load Diff

View File

@ -63,8 +63,7 @@
#define MAX_PARENT_VCN 32
typedef int (*COLLATE)(ntfs_volume *vol, const void *data1, int len1,
const void *data2, int len2);
typedef int (*COLLATE)(ntfs_volume *vol, const void *data1, int len1, const void *data2, int len2);
/**
* struct ntfs_index_context -
@ -112,7 +111,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;
@ -133,21 +133,16 @@ typedef struct {
u8 vcn_size_bits;
} ntfs_index_context;
extern ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *ni,
ntfschar *name, u32 name_len);
extern ntfs_index_context *ntfs_index_ctx_get(ntfs_inode *ni, ntfschar *name, u32 name_len);
extern void ntfs_index_ctx_put(ntfs_index_context *ictx);
extern void ntfs_index_ctx_reinit(ntfs_index_context *ictx);
extern int ntfs_index_lookup(const void *key, const int key_len,
ntfs_index_context *ictx) __attribute_warn_unused_result__;
extern int ntfs_index_lookup(const void *key, const int key_len, ntfs_index_context *ictx) __attribute_warn_unused_result__;
extern INDEX_ENTRY *ntfs_index_next(INDEX_ENTRY *ie,
ntfs_index_context *ictx);
extern INDEX_ENTRY *ntfs_index_next(INDEX_ENTRY *ie, ntfs_index_context *ictx);
extern int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn,
MFT_REF mref);
extern int ntfs_index_remove(ntfs_inode *dir_ni, ntfs_inode *ni,
const void *key, const int keylen);
extern int ntfs_index_add_filename(ntfs_inode *ni, FILE_NAME_ATTR *fn, MFT_REF mref);
extern int ntfs_index_remove(ntfs_inode *dir_ni, ntfs_inode *ni, const void *key, const int keylen);
extern INDEX_ROOT *ntfs_index_root_get(ntfs_inode *ni, ATTR_RECORD *attr);

File diff suppressed because it is too large Load Diff

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. */
@ -51,7 +52,8 @@ typedef enum {
in the index. */
NI_v3_Extensions, /* 1: JPA v3.x extensions present. */
NI_TimesSet, /* 1: Use times which were set */
NI_KnownSize, /* 1: Set if sizes are meaningful */
NI_KnownSize,
/* 1: Set if sizes are meaningful */
} ntfs_inode_state_bits;
#define test_nino_flag(ni, flag) test_bit(NI_##flag, (ni)->state)
@ -73,7 +75,6 @@ typedef enum {
#define NInoSetAttrList(ni) set_nino_flag(ni, AttrList)
#define NInoClearAttrList(ni) clear_nino_flag(ni, AttrList)
#define test_nino_al_flag(ni, flag) test_nino_flag(ni, AttrList##flag)
#define set_nino_al_flag(ni, flag) set_nino_flag(ni, AttrList##flag)
#define clear_nino_al_flag(ni, flag) clear_nino_flag(ni, AttrList##flag)
@ -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,10 +169,9 @@ struct _ntfs_inode {
le64 usn;
};
typedef enum {
NTFS_UPDATE_ATIME = 1 << 0,
NTFS_UPDATE_MTIME = 1 << 1,
NTFS_UPDATE_CTIME = 1 << 2,
typedef enum
{
NTFS_UPDATE_ATIME = 1 << 0, NTFS_UPDATE_MTIME = 1 << 1, NTFS_UPDATE_CTIME = 1 << 2,
} ntfs_time_update_flags;
#define NTFS_UPDATE_MCTIME (NTFS_UPDATE_MTIME | NTFS_UPDATE_CTIME)
@ -195,9 +197,7 @@ extern int ntfs_inode_nidata_hash(const struct CACHED_GENERIC *item);
#endif
extern ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni,
const MFT_REF mref);
extern ntfs_inode *ntfs_extent_inode_open(ntfs_inode *base_ni, const MFT_REF mref);
extern int ntfs_inode_attach_all_extents(ntfs_inode *ni);
@ -215,8 +215,7 @@ extern int ntfs_inode_badclus_bad(u64 mft_no, ATTR_RECORD *a);
extern int ntfs_inode_get_times(ntfs_inode *ni, char *value, size_t size);
extern int ntfs_inode_set_times(ntfs_inode *ni, const char *value,
size_t size, int flags);
extern int ntfs_inode_set_times(ntfs_inode *ni, const char *value, size_t size, int flags);
/* debugging */
#define debug_double_inode(num, type)

File diff suppressed because it is too large Load Diff

View File

@ -55,10 +55,9 @@
#define NTFS_LCNALLOC_BSIZE 4096
#define NTFS_LCNALLOC_SKIP NTFS_LCNALLOC_BSIZE
enum {
ZONE_MFT = 1,
ZONE_DATA1 = 2,
ZONE_DATA2 = 4
enum
{
ZONE_MFT = 1, ZONE_DATA1 = 2, ZONE_DATA2 = 4
};
static void ntfs_cluster_set_zone_pos(LCN start, LCN end, LCN *pos, LCN tc)
@ -67,8 +66,7 @@ static void ntfs_cluster_set_zone_pos(LCN start, LCN end, LCN *pos, LCN tc)
if (tc >= end)
*pos = start;
else if (tc >= start)
*pos = tc;
else if (tc >= start) *pos = tc;
}
static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc)
@ -76,14 +74,11 @@ static void ntfs_cluster_update_zone_pos(ntfs_volume *vol, u8 zone, LCN tc)
ntfs_log_trace("tc = %lld, zone = %d\n", (long long)tc, zone);
if (zone == ZONE_MFT)
ntfs_cluster_set_zone_pos(vol->mft_lcn, vol->mft_zone_end,
&vol->mft_zone_pos, tc);
ntfs_cluster_set_zone_pos(vol->mft_lcn, vol->mft_zone_end, &vol->mft_zone_pos, tc);
else if (zone == ZONE_DATA1)
ntfs_cluster_set_zone_pos(vol->mft_zone_end, vol->nr_clusters,
&vol->data1_zone_pos, tc);
ntfs_cluster_set_zone_pos(vol->mft_zone_end, vol->nr_clusters, &vol->data1_zone_pos, tc);
else /* zone == ZONE_DATA2 */
ntfs_cluster_set_zone_pos(0, vol->mft_zone_start,
&vol->data2_zone_pos, tc);
ntfs_cluster_set_zone_pos(0, vol->mft_zone_start, &vol->data2_zone_pos, tc);
}
/*
@ -94,19 +89,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,39 +124,47 @@ 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);
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));
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
run++;
}
else run++;
}
i++;
buf++;
@ -162,28 +172,25 @@ static s64 max_empty_bit_range(unsigned char *buf, int size)
}
}
if (run > max_range)
start_pos = (s64)i * 8 - run;
if (run > max_range) start_pos = (s64) i * 8 - run;
return start_pos;
}
static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b,
u8 *writeback)
static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b, u8 *writeback)
{
s64 written;
ntfs_log_trace("Entering\n");
if (!*writeback)
return 0;
if (!*writeback) return 0;
*writeback = 0;
written = ntfs_attr_pwrite(vol->lcnbmp_na, pos, size, b);
if (written != size) {
if (!written)
errno = EIO;
if (written != size)
{
if (!written) errno = EIO;
ntfs_log_perror("Bitmap write error (%lld, %lld)",
(long long)pos, (long long)size);
return -1;
@ -232,8 +239,8 @@ static int bitmap_writeback(ntfs_volume *vol, s64 pos, s64 size, void *b,
* 2) causes reduction in fragmentation.
* The code is not optimized for speed.
*/
runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
LCN start_lcn, const NTFS_CLUSTER_ALLOCATION_ZONES zone)
runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, LCN start_lcn,
const NTFS_CLUSTER_ALLOCATION_ZONES zone)
{
LCN zone_start, zone_end; /* current search range */
LCN last_read_pos, lcn;
@ -252,8 +259,8 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
"zone = %s_ZONE.\n", (long long)count, (long long)
start_lcn, zone == MFT_ZONE ? "MFT" : "DATA");
if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na ||
(s8)zone < FIRST_ZONE || zone > LAST_ZONE) {
if (!vol || count < 0 || start_lcn < -1 || !vol->lcnbmp_na || (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 +269,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;
@ -273,8 +282,7 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
}
buf = ntfs_malloc(NTFS_LCNALLOC_BSIZE);
if (!buf)
goto out;
if (!buf) goto out;
/*
* If no @start_lcn was requested, use the current zone
* position otherwise use the requested @start_lcn.
@ -282,27 +290,30 @@ 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
zone_start = vol->mft_zone_pos;
else zone_start = vol->mft_zone_pos;
has_guess = 0;
}
used_zone_pos = has_guess ? 0 : 1;
if (!zone_start || zone_start == vol->mft_zone_start ||
zone_start == vol->mft_zone_end)
pass = 2;
if (!zone_start || zone_start == vol->mft_zone_start || 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,16 +323,15 @@ 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;
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)
goto zone_pass_done;
br = ntfs_attr_pread(vol->lcnbmp_na, last_read_pos, NTFS_LCNALLOC_BSIZE, buf);
if (br <= 0)
{
if (!br) goto zone_pass_done;
err = errno;
ntfs_log_perror("Reading $BITMAP failed");
goto err_ret;
@ -335,18 +345,22 @@ 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;
if (lcn < 0) break;
has_guess = 1;
continue;
}
@ -354,10 +368,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;
@ -372,14 +388,14 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
ntfs_log_error("Non-positive free clusters "
"(%lld)!\n",
(long long)vol->free_clusters);
else
vol->free_clusters--;
else vol->free_clusters--;
/*
* 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 +403,13 @@ 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 {
rl[rlpos].vcn = rl[rlpos - 1].vcn + prev_run_len;
else
{
rl[rlpos].vcn = start_vcn;
ntfs_log_debug("Start_vcn: %lld\n",
(long long)start_vcn);
@ -407,23 +425,24 @@ 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 (used_zone_pos)
ntfs_cluster_update_zone_pos(vol,
search_zone, lcn + bmp_pos + 1 +
NTFS_LCNALLOC_SKIP);
if (!--clusters)
{
if (used_zone_pos) ntfs_cluster_update_zone_pos(vol, search_zone, lcn + bmp_pos + 1
+ NTFS_LCNALLOC_SKIP);
goto done_ret;
}
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;
@ -431,22 +450,19 @@ runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
zone_start = vol->mft_zone_pos;
else if (search_zone == ZONE_DATA1)
zone_start = vol->data1_zone_pos;
else
zone_start = vol->data2_zone_pos;
else zone_start = vol->data2_zone_pos;
if (!zone_start || zone_start == vol->mft_zone_start ||
zone_start == vol->mft_zone_end)
pass = 2;
if (!zone_start || zone_start == vol->mft_zone_start || zone_start == vol->mft_zone_end) pass = 2;
bmp_pos = zone_start;
} else
bmp_pos += buf_size;
}
else bmp_pos += buf_size;
if (bmp_pos < zone_end)
continue;
if (bmp_pos < zone_end) continue;
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;
@ -454,52 +470,48 @@ zone_pass_done:
zone_start = vol->mft_zone_start;
else if (search_zone == ZONE_DATA1)
zone_start = vol->mft_zone_end;
else
zone_start = 0;
else zone_start = 0;
/* Sanity check. */
if (zone_end < zone_start)
zone_end = zone_start;
if (zone_end < zone_start) zone_end = zone_start;
bmp_pos = zone_start;
continue;
}
/* pass == 2 */
done_zones_check:
done_zones |= search_zone;
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) {
LCN tc = rl[rlpos - 1].lcn +
rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP;
if (rlpos)
{
LCN tc = rl[rlpos - 1].lcn + rl[rlpos - 1].length + NTFS_LCNALLOC_SKIP;
if (used_zone_pos)
ntfs_cluster_update_zone_pos(vol,
search_zone, tc);
if (used_zone_pos) ntfs_cluster_update_zone_pos(vol, 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;
zone_start = vol->data1_zone_pos;
zone_end = vol->nr_clusters;
if (zone_start == vol->mft_zone_end)
pass = 2;
if (zone_start == vol->mft_zone_end) pass = 2;
break;
case ZONE_DATA1:
ntfs_log_trace("Zone switch: data1 -> data2\n");
search_zone = ZONE_DATA2;
zone_start = vol->data2_zone_pos;
zone_end = vol->mft_zone_start;
if (!zone_start)
pass = 2;
if (!zone_start) 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;
}
@ -507,14 +519,14 @@ switch_to_data1_zone: search_zone = ZONE_DATA1;
search_zone = ZONE_MFT;
zone_start = vol->mft_zone_pos;
zone_end = vol->mft_zone_end;
if (zone_start == vol->mft_zone_start)
pass = 2;
if (zone_start == vol->mft_zone_start) pass = 2;
break;
}
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 +544,14 @@ 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) {
done_err_ret: free(buf);
if (err)
{
errno = err;
ntfs_log_perror("Failed to allocate clusters");
rl = NULL;
@ -549,11 +562,11 @@ out:
wb_err_ret:
ntfs_log_trace("At wb_err_ret.\n");
if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback))
err = errno;
if (bitmap_writeback(vol, last_read_pos, br, buf, &writeback)) 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 +593,17 @@ 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)) {
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, rl->length))
{
ntfs_log_perror("Cluster deallocation failed "
"(%lld, %lld)",
(long long)rl->lcn,
@ -600,10 +615,8 @@ int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl)
}
ret = 0;
out:
vol->free_clusters += nr_freed;
if (vol->free_clusters > vol->nr_clusters)
ntfs_log_error("Too many free clusters (%lld > %lld)!",
out: vol->free_clusters += nr_freed;
if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!",
(long long)vol->free_clusters,
(long long)vol->nr_clusters);
return ret;
@ -623,10 +636,11 @@ 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)) {
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, lcn, count))
{
ntfs_log_perror("Cluster deallocation failed "
"(%lld, %lld)",
(long long)lcn,
@ -636,10 +650,8 @@ int ntfs_cluster_free_basic(ntfs_volume *vol, s64 lcn, s64 count)
nr_freed += count;
}
ret = 0;
out:
vol->free_clusters += nr_freed;
if (vol->free_clusters > vol->nr_clusters)
ntfs_log_error("Too many free clusters (%lld > %lld)!",
out: vol->free_clusters += nr_freed;
if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!",
(long long)vol->free_clusters,
(long long)vol->nr_clusters);
return ret;
@ -667,8 +679,8 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
s64 delta, to_free, nr_freed = 0;
int ret = -1;
if (!vol || !vol->lcnbmp_na || !na || start_vcn < 0 ||
(count < 0 && count != -1)) {
if (!vol || !vol->lcnbmp_na || !na || start_vcn < 0 || (count < 0 && count != -1))
{
ntfs_log_trace("Invalid arguments!\n");
errno = EINVAL;
return -1;
@ -679,13 +691,14 @@ 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 (errno == ENOENT)
ret = 0;
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);
@ -697,31 +710,30 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
/* The number of clusters in this run that need freeing. */
to_free = rl->length - delta;
if (count >= 0 && to_free > count)
to_free = 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,
to_free))
goto leave;
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn + delta, to_free)) goto leave;
nr_freed = to_free;
}
/* Go to the next run and adjust the number of clusters left to free. */
++rl;
if (count >= 0)
count -= to_free;
if (count >= 0) count -= to_free;
/*
* 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)",
@ -731,13 +743,13 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
/* The number of clusters in this run that need freeing. */
to_free = rl->length;
if (count >= 0 && to_free > count)
to_free = 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)) {
if (ntfs_bitmap_clear_run(vol->lcnbmp_na, rl->lcn, to_free))
{
// FIXME: Eeek! We need rollback! (AIA)
ntfs_log_perror("%s: Clearing bitmap run failed",
__FUNCTION__);
@ -746,11 +758,11 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
nr_freed += to_free;
}
if (count >= 0)
count -= to_free;
if (count >= 0) 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__,
@ -759,10 +771,8 @@ int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count)
}
ret = nr_freed;
out:
vol->free_clusters += nr_freed ;
if (vol->free_clusters > vol->nr_clusters)
ntfs_log_error("Too many free clusters (%lld > %lld)!",
out: vol->free_clusters += nr_freed;
if (vol->free_clusters > vol->nr_clusters) ntfs_log_error("Too many free clusters (%lld > %lld)!",
(long long)vol->free_clusters,
(long long)vol->nr_clusters);
leave:

View File

@ -31,21 +31,22 @@
/**
* 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. */
LAST_ZONE = 1, /* For sanity checking. */
LAST_ZONE = 1,
/* For sanity checking. */
} NTFS_CLUSTER_ALLOCATION_ZONES;
extern runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count,
LCN start_lcn, const NTFS_CLUSTER_ALLOCATION_ZONES zone);
extern runlist *ntfs_cluster_alloc(ntfs_volume *vol, VCN start_vcn, s64 count, LCN start_lcn,
const NTFS_CLUSTER_ALLOCATION_ZONES zone);
extern int ntfs_cluster_free_from_rl(ntfs_volume *vol, runlist *rl);
extern int ntfs_cluster_free_basic(ntfs_volume *vol, s64 lcn, s64 count);
extern int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn,
s64 count);
extern int ntfs_cluster_free(ntfs_volume *vol, ntfs_attr *na, VCN start_vcn, s64 count);
#endif /* defined _NTFS_LCNALLOC_H */

View File

@ -67,11 +67,10 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
*/
logfile_system_page_size = le32_to_cpu(rp->system_page_size);
logfile_log_page_size = le32_to_cpu(rp->log_page_size);
if (logfile_system_page_size < NTFS_BLOCK_SIZE ||
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)) {
if (logfile_system_page_size < NTFS_BLOCK_SIZE || 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))
{
ntfs_log_error("$LogFile uses unsupported page size.\n");
return FALSE;
}
@ -79,14 +78,15 @@ 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) {
if (sle16_to_cpu(rp->major_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 +97,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;
@ -111,8 +113,8 @@ static BOOL ntfs_check_restart_page_header(RESTART_PAGE_HEADER *rp, s64 pos)
/* Verify the position of the update sequence array. */
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)) {
if (usa_ofs < sizeof(RESTART_PAGE_HEADER) || usa_end > NTFS_BLOCK_SIZE - sizeof(u16))
{
ntfs_log_error("$LogFile restart page specifies "
"inconsistent update sequence array offset.\n");
return FALSE;
@ -125,9 +127,9 @@ skip_usa_checks:
* - within the system page size.
*/
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) {
if (ra_ofs & 7 || (have_usa ? ra_ofs < usa_end : ra_ofs < sizeof(RESTART_PAGE_HEADER)) || ra_ofs
> logfile_system_page_size)
{
ntfs_log_error("$LogFile restart page specifies "
"inconsistent restart area offset.\n");
return FALSE;
@ -136,7 +138,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;
@ -173,8 +176,8 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
* protected by an update sequence number. This ensures that it is
* safe to access ra->client_array_offset.
*/
if (ra_ofs + offsetof(RESTART_AREA, file_size) >
NTFS_BLOCK_SIZE - sizeof(u16)) {
if (ra_ofs + offsetof(RESTART_AREA, file_size) > NTFS_BLOCK_SIZE - sizeof(u16))
{
ntfs_log_error("$LogFile restart area specifies "
"inconsistent file offset.\n");
return FALSE;
@ -187,9 +190,8 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
* aligned to an 8-byte boundary.
*/
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))) {
if (((ca_ofs + 7) & ~7) != ca_ofs || ra_ofs + ca_ofs > (u16) (NTFS_BLOCK_SIZE - sizeof(u16)))
{
ntfs_log_error("$LogFile restart area specifies "
"inconsistent client array offset.\n");
return FALSE;
@ -199,12 +201,11 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
* calculated manually and as specified by ra->restart_area_length.
* Also, the calculated length must not exceed the specified length.
*/
ra_len = ca_ofs + le16_to_cpu(ra->log_clients) *
sizeof(LOG_CLIENT_RECORD);
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 = ca_ofs + le16_to_cpu(ra->log_clients) * sizeof(LOG_CLIENT_RECORD);
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))
{
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 "
@ -216,12 +217,10 @@ static BOOL ntfs_check_restart_area(RESTART_PAGE_HEADER *rp)
* LOGFILE_NO_CLIENT or less than ra->log_clients or they are
* overflowing the client array.
*/
if ((ra->client_free_list != LOGFILE_NO_CLIENT &&
le16_to_cpu(ra->client_free_list) >=
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))) {
if ((ra->client_free_list != LOGFILE_NO_CLIENT && le16_to_cpu(ra->client_free_list) >= 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)))
{
ntfs_log_error("$LogFile restart area specifies "
"overflowing client free and/or in use lists.\n");
return FALSE;
@ -232,25 +231,27 @@ 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)) {
if (((le16_to_cpu(ra->log_record_header_length) + 7) & ~7) != 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)) {
if (((le16_to_cpu(ra->log_page_data_offset) + 7) & ~7) != le16_to_cpu(ra->log_page_data_offset))
{
ntfs_log_error("$LogFile restart area specifies "
"inconsistent log page data offset.\n");
return FALSE;
@ -282,8 +283,7 @@ static BOOL ntfs_check_log_client_array(RESTART_PAGE_HEADER *rp)
ntfs_log_trace("Entering.\n");
ra = (RESTART_AREA*) ((u8*) rp + le16_to_cpu(rp->restart_area_offset));
ca = (LOG_CLIENT_RECORD*)((u8*)ra +
le16_to_cpu(ra->client_array_offset));
ca = (LOG_CLIENT_RECORD*) ((u8*) ra + le16_to_cpu(ra->client_array_offset));
/*
* Check the ra->client_free_list first and then check the
* ra->client_in_use_list. Check each of the log client records in
@ -295,30 +295,29 @@ static BOOL ntfs_check_log_client_array(RESTART_PAGE_HEADER *rp)
nr_clients = le16_to_cpu(ra->log_clients);
idx = le16_to_cpu(ra->client_free_list);
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)) {
if (!nr_clients || idx >= le16_to_cpu(ra->log_clients))
goto err_out;
check_list: for (idx_is_first = TRUE; idx != LOGFILE_NO_CLIENT_CPU; nr_clients--, 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 (cr->prev_client != LOGFILE_NO_CLIENT)
goto err_out;
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;
}
ntfs_log_trace("Done.\n");
return TRUE;
err_out:
ntfs_log_error("$LogFile log client array is corrupt.\n");
err_out: ntfs_log_error("$LogFile log client array is corrupt.\n");
return FALSE;
}
@ -349,9 +348,8 @@ err_out:
* ENOMEM - Not enough memory to load the restart page.
* EIO - Failed to reading from $LogFile.
*/
static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
RESTART_PAGE_HEADER *rp, s64 pos, RESTART_PAGE_HEADER **wrp,
LSN *lsn)
static int ntfs_check_and_load_restart_page(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp, s64 pos,
RESTART_PAGE_HEADER **wrp, LSN *lsn)
{
RESTART_AREA *ra;
RESTART_PAGE_HEADER *trp;
@ -359,12 +357,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;
}
@ -374,8 +374,7 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
* sector transfer deprotect it.
*/
trp = ntfs_malloc(le32_to_cpu(rp->system_page_size));
if (!trp)
return errno;
if (!trp) return errno;
/*
* Read the whole of the restart page into the buffer. If it fits
* completely inside @rp, just copy it from there. Otherwise read it
@ -383,31 +382,29 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
*/
if (le32_to_cpu(rp->system_page_size) <= NTFS_BLOCK_SIZE)
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)) {
else if (ntfs_attr_pread(log_na, pos, le32_to_cpu(rp->system_page_size), trp) != le32_to_cpu(rp->system_page_size))
{
err = errno;
ntfs_log_error("Failed to read whole restart page into the "
"buffer.\n");
if (err != ENOMEM)
err = EIO;
if (err != ENOMEM) err = EIO;
goto err_out;
}
/*
* Perform the multi sector transfer deprotection on the buffer if the
* restart page is protected.
*/
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))) {
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)))
{
/*
* A multi sector tranfer error was detected. We only need to
* abort if the restart page contents exceed the multi sector
* transfer fixup of the first sector.
*/
if (le16_to_cpu(rp->restart_area_offset) +
le16_to_cpu(ra->restart_area_length) >
NTFS_BLOCK_SIZE - (int)sizeof(u16)) {
if (le16_to_cpu(rp->restart_area_offset) + le16_to_cpu(ra->restart_area_length) > NTFS_BLOCK_SIZE
- (int) sizeof(u16))
{
ntfs_log_error("Multi sector transfer error "
"detected in $LogFile restart page.\n");
err = EINVAL;
@ -420,14 +417,16 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
* check the log client records for consistency, too.
*/
err = 0;
if (ntfs_is_rstr_record(rp->magic) &&
ra->client_in_use_list != LOGFILE_NO_CLIENT) {
if (!ntfs_check_log_client_array(trp)) {
if (ntfs_is_rstr_record(rp->magic) && 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,9 +435,9 @@ static int ntfs_check_and_load_restart_page(ntfs_attr *log_na,
ntfs_log_trace("Done.\n");
if (wrp)
*wrp = trp;
else {
err_out:
free(trp);
else
{
err_out: free(trp);
}
return err;
}
@ -474,12 +473,10 @@ BOOL ntfs_check_logfile(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(vol))
goto is_empty;
if (NVolLogFileEmpty(vol)) goto is_empty;
size = log_na->data_size;
/* Make sure the file doesn't exceed the maximum allowed size. */
if (size > (s64)MaxLogFileSize)
size = MaxLogFileSize;
if (size > (s64) MaxLogFileSize) size = MaxLogFileSize;
log_page_size = DefaultLogPageSize;
log_page_mask = log_page_size - 1;
/*
@ -493,15 +490,14 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
* Ensure the log file is big enough to store at least the two restart
* pages and the minimum number of log record pages.
*/
if (size < log_page_size * 2 || (size - log_page_size * 2) >>
log_page_bits < MinLogRecordPages) {
if (size < log_page_size * 2 || (size - log_page_size * 2) >> log_page_bits < MinLogRecordPages)
{
ntfs_log_error("$LogFile is too small.\n");
return FALSE;
}
/* Allocate memory for restart page. */
kaddr = ntfs_malloc(NTFS_BLOCK_SIZE);
if (!kaddr)
return FALSE;
if (!kaddr) return FALSE;
/*
* Read through the file looking for a restart page. Since the restart
* page header is at the beginning of a page we only need to search at
@ -510,12 +506,13 @@ 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) {
if (ntfs_attr_pread(log_na, pos, NTFS_BLOCK_SIZE, kaddr) != NTFS_BLOCK_SIZE)
{
ntfs_log_error("Failed to read first NTFS_BLOCK_SIZE "
"bytes of potential restart page.\n");
goto err_out;
@ -528,19 +525,16 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
*/
if (!ntfs_is_empty_recordp((le32*)kaddr))
logfile_is_empty = FALSE;
else if (!logfile_is_empty)
break;
else if (!logfile_is_empty) break;
/*
* A log record page means there cannot be a restart page after
* this so no need to continue searching.
*/
if (ntfs_is_rcrd_recordp((le32*)kaddr))
break;
if (ntfs_is_rcrd_recordp((le32*)kaddr)) break;
/* If not a (modified by chkdsk) restart page, continue. */
if (!ntfs_is_rstr_recordp((le32*)kaddr) &&
!ntfs_is_chkd_recordp((le32*)kaddr)) {
if (!pos)
pos = NTFS_BLOCK_SIZE >> 1;
if (!ntfs_is_rstr_recordp((le32*)kaddr) && !ntfs_is_chkd_recordp((le32*)kaddr))
{
if (!pos) pos = NTFS_BLOCK_SIZE >> 1;
continue;
}
/*
@ -548,16 +542,16 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
* and get a copy of the complete multi sector transfer
* deprotected restart page.
*/
err = ntfs_check_and_load_restart_page(log_na,
(RESTART_PAGE_HEADER*)kaddr, pos,
!rstr1_ph ? &rstr1_ph : &rstr2_ph,
!rstr1_ph ? &rstr1_lsn : &rstr2_lsn);
if (!err) {
err = ntfs_check_and_load_restart_page(log_na, (RESTART_PAGE_HEADER*) kaddr, pos, !rstr1_ph ? &rstr1_ph
: &rstr2_ph, !rstr1_ph ? &rstr1_lsn : &rstr2_lsn);
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;
}
@ -572,42 +566,46 @@ BOOL ntfs_check_logfile(ntfs_attr *log_na, RESTART_PAGE_HEADER **rp)
* not abort if the restart page was invalid as we might still
* find a valid one further in the file.
*/
if (err != EINVAL)
goto err_out;
if (err != EINVAL) goto err_out;
/* Continue looking. */
if (!pos)
pos = NTFS_BLOCK_SIZE >> 1;
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 (rstr2_ph)
ntfs_log_error("BUG: rstr2_ph isn't NULL!\n");
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 "
"$LogFile and it was not empty.\n");
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);
@ -617,12 +615,10 @@ is_empty:
/* All consistency checks passed. */
if (rp)
*rp = rstr1_ph;
else
free(rstr1_ph);
else free(rstr1_ph);
ntfs_log_trace("Done.\n");
return TRUE;
err_out:
free(kaddr);
err_out: free(kaddr);
free(rstr1_ph);
free(rstr2_ph);
return FALSE;
@ -654,16 +650,18 @@ 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)) {
if (!ntfs_is_rstr_record(rp->magic) && !ntfs_is_chkd_record(rp->magic))
{
ntfs_log_error("Restart page buffer is invalid\n");
return FALSE;
}
@ -674,8 +672,8 @@ BOOL ntfs_is_logfile_clean(ntfs_attr *log_na, RESTART_PAGE_HEADER *rp)
* have the RESTART_VOLUME_IS_CLEAN bit set in the restart area flags,
* we assume there was an unclean shutdown.
*/
if (ra->client_in_use_list != LOGFILE_NO_CLIENT &&
!(ra->flags & RESTART_VOLUME_IS_CLEAN)) {
if (ra->client_in_use_list != LOGFILE_NO_CLIENT && !(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));
@ -704,10 +702,10 @@ int ntfs_empty_logfile(ntfs_attr *na)
ntfs_log_trace("Entering.\n");
if (NVolLogFileEmpty(na->ni->vol))
return 0;
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,16 +714,16 @@ 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;
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;
if (count != -1) errno = EIO;
return -1;
}
pos += count;

View File

@ -61,37 +61,47 @@
*
* 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". */
/* 4*/ le16 usa_ofs; /* See NTFS_RECORD definition in layout.h.
/* 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
alignment). */
/* 6*/ le16 usa_count; /* See NTFS_RECORD definition in layout.h. */
/* 6*/
le16 usa_count; /* See NTFS_RECORD definition in layout.h. */
/* 8*/ leLSN chkdsk_lsn; /* The last log file sequence number found by
/* 8*/
leLSN chkdsk_lsn; /* The last log file sequence number found by
chkdsk. Only used when the magic is changed
to "CHKD". Otherwise this is zero. */
/* 16*/ le32 system_page_size; /* Byte size of system pages when the log file
/* 16*/
le32 system_page_size; /* Byte size of system pages when the log file
was created, has to be >= 512 and a power of
2. Use this to calculate the required size
of the usa (usa_count) and add it to usa_ofs.
Then verify that the result is less than the
value of the restart_area_offset. */
/* 20*/ le32 log_page_size; /* Byte size of log file pages, has to be >=
/* 20*/
le32 log_page_size; /* Byte size of log file pages, has to be >=
512 and a power of 2. The default is 4096
and is used when the system page size is
between 4096 and 8192. Otherwise this is
set to the system page size instead. */
/* 24*/ le16 restart_area_offset;/* Byte offset from the start of this header to
/* 24*/
le16 restart_area_offset;/* Byte offset from the start of this header to
the RESTART_AREA. Value has to be aligned
to 8-byte boundary. When creating, set this
to be after the usa. */
/* 26*/ sle16 minor_ver; /* Log file minor version. Only check if major
/* 26*/
sle16 minor_ver; /* Log file minor version. Only check if major
version is 1. */
/* 28*/ sle16 major_ver; /* Log file major version. We only support
/* 28*/
sle16 major_ver; /* Log file major version. We only support
version 1.1. */
/* sizeof() = 30 (0x1e) bytes */
}__attribute__((__packed__)) RESTART_PAGE_HEADER;
@ -108,9 +118,10 @@ 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 {
RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16(0x0002),
RESTART_SPACE_FILLER = 0xffff, /* gcc: Force enum bit width to 16. */
enum
{
RESTART_VOLUME_IS_CLEAN = const_cpu_to_le16(0x0002), RESTART_SPACE_FILLER = 0xffff,
/* gcc: Force enum bit width to 16. */
}__attribute__((__packed__));
typedef le16 RESTART_AREA_FLAGS;
@ -122,18 +133,22 @@ 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
check point is written or something else?
On create set to 0. */
/* 8*/ le16 log_clients; /* Number of log client records in the array of
/* 8*/
le16 log_clients; /* Number of log client records in the array of
log client records which follows this
restart area. Must be 1. */
/* 10*/ le16 client_free_list; /* The index of the first free log client record
/* 10*/
le16 client_free_list; /* The index of the first free log client record
in the array of log client records.
LOGFILE_NO_CLIENT means that there are no
free log client records in the array.
@ -149,7 +164,8 @@ typedef struct {
and presumably later, the logfile is always
open, even on clean shutdown so this should
always be LOGFILE_NO_CLIENT. */
/* 12*/ le16 client_in_use_list;/* The index of the first in-use log client
/* 12*/
le16 client_in_use_list;/* The index of the first in-use log client
record in the array of log client records.
LOGFILE_NO_CLIENT means that there are no
in-use log client records in the array. If
@ -166,7 +182,8 @@ typedef struct {
presumably later, the logfile is always
open, even on clean shutdown so this should
always be 0. */
/* 14*/ RESTART_AREA_FLAGS flags;/* Flags modifying LFS behaviour. On Win2k
/* 14*/
RESTART_AREA_FLAGS flags;/* Flags modifying LFS behaviour. On Win2k
and presumably earlier this is always 0. On
WinXP and presumably later, if the logfile
was shutdown cleanly, the second bit,
@ -182,13 +199,15 @@ typedef struct {
clean. If on the other hand the logfile is
open and this bit is clear, we can be almost
certain that the logfile is dirty. */
/* 16*/ le32 seq_number_bits; /* How many bits to use for the sequence
/* 16*/
le32 seq_number_bits; /* How many bits to use for the sequence
number. This is calculated as 67 - the
number of bits required to store the logfile
size in bytes and this can be used in with
the specified file_size as a consistency
check. */
/* 20*/ le16 restart_area_length;/* Length of the restart area including the
/* 20*/
le16 restart_area_length;/* Length of the restart area including the
client array. Following checks required if
version matches. Otherwise, skip them.
restart_area_offset + restart_area_length
@ -196,7 +215,8 @@ typedef struct {
restart_area_length has to be >=
client_array_offset + (log_clients *
sizeof(log client record)). */
/* 22*/ le16 client_array_offset;/* Offset from the start of this record to
/* 22*/
le16 client_array_offset;/* Offset from the start of this record to
the first log client record if versions are
matched. When creating, set this to be
after this restart area structure, aligned
@ -218,7 +238,8 @@ typedef struct {
the client array. This probably means that
the RESTART_AREA record is actually bigger
in WinXP and later. */
/* 24*/ sle64 file_size; /* Usable byte size of the log file. If the
/* 24*/
sle64 file_size; /* Usable byte size of the log file. If the
restart_area_offset + the offset of the
file_size are > 510 then corruption has
occurred. This is the very first check when
@ -231,10 +252,12 @@ typedef struct {
then it has to be at least big enough to
store the two restart pages and 48 (0x30)
log record pages. */
/* 32*/ le32 last_lsn_data_length;/* Length of data of last LSN, not including
/* 32*/
le32 last_lsn_data_length;/* Length of data of last LSN, not including
the log record header. On create set to
0. */
/* 36*/ le16 log_record_header_length;/* Byte size of the log record header.
/* 36*/
le16 log_record_header_length;/* Byte size of the log record header.
If the version matches then check that the
value of log_record_header_length is a
multiple of 8, i.e.
@ -242,17 +265,20 @@ typedef struct {
log_record_header_length. When creating set
it to sizeof(LOG_RECORD_HEADER), aligned to
8 bytes. */
/* 38*/ le16 log_page_data_offset;/* Offset to the start of data in a log record
/* 38*/
le16 log_page_data_offset;/* Offset to the start of data in a log record
page. Must be a multiple of 8. On create
set it to immediately after the update
sequence array of the log record page. */
/* 40*/ le32 restart_log_open_count;/* A counter that gets incremented every
/* 40*/
le32 restart_log_open_count;/* A counter that gets incremented every
time the logfile is restarted which happens
at mount time when the logfile is opened.
When creating set to a random value. Win2k
sets it to the low 32 bits of the current
system time in NTFS format (see time.h). */
/* 44*/ le32 reserved; /* Reserved/alignment to 8-byte boundary. */
/* 44*/
le32 reserved; /* Reserved/alignment to 8-byte boundary. */
/* sizeof() = 48 (0x30) bytes */
}__attribute__((__packed__)) RESTART_AREA;
@ -262,36 +288,45 @@ 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
/* 8*/
leLSN client_restart_lsn;/* LSN at which this client needs to restart
the volume, i.e. the current position within
the log file. At present, if clean this
should = current_lsn in restart area but it
probably also = current_lsn when dirty most
of the time. At create set to 0. */
/* 16*/ le16 prev_client; /* The offset to the previous log client record
/* 16*/
le16 prev_client; /* The offset to the previous log client record
in the array of log client records.
LOGFILE_NO_CLIENT means there is no previous
client record, i.e. this is the first one.
This is always LOGFILE_NO_CLIENT. */
/* 18*/ le16 next_client; /* The offset to the next log client record in
/* 18*/
le16 next_client; /* The offset to the next log client record in
the array of log client records.
LOGFILE_NO_CLIENT means there are no next
client records, i.e. this is the last one.
This is always LOGFILE_NO_CLIENT. */
/* 20*/ le16 seq_number; /* On Win2k and presumably earlier, this is set
/* 20*/
le16 seq_number; /* On Win2k and presumably earlier, this is set
to zero every time the logfile is restarted
and it is incremented when the logfile is
closed at dismount time. Thus it is 0 when
dirty and 1 when clean. On WinXP and
presumably later, this is always 0. */
/* 22*/ u8 reserved[6]; /* Reserved/alignment. */
/* 28*/ le32 client_name_length;/* Length of client name in bytes. Should
/* 22*/
u8 reserved[6]; /* Reserved/alignment. */
/* 28*/
le32 client_name_length;/* Length of client name in bytes. Should
always be 8. */
/* 32*/ ntfschar client_name[64];/* Name of the client in Unicode. Should
/* 32*/
ntfschar client_name[64];/* Name of the client in Unicode. Should
always be "NTFS" with the remaining bytes
set to 0. */
/* sizeof() = 160 (0xa0) bytes */
@ -305,7 +340,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 +350,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 +374,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 +385,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 +396,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 +423,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;
@ -82,10 +83,8 @@ static struct ntfs_logging ntfs_log = {
NTFS_LOG_LEVEL_DEBUG | NTFS_LOG_LEVEL_TRACE | NTFS_LOG_LEVEL_ENTER |
NTFS_LOG_LEVEL_LEAVE |
#endif
NTFS_LOG_LEVEL_INFO | NTFS_LOG_LEVEL_QUIET | NTFS_LOG_LEVEL_WARNING |
NTFS_LOG_LEVEL_ERROR | NTFS_LOG_LEVEL_PERROR | NTFS_LOG_LEVEL_CRITICAL |
NTFS_LOG_LEVEL_PROGRESS,
NTFS_LOG_FLAG_ONLYNAME,
NTFS_LOG_LEVEL_INFO | NTFS_LOG_LEVEL_QUIET | NTFS_LOG_LEVEL_WARNING | NTFS_LOG_LEVEL_ERROR
| NTFS_LOG_LEVEL_PERROR | NTFS_LOG_LEVEL_CRITICAL | NTFS_LOG_LEVEL_PROGRESS, NTFS_LOG_FLAG_ONLYNAME,
#ifdef DEBUG
ntfs_log_handler_outerr
#else
@ -93,7 +92,6 @@ static struct ntfs_logging ntfs_log = {
#endif
};
/**
* ntfs_log_get_levels - Get a list of the current logging levels
*
@ -140,7 +138,6 @@ u32 ntfs_log_clear_levels(u32 levels)
return old;
}
/**
* ntfs_log_get_flags - Get a list of logging style flags
*
@ -187,7 +184,6 @@ u32 ntfs_log_clear_flags(u32 flags)
return old;
}
/**
* ntfs_log_get_stream - Default output streams for logging levels
* @level: Log level
@ -201,7 +197,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 +234,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;
@ -276,7 +274,6 @@ static const char * ntfs_log_get_prefix(u32 level)
return prefix;
}
/**
* ntfs_log_set_handler - Provide an alternate logging handler
* @handler: function to perform the logging
@ -286,14 +283,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
ntfs_log.handler = ntfs_log_handler_null;
}
else ntfs_log.handler = ntfs_log_handler_null;
}
/**
@ -313,8 +311,7 @@ void ntfs_log_set_handler(ntfs_log_handler *handler)
* 0 Message wasn't logged
* num Number of output characters
*/
int ntfs_log_redirect(const char *function, const char *file,
int line, u32 level, void *data, const char *format, ...)
int ntfs_log_redirect(const char *function, const char *file, int line, u32 level, void *data, const char *format, ...)
{
int olderr = errno;
int ret;
@ -332,7 +329,6 @@ int ntfs_log_redirect(const char *function, const char *file,
return ret;
}
/**
* ntfs_log_handler_syslog - syslog logging handler
* @function: Function in which the log line occurred
@ -350,7 +346,6 @@ int ntfs_log_redirect(const char *function, const char *file,
* num Number of output characters
*/
#ifdef HAVE_SYSLOG_H
#define LOG_LINE_LEN 512
@ -369,13 +364,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);
@ -409,8 +406,8 @@ out:
* 0 Message wasn't logged
* num Number of output characters
*/
int ntfs_log_handler_fprintf(const char *function, const char *file,
int line, u32 level, void *data, const char *format, va_list args)
int ntfs_log_handler_fprintf(const char *function, const char *file, int line, u32 level, void *data,
const char *format, va_list args)
{
#ifdef DEBUG
int i;
@ -424,7 +421,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;
@ -433,8 +431,7 @@ int ntfs_log_handler_fprintf(const char *function, const char *file,
for (i = 0; i < tab; i++)
ret += fprintf(stream, " ");
#endif
if ((ntfs_log.flags & NTFS_LOG_FLAG_ONLYNAME) &&
(strchr(file, PATH_SEP))) /* Abbreviate the filename */
if ((ntfs_log.flags & NTFS_LOG_FLAG_ONLYNAME) && (strchr(file, PATH_SEP))) /* Abbreviate the filename */
file = strrchr(file, PATH_SEP) + 1;
if (ntfs_log.flags & NTFS_LOG_FLAG_PREFIX) /* Prefix the output */
@ -447,13 +444,11 @@ int ntfs_log_handler_fprintf(const char *function, const char *file,
ret += fprintf(stream, "(%d) ", line);
if ((ntfs_log.flags & NTFS_LOG_FLAG_FUNCTION) || /* Source function */
(level & NTFS_LOG_LEVEL_TRACE) || (level & NTFS_LOG_LEVEL_ENTER))
ret += fprintf(stream, "%s(): ", function);
(level & NTFS_LOG_LEVEL_TRACE) || (level & NTFS_LOG_LEVEL_ENTER)) ret += fprintf(stream, "%s(): ", function);
ret += vfprintf(stream, format, args);
if (level & NTFS_LOG_LEVEL_PERROR)
ret += fprintf(stream, ": %s\n", strerror(olderr));
if (level & NTFS_LOG_LEVEL_PERROR) ret += fprintf(stream, ": %s\n", strerror(olderr));
#ifdef DEBUG
if (level == NTFS_LOG_LEVEL_ENTER)
@ -479,9 +474,8 @@ int ntfs_log_handler_fprintf(const char *function, const char *file,
*
* Returns: 0 Message wasn't logged
*/
int ntfs_log_handler_null(const char *function __attribute__((unused)), const char *file __attribute__((unused)),
int line __attribute__((unused)), u32 level __attribute__((unused)), void *data __attribute__((unused)),
const char *format __attribute__((unused)), va_list args __attribute__((unused)))
int ntfs_log_handler_null(const char *function __attribute__((unused)), const char *file __attribute__((unused)), int line __attribute__((unused)), u32 level __attribute__((unused)), void *data __attribute__((unused)), const char *format __attribute__((unused)),
va_list args __attribute__((unused)))
{
return 0;
}
@ -507,11 +501,10 @@ int ntfs_log_handler_null(const char *function __attribute__((unused)), const ch
* 0 Message wasn't logged
* num Number of output characters
*/
int ntfs_log_handler_stdout(const char *function, const char *file,
int line, u32 level, void *data, const char *format, va_list args)
int ntfs_log_handler_stdout(const char *function, const char *file, int line, u32 level, void *data,
const char *format, va_list args)
{
if (!data)
data = stdout;
if (!data) data = stdout;
return ntfs_log_handler_fprintf(function, file, line, level, data, format, args);
}
@ -538,11 +531,10 @@ int ntfs_log_handler_stdout(const char *function, const char *file,
* 0 Message wasn't logged
* num Number of output characters
*/
int ntfs_log_handler_outerr(const char *function, const char *file,
int line, u32 level, void *data, const char *format, va_list args)
int ntfs_log_handler_outerr(const char *function, const char *file, int line, u32 level, void *data,
const char *format, va_list args)
{
if (!data)
data = ntfs_log_get_stream(level);
if (!data) data = ntfs_log_get_stream(level);
return ntfs_log_handler_fprintf(function, file, line, level, data, format, args);
}
@ -568,16 +560,14 @@ int ntfs_log_handler_outerr(const char *function, const char *file,
* 0 Message wasn't logged
* num Number of output characters
*/
int ntfs_log_handler_stderr(const char *function, const char *file,
int line, u32 level, void *data, const char *format, va_list args)
int ntfs_log_handler_stderr(const char *function, const char *file, int line, u32 level, void *data,
const char *format, va_list args)
{
if (!data)
data = stderr;
if (!data) data = stderr;
return ntfs_log_handler_fprintf(function, file, line, level, data, format, args);
}
/**
* ntfs_log_parse_option - Act upon command line options
* @option: Option flag
@ -593,16 +583,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

@ -34,8 +34,8 @@
#include "types.h"
/* Function prototype for the logging handlers */
typedef int (ntfs_log_handler)(const char *function, const char *file, int line,
u32 level, void *data, const char *format, va_list args);
typedef int ( ntfs_log_handler)(const char *function, const char *file, int line, u32 level, void *data,
const char *format, va_list args);
/* Set the logging handler from one of the functions, below. */
void ntfs_log_set_handler(ntfs_log_handler *handler
@ -62,8 +62,7 @@ u32 ntfs_log_get_flags(void);
/* Turn command-line options into logging flags */
BOOL ntfs_log_parse_option(const char *option);
int ntfs_log_redirect(const char *function, const char *file, int line,
u32 level, void *data, const char *format, ...)
int ntfs_log_redirect(const char *function, const char *file, int line, u32 level, void *data, const char *format, ...)
__attribute__((format(printf, 6, 7)));
/* Logging levels - Determine what gets logged */

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);
}

File diff suppressed because it is too large Load Diff

View File

@ -29,8 +29,7 @@
#include "layout.h"
#include "logging.h"
extern int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
const s64 count, MFT_RECORD *b);
extern int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref, const s64 count, MFT_RECORD *b);
/**
* ntfs_mft_record_read - read a record from the mft
@ -47,8 +46,7 @@ extern int ntfs_mft_records_read(const ntfs_volume *vol, const MFT_REF mref,
*
* NOTE: @b has to be at least of size vol->mft_record_size.
*/
static __inline__ int ntfs_mft_record_read(const ntfs_volume *vol,
const MFT_REF mref, MFT_RECORD *b)
static __inline__ int ntfs_mft_record_read(const ntfs_volume *vol, const MFT_REF mref, MFT_RECORD *b)
{
int ret;
@ -58,14 +56,11 @@ static __inline__ int ntfs_mft_record_read(const ntfs_volume *vol,
return ret;
}
extern int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref,
MFT_RECORD *m);
extern int ntfs_mft_record_check(const ntfs_volume *vol, const MFT_REF mref, MFT_RECORD *m);
extern int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref,
MFT_RECORD **mrec, ATTR_RECORD **attr);
extern int ntfs_file_record_read(const ntfs_volume *vol, const MFT_REF mref, MFT_RECORD **mrec, ATTR_RECORD **attr);
extern int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
const s64 count, MFT_RECORD *b);
extern int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref, const s64 count, MFT_RECORD *b);
/**
* ntfs_mft_record_write - write an mft record to disk
@ -82,8 +77,7 @@ extern int ntfs_mft_records_write(const ntfs_volume *vol, const MFT_REF mref,
*
* NOTE: @b has to be at least of size vol->mft_record_size.
*/
static __inline__ int ntfs_mft_record_write(const ntfs_volume *vol,
const MFT_REF mref, MFT_RECORD *b)
static __inline__ int ntfs_mft_record_write(const ntfs_volume *vol, const MFT_REF mref, MFT_RECORD *b)
{
int ret;
@ -111,14 +105,12 @@ static __inline__ int ntfs_mft_record_write(const ntfs_volume *vol,
*/
static __inline__ u32 ntfs_mft_record_get_data_size(const MFT_RECORD *m)
{
if (!m || !ntfs_is_mft_record(m->magic))
return 0;
if (!m || !ntfs_is_mft_record(m->magic)) return 0;
/* Get the number of used bytes and return it. */
return le32_to_cpu(m->bytes_in_use);
}
extern int ntfs_mft_record_layout(const ntfs_volume *vol, const MFT_REF mref,
MFT_RECORD *mrec);
extern int ntfs_mft_record_layout(const ntfs_volume *vol, const MFT_REF mref, MFT_RECORD *mrec);
extern int ntfs_mft_record_format(const ntfs_volume *vol, const MFT_REF mref);

View File

@ -45,8 +45,7 @@ void *ntfs_calloc(size_t size)
void *p;
p = calloc(1, size);
if (!p)
ntfs_log_perror("Failed to calloc %lld bytes", (long long)size);
if (!p) ntfs_log_perror("Failed to calloc %lld bytes", (long long)size);
return p;
}
@ -55,7 +54,6 @@ void *ntfs_malloc(size_t size)
void *p;
p = malloc(size);
if (!p)
ntfs_log_perror("Failed to malloc %lld bytes", (long long)size);
if (!p) ntfs_log_perror("Failed to malloc %lld bytes", (long long)size);
return p;
}

View File

@ -59,9 +59,9 @@ int ntfs_mst_post_read_fixup(NTFS_RECORD *b, const u32 size)
/* Decrement usa_count to get number of fixups. */
usa_count = le16_to_cpu(b->usa_count) - 1;
/* 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) {
if (size & (NTFS_BLOCK_SIZE - 1) || usa_ofs & 1 || (u32) (usa_ofs + (usa_count * 2)) > size || (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 +85,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 +108,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.
@ -146,8 +149,8 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
ntfs_log_trace("Entering\n");
/* Sanity check + only fixup if it makes sense. */
if (!b || ntfs_is_baad_record(b->magic) ||
ntfs_is_hole_record(b->magic)) {
if (!b || ntfs_is_baad_record(b->magic) || ntfs_is_hole_record(b->magic))
{
errno = EINVAL;
ntfs_log_perror("%s: bad argument", __FUNCTION__);
return -1;
@ -157,9 +160,9 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
/* Decrement usa_count to get number of fixups. */
usa_count = le16_to_cpu(b->usa_count) - 1;
/* 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) {
if (size & (NTFS_BLOCK_SIZE - 1) || usa_ofs & 1 || (u32) (usa_ofs + (usa_count * 2)) > size || (size
>> NTFS_BLOCK_SIZE_BITS) != usa_count)
{
errno = EINVAL;
ntfs_log_perror("%s", __FUNCTION__);
return -1;
@ -171,14 +174,14 @@ int ntfs_mst_pre_write_fixup(NTFS_RECORD *b, const u32 size)
* (skipping 0 and -1, i.e. 0xffff).
*/
usn = le16_to_cpup(usa_pos) + 1;
if (usn == 0xffff || !usn)
usn = 1;
if (usn == 0xffff || !usn) usn = 1;
usn = cpu_to_le16(usn);
*usa_pos = usn;
/* 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 +220,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,30 +41,10 @@
#include "cache.h"
// NTFS device driver devoptab
static const devoptab_t devops_ntfs = {
NULL, /* Device name */
sizeof (ntfs_file_state),
ntfs_open_r,
ntfs_close_r,
ntfs_write_r,
ntfs_read_r,
ntfs_seek_r,
ntfs_fstat_r,
ntfs_stat_r,
ntfs_link_r,
ntfs_unlink_r,
ntfs_chdir_r,
ntfs_rename_r,
ntfs_mkdir_r,
sizeof (ntfs_dir_state),
ntfs_diropen_r,
ntfs_dirreset_r,
ntfs_dirnext_r,
ntfs_dirclose_r,
ntfs_statvfs_r,
ntfs_ftruncate_r,
ntfs_fsync_r,
NULL /* Device data */
static const devoptab_t devops_ntfs = { NULL, /* Device name */
sizeof(ntfs_file_state), ntfs_open_r, ntfs_close_r, ntfs_write_r, ntfs_read_r, ntfs_seek_r, ntfs_fstat_r, ntfs_stat_r,
ntfs_link_r, ntfs_unlink_r, ntfs_chdir_r, ntfs_rename_r, ntfs_mkdir_r, sizeof(ntfs_dir_state), ntfs_diropen_r,
ntfs_dirreset_r, ntfs_dirnext_r, ntfs_dirclose_r, ntfs_statvfs_r, ntfs_ftruncate_r, ntfs_fsync_r, NULL /* Device data */
};
void ntfsInit(void)
@ -72,7 +52,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 +79,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,38 +88,43 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
} sector;
// Sanity check
if (!interface) {
if (!interface)
{
errno = EINVAL;
return -1;
}
if (!partitions)
return 0;
if (!partitions) return 0;
// Initialise ntfs-3g
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 +133,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 +169,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,20 +194,26 @@ 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;
}
}
@ -221,17 +225,22 @@ int ntfsFindPartitions (const DISC_INTERFACE *interface, sec_t **partitions)
}
// 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 +256,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 +284,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,16 +312,21 @@ 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;
@ -312,8 +334,11 @@ int ntfsMountAll (ntfs_md **mounts, u32 flags)
} 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 +352,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 +377,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,17 +387,23 @@ 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;
@ -377,8 +411,11 @@ int ntfsMountDevice (const DISC_INTERFACE *interface, ntfs_md **mounts, u32 flag
} 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 +431,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;
}
@ -411,13 +451,15 @@ int ntfsMountDevice (const DISC_INTERFACE *interface, ntfs_md **mounts, u32 flag
return 0;
}
bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSector, u32 cachePageCount, u32 cachePageSize, u32 flags)
bool ntfsMount(const char *name, const DISC_INTERFACE *interface, sec_t startSector, u32 cachePageCount,
u32 cachePageSize, u32 flags)
{
ntfs_vd *vd = NULL;
gekko_fd *fd = NULL;
// Sanity check
if (!name || !interface) {
if (!name || !interface)
{
errno = EINVAL;
return false;
}
@ -426,20 +468,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 +502,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 +519,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;
@ -484,46 +531,56 @@ bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSe
vd->flags |= MS_RDONLY;
else
{
if (!(interface->features & FEATURE_MEDIUM_CANWRITE))
vd->flags |= MS_RDONLY;
if ((interface->features & FEATURE_MEDIUM_CANREAD) && (interface->features & FEATURE_MEDIUM_CANWRITE))
vd->flags |= MS_EXCLUSIVE;
if (!(interface->features & FEATURE_MEDIUM_CANWRITE)) vd->flags |= MS_RDONLY;
if ((interface->features & FEATURE_MEDIUM_CANREAD) && (interface->features & FEATURE_MEDIUM_CANWRITE)) vd->flags
|= MS_EXCLUSIVE;
}
if (flags & NTFS_RECOVER)
vd->flags |= MS_RECOVER;
if (flags & NTFS_IGNORE_HIBERFILE)
vd->flags |= MS_IGNORE_HIBERFILE;
if (flags & NTFS_RECOVER) vd->flags |= MS_RECOVER;
if (flags & NTFS_IGNORE_HIBERFILE) vd->flags |= MS_IGNORE_HIBERFILE;
if (vd->flags & MS_RDONLY)
ntfs_log_debug("Mounting \"%s\" as read-only\n", name);
// Mount the device
vd->vol = ntfs_device_mount(vd->dev, vd->flags);
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;
case NTFS_VOLUME_UNCLEAN_UNMOUNT: errno = EDIRTY; break;
default: errno = EINVAL; break;
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;
case NTFS_VOLUME_UNCLEAN_UNMOUNT:
errno = EDIRTY;
break;
default:
errno = EINVAL;
break;
}
ntfs_device_free(vd->dev);
ntfs_free(vd);
return false;
}
if (flags & NTFS_IGNORE_CASE)
ntfs_set_ignore_case(vd->vol);
if (flags & NTFS_IGNORE_CASE) ntfs_set_ignore_case(vd->vol);
// 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);
@ -539,8 +596,7 @@ void ntfsUnmount (const char *name, bool force)
// Get the devices volume descriptor
vd = ntfsGetVolume(name);
if (!vd)
return;
if (!vd) return;
// Remove the device from the devoptab table
ntfsRemoveDevice(name);
@ -565,14 +621,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;
}
@ -645,14 +703,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;
}
@ -662,7 +722,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;
@ -670,26 +731,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;
@ -701,11 +768,11 @@ bool ntfsSetVolumeName (const char *name, const char *volumeName)
vd->name[0] = '\0';
// Close the volume name attribute
if (na)
ntfs_attr_close(na);
if (na) 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>
@ -55,7 +56,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 */
@ -110,7 +112,8 @@ extern int ntfsMountDevice (const DISC_INTERFACE* interface, ntfs_md **mounts, u
* @return True if mount was successful, false if no partition was found or an error occurred (see errno)
* @note ntfsFindPartitions should be used first to locate the partitions start sector
*/
extern bool ntfsMount (const char *name, const DISC_INTERFACE *interface, sec_t startSector, u32 cachePageCount, u32 cachePageSize, u32 flags);
extern bool ntfsMount(const char *name, const DISC_INTERFACE *interface, sec_t startSector, u32 cachePageCount,
u32 cachePageSize, u32 flags);
/**
* Unmount a NTFS partition.

View File

@ -50,11 +50,11 @@
void ntfsCloseDir(ntfs_dir_state *dir)
{
// Sanity check
if (!dir || !dir->vd)
return;
if (!dir || !dir->vd) 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);
@ -62,8 +62,7 @@ void ntfsCloseDir (ntfs_dir_state *dir)
}
// Close the directory (if open)
if (dir->ni)
ntfsCloseEntry(dir->vd, dir->ni);
if (dir->ni) ntfsCloseEntry(dir->vd, dir->ni);
// Reset the directory state
dir->ni = NULL;
@ -76,8 +75,7 @@ void ntfsCloseDir (ntfs_dir_state *dir)
int ntfs_stat_r(struct _reent *r, const char *path, struct stat *st)
{
// Short circuit cases were we don't actually have to do anything
if (!st || !path)
return 0;
if (!st || !path) return 0;
ntfs_log_trace("path %s, st %p\n", path, st);
@ -86,7 +84,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 +102,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;
@ -111,8 +111,7 @@ int ntfs_stat_r (struct _reent *r, const char *path, struct stat *st)
// Get the entry stats
int ret = ntfsStat(vd, ni, st);
if (ret)
r->_errno = errno;
if (ret) r->_errno = errno;
// Close the entry
ntfsCloseEntry(vd, ni);
@ -131,7 +130,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 +141,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;
@ -162,8 +163,7 @@ int ntfs_unlink_r (struct _reent *r, const char *name)
// Unlink the entry
int ret = ntfsUnlink(ntfsGetVolume(name), name);
if (ret)
r->_errno = errno;
if (ret) r->_errno = errno;
return ret;
}
@ -177,7 +177,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 +188,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;
@ -202,8 +205,7 @@ int ntfs_chdir_r (struct _reent *r, const char *name)
}
// Close the old current directory (if any)
if (vd->cwd_ni)
ntfsCloseEntry(vd, vd->cwd_ni);
if (vd->cwd_ni) ntfsCloseEntry(vd, vd->cwd_ni);
// Set the new current directory
vd->cwd_ni = ni;
@ -223,7 +225,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 +235,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 +244,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 +253,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 +286,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 +297,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,14 +323,14 @@ 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;
}
// Short circuit cases were we don't actually have to do anything
if (!buf)
return 0;
if (!buf) return 0;
// Lock
ntfsLock(vd);
@ -351,8 +361,7 @@ int ntfs_statvfs_r (struct _reent *r, const char *path, struct statvfs *buf)
delta_bits = vd->vol->cluster_size_bits - vd->vol->mft_record_size_bits;
if (delta_bits >= 0)
size <<= delta_bits;
else
size >>= -delta_bits;
else size >>= -delta_bits;
// Number of inodes at this point in time
buf->f_files = (vd->vol->mftbmp_na->allocated_size << 3) + size;
@ -387,41 +396,45 @@ 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;
}
if(dir->first && dir->first->mref == FILE_root &&
MREF(mref) == FILE_root && strcmp(entry_name, "..") == 0)
if (dir->first && dir->first->mref == FILE_root && MREF(mref) == FILE_root && strcmp(entry_name, "..") == 0)
{
return 0;
}
// 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);
if (!ni)
return -1;
if (!ni) return -1;
// 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)) {
if (((ni->flags & FILE_ATTR_HIDDEN) && !dir->vd->showHiddenFiles) || ((ni->flags & FILE_ATTR_SYSTEM)
&& !dir->vd->showSystemFiles))
{
ntfs_inode_close(ni);
return 0;
}
@ -433,8 +446,7 @@ int ntfs_readdir_filler (DIR_ITER *dirState, const ntfschar *name, const int nam
// Allocate a new directory entry
entry = (ntfs_dir_entry *) ntfs_alloc(sizeof(ntfs_dir_entry));
if (!entry)
return -1;
if (!entry) return -1;
// Setup the entry
entry->name = entry_name;
@ -442,11 +454,15 @@ 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;
while (last->next)
last = last->next;
last->next = entry;
}
@ -464,7 +480,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 +491,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 +509,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 +524,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 +551,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 +580,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 +590,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 +609,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 +636,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;
}
@ -622,12 +650,10 @@ int ntfs_dirclose_r (struct _reent *r, DIR_ITER *dirState)
// Remove the directory from the double-linked FILO list of open directories
dir->vd->openDirCount--;
if (dir->nextOpenDir)
dir->nextOpenDir->prevOpenDir = dir->prevOpenDir;
if (dir->nextOpenDir) dir->nextOpenDir->prevOpenDir = dir->prevOpenDir;
if (dir->prevOpenDir)
dir->prevOpenDir->nextOpenDir = dir->nextOpenDir;
else
dir->vd->firstOpenDir = dir->nextOpenDir;
else dir->vd->firstOpenDir = dir->nextOpenDir;
// Unlock
ntfsUnlock(dir->vd);

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

@ -48,19 +48,16 @@
void ntfsCloseFile(ntfs_file_state *file)
{
// Sanity check
if (!file || !file->vd)
return;
if (!file || !file->vd) return;
// Special case fix ups for compressed and/or encrypted files
if (file->compressed)
ntfs_attr_pclose(file->data_na);
if (file->compressed) ntfs_attr_pclose(file->data_na);
#ifdef HAVE_SETXATTR
if (file->encrypted)
ntfs_efs_fixup_attribute(NULL, file->data_na);
#endif
// Close the file data attribute (if open)
if (file->data_na)
ntfs_attr_close(file->data_na);
if (file->data_na) ntfs_attr_close(file->data_na);
// Sync the file (and its attributes) to disc
if (file->write)
@ -69,12 +66,10 @@ void ntfsCloseFile (ntfs_file_state *file)
ntfsSync(file->vd, file->ni);
}
if (file->read)
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_ATIME);
if (file->read) ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_ATIME);
// Close the file (if open)
if (file->ni)
ntfsCloseEntry(file->vd, file->ni);
if (file->ni) ntfsCloseEntry(file->vd, file->ni);
// Reset the file state
file->ni = NULL;
@ -97,7 +92,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 +103,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 +130,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,11 +139,13 @@ int ntfs_open_r (struct _reent *r, void *fileStruct, const char *path, int flags
}
// Are we creating this file?
if ((flags & O_CREAT) && !file->ni) {
if ((flags & O_CREAT) && !file->ni)
{
// Create the file
file->ni = ntfsCreate(file->vd, path, S_IFREG, NULL);
if (!file->ni) {
if (!file->ni)
{
ntfsUnlock(file->vd);
return -1;
}
@ -147,7 +153,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;
@ -155,7 +162,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;
@ -166,7 +174,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);
@ -175,7 +184,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);
@ -184,8 +194,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);
@ -204,10 +216,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;
@ -227,7 +242,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;
}
@ -240,12 +256,10 @@ int ntfs_close_r (struct _reent *r, int fd)
// Remove the file from the double-linked FILO list of open files
file->vd->openFileCount--;
if (file->nextOpenFile)
file->nextOpenFile->prevOpenFile = file->prevOpenFile;
if (file->nextOpenFile) file->nextOpenFile->prevOpenFile = file->prevOpenFile;
if (file->prevOpenFile)
file->prevOpenFile->nextOpenFile = file->nextOpenFile;
else
file->vd->firstOpenFile = file->nextOpenFile;
else file->vd->firstOpenFile = file->nextOpenFile;
// Unlock
ntfsUnlock(file->vd);
@ -262,13 +276,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;
}
@ -276,22 +292,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;
@ -302,13 +322,13 @@ 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;
}
// Mark the file for archiving (if we actually wrote something)
if (written)
file->ni->flags |= FILE_ATTR_ARCHIVE;
if (written) file->ni->flags |= FILE_ATTR_ARCHIVE;
// Update the files data length
file->len = file->data_na->data_size;
@ -327,13 +347,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;
}
@ -341,14 +363,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");
@ -357,9 +381,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;
@ -386,7 +412,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;
}
@ -395,10 +422,17 @@ 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) {
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;
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;
}
// Unlock
@ -414,19 +448,18 @@ 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;
}
// Short circuit cases were we don't actually have to do anything
if (!st)
return 0;
if (!st) return 0;
// Get the file stats
ret = ntfsStat(file->vd, file->ni, st);
if (ret)
r->_errno = errno;
if (ret) r->_errno = errno;
return ret;
}
@ -438,7 +471,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;
}
@ -447,31 +481,36 @@ 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;
}
// For compressed files, only deleting and expanding contents are implemented
if (file->compressed &&
len > 0 &&
len < file->data_na->initialized_size) {
if (file->compressed && len > 0 && 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;
@ -479,12 +518,10 @@ int ntfs_ftruncate_r (struct _reent *r, int fd, off_t len)
}
// Mark the file for archiving (if we actually changed something)
if (file->len != file->data_na->data_size)
file->ni->flags |= FILE_ATTR_ARCHIVE;
if (file->len != file->data_na->data_size) file->ni->flags |= FILE_ATTR_ARCHIVE;
// Update file times (if we actually changed something)
if (file->len != file->data_na->data_size)
ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_AMCTIME);
if (file->len != file->data_na->data_size) ntfsUpdateTimes(file->vd, file->ni, NTFS_UPDATE_AMCTIME);
// Update the files data length
file->len = file->data_na->data_size;
@ -506,7 +543,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;
}
@ -516,8 +554,7 @@ int ntfs_fsync_r (struct _reent *r, int fd)
// Sync the file (and its attributes) to disc
ret = ntfsSync(file->vd, file->ni);
if (ret)
r->_errno = errno;
if (ret) r->_errno = errno;
// Unlock
ntfsUnlock(file->vd);

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

@ -363,11 +363,10 @@ ssize_t ntfs_write_r ( struct _reent *r, int fd, const char *ptr, size_t len )
#endif
s64 ntfs_attr_getfragments( ntfs_attr *na, const s64 pos, s64 count, u64 offset,
_ntfs_frag_append_t append_fragment, void *callback_data );
s64 ntfs_attr_getfragments(ntfs_attr *na, const s64 pos, s64 count, u64 offset, _ntfs_frag_append_t append_fragment,
void *callback_data);
int _NTFS_get_fragments ( const char *path,
_ntfs_frag_append_t append_fragment, void *callback_data )
int _NTFS_get_fragments(const char *path, _ntfs_frag_append_t append_fragment, void *callback_data)
{
struct _reent r;
ntfs_file_state file_st, *file = &file_st;
@ -379,10 +378,6 @@ int _NTFS_get_fragments ( const char *path,
int fd = ntfs_open_r(&r, file, path, O_RDONLY, 0);
if (fd != (int) file) return -12;
// Sanity check
if (!file || !file->vd || !file->ni || !file->data_na)
{
@ -421,8 +416,7 @@ int _NTFS_get_fragments ( const char *path,
// Read from the files data attribute
while (len)
{
s64 ret = ntfs_attr_getfragments( file->data_na, file->pos,
len, offset, append_fragment, callback_data );
s64 ret = ntfs_attr_getfragments(file->data_na, file->pos, len, offset, append_fragment, callback_data);
if (ret <= 0 || ret > len)
{
ntfsUnlock(file->vd);

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