The concept of the NIC address is a bit confusing. Because there are two addresses, MAC addresses, and physical addresses, I usually say the network card address, I refer to the physical address, I don't know how others see? The physical address refers to the address of the ROM of the storage address on the NIC. The MAC address is this. The address used when the block card works, in general, the two addresses are the same, so many people are mixed, and even if they don't know when they are -_- # network cards, an Ethernet frame 60 to 1514 (no Including CRCs), the Crc of the frame is automatically added, and the preamble is automatically added. The NIC destination address and source address are driver added. So what address is used when the NIC work is used as a working address is determined by the driver :) Therefore, we can use it without changing the physical address of the NIC. The software method changes the work address of the specific NIC. The MAC address is typically saved in the registry, which can be modified, so there is a question: 1st, can be illegitized, IP, 2, can break some garbage encryption Software ... Many software is encrypted through the NIC address, there are two different. Some of the better than the physical address is encrypted. Some are encrypted by work addresses. The address obtained by working address encryption is a MAC address. This method can generally be cracked. It is a bit difficult to encrypt through physical address, but it is not no way. Three methods of obtaining the system's MAC address: QinJia first method uses the Microsoft Netbios API. This is a set of commands that provide underlying networks through Winsock. The biggest disadvantage using NetBIOS is that you must have a NetBIOS service in your system (if you enable file sharing in your Windows network, this is not a problem). In addition, this method is fast and accurate. The NetBIOS API only includes a function, just called NetBIOS. This function uses the Network Control Block structure as a parameter, which tells the function to do. Definition structure follows: typedef struct _NCB {UCHAR ncb_command; UCHAR ncb_retcode; UCHAR ncb_lsn; UCHAR ncb_num; PUCHAR ncb_buffer; WORD ncb_length; UCHAR ncb_callname [NCBNAMSZ]; UCHAR ncb_name [NCBNAMSZ]; UCHAR ncb_rto; UCHAR ncb_sto; void (CALLBACK * ncb_post (struct _ncb *); uchar ncb_lana_num; uchar ncb_cmd_cplt; #ifdef _win64 uchar ncb_reserve [18]; #ELSE uchar ncb_reserve [10]; #ENDIF HANDLE NCB_EVENT;} NCB, * PNCB; focus on NCB_COMMAND member. This member tells NetBIOS what should I do. We use three commands to detect the MAC address. They are defined in MSDN as follows: Command Description: NcBenum Windows NT / 2000: Enumerally listing the number of network cards in the system. After using this command, the NCB_BUFFER member points to the buffer filled by the LANA_ENUM structure. Ncbenum is not a standard NetBIOS 3.0 command. Ncbreset reset the network card. The NIC must reset before accepting the new NCB command. NCBastat accepts the status of the local or remote interface card. After using this command, the NCB_Buffer member points to the buffer filled by the Adapter_status structure, followed by an array of Name_Buffer structures. Here is to get the steps of your system MAC address: 1 "list all interface cards. 2 "Reset each card to obtain its correct information. 3 "Query the interface card, get the MAC address and generate a standard colonial separation format. Here is an example source program. #include
#include
#include
#include
#includeusing namespace std; #define Bzero (Thing, SZ) MEMSET (Thing, 0, SZ) Bool getAdapterInfo (int adapter_num, string & mac_addr) {// Reset NCB NCB; MEMSET (& NCB, 0, sizeof (Ncb)); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = adapter_num; if (Netbios (& Ncb) = NRC_GOODRET) {mac_addr = "bad (NCBRESET):";! mac_addr = string (Ncb.ncb_retcode); return False;} // Prepare the status block BZERO (& NCB, SIZEOF (NCB); ncb.ncb_command = ncbastat; ncb.ncb_lana_num = adapter_num; strcpy ((char *) ncb.ncb_callname, "*"); struct Astat {ADAPTER_STATUS adapt; NAME_BUFFER NameBuff [30];} Adapter; bzero (& Adapter, sizeof (Adapter)); Ncb.ncb_buffer = (unsigned char *) & Adapter; Ncb.ncb_length = sizeof (Adapter); // acquired card information, And if the NIC works normally, return to the standard colonial separation format.
IF (NetBIOS (& NCB) == 0) {Char Acmac [18]; Sprintf (acmac, "% 02x:% 02x:% 02x:% 02x:% 02x:% 02x", int (adapter.adapt.adapter_address [0 ]), int (adapter.adapt.adapter_address [1]), int (adapter.adapt.adapter_address [2]), int (adapter.adapt.adapter_address [3]), int (adapter.adapt.adapter_address [4]) , int (adapter.adapt.adapter_address [5]))); mac_addr = acmac; return true;} else {mac_addr = ") (ncbastat):"; mac_addr = string (ncb.ncb_retcode); return false;}}}} int@af main () {// acquired card list LANA_ENUM AdapterList; NCB Ncb; memset (& Ncb, 0, sizeof (NCB)); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (unsigned char *) & AdapterList; Ncb.ncb_length = sizeof ( AdapterList); NetBIOS (& NCB); // Get the address of the local Ethernet card string mac_addr; for (int i = 0; i #include Using namespace std; int main () {cout << "Mac Address is:"; // requires a UUID to COM. If there is an Ethernet card in the machine, // uuid's last six bytes (2-7 bytes of DATA4) should be the MAC address of the local Ethernet card. Guid uuid; cocreateguid; // spit the address out char mac_addr [18]; sprintf (mac_addr, "% 02x:% 02x:% 02x:% 02x:% 02x:% 02x", uuid.data4 [2] UUID.DATA4 [3], uuid.data4 [4], uuid.data4 [5], uuid.data4 [6], uuid.data4 [7]); cout << mac_addr << Endl; getch (); return 0;} Third Method - The third method I want to discuss using the SNMP extended API is to use Windows SNMP (Simple Network Management Protocol) extension to obtain the MAC address. In my experience, this agreement is simple. The code is also forwarded. Basic steps and NetBIOS: 1 "Net Card List 2" Query the Type of Each Card and MAC Address 3 "Save the current network card, I personally know much about SNMP, but I just said that the code is very clear. # include # include #include typedef bool (WINAPI * pSnmpExtensionInit) (IN DWORD dwTimeZeroReference, OUT HANDLE * hPollForTrapEvent, OUT AsnObjectIdentifier * supportedView); typedef bool (WINAPI * pSnmpExtensionTrap) (OUT AsnObjectIdentifier * enterprise, OUT AsnInteger * genericTrap, OUT AsnInteger * specificTrap, OUT AsnTimeticks * timeStamp , OUT RFC1157VarBindList * variableBindings); typedef bool (WINAPI * pSnmpExtensionQuery) (IN BYTE requestType, IN OUT RFC1157VarBindList * variableBindings, OUT AsnInteger * errorStatus, OUT AsnInteger * errorIndex); typedef bool (WINAPI * pSnmpExtensionInitEx) (OUT AsnObjectIdentifier * supportedView); void main () {HINSTANCE m_hInst; pSnmpExtensionInit m_Init; pSnmpExtensionInitEx m_InitEx; pSnmpExtensionQuery m_Query; pSnmpExtensionTrap m_Trap; HANDLE PollForTrapEvent; AsnObjectIdentifier SupportedView; UINT OID_ifEntryType [] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 3}; uint oid_ifentrynum [] = {1, 3, 6, 1, 2, 1, 2, 1}; uint oid_ipmacentaddr [] = {1, 3, 6, 1, 2, 1, 2, 2, 1, 6}; ObjectIdentifier MIB_ifMACEntAddr = {sizeof (OID_ipMACEntAddr) sizeof (UINT), OID_ipMACEntAddr}; AsnObjectIdentifier MIB_ifEntryType = {sizeof (OID_ifEntryType) sizeof (UINT), OID_ifEntryType}; AsnObjectIdentifier MIB_ifEntryNum = {sizeof (OID_ifEntryNum) sizeof (UINT), OID_ifEntryNum}; RFC1157VarBindList varBindList ; RFC1157VarBind varBind [2]; AsnInteger errorStatus; AsnInteger errorIndex; AsnObjectIdentifier MIB_NULL = {0, 0}; int ret; int dtmp; int i = 0, j = 0; bool found = false; char TempEthernet [13]; m_Init = NULL; M_INITEX = NULL; M_QUERY = NULL; M_TRAP = NULL; / * Load SNMP DLL and acquire an instance handle * / m_hinst = loadingLibrary ("inetmib1.dll"); if (m_hinst < (HINSTANCE) HINSTANCE_ERROR) {m_hInst = NULL; return;} m_Init = (pSnmpExtensionInit) GetProcAddress (m_hInst, "SnmpExtensionInit"); m_InitEx = (pSnmpExtensionInitEx) GetProcAddress (m_hInst, "SnmpExtensionInitEx"); m_Query = (pSnmpExtensionQuery) GetProcAddress (m_hInst, "SnmpExtensionQuery"); m_Trap = (pSnmpExtensionTrap) GetProcAddress (m_hInst, "SnmpExtensionTrap"); m_Init (GetTickCount (), & PollForTrapEvent, & SupportedView); / * initialize variables m_Query for receiving query result list * / varBindList.list = varBind; Varbind [0] .name = mib_null; varbind [1] .name = mib_null; / * Copy in OID and look up the number of portals in the interface table * / varbindlist.len = 1; / * only retrieving one item * / snmp_oidcpy & varBind [0] .name, & MIB_ifEntryNum); ret = m_Query (ASN_RFC1157_GETNEXTREQUEST, & varBindList, & errorStatus, & errorIndex); printf ( "# of adapters in this system:% in", varBind [0] .value.asnValue.number); varBindList .len = 2; / * Copy OID IFTYPE - Interface Type * / SNMP_OIDCPY (& Varbind [0] .Name, & MIB_IFENTRYTYPE); / * Copy OID IFPHYSADDRESS- Physical Address * / SNMP_OIDCPY (& Varbind [1] .name, & MIB_IFMACEN TADDR); Do {/ * submit query, the result will be loaded into VarbindList. It can be expected that the number of cyclic calls and the number of interface cards in the system are equal * / RET = M_Query (asn_rfc1157_getnextrequest, & varbindlist, & errorstatus, & errorindex); if (! RET) RET = 1; Else / * confirm the correct return type * / Ret = SNMP_OIDNCMP (& varbind [0] .name, & mib_ifenTrytype, MIB_IB_IFENTRYTYPE.IDLENGTH); if (! RET) {J ; DTMP = varbind [0] .value.asnvalue.Number; Printf ("interface #% i type:% in" , J, DTMP); / * TYPE 6 Describes Ethernet interfaces * / if (DTMP == 6) {/ * Confirm that we already get the address * / RET = snmp_oidncmp (& varbind [1] .name, & mib_ifmacentaddr, mib_ifmaceaddr.idlength ); if ((! RET) && (varbind [1] .value.asnvalue.address.Stream! = null) {if ((varbind [1] .Value.asnvalue.address.Stream [0] == 0x44) && (VARBIND [1] .Value.asnvalue.address.Stream [1] == 0x45) && (varbind [1] .value.asnvalue.address.stream [2] == 0x53) && (varbind [1] .value .asnvalue.address.Stream [3] == 0x54) && (varbind [1] .value.asnvalue.address.Stream [4] == 0x00)) {/ * ignore all dial-up network interface card * / printf (" Interface #% i is a dun adaptern ", J); Continue;} IF ((varbind [1] .value.asnvalue.address.Stream [0] == 0x00) && (VARB Ind [1] .Value.asnvalue.address.Stream [1] == 0x00) && (varbind [1] .value.asnvalue.address.Stream [2] == 0x00) && (varbind [1] .value.asnvalue .address.Stream [3] == 0x00) && (varbind [1] .value.asnvalue.address.Stream [4] == 0x00) && (varbind [1] .Value.asnvalue.address.Stream [5] = = 0x00)) {/ * ignores NULL addresses returned by other network interface cards * / printf ("Interface #% I is a null addressn, j), joint;} sprintf (TemPethernet,"% 02x% 02x% 02X % 02x% 02x% 02X " Varbind [1] .value.asnvalue.address.Stream [0], Varbind [1] .value.asnvalue.address.Stream [1], Varbind [1] .Value.asnvalue.address.Stream [2], varbind [1] .value.asnvalue.address.Stream [3], Varbind [1] .Value.asnvalue.address.Stream [4], Varbind [1] .Value.asnvalue.address.Stream [5]); Printf "Mac Address of Interface #% i:% SN", J, Tempethernet);}}}} while (! RET); / * Error termination occurs. * / getch (); freelibrary (m_hinst); / * Release binding * / snmp_freevarbind (& varbind [0]); SNMP_Freevarbind (& varbind [1]);} Getting a physical address method is different for different network cards, but all It is an operation of the IO port, the specific address of the port To see the specific chip. Encryption software should get a physical address and cannot use this method. In general, it is obtained by NDISREQUEST in the core state. A method of applying a layer is provided here. To pull NDisRequest, you have to be far away, or stop ... NDIS specification, the NDIS specification supports the ioctl_ndis_query_stats interface: OID_802_3_Permanent_address: physical address OID_802_3_current_address: MAC address is already our method. First, look at the registry, find a few pieces of network card, what equipment name is it. The specific location is related to the OS, 2000 under HLM / Software / Microsoft / Windows NT / Current Version / NetworkCards. Then createfile (devicename, ...) Note that the use linkname, therefore plus ".//device//". Then deviceiocontrol (hmac, IOCTL_NDIS_QUERY_STATS, OID_802_3_PERMANENT_ADDRESS / OID_802_3_CURRENT_ADDRESS ...) can be found in the specific circumstances under ddk OID_802_3_current_address entry. So we got the MAC address and physical address. -------------------------------------------------- ------------------------------ Jzyhummel (blade [fellet]) said: About how to modify the MAC address, there is not much The necessary, anyway, and the registry, how to modify the network card physical address, you can read or modify directly from EEPROM (such as: 8029as, 93C46 chip), but the network card is different, and the reading method is different. For example, if you read 8029AS EEPROM's OFFSET 0001H; actual Address I / O 01 MAC is stored in the Address 1H, 2H, 3H of EEPROM; if you read 8139C (1) of the EEPROM (93C46) of Offset 0050H; actual I / O 0x50 MAC is stored in EEPROM, am ADDRESS 7H, 8H, 9H; the system actually used MAC is placed in the REGISTER of 8139chin, the offset address is 0000H, 0001H, 0002H, 0003H, 0004H, 0005H how to implement Three ways to modify the physical address of the network card also thank Hu Shrimp 1, buy a piece of card can be modified by writing EEPROM physics, this card is now much now, not to buy. If you need to apply the network in the environment, modify the MAC address so that the MAC address of the two cards is different, then the network is still working. 2, find a NE2K or EEPRO100 network card, I believe that any electronic market has two network cards, then find its driver source code in the DDK Sample, find the driver read physical port or PCI mapping memory get the physical address The code that allows functions to return to the physical address you need. This method may be the most easy to implement. In 1998, 17 had a $ 100,000 software with this method D version. If you need to apply the network environment, you also modify the MAC address. Both of these two cards support to modify the MAC address by modifying the registry. Please note that not all card drivers are supported. The principle of this method can be obtained by reading the Source of EEPRO100. The EEPRO100 will read the registry when Load, and then use the physical address if not read, otherwise the address in the registry will be used. This function does not seem to be enforced. So if you don't want to modify the registry, you can still be implemented by modifying the NIC DRIVER. This method is suitable for all platforms that support NDIS Driver. 3, this method is that I have not specifically tried, but the principle is feasible. All methods for obtaining a NIC address, whether it is a MAC address or a physical address, the root finish is implemented by sending NDisRequest to the NDS DRIVER. But please note that the NDisRequest is a macro under W2K. This macro actually calls the miniporthandler -> RequestHandler function To HOO MiniPort's function does not seem to find a suitable timing, and it is also difficult to give a general solution. However, the method is always thinking, as long as there is a meter, like a paradise "1024 bit RSA, That's Impossible" "1024 Bit RSA, That's Impossible" "Nothing is iMpossible", you can still be in many Place hook. If it is a Win9X platform, simply call hook_device_service, you can Hook NDisRequest, I will modify the MTU through the Hook this function, or you can also modify the network card physical address. If it is NT4.0, you can also hook ndisRequest, because this is a function, not a macro, you can directly modify the NDIS PE output function portfolio implementation. The method is that I have not tried it. I heard that Rising is to achieve their virus firewall with this method. These three ways, I strong suggestions, the second method, simple and easy, and can bought the piracy, EEPRO100 and NE2K network cards are bought, and the price is cheap - -------------------------------------------------- ---------------- The following describes the modification of the comparative benzene Win2000 modification: 1, in hkey_local_machine / system / currentcontrolset / control / class {4D36E972-E325-11CE-BFC1- 08002BE10318} / 0000,000,000,000, etc. The following method and the Rifter "Modify MAC Address Examples", I will follow (the area "^^" labeled). 2, under it, add a string, name is NetworkAddress, and the value is set to the MAC place (refer to 0000 primary key), to write. To 004040404040. 3, then add a networkaddress's primary key to NDI / params, add a string named Default, and write the MAC address to be set, such as 004040404040. (In fact, this is just the ** initial value ** in the advanced properties mentioned later. The actually used MAC address still depends on the NetWorkadDress parameters mentioned in Point 2, and once it is set, advanced attributes in later properties The value is the value given by NetWorkAddress.) 4, continue to add a string called paramDesc under NetworkAddress's primary key, and its value can be a description of the networkAddress primary key, and its value can be "Mac Address", This will open the properties of the network neighbor, double-click the corresponding network card item, find a advanced setting, under the Mac Address option, which is the new NetWorkAddress you add in the registry, as long as you modify the MAC address here. 5, turn off the registry, restart, your network card address has been changed. Open the properties of the network neighbor, double-click the corresponding NIC item to find a high-level setting item with a Mac Address. Used to directly modify the MAC address. ××××××××××××××××××××××××× Get a remote network card MAC address. ××××××××××××××××××××××××× First, add #include "nb30.h" #pragma Comment (LIB, "Netapi32.lib, first in the header file definition. ") typedef struct _ASTAT_ {ADAPTER_STATUS adapt; NAME_BUFFER NameBuff [30];} ASTAT, * PASTAT; you can call to get the remote MAC address of: CString getMacAddress (CString sNetBiosName) {ASTAT Adapter; NCB ncb; UCHAR uRetCode; memset (& NCB, 0, SIZEOF (NCB)); ncb.ncb_command = ncbreset; ncb.ncb_lana_num = 0; uretcode = netbios (& NCB); MEMSET (& NCB, 0, SIZEOF (NCB)); ncb.ncb_command = ncbast; ncb. ncb_lana_num = 0; sNetBiosName.MakeUpper (); FillMemory (ncb.ncb_callname, NCBNAMSZ - 1, 0x20); strcpy ((char *) ncb.ncb_callname, (LPCTSTR) sNetBiosName); ncb.ncb_callname [sNetBiosName.GetLength ()] = 0x20; ncb.ncb_callname [NCBNAMSZ] = 0x0; ncb.ncb_buffer = (unsigned char *) & Adapter; ncb.ncb_length = sizeof (Adapter); uRetCode = Netbios (& ncb); CString sMacAddress; if (uRetCode == 0) {sMacAddress .Format ("% 02x% 02x% 02x% 02x% 02x% 02x"), adapter.adapt.adapter_address [0], adapter.adapt.adapter_address [1], adapter.adapt.adapter_address [2], Ada Pter.Adapt.adapter_address [3], adapter.adapt.adapter_address [4], adapter.adapt.adapter_address [5]);} ××××××××××××××××××× ××××××××××××××××××× Modified Windows 2000 Mac Address Jointels ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× ××××××××××××××××× 小 is taken from http://www.driverdevelop.com/ because you don't understand compilation, no debugging, Is not guaranteed ^ _ ^ 2 MAC address type: OID_802_3_PERMANENT_ADDRESS OID_802_3_CURRENT_ADDRESS modify registry can change: OID_802_3_CURRENT_ADDRESS but OID_802_3_PERMANENT_ADDRESS, you must modify driver Use following APIs, you can get PERMANENT_ADDRESS CreateFile:. Opened the driver DeviceIoControl: send query to driver Use softice to track where the OID_802_3_PERMANENT_ADDRESS is processed: Find the location: .................: 0001ACB6 8D B3 EA 00 00 00 lea esi, dword ptr [ebx 000000EA]: 0001ACBC 8D7DDC lea edi , DWORD PTR [EBP-24]: 0001ACBF A5 MOVSD // CYM: Move Out the Mac Address: 0001ACC2 C745MOVSW: 0001ACC2 C745F406000000 MOV [EBP-0C] 00000006: 0001ACC9 8D75DC LEA ESI, DWORD PTR [EBP-24]: 0001ACCC E926070000 JMP 0001B3F7 ............ Change to:: 0001ACB6 8D75DC Lea ESI, DWORD PTR [EBP-24]: 0001ACB9 C70600002003 MOV DWORD PTR [ESI], 03200000 // CYM: 0001ACBF 66C746041224 MOV [ESI 04], 2412: 0001ACC5 C745F406000000 MOV [EBP-0C], 00000006: 0001ACCC E926070000 JMP 0001B3F7 ..... DASM Driver. sys file, find NdisReadNetworkAddress ......: 000109B9 50 push eax * Reference To: NDIS.NdisReadNetworkAddress, Ord: 00EAh |: 000109BA FF1538040100 Call dword ptr [00010438]: 000109C0 837DF400 cmp dword ptr [ebp-0C], 00000000 :. 000109C4 7516 jne 000109DC // is set mac addr in registry, use it others jump: 000109C6 8B45E8 mov eax, dword ptr [ebp-18]: 000109C9 8B08 mov ecx, dword ptr [eax]: 000109CB 898EE4000000 mov dword ptr [ ESI 000000E4], ECX: 000109D1 668B4004 MOV AX, Word PTR [EAX 04]: 000109D5 668986E8000000 MOV Word PTR [ESI 000000E8], AX ... SET W MEMORY BREAL POINT AT ESI 000000E4, Find Location : ... // mac addr 2nd byte: 000124D6 8A83E5000000 MOV Al, Byte PTR [EBX 000000E5] // mac addr 3rd byte: 000124DC 0A83E6000000 or al, byte ptr [ebx 000000E6]: 000124E2 0A83E7000000 or al, byte ptr [ebx 000000E7] ...: 000124E8 0A83E8000000 or al, byte ptr [ebx 000000E8] // mac addr 6th byte: 000124EE 0A83E9000000 or al, byte ptr [ebx 000000E9]: 000124F4 0A07 or al, byte ptr [edi]: 000124F6 7503 jne 000124FB: 000124F8 A5 movsd: 000124F9 66A5 movsw // if no station addr use permanent address as mac addr ..... change to: 000124D6 C683E500000000 mov byte ptr [ebx 000000E5], 00 // CYM: 000124DD C683E600000020 mov byte ptr [ebx 000000E6], 20: 000124E4 C683E700000003 mov byte ptr [ebx 000000E7], 03: 000124EB C683E800000012 mov byte ptr [ebx 000000E8], 12: 000124F2 C683E900000024 mov byte ptr [ebx 000000E9], 24: 000124F9 90 nop:. 000124FA 90 nop It seems that the driver can work now Testing: disable NIC, Enable Nic. Jump 0xc0000221 Error, Checksum Error Before Windows Load .sys File, It Will Check The CHECKSUM The CHECKSUM CAN Be Get by ChecksumMappedFile. Build A SM All Tools to Reset The Checksum in .sys File. Test Again, OK. Related EXE Download http://www.driverdevelop.com/Article/chengyu_Checksum.zip ×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××× ××××××××××××××××××× NetBIOS API gets NIC MAC address ×××××××××××××××××××××××× ××××××××××××× #include "nb30.h" #pragma comment (lib, "netapi32.lib") typef struct tagmac_address {BYTE B1, B2, B3, B4, B5, B6; } MAC_ADDRESS, * LPMAC_ADDRESS; typedef struct tagASTAT {ADAPTER_STATUS adapt; NAME_BUFFER NameBuff [30];} ASTAT, * LPASTAT; UCHAR GetAddressByIndex (int lana_num, ASTAT & Adapter) {NCB ncb; UCHAR uRetCode; memset (& ncb, 0, sizeof (ncb )); ncb.ncb_command = ncbreset; ncb.ncb_lana_num = lana_num; // Specify the NIC number, first send an ncbreset command to the selected network card for initialization uretcode = NetBIOS (& NCB); MEMSET (& NCB, 0, SIZEOF (NCB)); ncb.ncb_command = ncbastat; ncb.ncb_lana_num = lana_num; // Specify NIC NS NOTS STRCPY ((char *) ncb.ncb_callname, "*"); NCB .ncb_buffer = (unsigned char *) & adapter; // Specify the returned information storage variable ncb.ncb_length = sizeof (adapter); / / Next, you can send the ncbastat command to get the information uretcode = netbios (& NCB); Return URetcode ;} int getMAC (LPMAC_ADDRESS pMacAddr) {NCB ncb; UCHAR uRetCode; int num = 0; lANA_ENUM lana_enum; memset (& ncb, 0, sizeof (ncb)); ncb.ncb_command = NCBENUM; ncb.ncb_buffer = (unsigned char *) & lana_enum; ncb.ncb_length = sizeof (LANA_ENUM); // Send NcBenum command to the NCBENUM command to get the network card information of the current machine, if there is a network card // each network card number and other URETCODE = NetBIOS (& NCB); if (Uretcode == 0) {NUM = LANA_ENUM.LENGTH; / / For each network card, with its NIC number as the input number, obtain its MAC address for (int i = 0; I // This can obtain MAC address strings such as 00-E0-AA-AA-AA-AA ×××××××××××××××××××××××××× ×××××××××× use IP Helper API to get network card address ××××××××××××××××××××××××××××××××× ×××× huh, the most common method is in the final use of the GetAdaptersinfo function here, the brothers can choose ^ _ ^ #include as appropriate #pragma comment (lib, "iphlpapi.lib") typef struct tagadapterinfo {char szdevicename [128]; // Name char szipaddrstr [16]; // ip char szhwaddrstr [18]; // Mac DWORD dwindex; // number} INFO_ADAPTER, * PINFO_ADAPTER; Info_Adapter Adapterlist [10]; // NIC list, such as ten / ***************************** ***************************************** * Name & params :: * formatMactostr * (* LPSTR LPHWADDRSTR: Displayed "-" Mac string * unsigned char * hwaddr: incoming mac string *) * purpose: * Transfers the user input MAC address characters into corresponding formats **** *********************************************************** *************** / VOID FORMATMACTOSTR (LPSTR LPHWADDRSTR, Const unsigned char * hwaddr) {INT i; short temp; char szstr [3]; strcpy (lphwaddrstr, ""); for (i = 0; i <6; i) {TEMP = (Short) (* (hwaddr i)); _itoa (TEMP, SZSTR, 16); if (Strlen (SZSTR) == 1) STRCAT (lphwaddrstr , "0"); STRCAT (LPHWADDRSTR, SZSTR); if (i <5) strcat (lphwaddrstr, "-"); // plus -}} // Fill structure void getadapterinfo () {char Tempchar; ulong ulistsize = 1; pip_adapter_info padapter; // Define PIP_ADAPTER_INFO Structure Storage Network Card Information int nAdapterIndex = 0; DWORD dwRet = GetAdaptersInfo ((PIP_ADAPTER_INFO) & tempChar, & uListSize); // key function if (dwRet == ERROR_BUFFER_OVERFLOW) {PIP_ADAPTER_INFO pAdapterListBuffer = (PIP_ADAPTER_INFO) new (char [uListSize]); dwRet = GetAdaptersInfo (pAdapterListBuffer , & uListSize); if (dwRet == ERROR_SUCCESS) {pAdapter = pAdapterListBuffer; while (pAdapter) // enumeration card {CString strTemp = pAdapter-> AdapterName; // name card strTemp = "// Device // NPF_" strTemp ; // Plus prefix strcpy (AdapterList [NADAPTERINDEX] .SZDeviceName, Strtemp); Strcpy (AdapterList [NadapterIndex] .szipaddrstr, Padapter->