I'm maintaining a port monitor for a virtual printer, and I noticed that some of the interface we implement, including AddPort, have been marked as obsolete (see: http://msdn.microsoft.com/en-us/library/windows/hardware/ff545022(v=VS.85).aspx). Problem is, the documentation doesn't say what methods to use instead.
The port monitor must still have to deal with adding ports though right?
There doesn't seem to be any other non-obsolete replacements in the Monitor2 structure either (see: http://msdn.microsoft.com/en-us/library/windows/hardware/ff557532(v=vs.85).aspx).
Any ideas?
Thanks!
Port monitors are distributed components with a server- and client-side DLL. The client-side DLL provides the UI functionality of AddPort with the AddPortUI function. That function sends a request to the monitor's server-side DLL via the XcvData function with DataName set to the string "AddPort". The server component then actually implements the AddPort functionality.
Related
I don't know if there is an API that makes this possible or if I would have to roll my own. Here is what I'm trying to accomplish.
I have an application that connects to an NT service to start a session with another COM server.
Application, the client.
Broker NT Service; (system account context).
Session COM Service; (system account context, will impersonate user as needed).
The session server will have a running instance for every application instance that connects to the NT service. The application can request that the session server load COM library DLLs and host objects and services from those DLLs in the session server. The DLLs register via registration-free activation.
Creating objects from the session server and passing them back to the application works fine as long as they are IDispatch derived, which is a requirement of entire system since it is expected that scripting languages may use this, and that is the interface requested. C++ application may also use objects hosted in the session server. But IDispatch is an overly verbose interface to deal with in C++.
My question is this:
Given that the DLLs being hosted have dual custom interfaces that the application does know about, and type information about those interface can be read by the application via ITypeInfo; Is there an API that at runtime will create a proxy to mimic the original custom interface if I can provide it the IDispatch interface, which also carries the ITypeInfo information. All the proxy needs is call the IDispatch interface, but appear to C++ as the custom interface. A more optimal solution would be to use the same proxy, the default OLE Automation proxy, that the DLLs registered in its manifest.
I cannot register the proxy/stubs for the DLLs since multiple application may have the same modules, but differing in version, hence the use of registration-free activation.
Any [oleautomation] interface (and any [dual] interface) described in a type library can use the type library marshaler.
Here, you trade the trouble of finding a proxy-stub DLL to that of finding a type library. So, you declare the interface and the type library in your assembly's manifest (directly under the assembly element) like this:
<comInterfaceExternalProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{00020424-0000-0000-C000-000000000046}"
tlbid="{TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT}" />
<!-- This also works for a type library embedded in a DLL -->
<file name="FooBar.tlb">
<!-- If you have multiple embedded type libraries, use the resourceid attribute -->
<typelib tlbid="{TTTTTTTT-TTTT-TTTT-TTTT-TTTTTTTTTTTT}"
version="1.0" />
</file>
If your interface were not an [oleautomation] interface, and you'd want to isolate the proxy-stub DLL, you'd use something like this:
<file name="FooBarPS.dll">
<comInterfaceProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}"
threadingModel="Both" />
</file>
A comInterfaceProxyStub is much like a comClass, but focused on proxy/stubs and it gets associated with an interface.
You can accomplish the same effect with a pair of comInterfaceExternalProxyStub (under an assembly element level) and comClass (under a file element), in case you want to test with and without an isolated proxy/stub DLL, by (un)commenting the proxy/stub file section:
<comInterfaceExternalProxyStub name="IFooBar"
iid="{IIIIIIII-IIII-IIII-IIII-IIIIIIIIIIII}"
proxyStubClsid32="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}" />
<file name="FooBarPS.dll">
<comClass description="PSFactoryBuffer"
clsid="{PPPPPPPP-PPPP-PPPP-PPPP-PPPPPPPPPPPP}"
threadingModel="Both" />
</file>
I'm not sure, but if your standard proxy/stub DLL is used for more than one interface, you must use this approach as well.
EDIT: It seems none of this is new to you. Your problem is that in the session service, even though you activate the dynamically loaded libraries' manifest, that state remains only in the current thread. So, COM worker threads (e.g. RPC threads) will not know about your interfaces, coclasses and proxy/stubs.
The error you see in the broker service (REGDB_E_IIDNOTREG) might originate in the marshaling back from the session service. You don't get that error in the session service because it happens after your methods return.
However, it might be happening in the broker service, as it's natural: it doesn't load any libraries, much less their manifests.
The approach I suggest you take is to make the session service and the broker service have manifests that depend on the assemblies where you declare the registration-free COM information. This way, it'll all be part of the default activation context and you don't have to do anything regarding activation contexts.
Remember, you have no control over the activation context of a thread you don't own, other than having the default activation context include what you need upfront.
Regarding this part of your question:
I cannot register the proxy/stubs for the DLLs since multiple application may have the same modules, but differing in version, hence the use of registration-free activation.
It's not clear to me what you're trying to say. If your modules are backwards compatible, you don't need to worry. If they're not, use different CLSIDs/ProgIDs.
I hope you don't mean you're using the same IIDs with actually different interfaces, as that is a violation of COM. The best way to solve this problem is to not do it, period. Another way is to have dedicated threads with dedicated activation contexts, both in the session service and in the broker service, which as you've probably seen with only the session service, this is a very brittle approach.
As I see it, you may have no need for COM isolation at all. But if you still want it, you need to do it for both services, broker and session, and do it from their manifests, instead of at runtime.
One option is to give up on the hard-typed dual interface and use IDispatch-only dispinterfaces via hard-typed, compile-time generated smart pointer wrappers. You'd use VC++ #import with raw_dispinterfaces and/or no_dual_interfaces options to generate those.
The COM marshaler doesn't need a type library to marshal IDispatch::Invoke calls. You'd however need to compile against the version of the type library/DLL you're going to run side-by-side. Or at least make sure the DISPIDs and method signatures remain the same across all versions of the COM DLL. AFAIR, the generated smart pointers don't use IDispatch::GetIdsOfNames, so DISPIDs are hard-coded.
The IDispatch::Invoke performance might be sub-optional compared to direct dual interface calls, but I don't think it matters, giving the inter-process call scenario you've described. A marshaled out-of-proc COM call is much more expensive than a in-process IDispatch::Invoke call.
I want to implement WiFi manager program which should handle the following.
notification on wi-fi access point has come or gone
provide information of available wifi access point
connect/disconnect with a given wi-fi access point
Which is the recommended C/C++ WiFi library for Linux to achieve this?
On Fedora (at least), the preferred way to interact with NetworkManager is via DBus.
While wireless-tools and the like will work — even direct kernel calls, if you must — there are a couple of problems:
You'll probably need superuser privileges
NetworkManager will probably have a panic attack and get into fights with you, unless you stop its service
The user's normal networking controls (e.g. desktop tray icons) are almost certainly configured to use NetworkManager.
You can send and receive DBus messages for all the tasks you mentioned, for WiFi as well as arbitrary other types of network interfaces. The API is published here, for version 0.8.
For newer operating systems, there are apparently changes in the API, with a migration guide.
Their wiki should be really helpful.
I know both Fedora and Ubuntu use NetworkManager by default; I believe many other systems do, as well, but don't have an exhaustive list.
Of course, if you're using an embedded system, custom distribution, or something, then your mileage may vary.
That would be wireless-tools
I would recommend using directly the NetworkManager Library.
You can use low-level D-Bus library or libnm-glib library, that makes communication easier: example add connection glib
For more info, you can take a look into the code of the command line client nmcli.
I use cwebpage_src code and I need to update some HTTP request headers while clicking on links. As I understand it can be done with self implementation of IHttpNegotiate->BeginTransaction. But how to get my IHttpNegotiate implementation called??
Thanks!
Although I have no experience of writing one, I believe that you need to write an asynchronous pluggable protocol, as recommended in this thread.
Details of how and why to do this are scattered around the web in various places, but the best exposition that I've read is in this post by Igor Tandetnik (abridged here for brevity):
There are several technology layers
that support the download and
navigation in Internet Explorer and
WebBrowser control. At the top, there
is WebBrowser itself and MSHTML object
that provides HTML parsing and
rendering. The client uses such
interfaces as IWebBrowser2 and
IHTMLDocument2 to communicate with
these high-level objects.
WebBrowser and MSHTML use URL Monikers
library to perform actual downloads.
URLMon exposes its services via
IMoniker and IBinding interfaces, and
the client (say MSHTML) implements
IBindStatusCallback and a number of
associated interfaces, e.g.
IHttpNegotiate or IAuthenticate.
Next down is an Asynchronous Pluggable
Protocol handler. An APP encapsulates
the details of a particular protocol,
such as http, file or res.
...
Most of the time, an application
hosting a WebBrowser control (or a BHO
running inside IE) uses high-level
services provided by WebBrowser and
MSHTML objects. However, sometimes
these services are insufficient, and a
lower-level hook is required.
...
It would be nice to be able to hook
into the communication sequence
between WebBrowser/MSHTML and URL
Monikers. Unfortunately, there does
not seem to be any way to do that - at
least, none that I know of. So, we
look at the next level - a
communication between a URL moniker
and an APP.
...
Now, it is rarely necessary to
implement a full-blown APP from
scratch - after all, how often do new
protocols actually get defined? But
for our purposes, it is useful to
implement a so-called passthrough APP
(pAPP). A pApp is an object that
implements both sides of URL
moniker-to-APP communication, that is,
it implements both IInternetProtocol
and IInternetProtocolSink /
IInternetBindInfo. We register it as a
temporary handler for a standard
protocol, such as HTTP. Now whenever
an HTTP request needs to be sent, URL
moniker will create an instance of our
pAPP and ask it to do the job. The
pAPP then creates an instance of a
standard APP for the protocol in
question (I call it a target APP, or
tAPP, but be aware that I've invented
the terminology myself, it's not
widely accepted, suggestions for a
better naming convention are welcome)
and acts as its client. At this point,
our pAPP becomes a proverbial
man-in-the-middle. In the simplest
case, any method call made by URL
Moniker on pAPP is forwarded to tAPP,
and any method call made by tAPP on
pAPP is forwarded back to URL Moniker.
The pAPP gets to observe and, if
desired, modify every bit of
information relevant to this request
passing back and forth between the
moniker and the tAPP.
Igor has a couple of sample projects that should help in writing your own pAPP:
PassthruApp.zip
PassthruAppBeta.zip
I'm using C++/boost::asio under Win7.
I'm trying to "sniff" trafic over a given TCP/IP port. Hence, I'd like to listen on that port, receive messages, analyze them, but also immidately allow them to flow further, as if I never intercepted them. I want them to sink into the program that normally listens and connects on that port. Imagine a transparent proxy, but not for HTTP.
I'd rather find a code-based solution, but barring that, maybe you would suggest a tool?
what you are trying to do is basically a firewall program.
On windows there is several approach to do that, you can hook winsock. The better (or not hacky) is to use TDI filter (you take a look a this) or to make a NDIS filter.
Microsoft also introduced new API, WPF and LSP. I think you have better to use it because the TDI filter and NDIS wrapper involve driver programming which complicated and can be time consuming.
If this is for a product you are developing you may want to take a look at the WinPcap library http://www.winpcap.org/ which you can embed into your own program.
If you just need to analyze for yourself, use one of the tools that uses WinPcap, I have had great success with WireShark; but check out the WinPcap site for other tools
You cannot use boost::asio (or any other socket based library) for this as it consumes all the traffic.
I need to do a number of network-related things in C++ that I would normally do with ifconfig in Linux, but I'd like to do it without parsing the output of a group of system calls. Which C or C++ libraries can I use to tell if a network adapter is up or down, read or change an adapter's IP address and netmask, and change the default DNS gateway?
Basically you need to make a bunch of ioctl calls using a socket handle (SIOCGIFADDR, SIOCADDRT). You can find sample programs that use it in the Linux kernel source under Documentation/networking. Some other links that might be helpful:
Network Interface operations on AIX
XBMC's implementation (check out CNetworkInterfaceLinux)
EDIT: Let me also add that if your target is desktop linux, then you can consider using the DBUS API to query network parameters using the NetworkManager.
http://people.redhat.com/dcbw/NetworkManager/NetworkManager DBUS API.txt (sorry there's some issue inserting links in edits)
You can always look at ifconfig's source code to see how they did it in the first place: http://archive.ubuntu.com/ubuntu/pool/main/n/net-tools/net-tools_1.60.orig.tar.gz
The NetworkManager service exposes an API over dbus for querying/manipulating the networking on many distributions these days. This may be too high-level for your purposes (e.g. you require finer control of the network, or dbus/NetworkManager are not available on the system...), but it may provide you with what you need.
Check out the dbus C++ bindings and the NetworkManager API (sorry, I can't find a better formatted version right now, but the information is there).