UInt32 pGetUnicodeHostname(UInt32 cbBuffer, UInt8* lpBuffer) { CFStringRef cfsName; UInt32 cbRequired; SInt32 osVersion; cfsName = CSCopyMachineName (); if (NULL == cfsName) { return 0; } cbRequired = (((CFStringGetLength(cfsName) + 1) * 2 > cbBuffer) ? cbBuffer : (CFStringGetLength(cfsName) + 1) * 2); memset(lpBuffer, 0, cbRequired); if (Gestalt(gestaltSystemVersion, &osVersion) == noErr) { if ( osVersion >= 0x1040 ) { #if MAC_OS_X_VERSION_10_4 <= MAC_OS_X_VERSION_MAX_ALLOWED CFStringGetCString ( cfsName, (char *)lpBuffer, cbBuffer, kCFStringEncodingUTF16BE ); #endif } else { CFStringGetCString ( cfsName, (char *)lpBuffer, cbBuffer, kCFStringEncodingUnicode ); } } CFRelease(cfsName); return cbRequired; }
// return a unique config string for this computer void get_unique_config_string(char* pszCString, int nSize) { CFStringRef strs[3]; CFStringRef SerialNumber; CFStringRef MachineName; CFStringRef Full; CFArrayRef ArrayStrings; CopySerialNumber(&SerialNumber); MachineName = CSCopyMachineName(); strs[0] = CFSTR(APPLE_DRIVER_PREFIX); strs[1] = SerialNumber; strs[2] = MachineName; ArrayStrings = CFArrayCreate(NULL, (void *)strs, numberof(strs), &kCFTypeArrayCallBacks); Full = CFStringCreateByCombiningStrings(NULL, ArrayStrings, CFSTR(" ")); CFStringGetCString(Full, pszCString, nSize, kCFStringEncodingUTF8); CFRelease(SerialNumber); CFRelease(MachineName); CFRelease(Full); }
PsychError SCREENComputer(void) { const char *majorStructFieldNames[]={"macintosh", "windows", "osx" ,"linux", "kern", "hw", "processUserLongName", "processUserShortName", "consoleUserName", "machineName", "localHostName", "location", "MACAddress", "system" }; const char *kernStructFieldNames[]={"ostype", "osrelease", "osrevision", "version","hostname"}; const char *hwStructFieldNames[]={"machine", "model", "ncpu", "physmem", "usermem", "busfreq", "cpufreq"}; int numMajorStructDimensions=1, numKernStructDimensions=1, numHwStructDimensions=1; int numMajorStructFieldNames=14, numKernStructFieldNames=5, numHwStructFieldNames=7; PsychGenericScriptType *kernStruct, *hwStruct, *majorStruct; //char tempStr[CTL_MAXNAME]; //this seems like a bug in Darwin, CTL_MAXNAME is shorter than the longest name. char tempStr[256], *ethernetMACStr; size_t tempIntSize, tempStrSize, tempULongIntSize; int mib[2]; int tempInt; unsigned long int tempULongInt; char *tempStrPtr; CFStringRef tempCFStringRef; psych_bool stringSuccess; int stringLengthChars, ethernetMACStrSizeBytes; long gestaltResult; OSErr gestaltError; // Str255 systemVersionStr, systemVersionStrForward; int i,strIndex, bcdDigit, lengthSystemVersionString; long osMajor, osMinor, osBugfix; char systemVersionStr[256]; //all subfunctions should have these two lines PsychPushHelp(useString, synopsisString, seeAlsoString); if(PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; PsychErrorExit(PsychCapNumOutputArgs(1)); PsychErrorExit(PsychCapNumInputArgs(0)); //fill the major struct PsychAllocOutStructArray(1, FALSE, numMajorStructDimensions, numMajorStructFieldNames, majorStructFieldNames, &majorStruct); PsychSetStructArrayDoubleElement("macintosh", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("windows", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("linux", 0, 0, majorStruct); PsychSetStructArrayDoubleElement("osx", 0, 1, majorStruct); //fill the kern struct and implant it within the major struct PsychAllocOutStructArray(-1, FALSE, numKernStructDimensions, numKernStructFieldNames, kernStructFieldNames, &kernStruct); mib[0]=CTL_KERN; mib[1]=KERN_OSTYPE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("ostype", 0, tempStr, kernStruct); mib[1]=KERN_OSRELEASE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("osrelease", 0, tempStr, kernStruct); mib[1]=KERN_OSREV; tempIntSize=sizeof(tempInt); ReportSysctlError(sysctl(mib, 2, &tempInt, &tempIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("osrevision", 0, (double)tempInt, kernStruct); mib[1]=KERN_VERSION; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("version", 0, tempStr, kernStruct); mib[1]=KERN_HOSTNAME; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("hostname", 0, tempStr, kernStruct); PsychSetStructArrayStructElement("kern",0, kernStruct, majorStruct); //fill the hw struct and implant it within the major struct PsychAllocOutStructArray(-1, FALSE, numHwStructDimensions, numHwStructFieldNames, hwStructFieldNames, &hwStruct); mib[0]=CTL_HW; mib[1]=HW_MACHINE; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("machine", 0, tempStr, hwStruct); mib[1]=HW_MODEL; tempStrSize=sizeof(tempStr); ReportSysctlError(sysctl(mib, 2, tempStr, &tempStrSize, NULL, 0)); PsychSetStructArrayStringElement("model", 0, tempStr, hwStruct); mib[1]=HW_NCPU; tempIntSize=sizeof(tempInt); ReportSysctlError(sysctl(mib, 2, &tempInt, &tempIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("ncpu", 0, (double)tempInt, hwStruct); mib[1]=HW_MEMSIZE; long long tempLongInt; tempULongIntSize=sizeof(tempLongInt); ReportSysctlError(sysctl(mib, 2, &tempLongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("physmem", 0, (double)tempLongInt, hwStruct); mib[1]=HW_USERMEM; tempULongIntSize=sizeof(tempULongInt); ReportSysctlError(sysctl(mib, 2, &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("usermem", 0, (double)tempULongInt, hwStruct); mib[1]=HW_BUS_FREQ; tempULongIntSize=sizeof(tempULongInt); ReportSysctlError(sysctl(mib, 2, &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("busfreq", 0, (double)tempULongInt, hwStruct); mib[1]=HW_CPU_FREQ; tempULongIntSize=sizeof(tempULongInt); ReportSysctlError(sysctl(mib, 2, &tempULongInt, &tempULongIntSize, NULL, 0)); PsychSetStructArrayDoubleElement("cpufreq", 0, (double)tempULongInt, hwStruct); PsychSetStructArrayStructElement("hw",0, hwStruct, majorStruct); //fill in the process user, console user and machine name in the root struct. tempCFStringRef= CSCopyMachineName(); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("machineName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("machineName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("machineName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= CSCopyUserName(TRUE); //use short name if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("processUserShortName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("processUserShortName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("processUserShortName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= CSCopyUserName(FALSE); //use long name if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("processUserLongName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("processUserLongName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("processUserLongName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyConsoleUser(NULL, NULL, NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("consoleUserName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("consoleUserName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("consoleUserName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyLocalHostName(NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("localHostName", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("localHostName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("localHostName", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } tempCFStringRef= SCDynamicStoreCopyLocation(NULL); if (tempCFStringRef) { stringLengthChars=(int) CFStringGetMaximumSizeForEncoding(CFStringGetLength(tempCFStringRef), kCFStringEncodingUTF8); tempStrPtr=malloc(sizeof(char) * (stringLengthChars+1)); stringSuccess= CFStringGetCString(tempCFStringRef, tempStrPtr, stringLengthChars+1, kCFStringEncodingUTF8); if(stringSuccess) { PsychSetStructArrayStringElement("location", 0, tempStrPtr, majorStruct); } else { PsychSetStructArrayStringElement("location", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } free(tempStrPtr); CFRelease(tempCFStringRef); } else { PsychSetStructArrayStringElement("location", 0, "UNKNOWN! QUERY FAILED DUE TO EMPTY OR PROBLEMATIC NAME.", majorStruct); } //Add the ethernet MAC address of the primary ethernet interface to the stuct. This can serve as a unique identifier for the computer. ethernetMACStrSizeBytes=GetPrimaryEthernetAddressStringLengthBytes(TRUE)+1; ethernetMACStr=(char*) malloc(sizeof(char) * ethernetMACStrSizeBytes); GetPrimaryEthernetAddressString(ethernetMACStr, TRUE, TRUE); PsychSetStructArrayStringElement("MACAddress", 0, ethernetMACStr, majorStruct); free(ethernetMACStr); //Add the system version string: Gestalt(gestaltSystemVersionMajor, &osMajor); Gestalt(gestaltSystemVersionMinor, &osMinor); Gestalt(gestaltSystemVersionBugFix, &osBugfix); sprintf(systemVersionStr, "Mac OS %i.%i.%i", osMajor, osMinor, osBugfix); //embed it in the return struct PsychSetStructArrayStringElement("system", 0, systemVersionStr, majorStruct); /* OLD DEAD Implementation, left for now as a reference... //Add the system version string: gestaltError=Gestalt(gestaltSystemVersion, &gestaltResult); //The result is a four-digit value stored in BCD in the lower 16-bits of the result. There are implicit decimal // points between the last three digis. For example Mac OS 10.3.6 is: // // 0000 0000 0000 0000 0001 0000 0011 0110 // 1 0 3 6 // 1 0. 3. 6 strIndex=0; //4th digit. bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //decimal point strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%s", "."); //3rd digit bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //decimal point strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%s", "."); //second digit //2nd digit. bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //1st digit bcdDigit=gestaltResult & 15; gestaltResult= gestaltResult>>4; strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%i", bcdDigit); //preface with "Mac OS " strIndex=strIndex+sprintf(systemVersionStr+strIndex, "%s", " SO caM"); //reverse to make it forward lengthSystemVersionString=strlen(systemVersionStr); for(i=0;i<lengthSystemVersionString;i++){ systemVersionStrForward[lengthSystemVersionString-1-i]=systemVersionStr[i]; } systemVersionStrForward[lengthSystemVersionString]='\0'; //embed it in the return struct PsychSetStructArrayStringElement("system", 0, systemVersionStrForward, majorStruct); */ return(PsychError_none); }