bool IOFDiskPartitionScheme::isPartitionInvalid( fdisk_part * partition, UInt32 partitionID, UInt32 fdiskBlock ) { // // Ask whether the given partition appears to be invalid. A partition that // is invalid will cause it to be skipped in the scan, but will not cause a // failure of the FDisk partition map recognition. // IOMedia * media = getProvider(); UInt64 mediaBlockSize = media->getPreferredBlockSize(); UInt64 partitionBase = 0; UInt64 partitionSize = 0; // Compute the relative byte position and size of the new partition. partitionBase = OSSwapLittleToHostInt32(partition->relsect) + fdiskBlock; partitionSize = OSSwapLittleToHostInt32(partition->numsect); partitionBase *= mediaBlockSize; partitionSize *= mediaBlockSize; // Determine whether the partition shares space with the partition map. if ( partitionBase == fdiskBlock * mediaBlockSize ) return true; // Determine whether the partition starts at (or past) the end-of-media. if ( partitionBase >= media->getSize() ) return true; return false; }
IOReturn RTL8139::getHardwareAddress( IOEthernetAddress *address ) { union { UInt8 bytes[4]; UInt32 int32; } idr; DEBUG_LOG( "getHardwareAddress() ===>\n" ); // Fetch the hardware address bootstrapped from EEPROM. idr.int32 = OSSwapLittleToHostInt32( csrRead32( RTL_IDR0 ) ); address->bytes[0] = idr.bytes[0]; address->bytes[1] = idr.bytes[1]; address->bytes[2] = idr.bytes[2]; address->bytes[3] = idr.bytes[3]; idr.int32 = OSSwapLittleToHostInt32( csrRead32( RTL_IDR4 ) ); address->bytes[4] = idr.bytes[0]; address->bytes[5] = idr.bytes[1]; ELG( *(UInt16*)address->bytes, *(UInt32*)&address->bytes[2], 'gHWA', "RTL8139::getHardwareAddress" ); DEBUG_LOG( "getHardwareAddress() <===\n" ); return kIOReturnSuccess; }/* end getHardwareAddress */
IOReturn IOFWAsyncStreamReceiver::receiveAsyncStream(void *refcon, IOFireWireMultiIsochReceivePacket *pPacket) { IOFWAsyncStreamReceiver *receiver = (IOFWAsyncStreamReceiver*)refcon; if( not receiver) return kIOReturnError; UInt16 index = 0; IOByteCount offset = 0; for(;;) { if(index == pPacket->numRanges) break; IOByteCount bytesWritten = receiver->fBufDesc->writeBytes(offset, (void*)pPacket->ranges[index].address, pPacket->ranges[index].length); offset += bytesWritten; index++; } // Need to make the isoch header native endian UInt32 *pHeader = (UInt32*)receiver->fBufDesc->getBytesNoCopy(); *pHeader = OSSwapLittleToHostInt32(*pHeader); receiver->indicateListeners( (UInt8*)receiver->fBufDesc->getBytesNoCopy() ); pPacket->clientDone(); return kIOReturnSuccess; }
UniversalMachOLayout::UniversalMachOLayout(const char* path, const std::set<ArchPair>* onlyArchs) : fPath(strdup(path)) { // map in whole file int fd = ::open(path, O_RDONLY, 0); if ( fd == -1 ) { int err = errno; if ( err == ENOENT ) throwf("file not found"); else throwf("can't open file, errno=%d", err); } struct stat stat_buf; if ( fstat(fd, &stat_buf) == -1) throwf("can't stat open file %s, errno=%d", path, errno); if ( stat_buf.st_size < 20 ) throwf("file too small %s", path); uint8_t* p = (uint8_t*)::mmap(NULL, stat_buf.st_size, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, 0); if ( p == (uint8_t*)(-1) ) throwf("can't map file %s, errno=%d", path, errno); ::close(fd); try { // if fat file, process each architecture const fat_header* fh = (fat_header*)p; const mach_header* mh = (mach_header*)p; if ( fh->magic == OSSwapBigToHostInt32(FAT_MAGIC) ) { // Fat header is always big-endian const struct fat_arch* slices = (struct fat_arch*)(p + sizeof(struct fat_header)); const uint32_t sliceCount = OSSwapBigToHostInt32(fh->nfat_arch); for (uint32_t i=0; i < sliceCount; ++i) { if ( requestedSlice(onlyArchs, OSSwapBigToHostInt32(slices[i].cputype), OSSwapBigToHostInt32(slices[i].cpusubtype)) ) { uint32_t fileOffset = OSSwapBigToHostInt32(slices[i].offset); if ( fileOffset > stat_buf.st_size ) { throwf("malformed universal file, slice %u for architecture 0x%08X is beyond end of file: %s", i, OSSwapBigToHostInt32(slices[i].cputype), path); } if ( (fileOffset+OSSwapBigToHostInt32(slices[i].size)) > stat_buf.st_size ) { throwf("malformed universal file, slice %u for architecture 0x%08X is beyond end of file: %s", i, OSSwapBigToHostInt32(slices[i].cputype), path); } try { switch ( OSSwapBigToHostInt32(slices[i].cputype) ) { case CPU_TYPE_I386: fLayouts.push_back(new MachOLayout<x86>(&p[fileOffset], fileOffset, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); break; case CPU_TYPE_X86_64: fLayouts.push_back(new MachOLayout<x86_64>(&p[fileOffset], fileOffset, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); break; case CPU_TYPE_ARM: fLayouts.push_back(new MachOLayout<arm>(&p[fileOffset], fileOffset, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); break; default: throw "unknown slice in fat file"; } } catch (const char* msg) { fprintf(stderr, "warning: %s for %s\n", msg, path); } } } } else { try { if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_I386)) { if ( requestedSlice(onlyArchs, OSSwapLittleToHostInt32(mh->cputype), OSSwapLittleToHostInt32(mh->cpusubtype)) ) fLayouts.push_back(new MachOLayout<x86>(mh, 0, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); } else if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC_64) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_X86_64)) { if ( requestedSlice(onlyArchs, OSSwapLittleToHostInt32(mh->cputype), OSSwapLittleToHostInt32(mh->cpusubtype)) ) fLayouts.push_back(new MachOLayout<x86_64>(mh, 0, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); } else if ( (OSSwapLittleToHostInt32(mh->magic) == MH_MAGIC) && (OSSwapLittleToHostInt32(mh->cputype) == CPU_TYPE_ARM)) { if ( requestedSlice(onlyArchs, OSSwapLittleToHostInt32(mh->cputype), OSSwapLittleToHostInt32(mh->cpusubtype)) ) fLayouts.push_back(new MachOLayout<arm>(mh, 0, fPath, stat_buf.st_ino, stat_buf.st_mtime, stat_buf.st_uid)); } else { throw "unknown file format"; } } catch (const char* msg) { fprintf(stderr, "warning: %s for %s\n", msg, path); } } } catch (...) { ::munmap(p, stat_buf.st_size); throw; } }
OSSet * IOGUIDPartitionScheme::scan(SInt32 * score) { // // Scan the provider media for a GUID partition map. Returns the set // of media objects representing each of the partitions (the retain for // the set is passed to the caller), or null should no partition map be // found. The default probe score can be adjusted up or down, based on // the confidence of the scan. // IOBufferMemoryDescriptor * buffer = 0; IOByteCount bufferSize = 0; UInt32 fdiskID = 0; disk_blk0 * fdiskMap = 0; UInt64 gptBlock = 0; UInt32 gptCheck = 0; UInt32 gptCount = 0; UInt32 gptID = 0; gpt_ent * gptMap = 0; UInt32 gptSize = 0; UInt32 headerCheck = 0; gpt_hdr * headerMap = 0; UInt32 headerSize = 0; IOMedia * media = getProvider(); UInt64 mediaBlockSize = media->getPreferredBlockSize(); bool mediaIsOpen = false; OSSet * partitions = 0; IOReturn status = kIOReturnError; // Determine whether this media is formatted. if ( media->isFormatted() == false ) goto scanErr; // Determine whether this media has an appropriate block size. if ( (mediaBlockSize % sizeof(disk_blk0)) ) goto scanErr; // Allocate a buffer large enough to hold one map, rounded to a media block. bufferSize = IORound(sizeof(disk_blk0), mediaBlockSize); buffer = IOBufferMemoryDescriptor::withCapacity( /* capacity */ bufferSize, /* withDirection */ kIODirectionIn ); if ( buffer == 0 ) goto scanErr; // Allocate a set to hold the set of media objects representing partitions. partitions = OSSet::withCapacity(8); if ( partitions == 0 ) goto scanErr; // Open the media with read access. mediaIsOpen = open(this, 0, kIOStorageAccessReader); if ( mediaIsOpen == false ) goto scanErr; // Read the protective map into our buffer. status = media->read(this, 0, buffer); if ( status != kIOReturnSuccess ) goto scanErr; fdiskMap = (disk_blk0 *) buffer->getBytesNoCopy(); // Determine whether the protective map signature is present. if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE ) { goto scanErr; } // Scan for valid partition entries in the protective map. for ( unsigned index = 0; index < DISK_NPART; index++ ) { if ( fdiskMap->parts[index].systid ) { if ( fdiskMap->parts[index].systid == 0xEE ) { if ( fdiskID ) goto scanErr; fdiskID = index + 1; } } } if ( fdiskID == 0 ) goto scanErr; // Read the partition header into our buffer. status = media->read(this, mediaBlockSize, buffer); if ( status != kIOReturnSuccess ) goto scanErr; headerMap = (gpt_hdr *) buffer->getBytesNoCopy(); // Determine whether the partition header signature is present. if ( memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) ) { goto scanErr; } // Determine whether the partition header size is valid. headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self); headerSize = OSSwapLittleToHostInt32(headerMap->hdr_size); if ( headerSize < offsetof(gpt_hdr, padding) ) { goto scanErr; } if ( headerSize > mediaBlockSize ) { goto scanErr; } // Determine whether the partition header checksum is valid. headerMap->hdr_crc_self = 0; if ( crc32(0, headerMap, headerSize) != headerCheck ) { goto scanErr; } // Determine whether the partition entry size is valid. gptCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_table); gptSize = OSSwapLittleToHostInt32(headerMap->hdr_entsz); if ( gptSize < sizeof(gpt_ent) ) { goto scanErr; } if ( gptSize > UINT16_MAX ) { goto scanErr; } // Determine whether the partition entry count is valid. gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table); gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries); if ( gptCount > UINT16_MAX ) { goto scanErr; } // Allocate a buffer large enough to hold one map, rounded to a media block. buffer->release(); bufferSize = IORound(gptCount * gptSize, mediaBlockSize); buffer = IOBufferMemoryDescriptor::withCapacity( /* capacity */ bufferSize, /* withDirection */ kIODirectionIn ); if ( buffer == 0 ) goto scanErr; // Read the partition header into our buffer. status = media->read(this, gptBlock * mediaBlockSize, buffer); if ( status != kIOReturnSuccess ) goto scanErr; gptMap = (gpt_ent *) buffer->getBytesNoCopy(); // Determine whether the partition entry checksum is valid. if ( crc32(0, gptMap, gptCount * gptSize) != gptCheck ) { goto scanErr; } // Scan for valid partition entries in the partition map. for ( gptID = 1; gptID <= gptCount; gptID++ ) { gptMap = (gpt_ent *) ( ((UInt8 *) buffer->getBytesNoCopy()) + (gptID * gptSize) - gptSize ); uuid_unswap( gptMap->ent_type ); uuid_unswap( gptMap->ent_uuid ); if ( isPartitionUsed( gptMap ) ) { // Determine whether the partition is corrupt (fatal). if ( isPartitionCorrupt( gptMap, gptID ) ) { goto scanErr; } // Determine whether the partition is invalid (skipped). if ( isPartitionInvalid( gptMap, gptID ) ) { continue; } // Create a media object to represent this partition. IOMedia * newMedia = instantiateMediaObject( gptMap, gptID ); if ( newMedia ) { partitions->setObject(newMedia); newMedia->release(); } } } // Release our resources. close(this); buffer->release(); return partitions; scanErr: // Release our resources. if ( mediaIsOpen ) close(this); if ( partitions ) partitions->release(); if ( buffer ) buffer->release(); return 0; }
IOMedia * IOFDiskPartitionScheme::instantiateMediaObject( fdisk_part * partition, UInt32 partitionID, UInt32 fdiskBlock ) { // // Instantiate a new media object to represent the given partition. // IOMedia * media = getProvider(); UInt64 mediaBlockSize = media->getPreferredBlockSize(); UInt64 partitionBase = 0; char * partitionHint = 0; UInt64 partitionSize = 0; // Compute the relative byte position and size of the new partition. partitionBase = OSSwapLittleToHostInt32(partition->relsect) + fdiskBlock; partitionSize = OSSwapLittleToHostInt32(partition->numsect); partitionBase *= mediaBlockSize; partitionSize *= mediaBlockSize; // Clip the size of the new partition if it extends past the end-of-media. if ( partitionBase + partitionSize > media->getSize() ) { partitionSize = media->getSize() - partitionBase; } // Look up a type for the new partition. char hintIndex[5]; snprintf(hintIndex, sizeof(hintIndex), "0x%02X", partition->systid & 0xFF); partitionHint = hintIndex; OSDictionary * hintTable = OSDynamicCast( /* type */ OSDictionary, /* instance */ getProperty(kIOFDiskPartitionSchemeContentTable) ); if ( hintTable ) { OSString * hintValue; hintValue = OSDynamicCast(OSString, hintTable->getObject(hintIndex)); if ( hintValue ) partitionHint = (char *) hintValue->getCStringNoCopy(); } // Create the new media object. IOMedia * newMedia = instantiateDesiredMediaObject( /* partition */ partition, /* partitionID */ partitionID, /* fdiskBlock */ fdiskBlock ); if ( newMedia ) { if ( newMedia->init( /* base */ partitionBase, /* size */ partitionSize, /* preferredBlockSize */ mediaBlockSize, /* attributes */ media->getAttributes(), /* isWhole */ false, /* isWritable */ media->isWritable(), /* contentHint */ partitionHint ) ) { // Set a name for this partition. char name[24]; snprintf(name, sizeof(name), "Untitled %d", (int) partitionID); newMedia->setName(name); // Set a location value (the partition number) for this partition. char location[12]; snprintf(location, sizeof(location), "%d", (int) partitionID); newMedia->setLocation(location); // Set the "Partition ID" key for this partition. newMedia->setProperty(kIOMediaPartitionIDKey, partitionID, 32); } else { newMedia->release(); newMedia = 0; } } return newMedia; }
OSSet * IOFDiskPartitionScheme::scan(SInt32 * score) { // // Scan the provider media for an FDisk partition map. Returns the set // of media objects representing each of the partitions (the retain for // the set is passed to the caller), or null should no partition map be // found. The default probe score can be adjusted up or down, based on // the confidence of the scan. // IOBufferMemoryDescriptor * buffer = 0; UInt32 bufferSize = 0; UInt32 fdiskBlock = 0; UInt32 fdiskBlockExtn = 0; UInt32 fdiskBlockNext = 0; UInt32 fdiskID = 0; disk_blk0 * fdiskMap = 0; IOMedia * media = getProvider(); UInt64 mediaBlockSize = media->getPreferredBlockSize(); bool mediaIsOpen = false; OSSet * partitions = 0; IOReturn status = kIOReturnError; // Determine whether this media is formatted. if ( media->isFormatted() == false ) goto scanErr; // Determine whether this media has an appropriate block size. if ( (mediaBlockSize % sizeof(disk_blk0)) ) goto scanErr; // Allocate a buffer large enough to hold one map, rounded to a media block. bufferSize = IORound(sizeof(disk_blk0), mediaBlockSize); buffer = IOBufferMemoryDescriptor::withCapacity( /* capacity */ bufferSize, /* withDirection */ kIODirectionIn ); if ( buffer == 0 ) goto scanErr; // Allocate a set to hold the set of media objects representing partitions. partitions = OSSet::withCapacity(4); if ( partitions == 0 ) goto scanErr; // Open the media with read access. mediaIsOpen = open(this, 0, kIOStorageAccessReader); if ( mediaIsOpen == false ) goto scanErr; // Scan the media for FDisk partition map(s). do { // Read the next FDisk map into our buffer. status = media->read(this, fdiskBlock * mediaBlockSize, buffer); if ( status != kIOReturnSuccess ) goto scanErr; fdiskMap = (disk_blk0 *) buffer->getBytesNoCopy(); // Determine whether the partition map signature is present. if ( OSSwapLittleToHostInt16(fdiskMap->signature) != DISK_SIGNATURE ) { goto scanErr; } // Scan for valid partition entries in the partition map. fdiskBlockNext = 0; for ( unsigned index = 0; index < DISK_NPART; index++ ) { // Determine whether this is an extended (vs. data) partition. if ( isPartitionExtended(fdiskMap->parts + index) ) // (extended) { // If peer extended partitions exist, we accept only the first. if ( fdiskBlockNext == 0 ) // (no peer extended partition) { fdiskBlockNext = fdiskBlockExtn + OSSwapLittleToHostInt32( /* data */ fdiskMap->parts[index].relsect ); if ( fdiskBlockNext * mediaBlockSize >= media->getSize() ) { fdiskBlockNext = 0; // (exceeds confines of media) } } } else if ( isPartitionUsed(fdiskMap->parts + index) ) // (data) { // Prepare this partition's ID. fdiskID = ( fdiskBlock == 0 ) ? (index + 1) : (fdiskID + 1); // Determine whether the partition is corrupt (fatal). if ( isPartitionCorrupt( /* partition */ fdiskMap->parts + index, /* partitionID */ fdiskID, /* fdiskBlock */ fdiskBlock ) ) { goto scanErr; } // Determine whether the partition is invalid (skipped). if ( isPartitionInvalid( /* partition */ fdiskMap->parts + index, /* partitionID */ fdiskID, /* fdiskBlock */ fdiskBlock ) ) { continue; } // Create a media object to represent this partition. IOMedia * newMedia = instantiateMediaObject( /* partition */ fdiskMap->parts + index, /* partitionID */ fdiskID, /* fdiskBlock */ fdiskBlock ); if ( newMedia ) { partitions->setObject(newMedia); newMedia->release(); } } } // Prepare for first extended partition, if any. if ( fdiskBlock == 0 ) { fdiskID = DISK_NPART; fdiskBlockExtn = fdiskBlockNext; } } while ( (fdiskBlock = fdiskBlockNext) ); // Release our resources. close(this); buffer->release(); return partitions; scanErr: // Release our resources. if ( mediaIsOpen ) close(this); if ( partitions ) partitions->release(); if ( buffer ) buffer->release(); return 0; }
BVRef diskScanGPTBootVolumes(int biosdev, int * countPtr) { _DISK_DEBUG_DUMP("In diskScanGPTBootVolumes(%d)\n", biosdev); void *buffer = malloc(BPS); if (readBytes(biosdev, 1, 0, BPS, buffer) == 0) { int gptID = 1; gpt_ent * gptMap = 0; gpt_hdr * headerMap = buffer; // Partition header signature present? if (memcmp(headerMap->hdr_sig, GPT_HDR_SIG, strlen(GPT_HDR_SIG)) == 0) { UInt32 headerSize = OSSwapLittleToHostInt32(headerMap->hdr_size); // Valid partition header size? if (headerSize >= offsetof(gpt_hdr, padding)) { // No header size overrun (limiting to 512 bytes)? if (headerSize <= BPS) { UInt32 headerCheck = OSSwapLittleToHostInt32(headerMap->hdr_crc_self); headerMap->hdr_crc_self = 0; // Valid partition header checksum? if (crc32(0, headerMap, headerSize) == headerCheck) { UInt64 gptBlock = OSSwapLittleToHostInt64(headerMap->hdr_lba_table); UInt32 gptCount = OSSwapLittleToHostInt32(headerMap->hdr_entries); UInt32 gptSize = OSSwapLittleToHostInt32(headerMap->hdr_entsz); free(buffer); if (gptSize >= sizeof(gpt_ent)) { UInt32 bufferSize = IORound(gptCount * gptSize, BPS); buffer = malloc(bufferSize); // Allocate a buffer. if (readBytes(biosdev, gptBlock, 0, bufferSize, buffer) == 0) { // Allocate a new map for this device and insert it into the chain. struct DiskBVMap *map = malloc(sizeof(*map)); map->biosdev = biosdev; map->bvr = NULL; map->bvrcnt = 0; map->next = gDiskBVMap; gDiskBVMap = map; for (; gptID <= gptCount; gptID++) { gptMap = (gpt_ent *) (buffer + ((gptID - 1) * gptSize)); if (isPartitionUsed(gptMap)) { BVRef bvr = NULL; int bvrFlags = -1; #if DEBUG_DISK char stringuuid[100]; efi_guid_unparse_upper((EFI_GUID*)gptMap->ent_type, stringuuid); printf("Reading GPT partition %d, type %s\n", gptID, stringuuid); sleep(1); #endif if (efi_guid_compare(&GPT_HFS_GUID, (EFI_GUID const *)gptMap->ent_type) == 0) { _DISK_DEBUG_DUMP("Matched: GPT_HFS_GUID\n"); bvrFlags = kBVFlagZero; } /* else if (efi_guid_compare(&GPT_BOOT_GUID, (EFI_GUID const *)gptMap->ent_type) == 0) { _DISK_DEBUG_DUMP("Matched: GPT_BOOT_GUID\n"); bvrFlags = kBVFlagBooter; } */ #if EFI_SYSTEM_PARTITION_SUPPORT else if (efi_guid_compare(&GPT_EFISYS_GUID, (EFI_GUID const *)gptMap->ent_type) == 0) { _DISK_DEBUG_DUMP("Matched: GPT_EFISYS_GUID, probing for HFS format...\n"); //-------------- START ------------- // Allocate buffer for 4 sectors. void * probeBuffer = malloc(2048); bool probeOK = false; // Read the first 4 sectors. if (readBytes(biosdev, gptMap->ent_lba_start, 0, 2048, (void *)probeBuffer) == 0) { // Probing (returns true for HFS partitions). probeOK = HFSProbe(probeBuffer); _DISK_DEBUG_DUMP("HFSProbe status: Is %s a HFS partition.\n", probeOK ? "" : "not"); } free(probeBuffer); // Veto non-HFS partitions to be invalid. if (!probeOK) { continue; } //-------------- END --------------- bvrFlags = kBVFlagEFISystem; } #endif // Only true when we found a usable partition. if (bvrFlags >= 0) { bvr = newGPTBVRef(biosdev, gptID, gptMap->ent_lba_start, gptMap, bvrFlags); if (bvr) { bvr->part_type = FDISK_HFS; bvr->next = map->bvr; map->bvr = bvr; ++map->bvrcnt; // Don't waste time checking for boot.efi on ESP partitions. if ((bvrFlags & kBVFlagEFISystem) == 0) { // Flag System Volumes with kBVFlagSystemVolume. hasBootEFI(bvr); } // True on the initial run only. if (gPlatform.BootVolume == NULL) { // Initialize with the first bootable volume. gPlatform.BootVolume = gPlatform.RootVolume = bvr; _DISK_DEBUG_DUMP("Init B/RootVolume - partition: %d, flags: %d, gptID: %d\n", bvr->part_no, bvr->flags, gptID); } // Bail out after finding the first System Volume. if (bvr->flags & kBVFlagSystemVolume) { _DISK_DEBUG_DUMP("Partition %d is a System Volume\n", gptID); break; } } } } } free(buffer); *countPtr = map->bvrcnt; _DISK_DEBUG_DUMP("map->bvrcnt: %d\n", map->bvrcnt); _DISK_DEBUG_SLEEP(5); return map->bvr; } } } } } } } free(buffer); *countPtr = 0; _DISK_DEBUG_SLEEP(5); return NULL; }
uint32_t fmle32(uint32_t x) { return OSSwapLittleToHostInt32(x); }