Thread View: borland.public.cppbuilder.nativeapi
6 messages
6 total messages
Started by Borland Lover
Fri, 21 Apr 2006 22:57
AV - Stack getting trashed - HELP!
Author: Borland Lover
Date: Fri, 21 Apr 2006 22:57
Date: Fri, 21 Apr 2006 22:57
100 lines
4055 bytes
4055 bytes
I need to use the following code to get the MAC address on Win XP and 2k3.
It should work fine....
However, when execution gets to the lines (marked below) the stack gets
completely trashed. I have isolated the problem into a test app. You can
reproduce it by creating a new BCB project, drop a button on the form and
add this code.
Does it work on your system? Please help!
BCB6 Patched.
TIA
----------------
#include <winsock2.h>
#include "Iptypes.h"
#include "Iphlpapi.h"
typedef ULONG (*TGetAdaptersAddresses)(ULONG Family, ULONG Flags, PVOID
Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen);
void __fastcall TForm10::Button1Click(TObject *Sender)
{
HINSTANCE hinst = LoadLibrary("Iphlpapi.dll");
AnsiString AMacAddress = EmptyStr;
if(NULL != hinst)
{
try
{
try
{
TGetAdaptersAddresses pGetAdaptersAddresses =
(TGetAdaptersAddresses)GetProcAddress(hinst, "GetAdaptersAddresses");
if(NULL != pGetAdaptersAddresses)
{
IP_ADAPTER_ADDRESSES * pAddresses = NULL;
try
{
ULONG outBufLen = 0;
// Make an initial call to GetAdaptersAddresses to
get the
// size needed into the outBufLen variable
if (pGetAdaptersAddresses(AF_INET, 0, NULL,
pAddresses, &outBufLen) == ERROR_BUFFER_OVERFLOW)
{
if (pAddresses)
GlobalFree(pAddresses);
pAddresses = (IP_ADAPTER_ADDRESSES*)new unsigned
char[outBufLen];
}
// Make a second call to GetAdapters Addresses to
get the actual data we want
if (pGetAdaptersAddresses(AF_INET, 0, NULL,
pAddresses, &outBufLen) == NO_ERROR)
{
// successful,
unsigned char * MACData =
pAddresses->PhysicalAddress;
////////<<---------------- As this next loop
executes - the stack gets trashed !!! WHY???
DWORD i;
for (i = 0; i <
pAddresses->PhysicalAddressLength; i++)
AMacAddress = AMacAddress + Format("%.2X:",
ARRAYOFCONST(( MACData[i] )));
AMacAddress =
AMacAddress.Delete(AMacAddress.Length(), 1); // take off the last colon
}
}
__finally
{
if (pAddresses)
delete [] pAddresses;
}
}
}
catch(...)
{
AMacAddress = "UNKNOWN MAC ADDR";
}
}
__finally
{
FreeLibrary(hinst);
}
}
MessageDlg(AMacAddress, mtWarning, TMsgDlgButtons() << mbOK, 0);
}
Re: AV - Stack getting trashed - HELP!
Author: Remy Lebeau (TeamB)
Date: Mon, 24 Apr 2006 18:43
Date: Mon, 24 Apr 2006 18:43
94 lines
4263 bytes
4263 bytes
"Borland Lover" <kdhf@kbdf.com> wrote in message
news:4449633f$1@newsgroups.borland.com...
> However, when execution gets to the lines (marked below) the stack
> gets completely trashed.
That is because you are not managing the stack correctly in the first place.
See below.
> typedef ULONG (*TGetAdaptersAddresses)(ULONG Family, ULONG Flags, PVOID
> Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen);
You are not specifying any calling convention in that declaration, so the
compiler's default conention is used. Under C++, the default is __cdecl,
which is NOT the convention that GetAdaptersAddresses() actually uses. If
you look at the documentation for GetAdatersAddresses(), it uses WINAPI for
the calling convention, which in turn usually resolves to __stdcall. Win32
API functions always use the __stdcall convention (wsprintf() is about the
only API function that uses __cdecl instead). __cdecl and _stdcall
manipulate the stack very differently.
Use this code instead:
typedef ULONG (WINAPI *TGetAdaptersAddresses)(ULONG Family, ULONG Flags,
PVOID Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen);
void __fastcall TForm10::Button1Click(TObject *Sender)
{
HINSTANCE hinst = LoadLibrary("Iphlpapi.dll");
AnsiString AMacAddress;
if( NULL != hinst )
{
try
{
TGetAdaptersAddresses pGetAdaptersAddresses =
(TGetAdaptersAddresses) GetProcAddress(hinst, TEXT("GetAdaptersAddresses"));
if( NULL != pGetAdaptersAddresses )
{
IP_ADAPTER_ADDRESSES * pAddresses = NULL;
try
{
ULONG outBufLen = 0;
ULONG ulErr = pGetAdaptersAddresses(AF_INET, 0,
NULL, NULL, &outBufLen);
if( ERROR_BUFFER_OVERFLOW == ulErr )
{
pAddresses = (IP_ADAPTER_ADDRESSES*) new
BYTE[outBufLen];
ulErr = pGetAdaptersAddresses(AF_INET, 0, NULL,
pAddresses, &outBufLen);
}
if( (NO_ERROR == ulErr) && (0 !=
pAddresses->PhysicalAddressLength) )
{
AMacAddress.SetLength((pAddresses->PhysicalAddressLength * 3) - 1);
char *ptr = AMacAddress.c_str();
LPBYTE MACData = pAddresses->PhysicalAddress;
sprintf(ptr, "%02X", MACData[0]);
ptr += 2;
for(DWORD i = 1; i <
pAddresses->PhysicalAddressLength; ++i)
{
sprintf(ptr, ":%02X", MACData[i]);
ptr += 3;
}
}
}
__finally
{
delete [] pAddresses;
}
}
}
catch(...)
{
AMacAddress = "UNKNOWN MAC ADDR";
}
FreeLibrary(hinst);
}
MessageDlg(AMacAddress, mtWarning, TMsgDlgButtons() << mbOK, 0);
}
Gambit
Re: AV - Stack getting trashed - HELP!
Author: Borland Lover
Date: Tue, 25 Apr 2006 15:28
Date: Tue, 25 Apr 2006 15:28
19 lines
1611 bytes
1611 bytes
"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message news:444d1d06$1@newsgroups.borland.com... > > "Borland Lover" <kdhf@kbdf.com> wrote in message > news:4449633f$1@newsgroups.borland.com... > >> However, when execution gets to the lines (marked below) the stack >> gets completely trashed. > > That is because you are not managing the stack correctly in the first > place. > See below. > >> typedef ULONG (*TGetAdaptersAddresses)(ULONG Family, ULONG Flags, PVOID >> Reserved, PIP_ADAPTER_ADDRESSES pAdapterAddresses, PULONG pOutBufLen); Of course! Makes total sense. Works like a charm. Thank you very much.
Re: AV - Stack getting trashed - HELP!
Author: Borland Lover
Date: Tue, 25 Apr 2006 15:46
Date: Tue, 25 Apr 2006 15:46
11 lines
1401 bytes
1401 bytes
What about these two functions : GetAdaptersInfo - it does not specify a calling convention in the MSDN. What do I use in BCB? UuidCreateSequential - it specifies RPC_ENTRY. What do I use in BCB? I am loading and calling both right now without specifying the calling convention - and they seem to be working fine. Is this a fluke? TIA
Re: AV - Stack getting trashed - HELP!
Author: Remy Lebeau (TeamB)
Date: Tue, 25 Apr 2006 17:04
Date: Tue, 25 Apr 2006 17:04
31 lines
2072 bytes
2072 bytes
"Borland Lover" <kdhf@kbdf.com> wrote in message
news:444e4463$1@newsgroups.borland.com...
> GetAdaptersInfo - it does not specify a calling convention
> in the MSDN.
As I told you earlier, *all* Win32 API functions use WINAPI (aka __stdcall),
except for wsprintf() which uses __cdecl instead. If you look in
iphlpapi.h, where GetAdaptersInfo() is actually declared, you can see that:
DWORD
WINAPI // <-- here
GetAdaptersInfo(
PIP_ADAPTER_INFO pAdapterInfo, PULONG pOutBufLen
);
> UuidCreateSequential - it specifies RPC_ENTRY. What do I use in BCB?
You use RPC_ENTRY, which transparently maps to __stdcall. Always use what
is actually in the declaration.
> I am loading and calling both right now without specifying the calling
> convention - and they seem to be working fine. Is this a fluke?
Yes. You must always specify a calling convention, or else the compiler is
free to choose its own. As you have already seen earlier, the compiler can
chose the wrong convention and mess up the runtime behavior as a result.
Gambit
Re: AV - Stack getting trashed - HELP!
Author: Borland Lover
Date: Fri, 28 Apr 2006 15:36
Date: Fri, 28 Apr 2006 15:36
4 lines
1133 bytes
1133 bytes
Thank you Remy. "Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote [...]
Thread Navigation
This is a paginated view of messages in the thread with full content displayed inline.
Messages are displayed in chronological order, with the original post highlighted in green.
Use pagination controls to navigate through all messages in large threads.
Back to All Threads