Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

402 lines
11 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: cmsample.cpp
  4. //
  5. // Module: CMSAMPLE.DLL
  6. //
  7. // Synopsis: Main source for changing proxy file setting using a Tunnel Address
  8. //
  9. // Copyright (c) 2000 Microsoft Corporation
  10. //
  11. // Author: tomkel Created 11/02/2000
  12. //
  13. //+----------------------------------------------------------------------------
  14. #include <windows.h>
  15. //
  16. // Function prototypes
  17. //
  18. LPSTR *GetArgV(LPTSTR pszCmdLine);
  19. BOOL ReadProxyServerByTunnelAddressFromFile(LPCSTR pszSourceFile, LPSTR pszTunnelAddress, LPSTR *ppszProxyServer);
  20. BOOL WriteProxyServerSettingToFile(LPCSTR pszSourceFile, LPSTR pszProxyServer);
  21. HRESULT WINAPI SetProxyUsingTunnelAddress(HWND hWnd, HINSTANCE hInst, LPSTR pszArgs, int nShow);
  22. #define CMSAMPLE_STARTING_BUF_SIZE 256 // Starting size of the string buffer
  23. const CHAR* const c_pszManualProxySection = "Manual Proxy"; // Section to update
  24. const CHAR* const c_pszProxyServer = "ProxyServer"; // Key to update
  25. const CHAR* const c_pszTunnelAddressSection = "Tunnel Address"; // Section to read
  26. //+----------------------------------------------------------------------------
  27. //
  28. // Function: SetProxyUsingTunnelAddress
  29. //
  30. // Synopsis: Entry point for changing the proxy file settings using a tunnel
  31. // address. The parameters to the dll are passed via a string which
  32. // contains parameters.
  33. //
  34. // Arguments: HWND hWnd - Window handle of caller
  35. // HINSTANCE hInst - Instance handle of caller
  36. // LPSTR pszArgs - Argument string
  37. // int nShow - Unused
  38. //
  39. // Returns: DWORD WINAPI - Error code
  40. //
  41. // History: tomkel Created 11/02/2000
  42. //
  43. //+----------------------------------------------------------------------------
  44. HRESULT WINAPI SetProxyUsingTunnelAddress(HWND hWnd, HINSTANCE hInst, LPSTR pszArgs, int nShow)
  45. {
  46. HRESULT hr = S_FALSE;
  47. LPSTR* ArgV = NULL;
  48. LPSTR pszServiceDir = NULL;
  49. LPSTR pszTunnelAddress = NULL;
  50. LPSTR pszProxyFile = NULL;
  51. LPSTR pszTunnelFile = NULL;
  52. LPSTR pszTunnelSettingFilePath = NULL;
  53. LPSTR pszProxyFilePath = NULL;
  54. LPSTR pszProxyServer = NULL;
  55. DWORD dwTunnelPathLen = 0;
  56. DWORD dwProxyPathLen = 0;
  57. DWORD dwProxyServerLen = 0;
  58. HANDLE hCurrentHeap = GetProcessHeap();
  59. int i = 0;
  60. //
  61. // Parse out the command line parameters
  62. //
  63. // command line is of the form: /ServiceDir %SERVICEDIR% /TunnelServerAddress %TUNNELSERVERADDRESS% /ProxyFile <PROXYFILE> /TunnelFile <TUNNELFILE>
  64. //
  65. // Check if we have any arguments
  66. //
  67. if (!pszArgs)
  68. {
  69. goto exit;
  70. }
  71. //
  72. // Separate each argument in the string by '\0' and return a list of pointers
  73. // to each argument
  74. //
  75. ArgV = GetArgV(pszArgs);
  76. //
  77. // Check if we have any valid parsed arguments
  78. //
  79. if (!ArgV)
  80. {
  81. goto exit;
  82. }
  83. //
  84. // Search the command line arguments for the following switches and their
  85. // corresponding values
  86. //
  87. while (ArgV[i])
  88. {
  89. if (0 == lstrcmpi(ArgV[i], "/ServiceDir") && ArgV[i+1])
  90. {
  91. pszServiceDir = (ArgV[i+1]);
  92. i = i+2;
  93. }
  94. else if (0 == lstrcmpi(ArgV[i], "/TunnelServerAddress") && ArgV[i+1])
  95. {
  96. pszTunnelAddress = ArgV[i+1];
  97. i = i+2;
  98. }
  99. else if (0 == lstrcmpi(ArgV[i], "/ProxyFile") && ArgV[i+1])
  100. {
  101. pszProxyFile = ArgV[i+1];
  102. i = i+2;
  103. }
  104. else if (0 == lstrcmpi(ArgV[i], "/TunnelFile") && ArgV[i+1])
  105. {
  106. pszTunnelFile = ArgV[i+1];
  107. i = i+2;
  108. }
  109. else
  110. {
  111. //
  112. // Unknown option.
  113. //
  114. i++;
  115. }
  116. }
  117. //
  118. // Make sure we have values for the arguments
  119. //
  120. if (!pszServiceDir || !pszTunnelAddress || !pszProxyFile || !pszTunnelFile)
  121. {
  122. goto exit;
  123. }
  124. //
  125. // Check to see if we got zero length string values from the command line arguments.
  126. // Exit if that is the case
  127. //
  128. if (!(*pszServiceDir) || !(*pszTunnelAddress) ||
  129. !(*pszProxyFile) || !(*pszTunnelFile))
  130. {
  131. goto exit;
  132. }
  133. //
  134. // Calculate the string size for the two paths that need to be created
  135. //
  136. dwTunnelPathLen = lstrlen(pszServiceDir) + lstrlen(pszTunnelFile) + 2; // 1 space for NULL, 1 for backslash
  137. dwProxyPathLen = lstrlen(pszServiceDir) + lstrlen(pszProxyFile) + 2; // 1 space for NULL, 1 for backslash
  138. //
  139. // Allocate the memory
  140. //
  141. pszTunnelSettingFilePath = (LPSTR)HeapAlloc(hCurrentHeap, HEAP_ZERO_MEMORY, dwTunnelPathLen); // ANSI - char == byte
  142. if (!pszTunnelSettingFilePath)
  143. {
  144. goto exit;
  145. }
  146. pszProxyFilePath = (LPSTR)HeapAlloc(hCurrentHeap, HEAP_ZERO_MEMORY, dwProxyPathLen); // ANSI - char == byte
  147. if (!pszProxyFilePath)
  148. {
  149. goto exit;
  150. }
  151. //
  152. // Create the full path to the Tunnel Address file
  153. //
  154. if ( wsprintf(pszTunnelSettingFilePath, "%s\\%s", pszServiceDir, pszTunnelFile) < (int)(dwTunnelPathLen - 1))
  155. {
  156. goto exit;
  157. }
  158. //
  159. // Create the full path to the Proxy file
  160. //
  161. if (wsprintf(pszProxyFilePath, "%s\\%s", pszServiceDir, pszProxyFile) < (int)(dwProxyPathLen - 1))
  162. {
  163. goto exit;
  164. }
  165. if (ReadProxyServerByTunnelAddressFromFile(pszTunnelSettingFilePath, pszTunnelAddress, &pszProxyServer))
  166. {
  167. //
  168. // Call WriteProxyServerSettingToFile - the function checks for empty strings
  169. //
  170. if(WriteProxyServerSettingToFile(pszProxyFilePath, pszProxyServer))
  171. {
  172. hr = S_OK;
  173. }
  174. }
  175. exit:
  176. //
  177. // Clean up allocated memory
  178. // Delete the argument pointers, Tunnel Server path, Proxy file path and ProxyServer name pointers
  179. //
  180. if (ArgV)
  181. {
  182. HeapFree(hCurrentHeap, 0, ArgV);
  183. }
  184. if (pszTunnelSettingFilePath)
  185. {
  186. HeapFree(hCurrentHeap, 0, pszTunnelSettingFilePath);
  187. }
  188. if (pszProxyFilePath)
  189. {
  190. HeapFree(hCurrentHeap, 0, pszProxyFilePath);
  191. }
  192. if (pszProxyServer)
  193. {
  194. HeapFree(hCurrentHeap, 0, pszProxyServer);
  195. }
  196. return hr;
  197. }
  198. //+----------------------------------------------------------------------------
  199. //
  200. // Function: ReadProxyServerByTunnelAddressFromFile
  201. //
  202. // Synopsis: Reads the proxy settings from the given proxy file and stores them
  203. // in the provided pointers. Please note that the buffers allocated
  204. // here and stored in ppszProxyServer must be freed by the caller.
  205. // If the TunnelAddress doesn't exist in the pszSourceFile this
  206. // function still allocates memory and returns an empty string.
  207. //
  208. // Arguments: LPCSTR pszSourceFile - file to read the proxy settings from.
  209. // LPSTR pszTunnelAddress - string containing the TunnelAddress used
  210. // to look up the ProxyServer value
  211. // LPSTR *ppszProxyServer - string pointer that will have the Proxy server value
  212. // (in server:port format)
  213. //
  214. // Returns: BOOL - TRUE if the settings were successfully read
  215. //
  216. //+----------------------------------------------------------------------------
  217. BOOL ReadProxyServerByTunnelAddressFromFile(LPCSTR pszSourceFile, LPSTR pszTunnelAddress, LPSTR *ppszProxyServer)
  218. {
  219. BOOL bReturn = FALSE;
  220. BOOL bExit = FALSE;
  221. DWORD dwReturnedSize = 0;
  222. DWORD dwSize = CMSAMPLE_STARTING_BUF_SIZE;
  223. //
  224. // Check input parameters
  225. //
  226. if ((NULL == ppszProxyServer) || (NULL == pszSourceFile) || (NULL == pszTunnelAddress))
  227. {
  228. return FALSE;
  229. }
  230. //
  231. // Check for empty strings
  232. //
  233. if (!(*pszSourceFile) || !(*pszTunnelAddress) || !(*c_pszTunnelAddressSection))
  234. {
  235. return FALSE;
  236. }
  237. //
  238. // Set the incoming pointer to NULL
  239. //
  240. *ppszProxyServer = NULL;
  241. //
  242. // In case the original buffer size is too small, the loop will try to allocate
  243. // more buffer space and try to read the value until. The loop will exist if the
  244. // value properly fits into the buffer or the size exceeds 1024*1024.
  245. //
  246. do
  247. {
  248. //
  249. // Free allocated memory
  250. //
  251. if (*ppszProxyServer)
  252. {
  253. HeapFree(GetProcessHeap(), 0, *ppszProxyServer);
  254. *ppszProxyServer = NULL;
  255. }
  256. //
  257. // Allocate space for the ProxyServer name
  258. //
  259. *ppszProxyServer = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize); //ANSI - char == byte
  260. if (*ppszProxyServer)
  261. {
  262. // Since memory allocation succeeded, read the value from the settings file
  263. dwReturnedSize = GetPrivateProfileString(c_pszTunnelAddressSection, pszTunnelAddress, "", *ppszProxyServer, dwSize, pszSourceFile);
  264. //
  265. // Check if the value fits into the buffer
  266. //
  267. if ((dwReturnedSize == (dwSize - 2)) || (dwReturnedSize == (dwSize - 1)))
  268. {
  269. //
  270. // The buffer is too small, lets allocate a bigger one
  271. //
  272. dwSize = 2*dwSize;
  273. if (dwSize > 1024*1024)
  274. {
  275. //
  276. // Allocation above 1MB, need to exit
  277. //
  278. if (*ppszProxyServer)
  279. {
  280. HeapFree(GetProcessHeap(), 0, *ppszProxyServer);
  281. *ppszProxyServer = NULL;
  282. }
  283. goto exit;
  284. }
  285. }
  286. else if (0 == dwReturnedSize)
  287. {
  288. //
  289. // Either we got an error, or more likely there was no data to get
  290. //
  291. if (*ppszProxyServer)
  292. {
  293. HeapFree(GetProcessHeap(), 0, *ppszProxyServer);
  294. *ppszProxyServer = NULL;
  295. }
  296. goto exit;
  297. }
  298. else
  299. {
  300. //
  301. // The function read in the data correctly
  302. //
  303. bExit = TRUE;
  304. bReturn = TRUE;
  305. }
  306. }
  307. else
  308. {
  309. bExit = TRUE;
  310. }
  311. } while (!bExit);
  312. exit:
  313. return bReturn;
  314. }
  315. //+----------------------------------------------------------------------------
  316. //
  317. // Function: WriteProxyServerSettingToFile
  318. //
  319. // Synopsis: Writes the specified settings to the given backup proxy filename.
  320. // Please see the above format guide for specifics.
  321. //
  322. // Arguments: LPCSTR pszSourceFile - file to write the current settings to
  323. // LPSTR pszProxyServer - proxy server string in server:port format
  324. //
  325. // Returns: BOOL - TRUE if the values were written successfully
  326. //
  327. // History: tomkel Created 11/02/2000
  328. //
  329. //+----------------------------------------------------------------------------
  330. BOOL WriteProxyServerSettingToFile(LPCSTR pszSourceFile, LPSTR pszProxyServer)
  331. {
  332. BOOL bReturn = FALSE;
  333. //
  334. // Check input params
  335. //
  336. if ( (NULL == pszSourceFile) || (NULL == pszProxyServer))
  337. {
  338. return bReturn;
  339. }
  340. //
  341. // Check for empty strings
  342. //
  343. if (!(*pszSourceFile) || !(*pszProxyServer))
  344. {
  345. return bReturn;
  346. }
  347. //
  348. // Save the Proxy Server name to the Proxy setting file
  349. //
  350. if (WritePrivateProfileString(c_pszManualProxySection, c_pszProxyServer, pszProxyServer, pszSourceFile))
  351. {
  352. bReturn = TRUE;
  353. }
  354. return bReturn;
  355. }