windows-nt/Source/XPSP1/NT/net/rras/cm/customactions/cmsample/cmsample.cpp
2020-09-26 16:20:57 +08:00

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;
}