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