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.

1872 lines
55 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: Invoke.cpp
  7. //
  8. // Contents: Handles invocation cases, ENS, Schedule, etc.
  9. //
  10. // Classes: CSynchronizeInvoke
  11. //
  12. // Notes:
  13. //
  14. // History: 05-Nov-97 rogerg Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "precomp.h"
  18. // Review - Need to figure out logon logic. This just prevents ConnectionMade
  19. // events from being handled while we are in logon. If IsNetworkAlive becomse async
  20. // or someone calls IsNetworkAlive before us we will sync the same items twice.
  21. BOOL g_InAutoSync = FALSE;
  22. extern HINSTANCE g_hInst; // current instance
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Member: CSynchronizeInvoke::CSynchronizeInvoke, public
  26. //
  27. // Synopsis: Constructor
  28. // Increments the applications lifetime
  29. //
  30. // Arguments:
  31. //
  32. // Returns:
  33. //
  34. // Modifies:
  35. //
  36. // History: 05-Nov-97 rogerg Created.
  37. //
  38. //----------------------------------------------------------------------------
  39. CSynchronizeInvoke::CSynchronizeInvoke()
  40. {
  41. m_cRef = 1;
  42. m_pUnkOuter = &m_Unknown; // only support our unknown for know.
  43. m_pITypeInfoLogon = NULL;
  44. m_pITypeInfoNetwork = NULL;
  45. m_Unknown.SetParent(this);
  46. #ifdef _SENS
  47. m_PrivSensNetwork.SetParent(this);
  48. m_PrivSensLogon.SetParent(this);
  49. #endif // _SENS
  50. AddRefOneStopLifetime(TRUE /*External*/);
  51. }
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Member: CSynchronizeInvoke::~CSynchronizeInvoke, public
  55. //
  56. // Synopsis: Destructor
  57. // Decrements the applications lifetime
  58. //
  59. // Arguments:
  60. //
  61. // Returns:
  62. //
  63. // Modifies:
  64. //
  65. // History: 05-Nov-97 rogerg Created.
  66. //
  67. //----------------------------------------------------------------------------
  68. CSynchronizeInvoke::~CSynchronizeInvoke()
  69. {
  70. if (m_pITypeInfoLogon)
  71. {
  72. m_pITypeInfoLogon->Release();
  73. m_pITypeInfoLogon = NULL;
  74. }
  75. if (m_pITypeInfoNetwork)
  76. {
  77. m_pITypeInfoNetwork->Release();
  78. m_pITypeInfoNetwork = NULL;
  79. }
  80. ReleaseOneStopLifetime(TRUE /*External*/);
  81. }
  82. //+---------------------------------------------------------------------------
  83. //
  84. // Member: CSynchronizeInvoke::QueryInterface, public
  85. //
  86. // Synopsis: Standard QueryInterface
  87. //
  88. // Arguments: [iid] - Interface ID
  89. // [ppvObj] - Object return
  90. //
  91. // Returns: Appropriate status code
  92. //
  93. // Modifies: [ppvObj]
  94. //
  95. // History: 05-Nov-97 rogerg Created.
  96. //
  97. //----------------------------------------------------------------------------
  98. STDMETHODIMP CSynchronizeInvoke::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  99. {
  100. return m_pUnkOuter->QueryInterface(riid,ppv);
  101. }
  102. //+---------------------------------------------------------------------------
  103. //
  104. // Member: CSynchronizeInvoke::AddRef, public
  105. //
  106. // Synopsis: Add reference
  107. //
  108. // History: 05-Nov-97 rogerg Created.
  109. //
  110. //----------------------------------------------------------------------------
  111. STDMETHODIMP_(ULONG) CSynchronizeInvoke::AddRef()
  112. {
  113. return m_pUnkOuter->AddRef();
  114. }
  115. //+---------------------------------------------------------------------------
  116. //
  117. // Member: CSychrononizeInvoke::Release, public
  118. //
  119. // Synopsis: Release reference
  120. //
  121. // History: 05-Nov-97 rogerg Created.
  122. //
  123. //----------------------------------------------------------------------------
  124. STDMETHODIMP_(ULONG) CSynchronizeInvoke::Release()
  125. {
  126. return m_pUnkOuter->Release();
  127. }
  128. //+---------------------------------------------------------------------------
  129. //
  130. // Member: CSynchronizeInvoke::UpdateItems, public
  131. //
  132. // Synopsis: Handles a programmatic UpdateItems call.
  133. //
  134. // !!Warning - Liveness relies on a dialog being created
  135. // before return or we could go away when the
  136. // caler releases our interface.
  137. //
  138. // Arguments: [dwInvokeFlags] - InvokeFlags
  139. // [rclsid] - clsid of handler to load
  140. // [cbCookie] - Size of cookie data
  141. // [lpCookie] - Ptr to cookie data.
  142. //
  143. // Returns: Appropriate error codes
  144. //
  145. // Modifies:
  146. //
  147. // History: 05-Nov-97 rogerg Created.
  148. //
  149. //----------------------------------------------------------------------------
  150. STDMETHODIMP CSynchronizeInvoke::UpdateItems(DWORD dwInvokeFlags,REFCLSID rclsid,
  151. DWORD cbCookie,const BYTE*lpCookie)
  152. {
  153. HRESULT hr = E_OUTOFMEMORY;
  154. CHndlrQueue * pHndlrQueue = NULL;
  155. HANDLERINFO *pHandlerID;
  156. JOBINFO *pJobInfo = NULL;
  157. BOOL fReg;
  158. DWORD dwRegistrationFlags;
  159. int nCmdShow = (dwInvokeFlags & SYNCMGRINVOKE_MINIMIZED) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL;
  160. // when a new UpdateItems come through do the following
  161. // 1 - If should display choices see if existing choice dialog or create a new one
  162. // and then add the new items to the choice queue
  163. // 2 - If shouldn't display choices see if existing progress or create a new one
  164. // and then add the items to the progress queue.
  165. // behavior - If already an Update All choice dialog just pull it to the Front
  166. // If Already an UpdateAll progress bar bring it to the front
  167. // If Progress Bar but doesn't already contain an updateAll create the choice dialog.
  168. // we don't use stored preferences on invoke so doesn't matter what pass in as the connection
  169. pHndlrQueue = new CHndlrQueue(QUEUETYPE_CHOICE,NULL);
  170. if (NULL == pHndlrQueue)
  171. {
  172. hr = E_OUTOFMEMORY;
  173. return hr;
  174. }
  175. // attempt to initialize the queue
  176. hr = pHndlrQueue->AddQueueJobInfo(
  177. SYNCMGRFLAG_INVOKE | SYNCMGRFLAG_MAYBOTHERUSER,
  178. 0,NULL,NULL,FALSE,&pJobInfo);
  179. fReg = RegGetHandlerRegistrationInfo(rclsid,&dwRegistrationFlags);
  180. Assert(fReg || (0 == dwRegistrationFlags));
  181. if ( (S_OK == hr) && (S_OK == pHndlrQueue->AddHandler(&pHandlerID,pJobInfo,dwRegistrationFlags)) )
  182. {
  183. hr = pHndlrQueue->CreateServer(pHandlerID,&rclsid);
  184. if (S_OK == hr)
  185. {
  186. hr = pHndlrQueue->Initialize(pHandlerID,0,SYNCMGRFLAG_INVOKE | SYNCMGRFLAG_MAYBOTHERUSER,
  187. cbCookie,lpCookie);
  188. }
  189. }
  190. // can release our reference on the job info
  191. if (pJobInfo)
  192. {
  193. pHndlrQueue->ReleaseJobInfoExt(pJobInfo);
  194. pJobInfo = NULL;
  195. }
  196. if (S_OK == hr)
  197. {
  198. DWORD cbNumItemsAdded;
  199. hr = pHndlrQueue->AddHandlerItemsToQueue(pHandlerID,&cbNumItemsAdded);
  200. if (SYNCMGRINVOKE_STARTSYNC & dwInvokeFlags)
  201. {
  202. // if start invoke need to add the handlers items to the queue before
  203. // transferring
  204. if ( (S_OK == hr) && (pHndlrQueue->AreAnyItemsSelectedInQueue()) )
  205. {
  206. CProgressDlg *pProgressDlg;
  207. hr = FindProgressDialog(GUID_NULL,TRUE,nCmdShow,&pProgressDlg);
  208. if (S_OK == hr)
  209. {
  210. hr = pProgressDlg->TransferQueueData(pHndlrQueue);
  211. ReleaseProgressDialog(GUID_NULL,pProgressDlg,FALSE);
  212. }
  213. }
  214. pHndlrQueue->FreeAllHandlers(); // done with our queue.
  215. pHndlrQueue->Release();
  216. pHndlrQueue = NULL;
  217. }
  218. else
  219. {
  220. CChoiceDlg *pChoiceDlg;
  221. // Bring up the Choice dialog, Let choice dialog actually addes the hanlder items
  222. // if there are any so in the future we can async fill in the choices
  223. hr = FindChoiceDialog(rclsid,TRUE,nCmdShow,&pChoiceDlg);
  224. if (S_OK == hr)
  225. {
  226. if (FALSE == pChoiceDlg->SetQueueData(rclsid,pHndlrQueue) )
  227. {
  228. pHndlrQueue->FreeAllHandlers();
  229. pHndlrQueue->Release();
  230. pHndlrQueue = NULL;
  231. hr = E_UNEXPECTED;
  232. }
  233. ReleaseChoiceDialog(rclsid,pChoiceDlg);
  234. }
  235. }
  236. }
  237. else
  238. {
  239. // if initialize failed and have a queue release it now.
  240. if (pHndlrQueue)
  241. {
  242. pHndlrQueue->FreeAllHandlers();
  243. pHndlrQueue->Release();
  244. pHndlrQueue = NULL;
  245. }
  246. }
  247. // if we successfully added a jobinfo to the queue release our reference.
  248. return hr;
  249. }
  250. //+---------------------------------------------------------------------------
  251. //
  252. // Member: CSynchronizeInvoke::UpdateAll, public
  253. //
  254. // Synopsis: Handles a programmatic UpdateAll call.
  255. //
  256. // Arguments:
  257. //
  258. // Returns: Appropriate error codes
  259. //
  260. // Modifies:
  261. //
  262. // History: 05-Nov-97 rogerg Created.
  263. //
  264. //----------------------------------------------------------------------------
  265. STDMETHODIMP CSynchronizeInvoke::UpdateAll(void)
  266. {
  267. HRESULT hr = S_OK;
  268. TCHAR pConnectName[RAS_MaxEntryName + 1];
  269. TCHAR *pConnectionNameArray;
  270. if (!LoadString(g_hInst, IDS_LAN_CONNECTION, pConnectName, ARRAYSIZE(pConnectName)))
  271. {
  272. hr = HRESULT_FROM_WIN32(GetLastError());
  273. return hr;
  274. }
  275. pConnectionNameArray = pConnectName;
  276. // Review - Do we Need proper connection or do we always just
  277. // use the last items selected in a manual sync regardless
  278. // of the current connection
  279. return PrivUpdateAll(0, SYNCMGRFLAG_MANUAL | SYNCMGRFLAG_MAYBOTHERUSER, 0, NULL,
  280. 1, &pConnectionNameArray, NULL, FALSE, NULL, 0, 0, FALSE);
  281. }
  282. //+---------------------------------------------------------------------------
  283. //
  284. // Member: CSynchronizeInvoke::Logon, public
  285. //
  286. // Synopsis: Handles a Logon notification
  287. //
  288. // Arguments:
  289. //
  290. // Returns: Appropriate error codes
  291. //
  292. // Modifies:
  293. //
  294. // History: 05-Nov-97 rogerg Created.
  295. //
  296. //----------------------------------------------------------------------------
  297. STDMETHODIMP CSynchronizeInvoke::Logon()
  298. {
  299. HRESULT hr = E_UNEXPECTED;
  300. RegSetUserDefaults(); // Make Sure the UserDefaults are up to date
  301. // if on Win9x just call IsNetworkAlive and rely on ConnectionMade
  302. // events coming through. Can't just do this yet on NT 5.0 because
  303. // not guaranteed to get connectionMades on each logon.
  304. hr = PrivHandleAutoSync(SYNCMGRFLAG_CONNECT | SYNCMGRFLAG_MAYBOTHERUSER);
  305. return hr;
  306. }
  307. //+---------------------------------------------------------------------------
  308. //
  309. // Member: CSynchronizeInvoke::Logoff, public
  310. //
  311. // Synopsis: Handles a Logoff notification
  312. //
  313. // Arguments:
  314. //
  315. // Returns: Appropriate error codes
  316. //
  317. // Modifies:
  318. //
  319. // History: 05-Nov-97 rogerg Created.
  320. //
  321. //----------------------------------------------------------------------------
  322. STDMETHODIMP CSynchronizeInvoke::Logoff()
  323. {
  324. HRESULT hr = E_UNEXPECTED;
  325. RegSetUserDefaults(); // Make Sure the UserDefaults are up to date
  326. hr = PrivHandleAutoSync(SYNCMGRFLAG_PENDINGDISCONNECT | SYNCMGRFLAG_MAYBOTHERUSER);
  327. return hr;
  328. }
  329. //+---------------------------------------------------------------------------
  330. //
  331. // Member: CSynchronizeInvoke::Schedule, public
  332. //
  333. // Synopsis: Handles a shceduled notification
  334. //
  335. // Arguments:
  336. //
  337. // Returns: Appropriate error codes
  338. //
  339. // Modifies:
  340. //
  341. // History: 05-Nov-97 rogerg Created.
  342. //
  343. //----------------------------------------------------------------------------
  344. const TCHAR c_szTrayWindow[] = TEXT("Shell_TrayWnd");
  345. STDMETHODIMP CSynchronizeInvoke::Schedule(WCHAR *pszTaskName)
  346. {
  347. HRESULT hr = E_UNEXPECTED;
  348. TCHAR szConnectionName[RAS_MaxEntryName + 1];
  349. TCHAR *pszConnectionName = szConnectionName;
  350. CONNECTIONSETTINGS ConnectionSettings;
  351. if (!pszTaskName)
  352. {
  353. Assert(pszTaskName);
  354. return E_INVALIDARG;
  355. }
  356. // validate this is a valid schedule and if no registry data for
  357. // it then delete the .job file.
  358. // Get the UserName key from the TaskName itself since on NT schedules
  359. // can fire if User provided as Password as a different user thant the
  360. // current user.
  361. int OffsetToUserName = lstrlen(WSZGUID_IDLESCHEDULE)
  362. + 1; // +1 for _ char between guid and user name.
  363. WCHAR *pszDomainAndUser = pszTaskName + OffsetToUserName;
  364. HKEY hkeySchedSync,hkeyDomainUser,hkeySchedName;
  365. LONG lRegResult;
  366. hkeySchedSync = hkeyDomainUser = hkeySchedName = NULL;
  367. // open up keys ourselves so
  368. lRegResult = RegOpenKeyEx (HKEY_LOCAL_MACHINE,SCHEDSYNC_REGKEY,0,KEY_READ, &hkeySchedSync);
  369. if (ERROR_SUCCESS == lRegResult)
  370. {
  371. lRegResult = RegOpenKeyEx (hkeySchedSync,pszDomainAndUser,0,KEY_READ, &hkeyDomainUser);
  372. }
  373. if (ERROR_SUCCESS == lRegResult)
  374. {
  375. lRegResult = RegOpenKeyEx (hkeyDomainUser,pszTaskName,0,KEY_READ, &hkeySchedName);
  376. }
  377. // close up the keys
  378. if (hkeySchedName) RegCloseKey(hkeySchedName);
  379. if (hkeyDomainUser) RegCloseKey(hkeyDomainUser);
  380. if (hkeySchedSync) RegCloseKey(hkeySchedSync);
  381. // if any of the keys are bad then nix the TS file and return;
  382. if ( ERROR_FILE_NOT_FOUND == lRegResult)
  383. {
  384. // TODO: Call function to delete this .job file when
  385. // it is implemented for now just let it fire each time.
  386. return E_UNEXPECTED;
  387. }
  388. // assert is just so it fires if a new Error code occurs
  389. // so we make sure we handle it properly
  390. Assert(ERROR_SUCCESS == lRegResult);
  391. // check to see if this is really and idle and if so foward on to Idle
  392. // method
  393. WCHAR *pszSchedCookieIdle = WSZGUID_IDLESCHEDULE;
  394. int comparelength = (sizeof(WSZGUID_IDLESCHEDULE)/sizeof(WCHAR)) -1; // don't compare null
  395. // set the Idle flag instead
  396. if (0 == StrCmpNI(pszSchedCookieIdle, pszTaskName, comparelength))
  397. {
  398. return Idle();
  399. }
  400. // finally made it past verification if you can get a Connection
  401. // you can run the schedule.
  402. if (RegGetSchedConnectionName(pszTaskName,pszConnectionName,ARRAYSIZE(szConnectionName)))
  403. {
  404. BOOL fCanMakeConnection = FALSE;
  405. DWORD cbCookie = (lstrlen(pszTaskName) + 1)*(sizeof(WCHAR)/sizeof(BYTE));
  406. // if this is a valid schedule then go ahead and read in the settings
  407. // by default don't let the connection be made.
  408. StringCchCopy(ConnectionSettings.pszConnectionName, ARRAYSIZE(ConnectionSettings.pszConnectionName), pszConnectionName);
  409. if (RegGetSchedSyncSettings(&ConnectionSettings,pszTaskName))
  410. {
  411. fCanMakeConnection = ConnectionSettings.dwMakeConnection;
  412. }
  413. // if this schedule can't make the connectione then
  414. // check to see if the conneciton is available and if
  415. // it isn't bail here.
  416. BOOL fConnectionAvailable = FALSE;
  417. if (!fCanMakeConnection)
  418. {
  419. if (S_OK == ConnectObj_IsConnectionAvailable(pszConnectionName))
  420. {
  421. fConnectionAvailable = TRUE;
  422. }
  423. }
  424. // add to the queue and let the main progress determine if
  425. // can handle the schedule.
  426. if (fCanMakeConnection || fConnectionAvailable)
  427. {
  428. // on a schedule we pass in the schedule name for the cookie data.
  429. hr = PrivUpdateAll(SYNCMGRINVOKE_STARTSYNC | SYNCMGRINVOKE_MINIMIZED,SYNCMGRFLAG_SCHEDULED,
  430. cbCookie,(BYTE *) pszTaskName,1,&pszConnectionName,pszTaskName,fCanMakeConnection,NULL,0,0,FALSE);
  431. }
  432. else
  433. {
  434. hr = S_FALSE;
  435. }
  436. }
  437. else
  438. {
  439. AssertSz(0,"Schedule has no Connection");
  440. }
  441. return hr;
  442. }
  443. //+---------------------------------------------------------------------------
  444. //
  445. // Member: CSynchronizeInvoke::Idle, public
  446. //
  447. // Synopsis: Handles an Idle Notifications
  448. //
  449. // Arguments:
  450. //
  451. // Returns: Appropriate error codes
  452. //
  453. // Modifies:
  454. //
  455. // History: 20-Feb-98 rogerg Created.
  456. //
  457. //----------------------------------------------------------------------------
  458. STDMETHODIMP CSynchronizeInvoke::Idle()
  459. {
  460. HRESULT hr = E_UNEXPECTED;
  461. // request the idle Lock, If someone already has it then just return.
  462. if (S_OK == (hr = RequestIdleLock()))
  463. {
  464. hr = RunIdle();
  465. // if an error occured setting things up or nothing to do
  466. // then release our idle lock.
  467. if (S_OK != hr)
  468. {
  469. ReleaseIdleLock();
  470. }
  471. }
  472. return hr;
  473. }
  474. //+---------------------------------------------------------------------------
  475. //
  476. // Member: CSynchronizeInvoke::RunIdle, public
  477. //
  478. // Synopsis: Runs an Idle.
  479. //
  480. // Arguments:
  481. //
  482. // Returns: Appropriate error codes
  483. //
  484. // Modifies:
  485. //
  486. // History: 20-Feb-98 rogerg Created.
  487. //
  488. //----------------------------------------------------------------------------
  489. STDMETHODIMP CSynchronizeInvoke::RunIdle()
  490. {
  491. // for not just run the Idle as a Connect
  492. return PrivHandleAutoSync(SYNCMGRFLAG_IDLE);
  493. }
  494. //+---------------------------------------------------------------------------
  495. //
  496. // Member: CSynchronizeInvoke::RasPendingDisconnect, private
  497. //
  498. // Synopsis: Handles a programmatic Ras Pending Disconnect calls.
  499. //
  500. //
  501. // Arguments:
  502. //
  503. // Returns: Appropriate error codes
  504. //
  505. // Modifies:
  506. //
  507. // History: 05-Nov-97 rogerg Created.
  508. //
  509. //----------------------------------------------------------------------------
  510. STDMETHODIMP CSynchronizeInvoke::RasPendingDisconnect(DWORD cbConnectionName,
  511. const BYTE *lpConnectionName)
  512. {
  513. HRESULT hr = E_OUTOFMEMORY;
  514. CONNECTIONOBJ *pConnectionObj;
  515. // Thread with class factory is FreeThreaded so can block the return
  516. // until update is complete.
  517. // find connection object for this item so know its liveness.
  518. hr = ConnectObj_FindConnectionObj( (TCHAR*) lpConnectionName,TRUE,&pConnectionObj);
  519. if (S_OK == hr)
  520. {
  521. HANDLE hRasPendingEvent;
  522. hr = ConnectObj_GetConnectionObjCompletionEvent(pConnectionObj,&hRasPendingEvent);
  523. if (S_OK == hr)
  524. {
  525. hr = PrivAutoSyncOnConnection(SYNCMGRFLAG_PENDINGDISCONNECT | SYNCMGRFLAG_MAYBOTHERUSER,
  526. 1,(TCHAR **) &lpConnectionName,hRasPendingEvent);
  527. // if successfully invoked the connection then wait for the event
  528. // object to get set,
  529. if ( (S_OK == hr) && hRasPendingEvent)
  530. {
  531. WaitForSingleObject(hRasPendingEvent,INFINITE); // review if can determine a timeout
  532. }
  533. else
  534. {
  535. // !!!!on failure call close the Connection to make sure
  536. // the object gets cleaned up in case the progress queue didn't get kicked off.
  537. // If someone is currently using a connection they will be closed which is
  538. // the same as if autosync wasn't selected and the User chose to
  539. // close while a sync was in progress.
  540. ConnectObj_CloseConnection(pConnectionObj);
  541. }
  542. // Release our hold on the Connection.
  543. ConnectObj_ReleaseConnectionObj(pConnectionObj);
  544. if (hRasPendingEvent)
  545. {
  546. CloseHandle(hRasPendingEvent);
  547. }
  548. }
  549. }
  550. return hr;
  551. }
  552. //+---------------------------------------------------------------------------
  553. //
  554. // Member: QueryLoadHandlerOnEvent, private
  555. //
  556. // Synopsis: Determines if Handle needs to be loaded for the specified
  557. // Event and Connection.
  558. //
  559. //
  560. // Arguments: [pszClsid] - clsid of handler
  561. // [dwSyncFlags] - SyncFlags to pass onto initialize
  562. // [cbNumConnectionNames] - Number of ConnectionNames in array
  563. // [ppConnectionNames] - array of connection names.
  564. //
  565. // Returns: TRUE - handler needs to be loaded
  566. // FALSE - handler doesn't need to be loaded.
  567. //
  568. // Modifies:
  569. //
  570. // History: 24-Aug-98 rogerg Created.
  571. //
  572. //----------------------------------------------------------------------------
  573. BOOL QueryLoadHandlerOnEvent(TCHAR *pszClsid,DWORD dwSyncFlags,DWORD dwRegistrationFlags,
  574. DWORD cbNumConnectionNames,TCHAR **ppConnectionNames)
  575. {
  576. BOOL fLoadHandler = TRUE;
  577. DWORD dwSyncEvent = dwSyncFlags & SYNCMGRFLAG_EVENTMASK;
  578. // see if handler is registered for the event
  579. // if it is then we always load it. If its not the User had to have checked an item
  580. if (
  581. ( (dwSyncEvent == SYNCMGRFLAG_IDLE) && !(dwRegistrationFlags & SYNCMGRREGISTERFLAG_IDLE) )
  582. || ( (dwSyncEvent == SYNCMGRFLAG_CONNECT) && !(dwRegistrationFlags & SYNCMGRREGISTERFLAG_CONNECT) )
  583. || ( (dwSyncEvent == SYNCMGRFLAG_PENDINGDISCONNECT) && !(dwRegistrationFlags & SYNCMGRREGISTERFLAG_PENDINGDISCONNECT) )
  584. )
  585. {
  586. DWORD cbCurConnectionName;
  587. fLoadHandler = FALSE;
  588. for (cbCurConnectionName = 0 ; cbCurConnectionName < cbNumConnectionNames;cbCurConnectionName++)
  589. {
  590. fLoadHandler |= RegQueryLoadHandlerOnEvent(pszClsid,dwSyncFlags,ppConnectionNames[cbCurConnectionName]);
  591. }
  592. }
  593. return fLoadHandler;
  594. }
  595. //+---------------------------------------------------------------------------
  596. //
  597. // Member: CSynchronizeInvoke::PrivUpdateAll, private
  598. //
  599. // Synopsis: Handles a programmatic UpdateAll call.
  600. //
  601. // !!Warning - Liveness relies on a dialog being created
  602. // before return or we could go away when the
  603. // caler releases our interface.
  604. //
  605. // Arguments: [dwInvokeFlags] - InvokeFlags
  606. // [dwSyncFlags] - SyncFlags to pass onto initialize
  607. // [pszConnectionName] - array of connection names.
  608. // [pszScheduleName] - Name of schedule that was fired if a scheduled event.
  609. //
  610. // Returns: S_OK - If handled result
  611. // S_FALSE - if nothing to do (such as no items selected on Idle).
  612. // error codes - if errors occured
  613. //
  614. // Modifies:
  615. //
  616. // History: 05-Nov-97 rogerg Created.
  617. //
  618. //----------------------------------------------------------------------------
  619. STDMETHODIMP CSynchronizeInvoke::PrivUpdateAll(DWORD dwInvokeFlags,DWORD dwSyncFlags,
  620. DWORD cbCookie,const BYTE *lpCooke,
  621. DWORD cbNumConnectionNames,TCHAR **ppConnectionNames,
  622. TCHAR *pszScheduleName,BOOL fCanMakeConnection,HANDLE hRasPendingDisconnect,
  623. ULONG ulIdleRetryMinutes,ULONG ulDelayIdleShutDownTime,BOOL fRetryEnabled)
  624. {
  625. HRESULT hr = E_OUTOFMEMORY;
  626. CHndlrQueue * pHndlrQueue = NULL;
  627. CLSID clsidChoice = GUID_NULL;
  628. JOBINFO *pJobInfo = NULL;
  629. int nCmdShow = (dwInvokeFlags & SYNCMGRINVOKE_MINIMIZED) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL;
  630. DWORD dwSyncEvent = (dwSyncFlags & SYNCMGRFLAG_EVENTMASK);
  631. // On an UpdateAll
  632. // 1 - see if there is an existing UpdateAll choice, If so bring to foreground
  633. // 2 - Bring up update All choice dialog.
  634. // behavior - If already an Update All choice dialog just pull it to the Front
  635. // If Already an UpdateAll progress bar bring it to the front
  636. // If Progress Bar but doesn't already contain an updateAll create the choice dialog.
  637. Assert(ppConnectionNames && (cbNumConnectionNames >= 1));
  638. Assert( (NULL == pszScheduleName) || (SYNCMGRFLAG_SCHEDULED == dwSyncEvent)
  639. || (SYNCMGRFLAG_IDLE == dwSyncEvent) ); // review, temporary for idle.
  640. pHndlrQueue = new CHndlrQueue(QUEUETYPE_CHOICE,NULL);
  641. if (NULL == pHndlrQueue)
  642. return E_OUTOFMEMORY;
  643. hr = pHndlrQueue->AddQueueJobInfo(dwSyncFlags,cbNumConnectionNames,
  644. ppConnectionNames,pszScheduleName,fCanMakeConnection
  645. ,&pJobInfo);
  646. // loop through the reg getting the handlers and trying to
  647. // create them.
  648. if (S_OK == hr)
  649. {
  650. TCHAR lpName[256];
  651. DWORD cbName = 256;
  652. HKEY hkOneStop;
  653. CLSID clsid;
  654. HANDLERINFO *pHandlerID;
  655. BOOL fItemsInQueue = FALSE;
  656. hkOneStop = RegGetHandlerTopLevelKey(KEY_READ);
  657. if (hkOneStop)
  658. {
  659. DWORD dwIndex = 0;
  660. while ( ERROR_SUCCESS == RegEnumKey(hkOneStop,dwIndex, lpName,cbName) )
  661. {
  662. if (S_OK == CLSIDFromString(lpName,&clsid) )
  663. {
  664. BOOL fReg;
  665. DWORD dwRegistrationFlags;
  666. BOOL fLoadHandler = TRUE;
  667. fReg = RegGetHandlerRegistrationInfo(clsid,&dwRegistrationFlags);
  668. Assert(fReg || (0 == dwRegistrationFlags));
  669. //For scheduled, see if there are any items on this handler,
  670. if ((SYNCMGRINVOKE_STARTSYNC & dwInvokeFlags) &&
  671. (SYNCMGRFLAG_SCHEDULED == dwSyncEvent))
  672. {
  673. fLoadHandler = RegSchedHandlerItemsChecked(lpName, ppConnectionNames[0],pszScheduleName);
  674. }
  675. else if (SYNCMGRINVOKE_STARTSYNC & dwInvokeFlags)
  676. {
  677. fLoadHandler = QueryLoadHandlerOnEvent(lpName,dwSyncFlags,dwRegistrationFlags,
  678. cbNumConnectionNames,ppConnectionNames);
  679. }
  680. if (fLoadHandler)
  681. {
  682. if (S_OK == pHndlrQueue->AddHandler(&pHandlerID,pJobInfo,dwRegistrationFlags))
  683. {
  684. pHndlrQueue->CreateServer(pHandlerID,&clsid);
  685. }
  686. }
  687. }
  688. dwIndex++;
  689. }
  690. RegCloseKey(hkOneStop);
  691. }
  692. // Initialize the items.
  693. CLSID pHandlerClsid;
  694. while (S_OK == pHndlrQueue->FindFirstHandlerInState(HANDLERSTATE_INITIALIZE,GUID_NULL,&pHandlerID,&pHandlerClsid))
  695. {
  696. pHndlrQueue->Initialize(pHandlerID,0,dwSyncFlags,
  697. cbCookie,lpCooke);
  698. }
  699. // can release jobinfo since handlers need to hold their own addref.
  700. if (pJobInfo)
  701. {
  702. pHndlrQueue->ReleaseJobInfoExt(pJobInfo);
  703. pJobInfo = NULL;
  704. }
  705. // if start invoke need to add the handlers items to the queue before
  706. // transferring
  707. while (S_OK == pHndlrQueue->FindFirstHandlerInState(HANDLERSTATE_ADDHANDLERTEMS,GUID_NULL,&pHandlerID,&pHandlerClsid))
  708. {
  709. DWORD cbNumItemsAdded;
  710. // CODE REVIEW:
  711. // NOTENOTE:
  712. // What if one of these additems fails ?
  713. hr = pHndlrQueue->AddHandlerItemsToQueue(pHandlerID,&cbNumItemsAdded);
  714. // if an item was added, then there are items in the queue
  715. if (cbNumItemsAdded)
  716. {
  717. fItemsInQueue = TRUE;
  718. }
  719. }
  720. //
  721. // Move handlers that won't establish connections to end
  722. // of handler list.
  723. //
  724. pHndlrQueue->SortHandlersByConnection();
  725. if (SYNCMGRINVOKE_STARTSYNC & dwInvokeFlags)
  726. {
  727. CProgressDlg *pProgressDlg;
  728. CLSID clsid_Progress = GUID_NULL;
  729. // For Idle we want to use the idle progress dialog
  730. // currently progress dialog relies on some globals so
  731. // need to change that first before checking this in
  732. if (SYNCMGRFLAG_IDLE == dwSyncEvent)
  733. {
  734. clsid_Progress = GUID_PROGRESSDLGIDLE;
  735. }
  736. // if not items are selected, just free the queue.
  737. // Review - it would be better to always call Progress and progress
  738. // itself not show until there are items to synchronize
  739. if (pHndlrQueue->AreAnyItemsSelectedInQueue())
  740. {
  741. hr = FindProgressDialog(clsid_Progress,TRUE,nCmdShow,&pProgressDlg);
  742. if (S_OK == hr)
  743. {
  744. // for an Idle we now request the defaults for retryIdle
  745. // and delay shutdown, and change the queue order
  746. // based on the last item
  747. if (SYNCMGRFLAG_IDLE == dwSyncEvent)
  748. {
  749. CLSID clsidLastHandler;
  750. pProgressDlg->SetIdleParams(ulIdleRetryMinutes, ulDelayIdleShutDownTime, fRetryEnabled);
  751. if (S_OK == GetLastIdleHandler(&clsidLastHandler))
  752. {
  753. pHndlrQueue->ScrambleIdleHandlers(clsidLastHandler);
  754. }
  755. }
  756. hr = pProgressDlg->TransferQueueData(pHndlrQueue);
  757. ReleaseProgressDialog(clsid_Progress,pProgressDlg,FALSE);
  758. }
  759. }
  760. else
  761. {
  762. hr = S_FALSE; // return S_FALSE IF NOTHING TO DO.
  763. }
  764. pHndlrQueue->FreeAllHandlers(); // done with our queue.
  765. pHndlrQueue->Release();
  766. pHndlrQueue = NULL;
  767. }
  768. else
  769. {
  770. BOOL fDontShowIfNoItems = (
  771. (SYNCMGRFLAG_CONNECT == dwSyncEvent)
  772. || (SYNCMGRFLAG_PENDINGDISCONNECT == dwSyncEvent ) );
  773. // if the choice has been requested by a logon/logoff event and
  774. // there aren't any items in the queue for the User to choose then
  775. // if you want to turn on the code to now display anything
  776. // turn on this If statement. For now we always show the choice.
  777. // CODE REVIEW:
  778. // NOTENOTE:
  779. // This is ALWAYS executed..
  780. if (1 /* !fDontShowIfNoItems || fItemsInQueue */)
  781. {
  782. // Bring up the Choice dialog, Let choice dialog actually addes the hanlder items
  783. // if there are any so in the future we can async fill in the choices
  784. CChoiceDlg *pChoiceDlg;
  785. hr = FindChoiceDialog(clsidChoice,TRUE,nCmdShow,&pChoiceDlg);
  786. if (S_OK == hr)
  787. {
  788. if (FALSE == pChoiceDlg->SetQueueData(clsidChoice,pHndlrQueue) )
  789. {
  790. hr = E_UNEXPECTED;
  791. }
  792. else
  793. {
  794. pHndlrQueue = NULL; // set queue to NULL since Choice dialog owns it now.
  795. }
  796. ReleaseChoiceDialog(clsidChoice,pChoiceDlg);
  797. }
  798. }
  799. // release our queue if still have it otherwise choice owns it.
  800. if (pHndlrQueue)
  801. {
  802. pHndlrQueue->FreeAllHandlers();
  803. pHndlrQueue->Release();
  804. }
  805. }
  806. }
  807. return hr;
  808. }
  809. //+---------------------------------------------------------------------------
  810. //
  811. // Member: CSynchronizeInvoke::PrivHandleAutoSync, private
  812. //
  813. // Synopsis: Handles an AutoSync Update. Figures out what connections
  814. // if any are active and invoke an AutoSync on each one.
  815. //
  816. // Arguments: [dwSyncFlags] - SyncFlags to pass onto initialize
  817. //
  818. // Returns: S_OK - sync was started
  819. // S_FALSE - nothing to do
  820. // appropriate error codes.
  821. //
  822. // Modifies:
  823. //
  824. // History: 05-Nov-97 rogerg Created.
  825. //
  826. //----------------------------------------------------------------------------
  827. STDMETHODIMP CSynchronizeInvoke::PrivHandleAutoSync(DWORD dwSyncFlags)
  828. {
  829. HRESULT hr = E_UNEXPECTED;
  830. DWORD dwFlags = 0;
  831. LPNETAPI pNetApi = NULL;
  832. DWORD cbNumWanConnections = 0;
  833. LPRASCONN pRasConn = NULL;
  834. pNetApi = gSingleNetApiObj.GetNetApiObj();
  835. if (NULL == pNetApi)
  836. return S_FALSE;
  837. g_InAutoSync = TRUE;
  838. if (pNetApi->IsNetworkAlive(&dwFlags))
  839. {
  840. TCHAR **pConnections; // array of connection names. End with NULL;
  841. ULONG ulConnectionCount = 0;
  842. if (NETWORK_ALIVE_LAN & dwFlags)
  843. {
  844. // We curently don't care about these error results.
  845. // PrivAutoSyncOnConnection(dwSyncFlags,LANCONNECTIONNAME,NULL);
  846. // Review what we want this to do.
  847. ulConnectionCount += 1;
  848. }
  849. // loop through Ras Connections.
  850. if ( NETWORK_ALIVE_WAN & dwFlags)
  851. {
  852. if (S_OK == pNetApi->GetWanConnections(&cbNumWanConnections,&pRasConn)
  853. && (pRasConn) )
  854. {
  855. ulConnectionCount += cbNumWanConnections;
  856. }
  857. else
  858. {
  859. cbNumWanConnections = 0;
  860. pRasConn = NULL;
  861. }
  862. }
  863. // allocate array buffer for connections + 1 more for NULL
  864. if (ulConnectionCount
  865. && (pConnections = (TCHAR **) ALLOC(sizeof(TCHAR *)*(ulConnectionCount + 1))))
  866. {
  867. TCHAR **pCurConnection = pConnections;
  868. TCHAR *pLanConnection = NULL;
  869. // initialize the array.
  870. if (NETWORK_ALIVE_LAN & dwFlags)
  871. {
  872. pLanConnection = (TCHAR *) ALLOC(sizeof(TCHAR )*(MAX_PATH + 1));
  873. if (pLanConnection)
  874. {
  875. if (LoadString(g_hInst, IDS_LAN_CONNECTION, pLanConnection, MAX_PATH))
  876. {
  877. *pCurConnection = pLanConnection;
  878. ++pCurConnection;
  879. }
  880. }
  881. }
  882. while (cbNumWanConnections)
  883. {
  884. cbNumWanConnections--;
  885. *pCurConnection = pRasConn[cbNumWanConnections].szEntryName;
  886. ++pCurConnection;
  887. }
  888. *pCurConnection = NULL; // set the last connection to NULL;
  889. // now autosync these puppies
  890. hr = PrivAutoSyncOnConnection(dwSyncFlags,ulConnectionCount,pConnections,NULL);
  891. if (pLanConnection)
  892. {
  893. FREE(pLanConnection);
  894. }
  895. if (pRasConn)
  896. {
  897. pNetApi->FreeWanConnections(pRasConn);
  898. }
  899. if (pConnections)
  900. {
  901. FREE(pConnections);
  902. }
  903. }
  904. }
  905. g_InAutoSync = FALSE;
  906. if ( pNetApi )
  907. pNetApi->Release();
  908. return hr;
  909. }
  910. //+---------------------------------------------------------------------------
  911. //
  912. // Member: CSynchronizeInvoke::PrivAutoSyncOnConnection, private
  913. //
  914. // Synopsis: Handles an AutoSync Update. Given the SyncFlags and Connection
  915. // determines if anything should be done on this connection
  916. // and if so invokes it.
  917. //
  918. // Arguments: [dwSyncFlags] - SyncFlags to pass onto initialize
  919. // [ppConnectionNames] - array of connectnames that apply to this request
  920. //
  921. // Returns: Appropriate error codes
  922. //
  923. // Modifies:
  924. //
  925. // History: 08-Dec-97 rogerg Created.
  926. //
  927. //----------------------------------------------------------------------------
  928. STDMETHODIMP CSynchronizeInvoke::PrivAutoSyncOnConnection(DWORD dwSyncFlags,DWORD cbNumConnectionNames,
  929. TCHAR **ppConnectionNames,HANDLE hRasPendingEvent)
  930. {
  931. CONNECTIONSETTINGS ConnectSettings;
  932. DWORD dwSyncEvent;
  933. TCHAR **ppWorkerConnectionNames = NULL;
  934. DWORD cbNumWorkerConnections = 0;
  935. DWORD cbIndexCheck;
  936. DWORD dwPromptMeFirst = 0;
  937. ULONG ulIdleRetryMinutes;
  938. ULONG ulDelayIdleShutDownTime;
  939. BOOL fRetryEnabled = FALSE;
  940. HRESULT hr = S_FALSE;
  941. // assert there is at least one connection in the request
  942. Assert(ppConnectionNames && cbNumConnectionNames >= 1);
  943. if (NULL == ppConnectionNames || 0 == cbNumConnectionNames )
  944. return S_FALSE;
  945. ppWorkerConnectionNames = (TCHAR **) ALLOC(sizeof(TCHAR**) * cbNumConnectionNames);
  946. if (NULL == ppWorkerConnectionNames)
  947. {
  948. return E_OUTOFMEMORY;
  949. }
  950. dwSyncEvent = (dwSyncFlags & SYNCMGRFLAG_EVENTMASK);
  951. // loop through all the connections and move any of the ones that
  952. // are valid into our ppWorkerConnections name array.
  953. TCHAR **ppCurWorkerConnectionNamesIndex = ppWorkerConnectionNames;
  954. TCHAR **ppConnectionsNameIndex = ppConnectionNames;
  955. for (cbIndexCheck = 0; cbIndexCheck < cbNumConnectionNames; cbIndexCheck++)
  956. {
  957. StringCchCopy(ConnectSettings.pszConnectionName, ARRAYSIZE(ConnectSettings.pszConnectionName), *ppConnectionsNameIndex);
  958. // See if should do anything on this connection.
  959. if (RegGetSyncSettings(SYNCMGRFLAG_IDLE == dwSyncEvent
  960. ? SYNCTYPE_IDLE : SYNCTYPE_AUTOSYNC,&ConnectSettings))
  961. {
  962. if ( (((SYNCMGRFLAG_CONNECT == dwSyncEvent) && ConnectSettings.dwLogon))
  963. ||(((SYNCMGRFLAG_PENDINGDISCONNECT == dwSyncEvent) && ConnectSettings.dwLogoff))
  964. ||(((SYNCMGRFLAG_IDLE == dwSyncEvent) && ConnectSettings.dwIdleEnabled))
  965. )
  966. {
  967. *ppCurWorkerConnectionNamesIndex = *ppConnectionsNameIndex;
  968. ++ppCurWorkerConnectionNamesIndex;
  969. ++cbNumWorkerConnections;
  970. // update the variables for connection, for autosync if dwPromptMeFirst
  971. // is set on any match connection
  972. switch (dwSyncEvent)
  973. {
  974. case SYNCMGRFLAG_IDLE:
  975. // minimum retry idle values win.
  976. if ( (1 == cbNumWorkerConnections) || (ConnectSettings.ulIdleRetryMinutes < ulIdleRetryMinutes) )
  977. {
  978. ulIdleRetryMinutes = ConnectSettings.ulIdleRetryMinutes;
  979. }
  980. // maximum wait for shutdown wins.
  981. if ( (1 == cbNumWorkerConnections) || (ConnectSettings.ulDelayIdleShutDownTime > ulDelayIdleShutDownTime) )
  982. {
  983. ulDelayIdleShutDownTime = ConnectSettings.ulDelayIdleShutDownTime;
  984. }
  985. // if any connection has retry after xxx minutes set to bool then retry
  986. if (ConnectSettings.dwRepeatSynchronization)
  987. {
  988. fRetryEnabled = TRUE;
  989. }
  990. break;
  991. case SYNCMGRFLAG_PENDINGDISCONNECT:
  992. case SYNCMGRFLAG_CONNECT:
  993. // if any connection is set to prompt then prompt.
  994. if (ConnectSettings.dwPromptMeFirst)
  995. {
  996. dwPromptMeFirst = ConnectSettings.dwPromptMeFirst;
  997. }
  998. break;
  999. }
  1000. }
  1001. }
  1002. ++ppConnectionsNameIndex;
  1003. }
  1004. // if we found any connections to actually do work on start the sync off.
  1005. if (cbNumWorkerConnections > 0)
  1006. {
  1007. DWORD dwInvokeFlag = 0;
  1008. switch (dwSyncEvent)
  1009. {
  1010. case SYNCMGRFLAG_IDLE:
  1011. dwInvokeFlag |= SYNCMGRINVOKE_MINIMIZED | SYNCMGRINVOKE_STARTSYNC;
  1012. break;
  1013. case SYNCMGRFLAG_PENDINGDISCONNECT:
  1014. case SYNCMGRFLAG_CONNECT:
  1015. if (!dwPromptMeFirst)
  1016. {
  1017. dwInvokeFlag |= SYNCMGRINVOKE_STARTSYNC;
  1018. }
  1019. break;
  1020. default:
  1021. AssertSz(0,"Unknown SyncEvent");
  1022. break;
  1023. }
  1024. // perform the Update
  1025. hr = PrivUpdateAll(dwInvokeFlag,dwSyncFlags,0,NULL,
  1026. cbNumWorkerConnections,
  1027. ppWorkerConnectionNames,NULL,FALSE,hRasPendingEvent,
  1028. ulIdleRetryMinutes,
  1029. ulDelayIdleShutDownTime,fRetryEnabled);
  1030. }
  1031. if (ppWorkerConnectionNames)
  1032. {
  1033. FREE(ppWorkerConnectionNames);
  1034. }
  1035. return hr;
  1036. }
  1037. // default Unknown implementation
  1038. //+---------------------------------------------------------------------------
  1039. //
  1040. // Member: CSynchronizeInvoke::CPrivUnknown::QueryInterface, public
  1041. //
  1042. // Synopsis: Standard QueryInterface
  1043. //
  1044. // Arguments: [iid] - Interface ID
  1045. // [ppvObj] - Object return
  1046. //
  1047. // Returns: Appropriate status code
  1048. //
  1049. // Modifies: [ppvObj]
  1050. //
  1051. // History: 05-Nov-97 rogerg Created.
  1052. //
  1053. //----------------------------------------------------------------------------
  1054. STDMETHODIMP CSynchronizeInvoke::CPrivUnknown::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1055. {
  1056. *ppv = NULL;
  1057. if (IsEqualIID(riid, IID_IUnknown))
  1058. {
  1059. *ppv = this;
  1060. }
  1061. else if (IsEqualIID(riid, IID_IPrivSyncMgrSynchronizeInvoke))
  1062. {
  1063. *ppv = (IPrivSyncMgrSynchronizeInvoke *) m_pSynchInvoke;
  1064. }
  1065. #ifdef _SENS
  1066. else if (IsEqualIID(riid, IID_ISensNetwork))
  1067. {
  1068. *ppv = (ISensNetwork *) &(m_pSynchInvoke->m_PrivSensNetwork);
  1069. }
  1070. else if (IsEqualIID(riid, IID_ISensLogon))
  1071. {
  1072. *ppv = (ISensLogon *) &(m_pSynchInvoke->m_PrivSensLogon);
  1073. }
  1074. // in final this shouldn't return anything until LCE change, change
  1075. // depending on which interface we want to test.
  1076. else if (IsEqualIID(riid, IID_IDispatch))
  1077. {
  1078. *ppv = &(m_pSynchInvoke->m_PrivSensLogon);
  1079. }
  1080. #endif // _SENS
  1081. if (*ppv)
  1082. {
  1083. m_pSynchInvoke->m_pUnkOuter->AddRef();
  1084. return S_OK;
  1085. }
  1086. return E_NOINTERFACE;
  1087. }
  1088. //+---------------------------------------------------------------------------
  1089. //
  1090. // Member: CSynchronizeInvoke::CPrivUnknown::AddRef, public
  1091. //
  1092. // Synopsis: Add reference
  1093. //
  1094. // History: 05-Nov-97 rogerg Created.
  1095. //
  1096. //----------------------------------------------------------------------------
  1097. STDMETHODIMP_(ULONG) CSynchronizeInvoke::CPrivUnknown::AddRef()
  1098. {
  1099. ULONG cRefs;
  1100. cRefs = InterlockedIncrement((LONG *)& m_pSynchInvoke->m_cRef);
  1101. return cRefs;
  1102. }
  1103. //+---------------------------------------------------------------------------
  1104. //
  1105. // Member: CSychrononizeInvoke::CPrivUnknown::Release, public
  1106. //
  1107. // Synopsis: Release reference
  1108. //
  1109. // History: 05-Nov-97 rogerg Created.
  1110. //
  1111. //----------------------------------------------------------------------------
  1112. STDMETHODIMP_(ULONG) CSynchronizeInvoke::CPrivUnknown::Release()
  1113. {
  1114. ULONG cRefs;
  1115. cRefs = InterlockedDecrement( (LONG *) &m_pSynchInvoke->m_cRef);
  1116. if (0 == cRefs)
  1117. {
  1118. delete m_pSynchInvoke;
  1119. }
  1120. return cRefs;
  1121. }
  1122. #ifdef _SENS
  1123. // SENS Network connect Interfaces
  1124. STDMETHODIMP CSynchronizeInvoke::CPrivSensNetwork::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1125. {
  1126. return m_pSynchInvoke->m_pUnkOuter->QueryInterface(riid,ppv);
  1127. }
  1128. //+---------------------------------------------------------------------------
  1129. //
  1130. // Member: CSynchronizeInvoke::AddRef, public
  1131. //
  1132. // Synopsis: Add reference
  1133. //
  1134. // History: 05-Nov-97 rogerg Created.
  1135. //
  1136. //----------------------------------------------------------------------------
  1137. STDMETHODIMP_(ULONG) CSynchronizeInvoke::CPrivSensNetwork::AddRef()
  1138. {
  1139. return m_pSynchInvoke->m_pUnkOuter->AddRef();
  1140. }
  1141. //+---------------------------------------------------------------------------
  1142. //
  1143. // Member: CSychrononizeInvoke::Release, public
  1144. //
  1145. // Synopsis: Release reference
  1146. //
  1147. // History: 05-Nov-97 rogerg Created.
  1148. //
  1149. //----------------------------------------------------------------------------
  1150. STDMETHODIMP_(ULONG) CSynchronizeInvoke::CPrivSensNetwork::Release()
  1151. {
  1152. return m_pSynchInvoke->m_pUnkOuter->Release();
  1153. }
  1154. STDMETHODIMP
  1155. CSynchronizeInvoke::CPrivSensNetwork::GetTypeInfoCount(
  1156. UINT *pCountITypeInfo
  1157. )
  1158. {
  1159. *pCountITypeInfo = 1;
  1160. return S_OK;
  1161. }
  1162. STDMETHODIMP
  1163. CSynchronizeInvoke::CPrivSensNetwork::GetTypeInfo(
  1164. UINT iTypeInfo,
  1165. LCID lcid,
  1166. ITypeInfo **ppITypeInfo
  1167. )
  1168. {
  1169. HRESULT hr;
  1170. if (iTypeInfo)
  1171. {
  1172. return DISP_E_BADINDEX;
  1173. }
  1174. if (S_OK == (hr = m_pSynchInvoke->GetNetworkTypeInfo()))
  1175. {
  1176. // if got a typelib addref it and hand it out.
  1177. m_pSynchInvoke->m_pITypeInfoNetwork->AddRef();
  1178. *ppITypeInfo = m_pSynchInvoke->m_pITypeInfoNetwork;
  1179. }
  1180. return hr;
  1181. }
  1182. STDMETHODIMP
  1183. CSynchronizeInvoke::CPrivSensNetwork::GetIDsOfNames(
  1184. REFIID riid,
  1185. LPOLESTR *arrNames,
  1186. UINT cNames,
  1187. LCID lcid,
  1188. DISPID *arrDispIDs)
  1189. {
  1190. HRESULT hr;
  1191. if (S_OK == (hr = m_pSynchInvoke->GetNetworkTypeInfo()))
  1192. {
  1193. hr = m_pSynchInvoke->m_pITypeInfoNetwork->GetIDsOfNames(
  1194. arrNames,
  1195. cNames,
  1196. arrDispIDs
  1197. );
  1198. }
  1199. return hr;
  1200. }
  1201. STDMETHODIMP
  1202. CSynchronizeInvoke::CPrivSensNetwork::Invoke(
  1203. DISPID dispID,
  1204. REFIID riid,
  1205. LCID lcid,
  1206. WORD wFlags,
  1207. DISPPARAMS *pDispParams,
  1208. VARIANT *pvarResult,
  1209. EXCEPINFO *pExecpInfo,
  1210. UINT *puArgErr
  1211. )
  1212. {
  1213. HRESULT hr;
  1214. if (S_OK == (hr = m_pSynchInvoke->GetNetworkTypeInfo()))
  1215. {
  1216. hr = m_pSynchInvoke->m_pITypeInfoNetwork->Invoke(
  1217. (IDispatch*) this,
  1218. dispID,
  1219. wFlags,
  1220. pDispParams,
  1221. pvarResult,
  1222. pExecpInfo,
  1223. puArgErr);
  1224. }
  1225. return hr;
  1226. }
  1227. STDMETHODIMP
  1228. CSynchronizeInvoke::CPrivSensNetwork::ConnectionMade(
  1229. BSTR bstrConnection,
  1230. ULONG ulType,
  1231. LPSENS_QOCINFO pQOCInfo
  1232. )
  1233. {
  1234. HRESULT hr = E_UNEXPECTED;
  1235. TCHAR pszConnectionName[RAS_MaxEntryName + 1];
  1236. TCHAR *pConnectionNameArray;
  1237. if (g_InAutoSync) // Review logic, for now if in logon just return.
  1238. {
  1239. return S_OK;
  1240. }
  1241. RegSetUserDefaults(); // Make Sure the UserDefaults are up to date
  1242. // if Lan connection use our hardcoded value, else use the
  1243. // connection name given to use.
  1244. if (ulType & NETWORK_ALIVE_LAN)
  1245. {
  1246. LoadString(g_hInst, IDS_LAN_CONNECTION, pszConnectionName,ARRAYSIZE(pszConnectionName));
  1247. }
  1248. else
  1249. {
  1250. StringCchCopy(pszConnectionName, ARRAYSIZE(pszConnectionName), bstrConnection);
  1251. }
  1252. pConnectionNameArray = pszConnectionName;
  1253. if (pszConnectionName)
  1254. {
  1255. hr = m_pSynchInvoke->PrivAutoSyncOnConnection(SYNCMGRFLAG_CONNECT | SYNCMGRFLAG_MAYBOTHERUSER,1,
  1256. &pConnectionNameArray,
  1257. NULL);
  1258. }
  1259. return hr;
  1260. }
  1261. //
  1262. // CODE REVIEW:
  1263. // NOTENOTE:
  1264. // Can we remove this function ?
  1265. STDMETHODIMP
  1266. CSynchronizeInvoke::CPrivSensNetwork::ConnectionMadeNoQOCInfo(
  1267. BSTR bstrConnection,
  1268. ULONG ulType
  1269. )
  1270. {
  1271. /*
  1272. AssertSz(0,"ConnectionMadeNoQOCInfo called");
  1273. TCHAR *pszConnectionName = bstrConnection;
  1274. // m_pSynchInvoke->PrivAutoSyncOnConnection(SYNCMGRFLAG_CONNECT,pszConnectionName,
  1275. // NULL);
  1276. */
  1277. return S_OK;
  1278. }
  1279. STDMETHODIMP
  1280. CSynchronizeInvoke::CPrivSensNetwork::ConnectionLost(
  1281. BSTR bstrConnection,
  1282. ULONG ulType
  1283. )
  1284. {
  1285. return S_OK;
  1286. }
  1287. STDMETHODIMP
  1288. CSynchronizeInvoke::CPrivSensNetwork::BeforeDisconnect(
  1289. BSTR bstrConnection,
  1290. ULONG ulType
  1291. )
  1292. {
  1293. return S_OK;
  1294. }
  1295. STDMETHODIMP
  1296. CSynchronizeInvoke::CPrivSensNetwork::DestinationReachable(
  1297. BSTR bstrDestination,
  1298. BSTR bstrConnection,
  1299. ULONG ulType,
  1300. LPSENS_QOCINFO pQOCInfo
  1301. )
  1302. {
  1303. return S_OK;
  1304. }
  1305. STDMETHODIMP
  1306. CSynchronizeInvoke::CPrivSensNetwork::DestinationReachableNoQOCInfo(
  1307. BSTR bstrDestination,
  1308. BSTR bstrConnection,
  1309. ULONG ulType
  1310. )
  1311. {
  1312. return S_OK;
  1313. }
  1314. // ISensLogon/Logoff Events
  1315. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  1316. {
  1317. return m_pSynchInvoke->m_pUnkOuter->QueryInterface(riid,ppv);
  1318. }
  1319. //+---------------------------------------------------------------------------
  1320. //
  1321. // Member: CSynchronizeInvoke::AddRef, public
  1322. //
  1323. // Synopsis: Add reference
  1324. //
  1325. // History: 05-Nov-97 rogerg Created.
  1326. //
  1327. //----------------------------------------------------------------------------
  1328. STDMETHODIMP_(ULONG) CSynchronizeInvoke::CPrivSensLogon::AddRef()
  1329. {
  1330. return m_pSynchInvoke->m_pUnkOuter->AddRef();
  1331. }
  1332. //+---------------------------------------------------------------------------
  1333. //
  1334. // Member: CSychrononizeInvoke::Release, public
  1335. //
  1336. // Synopsis: Release reference
  1337. //
  1338. // History: 05-Nov-97 rogerg Created.
  1339. //
  1340. //----------------------------------------------------------------------------
  1341. STDMETHODIMP_(ULONG) CSynchronizeInvoke::CPrivSensLogon::Release()
  1342. {
  1343. return m_pSynchInvoke->m_pUnkOuter->Release();
  1344. }
  1345. STDMETHODIMP
  1346. CSynchronizeInvoke::CPrivSensLogon::GetTypeInfoCount(
  1347. UINT *pCountITypeInfo
  1348. )
  1349. {
  1350. *pCountITypeInfo = 1;
  1351. return S_OK;
  1352. }
  1353. STDMETHODIMP
  1354. CSynchronizeInvoke::CPrivSensLogon::GetTypeInfo(
  1355. UINT iTypeInfo,
  1356. LCID lcid,
  1357. ITypeInfo **ppITypeInfo
  1358. )
  1359. {
  1360. HRESULT hr;
  1361. if (iTypeInfo)
  1362. {
  1363. return DISP_E_BADINDEX;
  1364. }
  1365. if (S_OK == (hr = m_pSynchInvoke->GetLogonTypeInfo()))
  1366. {
  1367. // if got a typelib addref it and hand it out.
  1368. m_pSynchInvoke->m_pITypeInfoLogon->AddRef();
  1369. *ppITypeInfo = m_pSynchInvoke->m_pITypeInfoLogon;
  1370. }
  1371. return hr;
  1372. }
  1373. STDMETHODIMP
  1374. CSynchronizeInvoke::CPrivSensLogon::GetIDsOfNames(
  1375. REFIID riid,
  1376. LPOLESTR *arrNames,
  1377. UINT cNames,
  1378. LCID lcid,
  1379. DISPID *arrDispIDs)
  1380. {
  1381. HRESULT hr;
  1382. if (S_OK == (hr = m_pSynchInvoke->GetLogonTypeInfo()))
  1383. {
  1384. hr = m_pSynchInvoke->m_pITypeInfoLogon->GetIDsOfNames(
  1385. arrNames,
  1386. cNames,
  1387. arrDispIDs
  1388. );
  1389. }
  1390. return hr;
  1391. }
  1392. STDMETHODIMP
  1393. CSynchronizeInvoke::CPrivSensLogon::Invoke(
  1394. DISPID dispID,
  1395. REFIID riid,
  1396. LCID lcid,
  1397. WORD wFlags,
  1398. DISPPARAMS *pDispParams,
  1399. VARIANT *pvarResult,
  1400. EXCEPINFO *pExecpInfo,
  1401. UINT *puArgErr
  1402. )
  1403. {
  1404. HRESULT hr;
  1405. if (S_OK == (hr = m_pSynchInvoke->GetLogonTypeInfo()))
  1406. {
  1407. hr = m_pSynchInvoke->m_pITypeInfoLogon->Invoke(
  1408. (IDispatch*) this,
  1409. dispID,
  1410. wFlags,
  1411. pDispParams,
  1412. pvarResult,
  1413. pExecpInfo,
  1414. puArgErr);
  1415. }
  1416. return hr;
  1417. }
  1418. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::Logon(BSTR bstrUserName)
  1419. {
  1420. m_pSynchInvoke->Logon();
  1421. return S_OK;
  1422. }
  1423. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::Logoff(BSTR bstrUserName)
  1424. {
  1425. m_pSynchInvoke->Logoff();
  1426. return S_OK;
  1427. }
  1428. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::Startup(BSTR bstrUserName)
  1429. {
  1430. return S_OK;
  1431. }
  1432. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::StartShell(BSTR bstrUserName)
  1433. {
  1434. return S_OK;
  1435. }
  1436. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::Shutdown(BSTR bstrUserName)
  1437. {
  1438. return S_OK;
  1439. }
  1440. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::DisplayLock(BSTR bstrUserName)
  1441. {
  1442. return S_OK;
  1443. }
  1444. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::DisplayUnlock(BSTR bstrUserName)
  1445. {
  1446. return S_OK;
  1447. }
  1448. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::StartScreenSaver(BSTR bstrUserName)
  1449. {
  1450. return S_OK;
  1451. }
  1452. STDMETHODIMP CSynchronizeInvoke::CPrivSensLogon::StopScreenSaver(BSTR bstrUserName)
  1453. {
  1454. return S_OK;
  1455. }
  1456. //+---------------------------------------------------------------------------
  1457. //
  1458. // Member: CSynchronizeInvoke::GetLogonTypeInfo, private
  1459. //
  1460. // Synopsis: Loads the TypeInfo object for the Sens
  1461. // Logon Information.
  1462. //
  1463. // Arguments:
  1464. //
  1465. // Returns: S_OK if successfully loaded the TypeInfo.
  1466. //
  1467. // Modifies:
  1468. //
  1469. // History: 05-Nov-97 rogerg Created.
  1470. //
  1471. //+---------------------------------------------------------------------------
  1472. STDMETHODIMP CSynchronizeInvoke::GetLogonTypeInfo()
  1473. {
  1474. HRESULT hr;
  1475. ITypeLib *pITypeLib;
  1476. if (m_pITypeInfoLogon)
  1477. return S_OK;
  1478. hr = LoadRegTypeLib(
  1479. LIBID_SensEvents,
  1480. 1 /* MAJOR_VER */ ,
  1481. 0 /* MINOR_VER */ ,
  1482. 0 /* DEFAULT_LCID */,
  1483. &pITypeLib
  1484. );
  1485. if (S_OK == hr)
  1486. {
  1487. hr = pITypeLib->GetTypeInfoOfGuid(
  1488. IID_ISensLogon,
  1489. &m_pITypeInfoLogon
  1490. );
  1491. pITypeLib->Release();
  1492. }
  1493. if (S_OK != hr)
  1494. {
  1495. m_pITypeInfoLogon = NULL; // don't rely on call not to leave this alone.
  1496. }
  1497. return hr;
  1498. }
  1499. //+---------------------------------------------------------------------------
  1500. //
  1501. // Member: CSynchronizeInvoke::GetNetworkTypeInfo, private
  1502. //
  1503. // Synopsis: Loads the TypeInfo object for the Sens
  1504. // Network Information.
  1505. //
  1506. // Arguments:
  1507. //
  1508. // Returns: S_OK if successfully loaded the TypeInfo.
  1509. //
  1510. // Modifies:
  1511. //
  1512. // History: 05-Nov-97 rogerg Created.
  1513. //
  1514. //+---------------------------------------------------------------------------
  1515. STDMETHODIMP CSynchronizeInvoke::GetNetworkTypeInfo()
  1516. {
  1517. HRESULT hr;
  1518. ITypeLib *pITypeLib;
  1519. if (m_pITypeInfoNetwork)
  1520. return S_OK;
  1521. hr = LoadRegTypeLib(
  1522. LIBID_SensEvents,
  1523. 1 /* MAJOR_VER */ ,
  1524. 0 /* MINOR_VER */ ,
  1525. 0 /* DEFAULT_LCID */,
  1526. &pITypeLib
  1527. );
  1528. if (S_OK == hr)
  1529. {
  1530. hr = pITypeLib->GetTypeInfoOfGuid(
  1531. IID_ISensNetwork,
  1532. &m_pITypeInfoNetwork
  1533. );
  1534. pITypeLib->Release();
  1535. }
  1536. if (S_OK != hr)
  1537. {
  1538. m_pITypeInfoNetwork = NULL; // don't rely on call not to leave this alone.
  1539. }
  1540. return hr;
  1541. }
  1542. #endif // _SENS