Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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