Ejemplo n.º 1
0
int main(int argc, char * argv[])
{
	mach_port_t		masterPort;
    io_service_t	service = MACH_PORT_NULL;
	CFDataRef		dataRef;

	UInt16 maxStructureSize, structureCount = 0;
	UInt16 tableLength = 0, droppedTables = 0;
	UInt16 newTableLength = 0;

	// UInt32 * shadowTableData = NULL;

	IOMasterPort(MACH_PORT_NULL, &masterPort);
	service = IOServiceGetMatchingService(masterPort, IOServiceMatching("AppleSMBIOS"));

    if (service)
	{
#if DEBUG
		printf("\nHave AppleSMBIOS\n");
#endif
		dataRef = (CFDataRef) IORegistryEntryCreateCFProperty(service, 
															  CFSTR("SMBIOS-EPS"), 
															  kCFAllocatorDefault, 
															  kNilOptions);

		if (dataRef)
		{
			// We could use isA_CFData(dataRef) {} here, but that would force us to include 
			// another file, which in my opinion would be overkill (dataRef should always be there).
#if DEBUG
			printf("Have SMBIOS-EPS dataRef\n\n");
#endif
			struct SMBEntryPoint * eps = (struct SMBEntryPoint *) CFDataGetBytePtr(dataRef);
			tableLength = eps->dmi.tableLength;

			/* shadowTableData = malloc(tableLength);
			bzero(shadowTableData, tableLength);
			bcopy((void *)(unsigned int)eps->dmi.tableAddress, shadowTableData, tableLength); */
#if DEBUG
			// _SM_ 
			eps->anchor[4] = 0; // Prevent garbage output.
			printf("eps.anchor            : %s\n", eps->anchor);
			printf("eps.checksum          : 0x02%x\n", eps->checksum);
			printf("eps.entryPointLength  : 0x%x\n", eps->entryPointLength);
			printf("eps.majorVersion      : 0x%02x\n", eps->majorVersion);
			printf("eps.minorVersion      : 0x%02x\n", eps->minorVersion);
#endif
			maxStructureSize = eps->maxStructureSize;
#if DEBUG
			printf("eps.maxStructureSize  : 0x%04x\n", maxStructureSize);
			printf("eps.entryPointRevision: 0x%02x\n", eps->entryPointRevision);
			printf("eps.formattedArea     : %s\n\n", eps->formattedArea);

			// _DMI_
			eps->dmi.anchor[5] = 0; // Prevent garbage output.
			printf("eps.dmi.anchor        : %s\n", eps->dmi.anchor);
			printf("eps.dmi.checksum      : 0x%02x\n", eps->dmi.checksum);
			printf("eps.dmi.tableLength   : 0x%04x\n", tableLength); // eps->dmi.tableLength);
			printf("eps.dmi.tableAddress  : 0x%08x\n", (unsigned int)eps->dmi.tableAddress);
#endif
			structureCount = eps->dmi.structureCount;
#if DEBUG
			printf("eps.dmi.structureCount: 0x%04x\n", structureCount);
			printf("eps.dmi.bcdRevision   : 0x%x\n", eps->dmi.bcdRevision);
#endif
			// Done with dataRef / release it.
			CFRelease(dataRef);
		}
#if DEBUG			
		printf("\n");
#endif

		dataRef = (CFDataRef) IORegistryEntryCreateCFProperty(service, 
															  CFSTR("SMBIOS"), 
															  kCFAllocatorDefault, 
															  kNilOptions);

		if (dataRef)
		{
			// We could use isA_CFData(dataRef) {} here, but that would force us to include another
			// header file, which in my opinion would be overkill as dataRef should always be there.
#if DEBUG
			printf("Have SMBIOS dataRef\n");
#endif
			UInt32 * tableData = (UInt32 *) CFDataGetBytePtr(dataRef);

#if VERBOSE
			UInt16 numBytes = (int) CFDataGetLength(dataRef);
			printf("\nNumber of bytes: %d (Original SMBIOS table)\n", numBytes);
#endif

			SMBStructHeader * header;
			const UInt8 * tablePtr = (const UInt8 *) tableData;
			const UInt8 * tableEndPtr  = tablePtr + tableLength;
			const UInt8 * tableStructureStart = 0;
			const UInt8 * droppedTableStructureStart = 0;
			const UInt8 * tableBuffer = malloc(tableLength);

			// int index				= 0;
			int maxStructureSize	= 0;
			int newStructureCount	= 0;
			int structureLength		= 0;

			SMBWord newHandle = 0;

			bzero((void *)tableBuffer, sizeof(tableBuffer));

			while (structureCount-- && (tableEndPtr > tablePtr + sizeof(SMBStructHeader)))
			{
				droppedTableStructureStart = tableStructureStart = 0;

				header = (SMBStructHeader *) tablePtr;

				if (header->length > tableEndPtr - tablePtr)
				{
					break;
				}
				
				switch (header->type)
				{
					case kSMBTypeBIOSInformation:		// Type 0
					case kSMBTypeSystemInformation:		// Type 1
					case kSMBTypeBaseBoard:				// Type 2
					case kSMBTypeProcessorInformation:	// Type 4
					// case kSMBTypeMemoryModule:		// Type 6
					// case kSMBTypeSystemSlot:			// Type 9
					case kSMBTypePhysicalMemoryArray:	// Type 16
					case kSMBTypeMemoryDevice:			// Type 17
					case kSMBTypeEndOfTable:			// Type 127
					case kSMBTypeFirmwareVolume:		// Type 128
					case kSMBTypeMemorySPD:				// Type 130
					case kSMBTypeOemProcessorType:		// Type 131
					case kSMBTypeOemProcessorBusSpeed:	// Type 132

						newStructureCount++;
						tableStructureStart = tablePtr;
						header->handle = newHandle++;
						// printf("type: %d, handle: %d\n", header->type, header->handle);
						break;

					default:
						droppedTables++;
						droppedTableStructureStart = tablePtr;
				}
				
				VERBOSE_DUMP("Table: %3d %37s  @%p  Formatted area: %2d bytes  ", header->type, tableDescriptions[header->type], tablePtr, header->length);

				// Skip the formatted area of the structure.
				tablePtr += header->length;
				
				// Skip the unformatted structure area at the end (strings).
				for (; tableEndPtr > tablePtr + sizeof(SMBStructHeader); tablePtr++)
				{
					// Look for a terminating double NULL.
					if (tablePtr[0] == 0 && tablePtr[1] == 0)
					{
						tablePtr += 2;
						break;
					}
				}
				
				if (tableStructureStart)
				{
					structureLength = tablePtr - tableStructureStart;

					VERBOSE_DUMP("Structure length: %3d bytes.\n", structureLength);

					bcopy((void *)tableStructureStart, (void *)tableBuffer + newTableLength, structureLength);
					newTableLength += structureLength;
					
					// Taking care of eps->maxStructureSize
					if (maxStructureSize < structureLength)
					{
						maxStructureSize = structureLength;
					}
				}
				else if (droppedTableStructureStart)
				{
					structureLength = tablePtr - droppedTableStructureStart;
					VERBOSE_DUMP("Structure length: %3d bytes (dropped).\n", structureLength);
				}
			}
			
			VERBOSE_DUMP("\nDropped tables: %2d.\n", droppedTables);

			dumpStaticTableData(tableBuffer, maxStructureSize, newStructureCount, newTableLength);

			free((void *)tableBuffer);

			// Done with dataRef / release it.
			CFRelease(dataRef);
		}

		// Done with the service / release it.
		IOObjectRelease(service);
    }

	exit(0);
}
Ejemplo n.º 2
0
int main(int argc, char * argv[])
{
	char dirspec[128];
	int filedesc = 0;
	struct stat my_sb;

	if (argc == 2)
	{
		uid_t real_uid	= getuid();
		uid_t euid		= geteuid();

#if DEBUG
		printf("UID: %u EUID: %u\n", real_uid, euid);
#endif
		// Under sudo, getuid and geteuid return 0.
		if (real_uid != 0 || euid != 0)
		{
			printf("Error: Not root. Use sudo ./smbios2struct4 [filename without extension]\n");

			exit (-1);
		}
	}

	mach_port_t		masterPort;
    io_service_t	service = MACH_PORT_NULL;
	CFDataRef		dataRef;

	UInt16 maxStructureSize, structureCount = 0;
	UInt16 tableLength = 0, droppedTables = 0;
	UInt16 newTableLength = 0;

	IOMasterPort(MACH_PORT_NULL, &masterPort);

	//==================================================================================

	io_registry_entry_t efi = IORegistryEntryFromPath(kIOMasterPortDefault, kIODeviceTreePlane ":/efi");

	if (efi == IO_OBJECT_NULL)
	{
#if DEBUG
		printf("FAILURE: Unable to locate EFI registry entry.\n");
#endif
		exit(-1);
	}
	else
	{
#if DEBUG
		printf("OK\n");
#endif
		dataRef = (CFDataRef) IORegistryEntryCreateCFProperty(efi, CFSTR("device-properties"), kCFAllocatorDefault, kNilOptions);

		if (dataRef)
		{
			UInt32 * deviceProperties = (UInt32 *) CFDataGetBytePtr(dataRef);
			UInt16 devicePropertiesBytes = (int) CFDataGetLength(dataRef);
#if DEBUG
			printf("Property 'device-properties' %d bytes found.", numBytes);
#endif
			if ((argc == 2) && (devicePropertiesBytes)) // Write to file?
			{
				// Sanity check for required directory.
				if (stat("/Extra", &my_sb) != 0)
				{
					mkdir("/Extra", (S_IRWXU | S_IRWXG | S_IRWXO));
				}
				// Sanity check for required directory.
				if (stat("/Extra/EFI", &my_sb) != 0)
				{
					mkdir("/Extra/EFI", (S_IRWXU | S_IRWXG | S_IRWXO));
				}
				
				sprintf (dirspec, "/Extra/EFI/%s.bin", argv[1]);
				filedesc = open(dirspec, O_WRONLY|O_CREAT|O_TRUNC, 0644);
				
				if (filedesc == -1)
				{
					printf("Error: Unable to open file!\n");
				}
				else
				{
					int status = write(filedesc, deviceProperties, devicePropertiesBytes);
					
					if (status != devicePropertiesBytes)
					{
						printf("status %d, saved %d bytes\n", status, devicePropertiesBytes);
					}
					else
					{
						printf("%d bytes written to: %s\n", devicePropertiesBytes, dirspec);
					}
				}
				
				close (filedesc);
			}
		}
#if DEBUG
		else
		{
			printf("FAILURE: Unable to locate ':/efi/device-properties'\n");
		}
#endif
	}

	//==================================================================================

	service = IOServiceGetMatchingService(masterPort, IOServiceMatching("AppleSMBIOS"));

    if (service)
	{
#if DEBUG
		printf("\nAppleSMBIOS found\n");
#endif
		dataRef = (CFDataRef) IORegistryEntryCreateCFProperty(service, CFSTR("SMBIOS-EPS"), kCFAllocatorDefault, kNilOptions);

		if (dataRef)
		{
			// We could use isA_CFData(dataRef) {} here, but that would force us to include 
			// another file, which in my opinion would be overkill (dataRef should always be there).
#if DEBUG
			printf("Have SMBIOS-EPS dataRef\n\n");
#endif
			struct SMBEntryPoint * eps = (struct SMBEntryPoint *) CFDataGetBytePtr(dataRef);
			tableLength = eps->dmi.tableLength;

			/* shadowTableData = malloc(tableLength);
			bzero(shadowTableData, tableLength);
			bcopy((void *)(unsigned int)eps->dmi.tableAddress, shadowTableData, tableLength); */
#if DEBUG
			// _SM_ 
			eps->anchor[4] = 0; // Prevent garbage output.
			printf("eps.anchor            : %s\n", eps->anchor);
			printf("eps.checksum          : 0x02%x\n", eps->checksum);
			printf("eps.entryPointLength  : 0x%x\n", eps->entryPointLength);
			printf("eps.majorVersion      : 0x%02x\n", eps->majorVersion);
			printf("eps.minorVersion      : 0x%02x\n", eps->minorVersion);
#endif
			maxStructureSize = eps->maxStructureSize;
#if DEBUG
			printf("eps.maxStructureSize  : 0x%04x\n", maxStructureSize);
			printf("eps.entryPointRevision: 0x%02x\n", eps->entryPointRevision);
			printf("eps.formattedArea     : %s\n\n", eps->formattedArea);

			// _DMI_
			eps->dmi.anchor[5] = 0; // Prevent garbage output.
			printf("eps.dmi.anchor        : %s\n", eps->dmi.anchor);
			printf("eps.dmi.checksum      : 0x%02x\n", eps->dmi.checksum);
			printf("eps.dmi.tableLength   : 0x%04x\n", tableLength); // eps->dmi.tableLength);
			printf("eps.dmi.tableAddress  : 0x%08x\n", (unsigned int)eps->dmi.tableAddress);
#endif
			structureCount = eps->dmi.structureCount;
#if DEBUG
			printf("eps.dmi.structureCount: 0x%04x\n", structureCount);
			printf("eps.dmi.bcdRevision   : 0x%x\n", eps->dmi.bcdRevision);
#endif
			// Done with dataRef / release it.
			CFRelease(dataRef);
		}
#if DEBUG			
		printf("\n");
#endif

		dataRef = (CFDataRef) IORegistryEntryCreateCFProperty(service, CFSTR("SMBIOS"), kCFAllocatorDefault, kNilOptions);

		if (dataRef)
		{
			// We could use isA_CFData(dataRef) {} here, but that would force us to include another
			// header file, which in my opinion would be overkill as dataRef should always be there.
#if DEBUG
			printf("Have SMBIOS dataRef\n");
#endif
			UInt32 * tableData = (UInt32 *) CFDataGetBytePtr(dataRef);

#if VERBOSE
			UInt16 numBytes = (int) CFDataGetLength(dataRef);
			printf("\nNumber of bytes: %d (Original SMBIOS table)\n", numBytes);
#endif

			SMBStructHeader * header;
			const UInt8 * tablePtr = (const UInt8 *) tableData;
			const UInt8 * tableEndPtr  = tablePtr + tableLength;
			const UInt8 * tableStructureStart = 0;
			const UInt8 * droppedTableStructureStart = 0;
			const UInt8 * tableBuffer = malloc(tableLength);

			// int index				= 0;
			int maxStructureSize	= 0;
			int newStructureCount	= 0;
			int structureLength		= 0;

			SMBWord newHandle = 0;

			bzero((void *)tableBuffer, sizeof(tableBuffer));

			while (structureCount-- && (tableEndPtr > tablePtr + sizeof(SMBStructHeader)))
			{
				droppedTableStructureStart = tableStructureStart = 0;

				header = (SMBStructHeader *) tablePtr;

				if (header->length > tableEndPtr - tablePtr)
				{
					break;
				}
				
				switch (header->type)
				{
					case kSMBTypeBIOSInformation:		// Type 0
					case kSMBTypeSystemInformation:		// Type 1
					case kSMBTypeBaseBoard:				// Type 2
					case kSMBTypeProcessorInformation:	// Type 4
					// case kSMBTypeMemoryModule:		// Type 6
					// case kSMBTypeSystemSlot:			// Type 9
					case kSMBTypePhysicalMemoryArray:	// Type 16
					case kSMBTypeMemoryDevice:			// Type 17
					case kSMBTypeEndOfTable:			// Type 127
					case kSMBTypeFirmwareVolume:		// Type 128
					case kSMBTypeMemorySPD:				// Type 130
					case kSMBTypeOemProcessorType:		// Type 131
					case kSMBTypeOemProcessorBusSpeed:	// Type 132

						newStructureCount++;
						tableStructureStart = tablePtr;
						header->handle = newHandle++;
						// printf("type: %d, handle: %d\n", header->type, header->handle);
						break;

					default:
						droppedTables++;
						droppedTableStructureStart = tablePtr;
				}
				
				VERBOSE_DUMP("Table: %3d %37s  @%p  Formatted area: %2d bytes  ", header->type, tableDescriptions[header->type], tablePtr, header->length);

				// Skip the formatted area of the structure.
				tablePtr += header->length;
				
				// Skip the unformatted structure area at the end (strings).
				for (; tableEndPtr > tablePtr + sizeof(SMBStructHeader); tablePtr++)
				{
					// Look for a terminating double NULL.
					if (tablePtr[0] == 0 && tablePtr[1] == 0)
					{
						tablePtr += 2;
						break;
					}
				}
				
				if (tableStructureStart)
				{
					structureLength = tablePtr - tableStructureStart;

					VERBOSE_DUMP("Structure length: %3d bytes.\n", structureLength);

					bcopy((void *)tableStructureStart, (void *)tableBuffer + newTableLength, structureLength);
					newTableLength += structureLength;
					
					// Taking care of eps->maxStructureSize
					if (maxStructureSize < structureLength)
					{
						maxStructureSize = structureLength;
					}
				}
				else if (droppedTableStructureStart)
				{
					structureLength = tablePtr - droppedTableStructureStart;
					VERBOSE_DUMP("Structure length: %3d bytes (dropped).\n", structureLength);
				}
			}
			
			VERBOSE_DUMP("\nDropped tables: %2d.\n", droppedTables);

			if (argc == 2) // Write to file?
			{
				// Sanity check for required directory.
				if (stat("/Extra/SMBIOS", &my_sb) != 0)
				{
					mkdir("/Extra/SMBIOS", (S_IRWXU | S_IRWXG | S_IRWXO));
				}

				sprintf (dirspec, "/Extra/SMBIOS/%s.bin", argv[1]);
				filedesc = open(dirspec, O_WRONLY|O_CREAT|O_TRUNC, 0644);

				if (filedesc == -1)
				{
					printf("Error: Unable to open file!\n");
				}
				else
				{
					newTableLength = round2((newTableLength + 2), 4);

					VERBOSE_DUMP("newTableLength: %d\n", newTableLength);

					int status = write(filedesc, tableBuffer, newTableLength);

					if (status != newTableLength)
					{
						printf("status %d, saved %d bytes\n", status, newTableLength);
					}
					else
					{
						printf("%d bytes written to: %s\n", newTableLength, dirspec);
					}
				}

				close (filedesc);
			}
			else
			{
				dumpStaticTableData(tableBuffer, maxStructureSize, newStructureCount, newTableLength);
			}

			free((void *)tableBuffer);

			// Done with dataRef / release it.
			CFRelease(dataRef);
		}

		// Done with the service / release it.
		IOObjectRelease(service);
    }

	exit(0);
}