Solved

connect speed after RasDial

Posted on 1997-03-26
34
435 Views
Last Modified: 2013-12-03
Under WinNT 4.0, I'm using RasDial to establish a WinSock connection. The dialling and the connection work as expected. I'd like to get the connect speed as reported by the modem, but have been unable to figure out how.

I'm using RasDial in the asynchronous mode, with a callback function.

Using VC++ 4.2 without MFC (console app).

Additional info: I thought I could use RasAdminPortGetInfo, but this function just won't link. I am including rassapi.lib. (PLEASE DISREGARD THIS RasAdminPortGetInfo STUFF, IT'S ALREADY CONFUSED ONE OF THE EXPERTS AND IT SEEMS TO BE A DEAD END.)
0
Comment
Question by:llevel
  • 21
  • 8
  • 4
  • +1
34 Comments
 

Author Comment

by:llevel
Comment Utility
Edited text of question
0
 

Author Comment

by:llevel
Comment Utility
Edited text of question
0
 

Author Comment

by:llevel
Comment Utility
Adjusted points to 200
0
 

Author Comment

by:llevel
Comment Utility
Edited text of question
0
 

Author Comment

by:llevel
Comment Utility
Adjusted points to 290
0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
What specific error message do you get from the linker?
0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
What specific error message do you get from the linker?
0
 

Author Comment

by:llevel
Comment Utility
The linker error is:

mts.obj : error LNK2001: unresolved external symbol "unsigned long __stdcall RasAdminPortGetInfo(unsigned short const *,unsigned short const *,struct _RAS_PORT_1 *,struct _RAS_PORT_STATISTICS *,struct RAS_PARAMETERS * *)" (?RasAdminPortGetInfo@@YGKP
BG0PAU_RAS_PORT_1@@PAU_RAS_PORT_STATISTICS@@PAPAURAS_PARAMETERS@@@Z)

I am including rassapi.lib in the project settings. The error above was produced by VC++ 5.0. I get the same sort of error with VC++ 4.2. The function prototype is in rassapi.h.

By the way, what I need is the digital connect speed. If  you look at the NT DUN Monitor, there are two items that deal with connection speed. One is line speed, which is the analog portion of the line, and the other is the device response. This latter value is the modem-reported connect speed and is the value I want.

0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
The RAS headers are broken for C++ programs.  You need to do the extern "C" trick around your inclusion of the RAS headers, for now.

That would look like this:

extern "C" {
#include <ras.h>
}

.B ekiM
0
 

Author Comment

by:llevel
Comment Utility
The extern "C" did the trick for rassapi. I can now link in RasAdminGetPortInfo. However, the function always returns 2, which as far as I can tell is not successful, yet is not one of the documented return codes.


0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
Can you show your call to the function?

.B ekiM

0
 

Author Comment

by:llevel
Comment Utility
   char *theName = new char[40];
    gethostname(theName+2, 38);
    theName[0] = '\\';
    theName[1] = '\\';

    RAS_PORT_1 rp1;
    RAS_PORT_STATISTICS rps;
    RAS_PARAMETERS *rpp;
    WCHAR tname[20], cport[20];
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, theName, -1, tname, 20);
    MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, "CON1", -1, cport, 20);
    rpp = 0;
    DWORD rs = RasAdminPortGetInfo(tname, cport, &rp1, &rps, &rpp);

0
 

Author Comment

by:llevel
Comment Utility
To clarify my previous comment:

"CON1" is the name of the connection that has been just dialled. I also tried using "COM1", which is the com port used.

I do have a concern. This function call (RasAdminPortGetInfo) is NT-only. While that would be good enough for me, I can't help feeliing I'm missing something simple and obvious. I've seen Win 95 diallers report the modem's connect speed. There has to be a way!

0
 

Author Comment

by:llevel
Comment Utility
Hello, I hate to be a pest, but it's been some time since
you locked this question, and ...

0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
Sorry; sometimes, I travel for business.  Sometimes, I'm just too busy with other things to provide free help to other people.

It's hard for me to understand why you're using a buffer of twenty characters after the conversion, but a buffer of forty characters before the conversion.  It seems like you could be truncating the converted server name.

I also don't understand why you're calling MultiByteToWideChar() on the string literal "COM1".  Why not just code L"COM1" to get a wchar constant?

Finally, I'm not sure I understand where this code is running. It seems like you were calling it on the client-side of the RAS connection, but you're passing the name of the machine where the code is running to MultiByteToWideChar().  I think you should be passing the name of the RAS server, not the name of the RAS client.

.B ekiM

0
 

Author Comment

by:llevel
Comment Utility
No problem re the delay. I just posted a reminder in case you just forgot that you had locked the question. I do appreciate your efforts.

No, I'm not truncating the name. The discrepancy is that I haven't bothered cleaning up the code since it doesn't work. Not using a literal for COM1 has a similar explanation.

I also don't really think RasAdminGetPortInfo is my answer. If we refer back to the original question, all I want is a way to get the modem's reported connect speed after using RasDial (The value reported by the modem as part if the CONNECT report). The microsoft dialler seems to do this, and so do others like Ras+95. The fact that Win95 software seems capable of getting this info points away from RasAdminGetPortInfo, since it's advertised as NT only.

But I've scoured the documentation (what little there is), I've asked on usenet newsgroups, and nothing. This is driving me nuts.

0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
Sorry; I can only anaylse what code you give me.

I've done all I can for you.

.B ekiM
0
Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

 

Author Comment

by:llevel
Comment Utility
Mikeblas, thank you for your effort. Could you please unlock the question so maybe someone else can have a shot at it?


0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
I can't.  (And, actually, didn't mean to in the first place.)  You need to reject the answer if you don't feel like giving me points for what I've done for you.

.B ekiM

0
 

Author Comment

by:llevel
Comment Utility
OK. Sorry mikeblas. I wish I could grant the points, but I'm not an inch closer to a solution than when I started. This must be some deep, dark, Microsoft secret.

Good luck.

0
 

Author Comment

by:llevel
Comment Utility
Edited text of question
0
 
LVL 11

Expert Comment

by:mikeblas
Comment Utility
Actually, you couldn't even link before I answered; that's far more than an inch closer to a solution.

You'll probably want to post the code you're _really_ using so that the next person comes along will be able to see what's actually happening.

RasAdminGetPortInfo() will do what you want, if you call it correctly.

Good luck with your work.

.B ekiM


0
 

Author Comment

by:llevel
Comment Utility
Mikeblas, I don't know why you say I should post the code I'm _really_ using. This is what I did. It returns a code that isn't one of the documented ones. There is no RAS server in my application, I'm just using RasDial to establish a winsock/ppp connection to an ISP. The connection works just fine, I just can't get the connect speed.

Anyway, the question is available. If you know a method that should work, I'll try it. I'm not prejudiced for or against RasAdminPortGetInfo.

Also, I apologize if I misused you in any way. I only asked to be allowed to move on when you said "I've done all I can for you."

0
 
LVL 15

Expert Comment

by:NickRepin
Comment Utility
It seems that there is no (documented) way to determine connection speed after dial.

But I can show you three ways to do this.

1.There are many undocumented interesting functions in rasapi32.dll and  rasman.dll (and these functions are calling by rasmon.exe). Eg, RasGetConnectResponse, RasPortGetStatistics etc. We can try to find appropriate one.

2.You can see a tooltip with connection speed at the taskbar when connection has been established. We can install system hook and look for, say, TTN_SHOW message to retrieve text from this tooltip.

3.Most easy way. We can get connection speed from 'dialup monitor' dialog box.

If these ways are acceptable for you, let me know. May be, I can help you.
0
 

Author Comment

by:llevel
Comment Utility
NickRepin,

Thanks for adding your comment. Let me summarize some items
I'm not sure are clear from my question and other comments:

1. This is a console application, ported from a unix
original. So I don't think we can (or want to) deal with
windows messages. My main loop does a select on the tcp/ip
sockets.

2. The application runs unattended, no user interaction is
possible.

3. I need to handle two dial-up connections concurrantly.

4. Something I can call synchronously at around the same
time I get the IP projection info would be ideal. But I
can deal with a callback if necessary.

5. The connection monitor reports two speeds: One is the
analog baud rate, the other is the modem-reported connect
speed: such as 26400 or 28800, or 31600. This latter is
what I want. Modems report this as part of the CONNECT
message.

If you can help under these parameters, feel free to propose
an answer.

Sorry if this was long-winded. I appreciate you're not being
compensated and I don't want to waste your time.


0
 
LVL 1

Expert Comment

by:lowlevel
Comment Utility
don't know how far this will help you, but:

-get the commport for the device
-use createfile to get a handle to the commport.
-use getCommProperties to get the baudrate in a structure.
It's all documented. Look at the help for the functions.
0
 

Author Comment

by:llevel
Comment Utility
lowlevel: Thank you for taking the time to answer. There are a couple of issues with your proposal:

1. CreateFile won't let me open the COM port if it's allready in use by RasDial. I get an error 5 (access denied.)

2. The documentation for GetCommProperties says it returns the maximum baud rate (among other things).
What I need is the actual connect speed, which will vary between connections. This looks like a good function to use if
you're trying to find a suitable com port.

Again, thank you. If I misunderstood your answer and you want to clarify, please feel free to do so.

Darn, I wish these guys had a way of rejecting an answer which didn't sound so dunning.

0
 
LVL 15

Accepted Solution

by:
NickRepin earned 430 total points
Comment Utility
I found right answer! Here is the way the rasmon.exe (NT 4.0) determines connection speed.

I spend too much time to get it, so if you will be satisfied with my answer, please give me grade A.


#include <windows.h>
#include <ras.h>
#include <iostream.h>

// RASAPI32.DLL
extern "C" {
   DWORD APIENTRY RasGetSubEntryHandleW(HRASCONN ras,DWORD entry,
      DWORD subentry[5]);
   DWORD APIENTRY RasGetHport(HRASCONN);
};

// RASMAN.DLL
// You should make export library (run at command line
// 'implib.exe rasman.lib rasman.dll') and link it to your project.
extern "C" {
   DWORD APIENTRY RasGetInfo(DWORD port,DWORD info[210]);
};


void main(void)
{
   cout<<"sizeof(RASCONNSTATUS)="<<sizeof(RASCONNSTATUS)<<endl<<endl;

   // Find connection handle and store it to hRas.
   // Of course, you know you handle, so skip this
   RASCONN r[10];
   r[0].dwSize=sizeof(RASCONN);
   DWORD sz=sizeof(r);
   DWORD n;
   DWORD res;
   res=RasEnumConnections(&r[0],&sz,&n);
   cout<<"RasEnumConnections()="<<res<<endl;
   if(res || n<1) return; // Error!
   cout<<"Number of conn="<<n<<endl;

   // Just get first connection
   HRASCONN hRas=r[0].hrasconn;
   cout<<"Connection number zero: "<<r[0].szEntryName<<endl;
   cout<<"hRas="<<hex<<hRas<<endl;

   // Don't ask me why 5 or 1!
   DWORD subentry[5];
   DWORD entry=1;
   res=RasGetSubEntryHandleW(hRas,entry,subentry);
   cout<<"RasGetSubEntryHandleW()="<<res<<endl;
   if(res) return; // Error!
   // SubEntryHandle
   HRASCONN hSubEntry=HRASCONN(subentry[0]);
   cout<<"hSubEntry="<<hex<<hSubEntry<<endl;

   RASCONNSTATUS rs;
   rs.dwSize=sizeof(RASCONNSTATUS);
   res=RasGetConnectStatus(hSubEntry,&rs);
   cout<<"RasGetConnectStatus()="<<res<<endl;
   if(res) return; // Error!
   cout<<"rasconnstate="<<hex<<rs.rasconnstate<<endl;
   if(rs.rasconnstate!=RASCS_Connected &&
         rs.rasconnstate!=RASCS_AllDevicesConnected) {
      cout<<"Invalid connection state, line speed undefined"<<endl;
      return;
   }

   DWORD hPort;
   hPort=RasGetHport(hSubEntry);
   cout<<"hPort="<<hex<<hPort<<endl;

   // Don't ask why 210...
   DWORD portInfo[210];
   res=RasGetInfo(hPort,portInfo);
   cout<<"RasGetInfo="<<res<<endl;
   if(res) return; // Error!;

   // Here is we want!
   DWORD speed=portInfo[2];

   cout<<"****** SPEED= "<<speed<<" ******"<<endl;
}

0
 

Author Comment

by:llevel
Comment Utility
NickRepin,

Looks like you're gonna be my hero on this one. I'm too groggy to really check it out now, but I'll get to it as soon as possible tomorrow.


0
 

Author Comment

by:llevel
Comment Utility
NickRespon:

I'm feeling like a real dolt here. We're close, I know it, but:

I'm having trouble with making the .lib file for rasman. I found two copies of implib.exe. One on a VC++ version1.52 CDROM. This one says:

Microsoft (R) Import Library Manager  Version 1.50
Copyright (C) Microsoft Corp 1984-1993.  All rights reserved.

IMPLIB : error IM2603: rasman.dll : invalid .DLL file

I also managed to find a Borland copy, which just gets an access violation.

There doesn't seem to be an implib.exe in VC++ 4.0, 4.2, or 5.0. I suspect the version I have is just too old to deal with win32 dlls.

I found a knowledge base article which had a method for making a lib file which involved using dumpbin, creating a def file from the output, and then using lib.exe. However, so far I have been unsuccessful at this.

Any ideas welcome. I know  you've already gone beyond what you initially estimated. I'm going to give you the points at the end of this one way or another, but I'll be far happier if we succeed.

Oh. I can make RAS connections, so I don't think anything is wrong with rasman.dll.


0
 
LVL 15

Expert Comment

by:NickRepin
Comment Utility
Feel free to write me directly to nick@rtzi.ru .

I can send you rasman.lib via e-mail. I am using Borland Implib V2.0.126.1 from BCC 5.01 with following command line:

 implib rasman.lib rasman.dll

P.S. The last 'cout' in my program prints speed in hexadecimals.
To print in decimals just insert 'dec':

  cout<<"****** SPEED= "<<dec<<speed<<" ******"<<endl;
0
 
LVL 15

Expert Comment

by:NickRepin
Comment Utility
May be, there is implib32.exe with Microsoft compilers?
0
 

Author Comment

by:llevel
Comment Utility
NickRepin,

I'm giving you your well-earned "A" for this one. I'm still not quite there yet. I can't find any sort of implib or implib32 from Microsoft, and the Borland lib files won't link. When I try to create a lib from a .def file, it seems to want to link to _RasGetInfo@8.

I'll figure it out somehow. Thanks for all your help.


0
 

Author Comment

by:llevel
Comment Utility
One final comment on this: RasGetInfo reports the analog baud rate, among other things. The connect response string from the modem is available from:

extern "C" DWORD APIENTRY RasGetConnectResponse(HRASCONN, char *);

The second parameter is a char array that receives the modem's CONNECT string.

The import lib for RasGetConnectResponse is rasapi32, which is needed for most of the Ras functions.


0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

This article shows how to make a Windows 7 gadget that accepts files dropped from the Windows Explorer.  It also illustrates how to give your gadget a non-rectangular shape and how to add some nifty visual effects to text displayed in a your gadget.…
A theme is a collection of property settings that allow you to define the look of pages and controls, and then apply the look consistently across pages in an application. Themes can be made up of a set of elements: skins, style sheets, images, and o…
This is Part 3 in a 3-part series on Experts Exchange to discuss error handling in VBA code written for Excel. Part 1 of this series discussed basic error handling code using VBA. http://www.experts-exchange.com/videos/1478/Excel-Error-Handlin…
This video shows how to remove a single email address from the Outlook 2010 Auto Suggestion memory. NOTE: For Outlook 2016 and 2013 perform the exact same steps. Open a new email: Click the New email button in Outlook. Start typing the address: …

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

8 Experts available now in Live!

Get 1:1 Help Now