Get MAC address

by Maurits van Rijnen

Every network adapter has a unique id: the MAC address. The MAC address may be used to identify a computer, at least for a while until its network adapter is replaced or until someone decides to flash a new MAC address into the adapter. Also, be carefull if the computer has more than one network adapter.
To read the MAC address you should read the ARP cache, but that's very complicated. Let's forget about the ARP cache.
Maurits found a neat "workaround" based on UuidCreate:
UuidCreate creates a new universally unique identifier, which can be used for creating new ActiveX controls and so on. Because it has to be universally unique it is based on a MAC address and probably some datetime-value (and perhaps some other hardware metrics). Maurits recognized how to read the MAC address from the uuid :

PROCEDURE UuidCreate EXTERNAL "rpcrt4.dll":U :
    DEFINE INPUT-OUTPUT PARAMETER opi-guid AS CHARACTER NO-UNDO.
END PROCEDURE.
 
PROCEDURE UuidCreateSequential EXTERNAL "rpcrt4.dll":U :
    DEFINE INPUT-OUTPUT PARAMETER opi-guid AS CHARACTER NO-UNDO.
END PROCEDURE.
 
FUNCTION inttohex RETURNS CHARACTER (INPUT i AS INTEGER): 
   /* only for 0..255 integer values */
   DEFINE VARIABLE cHex AS CHARACTER NO-UNDO INIT '0123456789ABCDEF':U.
   DEFINE VARIABLE j1   AS INTEGER NO-UNDO.
   DEFINE VARIABLE j2   AS INTEGER NO-UNDO.
 
   j1 = TRUNCATE(i / 16, 0) .
   j2 = i - (j1 * 16).
   RETURN SUBSTR(cHex, j1 + 1, 1) + SUBSTR(cHex, j2 + 1, 1).
END.
 
 
FUNCTION GetMacAddress RETURNS CHAR:
   DEFINE VARIABLE X AS CHARACTER NO-UNDO.
   DEFINE VARIABLE i AS INTEGER NO-UNDO.
   DEFINE VARIABLE j AS INTEGER NO-UNDO.
   DEFINE VARIABLE r AS CHARACTER NO-UNDO.
 
   X = FILL(' ':U, 16).
 
   IF RunningWindows2000() THEN 
      RUN UuidCreateSequential (INPUT-OUTPUT X).
   ELSE 
      RUN UuidCreate (INPUT-OUTPUT X).
 
   DO i = 11 TO 16:
      r = r + ' ':U + inttohex(ASC(SUBSTR(X,i,1))). 
   END.
   RETURN SUBSTR(R,2).
END.
 
DISPLAY GetMAcAddress() FORMAT "X(20)":U. 

Notes

Procedure UuidCreate() in Windows 2000 returns a uuid that can not be traced back to the MAC address. Procedure UuidCreateSequential is provided for backward compatibility: it behaves like UuidCreate() in Windows 95/98/NT4.