/*! @file i386/libsaio/bootmap.h @abstract Routines to work with BootBVMap @copyright David Elliott */ /*! @class BootBVMap @abstract A node in a linked list of maps which points to a linked list of BVs. */ typedef struct BootBVMap BootBVMap, *BootBVMapRef; struct BootBVMap { BootBVMapRef next; unsigned int biosdev; BVRef bvChain; int bvCount; }; /*! @abstract Scans for bootable volumes on all devices @arg firstDev Device to process first (e.g. boot device). Use -1 to turn this off. @arg bvCount Pointer to count that will be filled in. @arg doCompleteScan True: Really do scan all devices, 0x80 through 0xff False: scan firstDev then 0x80 until a device doesn't have disk info and stop. @discussion At the moment this iterates all BIOS devices from 80h to ffh. When an active device is found scanBootVolumes is called to enumerate the boot volumes (if any) of that device. The list is linked in a specific order. Namely, if firstDev is >= 0 it is processed first such that it will wind up at the tail of the list. Then all other devices are processed in order. The result is a linked list whose head points to the last device scanned. The somewhat backwards ordering matches that of the BVRef chain returned from scanBootVolumes such that the entire list of boot volumes can be iterated in backwards order. The menuing system expects this order. */ extern BootBVMapRef scanBootVolumesOnAllDevices(int firstDev, int *bvCount, bool doCompleteScan); /*! @abstract Frees a BootBVMap returned from scanBootVolumesOnAllDevices */ extern void freeBootBVMap(BootBVMapRef head); /* --------------------------------------------------------------------- */ /*! @class BootBVMapBVIterator @abstract Iterates over BVRef in a BVMap. @discussion When displaying a flat list of bootable volumes it is useful to be able to iterate them without having to deal with the grunt work of navigating the outer BootBVMap list and the inner BVRef list. To use it allocate an iterator object on your stack and initialize it with a BootBVMapRef. Then call the GetNext method until it returns NULL. */ typedef struct BootBVMapBVIterator BootBVMapBVIterator; struct BootBVMapBVIterator { BootBVMapRef bootBvMapRef; BVRef bvRef; }; /*! @method BootBVMapBVIteratorInit @abstract Initializes the iterator to start with the specified BootBVMapRef */ static inline void BootBVMapBVIteratorInit(BootBVMapBVIterator *pIter, BootBVMapRef head) { pIter->bootBvMapRef = head; pIter->bvRef = head->bvChain; } /*! @method BootBVMapBVIteratorGetNext @abstract Returns the current iterator item and advances the iterator. */ static inline BVRef BootBVMapBVIteratorGetNext(BootBVMapBVIterator *pIter) { BVRef result; // if the bvChain of the iterator is NULL that means we're done with // boot volumes for this device (which may be because the device // never had any boot volumes to begin with) // In that case if we have a next device then move the iterator // to the start of the next device. // Keep doing this until we get a non-null bvChain or no longer // have a next device. while(pIter->bvRef == NULL && pIter->bootBvMapRef->next != NULL) BootBVMapBVIteratorInit(pIter, pIter->bootBvMapRef->next); // Return the boot volume that the iterator is pointing to now. result = pIter->bvRef; // Advance the iterator. If we wind up setting bvChain to NULL // because we hit the end, the next call will move on to the // next device. if(result != NULL) pIter->bvRef = pIter->bvRef->next; return result; }