Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Get Mac-address with NETBIOS

jaeger0
Beginner
2,561 Views
I'm searching for an unique identification for a machine, so I considered the mac-address.
I used the NEETBIOS function, by calling the command NCBASTAT, to get the mac-address. However, this works only if there is a connection to the network. Is there an alternative way to get the mac-address.
Or are there any unique alternative machine identifiers ?
0 Kudos
8 Replies
onkelhotte
New Contributor II
2,561 Views
Quoting - jaeger0
I'm searching for an unique identification for a machine, so I considered the mac-address.
I used the NEETBIOS function, by calling the command NCBASTAT, to get the mac-address. However, this works only if there is a connection to the network. Is there an alternative way to get the mac-address.
Or are there any unique alternative machine identifiers ?

Search for other threads, one of the latest had a program which gets the MAC Address.

Setting the MAC Address as a unique identifier is not simple. My colleague always used this mechanism to identify a machine. But nowadays you have more than one network adapter in a machine (LAN, WLAN, ISDN, Modems...) and that was (or is) a problem for him.

Markus
0 Kudos
Les_Neilson
Valued Contributor II
2,561 Views
Quoting - jaeger0
I'm searching for an unique identification for a machine, so I considered the mac-address.
I used the NEETBIOS function, by calling the command NCBASTAT, to get the mac-address. However, this works only if there is a connection to the network. Is there an alternative way to get the mac-address.
Or are there any unique alternative machine identifiers ?

If your intention is to prevent pirate copyingof your software, then the general concensus (that I have seen)is that a "home grown" solution will not be good enough. It may deter a casual user but not adetermined effort.

If that is not the problem then, if you tell us what you want to achieve, maybe someone here will be able to help.

Les
0 Kudos
jaeger0
Beginner
2,561 Views
Quoting - Les Neilson

If your intention is to prevent pirate copyingof your software, then the general concensus (that I have seen)is that a "home grown" solution will not be good enough. It may deter a casual user but not adetermined effort.

If that is not the problem then, if you tell us what you want to achieve, maybe someone here will be able to help.

Les
It's a part of a software access. So I think for the purpose of our software, the pirate copy protection is sufficient.
The mac-address, machine identification (for licence checking)is not the main goal. Moreover it is to identify, the machine or data of a specific machine.
0 Kudos
Jugoslav_Dujic
Valued Contributor II
2,561 Views

Quoting - onkelhotte

Search for other threads, one of the latest had a program which gets the MAC Address.


It was:

http://software.intel.com/en-us/forums/showthread.php?t=62485

Also, there was a thread concerning hard disk serial number, which could also be useful:

http://software.intel.com/en-us/forums/showthread.php?t=63845

0 Kudos
jaeger0
Beginner
2,561 Views
Quoting - Jugoslav Dujic

It was:

http://software.intel.com/en-us/forums/showthread.php?t=62485

Also, there was a thread concerning hard disk serial number, which could also be useful:

http://software.intel.com/en-us/forums/showthread.php?t=63845

Thanks, that helped a lot !
0 Kudos
Brian_Francis
Beginner
2,561 Views
Quoting - jaeger0
Quoting - Les Neilson

If your intention is to prevent pirate copyingof your software, then the general concensus (that I have seen)is that a "home grown" solution will not be good enough. It may deter a casual user but not adetermined effort.

If that is not the problem then, if you tell us what you want to achieve, maybe someone here will be able to help.

Les
It's a part of a software access. So I think for the purpose of our software, the pirate copy protection is sufficient.
The mac-address, machine identification (for licence checking)is not the main goal. Moreover it is to identify, the machine or data of a specific machine.

The Windows system identification number (SID) and program identification number (PID)are useful when trying to uniquely identify a Windows machine.Here's some C++ code to get these numbers. Error handling and conversion to Fortran is left as an exercise for the reader... :)

[cpp]#include 
#include 
#include 
#include 
#include 

void id()
{
    // Get the PID (Product Id) string from the registry
    const TCHAR kSubKey[] = _T("SOFTWAREMICROSOFTWindows NTCurrentVersion");
    const TCHAR kValueName[] = _T("DigitalProductId");
    HKEY hKey = NULL;
    if( RegOpenKeyEx(HKEY_LOCAL_MACHINE, kSubKey, 0, KEY_QUERY_VALUE|KEY_WOW64_64KEY, &hKey) == ERROR_SUCCESS )
    {
        DWORD dwType;
        if( RegQueryValueEx(hKey, kValueName, NULL, &dwType, NULL, NULL) == ERROR_SUCCESS )
        {
            if( dwType&(REG_SZ|REG_EXPAND_SZ))
            {
                char sPidStr[1024] = {0};
                DWORD dwSize = sizeof(sPidStr);
                if( RegQueryValueEx(hKey, kValueName, NULL, NULL, (unsigned char *)sPidStr, &dwSize) == ERROR_SUCCESS )
                {
                    sPidStr[dwSize] = 0;
                    // Print PID as string
                    printf("PID=%sn",sPidStr+8);
                    // Or print individual PID components
                    int n = 0;
                    char *context = NULL;
                    char *str = strtok_s(sPidStr+8, "-", &context);
                    while(str)
                    {
                        DWORD dwValue = atol(str);
                        printf("PID[%d]=%dn",n++,dwValue);
                        str = strtok_s(NULL, "-", &context);
                    }
                }
            }
        }
    }
    if (hKey)
        (void)RegCloseKey(hKey);

    // Get the SID (system identification) string
    TCHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
    DWORD ComputerNameLen = sizeof(ComputerName);
    if( GetComputerName(ComputerName, &ComputerNameLen))
    {
        PSID pSid = NULL;
        DWORD SidLen = 0;
        LPTSTR pDomain = NULL;
        DWORD DomainLen = 0;
        SID_NAME_USE AccountType;
        (void)LookupAccountName(NULL,ComputerName,
            pSid,&SidLen,
            pDomain,&DomainLen,
            &AccountType);
        pSid = (PSID)GlobalAlloc(GPTR,SidLen);
        pDomain = (LPTSTR)GlobalAlloc(GPTR,(DomainLen+1)*sizeof(TCHAR));
        if (LookupAccountName(NULL,ComputerName,
            pSid,&SidLen,
            pDomain,&DomainLen,
            &AccountType))
        {
            // Print SID as a string
            LPWSTR pSidStr = NULL;
            if (ConvertSidToStringSid(pSid,&pSidStr))
                wprintf(L"%sn",pSidStr);
            if (pSidStr)
                LocalFree(pSidStr);
            // Or print individual SID components
            if( IsValidSid(pSid))
            {
                DWORD dwValue;
                DWORD dwSubAuthorities;
                DWORD dwCounter;
                dwSubAuthorities = *GetSidSubAuthorityCount(pSid);
                for (dwCounter=0 ; dwCounter < dwSubAuthorities ; dwCounter++)
                {
                    dwValue = *GetSidSubAuthority(pSid, dwCounter) ;
                    printf("SID[%d]=%dn",dwCounter,dwValue);
                }
            }                    
            if (pDomain)
                GlobalFree(pDomain);
            if (pSid)
                GlobalFree(pSid);
        }
    }
}



[/cpp]
0 Kudos
yamajun2
Beginner
2,561 Views
Quoting - Brian Francis

The Windows system identification number (SID) and program identification number (PID)are useful when trying to uniquely identify a Windows machine.Here's some C++ code to get these numbers. Error handling and conversion to Fortran is left as an exercise for the reader... :)



Here is Fortran version without error checks.

[cpp]PROGRAM pid_main
USE ifwin
IMPLICIT NONE
CHARACTER(*), PARAMETER :: kSubKey = "SOFTWAREMICROSOFTWindows NTCurrentVersion"C
CHARACTER(*), PARAMETER :: kValueName = "DigitalProductId"C
INTEGER (HANDLE) :: hKey = NULL
INTEGER (BOOL) :: iret
INTEGER (DWORD):: dwType, dwSize = 1025
CHARACTER (1025) :: sPidStr = ''
INTEGER :: nlen
iret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, kSubKey, 0, IOR(KEY_QUERY_VALUE, KEY_WOW64_64KEY), LOC(hKey) )
iret = RegQueryValueEx(hKey, kValueName, NULL, LOC(dwType), NULL, NULL)
IF ( dwType == IOR(REG_SZ, REG_EXPAND_SZ) ) THEN
iret = RegQueryValueEx( hKey, kValueName, NULL, NULL, LOC(sPidStr), LOC(dwSize) )
nlen = INDEX( sPidStr(9:), ACHAR(0) ) - 1
PRINT *, 'PID=', sPidStr(9:nlen + 8)
ELSE
STOP 'Error: RegQueryValueEx'
END IF
STOP
END PROGRAM pid_main[/cpp]

[cpp]PROGRAM sid_main
USE, INTRINSIC :: ISO_C_BINDING
USE ifwin
IMPLICIT NONE
!
INTERFACE
 INTEGER (BOOL) FUNCTION ConvertSidToStringSid(arg1, arg2) 
  IMPORT
  INTEGER (PVOID), VALUE :: arg1
  INTEGER (PVOID), VALUE :: arg2
 END FUNCTION ConvertSidToStringSid
END INTERFACE
POINTER (ConvertSidToStringSid_PTR, ConvertSidToStringSid)
INTEGER (HANDLE) :: dllhInst
!
CHARACTER (LEN = MAX_COMPUTERNAME_LENGTH + 1) :: ComputerName
INTEGER :: ComputerNameLen = MAX_COMPUTERNAME_LENGTH + 1 
CHARACTER (LEN = 2048) :: Domain=''
INTEGER (BOOL) :: iret
INTEGER (PVOID) :: pSid
INTEGER (LONG) ::  DomainLen, SidLen = 0
CHARACTER (256):: SidStr
INTEGER (LPLONG) :: psidstr
POINTER (pSidStr, SidStr)
INTEGER (ENUM) :: AccountType  
INTEGER :: nlen
!
iret = GetComputerName( ComputerName, LOC(ComputerNameLen) ) 
!PRINT *, 'ComputerName =', ComputerName(1:ComputerNameLen)
iret = LookupAccountName(NULL, ComputerName, NULL, LOC(SidLen), Domain, LOC(DomainLen), LOC(AccountType) ) 
pSid = GlobalAlloc(GPTR, SidLen)
iret = LookupAccountName(NULL, ComputerName, pSid, LOC(SidLen), Domain(1:DomainLen), LOC(DomainLen), LOC(AccountType) )
!PRINT *, 'DOMAIN =', Domain(1:DomainLen)
!
dllhInst = LoadLibrary("Advapi32.dll"C)
ConvertSidToStringSid_PTR = GetProcAddress(dllhInst, "ConvertSidToStringSidA"C)
iret = ConvertSidToStringSid( pSid, LOC(pSidStr) )
!
nlen = INDEX(SidStr, ACHAR(0)) - 1
PRINT *, 'SID=', SidStr(1:nlen) 
iret = LocalFree(pSidStr)
iret = GlobalFree(psid)
STOP
END PROGRAM sid_main[/cpp]

P.S. In the MacAddress code (http://software.intel.com/en-us/forums/showthread.php?t=62485), please replace the DO LOOP as below. The DO LOOP index, which should be i, was 1.
[cpp]DO i = 1, 16   
! PRINT *, AdapterInfo(i)%pNext   
! PRINT *, AdapterInfo(i)%ComboIndex   
! PRINT *, AdapterInfo(i)%AddressLength   
 PRINT '(A)', AdapterInfo(i)%Description(1:INDEX(AdapterInfo(i)%Description(1:128), CHAR(0)))   
 PRINT '(5(Z2.2,"-"), Z2.2)', AdapterInfo(i)%Address(1:AdapterInfo(i)%AddressLength)   
 PRINT '(8A)', AdapterInfo(i)%IpAddressList%IpAddress, AdapterInfo(i)%IpAddressList%IpMask  
 IF (AdapterInfo(i)%pNext == NULL) EXIT   
END DO   
[/cpp]

0 Kudos
allenz
Beginner
2,561 Views
Quoting - Jugoslav Dujic

It was:

http://software.intel.com/en-us/forums/showthread.php?t=62485

Also, there was a thread concerning hard disk serial number, which could also be useful:

http://software.intel.com/en-us/forums/showthread.php?t=63845

Hi,
Thanks for the suggestion and links.......................... :)
0 Kudos
Reply