BoscoBilly
24th July 2009 18:45 UTC
pointers with System::Call
Hi.
I am using the GetMacAddr sample provided by Brainsucker.
Getting the IP_ADAPTER_INFO structure vars the way he did it works fine - thanks Brainsucker!
However, I am trying to get a string var in that struct that needs to be accessed by pointer.
here are two lines: the 1st is the working stuff with my attempt to get the pointer I need; the 2nd is my non-working atempt to retrieve the value of that pointer that I need.
System::Call '*$4(i.r4,i,&t260.r5, &t132.r6, i.r7, l.r8,,,,,*i R1)'
System::Call '$R1->IpAddressList.IpAddress.String(t R2)'
At the end of the first line, var R1 is a pointer.
In the 2nd line, I try to get the string - it returns nothing.
Could someone pl explain what I am doing wrong here?
Thx.
BoscoBilly
25th July 2009 02:27 UTC
I altered the prior code due to some errors.
The element I was trying to access is a struct, not ptr.
here is the new code:
First call is working code form Brainsucker
System::Call '*$4(i.r4,i,&t260.r5, &t132.r6, i.r7, l.r8,,,,i.R1)' # r1 is Struct IP_ADDR_STRING
This call is to get 2nd struct from R1
System::Call "*$R1(,i.R2)" #R1 is Struct IP_ADDR_STRING with 5 members --
This call crashes - it should get final 1-element struct from R2
; System::Call "*$R2(t.R3)" # R2 is struct IP_ADDR_STRING with 1 member
The 3rd Call returns nothing.
I have been all over the System plugin doc and cannot figger out this one.
Anyone done this b4?
BoscoBilly
25th July 2009 19:52 UTC
With the original Brainsucker code, it will only get first adapter.
I run C++ code in my app which uses this very same call and I have no problems with it on test machines that this code will:
1) only show 1 adapter when there are 5.
2) will not rtn IPAddress.
Is there someone who can help me with these problems?
f0rt
26th July 2009 19:34 UTC
I adapted Brainsucker's script to report the currently assigned IP address of a network adapter as well.
I did not have a debugger handy to analyze the memory layout of the IP_ADAPTER_INFO structure in detail. So there might be potential pitfalls.
"LogicLib.nsh"
>!define MAXSIZE 4096
Name "MacAddr Plugin Example"
>OutFile "macaddr.exe"
>SetPluginUnload alwaysoff
Section
SetOutPath $TEMP
System
::Alloc ${MAXSIZE}
Pop $3
System::Call 'iphlpapi::GetAdaptersInfo(i r3 r4, *l ${MAXSIZE} r2) i.r1'
MessageBox MB_OK "GetAdaptersInfo return is $1"
${If} $1 == 0
${While} $4 != 0
; Access IP_ADAPTER_INFO structure
; (PIP_ADAPTER_INFO next, DWORD ComboIndex, char AdapterName***91;256+4***93;, char Description***91;128+4***93;,
; UINT AddressLength, BYTE Address***91;8***93;, DWORD Index, UINT Type, UINT DhcpEnabled,
; PIP_ADDR_STRING CurrentIpAddress, IP_ADDR_STRING IpAddressList, ...)
;
;IP_ADDR_STRING (PIP_ADDR_STRING *Next, IP_ADDRESS_STRING IpAddress,
; IP_MASK_STRING IpMask, DWORD Context)
;
;IP_ADDRESS_STRING(char String***91;4 * 4***93;)
System::Call '*$4(i.r4, i, &m260.r5, &m132.r6, i.r7, l.r8, &m8, i, i, i, &m16.r9)'
Math::Script "hex={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};"
Math::Script "s=''; a=r8; b=r7; #{b-->0,s=s+hex***91;a/16%16***93;+hex***91;a%16***93;+#***91;b>0,'-',''***93;; a=a/256;}; R0=s;"
MessageBox MB_OK "Adapter name is $5$\ndesc $6$\naddr len $7$\naddr $8$\nMacAddr: $R0$\nIpAddress: $9"
${EndWhile}
${EndIf}
System::Free $3
; last plugin call must not have /NOUNLOAD so NSIS will be able to delete the temporary DLL
SetPluginUnload manual
; do nothing
System::Free 0
Math::Script ""
>SectionEnd
>
BoscoBilly
26th July 2009 19:50 UTC
Thanks, fOrt!
Your IP part is the right way to do it, despite that struct chain that seemed to require multiple CALLs with *!Rx.
The final struct in the IPAdressList chain has 1 element, which is the IP. It is a 16 byte array, just as you allocated for.
As I said in my post, in my app , I get 5 MACs on this machine using GetAdapterInfo.
This script only returns 1, which happens to be the one with the correct IP in it!
My plan was not to get the IP this way, but to loop thru the MACs, as I do in my app, comparing IPs to get the matching MAC.
Given that, I wonder how reliable this script will be?
It works on my XP pro Sp2 and W2003 server R2 machines.
It would be nice of Brainsucker could jump in here.
f0rt
26th July 2009 20:41 UTC
It would be helpful for further analysis to get a memory dump of the pAdapterInfo parameter after the return from GetAdaptersInfo.
I would suggest to use the example provided by Microsoft http://msdn.microsoft.com/en-us/libr...8VS.85%29.aspx as a basis and insert code to dump the memory of pAdapterInfo in the while loop.
The value of ulOutBufLen would also be of interest because the NSIS script uses a maximum buffer of 4096.