Connection Service Providers and Proxies

The Connection Manager uses what is known as a Connection Service Provider (CSP) to talk over a particular network. Each individual provider is a COM object that encapsulates the specifics for an individual network's communications. For example, there are currently CSPs for networking, proxy servers, VPNs, and GRPS connections?each providing specific instructions about how to talk over a network. When you request a network connection, the Connection Manager will determine which CSP to use based on the cost, latency, and bandwidth for the resource you are trying to access.

To exchange information with a CSP object, you can use the ConnMgrProviderMessage() API function:

HRESULT WINAPI ConnMgrProviderMessage(HANDLE hConnection,
   const GUID *pguidProvider, DWORD *pdwIndex, DWORD dwMsg1,
   DWORD dwMsg2, PBYTE pParams, ULONG cbParamSize);

The hConnection parameter is optional but can be set to a particular request handle if one is active. The next parameter, pguidProvider, should point to the GUID of the CSP to which you want to send a message. If multiple network providers are being used by a single connection, then you can set the pdwIndex pointer to the index of the specific provider to which the message should be sent. Both dwMsg1 and dwMsg2 are optional and have different meanings depending on the provider and message being sent. The pParams parameter should point to a data structure specific to the provider you are talking with, and is followed by cbParamSize, which should point to the size of the structure.

By this point, you are probably asking yourself why communicating with the provider interfaces is useful. One of the most common uses for sending a connection service provider a message is to obtain the proxy server configuration options for a particular communications request.

You can get proxy configuration information by passing a PROXY_CONFIG structure to the network provider defined by IID_ConnPrv_IProxyExtension. After the ConnMgrProviderMessage() function is called, the structure will be filled in with the requested information for the proxy type. The PROXY_CONFIG structure is defined as follows:

typedef struct _PROXY_CONFIG {
   DWORD dwType;
   DWORD dwEnable;

The dwType member specifies the type of proxy server to use. It can be set to the following: CONNMGR_FLAG_PROXY_HTTP (for standard HTTP proxies), CONNMGR_FLAG_PROXY_WAP (for a WAP gateway), CONNMGR_FLAG_PROXY_SOCKS4 (for a SOCKS 4.0 server), or CONNMGR_FLAG_PROXY_SOCKS5 (for a SOCKS 5.0 server). This member should be set before calling the function.

The dwEnable member specifies whether the CSP should have the capability to connect to the specified proxy server. The CSP automatically sets this to 1, which enables the proxy server. If you set it to 0, then although the proxy configuration will exist, the CSP will not connect to the server.

The szProxyServer member specifies the server and port of the proxy. The correct syntax for setting this should be a null-terminated string that contains the server name, a colon, and the port number (for example, server:port).

The szUsername and szPassword members specify the authorization to be used when communicating with a SOCKS4 or SOCKS5 proxy server.

The szProxyOverride and szExtraInfo members are not currently used.

The following example shows how you could obtain the proxy information for a standard HTTP request:

// Get information on the proxy for an HTTP connection
// request
PROXY_CONFIG proxyConfig;
DWORD dwSize = sizeof(PROXY_CONFIG);
HRESULT hr = 0;
GUID IID_ConnPrv_IProxyExtension = {0xaf96b0bd, 0xa481,
   0x482c, {0xa0, 0x94, 0xa8, 0x44, 0x87, 0x67, 0xa0, 0xc0}};

memset(&proxyConfig, 0, sizeof(PROXY_CONFIG));
proxyConfig.dwType = CONNMGR_FLAG_PROXY_HTTP;

hr = ConnMgrProviderMessage(NULL, &IID_ConnPrv_IProxyExtension,
    NULL, 0, 0,
    (PBYTE)&proxyConfig, dwSize);

if(FAILED(hr)) {
   OutputDebugString(TEXT("Could not get the proxy
   return FALSE;