403 lines
11 KiB
C++
403 lines
11 KiB
C++
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// File: cmsample.cpp
|
||
|
//
|
||
|
// Module: CMSAMPLE.DLL
|
||
|
//
|
||
|
// Synopsis: Main source for changing proxy file setting using a Tunnel Address
|
||
|
//
|
||
|
// Copyright (c) 2000 Microsoft Corporation
|
||
|
//
|
||
|
// Author: tomkel Created 11/02/2000
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
#include <windows.h>
|
||
|
|
||
|
//
|
||
|
// Function prototypes
|
||
|
//
|
||
|
LPSTR *GetArgV(LPTSTR pszCmdLine);
|
||
|
BOOL ReadProxyServerByTunnelAddressFromFile(LPCSTR pszSourceFile, LPSTR pszTunnelAddress, LPSTR *ppszProxyServer);
|
||
|
BOOL WriteProxyServerSettingToFile(LPCSTR pszSourceFile, LPSTR pszProxyServer);
|
||
|
HRESULT WINAPI SetProxyUsingTunnelAddress(HWND hWnd, HINSTANCE hInst, LPSTR pszArgs, int nShow);
|
||
|
|
||
|
|
||
|
#define CMSAMPLE_STARTING_BUF_SIZE 256 // Starting size of the string buffer
|
||
|
|
||
|
const CHAR* const c_pszManualProxySection = "Manual Proxy"; // Section to update
|
||
|
const CHAR* const c_pszProxyServer = "ProxyServer"; // Key to update
|
||
|
const CHAR* const c_pszTunnelAddressSection = "Tunnel Address"; // Section to read
|
||
|
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: SetProxyUsingTunnelAddress
|
||
|
//
|
||
|
// Synopsis: Entry point for changing the proxy file settings using a tunnel
|
||
|
// address. The parameters to the dll are passed via a string which
|
||
|
// contains parameters.
|
||
|
//
|
||
|
// Arguments: HWND hWnd - Window handle of caller
|
||
|
// HINSTANCE hInst - Instance handle of caller
|
||
|
// LPSTR pszArgs - Argument string
|
||
|
// int nShow - Unused
|
||
|
//
|
||
|
// Returns: DWORD WINAPI - Error code
|
||
|
//
|
||
|
// History: tomkel Created 11/02/2000
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
HRESULT WINAPI SetProxyUsingTunnelAddress(HWND hWnd, HINSTANCE hInst, LPSTR pszArgs, int nShow)
|
||
|
{
|
||
|
HRESULT hr = S_FALSE;
|
||
|
LPSTR* ArgV = NULL;
|
||
|
LPSTR pszServiceDir = NULL;
|
||
|
LPSTR pszTunnelAddress = NULL;
|
||
|
LPSTR pszProxyFile = NULL;
|
||
|
LPSTR pszTunnelFile = NULL;
|
||
|
LPSTR pszTunnelSettingFilePath = NULL;
|
||
|
LPSTR pszProxyFilePath = NULL;
|
||
|
LPSTR pszProxyServer = NULL;
|
||
|
DWORD dwTunnelPathLen = 0;
|
||
|
DWORD dwProxyPathLen = 0;
|
||
|
DWORD dwProxyServerLen = 0;
|
||
|
HANDLE hCurrentHeap = GetProcessHeap();
|
||
|
int i = 0;
|
||
|
|
||
|
//
|
||
|
// Parse out the command line parameters
|
||
|
//
|
||
|
// command line is of the form: /ServiceDir %SERVICEDIR% /TunnelServerAddress %TUNNELSERVERADDRESS% /ProxyFile <PROXYFILE> /TunnelFile <TUNNELFILE>
|
||
|
|
||
|
//
|
||
|
// Check if we have any arguments
|
||
|
//
|
||
|
if (!pszArgs)
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Separate each argument in the string by '\0' and return a list of pointers
|
||
|
// to each argument
|
||
|
//
|
||
|
ArgV = GetArgV(pszArgs);
|
||
|
|
||
|
//
|
||
|
// Check if we have any valid parsed arguments
|
||
|
//
|
||
|
|
||
|
if (!ArgV)
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Search the command line arguments for the following switches and their
|
||
|
// corresponding values
|
||
|
//
|
||
|
while (ArgV[i])
|
||
|
{
|
||
|
if (0 == lstrcmpi(ArgV[i], "/ServiceDir") && ArgV[i+1])
|
||
|
{
|
||
|
pszServiceDir = (ArgV[i+1]);
|
||
|
i = i+2;
|
||
|
}
|
||
|
else if (0 == lstrcmpi(ArgV[i], "/TunnelServerAddress") && ArgV[i+1])
|
||
|
{
|
||
|
pszTunnelAddress = ArgV[i+1];
|
||
|
i = i+2;
|
||
|
}
|
||
|
else if (0 == lstrcmpi(ArgV[i], "/ProxyFile") && ArgV[i+1])
|
||
|
{
|
||
|
pszProxyFile = ArgV[i+1];
|
||
|
i = i+2;
|
||
|
}
|
||
|
else if (0 == lstrcmpi(ArgV[i], "/TunnelFile") && ArgV[i+1])
|
||
|
{
|
||
|
pszTunnelFile = ArgV[i+1];
|
||
|
i = i+2;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// Unknown option.
|
||
|
//
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Make sure we have values for the arguments
|
||
|
//
|
||
|
if (!pszServiceDir || !pszTunnelAddress || !pszProxyFile || !pszTunnelFile)
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Check to see if we got zero length string values from the command line arguments.
|
||
|
// Exit if that is the case
|
||
|
//
|
||
|
if (!(*pszServiceDir) || !(*pszTunnelAddress) ||
|
||
|
!(*pszProxyFile) || !(*pszTunnelFile))
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Calculate the string size for the two paths that need to be created
|
||
|
//
|
||
|
dwTunnelPathLen = lstrlen(pszServiceDir) + lstrlen(pszTunnelFile) + 2; // 1 space for NULL, 1 for backslash
|
||
|
dwProxyPathLen = lstrlen(pszServiceDir) + lstrlen(pszProxyFile) + 2; // 1 space for NULL, 1 for backslash
|
||
|
|
||
|
//
|
||
|
// Allocate the memory
|
||
|
//
|
||
|
pszTunnelSettingFilePath = (LPSTR)HeapAlloc(hCurrentHeap, HEAP_ZERO_MEMORY, dwTunnelPathLen); // ANSI - char == byte
|
||
|
if (!pszTunnelSettingFilePath)
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
pszProxyFilePath = (LPSTR)HeapAlloc(hCurrentHeap, HEAP_ZERO_MEMORY, dwProxyPathLen); // ANSI - char == byte
|
||
|
if (!pszProxyFilePath)
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create the full path to the Tunnel Address file
|
||
|
//
|
||
|
|
||
|
if ( wsprintf(pszTunnelSettingFilePath, "%s\\%s", pszServiceDir, pszTunnelFile) < (int)(dwTunnelPathLen - 1))
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Create the full path to the Proxy file
|
||
|
//
|
||
|
|
||
|
if (wsprintf(pszProxyFilePath, "%s\\%s", pszServiceDir, pszProxyFile) < (int)(dwProxyPathLen - 1))
|
||
|
{
|
||
|
goto exit;
|
||
|
}
|
||
|
|
||
|
if (ReadProxyServerByTunnelAddressFromFile(pszTunnelSettingFilePath, pszTunnelAddress, &pszProxyServer))
|
||
|
{
|
||
|
//
|
||
|
// Call WriteProxyServerSettingToFile - the function checks for empty strings
|
||
|
//
|
||
|
if(WriteProxyServerSettingToFile(pszProxyFilePath, pszProxyServer))
|
||
|
{
|
||
|
hr = S_OK;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
exit:
|
||
|
//
|
||
|
// Clean up allocated memory
|
||
|
// Delete the argument pointers, Tunnel Server path, Proxy file path and ProxyServer name pointers
|
||
|
//
|
||
|
if (ArgV)
|
||
|
{
|
||
|
HeapFree(hCurrentHeap, 0, ArgV);
|
||
|
}
|
||
|
|
||
|
if (pszTunnelSettingFilePath)
|
||
|
{
|
||
|
HeapFree(hCurrentHeap, 0, pszTunnelSettingFilePath);
|
||
|
}
|
||
|
|
||
|
if (pszProxyFilePath)
|
||
|
{
|
||
|
HeapFree(hCurrentHeap, 0, pszProxyFilePath);
|
||
|
}
|
||
|
|
||
|
if (pszProxyServer)
|
||
|
{
|
||
|
HeapFree(hCurrentHeap, 0, pszProxyServer);
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: ReadProxyServerByTunnelAddressFromFile
|
||
|
//
|
||
|
// Synopsis: Reads the proxy settings from the given proxy file and stores them
|
||
|
// in the provided pointers. Please note that the buffers allocated
|
||
|
// here and stored in ppszProxyServer must be freed by the caller.
|
||
|
// If the TunnelAddress doesn't exist in the pszSourceFile this
|
||
|
// function still allocates memory and returns an empty string.
|
||
|
//
|
||
|
// Arguments: LPCSTR pszSourceFile - file to read the proxy settings from.
|
||
|
// LPSTR pszTunnelAddress - string containing the TunnelAddress used
|
||
|
// to look up the ProxyServer value
|
||
|
// LPSTR *ppszProxyServer - string pointer that will have the Proxy server value
|
||
|
// (in server:port format)
|
||
|
//
|
||
|
// Returns: BOOL - TRUE if the settings were successfully read
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
BOOL ReadProxyServerByTunnelAddressFromFile(LPCSTR pszSourceFile, LPSTR pszTunnelAddress, LPSTR *ppszProxyServer)
|
||
|
{
|
||
|
BOOL bReturn = FALSE;
|
||
|
BOOL bExit = FALSE;
|
||
|
DWORD dwReturnedSize = 0;
|
||
|
DWORD dwSize = CMSAMPLE_STARTING_BUF_SIZE;
|
||
|
|
||
|
//
|
||
|
// Check input parameters
|
||
|
//
|
||
|
if ((NULL == ppszProxyServer) || (NULL == pszSourceFile) || (NULL == pszTunnelAddress))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Check for empty strings
|
||
|
//
|
||
|
if (!(*pszSourceFile) || !(*pszTunnelAddress) || !(*c_pszTunnelAddressSection))
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Set the incoming pointer to NULL
|
||
|
//
|
||
|
*ppszProxyServer = NULL;
|
||
|
|
||
|
//
|
||
|
// In case the original buffer size is too small, the loop will try to allocate
|
||
|
// more buffer space and try to read the value until. The loop will exist if the
|
||
|
// value properly fits into the buffer or the size exceeds 1024*1024.
|
||
|
//
|
||
|
do
|
||
|
{
|
||
|
//
|
||
|
// Free allocated memory
|
||
|
//
|
||
|
|
||
|
if (*ppszProxyServer)
|
||
|
{
|
||
|
HeapFree(GetProcessHeap(), 0, *ppszProxyServer);
|
||
|
*ppszProxyServer = NULL;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Allocate space for the ProxyServer name
|
||
|
//
|
||
|
|
||
|
*ppszProxyServer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); //ANSI - char == byte
|
||
|
|
||
|
if (*ppszProxyServer)
|
||
|
{
|
||
|
// Since memory allocation succeeded, read the value from the settings file
|
||
|
dwReturnedSize = GetPrivateProfileString(c_pszTunnelAddressSection, pszTunnelAddress, "", *ppszProxyServer, dwSize, pszSourceFile);
|
||
|
|
||
|
//
|
||
|
// Check if the value fits into the buffer
|
||
|
//
|
||
|
if ((dwReturnedSize == (dwSize - 2)) || (dwReturnedSize == (dwSize - 1)))
|
||
|
{
|
||
|
//
|
||
|
// The buffer is too small, lets allocate a bigger one
|
||
|
//
|
||
|
dwSize = 2*dwSize;
|
||
|
if (dwSize > 1024*1024)
|
||
|
{
|
||
|
//
|
||
|
// Allocation above 1MB, need to exit
|
||
|
//
|
||
|
if (*ppszProxyServer)
|
||
|
{
|
||
|
HeapFree(GetProcessHeap(), 0, *ppszProxyServer);
|
||
|
*ppszProxyServer = NULL;
|
||
|
}
|
||
|
goto exit;
|
||
|
}
|
||
|
}
|
||
|
else if (0 == dwReturnedSize)
|
||
|
{
|
||
|
//
|
||
|
// Either we got an error, or more likely there was no data to get
|
||
|
//
|
||
|
if (*ppszProxyServer)
|
||
|
{
|
||
|
HeapFree(GetProcessHeap(), 0, *ppszProxyServer);
|
||
|
*ppszProxyServer = NULL;
|
||
|
}
|
||
|
goto exit;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//
|
||
|
// The function read in the data correctly
|
||
|
//
|
||
|
bExit = TRUE;
|
||
|
bReturn = TRUE;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bExit = TRUE;
|
||
|
}
|
||
|
|
||
|
} while (!bExit);
|
||
|
|
||
|
exit:
|
||
|
return bReturn;
|
||
|
}
|
||
|
|
||
|
//+----------------------------------------------------------------------------
|
||
|
//
|
||
|
// Function: WriteProxyServerSettingToFile
|
||
|
//
|
||
|
// Synopsis: Writes the specified settings to the given backup proxy filename.
|
||
|
// Please see the above format guide for specifics.
|
||
|
//
|
||
|
// Arguments: LPCSTR pszSourceFile - file to write the current settings to
|
||
|
// LPSTR pszProxyServer - proxy server string in server:port format
|
||
|
//
|
||
|
// Returns: BOOL - TRUE if the values were written successfully
|
||
|
//
|
||
|
// History: tomkel Created 11/02/2000
|
||
|
//
|
||
|
//+----------------------------------------------------------------------------
|
||
|
BOOL WriteProxyServerSettingToFile(LPCSTR pszSourceFile, LPSTR pszProxyServer)
|
||
|
{
|
||
|
BOOL bReturn = FALSE;
|
||
|
|
||
|
//
|
||
|
// Check input params
|
||
|
//
|
||
|
if ( (NULL == pszSourceFile) || (NULL == pszProxyServer))
|
||
|
{
|
||
|
return bReturn;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Check for empty strings
|
||
|
//
|
||
|
if (!(*pszSourceFile) || !(*pszProxyServer))
|
||
|
{
|
||
|
return bReturn;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save the Proxy Server name to the Proxy setting file
|
||
|
//
|
||
|
if (WritePrivateProfileString(c_pszManualProxySection, c_pszProxyServer, pszProxyServer, pszSourceFile))
|
||
|
{
|
||
|
bReturn = TRUE;
|
||
|
}
|
||
|
|
||
|
return bReturn;
|
||
|
}
|