+ MALLOC (btIterator, struct BTreeIterator*, sizeof(struct BTreeIterator), M_TEMP, M_WAITOK);
+ if (btIterator == NULL) {
+ return memFullErr; // translates to ENOMEM
+ }
+ bzero(btIterator, sizeof(*btIterator));
+
+ /* HFS Plus / HFSX */
+ if (vcb->vcbSigWord != kHFSSigWord) {
+ HFSPlusExtentKey * extentKeyPtr;
+ HFSPlusExtentRecord extentData;
+
+ extentKeyPtr = (HFSPlusExtentKey*) &btIterator->key;
+ extentKeyPtr->keyLength = kHFSPlusExtentKeyMaximumLength;
+ extentKeyPtr->forkType = forkType;
+ extentKeyPtr->pad = 0;
+ extentKeyPtr->fileID = fileID;
+ extentKeyPtr->startBlock = startBlock;
+
+ btRecord.bufferAddress = &extentData;
+ btRecord.itemSize = sizeof(HFSPlusExtentRecord);
+ btRecord.itemCount = 1;
+
+ err = BTSearchRecord(fcb, btIterator, &btRecord, &btRecordSize, btIterator);
+
+ if (err == btNotFound && allowPrevious) {
+ err = BTIterateRecord(fcb, kBTreePrevRecord, btIterator, &btRecord, &btRecordSize);
+
+ // A previous record may not exist, so just return btNotFound (like we would if
+ // it was for the wrong file/fork).
+ if (err == (OSErr) fsBTStartOfIterationErr) //¥¥ fsBTStartOfIterationErr is type unsigned long
+ err = btNotFound;
+
+ if (err == noErr) {
+ // Found a previous record. Does it belong to the same fork of the same file?
+ if (extentKeyPtr->fileID != fileID || extentKeyPtr->forkType != forkType)
+ err = btNotFound;
+ }
+ }
+
+ if (err == noErr) {
+ // Copy the found key back for the caller
+ if (foundKey)
+ BlockMoveData(extentKeyPtr, foundKey, sizeof(HFSPlusExtentKey));
+ // Copy the found data back for the caller
+ BlockMoveData(&extentData, foundData, sizeof(HFSPlusExtentRecord));
+ }
+ }
+#if CONFIG_HFS_STD
+ else {