Leaked source code of windows server 2003
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.

1078 lines
36 KiB

  1. #include "precomp.h"
  2. #include <rashelp.h>
  3. #pragma warning(disable: 4201) // nonstandard extension used : nameless struct/union
  4. #include <winineti.h>
  5. // Implementation helper structures/routines declarations
  6. BOOL importConnectSet(PCTSTR pszIns, PCTSTR pszTargetPath, PCTSTR pszCleanupPath, BOOL fImport,
  7. DWORD dwMode, PCTSTR pszPbkFile = NULL, HKEY hkRoot = NULL);
  8. typedef struct tagRASSETPARAMS {
  9. PCTSTR pszExtractPath;
  10. PCTSTR pszIns;
  11. HANDLE hfileDat,
  12. hfileInf;
  13. BOOL fInfFileNeeded,
  14. fIntranet;
  15. // support for legacy format in ie50
  16. struct {
  17. HANDLE hfileRas,
  18. hfileSet;
  19. UINT nRasFileIndex;
  20. } lcy50;
  21. } RASSETPARAMS, *PRASSETPARAMS;
  22. BOOL rasMainEnumProc(PCWSTR pszNameW, LPARAM lParam);
  23. BOOL exportRasSettings (PCWSTR pszNameA, const PRASSETPARAMS pcrsp);
  24. BOOL exportRasCredentialsSettings(PCWSTR pszNameA, const PRASSETPARAMS pcrsp);
  25. BOOL exportWininetSettings (PCWSTR pszNameA, const PRASSETPARAMS pcrsp);
  26. BOOL exportOtherSettings (PCWSTR pszNameA, const PRASSETPARAMS pcrsp);
  27. void lcy50_Initialize (PRASSETPARAMS prsp);
  28. void lcy50_Uninitialize (PRASSETPARAMS prsp);
  29. BOOL lcy50_ExportRasSettings (PCSTR pszNameA, const PRASSETPARAMS pcrsp);
  30. BOOL lcy50_ExportWininetSettings(PCSTR pszNameA, const PRASSETPARAMS pcrsp);
  31. void lcy50_CopySzToBlobA (PBYTE *ppBlob, PCSTR pszStrA);
  32. BOOL deleteScriptFiles(PCTSTR pszSettingsFile, PCTSTR pszExtractPath, PCTSTR pszIns);
  33. void parseProxyToIns(PCTSTR pszProxy, PCTSTR pszIns);
  34. void copySzToBlob(PBYTE *ppBlob, PCWSTR pszStrW);
  35. BOOL WINAPI ImportConnectSetA(LPCSTR pcszIns, LPCSTR pcszTargetPath, LPCSTR pcszCleanupPath,
  36. BOOL fImport, DWORD dwMode, LPCSTR pcszPbkFile /*= NULL*/, HKEY hkRoot /*= NULL*/)
  37. {
  38. USES_CONVERSION;
  39. return importConnectSet(A2CT(pcszIns), A2CT(pcszTargetPath), A2CT(pcszCleanupPath),
  40. fImport, dwMode, A2CT(pcszPbkFile), hkRoot);
  41. }
  42. BOOL WINAPI ImportConnectSetW(LPCWSTR pcwszIns, LPCWSTR pcwszTargetPath, LPCWSTR pcwszCleanupPath,
  43. BOOL fImport, DWORD dwMode, LPCWSTR pcwszPbkFile /*= NULL*/, HKEY hkRoot /*= NULL*/)
  44. {
  45. USES_CONVERSION;
  46. return importConnectSet(W2CT(pcwszIns), W2CT(pcwszTargetPath), W2CT(pcwszCleanupPath),
  47. fImport, dwMode, W2CT(pcwszPbkFile), hkRoot);
  48. }
  49. /////////////////////////////////////////////////////////////////////////////
  50. // Implementation helper routines
  51. BOOL importConnectSet(PCTSTR pszIns, PCTSTR pszTargetPath, PCTSTR pszCleanupPath, BOOL fImport,
  52. DWORD dwMode, PCTSTR pszPbkFile /*= NULL*/, HKEY hkRoot /*= NULL*/)
  53. {
  54. UNREFERENCED_PARAMETER(pszPbkFile);
  55. UNREFERENCED_PARAMETER(hkRoot);
  56. USES_CONVERSION;
  57. RASSETPARAMS rsp;
  58. TCHAR szTargetFile[MAX_PATH],
  59. szExtRegInfLine[MAX_PATH];
  60. DWORD dwAux,
  61. dwResult;
  62. BOOL fResult,
  63. fAux;
  64. //----- Clear out previous settings -----
  65. PathCombine(szTargetFile, pszCleanupPath, CONNECT_RAS);
  66. deleteScriptFiles(szTargetFile, pszCleanupPath, pszIns);
  67. DeleteFileInDir(CS_DAT, pszCleanupPath);
  68. // delete legacy stuff if there
  69. DeleteFileInDir(CONNECT_RAS, pszCleanupPath);
  70. DeleteFileInDir(CONNECT_SET, pszCleanupPath);
  71. DeleteFileInDir(CONNECT_INF, pszCleanupPath);
  72. InsDeleteSection(IS_CONNECTSET, pszIns);
  73. InsDeleteKey (IS_EXTREGINF, IK_CONNECTSET, pszIns);
  74. if (!fImport)
  75. return TRUE; // bail if that's all we need
  76. //----- Initialization -----
  77. fResult = FALSE;
  78. ZeroMemory(&rsp, sizeof(rsp));
  79. rsp.pszExtractPath = pszTargetPath;
  80. rsp.pszIns = pszIns;
  81. rsp.fIntranet = HasFlag(dwMode, IEM_ADMIN);
  82. PathCombine(szTargetFile, pszTargetPath, CS_DAT);
  83. rsp.hfileDat = CreateNewFile(szTargetFile);
  84. if (INVALID_HANDLE_VALUE == rsp.hfileDat) {
  85. rsp.hfileDat = NULL;
  86. goto Exit;
  87. }
  88. if (RasIsInstalled()) {
  89. PathCombine(szTargetFile, pszTargetPath, CONNECT_INF);
  90. rsp.hfileInf = CreateNewFile(szTargetFile);
  91. if (INVALID_HANDLE_VALUE == rsp.hfileInf) {
  92. rsp.hfileInf = NULL;
  93. goto Exit;
  94. }
  95. }
  96. //----- Write initial information into output files -----
  97. dwAux = CS_VERSION_5X;
  98. WriteFile(rsp.hfileDat, &dwAux, sizeof(DWORD), &dwResult, NULL);
  99. if (rsp.hfileInf != NULL)
  100. WriteStringToFile(rsp.hfileInf, INF_PROLOG_CS, StrLen(INF_PROLOG_CS));
  101. lcy50_Initialize(&rsp);
  102. //----- Enumerate connections -----
  103. fResult = RasEnumEntriesCallback(NULL, rasMainEnumProc, (LPARAM)&rsp);
  104. if (!fResult)
  105. goto Exit;
  106. //----- Save global registry settings into the inf file -----
  107. if (rsp.hfileInf != NULL) {
  108. HKEY hk;
  109. if (ERROR_SUCCESS == SHOpenKeyHKCU(RK_INETSETTINGS, KEY_READ, &hk)) {
  110. if (S_OK == SHValueExists(hk, RV_ENABLESECURITYCHECK)) {
  111. ExportRegValue2Inf(hk, RV_ENABLESECURITYCHECK, TEXT("HKCU"), RK_INETSETTINGS, rsp.hfileInf);
  112. rsp.fInfFileNeeded = TRUE;
  113. }
  114. SHCloseKey(hk);
  115. }
  116. if (ERROR_SUCCESS == SHOpenKeyHKCU(RK_REMOTEACCESS, KEY_READ, &hk)) {
  117. if (S_OK == SHValueExists(hk, RV_INTERNETPROFILE)) {
  118. ExportRegValue2Inf(hk, RV_INTERNETPROFILE, TEXT("HKCU"), RK_REMOTEACCESS, rsp.hfileInf);
  119. rsp.fInfFileNeeded = TRUE;
  120. }
  121. SHCloseKey(hk);
  122. }
  123. if (rsp.fInfFileNeeded) {
  124. szExtRegInfLine[0] = TEXT('\0');
  125. wnsprintf(szExtRegInfLine, countof(szExtRegInfLine), TEXT("%s,") IS_DEFAULTINSTALL, CONNECT_INF);
  126. InsWriteString(IS_EXTREGINF, IK_CONNECTSET, szExtRegInfLine, pszIns);
  127. szExtRegInfLine[0] = TEXT('\0');
  128. wnsprintf(szExtRegInfLine, countof(szExtRegInfLine), TEXT("%s,") IS_IEAKINSTALL_HKCU, CONNECT_INF);
  129. InsWriteString(IS_EXTREGINF_HKCU, IK_CONNECTSET, szExtRegInfLine, pszIns);
  130. }
  131. }
  132. //----- Save global settings into the ins file -----
  133. InsWriteBool(IS_CONNECTSET, IK_OPTION, TRUE, pszIns);
  134. // NOTE: (andrewgu) have to do this instead of going through inf because it's impossible to
  135. // write to HKCC in the inf. and we have to write to HKCC, otherwise clients with intergated
  136. // shell are broken.
  137. dwAux = sizeof(fAux);
  138. dwResult = SHGetValue(HKEY_CURRENT_USER, RK_INETSETTINGS, RV_ENABLEAUTODIAL, NULL, (LPBYTE)&fAux, &dwAux);
  139. if (dwResult == ERROR_SUCCESS)
  140. InsWriteBool(IS_CONNECTSET, IK_ENABLEAUTODIAL, fAux, pszIns);
  141. dwAux = sizeof(fAux);
  142. dwResult = SHGetValue(HKEY_CURRENT_USER, RK_INETSETTINGS, RV_NONETAUTODIAL, NULL, (LPBYTE)&fAux, &dwAux);
  143. if (dwResult == ERROR_SUCCESS)
  144. InsWriteBool(IS_CONNECTSET, IK_NONETAUTODIAL, fAux, pszIns);
  145. fResult = TRUE;
  146. Exit:
  147. lcy50_Uninitialize(&rsp);
  148. if (NULL != rsp.hfileInf) {
  149. CloseFile(rsp.hfileInf);
  150. if (!rsp.fInfFileNeeded)
  151. DeleteFileInDir(CONNECT_INF, pszTargetPath);
  152. }
  153. if (NULL != rsp.hfileDat)
  154. CloseFile(rsp.hfileDat);
  155. return fResult;
  156. }
  157. BOOL rasMainEnumProc(PCWSTR pszNameW, LPARAM lParam)
  158. {
  159. USES_CONVERSION;
  160. PRASSETPARAMS pcrsp;
  161. BYTE rgbName[2*sizeof(DWORD) + StrCbFromCch(RAS_MaxEntryName+1)];
  162. PCSTR pszNameA;
  163. PBYTE pCur;
  164. DWORD cbName,
  165. dwAux;
  166. pcrsp = (const PRASSETPARAMS)lParam;
  167. ASSERT(NULL != pcrsp && NULL != pcrsp->hfileDat);
  168. //----- Connection name -----
  169. ZeroMemory(rgbName, sizeof(rgbName));
  170. pCur = rgbName;
  171. cbName = 2*sizeof(DWORD);
  172. cbName += (DWORD)((pszNameW != NULL) ? StrCbFromSzW(pszNameW) : sizeof(DWORD));
  173. *((PDWORD)pCur) = CS_STRUCT_HEADER;
  174. pCur += sizeof(DWORD);
  175. *((PDWORD)pCur) = cbName;
  176. pCur += sizeof(DWORD);
  177. copySzToBlob(&pCur, pszNameW);
  178. WriteFile(pcrsp->hfileDat, rgbName, cbName, &dwAux, NULL);
  179. //----- All other structures -----
  180. pszNameA = W2CA(pszNameW);
  181. if (NULL != pszNameW) {
  182. ASSERT(RasIsInstalled());
  183. exportRasSettings (pszNameW, pcrsp);
  184. exportRasCredentialsSettings(pszNameW, pcrsp);
  185. exportWininetSettings (pszNameW, pcrsp);
  186. exportOtherSettings (pszNameW, pcrsp);
  187. lcy50_ExportRasSettings (pszNameA, pcrsp);
  188. lcy50_ExportWininetSettings (pszNameA, pcrsp);
  189. }
  190. else {
  191. exportWininetSettings (pszNameW, pcrsp);
  192. lcy50_ExportWininetSettings (pszNameA, pcrsp);
  193. }
  194. return TRUE;
  195. }
  196. BOOL exportRasSettings(PCWSTR pszNameW, const PRASSETPARAMS pcrsp)
  197. {
  198. USES_CONVERSION;
  199. LPRASENTRYW preW;
  200. PBYTE pBlob, pCur;
  201. DWORD cbBlob, cbWritten,
  202. dwResult;
  203. ASSERT(RasIsInstalled());
  204. ASSERT(pszNameW != NULL);
  205. ASSERT(pcrsp != NULL && pcrsp->hfileDat != NULL);
  206. pBlob = NULL;
  207. //----- RAS structure -----
  208. dwResult = RasGetEntryPropertiesExW(pszNameW, (LPRASENTRYW *)&pBlob, &cbBlob);
  209. if (dwResult != ERROR_SUCCESS)
  210. goto Exit;
  211. cbBlob += 2*sizeof(DWORD);
  212. pBlob = (PBYTE)CoTaskMemRealloc(pBlob, cbBlob);
  213. if (pBlob == NULL)
  214. goto Exit;
  215. MoveMemory(pBlob + 2*sizeof(DWORD), pBlob, cbBlob - 2*sizeof(DWORD));
  216. //----- Header -----
  217. pCur = pBlob;
  218. *((PDWORD)pCur) = CS_STRUCT_RAS;
  219. pCur += sizeof(DWORD);
  220. *((PDWORD)pCur) = cbBlob;
  221. pCur += sizeof(DWORD);
  222. //----- Script file -----
  223. preW = (LPRASENTRYW)pCur;
  224. if (preW->szScript[0] != L'\0') {
  225. PCWSTR pszScriptW;
  226. pszScriptW = preW->szScript;
  227. if (preW->szScript[0] == L'[')
  228. pszScriptW = &preW->szScript[1];
  229. if (PathFileExistsW(pszScriptW)) {
  230. if (pszScriptW > preW->szScript)
  231. StrCpyW(preW->szScript, pszScriptW);
  232. CopyFileToDir(W2CT(preW->szScript), pcrsp->pszExtractPath);
  233. }
  234. }
  235. WriteFile(pcrsp->hfileDat, pBlob, cbBlob, &cbWritten, NULL);
  236. Exit:
  237. if (pBlob != NULL)
  238. CoTaskMemFree(pBlob);
  239. return TRUE;
  240. }
  241. BOOL exportRasCredentialsSettings(PCWSTR pszNameW, const PRASSETPARAMS pcrsp)
  242. {
  243. RASDIALPARAMSW rdpW;
  244. PCWSTR pszUserNameW, pszPasswordW, pszDomainW;
  245. PBYTE pBlob, pCur;
  246. DWORD cbBlob, cbWritten,
  247. dwResult;
  248. BOOL fPassword;
  249. ASSERT(RasIsInstalled());
  250. ASSERT(pszNameW != NULL);
  251. ASSERT(pcrsp != NULL && pcrsp->hfileDat != NULL);
  252. pBlob = NULL;
  253. ZeroMemory(&rdpW, sizeof(rdpW));
  254. rdpW.dwSize = sizeof(rdpW);
  255. StrCpyW(rdpW.szEntryName, pszNameW);
  256. dwResult = RasGetEntryDialParamsWrap(&rdpW, &fPassword);
  257. if (dwResult != ERROR_SUCCESS)
  258. goto Exit;
  259. pszUserNameW = (*rdpW.szUserName != TEXT('\0')) ? rdpW.szUserName : NULL;
  260. pszPasswordW = fPassword ? rdpW.szPassword : NULL;
  261. pszDomainW = (*rdpW.szDomain != TEXT('\0')) ? rdpW.szDomain : NULL;
  262. //----- Figure out the size of the blob -----
  263. // size of structure header
  264. cbBlob = 2*sizeof(DWORD);
  265. // size of essential information
  266. cbBlob += (DWORD)((pszUserNameW != NULL) ? StrCbFromSzW(pszUserNameW) : sizeof(DWORD));
  267. cbBlob += (DWORD)((pszPasswordW != NULL) ? StrCbFromSzW(pszPasswordW) : sizeof(DWORD));
  268. cbBlob += (DWORD)((pszDomainW != NULL) ? StrCbFromSzW(pszDomainW) : sizeof(DWORD));
  269. pBlob = (PBYTE)CoTaskMemAlloc(cbBlob);
  270. if (pBlob == NULL)
  271. goto Exit;
  272. ZeroMemory(pBlob, cbBlob);
  273. //----- Copy information into the blob -----
  274. pCur = pBlob;
  275. // stucture header
  276. *((PDWORD)pCur) = CS_STRUCT_RAS_CREADENTIALS;
  277. pCur += sizeof(DWORD);
  278. *((PDWORD)pCur) = cbBlob;
  279. pCur += sizeof(DWORD);
  280. // essential information
  281. copySzToBlob(&pCur, pszUserNameW);
  282. copySzToBlob(&pCur, pszPasswordW);
  283. copySzToBlob(&pCur, pszDomainW);
  284. ASSERT(pCur == pBlob + cbBlob);
  285. WriteFile(pcrsp->hfileDat, pBlob, cbBlob, &cbWritten, NULL);
  286. Exit:
  287. if (pBlob != NULL)
  288. CoTaskMemFree(pBlob);
  289. return TRUE;
  290. }
  291. BOOL exportWininetSettings(PCWSTR pszNameW, const PRASSETPARAMS pcrsp)
  292. {
  293. USES_CONVERSION;
  294. INTERNET_PER_CONN_OPTION_LISTW list;
  295. INTERNET_PER_CONN_OPTIONW rgOptions[7];
  296. PCWSTR pszAuxW;
  297. PBYTE pBlob, pCur;
  298. DWORD cbBlob, cbAux;
  299. UINT i;
  300. ASSERT(pcrsp != NULL && pcrsp->hfileDat != NULL && pcrsp->pszIns != NULL);
  301. pBlob = NULL;
  302. ZeroMemory(&list, sizeof(list));
  303. list.dwSize = sizeof(list);
  304. list.pszConnection = (PWSTR)pszNameW;
  305. ZeroMemory(rgOptions, sizeof(rgOptions));
  306. list.dwOptionCount = countof(rgOptions);
  307. list.pOptions = rgOptions;
  308. list.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
  309. list.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
  310. list.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
  311. list.pOptions[3].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
  312. list.pOptions[4].dwOption = INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL;
  313. list.pOptions[5].dwOption = INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS;
  314. list.pOptions[6].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
  315. if (!pcrsp->fIntranet) // autoconfig stuff should be ignored
  316. list.dwOptionCount = 3;
  317. cbAux = list.dwSize;
  318. if (FALSE == InternetQueryOptionW(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &list, &cbAux))
  319. goto Exit;
  320. if (!pcrsp->fIntranet) // autoconfig stuff should be ignored
  321. list.pOptions[0].Value.dwValue &= PROXY_TYPE_PROXY;
  322. //----- Figure out the size of the blob -----
  323. // size of structure header
  324. cbBlob = 2*sizeof(DWORD);
  325. // size of INTERNET_PER_CONN_OPTION_LIST header
  326. cbBlob += sizeof(DWORD); // list.dwOptionCount
  327. // size of INTERNET_PER_CONN_xxx - all of list.pOptions
  328. for (i = 0; i < min(list.dwOptionCount, countof(rgOptions)); i++) {
  329. cbBlob += sizeof(DWORD);
  330. switch (list.pOptions[i].dwOption) {
  331. case INTERNET_PER_CONN_PROXY_SERVER:
  332. case INTERNET_PER_CONN_PROXY_BYPASS:
  333. case INTERNET_PER_CONN_AUTOCONFIG_URL:
  334. case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
  335. pszAuxW = list.pOptions[i].Value.pszValue;
  336. cbBlob += (DWORD)((pszAuxW != NULL) ? StrCbFromSzW(pszAuxW) : sizeof(DWORD));
  337. break;
  338. case INTERNET_PER_CONN_FLAGS:
  339. case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
  340. case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
  341. default: // everything else is also DWORD
  342. cbBlob += sizeof(DWORD);
  343. break;
  344. }
  345. }
  346. pBlob = (PBYTE)CoTaskMemAlloc(cbBlob);
  347. if (pBlob == NULL)
  348. goto Exit;
  349. //----- Copy information into the blob -----
  350. ZeroMemory(pBlob, cbBlob);
  351. pCur = pBlob;
  352. // stucture header
  353. *((PDWORD)pCur) = CS_STRUCT_WININET;
  354. pCur += sizeof(DWORD);
  355. *((PDWORD)pCur) = cbBlob;
  356. pCur += sizeof(DWORD);
  357. // INTERNET_PER_CONN_OPTION_LIST header
  358. *((PDWORD)pCur) = list.dwOptionCount; // list.dwOptionCount
  359. pCur += sizeof(DWORD);
  360. // INTERNET_PER_CONN_xxx - all of list.pOptions
  361. for (i = 0; i < min(list.dwOptionCount, countof(rgOptions)); i++) {
  362. *((PDWORD)pCur) = list.pOptions[i].dwOption;
  363. pCur += sizeof(DWORD);
  364. switch (list.pOptions[i].dwOption) {
  365. case INTERNET_PER_CONN_PROXY_SERVER:
  366. case INTERNET_PER_CONN_PROXY_BYPASS:
  367. case INTERNET_PER_CONN_AUTOCONFIG_URL:
  368. case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
  369. copySzToBlob(&pCur, list.pOptions[i].Value.pszValue);
  370. break;
  371. case INTERNET_PER_CONN_FLAGS:
  372. case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
  373. case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
  374. default: // everything else is also DWORD
  375. *((PDWORD)pCur) = list.pOptions[i].Value.dwValue;
  376. pCur += sizeof(DWORD);
  377. break;
  378. }
  379. }
  380. ASSERT(pCur == pBlob + cbBlob);
  381. WriteFile(pcrsp->hfileDat, pBlob, cbBlob, &cbAux, NULL);
  382. //----- Save LAN's autoconfig and proxy settings to the ins -----
  383. if (pszNameW == NULL) {
  384. ASSERT(list.pOptions[0].dwOption == INTERNET_PER_CONN_FLAGS);
  385. //_____ autoconfig _____
  386. if (pcrsp->fIntranet) {
  387. TCHAR szReloadDelayMins[33];
  388. InsWriteBool(IS_URL, IK_DETECTCONFIG,
  389. HasFlag(list.pOptions[0].Value.dwValue, PROXY_TYPE_AUTO_DETECT), pcrsp->pszIns);
  390. InsWriteBool(IS_URL, IK_USEAUTOCONF,
  391. HasFlag(list.pOptions[0].Value.dwValue, PROXY_TYPE_AUTO_PROXY_URL), pcrsp->pszIns);
  392. ASSERT(list.pOptions[3].dwOption == INTERNET_PER_CONN_AUTOCONFIG_URL);
  393. InsWriteString(IS_URL, IK_AUTOCONFURL, W2CT(list.pOptions[3].Value.pszValue), pcrsp->pszIns);
  394. ASSERT(list.pOptions[4].dwOption == INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL);
  395. InsWriteString(IS_URL, IK_AUTOCONFURLJS, W2CT(list.pOptions[4].Value.pszValue), pcrsp->pszIns);
  396. ASSERT(list.pOptions[5].dwOption == INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS);
  397. wnsprintf(szReloadDelayMins, countof(szReloadDelayMins), TEXT("%lu"), list.pOptions[5].Value.dwValue);
  398. InsWriteString(IS_URL, IK_AUTOCONFTIME, szReloadDelayMins, pcrsp->pszIns);
  399. }
  400. else { /* if (!pcrsp->fIntranet) */ // autoconfig stuff should be ignored
  401. InsDeleteKey(IS_URL, IK_DETECTCONFIG, pcrsp->pszIns);
  402. InsDeleteKey(IS_URL, IK_USEAUTOCONF, pcrsp->pszIns);
  403. InsDeleteKey(IS_URL, IK_AUTOCONFURL, pcrsp->pszIns);
  404. InsDeleteKey(IS_URL, IK_AUTOCONFURLJS, pcrsp->pszIns);
  405. InsDeleteKey(IS_URL, IK_AUTOCONFTIME, pcrsp->pszIns);
  406. }
  407. //_____ proxy and proxy bypass settings _____
  408. if (pcrsp->fIntranet || HasFlag(list.pOptions[0].Value.dwValue, PROXY_TYPE_PROXY)) {
  409. InsWriteBool(IS_PROXY, IK_PROXYENABLE,
  410. HasFlag(list.pOptions[0].Value.dwValue, PROXY_TYPE_PROXY), pcrsp->pszIns);
  411. ASSERT(list.pOptions[1].dwOption == INTERNET_PER_CONN_PROXY_SERVER);
  412. parseProxyToIns(W2CT(list.pOptions[1].Value.pszValue), pcrsp->pszIns);
  413. ASSERT(list.pOptions[2].dwOption == INTERNET_PER_CONN_PROXY_BYPASS);
  414. InsWriteString(IS_PROXY, IK_PROXYOVERRIDE, W2CT(list.pOptions[2].Value.pszValue), pcrsp->pszIns);
  415. }
  416. else // proxy not customized, delete the section
  417. InsDeleteSection(IS_PROXY, pcrsp->pszIns);
  418. }
  419. Exit:
  420. if (pBlob != NULL)
  421. CoTaskMemFree(pBlob);
  422. if (list.pOptions[1].Value.pszValue != NULL) // INTERNET_PER_CONN_PROXY_SERVER
  423. GlobalFree(list.pOptions[1].Value.pszValue);
  424. if (list.pOptions[2].Value.pszValue != NULL) // INTERNET_PER_CONN_PROXY_BYPASS
  425. GlobalFree(list.pOptions[2].Value.pszValue);
  426. if (list.pOptions[3].Value.pszValue != NULL) // INTERNET_PER_CONN_AUTOCONFIG_URL
  427. GlobalFree(list.pOptions[3].Value.pszValue);
  428. if (list.pOptions[4].Value.pszValue != NULL) // INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL
  429. GlobalFree(list.pOptions[4].Value.pszValue);
  430. return TRUE;
  431. }
  432. BOOL exportOtherSettings(PCWSTR pszNameW, const PRASSETPARAMS pcrsp)
  433. {
  434. USES_CONVERSION;
  435. TCHAR szKey[MAX_PATH];
  436. PCTSTR pszName;
  437. HKEY hk;
  438. BOOL fExported;
  439. ASSERT(pszNameW != NULL);
  440. ASSERT(pcrsp != NULL && pcrsp->hfileInf != NULL && pcrsp->pszIns != NULL);
  441. fExported = FALSE;
  442. pszName = W2CT(pszNameW);
  443. wnsprintf(szKey, countof(szKey), RK_REMOTEACCESS_PROFILES TEXT("\\%s"), pszName);
  444. if (ERROR_SUCCESS != SHOpenKeyHKCU(szKey, KEY_READ, &hk))
  445. return TRUE;
  446. if (S_OK == SHValueExists(hk, RV_COVEREXCLUDE)) {
  447. ExportRegValue2Inf(hk, RV_COVEREXCLUDE, TEXT("HKCU"), szKey, pcrsp->hfileInf);
  448. pcrsp->fInfFileNeeded = fExported = TRUE;
  449. }
  450. if (S_OK == SHValueExists(hk, RV_ENABLEAUTODISCONNECT)) {
  451. ExportRegValue2Inf(hk, RV_ENABLEAUTODISCONNECT, TEXT("HKCU"), szKey, pcrsp->hfileInf);
  452. pcrsp->fInfFileNeeded = fExported = TRUE;
  453. }
  454. if (S_OK == SHValueExists(hk, RV_ENABLEEXITDISCONNECT)) {
  455. ExportRegValue2Inf(hk, RV_ENABLEEXITDISCONNECT, TEXT("HKCU"), szKey, pcrsp->hfileInf);
  456. pcrsp->fInfFileNeeded = fExported = TRUE;
  457. }
  458. if (S_OK == SHValueExists(hk, RV_DISCONNECTIDLETIME)) {
  459. ExportRegValue2Inf(hk, RV_DISCONNECTIDLETIME, TEXT("HKCU"), szKey, pcrsp->hfileInf);
  460. pcrsp->fInfFileNeeded = fExported = TRUE;
  461. }
  462. if (S_OK == SHValueExists(hk, RV_REDIALATTEMPTS)) {
  463. ExportRegValue2Inf(hk, RV_REDIALATTEMPTS, TEXT("HKCU"), szKey, pcrsp->hfileInf);
  464. pcrsp->fInfFileNeeded = fExported = TRUE;
  465. }
  466. if (S_OK == SHValueExists(hk, RV_REDIALINTERVAL)) {
  467. ExportRegValue2Inf(hk, RV_REDIALINTERVAL, TEXT("HKCU"), szKey, pcrsp->hfileInf);
  468. pcrsp->fInfFileNeeded = fExported = TRUE;
  469. }
  470. SHCloseKey(hk);
  471. if (fExported)
  472. WriteStringToFile(pcrsp->hfileInf, (LPCVOID)TEXT("\r\n"), 2);
  473. return TRUE;
  474. }
  475. void lcy50_Initialize(PRASSETPARAMS prsp)
  476. {
  477. TCHAR szTargetFile[MAX_PATH];
  478. DWORD dwVersion,
  479. dwAux;
  480. ASSERT(NULL != prsp && NULL != prsp->pszExtractPath);
  481. ZeroMemory(&prsp->lcy50, sizeof(prsp->lcy50));
  482. dwVersion = CS_VERSION_50;
  483. if (RasIsInstalled()) {
  484. PathCombine(szTargetFile, prsp->pszExtractPath, CONNECT_RAS);
  485. prsp->lcy50.hfileRas = CreateNewFile(szTargetFile);
  486. if (INVALID_HANDLE_VALUE != prsp->lcy50.hfileRas)
  487. WriteFile(prsp->lcy50.hfileRas, &dwVersion, sizeof(DWORD), &dwAux, NULL);
  488. else
  489. prsp->lcy50.hfileRas = NULL;
  490. }
  491. PathCombine(szTargetFile, prsp->pszExtractPath, CONNECT_SET);
  492. prsp->lcy50.hfileSet = CreateNewFile(szTargetFile);
  493. if (INVALID_HANDLE_VALUE != prsp->lcy50.hfileSet)
  494. WriteFile(prsp->lcy50.hfileSet, &dwVersion, sizeof(DWORD), &dwAux, NULL);
  495. else
  496. prsp->lcy50.hfileSet = NULL;
  497. }
  498. void lcy50_Uninitialize(PRASSETPARAMS prsp)
  499. {
  500. ASSERT(NULL != prsp && NULL != prsp->pszExtractPath);
  501. if (NULL != prsp->lcy50.hfileSet) {
  502. CloseFile(prsp->lcy50.hfileSet);
  503. prsp->lcy50.hfileSet = NULL;
  504. }
  505. if (NULL != prsp->lcy50.hfileRas) {
  506. CloseFile(prsp->lcy50.hfileRas);
  507. prsp->lcy50.hfileRas = NULL;
  508. if (prsp->lcy50.nRasFileIndex == 0)
  509. DeleteFileInDir(CONNECT_RAS, prsp->pszExtractPath);
  510. }
  511. }
  512. BOOL lcy50_ExportRasSettings(PCSTR pszNameA, const PRASSETPARAMS pcrsp)
  513. {
  514. USES_CONVERSION;
  515. TCHAR szKeyName[16],
  516. szKeySize[16],
  517. szValueSize[16];
  518. PBYTE pBlob;
  519. DWORD cbBlob,
  520. dwResult;
  521. if (NULL == pcrsp->lcy50.hfileRas)
  522. return FALSE;
  523. ASSERT(RasIsInstalled());
  524. ASSERT(NULL != pszNameA);
  525. ASSERT(NULL != pcrsp && NULL != pcrsp->pszIns);
  526. pBlob = NULL;
  527. dwResult = RasGetEntryPropertiesExA(pszNameA, (LPRASENTRYA *)&pBlob, &cbBlob);
  528. if (dwResult != ERROR_SUCCESS)
  529. goto Exit;
  530. // NOTE: (andrewgu) need to write the size of the data in the ins file because it's variable.
  531. // it can change depending on alternate phone numbers list at the end of the RASENTRYA
  532. // structure.
  533. wnsprintf(szKeyName, countof(szKeyName), IK_CONNECTNAME, pcrsp->lcy50.nRasFileIndex);
  534. wnsprintf(szKeySize, countof(szKeySize), IK_CONNECTSIZE, pcrsp->lcy50.nRasFileIndex);
  535. wnsprintf(szValueSize, countof(szValueSize), TEXT("%lu"), cbBlob);
  536. InsWriteString(IS_CONNECTSET, szKeyName, A2CT(pszNameA), pcrsp->pszIns);
  537. InsWriteString(IS_CONNECTSET, szKeySize, szValueSize, pcrsp->pszIns);
  538. // NOTE: (andrewgu) no script file processing is needed here. it's been taken care of when
  539. // processing settings for the new format. connection is ulimately the same it's just stored
  540. // differently.
  541. WriteFile(pcrsp->lcy50.hfileRas, pBlob, cbBlob, &dwResult, NULL);
  542. pcrsp->lcy50.nRasFileIndex++;
  543. Exit:
  544. if (NULL != pBlob)
  545. CoTaskMemFree(pBlob);
  546. return TRUE;
  547. }
  548. BOOL lcy50_ExportWininetSettings(PCSTR pszNameA, const PRASSETPARAMS pcrsp)
  549. {
  550. INTERNET_PER_CONN_OPTION_LISTA listA;
  551. INTERNET_PER_CONN_OPTIONA rgOptionsA[7];
  552. PCSTR pszAuxA;
  553. PBYTE pBlob, pCur;
  554. DWORD cbBlob, cbAux;
  555. UINT i;
  556. if (NULL == pcrsp->lcy50.hfileSet)
  557. return FALSE;
  558. ASSERT(NULL != pcrsp && NULL != pcrsp->pszIns);
  559. pBlob = NULL;
  560. ZeroMemory(&listA, sizeof(listA));
  561. listA.dwSize = sizeof(listA);
  562. listA.pszConnection = (PSTR)pszNameA;
  563. ZeroMemory(rgOptionsA, sizeof(rgOptionsA));
  564. listA.dwOptionCount = countof(rgOptionsA);
  565. listA.pOptions = rgOptionsA;
  566. listA.pOptions[0].dwOption = INTERNET_PER_CONN_FLAGS;
  567. listA.pOptions[1].dwOption = INTERNET_PER_CONN_PROXY_SERVER;
  568. listA.pOptions[2].dwOption = INTERNET_PER_CONN_PROXY_BYPASS;
  569. listA.pOptions[3].dwOption = INTERNET_PER_CONN_AUTOCONFIG_URL;
  570. listA.pOptions[4].dwOption = INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL;
  571. listA.pOptions[5].dwOption = INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS;
  572. listA.pOptions[6].dwOption = INTERNET_PER_CONN_AUTODISCOVERY_FLAGS;
  573. if (!pcrsp->fIntranet) // autoconfig stuff should be ignored
  574. listA.dwOptionCount = 3;
  575. cbAux = listA.dwSize;
  576. if (FALSE == InternetQueryOptionA(NULL, INTERNET_OPTION_PER_CONNECTION_OPTION, &listA, &cbAux))
  577. goto Exit;
  578. if (!pcrsp->fIntranet) // autoconfig stuff should be ignored
  579. listA.pOptions[0].Value.dwValue &= PROXY_TYPE_PROXY;
  580. //----- Figure out the size of the blob describing this connection -----
  581. // size of INTERNET_PER_CONN_OPTION_LIST header
  582. cbBlob = sizeof(DWORD); // listA.dwSize
  583. pszAuxA = listA.pszConnection; // listA.pszConnection
  584. cbBlob += (DWORD)((NULL != pszAuxA) ? StrCbFromSzA(pszAuxA) : sizeof(DWORD));
  585. #ifdef _WIN64
  586. cbBlob = LcbAlignLcb(cbBlob);
  587. #endif
  588. cbBlob += sizeof(DWORD); // listA.dwOptionCount
  589. // size of INTERNET_PER_CONN_xxx - all of listA.pOptions
  590. for (i = 0; i < min(listA.dwOptionCount, countof(rgOptionsA)); i++) {
  591. cbBlob += sizeof(DWORD);
  592. switch (listA.pOptions[i].dwOption) {
  593. case INTERNET_PER_CONN_PROXY_SERVER:
  594. case INTERNET_PER_CONN_PROXY_BYPASS:
  595. case INTERNET_PER_CONN_AUTOCONFIG_URL:
  596. case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
  597. pszAuxA = listA.pOptions[i].Value.pszValue;
  598. cbBlob += (DWORD)((NULL != pszAuxA) ? StrCbFromSzA(pszAuxA) : sizeof(DWORD));
  599. #ifdef _WIN64
  600. cbBlob = LcbAlignLcb(cbBlob);
  601. #endif
  602. break;
  603. case INTERNET_PER_CONN_FLAGS:
  604. case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
  605. case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
  606. default: // everything else is also DWORD
  607. cbBlob += sizeof(DWORD);
  608. break;
  609. }
  610. }
  611. pBlob = (PBYTE)CoTaskMemAlloc(cbBlob);
  612. if (NULL == pBlob)
  613. goto Exit;
  614. //----- Copy connection information into the blob -----
  615. ZeroMemory(pBlob, cbBlob);
  616. pCur = pBlob;
  617. // INTERNET_PER_CONN_OPTION_LIST header
  618. *((PDWORD)pCur) = cbBlob; // listA.dwSize
  619. pCur += sizeof(DWORD);
  620. lcy50_CopySzToBlobA(&pCur, listA.pszConnection); // listA.pszConnection
  621. #ifdef _WIN64
  622. pCur = MyPbAlignPb(pCur);
  623. #endif
  624. *((PDWORD)pCur) = listA.dwOptionCount; // listA.dwOptionCount
  625. pCur += sizeof(DWORD);
  626. // INTERNET_PER_CONN_xxx - all of listA.pOptions
  627. for (i = 0; i < min(listA.dwOptionCount, countof(rgOptionsA)); i++) {
  628. *((PDWORD)pCur) = listA.pOptions[i].dwOption;
  629. pCur += sizeof(DWORD);
  630. switch (listA.pOptions[i].dwOption) {
  631. case INTERNET_PER_CONN_PROXY_SERVER:
  632. case INTERNET_PER_CONN_PROXY_BYPASS:
  633. case INTERNET_PER_CONN_AUTOCONFIG_URL:
  634. case INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL:
  635. lcy50_CopySzToBlobA(&pCur, listA.pOptions[i].Value.pszValue);
  636. #ifdef _WIN64
  637. pCur = MyPbAlignPb(pCur);
  638. #endif
  639. break;
  640. case INTERNET_PER_CONN_FLAGS:
  641. case INTERNET_PER_CONN_AUTOCONFIG_RELOAD_DELAY_MINS:
  642. case INTERNET_PER_CONN_AUTODISCOVERY_FLAGS:
  643. default: // everything else is also DWORD
  644. *((PDWORD)pCur) = listA.pOptions[i].Value.dwValue;
  645. pCur += sizeof(DWORD);
  646. break;
  647. }
  648. }
  649. ASSERT(pCur == pBlob + cbBlob);
  650. WriteFile(pcrsp->lcy50.hfileSet, pBlob, cbBlob, &cbAux, NULL);
  651. // NOTE: (andrewgu) no processing that saves LAN's autoconfig and proxy settings to the ins is
  652. // needed. this processing is performed when processing settings for the new format. the
  653. // information is ulimately the same it's just stored differently.
  654. Exit:
  655. if (NULL != pBlob)
  656. CoTaskMemFree(pBlob);
  657. if (NULL != listA.pOptions[1].Value.pszValue) // INTERNET_PER_CONN_PROXY_SERVER
  658. GlobalFree(listA.pOptions[1].Value.pszValue);
  659. if (NULL != listA.pOptions[2].Value.pszValue) // INTERNET_PER_CONN_PROXY_BYPASS
  660. GlobalFree(listA.pOptions[2].Value.pszValue);
  661. if (NULL != listA.pOptions[3].Value.pszValue) // INTERNET_PER_CONN_AUTOCONFIG_URL
  662. GlobalFree(listA.pOptions[3].Value.pszValue);
  663. if (NULL != listA.pOptions[4].Value.pszValue) // INTERNET_PER_CONN_AUTOCONFIG_SECONDARY_URL
  664. GlobalFree(listA.pOptions[4].Value.pszValue);
  665. return TRUE;
  666. }
  667. inline void lcy50_CopySzToBlobA(PBYTE *ppBlob, PCSTR pszStrA)
  668. {
  669. ASSERT(ppBlob != NULL && *ppBlob != NULL);
  670. if (NULL == pszStrA) {
  671. *((PDWORD)(*ppBlob)) = (DWORD)NULL;
  672. *ppBlob += sizeof(DWORD);
  673. }
  674. else {
  675. StrCpyA((PSTR)(*ppBlob), pszStrA);
  676. *ppBlob += StrCbFromSzA(pszStrA);
  677. }
  678. }
  679. BOOL deleteScriptFiles(PCTSTR pszSettingsFile, PCTSTR pszExtractPath, PCTSTR pszIns)
  680. {
  681. TCHAR szScript[MAX_PATH],
  682. szKey[16];
  683. PBYTE pBlob, pCur;
  684. HANDLE hFile;
  685. DWORD dwVersion,
  686. cbBlob, cbAux;
  687. BOOL fResult;
  688. if (pszSettingsFile == NULL || *pszSettingsFile == TEXT('\0') ||
  689. pszExtractPath == NULL || *pszExtractPath == TEXT('\0'))
  690. return FALSE;
  691. hFile = NULL;
  692. pBlob = NULL;
  693. fResult = FALSE;
  694. //----- Read settings file into internal memory buffer -----
  695. hFile = CreateFile(pszSettingsFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
  696. if (hFile == INVALID_HANDLE_VALUE) {
  697. hFile = NULL;
  698. goto Exit;
  699. }
  700. SetFilePointer(hFile, 0, NULL, FILE_BEGIN);
  701. cbBlob = GetFileSize(hFile, NULL);
  702. if (cbBlob == 0xFFFFFFFF)
  703. goto Exit;
  704. pBlob = (PBYTE)CoTaskMemAlloc(cbBlob);
  705. if (pBlob == NULL)
  706. goto Exit;
  707. ZeroMemory(pBlob, cbBlob);
  708. if (ReadFile(hFile, pBlob, cbBlob, &cbAux, NULL) != TRUE)
  709. goto Exit;
  710. dwVersion = *((PDWORD)pBlob);
  711. pCur = pBlob + sizeof(DWORD);
  712. if (dwVersion == CS_VERSION_50) {
  713. LPRASENTRYA preA;
  714. PSTR pszScriptA;
  715. UINT i;
  716. //----- Parse through RAS connections information -----
  717. for (i = 0; TRUE; i++, pCur += cbAux) {
  718. //_____ Initialization _____
  719. wnsprintf(szKey, countof(szKey), IK_CONNECTNAME, i);
  720. if (InsKeyExists(IS_CONNECTSET, szKey, pszIns))
  721. break;
  722. wnsprintf(szKey, countof(szKey), IK_CONNECTSIZE, i);
  723. cbAux = InsGetInt(IS_CONNECTSET, szKey, 0, pszIns);
  724. if (cbAux == 0)
  725. goto Exit;
  726. //_____ Main processing _____
  727. preA = (LPRASENTRYA)pCur;
  728. if (preA->szScript[0] != '\0') {
  729. pszScriptA = preA->szScript;
  730. if (preA->szScript[0] == '[')
  731. pszScriptA = &preA->szScript[1];
  732. A2Tbuf(pszScriptA, szScript, countof(szScript));
  733. DeleteFileInDir(PathFindFileName(szScript), pszExtractPath);
  734. }
  735. }
  736. }
  737. else if (dwVersion >= CS_VERSION_5X && dwVersion <= CS_VERSION_5X_MAX) {
  738. LPRASENTRYW preW;
  739. PWSTR pszScriptW;
  740. //----- Parse through all structures -----
  741. while (pCur < pBlob + cbBlob)
  742. switch (*((PDWORD)pCur)) {
  743. case CS_STRUCT_RAS:
  744. //_____ Main processing _____
  745. preW = (LPRASENTRYW)(pCur + 2*sizeof(DWORD));
  746. // preW->szScript
  747. if (preW->szScript[0] != L'\0') {
  748. pszScriptW = preW->szScript;
  749. if (preW->szScript[0] == L'[')
  750. pszScriptW = &preW->szScript[1];
  751. W2Tbuf(pszScriptW, szScript, countof(szScript));
  752. DeleteFileInDir(PathFindFileName(szScript), pszExtractPath);
  753. }
  754. break;
  755. default:
  756. pCur += *((PDWORD)(pCur + sizeof(DWORD)));
  757. }
  758. }
  759. else {
  760. ASSERT(FALSE);
  761. goto Exit;
  762. }
  763. fResult = TRUE;
  764. //----- Cleanup -----
  765. Exit:
  766. if (pBlob != NULL)
  767. CoTaskMemFree(pBlob);
  768. if (hFile != NULL)
  769. CloseFile(hFile);
  770. return fResult;
  771. }
  772. void parseProxyToIns(PCTSTR pszProxy, PCTSTR pszIns)
  773. {
  774. struct {
  775. PCTSTR pszServer;
  776. PCTSTR pszKey;
  777. PCTSTR pszValue;
  778. } rgProxyMap[] = {
  779. { TEXT("http"), IK_HTTPPROXY, NULL },
  780. { TEXT("https"), IK_SECPROXY, NULL },
  781. { TEXT("ftp"), IK_FTPPROXY, NULL },
  782. { TEXT("gopher"), IK_GOPHERPROXY, NULL },
  783. { TEXT("socks"), IK_SOCKSPROXY, NULL }
  784. };
  785. TCHAR szProxy[MAX_PATH];
  786. PTSTR pszCur, pszToken, pszAux;
  787. UINT i;
  788. BOOL fSameProxy;
  789. if (pszProxy == NULL || *pszProxy == TEXT('\0') ||
  790. pszIns == NULL || *pszIns == TEXT('\0'))
  791. return;
  792. fSameProxy = (NULL == StrChr(pszProxy, TEXT('=')));
  793. InsWriteBool(IS_PROXY, IK_SAMEPROXY, fSameProxy, pszIns);
  794. if (fSameProxy) {
  795. InsWriteString(IS_PROXY, IK_HTTPPROXY, pszProxy, pszIns);
  796. return;
  797. }
  798. StrCpy(szProxy, pszProxy);
  799. for (pszCur = szProxy;
  800. pszCur != NULL && *pszCur != TEXT('\0');
  801. pszCur = (pszToken != NULL) ? (pszToken + 1) : NULL) {
  802. // strip out token in the from "server=value:port#;"
  803. pszToken = StrChr(pszCur, TEXT(';'));
  804. if (pszToken != NULL)
  805. *pszToken = TEXT('\0');
  806. // strip out the server part "server="
  807. pszAux = StrChr(pszCur, TEXT('='));
  808. if (pszAux == NULL) {
  809. ASSERT(FALSE); // no TEXT('=') in the token,
  810. continue; // continue
  811. }
  812. *pszAux = TEXT('\0');
  813. StrRemoveWhitespace(pszCur);
  814. for (i = 0; i < countof(rgProxyMap); i++)
  815. if (0 == StrCmpI(rgProxyMap[i].pszServer, pszCur))
  816. break;
  817. if (i >= countof(rgProxyMap))
  818. continue; // unknown server, continue
  819. StrRemoveWhitespace(pszAux + 1);
  820. rgProxyMap[i].pszValue = pszAux + 1;
  821. }
  822. for (i = 0; i < countof(rgProxyMap); i++)
  823. InsWriteString(IS_PROXY, rgProxyMap[i].pszKey, rgProxyMap[i].pszValue, pszIns);
  824. }
  825. inline void copySzToBlob(PBYTE *ppBlob, PCWSTR pszStrW)
  826. {
  827. ASSERT(ppBlob != NULL && *ppBlob != NULL);
  828. if (pszStrW == NULL) {
  829. *((PDWORD)(*ppBlob)) = (DWORD)NULL;
  830. *ppBlob += sizeof(DWORD);
  831. }
  832. else {
  833. StrCpyW((PWSTR)(*ppBlob), pszStrW);
  834. *ppBlob += StrCbFromSzW(pszStrW);
  835. }
  836. }