/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2002, 2004-2005 Apple Computer, Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
- * The contents of this file constitute Original Code as defined in and
- * are subject to the Apple Public Source License Version 1.1 (the
- * "License"). You may not use this file except in compliance with the
- * License. Please obtain a copy of the License at
- * http://www.apple.com/publicsource and read it before using this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
*
- * This Original Code and all software distributed under the License are
- * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ *
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
- * License for the specific language governing rights and limitations
- * under the License.
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
-/*
- File: CatalogUtilities.c
-
- Contains: Private Catalog Manager support routines.
-
- Version: HFS Plus 1.0
-
- Copyright: © 1997-2000 by Apple Computer, Inc., all rights reserved.
-
- File Ownership:
-
- DRI: Don Brady
-
- Other Contact: Mark Day
-
- Technology: xxx put technology here xxx
-
- Writers:
-
- (DSH) Deric Horn
- (msd) Mark Day
- (djb) Don Brady
-
- Change History (most recent first):
- <MacOSX> 1/8/99 djb Fixing LocateCatalogNodeByMangledName...
- <MacOSX> 1/7/99 djb In BuildCatalogKeyUTF8 check name length against NAME_MAX.
- <MacOSX> 12/7/98 djb Add ExtractTextEncoding routine to get text encodings.
- <MacOSX> 11/20/98 djb Add support for UTF-8 names.
- <MacOSX> 8/31/98 djb GetTimeLocal now takes an input.
- <MacOSX> 4/17/98 djb Add VCB locking.
- <MacOSX> 4/3/98 djb Removed last name conversion cache from LocateCatalogNodeWithRetry.
- <MacOSX> 4/2/98 djb InvalidateCatalogNodeCache and TrashCatalogNodeCache are not used in MacOS X.
- <MacOSX> 03/31/98 djb Sync up with final HFSVolumes.h header file.
-
- <CS24> 1/29/98 DSH Add TrashCatalogNodeCache for TrashAllFSCaches API support.
- <CS23> 12/15/97 djb Radar #2202860, In LocateCatalogNodeByMangledName remap
- cmParentNotFound error code to cmNotFound.
- <CS22> 12/10/97 DSH 2201501, Pin the leof and peof to multiple of allocation blocks
- under 2 Gig.
- <CS21> 12/9/97 DSH 2201501, Pin returned leof values to 2^31-1 (SInt32), instead of
- 2^32-1
- <CS20> 11/26/97 djb Radar #2005688, 2005461 - need to handle kTextMalformedInputErr.
- <CS19> 11/25/97 djb Radar #2002357 (again) fix new bug introduced in <CS18>.
- <CS18> 11/17/97 djb PrepareInputName routine now returns an error.
- <CS17> 10/19/97 msd Bug 1684586. GetCatInfo and SetCatInfo use only contentModDate.
- <CS16> 10/17/97 djb Add ConvertInputNameToUnicode for Catalog Create/Rename.
- <CS15> 10/14/97 djb Fix LocateCatalogNode's MakeFSSpec optimization (radar #1683166)
- <CS14> 10/13/97 djb Copy text encoding in CopyCatalogNodeData. Fix cut/paste error
- in VolumeHasEncodings macro. When accessing encoding bitmap use
- the MapEncodingToIndex and MapIndexToEncoding macros.
- <CS13> 10/1/97 djb Remove old Catalog Iterator code...
- <CS12> 9/8/97 msd Make sure a folder's modifyDate is set whenever its
- contentModDate is set.
- <CS11> 9/4/97 djb Add MakeFSSpec optimization.
- <CS10> 9/4/97 msd In CatalogNodeData, change attributeModDate to modifyDate.
- <CS9> 8/26/97 djb Back out <CS4> (UpdateFolderCount must maintain vcbNmFls for HFS
- Plus volumes too).
- <CS8> 8/14/97 djb Remove hard link support.
- <CS7> 7/18/97 msd Include LowMemPriv.h.
- <CS6> 7/16/97 DSH FilesInternal.i renamed FileMgrInternal.i to avoid name
- collision
- <CS5> 7/8/97 DSH Loading PrecompiledHeaders from define passed in on C line
- <CS4> 6/27/97 msd UpdateFolderCount should update number of root files/folders for
- HFS volumes, not HFS Plus.
- <CS3> 6/24/97 djb LocateCatalogNodeWithRetry did not always set result code.
- <CS2> 6/24/97 djb Add LocateCatalogNodeByMangledName routine
- <CS1> 6/24/97 djb first checked in
-*/
#include <sys/param.h>
#include <sys/utfconv.h>
+#include <sys/stat.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <libkern/libkern.h>
#include "../headers/FileMgrInternal.h"
#include "../headers/BTreesInternal.h"
#include "../headers/CatalogPrivate.h"
#include "../headers/HFSUnicodeWrappers.h"
+#include "../headers/BTreesPrivate.h"
#include <string.h>
-static void ExtractTextEncoding (ItemCount length, ConstUniCharArrayPtr string, UInt32 * textEncoding);
-
-//*******************************************************************************
-// Routine: LocateCatalogNode
+//
+// Routine: LocateCatalogNodeByKey
//
// Function: Locates the catalog record for an existing folder or file
-// CNode and returns pointers to the key and data records.
+// CNode and returns the key and data records.
//
-//*******************************************************************************
OSErr
-LocateCatalogNode(const ExtendedVCB *volume, HFSCatalogNodeID folderID, const CatalogName *name,
- UInt32 hint, CatalogKey *keyPtr, CatalogRecord *dataPtr, UInt32 *newHint)
+LocateCatalogNodeByKey(const ExtendedVCB *volume, u_int32_t hint, CatalogKey *keyPtr,
+ CatalogRecord *dataPtr, u_int32_t *newHint)
{
OSErr result;
- CatalogName *nodeName = NULL; /* To ward off uninitialized use warnings from compiler */
+ CatalogName *nodeName = NULL;
HFSCatalogNodeID threadParentID;
+ u_int16_t tempSize;
+ FSBufferDescriptor btRecord;
+ struct BTreeIterator *searchIterator;
+ FCB *fcb;
+
+ MALLOC (searchIterator, struct BTreeIterator*, sizeof(struct BTreeIterator), M_TEMP, M_WAITOK);
+ if (searchIterator == NULL) {
+ return memFullErr; // translates to ENOMEM
+ }
+ bzero(searchIterator, sizeof(*searchIterator));
- result = LocateCatalogRecord(volume, folderID, name, hint, keyPtr, dataPtr, newHint);
- ReturnIfError(result);
-
- // if we got a thread record, then go look up real record
- switch ( dataPtr->recordType )
- {
- case kHFSFileThreadRecord:
- case kHFSFolderThreadRecord:
- threadParentID = dataPtr->hfsThread.parentID;
- nodeName = (CatalogName *) &dataPtr->hfsThread.nodeName;
- break;
+ fcb = GetFileControlBlock(volume->catalogRefNum);
- case kHFSPlusFileThreadRecord:
- case kHFSPlusFolderThreadRecord:
- threadParentID = dataPtr->hfsPlusThread.parentID;
- nodeName = (CatalogName *) &dataPtr->hfsPlusThread.nodeName;
- break;
+ btRecord.bufferAddress = dataPtr;
+ btRecord.itemCount = 1;
+ btRecord.itemSize = sizeof(CatalogRecord);
- default:
- threadParentID = 0;
- break;
- }
-
- if ( threadParentID ) // found a thread
- result = LocateCatalogRecord(volume, threadParentID, nodeName, kNoHint, keyPtr, dataPtr, newHint);
+ searchIterator->hint.nodeNum = hint;
+
+ bcopy(keyPtr, &searchIterator->key, sizeof(CatalogKey));
- return result;
-}
+ result = BTSearchRecord( fcb, searchIterator, &btRecord, &tempSize, searchIterator );
-//
-// Routine: LocateCatalogNodeByKey
-//
-// Function: Locates the catalog record for an existing folder or file
-// CNode and returns the key and data records.
-//
+ if (result == noErr)
+ {
+ *newHint = searchIterator->hint.nodeNum;
-OSErr
-LocateCatalogNodeByKey(const ExtendedVCB *volume, UInt32 hint, CatalogKey *keyPtr,
- CatalogRecord *dataPtr, UInt32 *newHint)
-{
- OSErr result;
- CatalogName *nodeName = NULL; /* To ward off uninitialized use warnings from compiler */
- HFSCatalogNodeID threadParentID;
- UInt16 tempSize;
+ BlockMoveData(&searchIterator->key, keyPtr, sizeof(CatalogKey));
+ }
+ if (result == btNotFound) {
+ result = cmNotFound;
+ }
- result = SearchBTreeRecord(volume->catalogRefNum, keyPtr, hint, keyPtr,
- dataPtr, &tempSize, newHint);
- if (result == btNotFound)
- result = cmNotFound;
- ReturnIfError(result);
+ if (result) {
+ FREE(searchIterator, M_TEMP);
+ return result;
+ }
// if we got a thread record, then go look up real record
switch ( dataPtr->recordType )
{
+
+#if CONFIG_HFS_STD
case kHFSFileThreadRecord:
case kHFSFolderThreadRecord:
threadParentID = dataPtr->hfsThread.parentID;
nodeName = (CatalogName *) &dataPtr->hfsThread.nodeName;
break;
+#endif
case kHFSPlusFileThreadRecord:
case kHFSPlusFolderThreadRecord:
if ( threadParentID ) // found a thread
result = LocateCatalogRecord(volume, threadParentID, nodeName, kNoHint, keyPtr, dataPtr, newHint);
+ FREE (searchIterator, M_TEMP);
return result;
}
-#if 0
-//*******************************************************************************
-// Routine: LocateCatalogNodeWithRetry
-//
-// Function: Locates the catalog record for an existing folder or file node.
-// For HFS Plus volumes a retry is performed when a catalog node is
-// not found and the volume contains more than one text encoding.
-//
-//ÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑÑ
-
-#define VolumeHasEncodings(v) \
- ( ((v)->encodingsBitmap != 0 )
-
-#define EncodingInstalled(i) \
- ( (fsVars)->gConversionContext[(i)].toUnicode != 0 )
-
-#define EncodingUsedByVolume(v,i) \
- ( ((v)->encodingsBitmap & (1 << (i))) )
-
-
-OSErr
-LocateCatalogNodeWithRetry (const ExtendedVCB *volume, HFSCatalogNodeID folderID, ConstStr31Param pascalName, CatalogName *unicodeName,
- UInt32 hint, CatalogKey *keyPtr, CatalogRecord *dataPtr, UInt32 *newHint)
-{
- TextEncoding defaultEncoding;
- TextEncoding encoding;
- ItemCount encodingsToTry;
- FSVarsRec *fsVars;
- OSErr result = cmNotFound;
-
- fsVars = (FSVarsRec*) LMGetFSMVars(); // used by macros
-
- defaultEncoding = GetDefaultTextEncoding();
- encodingsToTry = CountInstalledEncodings();
-
- // 1. Try finding file using default encoding (typical case)
-
- {
- --encodingsToTry;
- result = PrepareInputName(pascalName, true, defaultEncoding, unicodeName);
- if (result == noErr)
- result = LocateCatalogNode(volume, folderID, unicodeName, hint, keyPtr, dataPtr, newHint);
- else
- result = cmNotFound;
-
- if ( result != cmNotFound || encodingsToTry == 0)
- return result;
- }
-
- //
- // XXX if the pascal string contains all 7-bit ascii then we don't need to do anymore retries
- //
-
- // 2. Try finding file using Mac Roman (if not already tried above)
-
- if ( defaultEncoding != kTextEncodingMacRoman )
- {
- --encodingsToTry;
- result = PrepareInputName(pascalName, true, kTextEncodingMacRoman, unicodeName);
- if (result == noErr)
- result = LocateCatalogNode(volume, folderID, unicodeName, hint, keyPtr, dataPtr, newHint);
- else
- result = cmNotFound;
-
- if ( result != cmNotFound || encodingsToTry == 0 )
- return result;
- }
-
- // 3. Try with encodings from disk (if any)
-
- if ( VolumeHasEncodings(volume) ) // any left to try?
- {
- UInt32 index;
-
- index = 0; // since we pre increment this will skip MacRoman (which was already tried above)
-
- while ( index < kMacBaseEncodingCount )
- {
- ++index;
-
- encoding = MapIndexToEncoding(index);
-
- if ( encoding == defaultEncoding )
- continue; // we did this one already
-
- if ( EncodingInstalled(index) && EncodingUsedByVolume(volume, index) )
- {
- --encodingsToTry;
- result = PrepareInputName(pascalName, true, encoding, unicodeName);
- if (result == noErr)
- result = LocateCatalogNode(volume, folderID, unicodeName, hint, keyPtr, dataPtr, newHint);
- else
- result = cmNotFound;
-
- if ( result != cmNotFound || encodingsToTry == 0 )
- return result;
- }
- }
- }
-
- // 4. Try any remaining encodings (if any)
-
- {
- UInt32 index;
-
- index = 0; // since we pre increment this will skip MacRoman (which was already tried above)
-
- while ( (encodingsToTry > 0) && (index < kMacBaseEncodingCount) )
- {
- ++index;
-
- encoding = MapIndexToEncoding(index);
-
- if ( encoding == defaultEncoding )
- continue; // we did this one already
-
- if ( EncodingInstalled(index) && EncodingUsedByVolume(volume, index) == false )
- {
- --encodingsToTry;
- result = PrepareInputName(pascalName, true, encoding, unicodeName);
- if (result == noErr)
- result = LocateCatalogNode(volume, folderID, unicodeName, hint, keyPtr, dataPtr, newHint);
- else
- result = cmNotFound;
-
- if ( result != cmNotFound || encodingsToTry == 0 )
- return result;
- }
- }
- }
-
- return cmNotFound;
-}
-#endif
-
-//*******************************************************************************
-// Routine: LocateCatalogNodeByMangledName
-//
-// Function: Locates the catalog record associated with a mangled name (if any)
-//
-//*******************************************************************************
-#define kMaxCompareLen 64 /* If it compares this far...lets believe it */
-
-OSErr
-LocateCatalogNodeByMangledName( const ExtendedVCB *volume, HFSCatalogNodeID folderID,
- const unsigned char * name, UInt32 length, CatalogKey *keyPtr,
- CatalogRecord *dataPtr, UInt32 *hintPtr )
-{
- HFSCatalogNodeID fileID;
- unsigned char nodeName[kMaxCompareLen+1];
- OSErr result;
- size_t actualDstLen;
- ByteCount prefixlen;
-
-
- if (name == NULL || name[0] == '\0')
- return cmNotFound;
-
- fileID = GetEmbeddedFileID(name, length, &prefixlen);
-
- if ( fileID < kHFSFirstUserCatalogNodeID )
- return cmNotFound;
-
- result = LocateCatalogNode(volume, fileID, NULL, kNoHint, keyPtr, dataPtr, hintPtr);
- if ( result == cmParentNotFound ) // GetCatalogNode already handled cmParentNotFound case <CS23>
- result = cmNotFound; // so remap <CS23>
- ReturnIfError(result);
-
- // first make sure that the parents match
- if ( folderID != keyPtr->hfsPlus.parentID )
- return cmNotFound; // not the same folder so this is a false match
-
- (void) utf8_encodestr(keyPtr->hfsPlus.nodeName.unicode,
- keyPtr->hfsPlus.nodeName.length * sizeof (UniChar),
- nodeName, &actualDstLen, kMaxCompareLen+1, ':', 0);
-
- prefixlen = min(prefixlen, kMaxCompareLen);
-
- if ((prefixlen - actualDstLen) < 6)
- prefixlen = actualDstLen; /* To take into account UTF8 rounding */
-
- if ( (actualDstLen < prefixlen) || bcmp(nodeName, name, prefixlen-6) != 0)
- return cmNotFound; // mangled names didn't match so this is a false match
-
- return noErr; // we found it
-}
-
//*******************************************************************************
// Routine: LocateCatalogRecord
OSErr
LocateCatalogRecord(const ExtendedVCB *volume, HFSCatalogNodeID folderID, const CatalogName *name,
- UInt32 hint, CatalogKey *keyPtr, CatalogRecord *dataPtr, UInt32 *newHint)
+ __unused u_int32_t hint, CatalogKey *keyPtr, CatalogRecord *dataPtr, u_int32_t *newHint)
{
- OSErr result;
- CatalogKey tempKey; // 518 bytes
- UInt16 tempSize;
+ OSErr result;
+ uint16_t tempSize;
+ FSBufferDescriptor btRecord;
+ struct BTreeIterator *searchIterator = NULL;
+ FCB *fcb;
+ BTreeControlBlock *btcb;
+
+ MALLOC (searchIterator, struct BTreeIterator*, sizeof(struct BTreeIterator), M_TEMP, M_WAITOK);
+ if (searchIterator == NULL) {
+ return memFullErr; // translates to ENOMEM
+ }
- BuildCatalogKey(folderID, name, (volume->vcbSigWord == kHFSPlusSigWord), &tempKey);
+ bzero(searchIterator, sizeof(*searchIterator));
- if ( name == NULL )
- hint = kNoHint; // no CName given so clear the hint
- result = SearchBTreeRecord(volume->catalogRefNum, &tempKey, hint, keyPtr, dataPtr, &tempSize, newHint);
+ fcb = GetFileControlBlock(volume->catalogRefNum);
+ btcb = (BTreeControlBlock *)fcb->fcbBTCBPtr;
- return (result == btNotFound ? cmNotFound : result);
-}
+ btRecord.bufferAddress = dataPtr;
+ btRecord.itemCount = 1;
+ btRecord.itemSize = sizeof(CatalogRecord);
+ BuildCatalogKey(folderID, name, (volume->vcbSigWord == kHFSPlusSigWord), (CatalogKey *)&searchIterator->key);
-//*******************************************************************************
-// Routine: LocateCatalogThread
-//
-// Function: Locates a catalog thread record in the catalog BTree file and
-// returns a pointer to the data record.
-//
-//*******************************************************************************
-
-OSErr
-LocateCatalogThread(const ExtendedVCB *volume, HFSCatalogNodeID nodeID, CatalogRecord *threadData, UInt16 *threadSize, UInt32 *threadHint)
-{
- CatalogKey threadKey; // 518 bytes
- OSErr result;
-
- //--- build key record
-
- BuildCatalogKey(nodeID, NULL, (volume->vcbSigWord == kHFSPlusSigWord), &threadKey);
-
- //--- locate thread record in BTree
+ result = BTSearchRecord(fcb, searchIterator, &btRecord, &tempSize, searchIterator);
+ if (result == noErr) {
+ *newHint = searchIterator->hint.nodeNum;
+ BlockMoveData(&searchIterator->key, keyPtr, CalcKeySize(btcb, &searchIterator->key));
+ }
- result = SearchBTreeRecord( volume->catalogRefNum, &threadKey, kNoHint, &threadKey,
- threadData, threadSize, threadHint);
-
- return (result == btNotFound ? cmNotFound : result);
+ FREE (searchIterator, M_TEMP);
+ return (result == btNotFound ? cmNotFound : result);
}
+
/*
* Routine: BuildCatalogKey
*
key->hfsPlus.keyLength += sizeof(UniChar) * cName->ustr.length; // add CName size to key length
}
}
+#if CONFIG_HFS_STD
else
{
key->hfs.keyLength = kHFSCatalogKeyMinimumLength; // initial key length (1 + 4 + 1)
key->hfs.keyLength += key->hfs.nodeName[0]; // add CName size to key length
}
}
+#endif
+
}
-/*
- * for HFS, only MacRoman is supported. If a non-MacRoman character is found, an error is returned
- */
OSErr
-BuildCatalogKeyUTF8(ExtendedVCB *volume, HFSCatalogNodeID parentID, const char *name, UInt32 nameLength,
- CatalogKey *key, UInt32 *textEncoding)
+BuildCatalogKeyUTF8(ExtendedVCB *volume, HFSCatalogNodeID parentID, const unsigned char *name, u_int32_t nameLength,
+ CatalogKey *key, u_int32_t *textEncoding)
{
OSErr err = 0;
if ( name == NULL)
nameLength = 0;
else if (nameLength == kUndefinedStrLen)
- nameLength = strlen(name);
+ nameLength = strlen((const char *)name);
if ( volume->vcbSigWord == kHFSPlusSigWord ) {
size_t unicodeBytes = 0;
key->hfsPlus.keyLength += unicodeBytes;
}
- if (textEncoding)
- ExtractTextEncoding(key->hfsPlus.nodeName.length, key->hfsPlus.nodeName.unicode, textEncoding);
+ if (textEncoding && (*textEncoding != kTextEncodingMacUnicode))
+ *textEncoding = hfs_pickencoding(key->hfsPlus.nodeName.unicode,
+ key->hfsPlus.nodeName.length);
}
+#if CONFIG_HFS_STD
else {
key->hfs.keyLength = kHFSCatalogKeyMinimumLength; // initial key length (1 + 4 + 1)
key->hfs.reserved = 0; // clear unused byte
if (textEncoding)
*textEncoding = 0;
}
+#endif
if (err) {
if (err == ENAMETOOLONG)
}
-/*
- * make a guess at the text encoding value that coresponds to the Unicode characters
- */
-static void
-ExtractTextEncoding(ItemCount length, ConstUniCharArrayPtr string, UInt32 * textEncoding)
-{
- int i;
- UniChar ch;
-
- *textEncoding = 0;
-
- for (i = 0; i < length; ++i) {
- ch = string[i];
- /* CJK codepoints are 0x3000 thru 0x9FFF */
- if (ch >= 0x3000) {
- if (ch < 0xa000) {
- *textEncoding = kTextEncodingMacJapanese;
- break;
- }
-
- /* fullwidth character codepoints are 0xFF00 thru 0xFFEF */
- if (ch >= 0xff00 && ch <= 0xffef) {
- *textEncoding = kTextEncodingMacJapanese;
- break;
- }
- }
- }
-}
-
-
//*******************************************************************************
// Routine: FlushCatalog
//
{
FCB * fcb;
OSErr result;
+ struct hfsmount *hfsmp = VCBTOHFS (volume);
fcb = GetFileControlBlock(volume->catalogRefNum);
result = BTFlushPath(fcb);
{
//--- check if catalog's fcb is dirty...
- if ( fcb->fcbFlags & fcbModifiedMask )
+ if ( (0) /*fcb->fcbFlags & fcbModifiedMask*/ )
{
- VCB_LOCK(volume);
- volume->vcbFlags |= 0xFF00; // Mark the VCB dirty
+ hfs_lock_mount (hfsmp);
+ MarkVCBDirty(volume); // Mark the VCB dirty
volume->vcbLsMod = GetTimeUTC(); // update last modified date
- VCB_UNLOCK(volume);
+ hfs_unlock_mount (hfsmp);
- result = FlushVolumeControlBlock(volume);
+ // result = FlushVolumeControlBlock(volume);
}
}
BlockMoveData(&srcName[1], &destName[1], length);
}
-
-//*******************************************************************************
-// Routine: AdjustVolumeCounts
-//
-// Function: Adjusts the folder and file counts in the VCB
-//
-//*******************************************************************************
-
-void
-AdjustVolumeCounts(ExtendedVCB *volume, SInt16 type, SInt16 delta)
-{
- //\80\80 also update extended VCB fields...
-
- VCB_LOCK(volume);
-
- if (type == kHFSFolderRecord || type == kHFSPlusFolderRecord)
- volume->vcbDirCnt += delta; // adjust volume folder count, \80\80 worry about overflow?
- else
- volume->vcbFilCnt += delta; // adjust volume file count
-
- volume->vcbFlags |= 0xFF00; // Mark the VCB dirty
- volume->vcbLsMod = GetTimeUTC(); // update last modified date
-
- VCB_UNLOCK(volume);
-}
-
-
-//*******************************************************************************
-
-void
-UpdateVolumeEncodings(ExtendedVCB *volume, TextEncoding encoding)
-{
- UInt32 index;
-
- encoding &= 0x7F;
-
- index = MapEncodingToIndex(encoding);
-
- VCB_LOCK(volume);
-
- volume->encodingsBitmap |= (1 << index);
-
- VCB_UNLOCK(volume);
-
- // vcb should already be marked dirty
-}
-
-
-//*******************************************************************************
-
-OSErr
-UpdateFolderCount( ExtendedVCB *volume, HFSCatalogNodeID parentID, const CatalogName *name, SInt16 newType,
- UInt32 hint, SInt16 valenceDelta)
-{
- CatalogKey tempKey; // 518 bytes
- CatalogRecord tempData; // 520 bytes
- UInt32 tempHint;
- HFSCatalogNodeID folderID;
- UInt16 recordSize;
- OSErr result;
-
-#if 0
- result = SearchBTreeRecord(volume->catalogRefNum, parentKey, hint,
- &tempKey, &tempData, &recordSize, &tempHint);
- if (result)
- return (result == btNotFound ? cmNotFound : result);
-#else
-
- result = LocateCatalogNode(volume, parentID, name, hint, &tempKey, &tempData, &tempHint);
- ReturnIfError(result);
-#endif
-
- if ( volume->vcbSigWord == kHFSPlusSigWord ) // HFS Plus
- {
- UInt32 timeStamp;
-
- if ( DEBUG_BUILD && tempData.recordType != kHFSPlusFolderRecord )
- DebugStr("\p UpdateFolder: found HFS folder on HFS+ volume!");
-
- timeStamp = GetTimeUTC();
- /* adjust valence, but don't go negative */
- if (valenceDelta > 0)
- tempData.hfsPlusFolder.valence += valenceDelta;
- else if (tempData.hfsPlusFolder.valence != 0)
- tempData.hfsPlusFolder.valence += valenceDelta;
- else
- volume->vcbFlags |= kHFS_DamagedVolume;
- tempData.hfsPlusFolder.contentModDate = timeStamp; // set date/time last modified
- folderID = tempData.hfsPlusFolder.folderID;
- recordSize = sizeof(tempData.hfsPlusFolder);
- }
- else // classic HFS
- {
- if ( DEBUG_BUILD && tempData.recordType != kHFSFolderRecord )
- DebugStr("\p UpdateFolder: found HFS+ folder on HFS volume!");
-
- /* adjust valence, but don't go negative */
- if (valenceDelta > 0)
- tempData.hfsFolder.valence += valenceDelta;
- else if (tempData.hfsFolder.valence != 0)
- tempData.hfsFolder.valence += valenceDelta;
- else
- volume->vcbFlags |= kHFS_DamagedVolume;
- tempData.hfsFolder.modifyDate = GetTimeLocal(true); // set date/time last modified
- folderID = tempData.hfsFolder.folderID;
- recordSize = sizeof(tempData.hfsFolder);
- }
-
- result = ReplaceBTreeRecord(volume->catalogRefNum, &tempKey, tempHint,
- &tempData, recordSize, &tempHint);
- ReturnIfError(result);
-
- if ( folderID == kHFSRootFolderID )
- {
- if (newType == kHFSFolderRecord || newType == kHFSPlusFolderRecord)
- {
- VCB_LOCK(volume);
- volume->vcbNmRtDirs += valenceDelta; // adjust root folder count (undefined for HFS Plus)
- VCB_UNLOCK(volume);
- }
- else
- {
- VCB_LOCK(volume);
- volume->vcbNmFls += valenceDelta; // adjust root file count (used by GetVolInfo)
- VCB_UNLOCK(volume);
- }
- }
-
- //XXX also update extended VCB fields...
-
- return result;
-}
-
-
-//*******************************************************************************
-
-UInt16
-GetCatalogRecordSize(const CatalogRecord *dataRecord)
-{
- switch (dataRecord->recordType)
- {
- case kHFSFileRecord:
- return sizeof(HFSCatalogFile);
-
- case kHFSFolderRecord:
- return sizeof(HFSCatalogFolder);
-
- case kHFSPlusFileRecord:
- return sizeof(HFSPlusCatalogFile);
-
- case kHFSPlusFolderRecord:
- return sizeof(HFSPlusCatalogFolder);
-
- case kHFSFolderThreadRecord:
- case kHFSFileThreadRecord:
- return sizeof(HFSCatalogThread);
-
- case kHFSPlusFolderThreadRecord:
- case kHFSPlusFileThreadRecord:
- return sizeof(HFSPlusCatalogThread);
-
- default:
- return 0;
- }
-}
-
-
-//*******************************************************************************
-
-void
-CopyCatalogNodeData(const ExtendedVCB *volume, const CatalogRecord *dataPtr, CatalogNodeData *nodeData)
-{
- /* convert classic hfs records to hfs plus format */
-
- if (dataPtr->recordType == kHFSFolderRecord) {
- nodeData->cnd_type = kCatalogFolderNode;
- nodeData->cnd_flags = dataPtr->hfsFolder.flags;
- nodeData->cnd_nodeID = dataPtr->hfsFolder.folderID;
- nodeData->cnd_createDate = LocalToUTC(dataPtr->hfsFolder.createDate);
- nodeData->cnd_contentModDate = LocalToUTC(dataPtr->hfsFolder.modifyDate);
- nodeData->cnd_backupDate = LocalToUTC(dataPtr->hfsFolder.backupDate);
- nodeData->cnd_valence = dataPtr->hfsFolder.valence;
-
- BlockMoveData(&dataPtr->hfsFolder.userInfo, &nodeData->cnd_finderInfo, 32);
- } else if (dataPtr->recordType == kHFSFileRecord) {
- UInt32 i;
-
- nodeData->cnd_type = kCatalogFileNode;
- nodeData->cnd_flags = dataPtr->hfsFile.flags;
- nodeData->cnd_nodeID = dataPtr->hfsFile.fileID;
- nodeData->cnd_createDate = LocalToUTC(dataPtr->hfsFile.createDate);
- nodeData->cnd_contentModDate = LocalToUTC(dataPtr->hfsFile.modifyDate);
- nodeData->cnd_backupDate = LocalToUTC(dataPtr->hfsFile.backupDate);
- nodeData->cnd_linkCount = 0;
-
- BlockMoveData(&dataPtr->hfsFile.userInfo, &nodeData->cnd_finderInfo, 16);
- BlockMoveData(&dataPtr->hfsFile.finderInfo, (void*)((UInt32)&nodeData->cnd_finderInfo + 16), 16);
-
- nodeData->cnd_datafork.logicalSize = dataPtr->hfsFile.dataLogicalSize;
- nodeData->cnd_datafork.totalBlocks =
- dataPtr->hfsFile.dataPhysicalSize / volume->blockSize;
-
- nodeData->cnd_rsrcfork.logicalSize = dataPtr->hfsFile.rsrcLogicalSize;
- nodeData->cnd_rsrcfork.totalBlocks =
- dataPtr->hfsFile.rsrcPhysicalSize / volume->blockSize;
-
- for (i = 0; i < kHFSExtentDensity; ++i) {
- nodeData->cnd_datafork.extents[i].startBlock =
- (UInt32) (dataPtr->hfsFile.dataExtents[i].startBlock);
-
- nodeData->cnd_datafork.extents[i].blockCount =
- (UInt32) (dataPtr->hfsFile.dataExtents[i].blockCount);
-
- nodeData->cnd_rsrcfork.extents[i].startBlock =
- (UInt32) (dataPtr->hfsFile.rsrcExtents[i].startBlock);
-
- nodeData->cnd_rsrcfork.extents[i].blockCount =
- (UInt32) (dataPtr->hfsFile.rsrcExtents[i].blockCount);
- }
- for (i = kHFSExtentDensity; i < kHFSPlusExtentDensity; ++i) {
- nodeData->cnd_datafork.extents[i].startBlock = 0;
- nodeData->cnd_datafork.extents[i].blockCount = 0;
- nodeData->cnd_rsrcfork.extents[i].startBlock = 0;
- nodeData->cnd_rsrcfork.extents[i].blockCount = 0;
- }
- } else {
- nodeData->cnd_type = 0;
- }
-}
-
-
//_______________________________________________________________________
void
-CopyCatalogName(const CatalogName *srcName, CatalogName *dstName, Boolean isHFSPLus)
+CopyCatalogName(const CatalogName *srcName, CatalogName *dstName, Boolean isHFSPlus)
{
- UInt32 length;
+ u_int32_t length = 0;
if ( srcName == NULL )
{
return;
}
- if (isHFSPLus)
+ if (isHFSPlus) {
length = sizeof(UniChar) * (srcName->ustr.length + 1);
- else
- length = sizeof(UInt8) + srcName->pstr[0];
+ }
+#if CONFIG_HFS_STD
+ else {
+ length = sizeof(u_int8_t) + srcName->pstr[0];
+ }
+#endif
if ( length > 1 )
BlockMoveData(srcName, dstName, length);
dstName->ustr.length = 0; // set length byte to zero (works for both unicode and pascal)
}
-//_______________________________________________________________________
-
-UInt32
-CatalogNameLength(const CatalogName *name, Boolean isHFSPlus)
-{
- if (isHFSPlus)
- return name->ustr.length;
- else
- return name->pstr[0];
-}
-
-
-