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.

853 lines
24 KiB

  1. /*++
  2. Copyright (c) 1998 Microsoft Corporation
  3. Module Name:
  4. connsink.c
  5. Abstract:
  6. Implements a COM sink object on which to receive connection folder
  7. events
  8. Author:
  9. CharlWi (Charlie Wickham) 11/30/98 - heavily ripped off from
  10. net\config\shell\folder\notify.cpp, originally authored by
  11. ShaunCo (Shaun Cox)
  12. Revision History:
  13. --*/
  14. #define UNICODE 1
  15. #include "connsink.h"
  16. #include <iaccess.h>
  17. extern "C" {
  18. #include "nmp.h"
  19. VOID
  20. ProcessNameChange(
  21. GUID * GuidId,
  22. LPCWSTR NewName
  23. );
  24. }
  25. EXTERN_C const CLSID CLSID_ConnectionManager;
  26. EXTERN_C const IID IID_INetConnectionNotifySink;
  27. #define INVALID_COOKIE -1
  28. CComModule _Module;
  29. DWORD AdviseCookie = INVALID_COOKIE;
  30. //static
  31. HRESULT
  32. CConnectionNotifySink::CreateInstance (
  33. REFIID riid,
  34. VOID** ppv)
  35. {
  36. HRESULT hr = E_OUTOFMEMORY;
  37. // Initialize the output parameter.
  38. //
  39. *ppv = NULL;
  40. CConnectionNotifySink* pObj;
  41. pObj = new CComObject <CConnectionNotifySink>;
  42. if (pObj)
  43. {
  44. // Do the standard CComCreator::CreateInstance stuff.
  45. //
  46. pObj->SetVoid (NULL);
  47. pObj->InternalFinalConstructAddRef ();
  48. hr = pObj->FinalConstruct ();
  49. pObj->InternalFinalConstructRelease ();
  50. if (SUCCEEDED(hr))
  51. {
  52. hr = pObj->QueryInterface (riid, ppv);
  53. }
  54. if (FAILED(hr))
  55. {
  56. delete pObj;
  57. }
  58. }
  59. if ( FAILED( hr )) {
  60. ClRtlLogPrint(LOG_CRITICAL,
  61. "[NM] Unable to create Net Connection Manager advise sink "
  62. "object, status %08X.\n",
  63. hr);
  64. }
  65. return hr;
  66. } // CConnectionNotifySink::CreateInstance
  67. //+---------------------------------------------------------------------------
  68. //
  69. // Member: CConnectionNotifySink::~CConnectionNotifySink
  70. //
  71. // Purpose: Clean up the sink object
  72. //
  73. // Arguments:
  74. // (none)
  75. //
  76. // Returns:
  77. //
  78. CConnectionNotifySink::~CConnectionNotifySink()
  79. {
  80. }
  81. //
  82. // all we really care about are renaming events hence the rest of the routines
  83. // are stubbed out
  84. //
  85. HRESULT
  86. CConnectionNotifySink::ConnectionAdded (
  87. const NETCON_PROPERTIES_EX* pPropsEx)
  88. {
  89. return E_NOTIMPL;
  90. }
  91. HRESULT
  92. CConnectionNotifySink::ConnectionBandWidthChange (
  93. const GUID* pguidId)
  94. {
  95. return E_NOTIMPL;
  96. }
  97. HRESULT
  98. CConnectionNotifySink::ConnectionDeleted (
  99. const GUID* pguidId)
  100. {
  101. return E_NOTIMPL;
  102. }
  103. HRESULT
  104. CConnectionNotifySink::ConnectionModified (
  105. const NETCON_PROPERTIES_EX* pPropsEx)
  106. {
  107. ProcessNameChange(const_cast<GUID *>(&(pPropsEx->guidId)), pPropsEx->bstrName );
  108. return S_OK;
  109. }
  110. HRESULT
  111. CConnectionNotifySink::ConnectionRenamed (
  112. const GUID* GuidId,
  113. LPCWSTR NewName)
  114. {
  115. ProcessNameChange(( GUID *)GuidId, NewName );
  116. return S_OK;
  117. } // CConnectionNotifySink::ConnectionRenamed
  118. HRESULT
  119. CConnectionNotifySink::ConnectionStatusChange (
  120. const GUID* pguidId,
  121. NETCON_STATUS Status)
  122. {
  123. return E_NOTIMPL;
  124. }
  125. HRESULT
  126. CConnectionNotifySink::RefreshAll ()
  127. {
  128. return E_NOTIMPL;
  129. }
  130. HRESULT CConnectionNotifySink::ConnectionAddressChange (
  131. const GUID* pguidId )
  132. {
  133. return E_NOTIMPL;
  134. }
  135. HRESULT CConnectionNotifySink::ShowBalloon(
  136. IN const GUID* pguidId,
  137. IN const BSTR szCookie,
  138. IN const BSTR szBalloonText)
  139. {
  140. return E_NOTIMPL;
  141. }
  142. HRESULT CConnectionNotifySink::DisableEvents(
  143. IN const BOOL fDisable,
  144. IN const ULONG ulDisableTimeout)
  145. {
  146. return E_NOTIMPL;
  147. }
  148. //+---------------------------------------------------------------------------
  149. //
  150. // Function: HrGetNotifyConPoint
  151. //
  152. // Purpose: Common code for getting the connection point for use in
  153. // NotifyAdd and NotifyRemove
  154. //
  155. // Arguments:
  156. // ppConPoint [out] Return ptr for IConnectionPoint
  157. //
  158. // Returns:
  159. //
  160. // Author: jeffspr 24 Aug 1998
  161. //
  162. // Notes:
  163. //
  164. HRESULT HrGetNotifyConPoint(
  165. IConnectionPoint ** ppConPoint)
  166. {
  167. HRESULT hr;
  168. IConnectionPointContainer * pContainer = NULL;
  169. CL_ASSERT(ppConPoint);
  170. // Get the debug interface from the connection manager
  171. //
  172. hr = CoCreateInstance(CLSID_ConnectionManager, NULL,
  173. CLSCTX_LOCAL_SERVER,
  174. IID_IConnectionPointContainer,
  175. (LPVOID*)&pContainer);
  176. if (SUCCEEDED(hr)) {
  177. IConnectionPoint * pConPoint = NULL;
  178. // Get the connection point itself and fill in the return param
  179. // on success
  180. //
  181. hr = pContainer->FindConnectionPoint(
  182. IID_INetConnectionNotifySink,
  183. &pConPoint);
  184. if (SUCCEEDED(hr)) {
  185. //
  186. // set up a proxy on the connection point interface that will
  187. // identify ourselves as ourselves.
  188. //
  189. hr = CoSetProxyBlanket(pConPoint,
  190. RPC_C_AUTHN_WINNT, // use NT default security
  191. RPC_C_AUTHZ_NONE, // use NT default authentication
  192. NULL, // must be null if default
  193. RPC_C_AUTHN_LEVEL_CALL, // call
  194. RPC_C_IMP_LEVEL_IMPERSONATE,
  195. NULL, // use process token
  196. EOAC_NONE);
  197. if (SUCCEEDED(hr)) {
  198. *ppConPoint = pConPoint;
  199. } else {
  200. ClRtlLogPrint(LOG_CRITICAL,
  201. "[NM] Couldn't set proxy blanket on Net Connection "
  202. "point, status %1!08X!.\n",
  203. hr);
  204. pConPoint->Release();
  205. }
  206. } else {
  207. ClRtlLogPrint(LOG_CRITICAL,
  208. "[NM] Couldn't find notify sink connection point on Net Connection "
  209. "Manager, status %1!08X!.\n",
  210. hr);
  211. }
  212. pContainer->Release();
  213. } else {
  214. ClRtlLogPrint(LOG_CRITICAL,
  215. "[NM] Couldn't establish connection point with Net Connection "
  216. "Manager, status %1!08X!.\n",
  217. hr);
  218. }
  219. return hr;
  220. }
  221. EXTERN_C {
  222. HRESULT
  223. NmpGrantAccessToNotifySink(
  224. VOID
  225. )
  226. /*++
  227. Routine Description:
  228. allow localsystem, cluster service account and backup operators group access to make callbacks
  229. into the service.
  230. stolen from private\admin\snapin\netsnap\remrras\server\remrras.cpp and
  231. code reviewed by SajiA
  232. Arguments:
  233. None
  234. Return Value:
  235. ERROR_SUCCESS if everything went ok.
  236. --*/
  237. {
  238. IAccessControl* pAccessControl = NULL;
  239. SID_IDENTIFIER_AUTHORITY siaNtAuthority = SECURITY_NT_AUTHORITY;
  240. PSID pSystemSid = NULL;
  241. HANDLE processToken = NULL;
  242. ULONG tokenUserSize;
  243. PTOKEN_USER processTokenUser = NULL;
  244. DWORD status;
  245. PSID pBackupOperatorsSid = NULL;
  246. PSID pAdminGroupSid = NULL;
  247. HRESULT hr = CoCreateInstance(CLSID_DCOMAccessControl,
  248. NULL,
  249. CLSCTX_INPROC_SERVER,
  250. IID_IAccessControl,
  251. (void**)&pAccessControl);
  252. if( FAILED( hr ) ) {
  253. ClRtlLogPrint(LOG_CRITICAL,
  254. "[NM] Couldn't create access control class object "
  255. "status 0x%1!08X!.\n",
  256. hr);
  257. goto Error;
  258. }
  259. //
  260. // Setup the property list. We use the NULL property because we are trying
  261. // to adjust the security of the object itself
  262. //
  263. ACTRL_ACCESSW access;
  264. ACTRL_PROPERTY_ENTRYW propEntry;
  265. access.cEntries = 1;
  266. access.pPropertyAccessList = &propEntry;
  267. ACTRL_ACCESS_ENTRY_LISTW entryList;
  268. propEntry.lpProperty = NULL;
  269. propEntry.pAccessEntryList = &entryList;
  270. propEntry.fListFlags = 0;
  271. //
  272. // Setup the access control list for the default property
  273. //
  274. ACTRL_ACCESS_ENTRYW entry[3];
  275. entryList.cEntries = 3;
  276. entryList.pAccessList = entry;
  277. //
  278. // Setup the access control entry for localsystem
  279. //
  280. entry[0].fAccessFlags = ACTRL_ACCESS_ALLOWED;
  281. entry[0].Access = COM_RIGHTS_EXECUTE;
  282. entry[0].ProvSpecificAccess = 0;
  283. entry[0].Inheritance = NO_INHERITANCE;
  284. entry[0].lpInheritProperty = NULL;
  285. //
  286. // NT requires the system account to have access (for launching)
  287. //
  288. entry[0].Trustee.pMultipleTrustee = NULL;
  289. entry[0].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  290. entry[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  291. entry[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
  292. //
  293. // allocate and init the SYSTEM sid
  294. //
  295. if ( !AllocateAndInitializeSid( &siaNtAuthority,
  296. 1,
  297. SECURITY_LOCAL_SYSTEM_RID,
  298. 0, 0, 0, 0, 0, 0, 0,
  299. &pSystemSid ) ) {
  300. status = GetLastError();
  301. hr = HRESULT_FROM_WIN32( status );
  302. ClRtlLogPrint(LOG_CRITICAL,
  303. "[NM] Failed in allocating and initializing system SID, status %1!u!.\n",
  304. status);
  305. goto Error;
  306. }
  307. entry[0].Trustee.ptstrName = ( PWCHAR ) pSystemSid;
  308. #if 0
  309. //
  310. // Setup the access control entry for cluster service account
  311. //
  312. entry[1].fAccessFlags = ACTRL_ACCESS_ALLOWED;
  313. entry[1].Access = COM_RIGHTS_EXECUTE;
  314. entry[1].ProvSpecificAccess = 0;
  315. entry[1].Inheritance = NO_INHERITANCE;
  316. entry[1].lpInheritProperty = NULL;
  317. entry[1].Trustee.pMultipleTrustee = NULL;
  318. entry[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  319. entry[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  320. entry[1].Trustee.TrusteeType = TRUSTEE_IS_USER;
  321. status = NtOpenProcessToken(
  322. NtCurrentProcess(),
  323. TOKEN_QUERY,
  324. &processToken
  325. );
  326. if ( !NT_SUCCESS( status ) ) {
  327. ClRtlLogPrint(LOG_CRITICAL,
  328. "[NM] Failed in opening cluster service process token, status 0x%1!08lx!.\n",
  329. status);
  330. hr = HRESULT_FROM_NT( status );
  331. goto Error;
  332. }
  333. //
  334. // find out the size of token, allocate and requery to get info
  335. //
  336. status = NtQueryInformationToken(
  337. processToken,
  338. TokenUser,
  339. NULL,
  340. 0,
  341. &tokenUserSize
  342. );
  343. CL_ASSERT( status == STATUS_BUFFER_TOO_SMALL );
  344. if ( status != STATUS_BUFFER_TOO_SMALL ) {
  345. ClRtlLogPrint(LOG_CRITICAL,
  346. "[NM] Failed in querying cluster service process token info, status 0x%1!08lx!.\n",
  347. status);
  348. hr = HRESULT_FROM_NT( status );
  349. goto Error;
  350. }
  351. processTokenUser = (PTOKEN_USER) LocalAlloc( 0, tokenUserSize );
  352. if (( processToken == NULL ) || ( processTokenUser == NULL ) ) {
  353. status = STATUS_INSUFFICIENT_RESOURCES;
  354. ClRtlLogPrint(LOG_CRITICAL,
  355. "[NM] Failed in memory alloc for cluster service process token, status 0x%1!08lx!.\n",
  356. status);
  357. hr = HRESULT_FROM_NT( status );
  358. goto Error;
  359. }
  360. status = NtQueryInformationToken(
  361. processToken,
  362. TokenUser,
  363. processTokenUser,
  364. tokenUserSize,
  365. &tokenUserSize
  366. );
  367. if ( !NT_SUCCESS( status ) ) {
  368. ClRtlLogPrint(LOG_CRITICAL,
  369. "[NM] Failed in querying cluster service process token info with alloced buffer, status 0x%1!08lx!.\n",
  370. status);
  371. hr = HRESULT_FROM_NT( status );
  372. goto Error;
  373. }
  374. entry[1].Trustee.ptstrName = (PWCHAR)processTokenUser->User.Sid;
  375. #else
  376. //
  377. // Setup the access control entry for administrators group
  378. //
  379. entry[1].fAccessFlags = ACTRL_ACCESS_ALLOWED;
  380. entry[1].Access = COM_RIGHTS_EXECUTE;
  381. entry[1].ProvSpecificAccess = 0;
  382. entry[1].Inheritance = NO_INHERITANCE;
  383. entry[1].lpInheritProperty = NULL;
  384. entry[1].Trustee.pMultipleTrustee = NULL;
  385. entry[1].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  386. entry[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  387. entry[1].Trustee.TrusteeType = TRUSTEE_IS_USER;
  388. if ( !AllocateAndInitializeSid( &siaNtAuthority,
  389. 2,
  390. SECURITY_BUILTIN_DOMAIN_RID,
  391. DOMAIN_ALIAS_RID_ADMINS,
  392. 0, 0, 0, 0, 0, 0,
  393. &pAdminGroupSid ) ) {
  394. status = GetLastError();
  395. hr = HRESULT_FROM_WIN32( status );
  396. ClRtlLogPrint(LOG_CRITICAL,
  397. "[NM] Failed in allocating and initializing admin group SID, status %1!u!.\n",
  398. status);
  399. goto Error;
  400. }
  401. entry[1].Trustee.ptstrName = ( PWCHAR ) pAdminGroupSid;
  402. #endif
  403. //
  404. // Setup the access control entry for backup operators
  405. //
  406. entry[2].fAccessFlags = ACTRL_ACCESS_ALLOWED;
  407. entry[2].Access = COM_RIGHTS_EXECUTE;
  408. entry[2].ProvSpecificAccess = 0;
  409. entry[2].Inheritance = NO_INHERITANCE;
  410. entry[2].lpInheritProperty = NULL;
  411. entry[2].Trustee.pMultipleTrustee = NULL;
  412. entry[2].Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
  413. entry[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
  414. entry[2].Trustee.TrusteeType = TRUSTEE_IS_USER;
  415. if ( !AllocateAndInitializeSid( &siaNtAuthority,
  416. 2,
  417. SECURITY_BUILTIN_DOMAIN_RID,
  418. DOMAIN_ALIAS_RID_BACKUP_OPS,
  419. 0, 0, 0, 0, 0, 0,
  420. &pBackupOperatorsSid ) ) {
  421. status = GetLastError();
  422. hr = HRESULT_FROM_WIN32( status );
  423. ClRtlLogPrint(LOG_CRITICAL,
  424. "[NM] Failed in allocating and initializing backup operators SID, status %1!u!.\n",
  425. status);
  426. goto Error;
  427. }
  428. entry[2].Trustee.ptstrName = ( PWCHAR ) pBackupOperatorsSid;
  429. //
  430. // grant access to this mess
  431. //
  432. hr = pAccessControl->GrantAccessRights(&access);
  433. if( SUCCEEDED(hr) )
  434. {
  435. hr = CoInitializeSecurity(pAccessControl,
  436. -1,
  437. NULL,
  438. NULL,
  439. RPC_C_AUTHN_LEVEL_CONNECT,
  440. RPC_C_IMP_LEVEL_IDENTIFY,
  441. NULL,
  442. EOAC_ACCESS_CONTROL,
  443. NULL);
  444. }
  445. Error:
  446. if( pAccessControl ) {
  447. pAccessControl->Release();
  448. }
  449. if ( processTokenUser != NULL ) {
  450. LocalFree( processTokenUser );
  451. }
  452. if ( processToken != NULL ) {
  453. NtClose( processToken );
  454. }
  455. if( pSystemSid != NULL ) {
  456. FreeSid( pSystemSid );
  457. }
  458. if ( pBackupOperatorsSid != NULL ) {
  459. FreeSid( pBackupOperatorsSid );
  460. }
  461. if ( pAdminGroupSid != NULL ) {
  462. FreeSid( pAdminGroupSid );
  463. }
  464. return hr;
  465. }
  466. HRESULT
  467. NmpInitializeConnectoidAdviseSink(
  468. VOID
  469. )
  470. /*++
  471. Routine Description:
  472. Get an instance pointer to the conn mgr's connection point object and hook
  473. up our advice sink so we can catch connectoid rename events
  474. Arguments:
  475. None
  476. Return Value:
  477. ERROR_SUCCESS if everything worked...
  478. --*/
  479. {
  480. HRESULT hr = S_OK; // Not returned, but used for debugging
  481. IConnectionPoint * pConPoint = NULL;
  482. INetConnectionNotifySink * pSink = NULL;
  483. PSECURITY_DESCRIPTOR sinkSD;
  484. hr = NmpGrantAccessToNotifySink();
  485. if ( SUCCEEDED( hr )) {
  486. hr = HrGetNotifyConPoint(&pConPoint);
  487. if (SUCCEEDED(hr)) {
  488. // Create the notify sink
  489. //
  490. hr = CConnectionNotifySink::CreateInstance(
  491. IID_INetConnectionNotifySink,
  492. (LPVOID*)&pSink);
  493. if (SUCCEEDED(hr)) {
  494. CL_ASSERT(pSink);
  495. hr = pConPoint->Advise(pSink, &AdviseCookie);
  496. if ( !SUCCEEDED( hr )) {
  497. ClRtlLogPrint(LOG_UNUSUAL,
  498. "[NM] Couldn't initialize Net Connection Manager advise "
  499. "sink, status %1!08X!\n",
  500. hr);
  501. }
  502. pSink->Release();
  503. } else {
  504. hr = GetLastError();
  505. ClRtlLogPrint(LOG_UNUSUAL,
  506. "[NM] Couldn't create sink instance, status %1!08X!\n",
  507. hr);
  508. }
  509. pConPoint->Release();
  510. }
  511. } else {
  512. ClRtlLogPrint(LOG_UNUSUAL,
  513. "[NM] CoInitializeSecurity failed, status %1!08X!\n",
  514. hr);
  515. }
  516. if ( FAILED( hr )) {
  517. ClRtlLogPrint(LOG_UNUSUAL,
  518. "[NM] Couldn't initialize Net Connection Manager advise "
  519. "sink, status %1!08X!\n",
  520. hr);
  521. AdviseCookie = INVALID_COOKIE;
  522. }
  523. return hr;
  524. } // NmpInitializeConnectoidAdviseSink
  525. VOID
  526. NmCloseConnectoidAdviseSink(
  527. VOID
  528. )
  529. /*++
  530. Routine Description:
  531. close down the conn mgr event sink. this routine is public since it is
  532. called prior to CoUninitialize in ClusterShutdown()
  533. Arguments:
  534. None
  535. Return Value:
  536. None
  537. --*/
  538. {
  539. HRESULT hr = S_OK;
  540. IConnectionPoint * pConPoint = NULL;
  541. if ( AdviseCookie != INVALID_COOKIE ) {
  542. hr = HrGetNotifyConPoint(&pConPoint);
  543. if (SUCCEEDED(hr)) {
  544. // Unadvise
  545. //
  546. hr = pConPoint->Unadvise(AdviseCookie);
  547. AdviseCookie = INVALID_COOKIE;
  548. pConPoint->Release();
  549. }
  550. if ( FAILED( hr )) {
  551. ClRtlLogPrint(LOG_UNUSUAL,
  552. "[NM] Couldn't close Net Connection Manager advise sink, status %1!08X!\n",
  553. hr);
  554. }
  555. }
  556. } // NmCloseConnectoidAdviseSink
  557. VOID
  558. ProcessNameChange(
  559. GUID * GuidId,
  560. LPCWSTR NewName
  561. )
  562. /*++
  563. Routine Description:
  564. wrapper that enums the net interfaces
  565. Arguments:
  566. GuidId - pointer to connectoid that changed
  567. NewName - pointer to new name of connectoid
  568. Return Value:
  569. None
  570. --*/
  571. {
  572. RPC_STATUS rpcStatus;
  573. LPWSTR connectoidId = NULL;
  574. CL_ASSERT(GuidId);
  575. CL_ASSERT(NewName);
  576. rpcStatus = UuidToString( (GUID *) GuidId, &connectoidId);
  577. if ( rpcStatus == RPC_S_OK ) {
  578. PNM_INTERFACE netInterface;
  579. DWORD status;
  580. PLIST_ENTRY entry;
  581. ClRtlLogPrint(LOG_NOISE,
  582. "[NM] Received notification that name for connectoid %1!ws! was changed "
  583. "to '%2!ws!'\n",
  584. connectoidId,
  585. NewName);
  586. NmpAcquireLock();
  587. //
  588. // enum the interfaces, looking for the connectoid GUID as the
  589. // adapter ID
  590. //
  591. for (entry = NmpInterfaceList.Flink;
  592. entry != &NmpInterfaceList;
  593. entry = entry->Flink
  594. )
  595. {
  596. netInterface = CONTAINING_RECORD(entry, NM_INTERFACE, Linkage);
  597. if ( lstrcmpiW( connectoidId , netInterface->AdapterId ) == 0 ) {
  598. PNM_NETWORK network = netInterface->Network;
  599. LPWSTR networkName = (LPWSTR) OmObjectName( network );
  600. BOOL nameMatch = (lstrcmpW( networkName, NewName ) == 0);
  601. // Ignore this callback if there is a pending GUM update
  602. // with a different network name.
  603. if (NmpIsNetworkNameChangePending(network)) {
  604. if (nameMatch) {
  605. // Assume this is the callback we're waiting for.
  606. // Clear the pending flag and the timer.
  607. network->Flags &= ~NM_FLAG_NET_NAME_CHANGE_PENDING;
  608. NmpStartNetworkNameChangePendingTimer(network, 0);
  609. } else {
  610. // Ignore.
  611. NmpReleaseLock();
  612. ClRtlLogPrint(LOG_NOISE,
  613. "[NM] Ignoring notification that name for "
  614. "connectoid %1!ws! was changed to '%2!ws!' "
  615. "because a network name global update "
  616. "is pending for network %3!ws!.\n",
  617. connectoidId, NewName, networkName
  618. );
  619. break;
  620. }
  621. }
  622. if ( !nameMatch ) {
  623. NM_NETWORK_INFO netInfo;
  624. //
  625. // For some reason, OmReferenceObject causes a compiler
  626. // error here. Likely a header ordering problem. The
  627. // function has been wrappered as a workaround.
  628. //
  629. NmpReferenceNetwork(network);
  630. NmpReleaseLock();
  631. netInfo.Id = (LPWSTR) OmObjectId( network );
  632. netInfo.Name = (LPWSTR) NewName;
  633. status = NmpSetNetworkName( &netInfo );
  634. if ( status != ERROR_SUCCESS ) {
  635. ClRtlLogPrint( LOG_UNUSUAL,
  636. "[NM] Couldn't rename network '%1!ws!' to '%2!ws!', status %3!u!\n",
  637. networkName,
  638. NewName,
  639. status
  640. );
  641. //If the error condition is due to the object
  642. //already existing revert back to the old name.
  643. if(status == ERROR_OBJECT_ALREADY_EXISTS) {
  644. DWORD tempStatus = ERROR_SUCCESS;
  645. INetConnection *connectoid;
  646. ClRtlLogPrint(LOG_UNUSUAL,
  647. "[NM] Reverting back network name to '%1!ws!', from '%2!ws!\n",
  648. networkName,
  649. NewName
  650. );
  651. connectoid = ClRtlFindConnectoidByGuid(connectoidId);
  652. if(connectoid != NULL){
  653. tempStatus = ClRtlSetConnectoidName(
  654. connectoid,
  655. networkName);
  656. }
  657. if((tempStatus != ERROR_SUCCESS) ||
  658. (connectoid == NULL)) {
  659. ClRtlLogPrint(LOG_UNUSUAL,
  660. "[NM] Failed to set name of network connection"
  661. "%1!ws!, status %2!u!\n",
  662. networkName,
  663. tempStatus);
  664. }
  665. }
  666. }
  667. NmpDereferenceNetwork(network);
  668. }
  669. else {
  670. NmpReleaseLock();
  671. }
  672. break;
  673. }
  674. }
  675. if ( entry == &NmpInterfaceList ) {
  676. NmpReleaseLock();
  677. ClRtlLogPrint(LOG_UNUSUAL,
  678. "[NM] Couldn't find net interface for connectoid '%1!ws!'\n",
  679. connectoidId
  680. );
  681. }
  682. RpcStringFree( &connectoidId );
  683. }
  684. return;
  685. } // ProcessNameChange
  686. } // EXTERN_C