Page 1 of 1

PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 1:42 pm
by Guimauve
Hello everyone,

I wish to have a native command to get the CPU name. I provide a custom one, maybe it can be used as base to create the native one.

Best regards
Guimauve

Code: Select all

; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; Project name : GetSystemCPUName
; File Name : GetSystemCPUName.pb
; File version: 1.0.1
; Programming : OK
; Programmed by : Progi1984, Dobro, jack, Guimauve
; Date : 20-02-2010
; Last Update : 17-02-2013
; PureBasic code : V5.10
; Platform : Windows, Linux, MacOS X
; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS 
  
  ImportC "/usr/lib/libc.dylib"
    sysctlbyname(s.s,*buffer,*length,*null,*null2)
  EndImport
  
CompilerEndIf

Procedure.s GetSystemCPUName()
  
  CompilerSelect #PB_Compiler_OS
      
    CompilerCase #PB_OS_Linux 
      Protected lProgram.l
      Protected sOutput.s
      lProgram = RunProgram("grep", Chr(34) + "model name" + Chr(34) + " /proc/cpuinfo", "", #PB_Program_Open|#PB_Program_Read)
      If lProgram
        sOutput = ReadProgramString(lProgram)
        sOutput = ReplaceString(sOutput, "model name", "")
        sOutput = ReplaceString(sOutput, ":", "")
        sOutput = Trim(sOutput)
        ProcedureReturn Trim(RemoveString(sOutput, Chr(9)))
      Else
        ProcedureReturn ""
      EndIf
      
    CompilerCase #PB_OS_MacOS 
      Protected *MemBuffer, lMemLength.l = 128, sOutput.s
      *MemBuffer = AllocateMemory(lMemLength)
      If *MemBuffer <> #Null
        sysctlbyname("machdep.cpu.brand_string", *MemBuffer, @lMemLength, 0, 0)
        sOutput.s = PeekS(*MemBuffer)
        FreeMemory(*MemBuffer)
      Else
        sOutput.s = ""
      EndIf
      
      ProcedureReturn sOutput
      
    CompilerCase #PB_OS_Windows
      Protected sSubKey.s, sKeyValue.s, sResult.s
      Protected lKey.l, lResultLen.l
      sSubKey = "HARDWARE\DESCRIPTION\System\CentralProcessor\0"
      sKeyValue = "ProcessorNameString"
      sResult = Space(255)
      lResultLen = 255
      If RegOpenKeyEx_(#HKEY_LOCAL_MACHINE, sSubKey, #Null, #KEY_READ, @lKey) = #ERROR_SUCCESS 
        If lKey
          If RegQueryValueEx_(lKey, sKeyValue, 0, 0, @sResult, @lResultLen) = #ERROR_SUCCESS 
            ProcedureReturn sResult
          EndIf
          RegCloseKey_(lKey) 
        EndIf
      EndIf
      
  CompilerEndSelect
  
EndProcedure

Debug GetSystemCPUName()

; <<<<<<<<<<<<<<<<<<<<<<<
; <<<<< END OF FILE <<<<<
; <<<<<<<<<<<<<<<<<<<<<<<

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 2:28 pm
by davido
Hi Guimauve,

+1

Nice work! Even better as it is cross-platform

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 4:16 pm
by eesau
Thanks, might be useful.

There's a memory leak in your #PB_OS_MacOS code btw...

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 5:00 pm
by Guimauve
eesau wrote:There's a memory leak in your #PB_OS_MacOS code btw...
Corrected, Thanks for your observation.

Best regards
Guimauve

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 5:09 pm
by Falko
Thank you :)

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 6:12 pm
by User_Russian
IMHO, it is better to receive data from the CPU instruction CPUID.

Code: Select all

;Получение информации о процессоре 
 ;Если возвращается nocpuid/cpuidcount значить нет 
 ;поддержки cpuid или нельзя вызвать его нужное кол-во раз 
 ;@return String 
 Procedure.s GetCPUInfo() 
   ;sBuffer - Результирующая строка 
   ;pEAX : pEDX - Указатели на соотв. регистры процессора 
   Protected sBuffer.s, pEAX.l, pEBX.l, pECX.l, pEDX.l 
   
   ;Проверить наличие поддержки CPUID 
   !PUSHFD 
   !POP EAX 
   !MOV EBX, EAX 
   !XOR EAX, $200000 
   !PUSH EAX 
   !POPFD 
   !PUSHFD 
   !POP EAX 
   !XOR EAX, EBX 
   !JE nocpuid 
   
   ;Проверить максимальное разрешенное кол-во вызовов cpuid 
   !XOR EAX, EAX 
   !CPUID 
   !CMP EAX, 4 
   !JB cpuidcounterror 
   
   ;Получить информацию о производителе 
   !MOV eax, $0 
   !CPUID 
   !MOV dword [p.v_pEAX], EAX 
   !MOV dword [p.v_pEBX], EBX 
   !MOV dword [p.v_pECX], ECX 
   !MOV dword [p.v_pEDX], EDX 
   sBuffer = PeekS(@pEBX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pEDX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pECX, 4, #PB_Ascii) 
   sBuffer + ", " 
   
   ;Получить информацию о модели 
   !MOV EAX, $80000002 
   !CPUID 
   !MOV dword[p.v_pEAX], EAX 
   !MOV dword[p.v_pEBX], EBX 
   !MOV dword[p.v_pECX], ECX 
   !MOV dword[p.v_pEDX], EDX 
   sBuffer + PeekS(@pEAX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pEBX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pECX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pEDX, 4, #PB_Ascii) 
   !MOV EAX, $80000003 
   !CPUID 
   !MOV dword[p.v_pEAX], EAX 
   !MOV dword[p.v_pEBX], EBX 
   !MOV dword[p.v_pECX], ECX 
   !MOV dword[p.v_pEDX], EDX 
   sBuffer + PeekS(@pEAX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pEBX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pECX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pEDX, 4, #PB_Ascii) 
   !MOV EAX, $80000004 
   !CPUID 
   !MOV dword[p.v_pEAX], EAX 
   !MOV dword[p.v_pEBX], EBX 
   !MOV dword[p.v_pECX], ECX 
   !MOV dword[p.v_pEDX], EDX 
   sBuffer + PeekS(@pEAX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pEBX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pECX, 4, #PB_Ascii) 
   sBuffer + PeekS(@pEDX, 4, #PB_Ascii) 
   
   ProcedureReturn sBuffer 
   
   !nocpuid: 
   ;Нет поддержки CPUID 
   ProcedureReturn "nocpuid" 
   
   !cpuidcounterror: 
   ;Не доступно необходимое кол-во вызовов CPUID 
   ProcedureReturn "cpuidcount" 
 EndProcedure
 
 Debug GetCPUInfo() 

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 6:48 pm
by Guimauve
@User_Russian

I get an Assembler Error with your code.

Activating the Inline assembler or not in the compiler options don't change anything.

Best regards
Guimauve

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 6:57 pm
by User_Russian
What error message?
Code for x86.
For x64 it must be slightly modified.

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 7:12 pm
by ts-soft
Use this for windows (x86, x64, ASCII and Unicode)

Code: Select all

Procedure.s GetCPUName()
  Protected sBuffer.s
  Protected Zeiger1.l, Zeiger2.l, Zeiger3.l, Zeiger4.l

  !MOV eax, $80000002
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_Zeiger1], EAX ; move eax to the buffer
  !MOV [p.v_Zeiger2], EBX ; move ebx to the buffer
  !MOV [p.v_Zeiger3], ECX ; move ecx to the buffer
  !MOV [p.v_Zeiger4], EDX ; move edx to the buffer

  ;Now move the content of Zeiger (4*4=16 Bytes to a string
  sBuffer = PeekS(@Zeiger1, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger2, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger3, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger4, 4, #PB_Ascii)

  ;Second Part of the Name
  !MOV eax, $80000003
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_Zeiger1], EAX ; move eax to the buffer
  !MOV [p.v_Zeiger2], EBX ; move ebx to the buffer
  !MOV [p.v_Zeiger3], ECX ; move ecx to the buffer
  !MOV [p.v_Zeiger4], EDX ; move edx to the buffer

  ;Now move the content of Zeiger (4*4=16 Bytes to a string
  sBuffer + PeekS(@Zeiger1, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger2, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger3, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger4, 4, #PB_Ascii)


  ;Third Part of the Name
  !MOV eax, $80000004
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_Zeiger1], EAX ; move eax to the buffer
  !MOV [p.v_Zeiger2], EBX ; move ebx to the buffer
  !MOV [p.v_Zeiger3], ECX ; move ecx to the buffer
  !MOV [p.v_Zeiger4], EDX ; move edx to the buffer

  ;Now move the content of Zeiger (4*4=16 Bytes to a string
  sBuffer + PeekS(@Zeiger1, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger2, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger3, 4, #PB_Ascii)
  sBuffer + PeekS(@Zeiger4, 4, #PB_Ascii)

  ProcedureReturn sBuffer
EndProcedure
Debug GetCPUName()

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 7:28 pm
by wilbert
ts-soft wrote:Use this for windows (x86, x64, ASCII and Unicode)
Same approach but a little shorter

Code: Select all

Procedure.s GetCPUName()
  Protected sBuffer.s{48}

  !MOV eax, $80000002
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_sBuffer +  0], EAX ; move eax to the buffer
  !MOV [p.v_sBuffer +  4], EBX ; move ebx to the buffer
  !MOV [p.v_sBuffer +  8], ECX ; move ecx to the buffer
  !MOV [p.v_sBuffer + 12], EDX ; move edx to the buffer

  ;Second Part of the Name
  !MOV eax, $80000003
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_sBuffer + 16], EAX ; move eax to the buffer
  !MOV [p.v_sBuffer + 20], EBX ; move ebx to the buffer
  !MOV [p.v_sBuffer + 24], ECX ; move ecx to the buffer
  !MOV [p.v_sBuffer + 28], EDX ; move edx to the buffer

  ;Third Part of the Name
  !MOV eax, $80000004
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_sBuffer + 32], EAX ; move eax to the buffer
  !MOV [p.v_sBuffer + 36], EBX ; move ebx to the buffer
  !MOV [p.v_sBuffer + 40], ECX ; move ecx to the buffer
  !MOV [p.v_sBuffer + 44], EDX ; move edx to the buffer
  
  CompilerIf #PB_Compiler_Unicode
    ProcedureReturn PeekS(@sBuffer, 48, #PB_Ascii)
  CompilerElse
    ProcedureReturn sBuffer
  CompilerEndIf
EndProcedure

Debug GetCPUName()

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 7:31 pm
by Guimauve
@User_Russian

I don't know I just get Assembler error and an empty MessageRequester() from the compiler. Maybe Fred should have a look to this problem.

@ts_soft

Your code work fine on Linux Mint 14.1 x64 too. Ascii or Unicode.

@wilbert

Your code work fine on Linux Mint 14.1 x64 too and simpler than the ts_soft's one.

Any Mac User can try ts_soft or wilbert codes ?

Best regards
Guimauve

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 7:40 pm
by wilbert
@Guimauve, I am a Mac user. It works fine.

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 7:41 pm
by ts-soft
The only difference is the shortness :wink:
The CompilerIf for Unicode is useless:

Code: Select all

Procedure.s GetCPUName()
  Protected sBuffer.s{48}

  !MOV eax, $80000002
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_sBuffer +  0], EAX ; move eax to the buffer
  !MOV [p.v_sBuffer +  4], EBX ; move ebx to the buffer
  !MOV [p.v_sBuffer +  8], ECX ; move ecx to the buffer
  !MOV [p.v_sBuffer + 12], EDX ; move edx to the buffer

  ;Second Part of the Name
  !MOV eax, $80000003
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_sBuffer + 16], EAX ; move eax to the buffer
  !MOV [p.v_sBuffer + 20], EBX ; move ebx to the buffer
  !MOV [p.v_sBuffer + 24], ECX ; move ecx to the buffer
  !MOV [p.v_sBuffer + 28], EDX ; move edx to the buffer

  ;Third Part of the Name
  !MOV eax, $80000004
  !CPUID
  ; the CPU-Name is now stored in EAX-EBX-ECX-EDX
  !MOV [p.v_sBuffer + 32], EAX ; move eax to the buffer
  !MOV [p.v_sBuffer + 36], EBX ; move ebx to the buffer
  !MOV [p.v_sBuffer + 40], ECX ; move ecx to the buffer
  !MOV [p.v_sBuffer + 44], EDX ; move edx to the buffer
 
  ProcedureReturn PeekS(@sBuffer, 48, #PB_Ascii)
EndProcedure

Debug GetCPUName() 

Re: PureBasic - System - CPUName

Posted: Sun Feb 17, 2013 7:49 pm
by Guimauve
wilbert wrote:@Guimauve, I am a Mac user. It works fine.
So to make a long story short : The wilbert's code work on Windows x86, x86_64, Linux x86_64 and Mac OS.

Fred, you don't have any excuse, this command has to be added in PB 5.20. :wink:

Best regards
Guimauve