+void
+HFSGetDescription(CICell ih, char *str, long strMaxLen)
+{
+
+ UInt16 nodeSize;
+ UInt32 firstLeafNode;
+ long dirIndex;
+ char *name;
+ long flags, time;
+
+ if (HFSInitPartition(ih) == -1) { return; }
+
+ /* Fill some crucial data structures by side effect. */
+ dirIndex = 0;
+ HFSGetDirEntry(ih, "/", &dirIndex, &name, &flags, &time, 0, 0);
+
+ /* Now we can loook up the volume name node. */
+ nodeSize = SWAP_BE16(gBTHeaders[kBTreeCatalog]->nodeSize);
+ firstLeafNode = SWAP_BE32(gBTHeaders[kBTreeCatalog]->firstLeafNode);
+
+ dirIndex = firstLeafNode * nodeSize;
+
+ GetCatalogEntry(&dirIndex, &name, &flags, &time, 0, 0);
+
+ strncpy(str, name, strMaxLen);
+ str[strMaxLen] = '\0';
+}
+
+
+long
+HFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock)
+{
+ char entry[512];
+ long dirID, result, flags;
+ void *extents;
+ HFSCatalogFile *hfsFile = (void *)entry;
+ HFSPlusCatalogFile *hfsPlusFile = (void *)entry;
+
+ if (HFSInitPartition(ih) == -1) return -1;
+
+ dirID = kHFSRootFolderID;
+ // Skip a lead '\'. Start in the system folder if there are two.
+ if (filePath[0] == '/') {
+ if (filePath[1] == '/') {
+ if (gIsHFSPlus) dirID = SWAP_BE32(((long *)gHFSPlus->finderInfo)[5]);
+ else dirID = SWAP_BE32(gHFSMDB->drFndrInfo[5]);
+ if (dirID == 0) {
+ return -1;
+ }
+ filePath++;
+ }
+ filePath++;
+ }
+
+ result = ResolvePathToCatalogEntry(filePath, &flags, entry, dirID, 0);
+ if ((result == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) {
+ printf("HFS: Resolve path %s failed\n", filePath);
+ return -1;
+ }
+
+ if (gIsHFSPlus) {
+ extents = &hfsPlusFile->dataFork.extents;
+ } else {
+ extents = &hfsFile->dataExtents;
+ }
+
+#if DEBUG
+ printf("extent start 0x%x\n", (unsigned long)GetExtentStart(extents, 0));
+ printf("block size 0x%x\n", (unsigned long)gBlockSize);
+ printf("Allocation offset 0x%x\n", (unsigned long)gAllocationOffset);
+#endif
+ *firstBlock = ((unsigned long long)GetExtentStart(extents, 0) * (unsigned long long) gBlockSize + gAllocationOffset) / 512ULL;
+ return 0;
+}
+
+long HFSGetUUID(CICell ih, char *uuidStr)
+{
+ if (HFSInitPartition(ih) == -1) return -1;
+ if (gVolID == 0LL) return -1;
+
+ return CreateUUIDString((uint8_t*)(&gVolID), sizeof(gVolID), uuidStr);
+}
+