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.

925 lines
25 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. // This avoids duplicate definitions with Shell PIDL functions
  4. // and MUST BE DEFINED!
  5. #define AVOID_NET_CONFIG_DUPLICATES
  6. #include "nsbase.h"
  7. #include "nsres.h"
  8. #include "netshell.h"
  9. #include "ncnetcon.h"
  10. #include "ncui.h"
  11. // Connection Folder Objects
  12. //
  13. // Undocument shell32 stuff. Sigh.
  14. #define DONT_WANT_SHELLDEBUG 1
  15. #define NO_SHIDLIST 1
  16. #define USE_SHLWAPI_IDLIST
  17. #include <commctrl.h>
  18. #include <netcfgp.h>
  19. #include <netconp.h>
  20. #include <ncui.h>
  21. // Connection UI Objects
  22. //
  23. #include "..\lanui\lanuiobj.h"
  24. #include "..\lanui\lanui.h"
  25. #include "dialupui.h"
  26. #include "intnetui.h"
  27. #include "directui.h"
  28. #include "inbui.h"
  29. #include "vpnui.h"
  30. #include "pppoeui.h"
  31. #include "..\lanui\saui.h"
  32. #include "..\lanui\sauiobj.h"
  33. #include "foldinc.h"
  34. #include "openfold.h"
  35. #include "..\folder\confold.h"
  36. #include "..\folder\foldglob.h"
  37. #include "..\folder\oncommand.h"
  38. #include "..\folder\shutil.h"
  39. #include "..\dun\dunimport.h"
  40. // Connection Tray Objects
  41. //
  42. #include "..\folder\contray.h"
  43. // Common Connection Ui Objects
  44. #include "..\commconn\commconn.h"
  45. #include "netshell_i.c"
  46. // Icon support
  47. #include "..\folder\iconhandler.h"
  48. #include "..\folder\cmdtable.h"
  49. #include "repair.h"
  50. #define INITGUID
  51. #include "nsclsid.h"
  52. //+---------------------------------------------------------------------------
  53. // Note: Proxy/Stub Information
  54. // To merge the proxy/stub code into the object DLL, add the file
  55. // dlldatax.c to the project. Make sure precompiled headers
  56. // are turned off for this file, and add _MERGE_PROXYSTUB to the
  57. // defines for the project.
  58. //
  59. // If you are not running WinNT4.0 or Win95 with DCOM, then you
  60. // need to remove the following define from dlldatax.c
  61. // #define _WIN32_WINNT 0x0400
  62. //
  63. // Further, if you are running MIDL without /Oicf switch, you also
  64. // need to remove the following define from dlldatax.c.
  65. // #define USE_STUBLESS_PROXY
  66. //
  67. // Modify the custom build rule for foo.idl by adding the following
  68. // files to the Outputs.
  69. // foo_p.c
  70. // dlldata.c
  71. // To build a separate proxy/stub DLL,
  72. // run nmake -f foops.mk in the project directory.
  73. // Proxy/Stub registration entry points
  74. //
  75. #include "dlldatax.h"
  76. #ifdef _MERGE_PROXYSTUB
  77. extern "C" HINSTANCE hProxyDll;
  78. #endif
  79. CComModule _Module;
  80. CNetConfigIcons *g_pNetConfigIcons = NULL;
  81. CRITICAL_SECTION g_csPidl;
  82. BEGIN_OBJECT_MAP(ObjectMap)
  83. // Connection UI Objects
  84. //
  85. OBJECT_ENTRY(CLSID_DialupConnectionUi, CDialupConnectionUi)
  86. OBJECT_ENTRY(CLSID_DirectConnectionUi, CDirectConnectionUi)
  87. OBJECT_ENTRY(CLSID_InboundConnectionUi, CInboundConnectionUi)
  88. OBJECT_ENTRY(CLSID_LanConnectionUi, CLanConnectionUi)
  89. OBJECT_ENTRY(CLSID_VpnConnectionUi, CVpnConnectionUi)
  90. OBJECT_ENTRY(CLSID_PPPoEUi, CPPPoEUi)
  91. OBJECT_ENTRY(CLSID_SharedAccessConnectionUi, CSharedAccessConnectionUi)
  92. OBJECT_ENTRY(CLSID_InternetConnectionUi, CInternetConnectionUi)
  93. // Connection Folder and enumerator
  94. //
  95. OBJECT_ENTRY(CLSID_ConnectionFolder, CConnectionFolder)
  96. OBJECT_ENTRY(CLSID_ConnectionFolderWin98, CConnectionFolder)
  97. OBJECT_ENTRY(CLSID_ConnectionFolderEnum, CConnectionFolderEnum)
  98. OBJECT_ENTRY(CLSID_ConnectionTray, CConnectionTray)
  99. // Connection Common Ui
  100. OBJECT_ENTRY(CLSID_ConnectionCommonUi, CConnectionCommonUi)
  101. OBJECT_ENTRY(CLSID_NetConnectionUiUtilities, CNetConnectionUiUtilities)
  102. END_OBJECT_MAP()
  103. //+---------------------------------------------------------------------------
  104. // DLL Entry Point
  105. //
  106. EXTERN_C
  107. BOOL
  108. WINAPI
  109. DllMain (
  110. HINSTANCE hInstance,
  111. DWORD dwReason,
  112. LPVOID lpReserved)
  113. {
  114. #ifdef _MERGE_PROXYSTUB
  115. if (!PrxDllMain(hInstance, dwReason, lpReserved))
  116. {
  117. return FALSE;
  118. }
  119. #endif
  120. if (dwReason == DLL_PROCESS_ATTACH)
  121. {
  122. BOOL fRetVal = FALSE;
  123. DisableThreadLibraryCalls(hInstance);
  124. InitializeDebugging();
  125. if (FIsDebugFlagSet (dfidNetShellBreakOnInit))
  126. {
  127. DebugBreak();
  128. }
  129. // Initialize fusion
  130. fRetVal = SHFusionInitializeFromModuleID(hInstance, 50);
  131. Assert(fRetVal);
  132. _Module.Init(ObjectMap, hInstance);
  133. InitializeCriticalSection(&g_csPidl);
  134. // Initialize the list and tie it to the tray (param == TRUE)
  135. //
  136. g_ccl.Initialize(TRUE, TRUE);
  137. g_pNetConfigIcons = new CNetConfigIcons(_Module.GetResourceInstance());
  138. }
  139. else if (dwReason == DLL_PROCESS_DETACH)
  140. {
  141. DbgCheckPrematureDllUnload ("netshell.dll", _Module.GetLockCount());
  142. delete g_pNetConfigIcons;
  143. EnterCriticalSection(&g_csPidl);
  144. LeaveCriticalSection(&g_csPidl);
  145. DeleteCriticalSection(&g_csPidl);
  146. g_ccl.Uninitialize(TRUE);
  147. _Module.Term();
  148. SHFusionUninitialize();
  149. UnInitializeDebugging();
  150. }
  151. return TRUE;
  152. }
  153. //+---------------------------------------------------------------------------
  154. // Used to determine whether the DLL can be unloaded by OLE
  155. //
  156. STDAPI
  157. DllCanUnloadNow ()
  158. {
  159. #ifdef _MERGE_PROXYSTUB
  160. if (PrxDllCanUnloadNow() != S_OK)
  161. {
  162. return S_FALSE;
  163. }
  164. #endif
  165. return (_Module.GetLockCount() == 0) ? S_OK : S_FALSE;
  166. }
  167. //+---------------------------------------------------------------------------
  168. // Returns a class factory to create an object of the requested type
  169. //
  170. STDAPI
  171. DllGetClassObject (
  172. REFCLSID rclsid,
  173. REFIID riid,
  174. LPVOID* ppv)
  175. {
  176. #ifdef _MERGE_PROXYSTUB
  177. if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
  178. {
  179. return S_OK;
  180. }
  181. #endif
  182. // The check is to works around an ATL problem where AtlModuleGetClassObject will AV
  183. // if _Module.m_pObjMap == NULL
  184. if (_Module.m_pObjMap)
  185. {
  186. return _Module.GetClassObject(rclsid, riid, ppv);
  187. }
  188. else
  189. {
  190. return E_FAIL;
  191. }
  192. }
  193. //+---------------------------------------------------------------------------
  194. // DllRegisterServer - Adds entries to the system registry
  195. //
  196. STDAPI
  197. DllRegisterServer ()
  198. {
  199. BOOL fCoUninitialize = TRUE;
  200. HRESULT hr = CoInitializeEx (NULL,
  201. COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
  202. if (FAILED(hr))
  203. {
  204. fCoUninitialize = FALSE;
  205. if (RPC_E_CHANGED_MODE == hr)
  206. {
  207. hr = S_OK;
  208. }
  209. }
  210. if (SUCCEEDED(hr))
  211. {
  212. #ifdef _MERGE_PROXYSTUB
  213. hr = PrxDllRegisterServer ();
  214. if (FAILED(hr))
  215. {
  216. goto Exit;
  217. }
  218. #endif
  219. HKEY hkey;
  220. if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_LOCAL_MACHINE, REGSTR_PATH_SHELLSERVICEOBJECTDELAYED, 0, KEY_WRITE, &hkey))
  221. {
  222. RegDeleteValue(hkey, TEXT("Network.ConnectionTray"));
  223. RegCloseKey(hkey);
  224. }
  225. hr = NcAtlModuleRegisterServer (&_Module);
  226. if (SUCCEEDED(hr))
  227. {
  228. hr = HrRegisterFolderClass();
  229. if (SUCCEEDED(hr))
  230. {
  231. hr = HrRegisterDUNFileAssociation();
  232. }
  233. }
  234. Exit:
  235. if (fCoUninitialize)
  236. {
  237. CoUninitialize ();
  238. }
  239. }
  240. TraceHr (ttidError, FAL, hr, FALSE, "netshell!DllRegisterServer");
  241. return hr;
  242. }
  243. //+---------------------------------------------------------------------------
  244. // DllUnregisterServer - Removes entries from the system registry
  245. //
  246. STDAPI
  247. DllUnregisterServer ()
  248. {
  249. #ifdef _MERGE_PROXYSTUB
  250. PrxDllUnregisterServer ();
  251. #endif
  252. _Module.UnregisterServer ();
  253. return S_OK;
  254. }
  255. //+---------------------------------------------------------------------------
  256. //
  257. // Function: NcFreeNetconProperties
  258. //
  259. // Purpose: Free the memory assicated with the return value from
  260. // INetConnection->GetProperties. This is a helper function
  261. // used by clients of INetConnection.
  262. //
  263. // Arguments:
  264. // pProps [in] The properties to free.
  265. //
  266. // Returns: nothing.
  267. //
  268. // Author: shaunco 1 Feb 1998
  269. //
  270. // Notes:
  271. //
  272. STDAPI_(VOID)
  273. NcFreeNetconProperties (
  274. NETCON_PROPERTIES* pProps)
  275. {
  276. // Defer to the common function in nccon.h.
  277. // We do this so that netman.exe doesn't have to link to netshell.dll
  278. // just for this function.
  279. //
  280. FreeNetconProperties (pProps);
  281. }
  282. STDAPI_(BOOL)
  283. NcIsValidConnectionName (
  284. PCWSTR pszwName)
  285. {
  286. return FIsValidConnectionName (pszwName);
  287. }
  288. //+---------------------------------------------------------------------------
  289. //
  290. // Function: HrLaunchNetworkOptionalComponents
  291. //
  292. // Purpose: External Entry point for launching the Network Optional Components
  293. //
  294. // Arguments:
  295. //
  296. // Returns:
  297. //
  298. // Author: scottbri 29 Oct 1998
  299. //
  300. // Notes: The CreateFile in this function will fail if the user does
  301. // this very quickly twice in a row. In that case, the second
  302. // instance will fall out unharmed before the first one even
  303. // comes up, which is no big deal. The only negative impact
  304. // would be if the second client in rewrote the file while the
  305. // oc manager was attempting to read it, but oc manager would
  306. // have to allow FILE_SHARE_WRITE, which is doubtful.
  307. //
  308. // I've opened this window due to RAID 336302, which requires
  309. // that only a single instance of NETOC is running.
  310. //
  311. //
  312. const WCHAR c_szTmpMasterOC[] = L"[Version]\r\nSignature = \"$Windows NT$\"\r\n[Components]\r\nNetOC=netoc.dll,NetOcSetupProc,netoc.inf\r\niis=iis.dll,OcEntry,iis.inf,hide,7\r\n[Global]\r\nWindowTitle=\"";
  313. const WCHAR c_szQuote[] = L"\"";
  314. const WCHAR c_szTmpFileName[] = L"NDCNETOC.INF";
  315. const WCHAR c_szSysOCMgr[] = L"%SystemRoot%\\System32\\sysocmgr.exe";
  316. EXTERN_C
  317. HRESULT
  318. APIENTRY
  319. HrLaunchNetworkOptionalComponents()
  320. {
  321. DWORD BytesWritten = 0;
  322. HANDLE hFile = NULL;
  323. HRESULT hr = S_OK;
  324. PCWSTR pszName = NULL;
  325. WCHAR szName[MAX_PATH + 1];
  326. // Jump to the existing netoc dialog, if present
  327. //
  328. HWND hwnd = FindWindow(NULL, SzLoadIds(IDS_CONFOLD_OC_TITLE));
  329. if (IsWindow(hwnd))
  330. {
  331. SetForegroundWindow(hwnd);
  332. }
  333. else
  334. {
  335. // Generate a temporary filename
  336. //
  337. if (0 == GetTempPath(celems(szName), szName))
  338. {
  339. hr = ::HrFromLastWin32Error();
  340. TraceTag(ttidShellFolder, "Unable to get temporary path for Optional Component Launch\n");
  341. goto Error;
  342. }
  343. lstrcatW(szName, c_szTmpFileName);
  344. // Create the file
  345. //
  346. hFile = CreateFile(szName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ,
  347. NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
  348. if (INVALID_HANDLE_VALUE == hFile)
  349. {
  350. hr = ::HrFromLastWin32Error();
  351. goto Error;
  352. }
  353. // Generate the file contents
  354. //
  355. if (WriteFile(hFile, c_szTmpMasterOC, lstrlenW(c_szTmpMasterOC) * sizeof(WCHAR),
  356. &BytesWritten, NULL))
  357. {
  358. // Write the OC Dialog Title
  359. //
  360. WCHAR szBufW[256];
  361. if (LoadStringW(_Module.GetResourceInstance(), IDS_CONFOLD_OC_TITLE,
  362. szBufW, celems(szBufW)-1))
  363. {
  364. szBufW[255] = 0;
  365. if (WriteFile(hFile, szBufW, lstrlenW(szBufW) * sizeof(WCHAR), &BytesWritten, NULL) == FALSE)
  366. {
  367. CloseHandle(hFile);
  368. return(::HrFromLastWin32Error());
  369. }
  370. }
  371. if (WriteFile(hFile, c_szQuote, lstrlenW(c_szQuote) * sizeof(WCHAR), &BytesWritten, NULL) == FALSE)
  372. {
  373. CloseHandle(hFile);
  374. return(::HrFromLastWin32Error());
  375. }
  376. CloseHandle(hFile);
  377. SHELLEXECUTEINFO seiTemp = { 0 };
  378. tstring strParams = L"/x /i:";
  379. strParams += szName;
  380. // Fill in the data structure
  381. //
  382. seiTemp.cbSize = sizeof(SHELLEXECUTEINFO);
  383. seiTemp.fMask = SEE_MASK_DOENVSUBST;
  384. seiTemp.hwnd = NULL;
  385. seiTemp.lpVerb = NULL;
  386. seiTemp.lpFile = c_szSysOCMgr;
  387. seiTemp.lpParameters = strParams.c_str();
  388. seiTemp.lpDirectory = NULL;
  389. seiTemp.nShow = SW_SHOW;
  390. seiTemp.hInstApp = NULL;
  391. seiTemp.hProcess = NULL;
  392. // Execute the OC Manager Script
  393. //
  394. if (!::ShellExecuteEx(&seiTemp))
  395. {
  396. hr = ::HrFromLastWin32Error();
  397. }
  398. }
  399. else
  400. {
  401. CloseHandle(hFile);
  402. hr = HrFromLastWin32Error();
  403. }
  404. }
  405. Error:
  406. TraceError("HrOnCommandOptionalComponents", hr);
  407. return hr;
  408. }
  409. //+---------------------------------------------------------------------------
  410. //
  411. // Function: HrCreateDeskTopIcon
  412. //
  413. // Purpose: External Entry point for creating a desktop shortcut to
  414. // an existing connection
  415. //
  416. // Arguments: guidId: GUID of the connection
  417. //
  418. // Returns: S_OK if succeeded
  419. // S_FALSE if the GUID does not match any existing connection
  420. // standard error code otherwise
  421. //
  422. // Author: tongl 19 Feb 1999
  423. //
  424. // Notes:
  425. //
  426. EXTERN_C
  427. HRESULT APIENTRY HrCreateDesktopIcon(const GUID& guidId, PCWSTR pszDir)
  428. {
  429. HRESULT hr = S_OK;
  430. PCONFOLDPIDL pidlCon;
  431. PCONFOLDPIDLFOLDER pidlFolder;
  432. BOOL fValidConnection= FALSE;
  433. #ifdef DBG
  434. WCHAR szwGuid[c_cchGuidWithTerm];
  435. StringFromGUID2(guidId, szwGuid, c_cchGuidWithTerm);
  436. TraceTag(ttidShellFolder, "HrCreateDeskTopIcon called with GUID: %S", szwGuid);
  437. TraceTag(ttidShellFolder, "Dir path is: %S", pszDir);
  438. #endif
  439. // Initialize COM on this thread
  440. //
  441. BOOL fUninitCom = FALSE;
  442. hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
  443. if (RPC_E_CHANGED_MODE == hr)
  444. {
  445. hr = S_OK;
  446. }
  447. if (SUCCEEDED(hr))
  448. {
  449. fUninitCom = TRUE;
  450. hr = HrGetConnectionPidlWithRefresh(guidId, pidlCon);
  451. if (S_OK == hr)
  452. {
  453. AssertSz(!pidlCon.empty(), "We should have a valid PIDL for the connection !");
  454. // Get the pidl for the Connections Folder
  455. //
  456. hr = HrGetConnectionsFolderPidl(pidlFolder);
  457. if (SUCCEEDED(hr))
  458. {
  459. // Get the Connections Folder object
  460. //
  461. LPSHELLFOLDER psfConnections;
  462. hr = HrGetConnectionsIShellFolder(pidlFolder, &psfConnections);
  463. if (SUCCEEDED(hr))
  464. {
  465. PCONFOLDPIDLVEC pidlVec;
  466. pidlVec.push_back(pidlCon);
  467. hr = HrCreateShortcutWithPath(pidlVec,
  468. NULL,
  469. psfConnections,
  470. pszDir);
  471. ReleaseObj(psfConnections);
  472. }
  473. }
  474. }
  475. }
  476. if (fUninitCom)
  477. {
  478. CoUninitialize();
  479. }
  480. TraceError("HrCreateDeskTopIcon", hr);
  481. return hr;
  482. }
  483. //+---------------------------------------------------------------------------
  484. //
  485. // Function: HrLaunchConnection
  486. //
  487. // Purpose: External Entry point for "connecting" an existing connection
  488. //
  489. // Arguments: guidId: GUID of the connection
  490. //
  491. // Returns: S_OK if succeeded
  492. // S_FALSE if the GUID does not match any existing connection
  493. // standard error code otherwise
  494. //
  495. // Author: tongl 19 Feb 1999
  496. //
  497. // Notes:
  498. //
  499. EXTERN_C
  500. HRESULT APIENTRY HrLaunchConnection(const GUID& guidId)
  501. {
  502. HRESULT hr = S_OK;
  503. PCONFOLDPIDL pidlCon;
  504. PCONFOLDPIDLFOLDER pidlFolder;
  505. #ifdef DBG
  506. WCHAR szwGuid[c_cchGuidWithTerm];
  507. StringFromGUID2(guidId, szwGuid, c_cchGuidWithTerm);
  508. TraceTag(ttidShellFolder, "HrLaunchConnection called with GUID: %S", szwGuid);
  509. #endif
  510. // Initialize COM on this thread
  511. //
  512. BOOL fUninitCom = FALSE;
  513. hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
  514. if (RPC_E_CHANGED_MODE == hr)
  515. {
  516. hr = S_OK;
  517. }
  518. if (SUCCEEDED(hr))
  519. {
  520. fUninitCom = TRUE;
  521. hr = HrGetConnectionPidlWithRefresh(guidId, pidlCon);
  522. if (S_OK == hr)
  523. {
  524. AssertSz(!pidlCon.empty(), "We should have a valid PIDL for the connection !");
  525. // Get the pidl for the Connections Folder
  526. //
  527. hr = HrGetConnectionsFolderPidl(pidlFolder);
  528. if (SUCCEEDED(hr))
  529. {
  530. // Get the Connections Folder object
  531. //
  532. LPSHELLFOLDER psfConnections;
  533. hr = HrGetConnectionsIShellFolder(pidlFolder, &psfConnections);
  534. if (SUCCEEDED(hr))
  535. {
  536. PCONFOLDPIDLVEC pidlVec;
  537. pidlVec.push_back(pidlCon);
  538. hr = HrOnCommandConnect(pidlVec, NULL, psfConnections);
  539. ReleaseObj(psfConnections);
  540. }
  541. }
  542. }
  543. }
  544. if (fUninitCom)
  545. {
  546. CoUninitialize();
  547. }
  548. TraceError("HrLaunchConnection", hr);
  549. return hr;
  550. }
  551. //+---------------------------------------------------------------------------
  552. //
  553. // Function: HrLaunchConnectionEx
  554. //
  555. // Purpose: External Entry point for "connecting" an existing connection
  556. //
  557. // Arguments: dwFlags: Flags.
  558. // 0x00000001 - Opens the folder before launching the connection
  559. //
  560. // guidId: GUID of the connection
  561. //
  562. // Returns: S_OK if succeeded
  563. // S_FALSE if the GUID does not match any existing connection
  564. // standard error code otherwise
  565. //
  566. // Author: deonb 8 May 2001
  567. //
  568. // Notes:
  569. //
  570. EXTERN_C
  571. HRESULT APIENTRY HrLaunchConnectionEx(DWORD dwFlags, const GUID& guidId)
  572. {
  573. HRESULT hr = S_OK;
  574. PCONFOLDPIDL pidlCon;
  575. PCONFOLDPIDLFOLDER pidlFolder;
  576. HWND hwndConnFolder = NULL;
  577. #ifdef DBG
  578. WCHAR szwGuid[c_cchGuidWithTerm];
  579. StringFromGUID2(guidId, szwGuid, c_cchGuidWithTerm);
  580. TraceTag(ttidShellFolder, "HrLaunchConnection called with GUID: %S", szwGuid);
  581. #endif
  582. if (dwFlags & 0x00000001)
  583. {
  584. hwndConnFolder = FindWindow(NULL, SzLoadIds(IDS_CONFOLD_NAME));
  585. if (!hwndConnFolder)
  586. {
  587. HrOpenConnectionsFolder();
  588. DWORD dwRetries = 120; // 1 Minute
  589. while (!hwndConnFolder && dwRetries--)
  590. {
  591. hwndConnFolder = FindWindow(NULL, SzLoadIds(IDS_CONFOLD_NAME));
  592. Sleep(500);
  593. }
  594. }
  595. if (hwndConnFolder)
  596. {
  597. SetForegroundWindow(hwndConnFolder);
  598. }
  599. else
  600. {
  601. TraceError("Could not open the Network Connections Folder in time", E_FAIL);
  602. }
  603. }
  604. // Initialize COM on this thread
  605. //
  606. BOOL fUninitCom = FALSE;
  607. hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
  608. if (RPC_E_CHANGED_MODE == hr)
  609. {
  610. hr = S_OK;
  611. }
  612. if (SUCCEEDED(hr))
  613. {
  614. fUninitCom = TRUE;
  615. hr = HrGetConnectionPidlWithRefresh(guidId, pidlCon);
  616. if (S_OK == hr)
  617. {
  618. AssertSz(!pidlCon.empty(), "We should have a valid PIDL for the connection !");
  619. // Get the pidl for the Connections Folder
  620. //
  621. hr = HrGetConnectionsFolderPidl(pidlFolder);
  622. if (SUCCEEDED(hr))
  623. {
  624. // Get the Connections Folder object
  625. //
  626. LPSHELLFOLDER psfConnections;
  627. hr = HrGetConnectionsIShellFolder(pidlFolder, &psfConnections);
  628. if (SUCCEEDED(hr))
  629. {
  630. PCONFOLDPIDLVEC pidlVec;
  631. pidlVec.push_back(pidlCon);
  632. hr = HrOnCommandConnect(pidlVec, hwndConnFolder, psfConnections);
  633. ReleaseObj(psfConnections);
  634. }
  635. }
  636. }
  637. }
  638. if (fUninitCom)
  639. {
  640. CoUninitialize();
  641. }
  642. TraceError("HrLaunchConnection", hr);
  643. return hr;
  644. }
  645. //+---------------------------------------------------------------------------
  646. //
  647. // Function: HrRenameConnection
  648. //
  649. // Purpose: External Entry point for renaming an existing connection
  650. //
  651. // Arguments: guidId: GUID of the connection
  652. //
  653. //
  654. // Returns: S_OK if succeeded
  655. // S_FALSE if the GUID does not match any existing connection
  656. // standard error code otherwise
  657. //
  658. // Author: tongl 26 May 1999
  659. //
  660. // Notes:
  661. //
  662. EXTERN_C
  663. HRESULT APIENTRY HrRenameConnection(const GUID& guidId, PCWSTR pszNewName)
  664. {
  665. HRESULT hr = S_OK;
  666. PCONFOLDPIDL pidlCon;
  667. PCONFOLDPIDLFOLDER pidlFolder;
  668. #ifdef DBG
  669. WCHAR szwGuid[c_cchGuidWithTerm];
  670. StringFromGUID2(guidId, szwGuid, c_cchGuidWithTerm);
  671. TraceTag(ttidShellFolder, "HrRenameConnection called with GUID: %S, NewName: %S",
  672. szwGuid, pszNewName);
  673. #endif
  674. if (!pszNewName)
  675. {
  676. hr = E_INVALIDARG;
  677. }
  678. else
  679. {
  680. // check lpszName for validity
  681. if (!FIsValidConnectionName(pszNewName))
  682. {
  683. hr = HRESULT_FROM_WIN32(ERROR_INVALID_NAME);
  684. }
  685. }
  686. if (SUCCEEDED(hr))
  687. {
  688. // Initialize COM on this thread
  689. //
  690. BOOL fUninitCom = FALSE;
  691. hr = CoInitializeEx(NULL, COINIT_DISABLE_OLE1DDE | COINIT_APARTMENTTHREADED);
  692. if (RPC_E_CHANGED_MODE == hr)
  693. {
  694. hr = S_OK;
  695. }
  696. if (SUCCEEDED(hr))
  697. {
  698. fUninitCom = TRUE;
  699. hr = HrGetConnectionPidlWithRefresh(guidId, pidlCon);
  700. if (S_OK == hr)
  701. {
  702. AssertSz(!pidlCon.empty(), "We should have a valid PIDL for the connection !");
  703. // Get the pidl for the Connections Folder
  704. //
  705. hr = HrGetConnectionsFolderPidl(pidlFolder);
  706. if (SUCCEEDED(hr))
  707. {
  708. PCONFOLDPIDL pcfpEmpty;
  709. hr = HrRenameConnectionInternal(pidlCon, pidlFolder, pszNewName,
  710. FALSE, NULL, pcfpEmpty);
  711. }
  712. }
  713. }
  714. if (fUninitCom)
  715. {
  716. CoUninitialize();
  717. }
  718. }
  719. TraceError("HrRenameConnection", hr);
  720. return hr;
  721. }
  722. //+---------------------------------------------------------------------------
  723. //
  724. // Function: InvokeDunFile
  725. // Purpose: External Entry point for launching .dun files
  726. //
  727. // Arguments:
  728. //
  729. // Returns:
  730. //
  731. // Author: tongl 4 Feb 1999
  732. //
  733. // Notes:
  734. //
  735. EXTERN_C
  736. VOID APIENTRY InvokeDunFile(HWND hwnd, HINSTANCE hinst, LPCSTR lpszCmdLine, int nCmdShow)
  737. {
  738. if (lpszCmdLine)
  739. {
  740. INT cch = 0;
  741. WCHAR * pszFileW = NULL;
  742. cch = lstrlenA(lpszCmdLine) + 1;
  743. pszFileW = new WCHAR[cch];
  744. if (pszFileW)
  745. {
  746. int iRet = MultiByteToWideChar( CP_ACP,
  747. MB_PRECOMPOSED,
  748. lpszCmdLine,
  749. -1,
  750. pszFileW,
  751. cch);
  752. if (iRet)
  753. {
  754. HRESULT hr = HrInvokeDunFile_Internal(pszFileW);
  755. TraceError("Failed to invoke the DUN file", hr);
  756. }
  757. else
  758. {
  759. HRESULT hr = HrFromLastWin32Error();
  760. TraceError("Failed converting commandline to UniCode string", hr);
  761. }
  762. delete pszFileW;
  763. }
  764. }
  765. }
  766. EXTERN_C
  767. HRESULT APIENTRY RepairConnection(GUID guidConnection, LPWSTR * ppszMessage)
  768. {
  769. return RepairConnectionInternal(guidConnection, ppszMessage);
  770. }
  771. //+---------------------------------------------------------------------------
  772. //
  773. // Function: HrGetIconFromIconId
  774. //
  775. // Purpose: Exported version of CNetConfigIcons::HrGetIconFromMediaType
  776. //
  777. // Arguments:
  778. // dwIconSize [in] Size of the icon required
  779. // ncm [in] The NETCON_MEDIATYPE
  780. // ncsm [in] The NETCON_SUBMEDIATYPE
  781. // dwConnectionIcon [in] ENUM_CONNECTION_ICON (Not shifted (IOW: 0 or 4,5,6,7)
  782. // dwCharacteristics [in] The NCCF_CHARACTERISTICS flag (0 allowed)
  783. // phIcon [in] The resulting icon. Destroy using DestroyIcon
  784. //
  785. // Returns:
  786. //
  787. // Author: deonb 23 Apr 2001
  788. //
  789. // Notes:
  790. //
  791. EXTERN_C
  792. HRESULT APIENTRY HrGetIconFromMediaType(DWORD dwIconSize, IN NETCON_MEDIATYPE ncm, IN NETCON_SUBMEDIATYPE ncsm, IN DWORD dwConnectionIcon, IN DWORD dwCharacteristics, OUT HICON *phIcon)
  793. {
  794. Assert(g_pNetConfigIcons);
  795. if (g_pNetConfigIcons)
  796. {
  797. return g_pNetConfigIcons->HrGetIconFromMediaType(dwIconSize, ncm, ncsm, dwConnectionIcon, dwCharacteristics, phIcon);
  798. }
  799. else
  800. {
  801. return E_UNEXPECTED;
  802. }
  803. }