Q: All ROM-in-RAM (New World) Macs
return 406 (decimal) as their machine ID from
Gestalt . How do I determine which Mac
my software is running on in this case?
A: You will have to query the Name
Registry to get this information.
IMPORTANT:
Do not attempt to infer if a
feature exists by checking the machine ID. Use the
Name Registry or Gestalt to determine
if a specific feature exists. If checking the
machine ID is the only way to determine if a
specific feature exists, file a bug report with
us so that we can fix
that.
|
You can get the Mac's non-localized
name from the compatible property. The
value is an array of C-style strings, and the name
is the first entry of the property's value.
The compatible property is found at
the path "Devices:device-tree". For the
1999 Power Macintosh G3 this value is
"PowerMac1,1". For the iMac this value is
"iMac,1".
Note:
This string is not meant to be shown
to the user. It is not localized. Do not show this
string to the user.
|
Because these strings are not localized,
you can easily test them; just don't show them
to the user.
Note:
Currently, all iMacs have the same
compatible property value: "iMac,1".
|
To tell the difference between the
original iMac with the Rage II video chip and the
second revision of the iMac with the Rage Pro video
chip, you can look for a Name Registry node of
"Devices:device-tree:pci:ATY,RageIIC_C"
or
"Devices:device-tree:pci:ATY,RagePro_C",
respectively. You can also search for a node with a
name property of
"ATY,RageIIC_C" or
"ATY,RagePro_C", respectively. Either
method will work with equal effectiveness.
To tell the difference between the 233MHz
iMac with a Rage Pro video chip and the 266MHz iMac
(which also has a Rage Pro video chip), you will
need to check the clock-frequency
property in the CPU node. The best way to do this
is to search for a node with a
device_type property with the value of
"cpu\0" (the null terminator of the C
string needs to be passed; it is part of the
property's value). Once you have found the
node with the CPU value, you can get the value of
the clock-frequency property which is
in the same node. You cannot just search for
"clock-frequency" because there are many
"clock-frequency" entries in the Name
Registry and you are not guaranteed that the
"clock-frequency" value you get is the
one from the CPU node.
Important: I hope that the above serves to
show how strongly we suggest that you do not
try to identify specific Macs. Instead you should
look for specific features (via
Gestalt , or some other means) that you
need, such as FireWire or USB, rather than assuming
that they are present based solely on the model of
the computer.
You should always check for what you want,
rather than assume a specific machine always has
the feature you want. If you believe that you
cannot check for a specific feature and are
therefore relying on the machine ID, please
file a bug with us so that we
can have a selector added.
/* GetMacName returns a Pascal-formatted string with the model property string.
* Input macName - pointer to a buffer where the model property name
* will be returned, if the call succeeds
*
* Output function result - noErr indicates that the model name was
* read successfully
* macName - will contain the model name property if noErr
*
* Notes:
* Caller is responsible for disposing of macName. Use DisposePtr.
*/
OSStatus GetMacName (StringPtr * macName) {
OSStatus err = noErr;
RegEntryID compatibleEntry;
RegPropertyValueSize length;
RegCStrEntryNamePtr compatibleValue;
if (macName != nil) {
*macName = 0;
err = RegistryEntryIDInit (&compatibleEntry);
if (err == noErr) {
err = RegistryCStrEntryLookup (nil, "Devices:device-tree",
&compatibleEntry);
}
if (err == noErr) {
err = RegistryPropertyGetSize (&compatibleEntry,
"compatible", &length);
}
if (err == noErr) {
compatibleValue = (RegCStrEntryNamePtr)NewPtr (length);
err = MemError ();
}
if (err == noErr) {
err = RegistryPropertyGet (&compatibleEntry,
"compatible", compatibleValue,
&length);
}
if (err == noErr) {
SetPtrSize (compatibleValue, strlen (compatibleValue) + 1);
/* SetPtrSize shouldn't fail because we are shrinking the pointer,
but make sure. */
err = MemError ();
}
if (err == noErr) {
*macName = c2pstr (compatibleValue);
}
(void)RegistryEntryIDDispose (&compatibleEntry);
}
return err;
}
/* GetMacSpeed returns the clock-frequency property of the CPU
* Output function result - noErr indicates that the CPU clock-frequency
* property was read successfully
* cpuFreq - will contain the clock-frequency property if noErr
* set to 0 if the clock-frequency could not be read
*/
OSStatus GetMacSpeed (UInt32 * cpuFreq) {
OSStatus err = noErr;
RegEntryID cpuEntry;
RegEntryIter cookie = nil;
RegEntryIterationOp iterOp = kRegIterDescendants;
unsigned long cpuSpeedSize = sizeof (unsigned long);
char * cpuValue = "cpu";
Boolean done;
if (cpuFreq != nil) {
*cpuFreq = 0;
} else {
cpuSpeedSize = 0;
}
if (err == noErr) {
err = RegistryEntryIDInit (&cpuEntry);
}
if (err == noErr) {
err = RegistryEntryIterateCreate (&cookie);
}
if (err == noErr) {
err = RegistryEntrySearch (&cookie, iterOp,
&cpuEntry, &done, "device_type",
cpuValue, strlen (cpuValue) + 1);
if (done != true && err == noErr) {
(void)RegistryPropertyGet (&cpuEntry,
"clock-frequency", cpuFreq, &cpuSpeedSize);
}
}
(void)RegistryEntryIDDispose (&cpuEntry);
(void)RegistryEntryIterateDispose (&cookie);
return err;
}
|
This is some sample code that shows how to query
the Name Registry for the name and clock frequency
values.
|