userlibandfileserver/fileserver/sfat/sl_vfat.cpp
changeset 15 4122176ea935
parent 0 a41df078684a
equal deleted inserted replaced
0:a41df078684a 15:4122176ea935
    13 // Description:
    13 // Description:
    14 // f32\sfat\sl_vfat.cpp
    14 // f32\sfat\sl_vfat.cpp
    15 // 
    15 // 
    16 //
    16 //
    17 
    17 
       
    18 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    19 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    20 //!!
       
    21 //!! WARNING!! DO NOT edit this file !! '\sfat' component is obsolete and is not being used. '\sfat32'replaces it
       
    22 //!!
       
    23 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    24 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
       
    25 
       
    26 
    18 #include "sl_std.h"
    27 #include "sl_std.h"
    19 #include "sl_cache.h"
    28 #include "sl_cache.h"
    20 #include <e32svr.h>
    29 #include <e32svr.h>
    21 #include <e32math.h>
    30 #include <e32math.h>
    22 
    31 
    32 
    41 
    33 LOCAL_C TBool IsLegalChar(TChar aCharacter,TBool aAllowWildChars,TBool aUseExtendedChars=EFalse,TBool aInScanDrive=EFalse)
    42 LOCAL_C TBool IsLegalChar(TChar aCharacter,TBool aAllowWildChars,TBool aUseExtendedChars=EFalse,TBool aInScanDrive=EFalse)
    34 //
    43 //
    35 // Returns ETrue if aCharacter is legal inside a dos filename
    44 // Returns ETrue if aCharacter is legal inside a dos filename
    36 //
    45 //
    37 	{
    46     {
    38 	if ((aCharacter==KMatchOne) || (aCharacter==KMatchAny))
    47     if ((aCharacter==KMatchOne) || (aCharacter==KMatchAny))
    39 		return(aAllowWildChars);
    48         return(aAllowWildChars);
    40 	if ((TUint)aCharacter < 0x20)
    49     if ((TUint)aCharacter < 0x20)
    41 	    return EFalse;
    50         return EFalse;
    42    	// Don't check illegal ascii char because some non-English char value may
    51     // Don't check illegal ascii char because some non-English char value may
    43    	// fall in this area
    52     // fall in this area
    44     if (aInScanDrive)
    53     if (aInScanDrive)
    45     	return ETrue;
    54         return ETrue;
    46 	return LocaleUtils::IsLegalShortNameCharacter(aCharacter,aUseExtendedChars);
    55     return LocaleUtils::IsLegalShortNameCharacter(aCharacter,aUseExtendedChars);
    47 	}
    56     }
    48 
    57 
    49 LOCAL_C void ReplaceFirstCharacterIfClashesWithE5L(TDes8& aShortName)
    58 LOCAL_C void ReplaceFirstCharacterIfClashesWithE5L(TDes8& aShortName)
    50 	{
    59     {
    51 	if (0 < aShortName.Length() && aShortName[0] == KEntryErasedMarker)
    60     if (0 < aShortName.Length() && aShortName[0] == KEntryErasedMarker)
    52 		{
    61         {
    53 		aShortName[0] = KLeadingE5Replacement;
    62         aShortName[0] = KLeadingE5Replacement;
    54 		}
    63         }
    55 	}
    64     }
    56 
    65 
    57 LOCAL_C void ReplaceIllegalCharactersL(TDes& aLongName, TUint aCharacterToReplaceWith)
    66 LOCAL_C void ReplaceIllegalCharactersL(TDes& aLongName, TUint aCharacterToReplaceWith)
    58 	{
    67     {
    59 	TBool alreadyFoundExtensionDelimiter=EFalse;
    68     TBool alreadyFoundExtensionDelimiter=EFalse;
    60 
    69 
    61 	TInt LongNameLen = aLongName.Length();
    70     TInt LongNameLen = aLongName.Length();
    62 	TInt extDelimiterIndex = aLongName.LocateReverse(KExtDelimiter);
    71     TInt extDelimiterIndex = aLongName.LocateReverse(KExtDelimiter);
    63 
    72 
    64 	for (TInt i=LongNameLen-1; i>=0; --i) // iterate backwards as aLongName may change length during the loop, and also because we want to leave the *right-most* occurrence of KExtDelimiter unchanged
    73     for (TInt i=LongNameLen-1; i>=0; --i) // iterate backwards as aLongName may change length during the loop, and also because we want to leave the *right-most* occurrence of KExtDelimiter unchanged
    65 		{
    74         {
    66 		TUint character=aLongName[i];
    75         TUint character=aLongName[i];
    67 		if (character==(TUint)KExtDelimiter)
    76         if (character==(TUint)KExtDelimiter)
    68 			{
    77             {
    69 			if (alreadyFoundExtensionDelimiter)
    78             if (alreadyFoundExtensionDelimiter)
    70 				{
    79                 {
    71 				aLongName[i]=(TText)aCharacterToReplaceWith; // A.B.C becomes A_B.C
    80                 aLongName[i]=(TText)aCharacterToReplaceWith; // A.B.C becomes A_B.C
    72 				}
    81                 }
    73 			alreadyFoundExtensionDelimiter=ETrue;
    82             alreadyFoundExtensionDelimiter=ETrue;
    74 			}
    83             }
    75 		else
    84         else
    76 			{
    85             {
    77 			// the code below doesn't need any #if defined(_UNICODE) stuff as a narrow-build aLongName would not contain values above 0xff (which is well below the surrogates area in Unicode 0xd800-0xdfff)
    86             // the code below doesn't need any #if defined(_UNICODE) stuff as a narrow-build aLongName would not contain values above 0xff (which is well below the surrogates area in Unicode 0xd800-0xdfff)
    78 			TBool isSurrogatePair=EFalse;
    87             TBool isSurrogatePair=EFalse;
    79 
    88 
    80 			// LAST character in file name or file ext CAN NOT be HIGH surrogate
    89             // LAST character in file name or file ext CAN NOT be HIGH surrogate
    81 			if (i==LongNameLen-1 || i==extDelimiterIndex-1)
    90             if (i==LongNameLen-1 || i==extDelimiterIndex-1)
    82 				{
    91                 {
    83 				if (IsHighSurrogate((TText16)character))
    92                 if (IsHighSurrogate((TText16)character))
    84 					{
    93                     {
    85 					// Corrupt surrogate
    94                     // Corrupt surrogate
    86 					User::Leave(KErrBadName);
    95                     User::Leave(KErrBadName);
    87 					}
    96                     }
    88 				}
    97                 }
    89 			// FIRST character in file name or file ext CAN NOT be LOW surrogate
    98             // FIRST character in file name or file ext CAN NOT be LOW surrogate
    90 			if (i==0 || i==extDelimiterIndex+1)
    99             if (i==0 || i==extDelimiterIndex+1)
    91 				{
   100                 {
    92 				if (IsLowSurrogate((TText16)character))
   101                 if (IsLowSurrogate((TText16)character))
    93 					{
   102                     {
    94 					// Corrupt surrogate
   103                     // Corrupt surrogate
    95 					User::Leave(KErrBadName);
   104                     User::Leave(KErrBadName);
    96 					}
   105                     }
    97 				}
   106                 }
    98 			// if LOW Surrogate
   107             // if LOW Surrogate
    99 			if (IsLowSurrogate((TText16)character))
   108             if (IsLowSurrogate((TText16)character))
   100 				{
   109                 {
   101 				// check for HIGH surrogate
   110                 // check for HIGH surrogate
   102 				if (!IsHighSurrogate(aLongName[--i]))
   111                 if (!IsHighSurrogate(aLongName[--i]))
   103 					{
   112                     {
   104 					// Corrupt surrogate
   113                     // Corrupt surrogate
   105 					User::Leave(KErrBadName);
   114                     User::Leave(KErrBadName);
   106 					}
   115                     }
   107 				// surrogate pair found
   116                 // surrogate pair found
   108 				character&=~0xdc00;
   117                 character&=~0xdc00;
   109 				character|=((aLongName[i]&~0xd800)<<10);
   118                 character|=((aLongName[i]&~0xd800)<<10);
   110 				character+=0x00010000; // this must be added - it cannot be bitwise-"or"-ed
   119                 character+=0x00010000; // this must be added - it cannot be bitwise-"or"-ed
   111 				isSurrogatePair=ETrue;
   120                 isSurrogatePair=ETrue;
   112 				}
   121                 }
   113 
   122 
   114 			// if High Surrogate
   123             // if High Surrogate
   115 			if (!isSurrogatePair && IsHighSurrogate((TText16)character))
   124             if (!isSurrogatePair && IsHighSurrogate((TText16)character))
   116 				{
   125                 {
   117 				// Corrupt surrogate
   126                 // Corrupt surrogate
   118 				User::Leave(KErrBadName);
   127                 User::Leave(KErrBadName);
   119 				}
   128                 }
   120 
   129 
   121 			if (!IsLegalChar(character, EFalse))
   130             if (!IsLegalChar(character, EFalse))
   122 				{
   131                 {
   123 				if (isSurrogatePair)
   132                 if (isSurrogatePair)
   124 					{
   133                     {
   125 					aLongName.Delete(i+1, 1);
   134                     aLongName.Delete(i+1, 1);
   126 					}
   135                     }
   127 				aLongName[i]=(TText)aCharacterToReplaceWith;
   136                 aLongName[i]=(TText)aCharacterToReplaceWith;
   128 				}
   137                 }
   129 			}
   138             }
   130 		}
   139         }
   131 	}
   140     }
   132 
   141 
   133 TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively)
   142 TShortName DoGenerateShortNameL(const TDesC& aLongName,TInt& aNum,TBool aUseTildeSelectively)
   134 //
   143 //
   135 // Create a legal shortname from aLongName
   144 // Create a legal shortname from aLongName
   136 //
   145 //
   137 	{
   146     {
   138 
   147 
   139 	TFileName longName(aLongName);
   148     TFileName longName(aLongName);
   140 	longName.UpperCase();
   149     longName.UpperCase();
   141 	ReplaceIllegalCharactersL(longName, '_');
   150     ReplaceIllegalCharactersL(longName, '_');
   142 	TPtrC longNameWithoutExtension(longName);
   151     TPtrC longNameWithoutExtension(longName);
   143 	TPtrC longNameExtension(KNullDesC);
   152     TPtrC longNameExtension(KNullDesC);
   144 	const TInt positionOfExtension=longName.LocateReverse(KExtDelimiter);
   153     const TInt positionOfExtension=longName.LocateReverse(KExtDelimiter);
   145 	if (positionOfExtension==0)
   154     if (positionOfExtension==0)
   146 		{
   155         {
   147 		// No filename specified, so use the extension as the basis of the shortname.
   156         // No filename specified, so use the extension as the basis of the shortname.
   148 		// Make sure we always append a tilde+number in this case to avoid generating the same 
   157         // Make sure we always append a tilde+number in this case to avoid generating the same 
   149 		// short filename as one of the protected folders ("\SYS", "\RESOURCE","\PRIVATE")
   158         // short filename as one of the protected folders ("\SYS", "\RESOURCE","\PRIVATE")
   150 		longNameWithoutExtension.Set(longName.Mid(positionOfExtension+1));
   159         longNameWithoutExtension.Set(longName.Mid(positionOfExtension+1));
   151 		aUseTildeSelectively = EFalse;
   160         aUseTildeSelectively = EFalse;
   152 		if (aNum < 0)
   161         if (aNum < 0)
   153 			aNum = 1;
   162             aNum = 1;
   154 		}
   163         }
   155 	else if (positionOfExtension!=KErrNotFound)
   164     else if (positionOfExtension!=KErrNotFound)
   156 		{
   165         {
   157 		longNameWithoutExtension.Set(longName.Left(positionOfExtension));
   166         longNameWithoutExtension.Set(longName.Left(positionOfExtension));
   158 		longNameExtension.Set(longName.Mid(positionOfExtension+1));
   167         longNameExtension.Set(longName.Mid(positionOfExtension+1));
   159 		}
   168         }
   160 	
   169     
   161 	// Converts the original file name main part into 8-bit character string
   170     // Converts the original file name main part into 8-bit character string
   162 	TShortName tempShortName(0);
   171     TShortName tempShortName(0);
   163 
   172 
   164 	LocaleUtils::ConvertFromUnicodeL(tempShortName, longNameWithoutExtension);
   173     LocaleUtils::ConvertFromUnicodeL(tempShortName, longNameWithoutExtension);
   165 	const TInt originalNameLength = tempShortName.Length();
   174     const TInt originalNameLength = tempShortName.Length();
   166 
   175 
   167 	// Converts the original file name extension part into 8-bit character string
   176     // Converts the original file name extension part into 8-bit character string
   168 	TShortName tempShortNameExt(0);
   177     TShortName tempShortNameExt(0);
   169 	
   178     
   170 	LocaleUtils::ConvertFromUnicodeL(tempShortNameExt, longNameExtension);
   179     LocaleUtils::ConvertFromUnicodeL(tempShortNameExt, longNameExtension);
   171 	const TInt extensionNameLength = tempShortNameExt.Length();
   180     const TInt extensionNameLength = tempShortNameExt.Length();
   172 	// // const TInt extensionNameLength = tempShortNameExt.Length();
   181     // // const TInt extensionNameLength = tempShortNameExt.Length();
   173 
   182 
   174 	// Checks the length of both original file name main part and original file name extension part
   183     // Checks the length of both original file name main part and original file name extension part
   175 	if(aUseTildeSelectively)
   184     if(aUseTildeSelectively)
   176 		{
   185         {
   177 		// don't append ~<aNum>
   186         // don't append ~<aNum>
   178 		if(originalNameLength<=KMaxLengthWithoutTilde && extensionNameLength<=KMaxFatFileNameExt)
   187         if(originalNameLength<=KMaxLengthWithoutTilde && extensionNameLength<=KMaxFatFileNameExt)
   179 			aNum=-1;
   188             aNum=-1;
   180 		}
   189         }
   181 
   190 
   182 	// Applies tilde and number if necessary
   191     // Applies tilde and number if necessary
   183 	TBuf8<5> tildeAndNumber;
   192     TBuf8<5> tildeAndNumber;
   184 	if (aNum>=0)
   193     if (aNum>=0)
   185 		{
   194         {
   186 		tildeAndNumber.Append('~');
   195         tildeAndNumber.Append('~');
   187 		tildeAndNumber.AppendNumUC(aNum,EHex);
   196         tildeAndNumber.AppendNumUC(aNum,EHex);
   188 		}
   197         }
   189 	const TInt lengthOfTildeAndNumber=tildeAndNumber.Length();
   198     const TInt lengthOfTildeAndNumber=tildeAndNumber.Length();
   190 
   199 
   191 	// Creates actual shortname from longname of the original file
   200     // Creates actual shortname from longname of the original file
   192 	TShortName shortName(11);
   201     TShortName shortName(11);
   193 #if defined(_DEBUG)
   202 #if defined(_DEBUG)
   194 	shortName.Fill(0x01); // fill shortName with garbage to ensure that every byte is written to by this function
   203     shortName.Fill(0x01); // fill shortName with garbage to ensure that every byte is written to by this function
   195 #endif
   204 #endif
   196 
   205 
   197 	// Fills the main part of the shortname of the original file
   206     // Fills the main part of the shortname of the original file
   198 	const TInt numberOfBytesFreeBeforeTilde=KMaxFatFileNameWithoutExt-lengthOfTildeAndNumber;
   207     const TInt numberOfBytesFreeBeforeTilde=KMaxFatFileNameWithoutExt-lengthOfTildeAndNumber;
   199 
   208 
   200 	TPtr8 portionOfShortNameBeforeTilde((TUint8*)shortName.Ptr(), 0, numberOfBytesFreeBeforeTilde);
   209     TPtr8 portionOfShortNameBeforeTilde((TUint8*)shortName.Ptr(), 0, numberOfBytesFreeBeforeTilde);
   201 	TInt lengthOfPortionOfShortNameBeforeTilde = 
   210     TInt lengthOfPortionOfShortNameBeforeTilde = 
   202 				(originalNameLength < numberOfBytesFreeBeforeTilde) ? originalNameLength : numberOfBytesFreeBeforeTilde;
   211                 (originalNameLength < numberOfBytesFreeBeforeTilde) ? originalNameLength : numberOfBytesFreeBeforeTilde;
   203 
   212 
   204 	portionOfShortNameBeforeTilde.Copy((TUint8*)tempShortName.Ptr(), lengthOfPortionOfShortNameBeforeTilde);
   213     portionOfShortNameBeforeTilde.Copy((TUint8*)tempShortName.Ptr(), lengthOfPortionOfShortNameBeforeTilde);
   205 	if( lengthOfPortionOfShortNameBeforeTilde != originalNameLength)
   214     if( lengthOfPortionOfShortNameBeforeTilde != originalNameLength)
   206 		{
   215         {
   207 		for( int i = 0; i<lengthOfPortionOfShortNameBeforeTilde; i++)
   216         for( int i = 0; i<lengthOfPortionOfShortNameBeforeTilde; i++)
   208 			{
   217             {
   209 			if(portionOfShortNameBeforeTilde[i] >= 0x80) //leading byte found
   218             if(portionOfShortNameBeforeTilde[i] >= 0x80) //leading byte found
   210 				{
   219                 {
   211 				if( i == lengthOfPortionOfShortNameBeforeTilde - 1) //leading byte found on the edge
   220                 if( i == lengthOfPortionOfShortNameBeforeTilde - 1) //leading byte found on the edge
   212 					{
   221                     {
   213 					lengthOfPortionOfShortNameBeforeTilde -= 1;
   222                     lengthOfPortionOfShortNameBeforeTilde -= 1;
   214 					break;
   223                     break;
   215 					}
   224                     }
   216 				else
   225                 else
   217 					{
   226                     {
   218 					i++;
   227                     i++;
   219 					}
   228                     }
   220 				}
   229                 }
   221 			}
   230             }
   222 		}
   231         }
   223 	Mem::Copy(((TUint8*)shortName.Ptr())+lengthOfPortionOfShortNameBeforeTilde, tildeAndNumber.Ptr(), lengthOfTildeAndNumber);
   232     Mem::Copy(((TUint8*)shortName.Ptr())+lengthOfPortionOfShortNameBeforeTilde, tildeAndNumber.Ptr(), lengthOfTildeAndNumber);
   224 	TInt i;
   233     TInt i;
   225 	for (i=lengthOfPortionOfShortNameBeforeTilde+lengthOfTildeAndNumber; i<KMaxFatFileNameWithoutExt; ++i)
   234     for (i=lengthOfPortionOfShortNameBeforeTilde+lengthOfTildeAndNumber; i<KMaxFatFileNameWithoutExt; ++i)
   226 		{
   235         {
   227 		shortName[i]=' ';
   236         shortName[i]=' ';
   228 		}
   237         }
   229 
   238 
   230 	// Fills the extension part of the shortname of the original file
   239     // Fills the extension part of the shortname of the original file
   231 	TInt lengthOfExt = 
   240     TInt lengthOfExt = 
   232 				(extensionNameLength < KMaxFatFileNameExt) ? extensionNameLength : KMaxFatFileNameExt;
   241                 (extensionNameLength < KMaxFatFileNameExt) ? extensionNameLength : KMaxFatFileNameExt;
   233 	
   242     
   234 	if( lengthOfExt != extensionNameLength)
   243     if( lengthOfExt != extensionNameLength)
   235 		{
   244         {
   236 		for( int i = 0; i<lengthOfExt; i++)
   245         for( int i = 0; i<lengthOfExt; i++)
   237 			{
   246             {
   238 			if(tempShortNameExt[i] >= 0x80)
   247             if(tempShortNameExt[i] >= 0x80)
   239 				{
   248                 {
   240 				if( i == lengthOfExt - 1)
   249                 if( i == lengthOfExt - 1)
   241 					{
   250                     {
   242 					lengthOfExt -= 1;
   251                     lengthOfExt -= 1;
   243 					break;
   252                     break;
   244 					}
   253                     }
   245 				else
   254                 else
   246 					{
   255                     {
   247 					i++;
   256                     i++;
   248 					}
   257                     }
   249 				}
   258                 }
   250 			}
   259             }
   251 		}			
   260         }           
   252 	Mem::Copy(((TUint8*)shortName.Ptr()) + KMaxFatFileNameWithoutExt, tempShortNameExt.Ptr(), lengthOfExt);
   261     Mem::Copy(((TUint8*)shortName.Ptr()) + KMaxFatFileNameWithoutExt, tempShortNameExt.Ptr(), lengthOfExt);
   253 	for (i = KMaxFatFileNameWithoutExt + lengthOfExt; i<KMaxFatFileNameWithoutExt+KMaxFatFileNameExt; ++i)
   262     for (i = KMaxFatFileNameWithoutExt + lengthOfExt; i<KMaxFatFileNameWithoutExt+KMaxFatFileNameExt; ++i)
   254 		{
   263         {
   255 		shortName[i]=' ';
   264         shortName[i]=' ';
   256 		}
   265         }
   257 	
   266     
   258 	ReplaceFirstCharacterIfClashesWithE5L(shortName);		
   267     ReplaceFirstCharacterIfClashesWithE5L(shortName);       
   259 	return shortName;
   268     return shortName;
   260 	}
   269     }
   261 
   270 
   262 
   271 
   263 /**
   272 /**
   264 Check whether a Dos name is legal or not.
   273 Check whether a Dos name is legal or not.
   265 
   274 
   266 @param aName                The entry name to be analysed (may be represented as TDes16& or TDes8&)
   275 @param aName                The entry name to be analysed (may be represented as TDes16& or TDes8&)
   267 @param anAllowWildCards	    Flag to indicate whether to allow wildcards in name or not
   276 @param anAllowWildCards     Flag to indicate whether to allow wildcards in name or not
   268 @param aUseExtendedChars    Flag to indicate if extended characters are allowed
   277 @param aUseExtendedChars    Flag to indicate if extended characters are allowed
   269 @param aInScanDrive         Flag to indicate whether called when scanning drive
   278 @param aInScanDrive         Flag to indicate whether called when scanning drive
   270 @param aAllowLowerCase      ETrue to allow lower case in the analysed DOS name
   279 @param aAllowLowerCase      ETrue to allow lower case in the analysed DOS name
   271 
   280 
   272 @return ETrue if the name is a legal DOS one.
   281 @return ETrue if the name is a legal DOS one.
   273 */
   282 */
   274 
   283 
   275 static TBool DoCheckLegalDosName(const TDesC& aName, TBool anAllowWildCards, TBool aUseExtendedChars, TBool aInScanDrive, TBool aAllowLowerCase, TBool aIsForFileCreation)
   284 static TBool DoCheckLegalDosName(const TDesC& aName, TBool anAllowWildCards, TBool aUseExtendedChars, TBool aInScanDrive, TBool aAllowLowerCase, TBool aIsForFileCreation)
   276 	{
   285     {
   277     const TInt count=aName.Length();
   286     const TInt count=aName.Length();
   278 	if (count==0)
   287     if (count==0)
   279 		return EFalse;
   288         return EFalse;
   280 
   289 
   281 	TInt valid=0;
   290     TInt valid=0;
   282 	TInt i=0;
   291     TInt i=0;
   283 	
   292     
   284     //-- check the entry name
   293     //-- check the entry name
   285 	while (i<count)
   294     while (i<count)
   286 		{
   295         {
   287 		TChar c=aName[i++];
   296         TChar c=aName[i++];
   288 		if (c==KExtDelimiter)
   297         if (c==KExtDelimiter)
   289 			{
   298             {
   290 			// DOS entry names must contain at least one valid character before the extension
   299             // DOS entry names must contain at least one valid character before the extension
   291 			if (i == 1)
   300             if (i == 1)
   292 				return EFalse;
   301                 return EFalse;
   293 			break;
   302             break;
   294 			}
   303             }
   295 		
   304         
   296           if(!aAllowLowerCase && c.IsLower())
   305           if(!aAllowLowerCase && c.IsLower())
   297             return EFalse; //-- low case is not allowed
   306             return EFalse; //-- low case is not allowed
   298 
   307 
   299 		if (!IsLegalChar(c,anAllowWildCards,aUseExtendedChars,aInScanDrive))
   308         if (!IsLegalChar(c,anAllowWildCards,aUseExtendedChars,aInScanDrive))
   300 		    {
   309             {
   301 			return EFalse;
   310             return EFalse;
   302 		    }
   311             }
   303 		
   312         
   304 		if (aIsForFileCreation)
   313         if (aIsForFileCreation)
   305 			{
   314             {
   306 			if ((aUseExtendedChars && (TUint) c > KExtendedCharEnd) || 
   315             if ((aUseExtendedChars && (TUint) c > KExtendedCharEnd) || 
   307 					(!aUseExtendedChars && (TUint) c > KExtendedCharStart))
   316                     (!aUseExtendedChars && (TUint) c > KExtendedCharStart))
   308 				{
   317                 {
   309 				return EFalse;
   318                 return EFalse;
   310 				}
   319                 }
   311 			}
   320             }
   312 
   321 
   313 		if (c!=KMatchAny)
   322         if (c!=KMatchAny)
   314 			if (++valid>KMaxFatFileNameWithoutExt)
   323             if (++valid>KMaxFatFileNameWithoutExt)
   315 				return EFalse;
   324                 return EFalse;
   316 		}
   325         }
   317 	
   326     
   318 	//-- check entry extension
   327     //-- check entry extension
   319     valid=0;
   328     valid=0;
   320 	while (i<count)
   329     while (i<count)
   321 		{
   330         {
   322 		TChar c=aName[i++];
   331         TChar c=aName[i++];
   323 		if (c==KExtDelimiter)
   332         if (c==KExtDelimiter)
   324 			return EFalse;
   333             return EFalse;
   325 		
   334         
   326         if(!aAllowLowerCase && c.IsLower())
   335         if(!aAllowLowerCase && c.IsLower())
   327             return EFalse; //-- low case is not allowed
   336             return EFalse; //-- low case is not allowed
   328 
   337 
   329 		if (!IsLegalChar(c,anAllowWildCards,aUseExtendedChars,aInScanDrive))
   338         if (!IsLegalChar(c,anAllowWildCards,aUseExtendedChars,aInScanDrive))
   330 			return EFalse;
   339             return EFalse;
   331 		
   340         
   332 		if (aIsForFileCreation)
   341         if (aIsForFileCreation)
   333 			{
   342             {
   334 			if ((aUseExtendedChars && (TUint) c > KExtendedCharEnd) || 
   343             if ((aUseExtendedChars && (TUint) c > KExtendedCharEnd) || 
   335 					(!aUseExtendedChars && (TUint) c > KExtendedCharStart))
   344                     (!aUseExtendedChars && (TUint) c > KExtendedCharStart))
   336 				{
   345                 {
   337 				return EFalse;
   346                 return EFalse;
   338 				}
   347                 }
   339 			}
   348             }
   340 
   349 
   341 		if (c!=KMatchAny)
   350         if (c!=KMatchAny)
   342 			if (++valid>KMaxFatFileNameExt)
   351             if (++valid>KMaxFatFileNameExt)
   343 				return EFalse;
   352                 return EFalse;
   344 		}
   353         }
   345 	
   354     
   346 	// Unicode file name checking for file opening.
   355     // Unicode file name checking for file opening.
   347 	if (!aIsForFileCreation && GetFatUtilityFunctions())
   356     if (!aIsForFileCreation && GetFatUtilityFunctions())
   348 		{
   357         {
   349 		TBuf8<KMaxFileName*2> convertedName8;
   358         TBuf8<KMaxFileName*2> convertedName8;
   350 		TRAPD(err, LocaleUtils::ConvertFromUnicodeL(convertedName8, aName, TFatUtilityFunctions::EOverflowActionLeave));
   359         TRAPD(err, LocaleUtils::ConvertFromUnicodeL(convertedName8, aName, TFatUtilityFunctions::EOverflowActionLeave));
   351 		if (err != KErrNone)
   360         if (err != KErrNone)
   352 			return EFalse;
   361             return EFalse;
   353 		
   362         
   354 		const TInt len8 = convertedName8.Length();
   363         const TInt len8 = convertedName8.Length();
   355 		TInt j = 0; 
   364         TInt j = 0; 
   356 		TInt nonWildChar = 0;
   365         TInt nonWildChar = 0;
   357 		while (j < len8)
   366         while (j < len8)
   358 			{
   367             {
   359 			const TUint8 c8 = convertedName8[j++];
   368             const TUint8 c8 = convertedName8[j++];
   360 			if (c8 == KExtDelimiter)
   369             if (c8 == KExtDelimiter)
   361 				break;
   370                 break;
   362 			if (c8 == '*' && !anAllowWildCards)
   371             if (c8 == '*' && !anAllowWildCards)
   363 				return EFalse;
   372                 return EFalse;
   364 			if (c8 == '*' && anAllowWildCards)
   373             if (c8 == '*' && anAllowWildCards)
   365 				continue;
   374                 continue;
   366 			
   375             
   367 			if (++nonWildChar > KMaxFatFileNameWithoutExt)
   376             if (++nonWildChar > KMaxFatFileNameWithoutExt)
   368 				return EFalse;
   377                 return EFalse;
   369 			}
   378             }
   370 		
   379         
   371 		// check extension part
   380         // check extension part
   372 		nonWildChar = 0;
   381         nonWildChar = 0;
   373 		while (j < len8)
   382         while (j < len8)
   374 			{
   383             {
   375 			const TUint8 c8 = convertedName8[j++];
   384             const TUint8 c8 = convertedName8[j++];
   376 			if (c8 == KExtDelimiter)
   385             if (c8 == KExtDelimiter)
   377 				return EFalse;
   386                 return EFalse;
   378 			if (c8 == '*' && !anAllowWildCards)
   387             if (c8 == '*' && !anAllowWildCards)
   379 				return EFalse;
   388                 return EFalse;
   380 			if (c8 == '*' && anAllowWildCards)
   389             if (c8 == '*' && anAllowWildCards)
   381 				continue;
   390                 continue;
   382 			
   391             
   383 			if (++nonWildChar > KMaxFatFileNameExt)
   392             if (++nonWildChar > KMaxFatFileNameExt)
   384 				return EFalse;
   393                 return EFalse;
   385 			}
   394             }
   386 		}
   395         }
   387 
   396 
   388 	return ETrue;
   397     return ETrue;
   389 	}
   398     }
   390 
   399 
   391 /**
   400 /**
   392     Check whether a Dos name is legal or not. Unicode version
   401     Check whether a Dos name is legal or not. Unicode version
   393     parameters and return value absolutely the same as in DoCheckLegalDosName()
   402     parameters and return value absolutely the same as in DoCheckLegalDosName()
   394 */
   403 */
   395 TBool IsLegalDosName(const TDesC16& aName, TBool anAllowWildCards, TBool aUseExtendedChars, TBool aInScanDrive, TBool aAllowLowerCase, TBool aIsForFileCreation)
   404 TBool IsLegalDosName(const TDesC16& aName, TBool anAllowWildCards, TBool aUseExtendedChars, TBool aInScanDrive, TBool aAllowLowerCase, TBool aIsForFileCreation)
   396 	{
   405     {
   397 
   406 
   398 	__PRINT(_L("IsLegalDosName 16"));
   407     __PRINT(_L("IsLegalDosName 16"));
   399 
   408 
   400     return DoCheckLegalDosName(aName, anAllowWildCards, aUseExtendedChars, aInScanDrive, aAllowLowerCase, aIsForFileCreation);	
   409     return DoCheckLegalDosName(aName, anAllowWildCards, aUseExtendedChars, aInScanDrive, aAllowLowerCase, aIsForFileCreation);  
   401 	}
   410     }
   402 
   411 
   403 TBool CFatMountCB::FindShortNameL(const TShortName& aName,TEntryPos& anEntryPos)
   412 TBool CFatMountCB::FindShortNameL(const TShortName& aName,TEntryPos& anEntryPos)
   404 //
   413 //
   405 // Returns ETrue and the entryPos of aName if found or EFalse
   414 // Returns ETrue and the entryPos of aName if found or EFalse
   406 //
   415 //
   407 	{
   416     {
   408 	
   417     
   409 	__PRINT(_L("VFAT::CFatMountCB::FindShortNameL"));	
   418     __PRINT(_L("VFAT::CFatMountCB::FindShortNameL"));   
   410 	TFatDirEntry fatEntry;
   419     TFatDirEntry fatEntry;
   411 	TInt count=0;
   420     TInt count=0;
   412 	FOREVER
   421     FOREVER
   413 		{
   422         {
   414 		count++;
   423         count++;
   415 		ReadDirEntryL(anEntryPos,fatEntry);
   424         ReadDirEntryL(anEntryPos,fatEntry);
   416 		MoveToDosEntryL(anEntryPos,fatEntry);
   425         MoveToDosEntryL(anEntryPos,fatEntry);
   417 		if (fatEntry.IsEndOfDirectory())
   426         if (fatEntry.IsEndOfDirectory())
   418 			break;
   427             break;
   419 		if (IsRootDir(anEntryPos)&&(anEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))	
   428         if (IsRootDir(anEntryPos)&&(anEntryPos.iPos+StartOfRootDirInBytes()==(RootDirEnd()-KSizeOfFatDirEntry)))    
   420 			if (fatEntry.IsErased())
   429             if (fatEntry.IsErased())
   421 				break;//Allows maximum number of entries in root directory
   430                 break;//Allows maximum number of entries in root directory
   422 		if (fatEntry.Name()==aName)
   431         if (fatEntry.Name()==aName)
   423 			return ETrue;
   432             return ETrue;
   424 		MoveToNextEntryL(anEntryPos);
   433         MoveToNextEntryL(anEntryPos);
   425 		if (IsRootDir(anEntryPos)&&(StartOfRootDirInBytes()+anEntryPos.iPos==RootDirEnd()))
   434         if (IsRootDir(anEntryPos)&&(StartOfRootDirInBytes()+anEntryPos.iPos==RootDirEnd()))
   426 			break;//Allows maximum number of entries in root directory
   435             break;//Allows maximum number of entries in root directory
   427 		}
   436         }
   428 	return EFalse;
   437     return EFalse;
   429 	}
   438     }
   430 	
   439     
   431 TBool CFatMountCB::IsUniqueNameL(const TShortName& aName,TInt aDirCluster)
   440 TBool CFatMountCB::IsUniqueNameL(const TShortName& aName,TInt aDirCluster)
   432 //
   441 //
   433 // Returns ETrue if aName is unique, EFalse if a matching name is found.
   442 // Returns ETrue if aName is unique, EFalse if a matching name is found.
   434 //
   443 //
   435 	{
   444     {
   436 
   445 
   437 	__PRINT(_L("VFAT::CFatMountCB::IsUniqueNameL"));	
   446     __PRINT(_L("VFAT::CFatMountCB::IsUniqueNameL"));    
   438 	TEntryPos entryPos(aDirCluster,0);
   447     TEntryPos entryPos(aDirCluster,0);
   439 	if (FindShortNameL(aName,entryPos))
   448     if (FindShortNameL(aName,entryPos))
   440 		return(EFalse);
   449         return(EFalse);
   441 	return(ETrue);
   450     return(ETrue);
   442 	}
   451     }
   443 
   452 
   444 void CFatMountCB::ReplaceClashingNameL(const TShortName& aNewName,const TEntryPos& anEntryPos)
   453 void CFatMountCB::ReplaceClashingNameL(const TShortName& aNewName,const TEntryPos& anEntryPos)
   445 //
   454 //
   446 // A legal dos name has been typed that clashes with a computer generated shortname
   455 // A legal dos name has been typed that clashes with a computer generated shortname
   447 // Change the shortname to something else.
   456 // Change the shortname to something else.
   448 //
   457 //
   449 	{
   458     {
   450 
   459 
   451 	__PRINT(_L("VFAT::CFatMountCB::ReplaceClashingNameL"));	
   460     __PRINT(_L("VFAT::CFatMountCB::ReplaceClashingNameL")); 
   452 	TFatDirEntry entry;
   461     TFatDirEntry entry;
   453 	ReadDirEntryL(anEntryPos,entry);
   462     ReadDirEntryL(anEntryPos,entry);
   454 	__ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
   463     __ASSERT_ALWAYS(entry.IsEndOfDirectory()==EFalse,User::Leave(KErrCorrupt));
   455 	entry.SetName(aNewName);
   464     entry.SetName(aNewName);
   456 	WriteDirEntryL(anEntryPos,entry);
   465     WriteDirEntryL(anEntryPos,entry);
   457 //	We now need to fix up VFAT entries with a new checksum reflecting new shortname
   466 //  We now need to fix up VFAT entries with a new checksum reflecting new shortname
   458 //	Calculate new checksum
   467 //  Calculate new checksum
   459 	TUint8 checksum=CalculateShortNameCheckSum(aNewName);
   468     TUint8 checksum=CalculateShortNameCheckSum(aNewName);
   460 //	Now go back and adjust all VFAT entries corresponding to this shortname
   469 //  Now go back and adjust all VFAT entries corresponding to this shortname
   461 	TEntryPos entryPos=anEntryPos;
   470     TEntryPos entryPos=anEntryPos;
   462 	FOREVER
   471     FOREVER
   463 		{
   472         {
   464 		entryPos.iPos-=KSizeOfFatDirEntry;	
   473         entryPos.iPos-=KSizeOfFatDirEntry;  
   465 		ReadDirEntryL(entryPos,entry);
   474         ReadDirEntryL(entryPos,entry);
   466 		entry.iData[0x0D]=checksum;
   475         entry.iData[0x0D]=checksum;
   467 		if (entry.iData[0]&0x40)
   476         if (entry.iData[0]&0x40)
   468 			break;
   477             break;
   469 		}
   478         }
   470 	}
   479     }
   471 
   480 
   472 TBool CFatMountCB::GenerateShortNameL(TInt aDirCluster,const TDesC& aName,TShortName& aGeneratedName, TBool aForceRandomize)
   481 TBool CFatMountCB::GenerateShortNameL(TInt aDirCluster,const TDesC& aName,TShortName& aGeneratedName, TBool aForceRandomize)
   473 //
   482 //
   474 // Generate a legal dos filename as an alias for aName.
   483 // Generate a legal dos filename as an alias for aName.
   475 // Returns ETrue if aName is a legal dos name.
   484 // Returns ETrue if aName is a legal dos name.
   476 //
   485 //
   477 	{
   486     {
   478 
   487 
   479 	__PRINT(_L("VFAT::CFatMountCB::GenerateShortNameL"));
   488     __PRINT(_L("VFAT::CFatMountCB::GenerateShortNameL"));
   480 	// Given the long file-name "ABCDEFGHI.TXT", EPOC used to generate short 
   489     // Given the long file-name "ABCDEFGHI.TXT", EPOC used to generate short 
   481 	// file-names in the following pecking order:
   490     // file-names in the following pecking order:
   482 	//     "ABCDEFGH.TXT",
   491     //     "ABCDEFGH.TXT",
   483 	//     "ABCDEF~0.TXT",
   492     //     "ABCDEF~0.TXT",
   484 	//     "ABCDEF~1.TXT",
   493     //     "ABCDEF~1.TXT",
   485 	//     "ABCDEF~2.TXT",
   494     //     "ABCDEF~2.TXT",
   486 	//     etc.
   495     //     etc.
   487 	// Now, however, EPOC behaves in a more Windows-like manner and 
   496     // Now, however, EPOC behaves in a more Windows-like manner and 
   488 	// generates short file-names in this pecking order:
   497     // generates short file-names in this pecking order:
   489 	//     "ABCDEF~1.TXT",
   498     //     "ABCDEF~1.TXT",
   490 	//     "ABCDEF~2.TXT",
   499     //     "ABCDEF~2.TXT",
   491 	//     "ABCDEF~3.TXT",
   500     //     "ABCDEF~3.TXT",
   492 	//     "ABCDEF~4.TXT",
   501     //     "ABCDEF~4.TXT",
   493 	// After failing to find an unused short name 4 times in a row, 
   502     // After failing to find an unused short name 4 times in a row, 
   494 	// a random number is used to speed up the process. So subsequent
   503     // a random number is used to speed up the process. So subsequent
   495 	// short-file names become
   504     // short-file names become
   496 	//     "ABC~nnnn.TXT"	where nnnn is a random number
   505     //     "ABC~nnnn.TXT"   where nnnn is a random number
   497 	//    
   506     //    
   498 	TBool useTildeSelectively = ETrue;
   507     TBool useTildeSelectively = ETrue;
   499 	TInt endNum = KMaxDuplicateShortName;	//	0xFFFF
   508     TInt endNum = KMaxDuplicateShortName;   //  0xFFFF
   500 	const TInt KMaxNonRandomShortFileNames = 4;
   509     const TInt KMaxNonRandomShortFileNames = 4;
   501 
   510 
   502 	TInt i = 1;
   511     TInt i = 1;
   503 
   512 
   504 	TBool randomize = aForceRandomize;
   513     TBool randomize = aForceRandomize;
   505 	if (randomize)
   514     if (randomize)
   506 		{
   515         {
   507 		i = (TInt) (Math::Random() & KMaxDuplicateShortName);
   516         i = (TInt) (Math::Random() & KMaxDuplicateShortName);
   508 		endNum = (i - 1) & KMaxDuplicateShortName;
   517         endNum = (i - 1) & KMaxDuplicateShortName;
   509 		}
   518         }
   510 
   519 
   511 	while(i != endNum)
   520     while(i != endNum)
   512 		{
   521         {
   513 		aGeneratedName=DoGenerateShortNameL(aName,i,useTildeSelectively);
   522         aGeneratedName=DoGenerateShortNameL(aName,i,useTildeSelectively);
   514 
   523 
   515 		if (IsUniqueNameL(aGeneratedName,aDirCluster))
   524         if (IsUniqueNameL(aGeneratedName,aDirCluster))
   516 			break;
   525             break;
   517 
   526 
   518 		if (i == KMaxNonRandomShortFileNames && !randomize)
   527         if (i == KMaxNonRandomShortFileNames && !randomize)
   519 			{
   528             {
   520 			randomize = ETrue;
   529             randomize = ETrue;
   521 			i = (TInt) (Math::Random() & KMaxDuplicateShortName);
   530             i = (TInt) (Math::Random() & KMaxDuplicateShortName);
   522 			endNum = (i - 1) & KMaxDuplicateShortName;
   531             endNum = (i - 1) & KMaxDuplicateShortName;
   523 			}
   532             }
   524 		else if (i == -1)
   533         else if (i == -1)
   525 			{
   534             {
   526 			useTildeSelectively=EFalse;
   535             useTildeSelectively=EFalse;
   527 			i = 1;
   536             i = 1;
   528 			}
   537             }
   529 		else
   538         else
   530 			i = (i + 1) & KMaxDuplicateShortName;
   539             i = (i + 1) & KMaxDuplicateShortName;
   531 		}
   540         }
   532 
   541 
   533 	if (i == endNum)
   542     if (i == endNum)
   534 		User::Leave(KErrAlreadyExists);
   543         User::Leave(KErrAlreadyExists);
   535 
   544 
   536 	if((i == -1) && IsLegalDosName(aName,EFalse,EFalse,EFalse,EFalse,ETrue))
   545     if((i == -1) && IsLegalDosName(aName,EFalse,EFalse,EFalse,EFalse,ETrue))
   537 		{
   546         {
   538 		// Original file name is a legal 8.3 name
   547         // Original file name is a legal 8.3 name
   539 		return(ETrue);
   548         return(ETrue);
   540 		}
   549         }
   541 	else
   550     else
   542 		{
   551         {
   543 	    return(EFalse);
   552         return(EFalse);
   544 		}
   553         }
   545 
   554 
   546 
   555 
   547 	}
   556     }
   548 
   557 
   549 void TFatDirEntry::InitializeAsVFat(TUint8 aCheckSum)
   558 void TFatDirEntry::InitializeAsVFat(TUint8 aCheckSum)
   550 //
   559 //
   551 // Initialize a FAT entry as a VFAT filename
   560 // Initialize a FAT entry as a VFAT filename
   552 //
   561 //
   553 	{
   562     {
   554 
   563 
   555 	Mem::Fill(this,sizeof(SFatDirEntry),0xFF);
   564     Mem::Fill(this,sizeof(SFatDirEntry),0xFF);
   556 	iData[0x0B]=0x0F;
   565     iData[0x0B]=0x0F;
   557 	iData[0x0C]=0x00; iData[0x0D]=aCheckSum;
   566     iData[0x0C]=0x00; iData[0x0D]=aCheckSum;
   558 	iData[0x1A]=0x00; iData[0x1B]=0x00;
   567     iData[0x1A]=0x00; iData[0x1B]=0x00;
   559 	}
   568     }
   560 
   569 
   561 void TFatDirEntry::SetVFatEntry(const TDesC& aName,TInt aLen)
   570 void TFatDirEntry::SetVFatEntry(const TDesC& aName,TInt aLen)
   562 //
   571 //
   563 // Write up to KMaxVFatEntryName unicode chars from aName to the entry
   572 // Write up to KMaxVFatEntryName unicode chars from aName to the entry
   564 //
   573 //
   565 	{
   574     {
   566 
   575 
   567 	TInt rem=aName.Length()-aLen;
   576     TInt rem=aName.Length()-aLen;
   568 	TPtrC section(aName.Ptr()+aLen,Min(rem,KMaxVFatEntryName));
   577     TPtrC section(aName.Ptr()+aLen,Min(rem,KMaxVFatEntryName));
   569 	TBuf16<KMaxVFatEntryName> buf16;
   578     TBuf16<KMaxVFatEntryName> buf16;
   570 	buf16.Copy(section);
   579     buf16.Copy(section);
   571 	if (rem<KMaxVFatEntryName)
   580     if (rem<KMaxVFatEntryName)
   572 		{
   581         {
   573 		rem++;
   582         rem++;
   574 		buf16.ZeroTerminate();
   583         buf16.ZeroTerminate();
   575 		buf16.SetLength(rem); // Zero termination doesn't increase the buf length
   584         buf16.SetLength(rem); // Zero termination doesn't increase the buf length
   576 		}
   585         }
   577 	TUint8 orderNo=(TUint8)(aLen/KMaxVFatEntryName+1);
   586     TUint8 orderNo=(TUint8)(aLen/KMaxVFatEntryName+1);
   578 	TInt s=Min(rem,5);
   587     TInt s=Min(rem,5);
   579 	Mem::Copy(&iData[0x01],buf16.Ptr(),s*2);//Copy up to 10 bytes of buf16 into iData
   588     Mem::Copy(&iData[0x01],buf16.Ptr(),s*2);//Copy up to 10 bytes of buf16 into iData
   580 	TInt offset=s;
   589     TInt offset=s;
   581 	rem-=s;
   590     rem-=s;
   582 	s=Min(rem,6);
   591     s=Min(rem,6);
   583 	Mem::Copy(&iData[0x0E],buf16.Ptr()+offset,s*2);
   592     Mem::Copy(&iData[0x0E],buf16.Ptr()+offset,s*2);
   584 	offset+=s;
   593     offset+=s;
   585 	rem-=s;
   594     rem-=s;
   586 	s=Min(rem,2);
   595     s=Min(rem,2);
   587 	Mem::Copy(&iData[0x1C],buf16.Ptr()+offset,s*2);
   596     Mem::Copy(&iData[0x1C],buf16.Ptr()+offset,s*2);
   588 	rem-=s;
   597     rem-=s;
   589 	if (rem==0)
   598     if (rem==0)
   590 		orderNo|=0x40;
   599         orderNo|=0x40;
   591 	iData[0]=orderNo;
   600     iData[0]=orderNo;
   592 	}
   601     }
   593 
   602 
   594 void TFatDirEntry::ReadVFatEntry(TDes16& aBuf) const
   603 void TFatDirEntry::ReadVFatEntry(TDes16& aBuf) const
   595 //
   604 //
   596 // Read KMaxVFatEntryName unicode chars from the entry
   605 // Read KMaxVFatEntryName unicode chars from the entry
   597 //
   606 //
   598 	{
   607     {
   599 
   608 
   600 	aBuf.SetLength(KMaxVFatEntryName);
   609     aBuf.SetLength(KMaxVFatEntryName);
   601 	Mem::Copy(&aBuf[0],&iData[0x01],5*2);
   610     Mem::Copy(&aBuf[0],&iData[0x01],5*2);
   602 	Mem::Copy(&aBuf[5],&iData[0x0E],6*2);
   611     Mem::Copy(&aBuf[5],&iData[0x0E],6*2);
   603 	Mem::Copy(&aBuf[11],&iData[0x1C],2*2);
   612     Mem::Copy(&aBuf[11],&iData[0x1C],2*2);
   604 	}
   613     }
   605 
   614 
   606 void CFatMountCB::WriteDirEntryL(TEntryPos& aPos,const TFatDirEntry& aFatDirEntry,const TDesC& aLongName)
   615 void CFatMountCB::WriteDirEntryL(TEntryPos& aPos,const TFatDirEntry& aFatDirEntry,const TDesC& aLongName)
   607 //
   616 //
   608 // Write a VFAT directory entry to disk at position aPos - leave aPos refering to the dos entry
   617 // Write a VFAT directory entry to disk at position aPos - leave aPos refering to the dos entry
   609 // Assumes sufficient space has been created for it by AddDirEntry.
   618 // Assumes sufficient space has been created for it by AddDirEntry.
   610 //
   619 //
   611 	{
   620     {
   612 
   621 
   613 	__PRINT(_L("VFAT::CFatMountCB::WriteDirEntryL"));	
   622     __PRINT(_L("VFAT::CFatMountCB::WriteDirEntryL"));   
   614 	__ASSERT_DEBUG(aLongName.Length(),Fault(EVFatNoLongName));
   623     __ASSERT_DEBUG(aLongName.Length(),Fault(EVFatNoLongName));
   615 	TEntryPos startPos(aPos.iCluster,aPos.iPos);
   624     TEntryPos startPos(aPos.iCluster,aPos.iPos);
   616 	TUint8  localBuf[KDefaultSectorSize];
   625     TUint8  localBuf[KDefaultSectorSize];
   617 	TUint8 cksum=CalculateShortNameCheckSum(aFatDirEntry.Name());
   626     TUint8 cksum=CalculateShortNameCheckSum(aFatDirEntry.Name());
   618 	TInt numEntries=NumberOfVFatEntries(aLongName.Length())-1; // Excluding dos entry
   627     TInt numEntries=NumberOfVFatEntries(aLongName.Length())-1; // Excluding dos entry
   619 	// see if all entries written to one sector
   628     // see if all entries written to one sector
   620 	// single sector writes not supported if sector size>default size 
   629     // single sector writes not supported if sector size>default size 
   621 	TInt dosOffset=numEntries<<KSizeOfFatDirEntryLog2;
   630     TInt dosOffset=numEntries<<KSizeOfFatDirEntryLog2;
   622 	TInt absolutePos=(aPos.iCluster<<ClusterSizeLog2())+ClusterRelativePos(aPos.iPos);
   631     TInt absolutePos=(aPos.iCluster<<ClusterSizeLog2())+ClusterRelativePos(aPos.iPos);
   623 	TBool isSameSector=(((absolutePos^(absolutePos+dosOffset))>>SectorSizeLog2())==0 && ((TUint)(1<<SectorSizeLog2())<=KDefaultSectorSize));
   632     TBool isSameSector=(((absolutePos^(absolutePos+dosOffset))>>SectorSizeLog2())==0 && ((TUint)(1<<SectorSizeLog2())<=KDefaultSectorSize));
   624 	TFatDirEntry vFatEntry;
   633     TFatDirEntry vFatEntry;
   625 	vFatEntry.InitializeAsVFat(cksum);
   634     vFatEntry.InitializeAsVFat(cksum);
   626 	TInt offset=0;
   635     TInt offset=0;
   627 	while (numEntries--)
   636     while (numEntries--)
   628 		{
   637         {
   629 		vFatEntry.SetVFatEntry(aLongName,KMaxVFatEntryName*numEntries);//	KMaxVFatEntryName=13
   638         vFatEntry.SetVFatEntry(aLongName,KMaxVFatEntryName*numEntries);//   KMaxVFatEntryName=13
   630 		if(isSameSector)
   639         if(isSameSector)
   631 			{
   640             {
   632 			Mem::Copy(&localBuf[offset],&vFatEntry,KSizeOfFatDirEntry);
   641             Mem::Copy(&localBuf[offset],&vFatEntry,KSizeOfFatDirEntry);
   633 			offset+=KSizeOfFatDirEntry;
   642             offset+=KSizeOfFatDirEntry;
   634 			MoveToNextEntryL(aPos);
   643             MoveToNextEntryL(aPos);
   635 			}
   644             }
   636 		else
   645         else
   637 			{
   646             {
   638 			WriteDirEntryL(aPos,vFatEntry);
   647             WriteDirEntryL(aPos,vFatEntry);
   639 			MoveToNextEntryL(aPos);
   648             MoveToNextEntryL(aPos);
   640 			}
   649             }
   641 		}
   650         }
   642 	if(isSameSector)
   651     if(isSameSector)
   643 		{
   652         {
   644 		Mem::Copy(&localBuf[offset],&aFatDirEntry,KSizeOfFatDirEntry);
   653         Mem::Copy(&localBuf[offset],&aFatDirEntry,KSizeOfFatDirEntry);
   645 		
   654         
   646         //-- use special interface to access FAT directory file
   655         //-- use special interface to access FAT directory file
   647         DirWriteL(startPos,TPtrC8(&localBuf[0],dosOffset+KSizeOfFatDirEntry));
   656         DirWriteL(startPos,TPtrC8(&localBuf[0],dosOffset+KSizeOfFatDirEntry));
   648         }
   657         }
   649 	else
   658     else
   650 		WriteDirEntryL(aPos,aFatDirEntry);
   659         WriteDirEntryL(aPos,aFatDirEntry);
   651 	}
   660     }
   652 
   661 
   653 void CFatMountCB::EraseDirEntryL(TEntryPos aPos,const TFatDirEntry& aFirstEntry)
   662 void CFatMountCB::EraseDirEntryL(TEntryPos aPos,const TFatDirEntry& aFirstEntry)
   654 //
   663 //
   655 // Mark all entries in a VFat directory entry as erased
   664 // Mark all entries in a VFat directory entry as erased
   656 //
   665 //
   657 	{
   666     {
   658 	__PRINT(_L("VFAT::CFatMountCB::EraseDirEntryL"));
   667     __PRINT(_L("VFAT::CFatMountCB::EraseDirEntryL"));
   659 	TInt numEntries=0;
   668     TInt numEntries=0;
   660 	if (aFirstEntry.IsVFatEntry())
   669     if (aFirstEntry.IsVFatEntry())
   661 		numEntries=aFirstEntry.NumFollowing();
   670         numEntries=aFirstEntry.NumFollowing();
   662 	if(IsRuggedFSys()&&numEntries)
   671     if(IsRuggedFSys()&&numEntries)
   663 		{
   672         {
   664 		TInt count=numEntries;
   673         TInt count=numEntries;
   665 		TEntryPos pos=aPos;
   674         TEntryPos pos=aPos;
   666 		while(count--)
   675         while(count--)
   667 			MoveToNextEntryL(pos);
   676             MoveToNextEntryL(pos);
   668 		EraseDirEntryL(pos);
   677         EraseDirEntryL(pos);
   669 		numEntries--;
   678         numEntries--;
   670 		}
   679         }
   671 	FOREVER
   680     FOREVER
   672 		{
   681         {
   673 		EraseDirEntryL(aPos);
   682         EraseDirEntryL(aPos);
   674 		if (!numEntries--)
   683         if (!numEntries--)
   675 			break;
   684             break;
   676 		MoveToNextEntryL(aPos);
   685         MoveToNextEntryL(aPos);
   677 		}
   686         }
   678 	}
   687     }
   679 
   688 
   680 
   689 
   681 void  LocaleUtils::ConvertFromUnicodeL(TDes8& aForeign, const TDesC16& aUnicode, TFatUtilityFunctions::TOverflowAction aOverflowAction)
   690 void  LocaleUtils::ConvertFromUnicodeL(TDes8& aForeign, const TDesC16& aUnicode, TFatUtilityFunctions::TOverflowAction aOverflowAction)
   682 //
   691 //
   683 // Convert the volume label using the algorithm specified in the current locale-DLL.
   692 // Convert the volume label using the algorithm specified in the current locale-DLL.
   684 //
   693 //
   685 	{
   694     {
   686 	if(aOverflowAction == TFatUtilityFunctions::EOverflowActionLeave)
   695     if(aOverflowAction == TFatUtilityFunctions::EOverflowActionLeave)
   687 		{
   696         {
   688 		GetCodePage().ConvertFromUnicodeL(aForeign, aUnicode, TCodePageUtils::EOverflowActionLeave);
   697         GetCodePage().ConvertFromUnicodeL(aForeign, aUnicode, TCodePageUtils::EOverflowActionLeave);
   689 		}
   698         }
   690 	else
   699     else
   691 		{
   700         {
   692 		GetCodePage().ConvertFromUnicodeL(aForeign, aUnicode, TCodePageUtils::EOverflowActionTruncate);
   701         GetCodePage().ConvertFromUnicodeL(aForeign, aUnicode, TCodePageUtils::EOverflowActionTruncate);
   693 		}
   702         }
   694 	}
   703     }
   695 
   704 
   696 void  LocaleUtils::ConvertToUnicodeL(TDes16& aUnicode, const TDesC8& aForeign, TFatUtilityFunctions::TOverflowAction aOverflowAction)
   705 void  LocaleUtils::ConvertToUnicodeL(TDes16& aUnicode, const TDesC8& aForeign, TFatUtilityFunctions::TOverflowAction aOverflowAction)
   697 //
   706 //
   698 // Convert the volume label using the algorithm specified in the current locale-DLL.
   707 // Convert the volume label using the algorithm specified in the current locale-DLL.
   699 //
   708 //
   700 	{
   709     {
   701 	if(aOverflowAction == TFatUtilityFunctions::EOverflowActionLeave)
   710     if(aOverflowAction == TFatUtilityFunctions::EOverflowActionLeave)
   702 		{
   711         {
   703 		GetCodePage().ConvertToUnicodeL(aUnicode, aForeign, TCodePageUtils::EOverflowActionLeave);
   712         GetCodePage().ConvertToUnicodeL(aUnicode, aForeign, TCodePageUtils::EOverflowActionLeave);
   704 		}
   713         }
   705 	else
   714     else
   706 		{
   715         {
   707 		GetCodePage().ConvertToUnicodeL(aUnicode, aForeign, TCodePageUtils::EOverflowActionTruncate);
   716         GetCodePage().ConvertToUnicodeL(aUnicode, aForeign, TCodePageUtils::EOverflowActionTruncate);
   708 		}
   717         }
   709 	}
   718     }
   710 
   719 
   711 TBool LocaleUtils::IsLegalShortNameCharacter(TUint aCharacter,TBool aUseExtendedChars)
   720 TBool LocaleUtils::IsLegalShortNameCharacter(TUint aCharacter,TBool aUseExtendedChars)
   712 //
   721 //
   713 // Convert the volume label using the algorithm specified in the current locale-DLL.
   722 // Convert the volume label using the algorithm specified in the current locale-DLL.
   714 //
   723 //
   715 	{
   724     {
   716 	return GetCodePage().IsLegalShortNameCharacter(aCharacter, aUseExtendedChars);
   725     return GetCodePage().IsLegalShortNameCharacter(aCharacter, aUseExtendedChars);
   717 	}
   726     }