?
Solved

connect speed after RasDial

Posted on 1997-03-26
34
Medium Priority
?
451 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 21
  • 8
  • 4
  • +1
34 Comments
 

Author Comment

by:llevel
ID: 1334242
Edited text of question
0
 

Author Comment

by:llevel
ID: 1334243
Edited text of question
0
 

Author Comment

by:llevel
ID: 1334244
Adjusted points to 200
0
 [eBook] Windows Nano Server

Download this FREE eBook and learn all you need to get started with Windows Nano Server, including deployment options, remote management
and troubleshooting tips and tricks

 

Author Comment

by:llevel
ID: 1334245
Edited text of question
0
 

Author Comment

by:llevel
ID: 1334246
Adjusted points to 290
0
 
LVL 11

Expert Comment

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

Expert Comment

by:mikeblas
ID: 1334248
What specific error message do you get from the linker?
0
 

Author Comment

by:llevel
ID: 1334249
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
ID: 1334250
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
ID: 1334251
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
ID: 1334252
Can you show your call to the function?

.B ekiM

0
 

Author Comment

by:llevel
ID: 1334253
   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
ID: 1334254
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
ID: 1334255
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
ID: 1334256
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
ID: 1334257
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
ID: 1334258
Sorry; I can only anaylse what code you give me.

I've done all I can for you.

.B ekiM
0
 

Author Comment

by:llevel
ID: 1334259
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
ID: 1334260
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
ID: 1334261
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
ID: 1334262
Edited text of question
0
 
LVL 11

Expert Comment

by:mikeblas
ID: 1334263
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
ID: 1334264
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
ID: 1334265
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
ID: 1334266
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
ID: 1334267
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
ID: 1334268
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 860 total points
ID: 1334269
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
ID: 1334270
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
ID: 1334271
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
ID: 1334272
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
ID: 1334273
May be, there is implib32.exe with Microsoft compilers?
0
 

Author Comment

by:llevel
ID: 1334274
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
ID: 1334275
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

Get free NFR key for Veeam Availability Suite 9.5

Veeam is happy to provide a free NFR license (1 year, 2 sockets) to all certified IT Pros. The license allows for the non-production use of Veeam Availability Suite v9.5 in your home lab, without any feature limitations. It works for both VMware and Hyper-V environments

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

With most software applications trying to cater to multiple user needs nowadays, the focus is to make them as configurable as possible. For e.g., when creating Silverlight applications which will connect to WCF services, the service end point usuall…
What my article will show is if you ever had to do processing to a listbox without being able to just select all the items in it. My software Visual Studio 2008 crystal report v11 My issue was I wanted to add crystal report to a form and show…
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…
NetCrunch network monitor is a highly extensive platform for network monitoring and alert generation. In this video you'll see a live demo of NetCrunch with most notable features explained in a walk-through manner. You'll also get to know the philos…

764 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