long UFSGetDirEntry( CICell ih, char * dirPath, long long * dirIndex, char ** name, long * flags, long * time, FinderInfo * finderInfo, long * infoValid) { long ret, fileInodeNum, dirFlags; Inode tmpInode; if (UFSInitPartition(ih) == -1) return -1; if (infoValid) *infoValid = 0; // Skip a leading '/' if present if (*dirPath == '/') dirPath++; if (*dirPath == '/') dirPath++; ret = ResolvePathToInode(dirPath, &dirFlags, gFileInodePtr, gRootInodePtr); if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory)) return -1; ret = ReadDirEntry(gFileInodePtr, &fileInodeNum, dirIndex, name); if (ret != 0) return ret; ReadInode(fileInodeNum, &tmpInode, flags, time); return 0; }
long UFSGetUUID(CICell ih, char *uuidStr) { long long uuid = gUFSLabel.ul_uuid; if (UFSInitPartition(ih) == -1) return -1; if (uuid == 0LL) return -1; return CreateUUIDString((uint8_t*)(&uuid), sizeof(uuid), uuidStr); }
long UFSGetFileBlock(CICell ih, char *filePath, unsigned long long *firstBlock) { long ret, flags; if (UFSInitPartition(ih) == -1) return -1; // Skip one or two leading '/'. if (*filePath == '/') filePath++; if (*filePath == '/') filePath++; ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr); if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; *firstBlock = (gPartitionBase + 1ULL * gFileInodePtr->di_db[0] * gBlockSize) / 512ULL; return 0; }
long UFSLoadFile(CICell ih, char *filePath) { long ret, length, flags; if (UFSInitPartition(ih) == -1) return -1; printf("Loading UFS file: [%s] from %x.\n", filePath, ih); // Skip one or two leading '\'. if (*filePath == '\\') filePath++; if (*filePath == '\\') filePath++; ret = ResolvePathToInode(filePath, &flags, &gFileInode, &gRootInode); if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; if (flags & (kOwnerNotRoot | kPermGroupWrite | kPermOtherWrite)) return -1; ret = ReadFile(&gFileInode, &length); if (ret == -1) return -1; return length; }
long UFSReadFile( CICell ih, char * filePath, void * base, uint64_t offset, uint64_t length ) { long ret, flags; #if !BOOT1 verbose("Loading UFS file: [%s] from %x.\n", filePath, (unsigned)ih); #endif if (UFSInitPartition(ih) == -1) return -1; // Skip one or two leading '/'. if (*filePath == '/') filePath++; if (*filePath == '/') filePath++; ret = ResolvePathToInode(filePath, &flags, gFileInodePtr, gRootInodePtr); if ((ret == -1) || ((flags & kFileTypeMask) != kFileTypeFlat)) return -1; ret = ReadFile(gFileInodePtr, &length, base, offset); if (ret == -1) return -1; return length; }
long UFSGetDirEntry(CICell ih, char *dirPath, long *dirIndex, char **name, long *flags, long *time) { long ret, fileInodeNum, dirFlags; Inode tmpInode; if (UFSInitPartition(ih) == -1) return -1; // Skip a leading '\' if present if (*dirPath == '\\') dirPath++; if (*dirPath == '\\') dirPath++; ret = ResolvePathToInode(dirPath, &dirFlags, &gFileInode, &gRootInode); if ((ret == -1) || ((dirFlags & kFileTypeMask) != kFileTypeDirectory)) return -1; ret = ReadDirEntry(&gFileInode, &fileInodeNum, dirIndex, name); if (ret != 0) return ret; ReadInode(fileInodeNum, &tmpInode, flags, time); return 0; }
void UFSGetDescription(CICell ih, char *str, long strMaxLen) { if (UFSInitPartition(ih) == -1) { return; } struct ufslabel *ul; // Look for the Disk Label Seek(ih, 1ULL * UFS_LABEL_OFFSET); Read(ih, (long)gULBuf, UFS_LABEL_SIZE); ul = (struct ufslabel *)gULBuf; unsigned char magic_bytes[] = UFS_LABEL_MAGIC; int i; unsigned char *p = (unsigned char *)&ul->ul_magic; for (i=0; i<sizeof(magic_bytes); i++, p++) { if (*p != magic_bytes[i]) return; } strncpy(str, (const char *)ul->ul_name, strMaxLen); }
long LookupPartition(char *devSpec) { CICell partIH; long partIndex, partType; long deviceType; // See if the devSpec has already been opened. for (partIndex = 0; partIndex < kNumPartInfos; partIndex++) { if (!strcmp(gParts[partIndex].partName, devSpec)) break; } // If it has not been opened, do so now. if (partIndex == kNumPartInfos) { // Find a free slot. for (partIndex = 0; partIndex < kNumPartInfos; partIndex++) { if (gParts[partIndex].partIH == 0) break; } // No free slots, so return error. if (partIndex == kNumPartInfos) return -1; deviceType = GetDeviceType(devSpec); switch (deviceType) { case kNetworkDeviceType : partIH = NetInitPartition(devSpec); if (partIH == 0) return -1; partType = kPartNet; break; case kBlockDeviceType : printf("Opening partition [%s]...\n", devSpec); partIH = Open(devSpec); if (partIH == 0) { printf("Failed to open partition [%s].\n", devSpec); return -1; } // Find out what kind of partition it is. if (HFSInitPartition(partIH) != -1) partType = kPartHFS; else if (UFSInitPartition(partIH) != -1) partType = kPartUFS; else if (Ext2InitPartition(partIH) != -1) partType = kPartExt2; else return -1; break; default : return -1; } gParts[partIndex].partIH = partIH; gParts[partIndex].partType = partType; strcpy(gParts[partIndex].partName, devSpec); switch (partType) { case kPartNet: gParts[partIndex].loadFile = NetLoadFile; gParts[partIndex].readFile = NULL; gParts[partIndex].getDirEntry = NetGetDirEntry; gParts[partIndex].getUUID = NULL; break; case kPartHFS: gParts[partIndex].loadFile = HFSLoadFile; gParts[partIndex].readFile = HFSReadFile; gParts[partIndex].getDirEntry = HFSGetDirEntry; gParts[partIndex].getUUID = HFSGetUUID; break; case kPartUFS: gParts[partIndex].loadFile = UFSLoadFile; gParts[partIndex].readFile = UFSReadFile; gParts[partIndex].getDirEntry = UFSGetDirEntry; gParts[partIndex].getUUID = UFSGetUUID; break; case kPartExt2: gParts[partIndex].loadFile = Ext2LoadFile; gParts[partIndex].readFile = NULL; gParts[partIndex].getDirEntry = Ext2GetDirEntry; gParts[partIndex].getUUID = NULL; // Ext2GetUUID exists, but there's no kernel support break; } } return partIndex; }