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.

2070 lines
50 KiB

  1. /*
  2. * persist.cpp - IPersist, IPersistFile, and IPersistStream implementations for
  3. * CConfLink class.
  4. *
  5. * Taken from URL code - very similar to DavidDi's original code
  6. *
  7. * Created: ChrisPi 9-11-95
  8. *
  9. */
  10. /* Headers
  11. **********/
  12. #include "precomp.h"
  13. #include "CLinkID.h"
  14. #include "clrefcnt.hpp"
  15. #include "clenumft.hpp"
  16. #include "clCnfLnk.hpp"
  17. /* Global Constants
  18. *******************/
  19. #pragma data_seg(DATA_SEG_READ_ONLY)
  20. static const UINT g_ucMaxNameLen = MAX_DIALINFO_STRING; // (was 1024)
  21. static const UINT g_ucMaxAddrLen = MAX_DIALINFO_STRING; // (was 1024)
  22. static const UINT g_ucMaxRemoteConfNameLen = MAX_DIALINFO_STRING; // (was 1024)
  23. static const char g_cszConfLinkExt[] = ".cnf";
  24. static const char g_cszConfLinkDefaultFileNamePrompt[] = "*.cnf";
  25. static const char g_cszCRLF[] = "\r\n";
  26. static const char g_cszEmpty[] = "";
  27. #define EMPTY_STRING g_cszEmpty
  28. #pragma data_seg()
  29. /* Module Constants
  30. *******************/
  31. #pragma data_seg(DATA_SEG_READ_ONLY)
  32. // case-insensitive
  33. const char s_cszSectionBefore[] = "[";
  34. const char s_cszSectionAfter[] = "]";
  35. const char s_cszKeyValueSep[] = "=";
  36. const char s_cszConferenceShortcutSection[] = "ConferenceShortcut";
  37. const char s_cszNameKey[] = "ConfName";
  38. const char s_cszAddressKey[] = "Address";
  39. const char s_cszTransportKey[] = "Transport";
  40. const char s_cszRemoteConfNameKey[] = "RemoteConfName";
  41. const char s_cszCallFlagsKey[] = "CallFlags";
  42. const char s_cszIconFileKey[] = "IconFile";
  43. const char s_cszIconIndexKey[] = "IconIndex";
  44. const char s_cszHotkeyKey[] = "Hotkey";
  45. const char s_cszWorkingDirectoryKey[] = "WorkingDirectory";
  46. const char s_cszShowCmdKey[] = "ShowCommand";
  47. const UINT s_ucMaxIconIndexLen = 1 + 10 + 1; // -2147483647
  48. const UINT s_ucMaxTransportLen = 10 + 1; // 4294967296
  49. const UINT s_ucMaxCallFlagsLen = 10 + 1; // 4294967296
  50. const UINT s_ucMaxHotkeyLen = s_ucMaxIconIndexLen;
  51. const UINT s_ucMaxShowCmdLen = s_ucMaxIconIndexLen;
  52. #pragma data_seg()
  53. /***************************** Private Functions *****************************/
  54. BOOL DeletePrivateProfileString(PCSTR pcszSection, PCSTR pcszKey,
  55. PCSTR pcszFile)
  56. {
  57. ASSERT(IS_VALID_STRING_PTR(pcszSection, CSTR));
  58. ASSERT(IS_VALID_STRING_PTR(pcszKey, CSTR));
  59. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  60. return(WritePrivateProfileString(pcszSection, pcszKey, NULL, pcszFile));
  61. }
  62. HRESULT ReadConfNameFromFile(PCSTR pcszFile, PSTR *ppszName)
  63. {
  64. HRESULT hr;
  65. PSTR pszNewName;
  66. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  67. ASSERT(IS_VALID_WRITE_PTR(ppszName, PSTR));
  68. *ppszName = NULL;
  69. pszNewName = new(char[g_ucMaxNameLen]);
  70. if (pszNewName)
  71. {
  72. DWORD dwcValueLen;
  73. dwcValueLen = GetPrivateProfileString(s_cszConferenceShortcutSection,
  74. s_cszNameKey, EMPTY_STRING,
  75. pszNewName, g_ucMaxNameLen, pcszFile);
  76. if (dwcValueLen > 0)
  77. {
  78. hr = S_OK;
  79. *ppszName = pszNewName;
  80. }
  81. else
  82. {
  83. hr = S_FALSE;
  84. WARNING_OUT(("ReadConfNameFromFile: No Name found in file %s.",
  85. pcszFile));
  86. }
  87. }
  88. else
  89. hr = E_OUTOFMEMORY;
  90. if (FAILED(hr) ||
  91. hr == S_FALSE)
  92. {
  93. if (pszNewName)
  94. {
  95. delete [] pszNewName;
  96. pszNewName = NULL;
  97. }
  98. }
  99. ASSERT((hr == S_OK &&
  100. IS_VALID_STRING_PTR(*ppszName, STR)) ||
  101. (hr != S_OK &&
  102. ! *ppszName));
  103. return(hr);
  104. }
  105. HRESULT WriteConfNameToFile(PCSTR pcszFile, PCSTR pcszName)
  106. {
  107. HRESULT hr;
  108. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  109. ASSERT(! pcszName ||
  110. IS_VALID_STRING_PTR(pcszName, CSTR));
  111. if (AnyMeat(pcszName))
  112. {
  113. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  114. ASSERT(IS_VALID_STRING_PTR(pcszName, PSTR));
  115. // (- 1) for null terminator.
  116. hr = (WritePrivateProfileString(s_cszConferenceShortcutSection, s_cszNameKey,
  117. pcszName, pcszFile)) ? S_OK : E_FAIL;
  118. }
  119. else
  120. hr = (DeletePrivateProfileString(s_cszConferenceShortcutSection, s_cszNameKey, pcszFile))
  121. ? S_OK
  122. : E_FAIL;
  123. return(hr);
  124. }
  125. HRESULT ReadAddressFromFile(PCSTR pcszFile, PSTR *ppszAddress)
  126. {
  127. HRESULT hr;
  128. PSTR pszNewAddr;
  129. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  130. ASSERT(IS_VALID_WRITE_PTR(ppszAddress, PSTR));
  131. *ppszAddress = NULL;
  132. pszNewAddr = new(char[g_ucMaxAddrLen]);
  133. if (pszNewAddr)
  134. {
  135. DWORD dwcValueLen;
  136. dwcValueLen = GetPrivateProfileString(s_cszConferenceShortcutSection,
  137. s_cszAddressKey, EMPTY_STRING,
  138. pszNewAddr, g_ucMaxAddrLen, pcszFile);
  139. if (dwcValueLen > 0)
  140. {
  141. hr = S_OK;
  142. *ppszAddress = pszNewAddr;
  143. }
  144. else
  145. {
  146. hr = S_FALSE;
  147. WARNING_OUT(("ReadAddressFromFile: No Address found in file %s.",
  148. pcszFile));
  149. }
  150. }
  151. else
  152. hr = E_OUTOFMEMORY;
  153. if (FAILED(hr) ||
  154. hr == S_FALSE)
  155. {
  156. if (pszNewAddr)
  157. {
  158. delete [] pszNewAddr;
  159. pszNewAddr = NULL;
  160. }
  161. }
  162. ASSERT((hr == S_OK &&
  163. IS_VALID_STRING_PTR(*ppszAddress, STR)) ||
  164. (hr != S_OK &&
  165. ! *ppszAddress));
  166. return(hr);
  167. }
  168. HRESULT WriteAddressToFile(PCSTR pcszFile, PCSTR pcszAddress)
  169. {
  170. HRESULT hr;
  171. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  172. ASSERT(! pcszAddress ||
  173. IS_VALID_STRING_PTR(pcszAddress, CSTR));
  174. if (AnyMeat(pcszAddress))
  175. {
  176. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  177. ASSERT(IS_VALID_STRING_PTR(pcszAddress, PSTR));
  178. // (- 1) for null terminator.
  179. hr = (WritePrivateProfileString(s_cszConferenceShortcutSection, s_cszAddressKey,
  180. pcszAddress, pcszFile)) ? S_OK : E_FAIL;
  181. }
  182. else
  183. hr = (DeletePrivateProfileString(s_cszConferenceShortcutSection, s_cszAddressKey, pcszFile))
  184. ? S_OK
  185. : E_FAIL;
  186. return(hr);
  187. }
  188. HRESULT ReadRemoteConfNameFromFile(PCSTR pcszFile,
  189. PSTR *ppszRemoteConfName)
  190. {
  191. HRESULT hr;
  192. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  193. ASSERT(IS_VALID_WRITE_PTR(ppszRemoteConfName, PSTR));
  194. *ppszRemoteConfName = NULL;
  195. PSTR pszNewRemoteConfName = new(char[g_ucMaxAddrLen]);
  196. if (pszNewRemoteConfName)
  197. {
  198. DWORD dwcValueLen;
  199. dwcValueLen = GetPrivateProfileString(s_cszConferenceShortcutSection,
  200. s_cszRemoteConfNameKey, EMPTY_STRING,
  201. pszNewRemoteConfName,
  202. g_ucMaxRemoteConfNameLen, pcszFile);
  203. if (dwcValueLen > 0)
  204. {
  205. hr = S_OK;
  206. *ppszRemoteConfName = pszNewRemoteConfName;
  207. }
  208. else
  209. {
  210. hr = S_FALSE;
  211. TRACE_OUT(("ReadRemoteConfNameFromFile: No RemoteConfName found in file %s.",
  212. pcszFile));
  213. }
  214. }
  215. else
  216. hr = E_OUTOFMEMORY;
  217. if (FAILED(hr) ||
  218. hr == S_FALSE)
  219. {
  220. delete [] pszNewRemoteConfName;
  221. pszNewRemoteConfName = NULL;
  222. }
  223. ASSERT((hr == S_OK &&
  224. IS_VALID_STRING_PTR(*ppszRemoteConfName, STR)) ||
  225. (hr != S_OK &&
  226. ! *ppszRemoteConfName));
  227. return(hr);
  228. }
  229. HRESULT WriteRemoteConfNameToFile(PCSTR pcszFile,
  230. PCSTR pcszRemoteConfName)
  231. {
  232. HRESULT hr;
  233. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  234. ASSERT(! pcszRemoteConfName ||
  235. IS_VALID_STRING_PTR(pcszRemoteConfName, CSTR));
  236. if (AnyMeat(pcszRemoteConfName))
  237. {
  238. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  239. ASSERT(IS_VALID_STRING_PTR(pcszRemoteConfName, PSTR));
  240. // (- 1) for null terminator.
  241. hr = (WritePrivateProfileString(s_cszConferenceShortcutSection, s_cszRemoteConfNameKey,
  242. pcszRemoteConfName, pcszFile)) ? S_OK : E_FAIL;
  243. }
  244. else
  245. {
  246. hr = (DeletePrivateProfileString( s_cszConferenceShortcutSection,
  247. s_cszRemoteConfNameKey,
  248. pcszFile))
  249. ? S_OK
  250. : E_FAIL;
  251. }
  252. return(hr);
  253. }
  254. HRESULT ReadTransportFromFile(PCSTR pcszFile, PDWORD pdwTransport)
  255. {
  256. HRESULT hr;
  257. char rgchNewTransport[s_ucMaxTransportLen];
  258. DWORD dwcValueLen;
  259. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  260. ASSERT(IS_VALID_WRITE_PTR(pdwTransport, INT));
  261. *pdwTransport = 0;
  262. dwcValueLen = GetPrivateProfileString(s_cszConferenceShortcutSection,
  263. s_cszTransportKey, EMPTY_STRING,
  264. rgchNewTransport,
  265. sizeof(rgchNewTransport), pcszFile);
  266. if (dwcValueLen > 0)
  267. {
  268. *pdwTransport = DecimalStringToUINT(rgchNewTransport);
  269. hr = S_OK;
  270. }
  271. else
  272. {
  273. hr = S_FALSE;
  274. TRACE_OUT(("ReadTransportFromFile: No transport found in file %s.",
  275. pcszFile));
  276. }
  277. ASSERT((hr == S_OK) ||
  278. (hr == S_FALSE &&
  279. EVAL(*pdwTransport == 0)));
  280. return(hr);
  281. }
  282. HRESULT WriteTransportToFile(PCSTR pcszFile, DWORD dwTransport)
  283. {
  284. HRESULT hr;
  285. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  286. char rgchTransportRHS[s_ucMaxTransportLen];
  287. int ncLen;
  288. ncLen = wsprintf(rgchTransportRHS, "%u", dwTransport);
  289. ASSERT(ncLen > 0);
  290. ASSERT(ncLen < sizeof(rgchTransportRHS));
  291. ASSERT(ncLen == lstrlen(rgchTransportRHS));
  292. hr = (WritePrivateProfileString(s_cszConferenceShortcutSection,
  293. s_cszTransportKey, rgchTransportRHS,
  294. pcszFile))
  295. ? S_OK
  296. : E_FAIL;
  297. return(hr);
  298. }
  299. HRESULT ReadCallFlagsFromFile(PCSTR pcszFile, PDWORD pdwCallFlags)
  300. {
  301. HRESULT hr;
  302. char rgchNewCallFlags[s_ucMaxCallFlagsLen];
  303. DWORD dwcValueLen;
  304. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  305. ASSERT(IS_VALID_WRITE_PTR(pdwCallFlags, INT));
  306. *pdwCallFlags = 0;
  307. dwcValueLen = GetPrivateProfileString(s_cszConferenceShortcutSection,
  308. s_cszCallFlagsKey, EMPTY_STRING,
  309. rgchNewCallFlags,
  310. sizeof(rgchNewCallFlags), pcszFile);
  311. if (dwcValueLen > 0)
  312. {
  313. *pdwCallFlags = DecimalStringToUINT(rgchNewCallFlags);
  314. hr = S_OK;
  315. }
  316. else
  317. {
  318. hr = S_FALSE;
  319. TRACE_OUT(("ReadCallFlagsFromFile: No CallFlags found in file %s.",
  320. pcszFile));
  321. }
  322. ASSERT((hr == S_OK) ||
  323. (hr == S_FALSE &&
  324. EVAL(*pdwCallFlags == 0)));
  325. return(hr);
  326. }
  327. HRESULT WriteCallFlagsToFile(PCSTR pcszFile, DWORD dwCallFlags)
  328. {
  329. HRESULT hr;
  330. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  331. char rgchCallFlagsRHS[s_ucMaxCallFlagsLen];
  332. int ncLen;
  333. ncLen = wsprintf(rgchCallFlagsRHS, "%u", dwCallFlags);
  334. ASSERT(ncLen > 0);
  335. ASSERT(ncLen < sizeof(rgchCallFlagsRHS));
  336. ASSERT(ncLen == lstrlen(rgchCallFlagsRHS));
  337. hr = (WritePrivateProfileString(s_cszConferenceShortcutSection,
  338. s_cszCallFlagsKey, rgchCallFlagsRHS,
  339. pcszFile))
  340. ? S_OK
  341. : E_FAIL;
  342. return(hr);
  343. }
  344. #if 0
  345. HRESULT ReadIconLocationFromFile(PCSTR pcszFile,
  346. PSTR *ppszIconFile, PINT pniIcon)
  347. {
  348. HRESULT hr;
  349. char rgchNewIconFile[MAX_PATH_LEN];
  350. DWORD dwcValueLen;
  351. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  352. ASSERT(IS_VALID_WRITE_PTR(ppszIconFile, PSTR));
  353. ASSERT(IS_VALID_WRITE_PTR(pniIcon, INT));
  354. *ppszIconFile = NULL;
  355. *pniIcon = 0;
  356. dwcValueLen = GetPrivateProfileString(s_cszInternetShortcutSection,
  357. s_cszIconFileKey, EMPTY_STRING,
  358. rgchNewIconFile,
  359. sizeof(rgchNewIconFile), pcszFile);
  360. if (dwcValueLen > 0)
  361. {
  362. char rgchNewIconIndex[s_ucMaxIconIndexLen];
  363. dwcValueLen = GetPrivateProfileString(s_cszInternetShortcutSection,
  364. s_cszIconIndexKey,
  365. EMPTY_STRING, rgchNewIconIndex,
  366. sizeof(rgchNewIconIndex),
  367. pcszFile);
  368. if (dwcValueLen > 0)
  369. {
  370. int niIcon = DecimalStringToUINT(rgchNewIconIndex);
  371. *ppszIconFile = new(char[lstrlen(rgchNewIconFile) + 1]);
  372. if (*ppszIconFile)
  373. {
  374. lstrcpy(*ppszIconFile, rgchNewIconFile);
  375. *pniIcon = niIcon;
  376. hr = S_OK;
  377. }
  378. else
  379. hr = E_OUTOFMEMORY;
  380. }
  381. else
  382. {
  383. hr = S_FALSE;
  384. WARNING_OUT(("ReadIconLocationFromFile(): No icon index found in file %s.",
  385. pcszFile));
  386. }
  387. }
  388. else
  389. {
  390. hr = S_FALSE;
  391. TRACE_OUT(("ReadIconLocationFromFile(): No icon file found in file %s.",
  392. pcszFile));
  393. }
  394. ASSERT(IsValidIconIndex(hr, *ppszIconFile, MAX_PATH_LEN, *pniIcon));
  395. return(hr);
  396. }
  397. HRESULT WriteIconLocationToFile(PCSTR pcszFile,
  398. PCSTR pcszIconFile,
  399. int niIcon)
  400. {
  401. HRESULT hr;
  402. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  403. ASSERT(! pcszIconFile ||
  404. IS_VALID_STRING_PTR(pcszIconFile, CSTR));
  405. ASSERT(IsValidIconIndex((pcszIconFile ? S_OK : S_FALSE), pcszIconFile, MAX_PATH_LEN, niIcon));
  406. if (AnyMeat(pcszIconFile))
  407. {
  408. char rgchIconIndexRHS[s_ucMaxIconIndexLen];
  409. int ncLen;
  410. ncLen = wsprintf(rgchIconIndexRHS, "%d", niIcon);
  411. ASSERT(ncLen > 0);
  412. ASSERT(ncLen < sizeof(rgchIconIndexRHS));
  413. ASSERT(ncLen == lstrlen(rgchIconIndexRHS));
  414. hr = (WritePrivateProfileString(s_cszInternetShortcutSection,
  415. s_cszIconFileKey, pcszIconFile,
  416. pcszFile) &&
  417. WritePrivateProfileString(s_cszInternetShortcutSection,
  418. s_cszIconIndexKey, rgchIconIndexRHS,
  419. pcszFile))
  420. ? S_OK
  421. : E_FAIL;
  422. }
  423. else
  424. hr = (DeletePrivateProfileString(s_cszInternetShortcutSection,
  425. s_cszIconFileKey, pcszFile) &&
  426. DeletePrivateProfileString(s_cszInternetShortcutSection,
  427. s_cszIconIndexKey, pcszFile))
  428. ? S_OK
  429. : E_FAIL;
  430. return(hr);
  431. }
  432. HRESULT ReadHotkeyFromFile(PCSTR pcszFile, PWORD pwHotkey)
  433. {
  434. HRESULT hr = S_FALSE;
  435. char rgchHotkey[s_ucMaxHotkeyLen];
  436. DWORD dwcValueLen;
  437. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  438. ASSERT(IS_VALID_WRITE_PTR(pwHotkey, WORD));
  439. *pwHotkey = 0;
  440. dwcValueLen = GetPrivateProfileString(s_cszInternetShortcutSection,
  441. s_cszHotkeyKey, EMPTY_STRING,
  442. rgchHotkey, sizeof(rgchHotkey),
  443. pcszFile);
  444. if (dwcValueLen > 0)
  445. {
  446. *pwHotkey = (WORD) DecimalStringToUINT(rgchHotkey);
  447. hr = S_OK;
  448. }
  449. else
  450. WARNING_OUT(("ReadHotkeyFromFile(): No hotkey found in file %s.",
  451. pcszFile));
  452. ASSERT((hr == S_OK &&
  453. IsValidHotkey(*pwHotkey)) ||
  454. (hr == S_FALSE &&
  455. ! *pwHotkey));
  456. return(hr);
  457. }
  458. HRESULT WriteHotkeyToFile(PCSTR pcszFile, WORD wHotkey)
  459. {
  460. HRESULT hr;
  461. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  462. ASSERT(! wHotkey ||
  463. IsValidHotkey(wHotkey));
  464. if (wHotkey)
  465. {
  466. char rgchHotkeyRHS[s_ucMaxHotkeyLen];
  467. int ncLen;
  468. ncLen = wsprintf(rgchHotkeyRHS, "%u", (UINT)wHotkey);
  469. ASSERT(ncLen > 0);
  470. ASSERT(ncLen < sizeof(rgchHotkeyRHS));
  471. ASSERT(ncLen == lstrlen(rgchHotkeyRHS));
  472. hr = WritePrivateProfileString(s_cszInternetShortcutSection,
  473. s_cszHotkeyKey, rgchHotkeyRHS,
  474. pcszFile)
  475. ? S_OK
  476. : E_FAIL;
  477. }
  478. else
  479. hr = DeletePrivateProfileString(s_cszInternetShortcutSection,
  480. s_cszHotkeyKey, pcszFile)
  481. ? S_OK
  482. : E_FAIL;
  483. return(hr);
  484. }
  485. HRESULT ReadWorkingDirectoryFromFile(PCSTR pcszFile,
  486. PSTR *ppszWorkingDirectory)
  487. {
  488. HRESULT hr;
  489. char rgchDirValue[MAX_PATH_LEN];
  490. DWORD dwcValueLen;
  491. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  492. ASSERT(IS_VALID_WRITE_PTR(ppszWorkingDirectory, PSTR));
  493. *ppszWorkingDirectory = NULL;
  494. dwcValueLen = GetPrivateProfileString(s_cszInternetShortcutSection,
  495. s_cszWorkingDirectoryKey,
  496. EMPTY_STRING, rgchDirValue,
  497. sizeof(rgchDirValue), pcszFile);
  498. if (dwcValueLen > 0)
  499. {
  500. char rgchFullPath[MAX_PATH_LEN];
  501. PSTR pszFileName;
  502. if (GetFullPathName(rgchDirValue, sizeof(rgchFullPath), rgchFullPath,
  503. &pszFileName) > 0)
  504. {
  505. // (+ 1) for null terminator.
  506. *ppszWorkingDirectory = new(char[lstrlen(rgchFullPath) + 1]);
  507. if (*ppszWorkingDirectory)
  508. {
  509. lstrcpy(*ppszWorkingDirectory, rgchFullPath);
  510. hr = S_OK;
  511. }
  512. else
  513. hr = E_OUTOFMEMORY;
  514. }
  515. else
  516. hr = E_FAIL;
  517. }
  518. else
  519. {
  520. hr = S_FALSE;
  521. TRACE_OUT(("ReadWorkingDirectoryFromFile: No working directory found in file %s.",
  522. pcszFile));
  523. }
  524. ASSERT(IsValidPathResult(hr, *ppszWorkingDirectory, MAX_PATH_LEN));
  525. return(hr);
  526. }
  527. HRESULT WriteWorkingDirectoryToFile(PCSTR pcszFile,
  528. PCSTR pcszWorkingDirectory)
  529. {
  530. HRESULT hr;
  531. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  532. ASSERT(! pcszWorkingDirectory ||
  533. IS_VALID_STRING_PTR(pcszWorkingDirectory, CSTR));
  534. if (AnyMeat(pcszWorkingDirectory))
  535. hr = (WritePrivateProfileString(s_cszInternetShortcutSection,
  536. s_cszWorkingDirectoryKey,
  537. pcszWorkingDirectory, pcszFile))
  538. ? S_OK
  539. : E_FAIL;
  540. else
  541. hr = (DeletePrivateProfileString(s_cszInternetShortcutSection,
  542. s_cszWorkingDirectoryKey, pcszFile))
  543. ? S_OK
  544. : E_FAIL;
  545. return(hr);
  546. }
  547. HRESULT ReadShowCmdFromFile(PCSTR pcszFile, PINT pnShowCmd)
  548. {
  549. HRESULT hr;
  550. char rgchNewShowCmd[s_ucMaxShowCmdLen];
  551. DWORD dwcValueLen;
  552. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  553. ASSERT(IS_VALID_WRITE_PTR(pnShowCmd, INT));
  554. *pnShowCmd = g_nDefaultShowCmd;
  555. dwcValueLen = GetPrivateProfileString(s_cszInternetShortcutSection,
  556. s_cszShowCmdKey, EMPTY_STRING,
  557. rgchNewShowCmd,
  558. sizeof(rgchNewShowCmd), pcszFile);
  559. if (dwcValueLen > 0)
  560. {
  561. *pnShowCmd = DecimalStringToUINT(rgchNewShowCmd);
  562. hr = S_OK;
  563. }
  564. else
  565. {
  566. hr = S_FALSE;
  567. TRACE_OUT(("ReadShowCmdFromFile: No show command found in file %s.",
  568. pcszFile));
  569. }
  570. ASSERT((hr == S_OK &&
  571. EVAL(IsValidShowCmd(*pnShowCmd))) ||
  572. (hr == S_FALSE &&
  573. EVAL(*pnShowCmd == g_nDefaultShowCmd)));
  574. return(hr);
  575. }
  576. HRESULT WriteShowCmdToFile(PCSTR pcszFile, int nShowCmd)
  577. {
  578. HRESULT hr;
  579. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  580. ASSERT(IsValidShowCmd(nShowCmd));
  581. if (nShowCmd != g_nDefaultShowCmd)
  582. {
  583. char rgchShowCmdRHS[s_ucMaxShowCmdLen];
  584. int ncLen;
  585. ncLen = wsprintf(rgchShowCmdRHS, "%d", nShowCmd);
  586. ASSERT(ncLen > 0);
  587. ASSERT(ncLen < sizeof(rgchShowCmdRHS));
  588. ASSERT(ncLen == lstrlen(rgchShowCmdRHS));
  589. hr = (WritePrivateProfileString(s_cszInternetShortcutSection,
  590. s_cszShowCmdKey, rgchShowCmdRHS,
  591. pcszFile))
  592. ? S_OK
  593. : E_FAIL;
  594. }
  595. else
  596. hr = (DeletePrivateProfileString(s_cszInternetShortcutSection,
  597. s_cszShowCmdKey, pcszFile))
  598. ? S_OK
  599. : E_FAIL;
  600. return(hr);
  601. }
  602. #endif // 0
  603. /****************************** Public Functions *****************************/
  604. // BUGBUG - Isn't this already in NMUTIL?
  605. HRESULT UnicodeToANSI(LPCOLESTR pcwszUnicode, PSTR *ppszANSI)
  606. {
  607. HRESULT hr;
  608. int ncbLen;
  609. // BUGBUG: Need OLESTR validation function to validate pcwszUnicode here.
  610. ASSERT(IS_VALID_WRITE_PTR(ppszANSI, PSTR));
  611. *ppszANSI = NULL;
  612. // Get length of translated string.
  613. ncbLen = WideCharToMultiByte(CP_ACP, 0, pcwszUnicode, -1, NULL, 0, NULL,
  614. NULL);
  615. if (ncbLen > 0)
  616. {
  617. PSTR pszNewANSI;
  618. // (+ 1) for null terminator.
  619. pszNewANSI = new(char[ncbLen]);
  620. if (pszNewANSI)
  621. {
  622. // Translate string.
  623. if (WideCharToMultiByte(CP_ACP, 0, pcwszUnicode, -1, pszNewANSI,
  624. ncbLen, NULL, NULL) > 0)
  625. {
  626. *ppszANSI = pszNewANSI;
  627. hr = S_OK;
  628. }
  629. else
  630. {
  631. delete [] pszNewANSI;
  632. pszNewANSI = NULL;
  633. hr = E_UNEXPECTED;
  634. WARNING_OUT(("UnicodeToANSI(): Failed to translate Unicode string to ANSI."));
  635. }
  636. }
  637. else
  638. hr = E_OUTOFMEMORY;
  639. }
  640. else
  641. {
  642. hr = E_UNEXPECTED;
  643. WARNING_OUT(("UnicodeToANSI(): Failed to get length of translated ANSI string."));
  644. }
  645. ASSERT(FAILED(hr) ||
  646. IS_VALID_STRING_PTR(*ppszANSI, STR));
  647. return(hr);
  648. }
  649. HRESULT ANSIToUnicode(PCSTR pcszANSI, LPOLESTR *ppwszUnicode)
  650. {
  651. HRESULT hr;
  652. int ncbWideLen;
  653. ASSERT(IS_VALID_STRING_PTR(pcszANSI, CSTR));
  654. ASSERT(IS_VALID_WRITE_PTR(ppwszUnicode, LPOLESTR));
  655. *ppwszUnicode = NULL;
  656. // Get length of translated string.
  657. ncbWideLen = MultiByteToWideChar(CP_ACP, 0, pcszANSI, -1, NULL, 0);
  658. if (ncbWideLen > 0)
  659. {
  660. PWSTR pwszNewUnicode;
  661. // (+ 1) for null terminator.
  662. pwszNewUnicode = new(WCHAR[ncbWideLen]);
  663. if (pwszNewUnicode)
  664. {
  665. // Translate string.
  666. if (MultiByteToWideChar(CP_ACP, 0, pcszANSI, -1, pwszNewUnicode,
  667. ncbWideLen) > 0)
  668. {
  669. *ppwszUnicode = pwszNewUnicode;
  670. hr = S_OK;
  671. }
  672. else
  673. {
  674. delete [] pwszNewUnicode;
  675. pwszNewUnicode = NULL;
  676. hr = E_UNEXPECTED;
  677. WARNING_OUT(("ANSIToUnicode(): Failed to translate ANSI path string to Unicode."));
  678. }
  679. }
  680. else
  681. hr = E_OUTOFMEMORY;
  682. }
  683. else
  684. {
  685. hr = E_UNEXPECTED;
  686. WARNING_OUT(("ANSIToUnicode(): Failed to get length of translated Unicode string."));
  687. }
  688. // BUGBUG: Need OLESTR validation function to validate *ppwszUnicode here.
  689. return(hr);
  690. }
  691. /********************************** Methods **********************************/
  692. HRESULT STDMETHODCALLTYPE CConfLink::SaveToFile(PCSTR pcszFile,
  693. BOOL bRemember)
  694. {
  695. HRESULT hr;
  696. DebugEntry(CConfLink::SaveToFile);
  697. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  698. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  699. #if 0
  700. PSTR pszName;
  701. hr = GetName(&pszName);
  702. if (SUCCEEDED(hr))
  703. {
  704. hr = WriteConfNameToFile(pcszFile, pszName);
  705. // Free the string:
  706. if (pszName)
  707. {
  708. LPMALLOC pMalloc = NULL;
  709. if (SUCCEEDED(SHGetMalloc(&pMalloc)))
  710. {
  711. pMalloc->Free(pszName);
  712. pMalloc->Release();
  713. pMalloc = NULL;
  714. pszName = NULL;
  715. }
  716. }
  717. }
  718. #endif // 0
  719. hr = S_OK;
  720. if (NULL != m_pszName)
  721. {
  722. hr = WriteConfNameToFile(pcszFile, m_pszName);
  723. }
  724. if ((S_OK == hr) &&
  725. (NULL != m_pszAddress))
  726. {
  727. hr = WriteAddressToFile(pcszFile, m_pszAddress);
  728. }
  729. if ((S_OK == hr) &&
  730. (NULL != m_pszRemoteConfName))
  731. {
  732. hr = WriteRemoteConfNameToFile(pcszFile, m_pszRemoteConfName);
  733. }
  734. if (S_OK == hr)
  735. {
  736. hr = WriteCallFlagsToFile(pcszFile, m_dwCallFlags);
  737. }
  738. if (S_OK == hr)
  739. {
  740. hr = WriteTransportToFile(pcszFile, m_dwTransport);
  741. }
  742. #if 0
  743. if (hr == S_OK)
  744. {
  745. char rgchBuf[MAX_PATH_LEN];
  746. int niIcon;
  747. hr = GetIconLocation(rgchBuf, sizeof(rgchBuf), &niIcon);
  748. if (SUCCEEDED(hr))
  749. {
  750. hr = WriteIconLocationToFile(pcszFile, rgchBuf, niIcon);
  751. if (hr == S_OK)
  752. {
  753. WORD wHotkey;
  754. hr = GetHotkey(&wHotkey);
  755. if (SUCCEEDED(hr))
  756. {
  757. hr = WriteHotkeyToFile(pcszFile, wHotkey);
  758. if (hr == S_OK)
  759. {
  760. hr = GetWorkingDirectory(rgchBuf, sizeof(rgchBuf));
  761. if (SUCCEEDED(hr))
  762. {
  763. hr = WriteWorkingDirectoryToFile(pcszFile, rgchBuf);
  764. if (hr == S_OK)
  765. {
  766. int nShowCmd;
  767. GetShowCmd(&nShowCmd);
  768. hr = WriteShowCmdToFile(pcszFile, nShowCmd);
  769. if (hr == S_OK)
  770. {
  771. /* Remember file if requested. */
  772. #endif
  773. if (bRemember)
  774. {
  775. // Replace existing file string, if any
  776. if (m_pszFile)
  777. {
  778. delete m_pszFile;
  779. }
  780. m_pszFile = new TCHAR[lstrlen(pcszFile)+1];
  781. if (NULL != m_pszFile)
  782. {
  783. lstrcpy(m_pszFile, pcszFile);
  784. TRACE_OUT(("CConfLink::SaveToFile(): Remembering file %s, as requested.",
  785. m_pszFile));
  786. }
  787. else
  788. {
  789. hr = E_OUTOFMEMORY;
  790. }
  791. }
  792. if (hr == S_OK)
  793. {
  794. Dirty(FALSE);
  795. SHChangeNotify(SHCNE_UPDATEITEM,
  796. (SHCNF_PATH | SHCNF_FLUSH), pcszFile,
  797. NULL);
  798. #ifdef DEBUG
  799. TRACE_OUT(("CConfLink::SaveToFile(): Conf Link saved to file %s:",
  800. pcszFile));
  801. Dump();
  802. #endif // DEBUG
  803. }
  804. #if 0
  805. }
  806. }
  807. }
  808. }
  809. }
  810. }
  811. }
  812. }
  813. }
  814. #endif // 0
  815. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  816. DebugExitHRESULT(CConfLink::SaveToFile, hr);
  817. return(hr);
  818. }
  819. HRESULT STDMETHODCALLTYPE CConfLink::LoadFromFile( PCSTR pcszFile,
  820. BOOL bRemember)
  821. {
  822. HRESULT hr;
  823. PSTR pszName;
  824. PSTR pszAddr;
  825. PSTR pszRemoteConfName;
  826. DWORD dwTransport;
  827. DWORD dwCallFlags;
  828. DebugEntry(CConfLink::LoadFromFile);
  829. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  830. ASSERT(IS_VALID_STRING_PTR(pcszFile, CSTR));
  831. hr = ReadConfNameFromFile(pcszFile, &pszName);
  832. if (S_OK == hr)
  833. {
  834. hr = SetName(pszName);
  835. if (pszName)
  836. {
  837. delete pszName;
  838. pszName = NULL;
  839. }
  840. }
  841. if (SUCCEEDED(hr))
  842. {
  843. hr = ReadAddressFromFile(pcszFile, &pszAddr);
  844. if (S_OK == hr)
  845. {
  846. hr = SetAddress(pszAddr);
  847. if (NULL != pszAddr)
  848. {
  849. delete pszAddr;
  850. pszAddr = NULL;
  851. }
  852. }
  853. }
  854. if (SUCCEEDED(hr))
  855. {
  856. hr = ReadTransportFromFile(pcszFile, &dwTransport);
  857. if (S_OK == hr)
  858. {
  859. hr = SetTransport(dwTransport);
  860. }
  861. }
  862. if (SUCCEEDED(hr))
  863. {
  864. hr = ReadCallFlagsFromFile(pcszFile, &dwCallFlags);
  865. if (S_OK == hr)
  866. {
  867. hr = SetCallFlags(dwCallFlags);
  868. }
  869. }
  870. if (SUCCEEDED(hr))
  871. {
  872. hr = ReadRemoteConfNameFromFile(pcszFile, &pszRemoteConfName);
  873. if (S_OK == hr)
  874. {
  875. hr = SetRemoteConfName(pszRemoteConfName);
  876. delete pszRemoteConfName;
  877. pszRemoteConfName = NULL;
  878. }
  879. }
  880. #if 0
  881. if (hr == S_OK)
  882. {
  883. PSTR pszIconFile;
  884. int niIcon;
  885. hr = ReadIconLocationFromFile(pcszFile, &pszIconFile, &niIcon);
  886. if (SUCCEEDED(hr))
  887. {
  888. hr = SetIconLocation(pszIconFile, niIcon);
  889. if (pszIconFile)
  890. {
  891. delete pszIconFile;
  892. pszIconFile = NULL;
  893. }
  894. if (hr == S_OK)
  895. {
  896. WORD wHotkey;
  897. hr = ReadHotkeyFromFile(pcszFile, &wHotkey);
  898. if (SUCCEEDED(hr))
  899. {
  900. hr = SetHotkey(wHotkey);
  901. if (hr == S_OK)
  902. {
  903. PSTR pszWorkingDirectory;
  904. hr = ReadWorkingDirectoryFromFile(pcszFile,
  905. &pszWorkingDirectory);
  906. if (SUCCEEDED(hr))
  907. {
  908. hr = SetWorkingDirectory(pszWorkingDirectory);
  909. if (pszWorkingDirectory)
  910. {
  911. delete pszWorkingDirectory;
  912. pszWorkingDirectory = NULL;
  913. }
  914. if (hr == S_OK)
  915. {
  916. int nShowCmd;
  917. hr = ReadShowCmdFromFile(pcszFile, &nShowCmd);
  918. #endif // 0
  919. if (SUCCEEDED(hr))
  920. {
  921. /* Remember file if requested. */
  922. if (bRemember)
  923. {
  924. // PSTR pszFileCopy;
  925. //
  926. if (NULL != m_pszFile)
  927. {
  928. delete m_pszFile;
  929. }
  930. m_pszFile = new TCHAR[lstrlen(pcszFile) + 1];
  931. if (NULL != m_pszFile)
  932. {
  933. lstrcpy(m_pszFile, pcszFile);
  934. }
  935. else
  936. {
  937. hr = E_OUTOFMEMORY;
  938. }
  939. // if (StringCopy(pcszFile, &pszFileCopy))
  940. // {
  941. // if (m_pszFile)
  942. // delete m_pszFile;
  943. // m_pszFile = pszFileCopy;
  944. // TRACE_OUT(("CConfLink::LoadFromFile(): Remembering file %s, as requested.",
  945. // m_pszFile));
  946. // }
  947. // else
  948. // hr = E_OUTOFMEMORY;
  949. }
  950. if (SUCCEEDED(hr))
  951. {
  952. // SetShowCmd(nShowCmd);
  953. Dirty(FALSE);
  954. hr = S_OK;
  955. #ifdef DEBUG
  956. TRACE_OUT(("CConfLink::LoadFromFile(): Conf Link loaded from file %s:",
  957. pcszFile));
  958. Dump();
  959. #endif
  960. }
  961. }
  962. #if 0
  963. }
  964. }
  965. }
  966. }
  967. }
  968. }
  969. }
  970. }
  971. #endif // 0
  972. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  973. DebugExitHRESULT(CConfLink::LoadFromFile, hr);
  974. return(hr);
  975. }
  976. HRESULT STDMETHODCALLTYPE CConfLink::GetCurFile(PSTR pszFile,
  977. UINT ucbLen)
  978. {
  979. HRESULT hr;
  980. DebugEntry(CConfLink::GetCurFile);
  981. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  982. ASSERT(IS_VALID_WRITE_BUFFER_PTR(pszFile, STR, ucbLen));
  983. if (m_pszFile)
  984. {
  985. lstrcpyn(pszFile, m_pszFile, ucbLen);
  986. TRACE_OUT(("CConfLink::GetCurFile(): Current file name is %s.",
  987. pszFile));
  988. hr = S_OK;
  989. }
  990. else
  991. hr = S_FALSE;
  992. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  993. ASSERT(IS_VALID_STRING_PTR(pszFile, STR) &&
  994. EVAL((UINT)lstrlen(pszFile) < ucbLen));
  995. ASSERT(hr == S_OK ||
  996. hr == S_FALSE);
  997. DebugExitHRESULT(CConfLink::GetCurFile, hr);
  998. return(hr);
  999. }
  1000. HRESULT STDMETHODCALLTYPE CConfLink::Dirty(BOOL bDirty)
  1001. {
  1002. HRESULT hr;
  1003. DebugEntry(CConfLink::Dirty);
  1004. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1005. if (bDirty)
  1006. {
  1007. if (IS_FLAG_CLEAR(m_dwFlags, CONFLNK_FL_DIRTY))
  1008. {
  1009. TRACE_OUT(("CConfLink::Dirty(): Now dirty."));
  1010. }
  1011. SET_FLAG(m_dwFlags, CONFLNK_FL_DIRTY);
  1012. }
  1013. else
  1014. {
  1015. if (IS_FLAG_SET(m_dwFlags, CONFLNK_FL_DIRTY))
  1016. {
  1017. TRACE_OUT(("CConfLink::Dirty(): Now clean."));
  1018. }
  1019. CLEAR_FLAG(m_dwFlags, CONFLNK_FL_DIRTY);
  1020. }
  1021. hr = S_OK;
  1022. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1023. ASSERT(hr == S_OK);
  1024. DebugExitVOID(CConfLink::Dirty);
  1025. return(hr);
  1026. }
  1027. HRESULT STDMETHODCALLTYPE CConfLink::GetClassID(PCLSID pclsid)
  1028. {
  1029. HRESULT hr;
  1030. DebugEntry(CConfLink::GetClassID);
  1031. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1032. ASSERT(IS_VALID_STRUCT_PTR(pclsid, CCLSID));
  1033. *pclsid = CLSID_ConfLink;
  1034. hr = S_OK;
  1035. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1036. ASSERT(FAILED(hr) ||
  1037. IS_VALID_STRUCT_PTR(pclsid, CCLSID));
  1038. DebugExitHRESULT(CConfLink::GetClassID, hr);
  1039. return(hr);
  1040. }
  1041. HRESULT STDMETHODCALLTYPE CConfLink::IsDirty(void)
  1042. {
  1043. HRESULT hr;
  1044. DebugEntry(CConfLink::IsDirty);
  1045. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1046. if (IS_FLAG_SET(m_dwFlags, CONFLNK_FL_DIRTY))
  1047. hr = S_OK;
  1048. else
  1049. hr = S_FALSE;
  1050. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1051. DebugExitHRESULT(CConfLink::IsDirty, hr);
  1052. return(hr);
  1053. }
  1054. HRESULT STDMETHODCALLTYPE CConfLink::Save( LPCOLESTR pcwszFile,
  1055. BOOL bRemember)
  1056. {
  1057. HRESULT hr;
  1058. PSTR pszFile;
  1059. DebugEntry(CConfLink::Save);
  1060. // bRemember may be any value.
  1061. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1062. // BUGBUG: Need OLESTR validation function to validate pcwszFile here.
  1063. if (pcwszFile)
  1064. {
  1065. hr = UnicodeToANSI(pcwszFile, &pszFile);
  1066. if (hr == S_OK)
  1067. {
  1068. hr = SaveToFile(pszFile, bRemember);
  1069. delete pszFile;
  1070. pszFile = NULL;
  1071. }
  1072. }
  1073. else if (m_pszFile)
  1074. // Ignore bRemember.
  1075. hr = SaveToFile(m_pszFile, FALSE);
  1076. else
  1077. hr = E_FAIL;
  1078. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1079. DebugExitHRESULT(CConfLink::Save, hr);
  1080. return(hr);
  1081. }
  1082. // #pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
  1083. HRESULT STDMETHODCALLTYPE CConfLink::SaveCompleted(LPCOLESTR pcwszFile)
  1084. {
  1085. HRESULT hr;
  1086. DebugEntry(CConfLink::SaveCompleted);
  1087. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1088. // BUGBUG: Need OLESTR validation function to validate pcwszFile here.
  1089. hr = S_OK;
  1090. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1091. DebugExitHRESULT(CConfLink::SaveCompleted, hr);
  1092. return(hr);
  1093. }
  1094. HRESULT STDMETHODCALLTYPE CConfLink::Load( LPCOLESTR pcwszFile,
  1095. DWORD dwMode)
  1096. {
  1097. HRESULT hr;
  1098. PSTR pszFile;
  1099. DebugEntry(CConfLink::Load);
  1100. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1101. // BUGBUG: Need OLESTR validation function to validate pcwszFile here.
  1102. // BUGBUG: Validate dwMode here.
  1103. // BUGBUG: Implement dwMode flag support.
  1104. hr = UnicodeToANSI(pcwszFile, &pszFile);
  1105. if (hr == S_OK)
  1106. {
  1107. hr = LoadFromFile(pszFile, TRUE);
  1108. delete pszFile;
  1109. pszFile = NULL;
  1110. }
  1111. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1112. DebugExitHRESULT(CConfLink::Load, hr);
  1113. return(hr);
  1114. }
  1115. // #pragma warning(default:4100) /* "unreferenced formal parameter" warning */
  1116. HRESULT STDMETHODCALLTYPE CConfLink::GetCurFile(LPOLESTR *ppwszFile)
  1117. {
  1118. HRESULT hr;
  1119. LPOLESTR pwszTempFile;
  1120. DebugEntry(CConfLink::GetCurFile);
  1121. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1122. ASSERT(IS_VALID_WRITE_PTR(ppwszFile, LPOLESTR));
  1123. if (m_pszFile)
  1124. {
  1125. hr = ANSIToUnicode(m_pszFile, &pwszTempFile);
  1126. if (hr == S_OK)
  1127. {
  1128. TRACE_OUT(("CConfLink::GetCurFile(): Current file name is %s.",
  1129. m_pszFile));
  1130. }
  1131. }
  1132. else
  1133. {
  1134. hr = ANSIToUnicode(g_cszConfLinkDefaultFileNamePrompt, &pwszTempFile);
  1135. if (hr == S_OK)
  1136. {
  1137. hr = S_FALSE;
  1138. TRACE_OUT(("CConfLink::GetCurFile(): No current file name. Returning default file name prompt %s.",
  1139. g_cszConfLinkDefaultFileNamePrompt));
  1140. }
  1141. }
  1142. if (SUCCEEDED(hr))
  1143. {
  1144. // We should really call OleGetMalloc() to get the process IMalloc here.
  1145. // Use SHAlloc() here instead to avoid loading ole32.dll.
  1146. // SHAlloc() / SHFree() turn in to IMalloc::Alloc() and IMalloc::Free()
  1147. // once ole32.dll is loaded.
  1148. // N.b., lstrlenW() returns the length of the given string in characters,
  1149. // not bytes.
  1150. // (+ 1) for null terminator.
  1151. LPMALLOC pMalloc = NULL;
  1152. *ppwszFile = NULL;
  1153. if (SUCCEEDED(SHGetMalloc(&pMalloc)))
  1154. {
  1155. *ppwszFile = (LPOLESTR) pMalloc->Alloc((lstrlenW(pwszTempFile) + 1) *
  1156. sizeof(*pwszTempFile));
  1157. pMalloc->Release();
  1158. pMalloc = NULL;
  1159. }
  1160. if (*ppwszFile)
  1161. {
  1162. LStrCpyW(*ppwszFile, pwszTempFile);
  1163. }
  1164. else
  1165. hr = E_OUTOFMEMORY;
  1166. delete pwszTempFile;
  1167. pwszTempFile = NULL;
  1168. }
  1169. // BUGBUG: Need OLESTR validation function to validate *ppwszFile here.
  1170. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1171. DebugExitHRESULT(CConfLink::GetCurFile, hr);
  1172. return(hr);
  1173. }
  1174. // #pragma warning(disable:4100) /* "unreferenced formal parameter" warning */
  1175. HRESULT STDMETHODCALLTYPE CConfLink::Load(PIStream pistr)
  1176. {
  1177. HRESULT hr;
  1178. DebugEntry(CConfLink::Load);
  1179. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1180. ASSERT(IS_VALID_INTERFACE_PTR(pistr, IStream));
  1181. hr = E_NOTIMPL;
  1182. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1183. DebugExitHRESULT(CConfLink::Load, hr);
  1184. return(hr);
  1185. }
  1186. HRESULT STDMETHODCALLTYPE CConfLink::Save( PIStream pistr,
  1187. BOOL bClearDirty)
  1188. {
  1189. HRESULT hr;
  1190. DebugEntry(CConfLink::Save);
  1191. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1192. ASSERT(IS_VALID_INTERFACE_PTR(pistr, IStream));
  1193. hr = E_NOTIMPL;
  1194. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1195. DebugExitHRESULT(CConfLink::Save, hr);
  1196. return(hr);
  1197. }
  1198. HRESULT STDMETHODCALLTYPE CConfLink::GetSizeMax(PULARGE_INTEGER pcbSize)
  1199. {
  1200. HRESULT hr;
  1201. DebugEntry(CConfLink::GetSizeMax);
  1202. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1203. ASSERT(IS_VALID_WRITE_PTR(pcbSize, ULARGE_INTEGER));
  1204. hr = E_NOTIMPL;
  1205. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1206. DebugExitHRESULT(CConfLink::GetSizeMax, hr);
  1207. return(hr);
  1208. }
  1209. // #pragma warning(default:4100) /* "unreferenced formal parameter" warning */
  1210. DWORD STDMETHODCALLTYPE CConfLink::GetFileContentsSize(void)
  1211. {
  1212. DWORD dwcbLen;
  1213. DebugEntry(CConfLink::GetFileContentsSize);
  1214. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1215. // Section length.
  1216. // (- 1) for each null terminator.
  1217. dwcbLen = sizeof(s_cszSectionBefore) - 1 +
  1218. sizeof(s_cszConferenceShortcutSection) - 1 +
  1219. sizeof(s_cszSectionAfter) - 1;
  1220. if (m_pszName)
  1221. {
  1222. // Name length.
  1223. dwcbLen += sizeof(g_cszCRLF) - 1 +
  1224. sizeof(s_cszNameKey) - 1 +
  1225. sizeof(s_cszKeyValueSep) - 1 +
  1226. lstrlen(m_pszName);
  1227. }
  1228. if (m_pszAddress)
  1229. {
  1230. // Address length.
  1231. dwcbLen += sizeof(g_cszCRLF) - 1 +
  1232. sizeof(s_cszAddressKey) - 1 +
  1233. sizeof(s_cszKeyValueSep) - 1 +
  1234. lstrlen(m_pszAddress);
  1235. }
  1236. if (m_pszRemoteConfName)
  1237. {
  1238. // RemoteConfName length.
  1239. dwcbLen += sizeof(g_cszCRLF) - 1 +
  1240. sizeof(s_cszRemoteConfNameKey) - 1 +
  1241. sizeof(s_cszKeyValueSep) - 1 +
  1242. lstrlen(m_pszRemoteConfName);
  1243. }
  1244. // CallFlags length
  1245. dwcbLen += sizeof(g_cszCRLF) - 1 +
  1246. sizeof(s_cszCallFlagsKey) - 1 +
  1247. sizeof(s_cszKeyValueSep) - 1 +
  1248. s_ucMaxCallFlagsLen;
  1249. // Transport length
  1250. dwcbLen += sizeof(g_cszCRLF) - 1 +
  1251. sizeof(s_cszTransportKey) - 1 +
  1252. sizeof(s_cszKeyValueSep) - 1 +
  1253. s_ucMaxTransportLen;
  1254. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1255. DebugExitDWORD(CConfLink::GetFileContentsSize, dwcbLen);
  1256. return(dwcbLen);
  1257. }
  1258. #ifdef DEBUG
  1259. void STDMETHODCALLTYPE CConfLink::Dump(void)
  1260. {
  1261. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1262. TRACE_OUT(("m_dwFlags = %#08lx", m_dwFlags));
  1263. TRACE_OUT(("m_pszFile = \"%s\"", CHECK_STRING(m_pszFile)));
  1264. TRACE_OUT(("m_pszName = \"%s\"", CHECK_STRING(m_pszName)));
  1265. #if 0
  1266. TRACE_OUT(("m_pszIconFile = \"%s\"", CHECK_STRING(m_pszIconFile)));
  1267. TRACE_OUT(("m_niIcon = %d", m_niIcon));
  1268. TRACE_OUT(("m_wHotkey = %#04x", (UINT)m_wHotkey));
  1269. TRACE_OUT(("m_pszWorkingDirectory = \"%s\"", CHECK_STRING(m_pszWorkingDirectory)));
  1270. TRACE_OUT(("m_nShowCmd = %d", m_nShowCmd));
  1271. #endif // 0
  1272. return;
  1273. }
  1274. #endif
  1275. #if 0
  1276. HRESULT STDMETHODCALLTYPE CConfLink::TransferConfLink( PFORMATETC pfmtetc,
  1277. PSTGMEDIUM pstgmed)
  1278. {
  1279. HRESULT hr;
  1280. DebugEntry(CConfLink::TransferConfLink);
  1281. ASSERT(0 && "If we hit this assert, we need to implement this function");
  1282. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1283. ASSERT(IS_VALID_STRUCT_PTR(pfmtetc, CFORMATETC));
  1284. ASSERT(IS_VALID_WRITE_PTR(pstgmed, STGMEDIUM));
  1285. ASSERT(pfmtetc->dwAspect == DVASPECT_CONTENT);
  1286. ASSERT(pfmtetc->lindex == -1);
  1287. ZeroMemory(pstgmed, sizeof(*pstgmed));
  1288. if (IS_FLAG_SET(pfmtetc->tymed, TYMED_HGLOBAL))
  1289. {
  1290. // BUGBUG: ChrisPi 9-15-95
  1291. // This only transfers the conference name
  1292. // (It does not transfer the address)
  1293. if (m_pszName)
  1294. {
  1295. HGLOBAL hgName;
  1296. hr = E_OUTOFMEMORY;
  1297. // (+ 1) for null terminator.
  1298. hgName = GlobalAlloc(0, lstrlen(m_pszName) + 1);
  1299. if (hgName)
  1300. {
  1301. PSTR pszName;
  1302. pszName = (PSTR)GlobalLock(hgName);
  1303. if (EVAL(pszName))
  1304. {
  1305. lstrcpy(pszName, m_pszName);
  1306. pstgmed->tymed = TYMED_HGLOBAL;
  1307. pstgmed->hGlobal = hgName;
  1308. ASSERT(! pstgmed->pUnkForRelease);
  1309. hr = S_OK;
  1310. GlobalUnlock(hgName);
  1311. pszName = NULL;
  1312. }
  1313. if (hr != S_OK)
  1314. {
  1315. GlobalFree(hgName);
  1316. hgName = NULL;
  1317. }
  1318. }
  1319. }
  1320. else
  1321. {
  1322. hr = DV_E_FORMATETC;
  1323. }
  1324. }
  1325. else
  1326. {
  1327. hr = DV_E_TYMED;
  1328. }
  1329. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1330. ASSERT((hr == S_OK &&
  1331. IS_VALID_STRUCT_PTR(pstgmed, CSTGMEDIUM)) ||
  1332. (FAILED(hr) &&
  1333. (EVAL(pstgmed->tymed == TYMED_NULL) &&
  1334. EVAL(! pstgmed->hGlobal) &&
  1335. EVAL(! pstgmed->pUnkForRelease))));
  1336. DebugExitHRESULT(CConfLink::TransferConfLink, hr);
  1337. return(hr);
  1338. }
  1339. #endif // 0
  1340. #if 0
  1341. HRESULT STDMETHODCALLTYPE CConfLink::TransferText( PFORMATETC pfmtetc,
  1342. PSTGMEDIUM pstgmed)
  1343. {
  1344. HRESULT hr;
  1345. DebugEntry(CConfLink::TransferText);
  1346. // Assume CConfLink::TransferConfLink() will perform
  1347. // input and output validation.
  1348. hr = TransferConfLink(pfmtetc, pstgmed);
  1349. DebugExitHRESULT(CConfLink::TransferText, hr);
  1350. return(hr);
  1351. }
  1352. #endif // 0
  1353. #if 0
  1354. HRESULT STDMETHODCALLTYPE CConfLink::TransferFileGroupDescriptor( PFORMATETC pfmtetc,
  1355. PSTGMEDIUM pstgmed)
  1356. {
  1357. HRESULT hr;
  1358. DebugEntry(CConfLink::TransferFileGroupDescriptor);
  1359. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1360. ASSERT(IS_VALID_STRUCT_PTR(pfmtetc, CFORMATETC));
  1361. ASSERT(IS_VALID_WRITE_PTR(pstgmed, STGMEDIUM));
  1362. ASSERT(pfmtetc->dwAspect == DVASPECT_CONTENT);
  1363. ASSERT(pfmtetc->lindex == -1);
  1364. pstgmed->tymed = TYMED_NULL;
  1365. pstgmed->hGlobal = NULL;
  1366. pstgmed->pUnkForRelease = NULL;
  1367. if (IS_FLAG_SET(pfmtetc->tymed, TYMED_HGLOBAL))
  1368. {
  1369. HGLOBAL hgFileGroupDesc;
  1370. hr = E_OUTOFMEMORY;
  1371. hgFileGroupDesc = GlobalAlloc(GMEM_ZEROINIT,
  1372. sizeof(FILEGROUPDESCRIPTOR));
  1373. if (hgFileGroupDesc)
  1374. {
  1375. PFILEGROUPDESCRIPTOR pfgd;
  1376. pfgd = (PFILEGROUPDESCRIPTOR)GlobalLock(hgFileGroupDesc);
  1377. if (EVAL(pfgd))
  1378. {
  1379. PFILEDESCRIPTOR pfd = &(pfgd->fgd[0]);
  1380. // Do we already have a file name to use?
  1381. if (m_pszName)
  1382. {
  1383. TCHAR szFileName[MAX_PATH];
  1384. // copy shortcut
  1385. // BUGBUG: needs to be a resource INTL
  1386. lstrcpy(szFileName, _TEXT("Shortcut to "));
  1387. // copy Conference Name
  1388. lstrcat(szFileName, m_pszName);
  1389. // copy extension
  1390. lstrcat(szFileName, g_cszConfLinkExt);
  1391. MyLStrCpyN(pfd->cFileName, szFileName,
  1392. sizeof(pfd->cFileName));
  1393. hr = S_OK;
  1394. }
  1395. else
  1396. {
  1397. // BUGBUG: need resource here! INTL
  1398. //if (EVAL(LoadString(GetThisModulesHandle(),
  1399. // IDS_NEW_INTERNET_SHORTCUT, pfd->cFileName,
  1400. // sizeof(pfd->cFileName))))
  1401. MyLStrCpyN(pfd->cFileName, "New Conference Shortcut.cnf",
  1402. sizeof(pfd->cFileName));
  1403. hr = S_OK;
  1404. }
  1405. if (hr == S_OK)
  1406. {
  1407. pfd->dwFlags = (FD_FILESIZE |
  1408. FD_LINKUI);
  1409. pfd->nFileSizeHigh = 0;
  1410. pfd->nFileSizeLow = GetFileContentsSize();
  1411. pfgd->cItems = 1;
  1412. pstgmed->tymed = TYMED_HGLOBAL;
  1413. pstgmed->hGlobal = hgFileGroupDesc;
  1414. ASSERT(! pstgmed->pUnkForRelease);
  1415. }
  1416. GlobalUnlock(hgFileGroupDesc);
  1417. pfgd = NULL;
  1418. }
  1419. if (hr != S_OK)
  1420. {
  1421. GlobalFree(hgFileGroupDesc);
  1422. hgFileGroupDesc = NULL;
  1423. }
  1424. }
  1425. }
  1426. else
  1427. {
  1428. hr = DV_E_TYMED;
  1429. }
  1430. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1431. ASSERT((hr == S_OK &&
  1432. IS_VALID_STRUCT_PTR(pstgmed, CSTGMEDIUM)) ||
  1433. (FAILED(hr) &&
  1434. (EVAL(pstgmed->tymed == TYMED_NULL) &&
  1435. EVAL(! pstgmed->hGlobal) &&
  1436. EVAL(! pstgmed->pUnkForRelease))));
  1437. DebugExitHRESULT(CConfLink::TransferFileGroupDescriptor, hr);
  1438. return(hr);
  1439. }
  1440. #endif // 0
  1441. HRESULT STDMETHODCALLTYPE CConfLink::TransferFileContents( PFORMATETC pfmtetc,
  1442. PSTGMEDIUM pstgmed)
  1443. {
  1444. HRESULT hr;
  1445. DebugEntry(CConfLink::TransferFileContents);
  1446. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1447. ASSERT(IS_VALID_STRUCT_PTR(pfmtetc, CFORMATETC));
  1448. ASSERT(IS_VALID_WRITE_PTR(pstgmed, STGMEDIUM));
  1449. ASSERT(pfmtetc->dwAspect == DVASPECT_CONTENT);
  1450. ASSERT(! pfmtetc->lindex);
  1451. pstgmed->tymed = TYMED_NULL;
  1452. pstgmed->hGlobal = NULL;
  1453. pstgmed->pUnkForRelease = NULL;
  1454. if (IS_FLAG_SET(pfmtetc->tymed, TYMED_HGLOBAL))
  1455. {
  1456. DWORD dwcbLen;
  1457. HGLOBAL hgFileContents;
  1458. hr = E_OUTOFMEMORY;
  1459. dwcbLen = GetFileContentsSize();
  1460. hgFileContents = GlobalAlloc(0, dwcbLen);
  1461. if (hgFileContents)
  1462. {
  1463. PSTR pszFileContents;
  1464. pszFileContents = (PSTR)GlobalLock(hgFileContents);
  1465. if (EVAL(pszFileContents))
  1466. {
  1467. PSTR psz = pszFileContents;
  1468. // Copy section.
  1469. CopyMemory(psz, s_cszSectionBefore, sizeof(s_cszSectionBefore) - 1);
  1470. psz += sizeof(s_cszSectionBefore) - 1;
  1471. CopyMemory(psz, s_cszConferenceShortcutSection, sizeof(s_cszConferenceShortcutSection) - 1);
  1472. psz += sizeof(s_cszConferenceShortcutSection) - 1;
  1473. CopyMemory(psz, s_cszSectionAfter, sizeof(s_cszSectionAfter) - 1);
  1474. psz += sizeof(s_cszSectionAfter) - 1;
  1475. if (m_pszName)
  1476. {
  1477. // Copy Name.
  1478. CopyMemory(psz, g_cszCRLF, sizeof(g_cszCRLF) - 1);
  1479. psz += sizeof(g_cszCRLF) - 1;
  1480. CopyMemory(psz, s_cszNameKey, sizeof(s_cszNameKey) - 1);
  1481. psz += sizeof(s_cszNameKey) - 1;
  1482. CopyMemory(psz, s_cszKeyValueSep, sizeof(s_cszKeyValueSep) - 1);
  1483. psz += sizeof(s_cszKeyValueSep) - 1;
  1484. CopyMemory(psz, m_pszName, lstrlen(m_pszName));
  1485. psz += lstrlen(m_pszName);
  1486. }
  1487. if (m_pszAddress)
  1488. {
  1489. // Copy Name.
  1490. CopyMemory(psz, g_cszCRLF, sizeof(g_cszCRLF) - 1);
  1491. psz += sizeof(g_cszCRLF) - 1;
  1492. CopyMemory(psz, s_cszAddressKey, sizeof(s_cszAddressKey) - 1);
  1493. psz += sizeof(s_cszAddressKey) - 1;
  1494. CopyMemory(psz, s_cszKeyValueSep, sizeof(s_cszKeyValueSep) - 1);
  1495. psz += sizeof(s_cszKeyValueSep) - 1;
  1496. CopyMemory(psz, m_pszAddress, lstrlen(m_pszAddress));
  1497. psz += lstrlen(m_pszAddress);
  1498. }
  1499. // Copy Transport.
  1500. CopyMemory(psz, g_cszCRLF, sizeof(g_cszCRLF) - 1);
  1501. psz += sizeof(g_cszCRLF) - 1;
  1502. CopyMemory(psz, s_cszTransportKey, sizeof(s_cszTransportKey) - 1);
  1503. psz += sizeof(s_cszTransportKey) - 1;
  1504. CopyMemory(psz, s_cszKeyValueSep, sizeof(s_cszKeyValueSep) - 1);
  1505. psz += sizeof(s_cszKeyValueSep) - 1;
  1506. TCHAR szBuf[s_ucMaxTransportLen];
  1507. wsprintf(szBuf, "%10u", m_dwTransport);
  1508. CopyMemory(psz, szBuf, lstrlen(szBuf));
  1509. psz += lstrlen(szBuf);
  1510. ASSERT(psz == pszFileContents + dwcbLen);
  1511. pstgmed->tymed = TYMED_HGLOBAL;
  1512. pstgmed->hGlobal = hgFileContents;
  1513. ASSERT(! pstgmed->pUnkForRelease);
  1514. hr = S_OK;
  1515. GlobalUnlock(hgFileContents);
  1516. }
  1517. if (hr != S_OK)
  1518. {
  1519. GlobalFree(hgFileContents);
  1520. hgFileContents = NULL;
  1521. }
  1522. }
  1523. }
  1524. else
  1525. {
  1526. hr = DV_E_TYMED;
  1527. }
  1528. ASSERT(IS_VALID_STRUCT_PTR(this, CConfLink));
  1529. ASSERT((hr == S_OK &&
  1530. IS_VALID_STRUCT_PTR(pstgmed, CSTGMEDIUM)) ||
  1531. (FAILED(hr) &&
  1532. (EVAL(pstgmed->tymed == TYMED_NULL) &&
  1533. EVAL(! pstgmed->hGlobal) &&
  1534. EVAL(! pstgmed->pUnkForRelease))));
  1535. DebugExitHRESULT(CConfLink::TransferFileContents, hr);
  1536. return(hr);
  1537. }