Possible RAS bug?

Mar 17, 2009 at 3:39 PM
I'm posting this here since my other searches into this matter have so far panned out. Since people here have experience with RAS generally, I though I'd take the liberty of asking what might be regarded as a sligthly off topic question.

I'm developing an application that will use one of two interfaces (eventually with a VPN on top of one) depending on what is available. One interface at present is a cellular modem by Novatel; the other is an Agere Systems POTS modem. If the Novatel device is physically plugged in but not enabled (we have enable/disable stuff to prevent extra use) or is not plugged in at all, the list of dialup-type adapters includes this device still (due to its driver, I suppose). Now, the problem arises because there seems to be a bug in either the Novatel drivers (not confirmed with them as yet) or with Windows XP SP2. Now the bug is that the *device name* for each of the two modems is now the Agere thing. This bug is not purely cosmetic in the Network control panel; it appears that way through the RAS API that Jeff is nicely working on for us. So, if I have set up a machine to use the cellular system and it is not present, it is SUPPOSED to fall back to the POTS one. However, it does this imperfectly now, since it mistakes the devices: it makes an outgoing call using the dialing parameter of the cell system! This is annoying for all the reasons one would expect.

Thus I ask: has anyone encountered this bug and hence can confirm that this is an XP bug. If it is, is it fixed in SP3? (Our OS guys will be pushing that shortly.)
Coordinator
Mar 17, 2009 at 4:15 PM
Sounds like it'd be a problem with Windows more than the driver for your cellular modem. Perhaps you should build your failure system into the application you're using rather than letting Windows handle it. You'd have a lot more control over what it's doing if you wrote the application that way anyway. If you want to change the device being used to dial a connection, you'll need to update the RasEntry instance for that entry to use the device you want. The RasDialer component uses whichever device is listed in the entry while it's being dialed unless you haven't specified the name of an entry and simply provide it a phone number.

I'm not sure if there is anything available in the TAPI APIs to determine if a device is available, but I would think there would be. Maybe I'll do a bit of research on this when I get home later.

As for service pack fixes for RAS problems, I wouldn't count on it. I've been finding bugs with the API since I've been digging around in it. I'm sure most of this code has been around since Windows NT 4.0 and Windows 2000.
Mar 17, 2009 at 4:44 PM
Edited Mar 17, 2009 at 4:56 PM
Thanks for the advice, Jeff. What I'm doing now is checking (in the code) to see if there's an entry in the RAS phonebook with the name of the wireless connection, and if there is, using it first (falling back in the case of error). I guess I should check to see if it is of the right type, too. We don't yet know who is going to be providing the hardware, so I am trying to make the code independent of that, but alas I may have to not here as well ...

Edit: I hopefully will not actually run into this issue if the disable/enable device product we are using does what a colleague claims it does (and the Novatel drivers function the way they seem to).
Coordinator
Mar 17, 2009 at 4:58 PM
I wonder if you can query anything from WMI that'll tell you what kind of device it is. As far as I can tell, the name of the device in the RasDevice object should directly relate to a piece of hardware that's installed in the machine. That might give you some insight about the piece of hardware you're trying to use to dial a connection with.
May 29, 2009 at 1:39 PM

(Ressurrecting an old thread)

I've determined that the behaviour I discovered (as discussed above) is apparently by design, alas and thus unlikely to be fixed any time soon. (Cue "it isn't a bug, it is a feature!" chorus.) Anyway, looking at the *RasDevice* object doesn't seem to help, as that is precisely what gets clobbered. I can (and already do) detect what device is physically installed - this is how I decide which configuration and such to use. However, in order to get RAS to use the relevant device I thought I'd update a RasEntry.Device.Name field (getting the string via WMI), but unfortunately it is read only; one has to update the device object as a whole. This gets me no further ahead, as I cannot get the name in there for the same reason. I also tried creating a new RasDevice with the name passed to the constructor, but that class is set to Friend only ... grr. Am I missing something? How are RasDevices created? Only by the UI?

Coordinator
May 29, 2009 at 2:48 PM

RasDevices are created only from the Windows RasEnumDevices API or a device specified that's set on an entry. That's why everything I have everything locked down on the object. If I were to allow people to create new instances of the object, I'd essentially be allowing people to create new hardware on their machines without actually having the hardware installed.

RasDevice device = new RasDevice("My Fuzzy Slippers", "Pink Bunnies");

That scenario would be perfectly valid, which would cause problems with the dialer used by Windows when dialing network connections.

The way those devices are currently found, is by calling the API to have the machine indicate which devices are currently installed on the system. Which I've exposed a couple static methods on the RasDevice class to assist with locating devices. If you know the name of the device you want to retrieve, you can call the GetDeviceByName method. Once that's done, just set the Device on the entry and Update it in the phone book and it'll take effect.

May 29, 2009 at 3:06 PM

Sensible - I agree with the design decision.

I guess I'll have to do my stuff with GetDeviceByName ... problem is I haven't figured out when this "fallback" is NOT corrected by having the device present again, so it will be a pain to test. Oh well.

Coordinator
May 29, 2009 at 3:27 PM

I'm curious, if you get the source code, expose the constructor, and create the RasDevice instance yourself - what happens when Windows tries to use it? If the device isn't recognized by RasEnumDevices, would it even work?

Jun 2, 2009 at 3:43 PM

I haven't had the time to try do as you suggest, Jeff, but I did run into something else on this matter:

Update() seems to do a *complete* update; in particular various settings like the "default gateway on or off" thing get put back to "off" unless you set them explicitly. Is this a bug in Windows or in DotRas? I think it at least could appear in the documentation as a warning, if nothing else.

On the other hand, I did get a workaround to the problem above worked out, just that the "update" issue threw me through a loop - and the gateway thing is buried in the UI when one uses Explorer to set a connection up, so it took me a while to find it to realize that was the problem ...

Coordinator
Jun 2, 2009 at 4:03 PM

Looks like you found a bug in the project. That particular property isn't being set when the entry is retrieved through the RasGetEntryProperties API. If you want to fix it yourself for now, just go into the RasHelper class' GetEntryProperties method and place retval.Options = entry.options; in the block where all the properties are being copied over from the structure. I have them all alphabetized, so between "retval.NetworkProtocols = entry.networkProtocols;" and "retval.PhoneNumber = entry.phoneNumber;" would match everything else.

Guess I'll need to change the unit tests to check the objects returned from those methods to ensure all the information has been filled.

Coordinator
Jun 2, 2009 at 4:05 PM
This discussion has been copied to a work item. Click here to go to the work item and continue the discussion.
Jun 2, 2009 at 8:19 PM
Edited Jun 2, 2009 at 8:30 PM

I spoke too soon (in the issue that started this thread, not the spinoff bug). GetDeviceByName is *not* working. I have a sample device physically installed, drivers in the system, etc. but since there is no phonebook entry using it, thanks to that darn fallback, I *cannot* get it to be recognized in that list.

The question then becomes: how is the hardware listed in GetDeviceByName determined? Can there be a way to "force it to refresh" somehow?

 

Edit: I have now semi-determined that the updating of entries does occur on device insert but ONLY with one of my dev machine's USB ports. I am now baffled.

Edit 2: I have now tested that weird behaviour (see edit above) with the target machine. It updates only *some* of the entries (we have two for this device due to another weirdness with it; the default phone book entry doesn't work ...)

Coordinator
Jun 2, 2009 at 10:14 PM

I just checked in the changes to fix the bug you found with updating entry options earlier today.

The devices listed by GetDeviceByName is retrieved from the RasEnumDevices API in the SDK. That particular method is only there to reduce the amount of duplicate code everyone has to replicate to search for a specific device. It calls GetDevices and does the searching for a device name for you. I don't know what Windows does to determine the information retrieved by that function, and I'm fairly confident there is no way to force it to refresh.

I've exposed a Create method on the RasDevice class in the latest check-in, however be warned - just because you can create an instance of the device does not guarantee the availability or existance of the device when dialing the entry.

Jun 3, 2009 at 1:51 PM

So your 1.1 release will have these changes? (Or is there a way I'm missing to grab them now?)

I've now discovered something else stranger still. The problems I found with the updating entries *only* occurs with the Sierra Wireless Watcher application set to not autolaunch, at least with this particular device (I have to support several more, and will test those soon). Since we need the autolaunch off for our purposes ... Anyway, I'll post on the SW support page to see if I can confirm this bug.

Coordinator
Jun 3, 2009 at 2:31 PM

1.1 will have the changes yes, but that release is probably a ways off yet. You can go grab latest from the source code tab and they'll be available right now.

Jun 3, 2009 at 4:05 PM

Success, so far. (The batch file, even after removing the refences to the private key stuff didn't work, but opening the solution in VS worked once I got StyleCop installed.)Thanks for making the fix available promptly, Jeff. I'll be running a few more tests but the simple case in my code works with the new Create, so I do not anticipate problems.

Coordinator
Jun 3, 2009 at 4:45 PM

Yeah, the batch file was really only supposed to be used by me to build a full release. It does a lot more than just compiling the project.

It's too bad you couldn't use the methods to retrieve the devices, that's kind of upsetting it doesn't work when you're installing hardware.

Aug 18, 2010 at 1:41 PM
Edited Aug 18, 2010 at 1:42 PM

Resurrecting this thread again, since it has come back to haunt us.

We recently did a semi-production pilot test with our systems. Around 9 or so of 65 devices seemed to get this "won't rewrite the phonebook" to update when devices are reinserted. One of the support techs has a machine that *never* does it right with the SonyEricsson devices (any - we tried different instances of the same model). On the other hand, it is of different character than the bugs I discussed over a year ago. This time (on his machine; due to the other machiens being around the country I haven't seen them, but I suspect similar) the phonebook entry has the device (actually two, corresponding to different "aspects" of the same device from a user perspective) listed correctly, but in the *wrong order*, so the POTS modem gets dialed instead.

Grrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr. We have not found *anything* about how this process works and why it would be different on different machines (but built from the same disk image - the difference is in machine name and that sort of thing). I have discovered that the phonebook "rewrite" on device insert/removal is actually nothing of the kind; the file itself does not appear to change. This level of unreliability is making my managers wonder whether all of this "wireless" technology is premature, but I have the feeling it isn't that, but Windows. Where DOES one find an expert in device drivers, etc.? I looked in the DDK (scary!) and did not find anything useful.

Long story short: if anyone wanders by and has any advice, we'd be happy to receive it ...

Coordinator
Aug 18, 2010 at 2:51 PM

Hey Keith, I guess this is just one of those things that won't go away. Just to confirm, you don't think this is a problem with DotRas do you?

I'm not sure which phone book you might be using, but have you tried putting it in a custom location (ie. next to your app)? Perhaps the rewriting problem is from Windows monitoring the file. Also, if you're programmatically generating the entries, you could also kill the file and forcably rewrite it. Of course if you have it in the default location that would cause the user entries to be deleted, which is why I suggested storing the phonebook next to the app. You could do whatever you wanted to with it, without affecting the user and any custom entries they may have.

Using WMI to check which hardware is installed may be helpful, though it might just have the same problems as RAS does when playing musical chairs with the hardware.

Aug 18, 2010 at 3:51 PM

No, it has nothing to do with DotRas - one can see the out of order phonebook (or what *looks* like it) plain as day just with the Network Connections control panel.

The problem with using another phonebook, or dynamically rewriting as needed (though I already do this sometimes ...) is that the phonebook entries are created by the installer for each sort of device - i.e., the manufacturer does it. Although I could labouriously copy down everything, I know this is very fallible. I might have to start doing that. I am going to also try removing the POTS modem from the cellular entry - I am not sure why it even appears. I asked about this once and got sort of a shrug for an answer. At least that way the users who encounter the problem will hopefully fall back faster (rather than waiting a minute for the phone line to hang up).

WMI tells me that the device is installed, which is how matters pass my "make sure the user plugged in the device they are configured to use" test at the start up of my application. I do *not* know what determines the order in the phonebook entries as it seems to vary from machine to machine and, perhaps, spontaneously change on us.

I have used filemon to see if the phonebook gets written to. It doesn't. Gets read, though. A whole bunch of other stuff happens, including writes to mysterious files I cannot read because they are always in use. I suspect that these contain the mystery ...

Sep 2, 2010 at 6:52 PM

Finally!  I think at last I know what all of this is about, at least for the SonyEricsson version of the problem.

I've done some research on how Windows handles USB devices - had to hunt through some very obscure forums to do so; the WDK is even crazier and I am not sure this stuff is even in there. Anyway, for the sake of the record:

Windows distinguishes device by USB serial number (which seems to map to the WMI-accessible Plug and Play ID) and also by port. THis is why even mice and USB drives reload drivers when you plug them into USB ports. And this is why the SonyEricsson devices sometimes create problems: if your phonebook entry was created with device instance #1 (say) and you plug in (to the same port) #2, that's a *new* device. Subsequently the phonebook entry references to all the "POTS" type devices put it lower priority, since it is *not* the device you originally set up. Bingo, now lower priority than the built in non-cellular thing, try to dial it, no sale. The Sierra Wireless dvices are out of  the USB spec, but paradoxically, that's a *good* thing here, since they always look like the same device. (Even the different models 597 and 598 apparently have all the same identifiers.)

Solution, then, is to rewrite the phonebook entry with the device name for the attached device obtained via WMI.

I'm not entirely convinced the writeback is happening correctly, but I will do further investigations.

Coordinator
Sep 2, 2010 at 9:00 PM
Edited Sep 2, 2010 at 9:04 PM

Well I hope you found your answer Keith. I'm just glad I didn't try to hunt that one down, not that I could have even if I tried.

Edit: Come to think of it, if you nail down exactly what's causing the problem you could create a bug report for Windows on the Microsoft Connect website and see if they can fix it.

Apr 22, 2013 at 1:40 PM
ARRG! This has come back to haunt us - AGAIN - in our upgrade project. Seems that Windows 7 behaves differently than XP in this respect (or maybe it is just the modem types) and my fix of rewriting phonebook entries to force the device order to change doesn't work any more. (Confound: it is being done from a Windows Service running as SYSTEM now, because of the necessity of writing to the system phonebook ...)

In particular, it seems that sometimes it works. Sometimes also it works but does not show the modem as the right one (both with it appearing in the list and not!), which is weird but at least just confusing. But sometimes it fails, and it fails more with some Windows logins than others (or so it appears). Since the policy requirement to enable and disable on demand is being enforced now, disabling the internal modem (which is this time a cellular and the external is POTS ...) helps - or seems to - somewhat. Sometimes also it appears that the little Windows 7 UI of phonebook entries does not get updated. And even when an entry is deleted, I notice (though to what end I don't know) that the OS is still keeping track of all the old editions. We have a phonebook entry STC, and we make STC2 temporarily for the above reason; but then there are references to STCn for n >= 2 now ... in the location awareness thing which hopefully we also will get to turn off ...

I think I have to find some way to ask about this officially, though I despair about getting an answer.

I'm posting this just because it might matter to someone else (i.e., that their experiences are not unique) - but am I the only one who uses DotRas with several modem types at once?

For the sake of the record, the external POTS modem is a USB device, USR 5637. The internal is a cellular modem, Ericsson H5321.
Apr 22, 2013 at 3:16 PM
Update: It looks like the process works if the devices are both disabled prior to beginning; i.e. then we enable 1, do the update and everything is ok. If not, weird stuff happens.
Coordinator
Apr 22, 2013 at 4:38 PM
That doesn't seem surprising that Windows XP to Windows 7 changed how it behaves.

Can you reproduce the problem reliably now, or is it still an intermittent problem that users are occasionally reporting?
Apr 22, 2013 at 8:34 PM
It seems that if the USB one is enabled while trying to do the other device's entries, it fails altogether. If, however, the reverse is done, the entry works but has the wrong device visible. I think we're safe due to our enable/disable stuff, but others (if there are any) fighting with the same problem aren't so lucky, since they may wish to have their devices enabled all the time.
Apr 24, 2013 at 2:50 PM
Here's another fun fact in all of this.

Devcon returns without all of its side effects completed. I cannot tell if the actual enable is finished and then whatever mysterious process "picks up" devices for RAS (hence why I mention this here) is delayed or whether devcon runs and the device manager runs async even after devcon terminates. I would think it would have to be the former, since exit codes from devcon are always successful in such situations. I had a delay in place already, and now I'm going to have to guess how long to make one. Grumble!
Coordinator
Apr 25, 2013 at 3:05 AM
Have you considered using the RegisterDeviceNotification API to get notified when devices are added/removed from the system? Not really sure if it would do what you're looking for, but it could be used with a wait lock to make sure that you can hold the main thread until the device has been plugged in. Once the event gets raised, call RasDevice.GetDevices() and see if the device has been returned.

Looking at the API if you did have to implement it, you could follow a pattern similar to what I did with the RasConnectionWatcher, the APIs are quite similar how they work.

Just a thought, I could be way off base.
Apr 26, 2013 at 2:45 PM
That's an interesting thought, and I also saw a better use of WMI to do so as well. I'll have to consider it.
May 27, 2013 at 1:14 PM
I've looked at the RegisterDeviceNotification stuff and as far as I can tell that has to do with USB only. I don't know if the internal cellular modem in our new hardware counts (it doesn't get plugged in, just enabled, for example). I'm still investigating.

Meanwhile, I've posted to the driver forum, after someone on the "where's this go forum" at MSDN suggested I try there. It was ruled off topic, but I did learn (assuming correctness on the part of the moderator) that devcon does wait on the PNP stack but there is stuff that RAS and DUN and stuff do after that. And, needless to say, devcon doesn't wait on that. I was also told to talk to Microsoft support directly ...
May 30, 2013 at 7:34 PM
Edited May 30, 2013 at 7:47 PM
I have a question about all of this open at Microsoft, but meanwhile, I figured I'd ask here too:

How is the line PreferredDevice= in a phonebook entry filled in by the API? My symptom on my own testing machine is now that I get the following when rewriting the phonebook entry (and the only thing that looks wrong of relevance is that name):

EscalationObject.UpdatePhoneBookEntry: exception: System.ArgumentException: 'name' cannot be a null reference or empty string.
Parameter name: name
at DotRas.ThrowHelper.ThrowArgumentException(String argumentName, String resource, Object[] args)
at DotRas.RasDevice.Create(String name, String deviceType)
at DotRas.RasHelper.GetEntryProperties(RasPhoneBook phoneBook, String entryName)
at DotRas.RasHelper.SetEntryProperties(RasPhoneBook phoneBook, RasEntry value)
at DotRas.RasEntryCollection.InsertItem(Int32 index, RasEntry item)
at DotRas.Design.RasCollection`1.Add(TObject item)
at EricssonH5321gwBell.EricssonH5321gwBell.Update(String fullProperName, String phoneBookEntryName, String phoneNumberWanted)
at EricssonH5321gwBell.EricssonH5321gwBell.Update()
at EscalationService.Escalation.EscalationObject.UpdatePhonebookEntry(Int32 myPid, String password, String deviceSupportDllName)

Just before the pbk.Entries.Add that produces this error, a diagnostic logging confirms that both the entry name and the device name within that entry are non-null/empty strings. The phonebook entry itself is precreated (I see it in the phonebook file), successfully; it is just this add step which fails.

Crucial edit: It seems that this happens even if the device is enabled quite a while back; I did it manually this time to be sure. And the Windows 7 tray thing is very very confused now.
May 30, 2013 at 7:53 PM
Eureka!!!

I think I've got it! The name above is the name of the device of the other (external, POTS) modem, or conversely, sometimes, depending on the (&( ordering thing, the internal cellular relative to the external POTS. Enabling both seems to work perfectly, though of course this is what we don't want policywise. But I think that must be it!
Jun 17, 2013 at 8:30 PM
Edited Jun 17, 2013 at 8:37 PM
Jeff, is there any data-validation done when the RasEntryCollection is created? It looks like when devices are disabled they appear sometimes as devices with String.Empty as their name. I ask because I've finally gotten permission to talk the device-related questions through at Microsoft Premier support and want to ask a concrete question.

(I'm also asking what determines the order of devices in a phonebook entry and how to change it programmatically, which would help with some of this -maybe.)
Coordinator
Jun 18, 2013 at 12:18 AM
If there's any validation happening it's within the Win32 API, and not something I could change
Jun 18, 2013 at 8:43 PM
Edited Jun 18, 2013 at 8:50 PM
I've looked at a stack trace, and my code is doing the update of the phone book entry at the time, not exactly the read back into memory ... Loosely (my call at top, the library methods as they come):

add(entry)
InsertItem
SetEntryProperties
GetEntryProperties
RasDevice.Create

It is the create step which is where it goes wrong. retval is being assigned, and retval.Device calls RasDevice.Create with an empty name since the surrounding if only checks for a null deviceName (or null or empty type, but that's irrelevant). When does the structure called lpRasEntry get filled with (what becomes) String.Empty? I've asked Microsoft to clarify this call for us just in case, since I am starting to understand more of this now.
Jun 18, 2013 at 8:52 PM
It does seem that an empty string is not a documented return value:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa377274(v=vs.85).aspx does not list it as far as I can tell.
Coordinator
Jun 18, 2013 at 10:25 PM
Edited Jun 18, 2013 at 10:30 PM
Yeah it's definitely not a documented return value. The original RasDevice.Create method had a string.IsNullOrEmpty being done on the device name, but I had to remove it because of this very problem. Entries were coming back from the phonebook with an empty string, and causing the code to throw an exception to that effect. Since that empty string was causing the RasPhoneBook API to become impossible to use, and you couldn't even use DotRas to fix it programmatically, I made the decision to allow it to continue with an empty string in the device name.

I can't remember when I changed it, but it's probably been 2-3 years now since I did.

Edit: Forgot to answer your question.... The lpRasEntry struct gets szDeviceName filled with a string.Empty when returned from the RasGetEntryProperties Win32 API call internally. I do not set it to that, Microsoft is giving that back to me.
Jun 19, 2013 at 1:24 PM
Edited Jun 19, 2013 at 1:29 PM
I'm seeing that 1.2 introduced the change from null or empty to null only. Is that correct? The code looks that way, but I funnily enough cannot see it working that way. I'll test more - we weren't going to be using 1.2 for ease-of-upgrade reasons. EDIT: No, I just hadn't try to build our primary application with 1.2. Still, I'd like Microsoft to explain this.
Coordinator
Jun 19, 2013 at 9:48 PM
That sounds about right when it would have been introduced, the entries will not work if the device is an empty string, and will cause an exception when the entry is being saved, but the change allowed the caller to at least be able to open the phone book so that it can be fixed.
Jun 28, 2013 at 7:34 PM
Edited Jun 28, 2013 at 7:35 PM
I got an answer about empty strings:

Hi Everyone:

I received a response this morning from the RAS product group. I’ll just quote verbatim:

“The device name is empty if there was no valid modem present when the profile was created. Device name will not be cleared dynamically on disabling the modem.

You could use the API RasEnumDevices to get the list of RAS capable devices which will give only the enabled devices.”

So, the library vendor can’t rely on the disabled device’s name being empty in the RASENTRY structure after calling RasEnumEntries. However, in conjunction with RasEnumDevices the vendor should be able to determine which devices are enabled or diabled, and therefore which phonebook entries are linked to valid (enabled) modem devices.

Thanks

Does this help us any? I'm trying to sort through this for my own stuff.
Coordinator
Jun 29, 2013 at 12:03 AM
Yeah, but you're not disabling it when it occurs... you're physically removing the device from the system, aren't you?
Jul 2, 2013 at 5:18 PM
Edited Jul 2, 2013 at 5:19 PM
Both. I've gotten some further information:

I’m not sure what you mean when you say “So how do programs which want to use a specific ordering…”. Any ordering will need to be done by your own program. The RAS API’s will not order phonebook entries or devices for you.

In terms of the RAS API:
1) Use RasEnumEntries to enumerate phonebook entries for a specific phonebook.
2) Use RasGetEntryProperties to get information about a specific phonebook entry. This information will include the device associated with the phonebook entry. It will not tell you if the device is enabled however.
3) Use RasEnumDevices to enumerate the enabled devices.
4) If the device returned in step 2 is not included in the device list obtained in step 3, you will know that the device is disabled.

Please look at the following MSDN links:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa377380(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa377535(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa377274(v=vs.85).aspx
http://msdn.microsoft.com/en-us/library/windows/desktop/aa377289(v=vs.85).aspx


I understand that you aren’t using the RAS API’s yourself, you’re using a third party library. We can’t help you with that library. However, you’re free to pass our recommendations onto to the library vendor.

So it looks like the ordering of the devices is not in one's control.
Coordinator
Jul 2, 2013 at 6:37 PM
I'm basically doing steps 1 and 2 already underneath the hood. The problem is when your entries come back, they've got an empty string in the device name, so I technically don't know what device it is using to compare it against the list returned by RasEnumDevices.

You can see what's coming in and out of the RAS APIs internally if you enable the trace source that is now included in DotRas. In which case, you can tell that the device name returned is an empty string. The information being provided by the person you're talking to isn't matching what the RAS API is doing. He's saying that the device is included with the results from RasGetEntryProperties, and I'm saying that they aren't. In order to do steps 3 and 4, the information would need to be included in the results.

Instructions can be found here how to enable the DotRas trace source to confirm what I'm saying.
Jul 2, 2013 at 7:35 PM
Edited Jul 2, 2013 at 7:36 PM
Yes, I've noticed about 1 and 2. Could the claim be that one should:
1) Get the entries
2) Decide which entry to use
(No change to here)
3) props = RasGetEntryProperties(entry)
4) devs = RasEnumDevices()
5) if props.device not in devices ("device disabled don't use this entry")

The problem is still the fact the entry "sort of" has other devices associated with it (obviously not directly in the data structure, since RasEntry has no room for them); I've been told plainly the ordering is not under the programmer's control, so what is one supposed to do in this case?

From my followup question, I was told that "request that your library vendor provide the ordering for you" (or do it myself - but how??), which is weird, to say the least. Can't say it is unexpected, unfortunately.

EDIT the last paragraph was written after I received the followup to my request for clarification.
Coordinator
Jul 2, 2013 at 8:46 PM
I believe they're talking about prioritizing the device list yourself as you were essentially doing. As you said, the RasEntry structure doesn't provide space for a list of devices it should use, you'd have to replace the device with whichever device you wanted prior to dialing the connection.

Seems to me like the steps might be:
1) Get the entry
2) Determine if the first device it should use is available
3) If not, determine if the second device it should use is available
4) Update the entry with whichever device it is supposed to use
5) Dial the connection

Rather than using multiple entries to handle it, as long as the type of device you're using is the same (ie: not trying to go from VPN to a modem) swapping which device is to be used shouldn't be any harder than changing the Device property on the RasEntry object. Given that when the device is removed the device name comes back empty, I have no way of knowing whether the device has been disabled. As far as I'm aware, I don't know anything about which device it is or was using.

As for your follow-up question, more than likely they're hinting that I should provide some way of giving a list of devices that should be used and handle the steps I outlined above for you. However, given that it's pretty specific to your implementation, and I'd have to implement some kind of storage mechanism for the configuration data, I'd rather leave that up to the developers that use the product to implement themselves.
Aug 13, 2013 at 2:24 PM
Edited Aug 13, 2013 at 3:33 PM
(Here we go again!) As previously, I simply document my thoughts and problems here.

I've done a release where the Device is updated by writing back appropriately) i.e., with my stored version of the name and "modem") rather than writing whole phonebook entries. This works some of the time. Other times, the dial fails - RAS error 633, the famous "device problem" which doesn't say a heck of a lot. A tester and I did a whole bunch of tests with various permutations of restarts and relogins and what not. Doesn't seem to be any discernable pattern there or anywhere else we've been able to ascertain. It is intermittent, to say the least. Generally successes seem to breed success, but even that's not completely true.

Jeff: Why does the call to UnsafeNativeMethods.Instance.SetEntryProperties (RasHelper.cs, in the 1.2 or 1.3 source) set the device parameter to IntPtr.Zero (and the buffer size to 0)? There's no conditional compilation there: the documentation for the native method it seems to call says that this approach is for XP compatibility. For the purposes I've discussed, would it make sense to write this back? How else does the device stuff get updated? What am I missing here?

I've been trying to figure out the effect of assigning the device created by RasDevice.Create to myEntry.Device so maybe I can ask a better question to Microsoft. If there's another method that does the writing here when the assignment takes place, and I've missed it, please let me know.

EDIT: I realize there is also the device stuff in the entry itself. What's the difference?
Coordinator
Aug 13, 2013 at 11:47 PM
"Why does the call to UnsafeNativeMethods.Instance.SetEntryProperties (RasHelper.cs, in the 1.2 or 1.3 source) set the device parameter to IntPtr.Zero (and the buffer size to 0)?"

Because it was deprecated as of Windows XP, and it's already stored on the entry. Supporting both methods of storing device data for one operating system just didn't seem to make any sense, so I just pushed NULL and 0 into the parameters.

For the official documentation see:
http://msdn.microsoft.com/en-us/library/windows/desktop/aa377827(v=vs.85).aspx

MSDN says that as of Windows XP the parameter is unused. I wish I had a better answer about what the difference is, but to be completely honest I just don't know. I don't work at Microsoft, so anything I say would merely be conjecture.

"How else does the device stuff get updated?"
The device information is supposed to be pushed into RasSetEntryProperties on the RASENTRY structure using the device name and type fields. That's the only way to change the device for an entry. At least that's been exposed through the Win32 API, if there's stuff under the hood in RAS doing it directly, I don't know.

So about creating devices, that method was specifically introduced to help you deal with this problem you've been having. What Windows does with it under the hood I'm not sure, all I remember about our previous conversations was that your devices were occasionally not being returned from Windows via RasEnumDevices.
Aug 27, 2013 at 3:48 PM
More information for those who would also be doing any of this crazy stuff we do,

I am just running final tests now, but I believe I have determined that RasDevices.GetDevices() is more accurate as to the proper state of DUN devices than WMI's Win32_POTSModem. The latter (even when qualified with Status >= 3) includes the devices which are actually not usable by DUN/RAS as far as I can tell.

I have put RasDial (i.e. the built in tool) in a tight loop (in a batch file) with enable and disable calls to devcon. If one throws in a waitfor to use a 1 second delay, it seems to work every time to dial. If there is no wait or one uses the bogus 0 value with waitfor, that seems to be enough to always get a 797 (device missing). This doesn't correspond exactly to the 633 I was getting in my own code (and 631?), but for the moment I'm going on the assumption that they are symptoms of the same problem. I have also started experimenting with putting a 1 second delay after the call to devcon in my code - i.e., before the open the phonebook call. This seems to help, though it is a "bandage fix" in a way. If I'm right about GetDevices(), I suppose I could block on that for a bit instead. I do have an open question to our hardware vendor to see what they say about 633 ...
Aug 29, 2013 at 2:23 PM
An addition to the above ... I've released (to testing) a version of one of our DotRas using applications. Blocking on the RasDevices.GetDevices() returning a modem seems to do the trick, though I'm giving a few days for people to investigate. Meanwhile, I have discovered that there is a fair bit of variability in how long that takes to work, even with the same hardware and approximately the same resource usage on the machine (CPU and disk, anyway). Initial reports (at 1 second resolution) suggest as much as a factor of 8. This is very bizarre.