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.

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