[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 458
  • Last Modified:

connect speed after RasDial

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
llevel
Asked:
llevel
  • 21
  • 8
  • 4
  • +1
1 Solution
 
llevelAuthor Commented:
Edited text of question
0
 
llevelAuthor Commented:
Edited text of question
0
 
llevelAuthor Commented:
Adjusted points to 200
0
Get quick recovery of individual SharePoint items

Free tool – Veeam Explorer for Microsoft SharePoint, enables fast, easy restores of SharePoint sites, documents, libraries and lists — all with no agents to manage and no additional licenses to buy.

 
llevelAuthor Commented:
Edited text of question
0
 
llevelAuthor Commented:
Adjusted points to 290
0
 
mikeblasCommented:
What specific error message do you get from the linker?
0
 
mikeblasCommented:
What specific error message do you get from the linker?
0
 
llevelAuthor Commented:
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
 
mikeblasCommented:
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
 
llevelAuthor Commented:
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
 
mikeblasCommented:
Can you show your call to the function?

.B ekiM

0
 
llevelAuthor Commented:
   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
 
llevelAuthor Commented:
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
 
llevelAuthor Commented:
Hello, I hate to be a pest, but it's been some time since
you locked this question, and ...

0
 
mikeblasCommented:
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
 
llevelAuthor Commented:
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
 
mikeblasCommented:
Sorry; I can only anaylse what code you give me.

I've done all I can for you.

.B ekiM
0
 
llevelAuthor Commented:
Mikeblas, thank you for your effort. Could you please unlock the question so maybe someone else can have a shot at it?


0
 
mikeblasCommented:
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
 
llevelAuthor Commented:
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
 
llevelAuthor Commented:
Edited text of question
0
 
mikeblasCommented:
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
 
llevelAuthor Commented:
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
 
NickRepinCommented:
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
 
llevelAuthor Commented:
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
 
lowlevelCommented:
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
 
llevelAuthor Commented:
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
 
NickRepinCommented:
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
 
llevelAuthor Commented:
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
 
llevelAuthor Commented:
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
 
NickRepinCommented:
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
 
NickRepinCommented:
May be, there is implib32.exe with Microsoft compilers?
0
 
llevelAuthor Commented:
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
 
llevelAuthor Commented:
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 your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

  • 21
  • 8
  • 4
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now