long Ext2GetDirEntry(CICell ih, char *dirPath, long *dirIndex, char **name, long *flags, long *time) { long ret, fileInodeNum, dirFlags; Inode tmpInode; if (Ext2InitPartition(ih) == -1) return -1; // Skip a leading '\' if present if (dirPath[0] == '\\') 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; }
long Ext2LoadFile(CICell ih, char *filePath) { long ret, length, flags; if (Ext2InitPartition(ih) == -1) return -1; printf("Loading Ext2 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 != 0) return -1; return length; }
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; }