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.

2365 lines
56 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: sfolder.cxx
  7. //
  8. // Contents: Implementation of IShellFolder for Job Folders
  9. //
  10. // Classes: CJobFolder::IShellFolder members
  11. //
  12. // Functions:
  13. //
  14. // History: 1/4/1996 RaviR Created
  15. // 1-23-1997 DavidMun Destroy notify window upon receiving
  16. // DVM_WINDOWDESTROY
  17. //
  18. //____________________________________________________________________________
  19. #include "..\pch\headers.hxx"
  20. #pragma hdrstop
  21. #include "dbg.h"
  22. #include "macros.h"
  23. #include "resource.h"
  24. #include "..\schedui\rc.h"
  25. #include "jobidl.hxx"
  26. #include "jobfldr.hxx"
  27. #include "policy.hxx"
  28. #include "..\schedui\timeutil.hxx"
  29. #include "..\schedui\schedui.hxx"
  30. #include "util.hxx"
  31. #include "..\inc\defines.hxx"
  32. #include "..\inc\misc.hxx"
  33. #include "..\inc\common.hxx"
  34. #include "atacct.h"
  35. #define JF_FSNOTIFY (WM_USER + 0xA1)
  36. #define STUBM_SETDATA (WM_USER + 0xb1)
  37. #define STUBM_GETDATA (WM_USER + 0xb2)
  38. #define VIEW_ICON_MENU_ID 28713
  39. #define VIEW_SMALLICON_MENU_ID 28714
  40. #define VIEW_LIST_MENU_ID 28715
  41. #define VIEW_DETAILS_MENU_ID 28716
  42. //
  43. // extern
  44. //
  45. extern HINSTANCE g_hInstance;
  46. extern "C" UINT g_cfJobIDList;
  47. HRESULT
  48. JFGetShellDetails(
  49. HWND hwnd,
  50. LPVOID* ppvObj);
  51. HRESULT
  52. JFGetFolderContextMenu(
  53. HWND hwnd,
  54. CJobFolder * pCJobFolder,
  55. LPVOID * ppvObj);
  56. HRESULT
  57. JFGetDataObject(
  58. LPCTSTR pszFolderPath,
  59. LPCITEMIDLIST pidlFolder,
  60. UINT cidl,
  61. LPCITEMIDLIST * apidl,
  62. BOOL fCut,
  63. LPVOID * ppvObj);
  64. HRESULT
  65. JFGetItemContextMenu(
  66. HWND hwnd,
  67. ITaskScheduler * pScheduler,
  68. LPCTSTR ptszMachine,
  69. LPCTSTR pszFolderPath,
  70. LPCITEMIDLIST pidlFolder,
  71. UINT cidl,
  72. LPCITEMIDLIST* apidl,
  73. LPVOID * ppvOut);
  74. HRESULT
  75. JFGetExtractIcon(
  76. LPVOID * ppvObj,
  77. LPCTSTR pszFolderPath,
  78. LPCITEMIDLIST pidl);
  79. #ifdef UNICODE
  80. HRESULT
  81. JFGetExtractIconA(
  82. LPVOID * ppvObj,
  83. LPCTSTR pszFolderPath,
  84. LPCITEMIDLIST pidl);
  85. #endif // UNICODE
  86. HRESULT
  87. JFGetEnumIDList(
  88. ULONG uFlags,
  89. LPCTSTR pszFolderPath,
  90. IEnumWorkItems * pEnumJobs,
  91. LPVOID * ppvObj);
  92. HRESULT
  93. JFCreateNewQueue(
  94. HWND hwnd);
  95. void
  96. OnViewLog(
  97. LPTSTR lpMachineName,
  98. HWND hwndOwner);
  99. HRESULT
  100. GetSchSvcState(
  101. DWORD &dwCurrState);
  102. HRESULT
  103. StopScheduler(void);
  104. HRESULT
  105. StartScheduler(void);
  106. BOOL
  107. UserCanChangeService(
  108. LPCTSTR ptszServer);
  109. HRESULT
  110. PromptForServiceStart(
  111. HWND hwnd);
  112. HRESULT
  113. PauseScheduler(
  114. BOOL fPause);
  115. #if !defined(_CHICAGO_)
  116. VOID
  117. SecurityErrorDialog(
  118. HWND hWndOwner,
  119. HRESULT hr);
  120. VOID
  121. GetDefaultDomainAndUserName(
  122. LPTSTR ptszDomainAndUserName,
  123. ULONG cchBuf);
  124. #endif // !defined(_CHICAGO_)
  125. //
  126. // local funcs
  127. //
  128. HWND
  129. I_CreateNotifyWnd(void);
  130. int
  131. LocaleStrCmp(LPCTSTR ptsz1, LPCTSTR ptsz2);
  132. //____________________________________________________________________________
  133. //
  134. // Member: CJobFolder::ParseDisplayName
  135. //____________________________________________________________________________
  136. STDMETHODIMP
  137. CJobFolder::ParseDisplayName(
  138. HWND hwndOwner,
  139. LPBC pbcReserved,
  140. LPOLESTR lpszDisplayName,
  141. ULONG * pchEaten,
  142. LPITEMIDLIST * ppidl,
  143. ULONG * pdwAttributes)
  144. {
  145. TRACE(CJobFolder, ParseDisplayName);
  146. return E_NOTIMPL;
  147. }
  148. //____________________________________________________________________________
  149. //
  150. // Member: CJobFolder::EnumObjects
  151. //
  152. // Arguments: [hwndOwner] -- IN
  153. // [grfFlags] -- IN
  154. // [ppenumIDList] -- OUT
  155. //
  156. // Returns: HRESULT.
  157. //
  158. // History: 1/5/1996 RaviR Created
  159. //
  160. //____________________________________________________________________________
  161. STDMETHODIMP
  162. CJobFolder::EnumObjects(
  163. HWND hwndOwner,
  164. DWORD grfFlags,
  165. LPENUMIDLIST* ppenumUnknown)
  166. {
  167. DEBUG_OUT((DEB_USER12, "CJobFolder::EnumObjects<%x>\n", this));
  168. *ppenumUnknown = NULL;
  169. //
  170. // We dont support folders.
  171. //
  172. if (!(grfFlags & SHCONTF_NONFOLDERS))
  173. {
  174. return E_FAIL;
  175. }
  176. //
  177. // Get the IDList enumerator
  178. //
  179. HRESULT hr = S_OK;
  180. if (m_pScheduler == NULL)
  181. {
  182. hr = _InitRest();
  183. CHECK_HRESULT(hr);
  184. }
  185. IEnumWorkItems * pEnumJobs = NULL;
  186. if (SUCCEEDED(hr))
  187. {
  188. hr = m_pScheduler->Enum(&pEnumJobs);
  189. CHECK_HRESULT(hr);
  190. if (SUCCEEDED(hr))
  191. {
  192. hr = JFGetEnumIDList(grfFlags, m_pszFolderPath,
  193. pEnumJobs, (LPVOID*)ppenumUnknown);
  194. CHECK_HRESULT(hr);
  195. pEnumJobs->Release();
  196. }
  197. }
  198. return hr;
  199. }
  200. //____________________________________________________________________________
  201. //
  202. // Member: CJobFolder::BindToObject
  203. //____________________________________________________________________________
  204. STDMETHODIMP
  205. CJobFolder::BindToObject(
  206. LPCITEMIDLIST pidl,
  207. LPBC pbcReserved,
  208. REFIID riid,
  209. LPVOID* ppvOut)
  210. {
  211. TRACE(CJobFolder, BindToObject);
  212. // Job folder doesn't contain sub-folders
  213. return E_NOTIMPL;
  214. }
  215. //____________________________________________________________________________
  216. //
  217. // Member: CJobFolder::BindToStorage
  218. //
  219. // Note: not used in Win95
  220. //____________________________________________________________________________
  221. STDMETHODIMP
  222. CJobFolder::BindToStorage(
  223. LPCITEMIDLIST pidl,
  224. LPBC pbcReserved,
  225. REFIID riid,
  226. LPVOID* ppvObj)
  227. {
  228. TRACE(CJobFolder, BindToStorage);
  229. *ppvObj = NULL;
  230. return E_NOTIMPL;
  231. }
  232. //____________________________________________________________________________
  233. //
  234. // Member: CJobFolder::CompareIDs
  235. //
  236. // Arguments: [lParam] -- IN
  237. // [pidl1] -- IN
  238. // [pidl2] -- IN
  239. //
  240. // Returns: HRESULT.
  241. //
  242. // History: 1/5/1996 RaviR Created
  243. //
  244. //____________________________________________________________________________
  245. STDMETHODIMP
  246. CJobFolder::CompareIDs(
  247. LPARAM lCol,
  248. LPCITEMIDLIST pidl1,
  249. LPCITEMIDLIST pidl2)
  250. {
  251. DEBUG_OUT((DEB_USER12, "CJobFolder::CompareIDs<%d>\n", lCol));
  252. HRESULT hr = S_OK;
  253. int iCmp;
  254. if (JF_IsValidID(pidl1) == FALSE || JF_IsValidID(pidl2) == FALSE)
  255. {
  256. return E_INVALIDARG;
  257. }
  258. PJOBID pjid1 = (PJOBID)pidl1;
  259. PJOBID pjid2 = (PJOBID)pidl2;
  260. //
  261. // Ensure that the template object is always first
  262. //
  263. if (pjid1->IsTemplate() && pjid2->IsTemplate())
  264. {
  265. return S_OK; // equal
  266. }
  267. if (pjid1->IsTemplate())
  268. {
  269. return ResultFromShort(-1);
  270. }
  271. if (pjid2->IsTemplate())
  272. {
  273. return ResultFromShort(1);
  274. }
  275. switch (lCol)
  276. {
  277. case COLUMN_LASTRUNTIME:
  278. iCmp = CompareSystemTime(pjid1->GetLastRunTime(),
  279. pjid2->GetLastRunTime());
  280. break;
  281. case COLUMN_NEXTRUNTIME:
  282. {
  283. TCHAR buff1[MAX_PATH];
  284. TCHAR buff2[MAX_PATH];
  285. LPTSTR psz1, psz2;
  286. psz1 = pjid1->GetNextRunTimeString(buff1, MAX_PATH, TRUE);
  287. psz2 = pjid2->GetNextRunTimeString(buff2, MAX_PATH, TRUE);
  288. if (psz1 != NULL)
  289. {
  290. if (psz2 != NULL)
  291. {
  292. iCmp = LocaleStrCmp(psz1, psz2);
  293. }
  294. else
  295. {
  296. iCmp = 1;
  297. }
  298. }
  299. else
  300. {
  301. if (psz2 != NULL)
  302. {
  303. iCmp = -1;
  304. }
  305. else
  306. {
  307. iCmp = CompareSystemTime(pjid1->GetNextRunTime(),
  308. pjid2->GetNextRunTime());
  309. }
  310. }
  311. break;
  312. }
  313. case COLUMN_SCHEDULE:
  314. {
  315. TCHAR tszTrig1[SCH_XBIGBUF_LEN];
  316. TCHAR tszTrig2[SCH_XBIGBUF_LEN];
  317. if (pjid1->IsJobFlagOn(TASK_FLAG_DISABLED) == TRUE)
  318. {
  319. LoadString(g_hInstance, IDS_DISABLED, tszTrig1, SCH_XBIGBUF_LEN);
  320. }
  321. else
  322. {
  323. hr = GetTriggerStringFromTrigger(&pjid1->GetTrigger(),
  324. tszTrig1, SCH_XBIGBUF_LEN, NULL);
  325. BREAK_ON_FAIL(hr);
  326. }
  327. if (pjid2->IsJobFlagOn(TASK_FLAG_DISABLED) == TRUE)
  328. {
  329. LoadString(g_hInstance, IDS_DISABLED, tszTrig2, SCH_XBIGBUF_LEN);
  330. }
  331. else
  332. {
  333. hr = GetTriggerStringFromTrigger(&pjid2->GetTrigger(),
  334. tszTrig2, SCH_XBIGBUF_LEN, NULL);
  335. BREAK_ON_FAIL(hr);
  336. }
  337. iCmp = LocaleStrCmp(tszTrig1, tszTrig2);
  338. break;
  339. }
  340. case COLUMN_STATUS:
  341. {
  342. iCmp = pjid1->_status - pjid2->_status;
  343. break;
  344. }
  345. case COLUMN_NAME:
  346. // Fall through
  347. default:
  348. DEBUG_OUT((DEB_USER12, "CompareIDs<%ws, %ws>\n", pjid1->GetName(),
  349. pjid2->GetName()));
  350. iCmp = LocaleStrCmp(pjid1->GetName(), pjid2->GetName());
  351. break;
  352. #if !defined(_CHICAGO_)
  353. case COLUMN_LASTEXITCODE:
  354. iCmp = pjid1->GetExitCode() - pjid2->GetExitCode();
  355. break;
  356. case COLUMN_CREATOR:
  357. iCmp = LocaleStrCmp(pjid1->GetCreator(), pjid2->GetCreator());
  358. break;
  359. #endif // !defined(_CHICAGO_)
  360. }
  361. if (SUCCEEDED(hr))
  362. {
  363. hr = ResultFromShort(iCmp);
  364. }
  365. return hr;
  366. }
  367. //+---------------------------------------------------------------------------
  368. //
  369. // Function: LocaleStrCmp
  370. //
  371. // Synopsis: Do a case insensitive string compare that is safe for any
  372. // locale.
  373. //
  374. // Arguments: [ptsz1] - strings to compare
  375. // [ptsz2]
  376. //
  377. // Returns: -1, 0, or 1 just like lstrcmpi
  378. //
  379. // History: 10-28-96 DavidMun Created
  380. //
  381. // Notes: This is slower than lstrcmpi, but will work when sorting
  382. // strings even in Japanese.
  383. //
  384. //----------------------------------------------------------------------------
  385. int
  386. LocaleStrCmp(LPCTSTR ptsz1, LPCTSTR ptsz2)
  387. {
  388. int iRet;
  389. iRet = CompareString(LOCALE_USER_DEFAULT,
  390. NORM_IGNORECASE |
  391. NORM_IGNOREKANATYPE |
  392. NORM_IGNOREWIDTH,
  393. ptsz1,
  394. -1,
  395. ptsz2,
  396. -1);
  397. if (iRet)
  398. {
  399. iRet -= 2; // convert to lstrcmpi-style return -1, 0, or 1
  400. }
  401. else
  402. {
  403. DEBUG_OUT_LASTERROR;
  404. }
  405. return iRet;
  406. }
  407. //____________________________________________________________________________
  408. //
  409. // Member: CJobFolder::CreateViewObject
  410. //
  411. // Arguments: [hwndOwner] -- IN
  412. // [riid] -- IN
  413. // [ppvOut] -- IN
  414. //
  415. // Returns: HRESULT.
  416. //
  417. // History: 1/5/1996 RaviR Created
  418. //
  419. //____________________________________________________________________________
  420. STDMETHODIMP
  421. CJobFolder::CreateViewObject(
  422. HWND hwndOwner,
  423. REFIID riid,
  424. LPVOID* ppvOut)
  425. {
  426. TRACE(CJobFolder, CreateViewObject);
  427. HRESULT hr = S_OK;
  428. m_hwndOwner = hwndOwner;
  429. *ppvOut = NULL;
  430. if (m_pszFolderPath == NULL)
  431. {
  432. hr = _InitRest();
  433. CHECK_HRESULT(hr);
  434. if (FAILED(hr))
  435. {
  436. return hr;
  437. }
  438. }
  439. if (IsEqualIID(riid, IID_IShellView))
  440. {
  441. CSFV csfv =
  442. {
  443. sizeof(CSFV), // cbSize
  444. (IShellFolder*)this, // pshf
  445. NULL, // psvOuter
  446. m_pidlFldr, // pidl to monitor
  447. 0, // events
  448. s_JobsFVCallBack, // pfnCallback
  449. FVM_DETAILS
  450. };
  451. IShellView * pShellView;
  452. if (SUCCEEDED(hr))
  453. {
  454. hr = SHCreateShellFolderViewEx(&csfv, &pShellView);
  455. CHECK_HRESULT(hr);
  456. }
  457. if (SUCCEEDED(hr))
  458. {
  459. m_pShellView = pShellView;
  460. // WARNING: Do not AddRef m_pShellView this will cause
  461. // a cyclic addref. Use DVM_RELEASE in callback to know
  462. // whem m_pShellView is destroyed.
  463. }
  464. *ppvOut = (LPVOID)m_pShellView;
  465. }
  466. else if (IsEqualIID(riid, IID_IShellDetails))
  467. {
  468. hr = JFGetShellDetails(hwndOwner, ppvOut);
  469. }
  470. else if (IsEqualIID(riid, IID_IContextMenu))
  471. {
  472. hr = JFGetFolderContextMenu(hwndOwner, this, ppvOut);
  473. }
  474. else if (IsEqualIID(riid, IID_IDropTarget))
  475. {
  476. hr = this->QueryInterface(IID_IDropTarget, ppvOut);
  477. }
  478. else
  479. {
  480. hr = E_NOINTERFACE;
  481. CHECK_HRESULT(hr);
  482. }
  483. return hr;
  484. }
  485. //____________________________________________________________________________
  486. //
  487. // Member: CJobFolder::GetAttributesOf
  488. //
  489. // Arguments: [cidl] -- IN
  490. // [apidl] -- IN
  491. // [rgfInOut] -- IN
  492. //
  493. // Returns: HRESULT.
  494. //
  495. // History: 1/5/1996 RaviR Created
  496. // 5-09-1997 DavidMun handle template object
  497. //
  498. //____________________________________________________________________________
  499. STDMETHODIMP
  500. CJobFolder::GetAttributesOf(
  501. UINT cidl,
  502. LPCITEMIDLIST* apidl,
  503. ULONG* rgfInOut)
  504. {
  505. // TRACE(CJobFolder, GetAttributesOf);
  506. //
  507. // Three cases:
  508. //
  509. // a. list contains only non-template object(s)
  510. // b. list contains only a template object
  511. // c. list contains template object plus non-template object(s)
  512. //
  513. // For cases b and c, no operations are allowed, since the
  514. // template object is not a real object.
  515. //
  516. ULONG rgfMask;
  517. if (ContainsTemplateObject(cidl, apidl))
  518. {
  519. rgfMask = 0;
  520. }
  521. else
  522. {
  523. //
  524. // Policy - creation, deletion are regulated
  525. //
  526. rgfMask = 0;
  527. //
  528. // If no DRAG and DROP restriction, then it ok to copy.
  529. // read it once, for efficiency's sake.
  530. //
  531. BOOL fDragDropRestricted = RegReadPolicyKey(TS_KEYPOLICY_DENY_DRAGDROP);
  532. BOOL fDeleteRestricted = RegReadPolicyKey(TS_KEYPOLICY_DENY_DELETE);
  533. if (! fDragDropRestricted)
  534. {
  535. rgfMask |= SFGAO_CANCOPY;
  536. }
  537. if ((! fDeleteRestricted) && (! fDragDropRestricted))
  538. {
  539. // If allowed deletion, then move or delete is okay
  540. rgfMask |= SFGAO_CANMOVE;
  541. if (! RegReadPolicyKey(TS_KEYPOLICY_DENY_CREATE_TASK))
  542. {
  543. //
  544. // If allowed creation, as well, then rename is okay
  545. // Note we consider a RENAME both a create and a delete
  546. //
  547. rgfMask |= SFGAO_CANRENAME;
  548. }
  549. }
  550. if (! fDeleteRestricted)
  551. {
  552. rgfMask |= SFGAO_CANDELETE;
  553. }
  554. if ((cidl == 1) && (! RegReadPolicyKey(TS_KEYPOLICY_DENY_PROPERTIES)))
  555. {
  556. // no multi-select property sheets
  557. rgfMask |= SFGAO_HASPROPSHEET;
  558. }
  559. }
  560. *rgfInOut &= rgfMask;
  561. return S_OK;
  562. }
  563. //____________________________________________________________________________
  564. //
  565. // Member: CJobFolder::GetUIObjectOf
  566. //
  567. // Arguments: [hwndOwner] -- IN
  568. // [cidl] -- IN
  569. // [apidl] -- IN
  570. // [riid] -- IN
  571. // [prgfInOut] -- IN
  572. // [ppvOut] -- IN
  573. //
  574. // Returns: STDMETHODIMP
  575. //
  576. // History: 1/5/1996 RaviR Created
  577. //
  578. //____________________________________________________________________________
  579. STDMETHODIMP
  580. CJobFolder::GetUIObjectOf(
  581. HWND hwndOwner,
  582. UINT cidl,
  583. LPCITEMIDLIST* apidl,
  584. REFIID riid,
  585. UINT* prgfInOut,
  586. LPVOID* ppvOut)
  587. {
  588. TRACE(CJobFolder, GetUIObjectOf);
  589. if( NULL == apidl )
  590. {
  591. return E_INVALIDARG;
  592. }
  593. PJOBID pjid = (PJOBID)apidl[0];
  594. if (cidl < 1)
  595. {
  596. return E_INVALIDARG;
  597. }
  598. if (JF_IsValidID(apidl[0]) == FALSE)
  599. {
  600. return E_INVALIDARG;
  601. }
  602. HRESULT hr = E_NOINTERFACE;
  603. *ppvOut = NULL;
  604. if (cidl == 1 && IsEqualIID(riid, IID_IExtractIcon))
  605. {
  606. hr = JFGetExtractIcon(ppvOut, m_pszFolderPath, apidl[0]);
  607. }
  608. #ifdef UNICODE
  609. else if (cidl == 1 && IsEqualIID(riid, IID_IExtractIconA))
  610. {
  611. hr = JFGetExtractIconA(ppvOut, m_pszFolderPath, apidl[0]);
  612. }
  613. #endif // UNICODE
  614. else if (IsEqualIID(riid, IID_IContextMenu))
  615. {
  616. if (m_pszFolderPath == NULL)
  617. {
  618. hr = _InitRest();
  619. CHECK_HRESULT(hr);
  620. if (FAILED(hr))
  621. {
  622. return hr;
  623. }
  624. }
  625. hr = JFGetItemContextMenu(hwndOwner,
  626. m_pScheduler,
  627. m_pszMachine,
  628. m_pszFolderPath,
  629. m_pidlFldr,
  630. cidl,
  631. apidl,
  632. ppvOut);
  633. }
  634. else if (cidl > 0 && IsEqualIID(riid, IID_IDataObject))
  635. {
  636. DEBUG_OUT((DEB_USER1, "[GetUIObjectOf] IDataObject \n"));
  637. BOOL fCut = (GetKeyState(VK_CONTROL) >= 0);
  638. //
  639. // Policy - if DRAGDROP or DELETE and we are here,
  640. // we must be doing a cut or copy op and cannot allow it
  641. //
  642. if (RegReadPolicyKey(TS_KEYPOLICY_DENY_DRAGDROP) ||
  643. (fCut && RegReadPolicyKey(TS_KEYPOLICY_DENY_DELETE)))
  644. {
  645. return E_NOINTERFACE;
  646. }
  647. DEBUG_OUT((DEB_USER12, "fCut<%d>\n", fCut));
  648. hr = JFGetDataObject(m_pszFolderPath,
  649. m_pidlFldr,
  650. cidl,
  651. apidl,
  652. fCut,
  653. ppvOut);
  654. }
  655. return hr;
  656. }
  657. //____________________________________________________________________________
  658. //
  659. // Member: CJobFolder::GetDisplayNameOf
  660. //
  661. // Arguments: [pidl] -- IN
  662. // [uFlags] -- IN
  663. // [lpName] -- IN
  664. //
  665. // Returns: HRESULT.
  666. //
  667. // History: 1/5/1996 RaviR Created
  668. //
  669. //____________________________________________________________________________
  670. STDMETHODIMP
  671. CJobFolder::GetDisplayNameOf(
  672. LPCITEMIDLIST pidl,
  673. DWORD uFlags,
  674. LPSTRRET lpName)
  675. {
  676. TRACE(CJobFolder, GetDisplayNameOf);
  677. DEBUG_OUT((DEB_USER12, "CJobFolder::GetDisplayNameOf<uFlags = %d>\n", uFlags));
  678. if (JF_IsValidID(pidl) == FALSE)
  679. {
  680. return E_INVALIDARG;
  681. }
  682. PJOBID pjid = (PJOBID)pidl;
  683. LPTSTR ptszToReturn;
  684. TCHAR tszFullPath[MAX_PATH + 1];
  685. //
  686. // If the display name is to be used for parsing, return the full path to
  687. // the file. This is used by rshx32.dll when we request that it add the
  688. // security page for a file.
  689. //
  690. if (uFlags & SHGDN_FORPARSING)
  691. {
  692. //
  693. // If we don't have the folder path, complete the initialization to
  694. // get it.
  695. //
  696. if (m_pszFolderPath == NULL)
  697. {
  698. HRESULT hr = _InitRest();
  699. CHECK_HRESULT(hr);
  700. if (FAILED(hr))
  701. {
  702. return hr;
  703. }
  704. }
  705. wsprintf(tszFullPath,
  706. TEXT("%s\\%s.") TSZ_JOB,
  707. m_pszFolderPath,
  708. pjid->GetName());
  709. ptszToReturn = tszFullPath;
  710. DEBUG_OUT((DEB_TRACE,
  711. "CJobFolder::GetDisplayNameOf: Returning path '%S'\n",
  712. ptszToReturn));
  713. }
  714. else
  715. {
  716. ptszToReturn = pjid->GetName();
  717. }
  718. UINT uiByteLen = (lstrlen(ptszToReturn) + 1) * sizeof(TCHAR);
  719. #ifdef UNICODE
  720. lpName->uType = STRRET_WSTR;
  721. lpName->pOleStr = (LPWSTR) SHAlloc(uiByteLen);
  722. if (NULL == lpName->pOleStr)
  723. {
  724. return E_OUTOFMEMORY;
  725. }
  726. CopyMemory(lpName->pOleStr, ptszToReturn, uiByteLen);
  727. #else // ANSI
  728. lpName->uType = STRRET_CSTR;
  729. lstrcpy(lpName->cStr, ptszToReturn);
  730. #endif
  731. return NOERROR;
  732. }
  733. //____________________________________________________________________________
  734. //
  735. // Member: CJobFolder::SetNameOf
  736. //
  737. // Arguments: [hwndOwner] -- IN
  738. // [pidl] -- IN
  739. // [lpszName] -- IN
  740. // [uFlags] -- IN
  741. // [ppidlOut] -- IN
  742. //
  743. // Returns: STDMETHODIMP
  744. //
  745. // History: 1/5/1996 RaviR Created
  746. //
  747. //____________________________________________________________________________
  748. STDMETHODIMP
  749. CJobFolder::SetNameOf(
  750. HWND hwndOwner,
  751. LPCITEMIDLIST pidl,
  752. LPCOLESTR lpszName,
  753. DWORD uFlags,
  754. LPITEMIDLIST* ppidlOut)
  755. {
  756. TRACE(CJobFolder, SetNameOf);
  757. HRESULT hr = S_OK;
  758. if (JF_IsValidID(pidl) == FALSE)
  759. {
  760. return E_INVALIDARG;
  761. }
  762. PJOBID pjidOld = (PJOBID)pidl;
  763. DEBUG_ASSERT(!pjidOld->IsTemplate());
  764. if (ppidlOut != NULL)
  765. {
  766. *ppidlOut = NULL;
  767. }
  768. CJobID jidNew;
  769. jidNew.Rename(*pjidOld, lpszName);
  770. //
  771. // Change the file name
  772. //
  773. TCHAR szOldFile[MAX_PATH + 2];
  774. TCHAR szNewFile[MAX_PATH + 2];
  775. BOOL fRet;
  776. lstrcpy(szOldFile, m_pszFolderPath);
  777. lstrcat(szOldFile, TEXT("\\"));
  778. lstrcat(szOldFile, pjidOld->GetPath());
  779. lstrcat(szOldFile, TSZ_DOTJOB);
  780. lstrcpy(szNewFile, m_pszFolderPath);
  781. lstrcat(szNewFile, TEXT("\\"));
  782. lstrcat(szNewFile, jidNew.GetName());
  783. lstrcat(szNewFile, TSZ_DOTJOB);
  784. DEBUG_OUT((DEB_USER1, "Rename %ws to %ws\n", szOldFile, szNewFile));
  785. SHFILEOPSTRUCT fo;
  786. fo.hwnd = m_hwndOwner;
  787. fo.wFunc = FO_RENAME;
  788. fo.pFrom = szOldFile;
  789. fo.pTo = szNewFile;
  790. fo.fFlags = FOF_ALLOWUNDO;
  791. fo.fAnyOperationsAborted = FALSE;
  792. fo.hNameMappings = NULL;
  793. fo.lpszProgressTitle = NULL;
  794. // Make sure we have double trailing NULL!
  795. *(szOldFile + lstrlen(szOldFile) + 1) = TEXT('\0');
  796. *(szNewFile + lstrlen(szNewFile) + 1) = TEXT('\0');
  797. if ((SHFileOperation(&fo) !=0) || fo.fAnyOperationsAborted == TRUE)
  798. {
  799. hr = E_FAIL;
  800. CHECK_HRESULT(hr);
  801. return hr;
  802. }
  803. return hr;
  804. }
  805. #if DBG==1
  806. void JFDbgOutCallbackMsg(UINT uMsg);
  807. #endif // DBG==1
  808. //____________________________________________________________________________
  809. //
  810. // Member: CJobFolder::s_JobsFVCallBack, static
  811. //
  812. // Arguments: [psvOuter] -- IN
  813. // [psf] -- IN
  814. // [hwndOwner] -- IN
  815. // [uMsg] -- IN
  816. // [wParam] -- IN
  817. // [lParam] -- IN
  818. //
  819. // Returns: HRESULT
  820. //
  821. // History: 1/5/1996 RaviR Created
  822. //
  823. //____________________________________________________________________________
  824. HRESULT CALLBACK
  825. CJobFolder::s_JobsFVCallBack(
  826. LPSHELLVIEW psvOuter,
  827. LPSHELLFOLDER psf,
  828. HWND hwndOwner,
  829. UINT uMsg,
  830. WPARAM wParam,
  831. LPARAM lParam)
  832. {
  833. CJobFolder *pCJobFolder = (CJobFolder *)psf;
  834. return pCJobFolder->_JobsFVCallBack(psvOuter, psf, hwndOwner,
  835. uMsg, wParam, lParam);
  836. }
  837. #if !defined(_CHICAGO_)
  838. //+---------------------------------------------------------------------------
  839. //
  840. // Function: EnableAtAccountControls
  841. //
  842. // Synopsis: Enable or disable the account and password controls in the
  843. // at account dialog.
  844. //
  845. // Arguments: [hDlg] - handle to dialog
  846. // [fEnable] - TRUE = enable, FALSE = disable
  847. //
  848. // History: 09-19-96 DavidMun Created
  849. //
  850. //----------------------------------------------------------------------------
  851. VOID
  852. EnableAtAccountControls(HWND hDlg, BOOL fEnable)
  853. {
  854. EnableWindow(GetDlgItem(hDlg, IDD_AT_CUSTOM_ACCT_NAME), fEnable);
  855. EnableWindow(GetDlgItem(hDlg, IDD_AT_PASSWORD), fEnable);
  856. EnableWindow(GetDlgItem(hDlg, IDD_AT_CONFIRM_PASSWORD), fEnable);
  857. }
  858. //+---------------------------------------------------------------------------
  859. //
  860. // Function: InitAtAccountDlg
  861. //
  862. // Synopsis: Initialize the controls in the at account dialog
  863. //
  864. // Arguments: [hDlg] - handle to dialog
  865. //
  866. // History: 09-19-96 DavidMun Created
  867. //
  868. //----------------------------------------------------------------------------
  869. VOID
  870. InitAtAccountDlg(HWND hDlg)
  871. {
  872. HRESULT hr;
  873. WCHAR wszAccount[MAX_USERNAME + 1];
  874. DWORD cchAccount = MAX_USERNAME + 1;
  875. //
  876. // Limit the length of account and password edit controls, and init the
  877. // password controls to stars just like the task account dialog does.
  878. //
  879. SendDlgItemMessage(hDlg,
  880. IDD_AT_CUSTOM_ACCT_NAME,
  881. EM_LIMITTEXT,
  882. MAX_USERNAME,
  883. 0);
  884. SendDlgItemMessage(hDlg,
  885. IDD_AT_PASSWORD,
  886. EM_LIMITTEXT,
  887. MAX_PASSWORD,
  888. 0);
  889. SendDlgItemMessage(hDlg,
  890. IDD_AT_CONFIRM_PASSWORD,
  891. EM_LIMITTEXT,
  892. MAX_PASSWORD,
  893. 0);
  894. //
  895. // Ask the service for the current at account information. Menu item for
  896. // this dialog should be disabled if service isn't running, so this should
  897. // succeed. If this fails, we can't expect the Set api to work, so
  898. // complain and bail.
  899. //
  900. hr = GetNetScheduleAccountInformation(NULL, cchAccount, wszAccount);
  901. if (SUCCEEDED(hr))
  902. {
  903. if (hr == S_FALSE)
  904. {
  905. // running as local system
  906. CheckDlgButton(hDlg, IDD_AT_USE_SYSTEM, BST_CHECKED);
  907. EnableAtAccountControls(hDlg, FALSE);
  908. }
  909. else
  910. {
  911. CheckDlgButton(hDlg, IDD_AT_USE_CUSTOM, BST_CHECKED);
  912. SetDlgItemText(hDlg, IDD_AT_CUSTOM_ACCT_NAME, wszAccount);
  913. EnableAtAccountControls(hDlg, TRUE);
  914. }
  915. }
  916. else
  917. {
  918. SchedUIMessageDialog(hDlg,
  919. IERR_GETATACCOUNT,
  920. MB_OK | MB_ICONEXCLAMATION | MB_TASKMODAL,
  921. NULL);
  922. EndDialog(hDlg, 0);
  923. }
  924. }
  925. //+---------------------------------------------------------------------------
  926. //
  927. // Function: HandleAtAccountChange
  928. //
  929. // Synopsis: Make the At account reflect the current settings in the
  930. // dialog, and end the dialog if successful.
  931. //
  932. // Arguments: [hDlg] - handle to dialog
  933. //
  934. // History: 09-19-96 DavidMun Created
  935. //
  936. //----------------------------------------------------------------------------
  937. VOID
  938. HandleAtAccountChange(HWND hDlg)
  939. {
  940. HRESULT hr = S_OK;
  941. WCHAR wszAccountName[MAX_USERNAME + 1] = TEXT("");
  942. WCHAR wszPassword[MAX_PASSWORD + 1] = TEXT("");
  943. WCHAR wszConfirmedPassword[MAX_PASSWORD + 1] = TEXT("");
  944. do
  945. {
  946. //
  947. // See if user just wants at jobs to run as localsystem
  948. //
  949. if (IsDlgButtonChecked(hDlg, IDD_AT_USE_SYSTEM) == BST_CHECKED)
  950. {
  951. hr = SetNetScheduleAccountInformation(NULL, NULL, wszPassword);
  952. if (FAILED(hr))
  953. {
  954. SecurityErrorDialog(hDlg, hr);
  955. }
  956. else
  957. {
  958. EndDialog(hDlg, 0);
  959. }
  960. break;
  961. }
  962. //
  963. // No, we have to validate account and password controls. Get the
  964. // account name and fail if it's empty.
  965. //
  966. GetDlgItemText(hDlg,
  967. IDD_AT_CUSTOM_ACCT_NAME,
  968. wszAccountName,
  969. MAX_USERNAME + 1);
  970. if (wszAccountName[0] == L'\0')
  971. {
  972. SchedUIErrorDialog(hDlg, IERR_ACCOUNTNAME, (LPTSTR)NULL);
  973. break;
  974. }
  975. //
  976. // Get the passwords and fail if they haven't been changed, or if
  977. // they don't match eachother.
  978. //
  979. GetDlgItemText(hDlg,
  980. IDD_AT_PASSWORD,
  981. wszPassword,
  982. MAX_PASSWORD + 1);
  983. GetDlgItemText(hDlg,
  984. IDD_AT_CONFIRM_PASSWORD,
  985. wszConfirmedPassword,
  986. MAX_PASSWORD + 1);
  987. if (lstrcmp(wszPassword, wszConfirmedPassword) != 0)
  988. {
  989. SchedUIErrorDialog(hDlg, IERR_PASSWORD, (LPTSTR)NULL);
  990. break;
  991. }
  992. //
  993. // Account name and passwords valid (as far as we can tell). Make
  994. // the change to the account.
  995. //
  996. hr = SetNetScheduleAccountInformation(NULL, // local machine
  997. wszAccountName,
  998. wszPassword);
  999. if (FAILED(hr))
  1000. {
  1001. SecurityErrorDialog(hDlg, hr);
  1002. }
  1003. else
  1004. {
  1005. EndDialog(hDlg, 0);
  1006. }
  1007. } while (0);
  1008. }
  1009. //+---------------------------------------------------------------------------
  1010. //
  1011. // Function: SetAtAccountDlgProc
  1012. //
  1013. // Synopsis: Allow the user to specify which account to run AT jobs under
  1014. //
  1015. // Arguments: standard dialog proc
  1016. //
  1017. // Returns: standard dialog proc
  1018. //
  1019. // History: 09-19-96 DavidMun Created
  1020. //
  1021. //----------------------------------------------------------------------------
  1022. INT_PTR APIENTRY
  1023. SetAtAccountDlgProc(
  1024. HWND hDlg,
  1025. UINT uMsg,
  1026. WPARAM wParam,
  1027. LPARAM lParam)
  1028. {
  1029. BOOL fHandled = TRUE;
  1030. //
  1031. // Note: the DWLP_USER long is used as a dirty flag. If the user hits OK
  1032. // without having modified the edit controls or hit the radio buttons,
  1033. // then we'll just treat it as a Cancel if the dirty flag is FALSE.
  1034. //
  1035. switch (uMsg)
  1036. {
  1037. case WM_INITDIALOG:
  1038. InitAtAccountDlg(hDlg);
  1039. SetWindowLongPtr(hDlg, DWLP_USER, FALSE);
  1040. break; // return TRUE so windows will set focus
  1041. case WM_COMMAND:
  1042. switch(LOWORD(wParam))
  1043. {
  1044. case IDD_AT_USE_SYSTEM:
  1045. EnableAtAccountControls(hDlg, FALSE);
  1046. SetWindowLongPtr(hDlg, DWLP_USER, TRUE);
  1047. break;
  1048. case IDD_AT_USE_CUSTOM:
  1049. {
  1050. WCHAR wszUserName[MAX_USERNAME + 1];
  1051. DWORD cchUserName = MAX_USERNAME + 1;
  1052. SetWindowLongPtr(hDlg, DWLP_USER, TRUE);
  1053. //
  1054. // If there's nothing in the user account field, make it default
  1055. // to the logged-on user.
  1056. //
  1057. if (!GetDlgItemText(hDlg,
  1058. IDD_AT_CUSTOM_ACCT_NAME,
  1059. wszUserName,
  1060. cchUserName))
  1061. {
  1062. GetDefaultDomainAndUserName(wszUserName, cchUserName);
  1063. SetDlgItemText(hDlg, IDD_AT_CUSTOM_ACCT_NAME, wszUserName);
  1064. }
  1065. EnableAtAccountControls(hDlg, TRUE);
  1066. break;
  1067. }
  1068. case IDD_AT_CUSTOM_ACCT_NAME:
  1069. case IDD_AT_PASSWORD:
  1070. case IDD_AT_CONFIRM_PASSWORD:
  1071. if (EN_CHANGE == HIWORD(wParam))
  1072. {
  1073. SetWindowLongPtr(hDlg, DWLP_USER, TRUE);
  1074. }
  1075. else
  1076. {
  1077. fHandled = FALSE;
  1078. }
  1079. break;
  1080. case IDOK:
  1081. if (GetWindowLongPtr(hDlg, DWLP_USER))
  1082. {
  1083. //
  1084. // Do NOT clear the dirty flag here--if HandleAtAccountChange
  1085. // is successful, the dialog will end, but if not we need to
  1086. // retain the dirty state.
  1087. //
  1088. CWaitCursor WaitCursor;
  1089. HandleAtAccountChange(hDlg);
  1090. break;
  1091. }
  1092. // else FALL THROUGH
  1093. case IDCANCEL:
  1094. EndDialog(hDlg, wParam);
  1095. break;
  1096. default:
  1097. fHandled = FALSE;
  1098. break;
  1099. }
  1100. break;
  1101. default:
  1102. fHandled = FALSE;
  1103. break;
  1104. }
  1105. return fHandled;
  1106. }
  1107. #endif // !defined(_CHICAGO_)
  1108. //____________________________________________________________________________
  1109. //
  1110. // Member: CJobFolder::_JobsFVCallBack
  1111. //
  1112. // Arguments: [psvOuter] -- IN
  1113. // [psf] -- IN
  1114. // [hwndOwner] -- IN
  1115. // [uMsg] -- IN
  1116. // [wParam] -- IN
  1117. // [lParam] -- IN
  1118. //
  1119. // Returns: HRESULT
  1120. //
  1121. // History: 1/5/1996 RaviR Created
  1122. //
  1123. //____________________________________________________________________________
  1124. HRESULT CALLBACK
  1125. CJobFolder::_JobsFVCallBack(
  1126. LPSHELLVIEW psvOuter,
  1127. LPSHELLFOLDER psf,
  1128. HWND hwndOwner,
  1129. UINT uMsg,
  1130. WPARAM wParam,
  1131. LPARAM lParam)
  1132. {
  1133. DEBUG_OUT((DEB_USER12, "_JobsFVCallBack<uMsg=%d>\n", uMsg));
  1134. HRESULT hr = S_OK;
  1135. LRESULT lr = ERROR_SUCCESS;
  1136. switch(uMsg)
  1137. {
  1138. case DVM_GETCCHMAX:
  1139. {
  1140. UINT * pcchMax = (UINT *)lParam;
  1141. // <folder path> + '\' + cchMax + '.job' + null <= MAX_PATH
  1142. *pcchMax = MAX_PATH - (lstrlen(m_pszFolderPath) + 6);
  1143. break;
  1144. }
  1145. case DVM_DEFITEMCOUNT:
  1146. //
  1147. // If DefView times out enumerating items, let it know we probably only
  1148. // have about 20 items
  1149. //
  1150. *(int *)lParam = 20;
  1151. break;
  1152. case DVM_MERGEMENU:
  1153. {
  1154. m_qcm = *((LPQCMINFO)lParam);
  1155. UtMergeMenu(g_hInstance, POPUP_ADVANCED, POPUP_JOBS_MAIN_POPUPMERGE,
  1156. (LPQCMINFO)lParam);
  1157. break;
  1158. }
  1159. case DVM_INITMENUPOPUP:
  1160. {
  1161. UINT idCmdFirst = LOWORD(wParam);
  1162. UINT nIndex = HIWORD(wParam);
  1163. HMENU hmenu = (HMENU)lParam;
  1164. UINT idCmd = GetMenuItemID(hmenu, 0) - idCmdFirst;
  1165. if (idCmd == FSIDM_STOP_SCHED)
  1166. {
  1167. if (!UserCanChangeService(m_pszMachine))
  1168. {
  1169. //
  1170. // The job folder is on a remote machine, or we're on NT
  1171. // and the user is not an administrator. Disable stop,
  1172. // pause, and at account options and get out.
  1173. //
  1174. EnableMenuItem(hmenu, FSIDM_STOP_SCHED+idCmdFirst,
  1175. MF_DISABLED | MF_GRAYED);
  1176. EnableMenuItem(hmenu, FSIDM_PAUSE_SCHED+idCmdFirst,
  1177. MF_DISABLED | MF_GRAYED);
  1178. EnableMenuItem(hmenu, FSIDM_NOTIFY_MISSED+idCmdFirst,
  1179. MF_DISABLED | MF_GRAYED);
  1180. #if !defined(_CHICAGO_)
  1181. EnableMenuItem(hmenu, FSIDM_AT_ACCOUNT+idCmdFirst,
  1182. MF_DISABLED | MF_GRAYED);
  1183. #endif // !defined(_CHICAGO_)
  1184. break;
  1185. }
  1186. DWORD dwState;
  1187. hr = GetSchSvcState(dwState);
  1188. DEBUG_OUT((DEB_USER1, "Service state = %d\n", dwState));
  1189. if (FAILED(hr))
  1190. {
  1191. dwState = SERVICE_STOPPED;
  1192. }
  1193. UINT uiStartID = IDS_MI_STOP;
  1194. UINT uiPauseID = IDS_MI_PAUSE;
  1195. UINT uiPauseEnable = MFS_ENABLED;
  1196. #define CCH_MENU_TEXT 80
  1197. TCHAR tszStart[CCH_MENU_TEXT];
  1198. TCHAR tszPause[CCH_MENU_TEXT];
  1199. if (dwState == SERVICE_STOPPED ||
  1200. dwState == SERVICE_STOP_PENDING)
  1201. {
  1202. uiStartID = IDS_MI_START;
  1203. uiPauseEnable = MFS_DISABLED;
  1204. }
  1205. else if (dwState == SERVICE_PAUSED ||
  1206. dwState == SERVICE_PAUSE_PENDING)
  1207. {
  1208. uiPauseID = IDS_MI_CONTINUE;
  1209. }
  1210. if (dwState == SERVICE_START_PENDING)
  1211. {
  1212. uiPauseEnable = MFS_DISABLED;
  1213. }
  1214. MENUITEMINFO mii = {0};
  1215. mii.cbSize = sizeof(MENUITEMINFO);
  1216. mii.fMask = MIIM_TYPE;
  1217. LoadString(g_hInstance, uiStartID, tszStart, CCH_MENU_TEXT);
  1218. mii.dwTypeData = tszStart;
  1219. SetMenuItemInfo(hmenu, FSIDM_STOP_SCHED+idCmdFirst, FALSE,
  1220. &mii);
  1221. mii.fMask = MIIM_TYPE | MIIM_STATE;
  1222. LoadString(g_hInstance, uiPauseID, tszPause, CCH_MENU_TEXT);
  1223. mii.dwTypeData = tszPause;
  1224. mii.fState = uiPauseEnable;
  1225. SetMenuItemInfo(hmenu, FSIDM_PAUSE_SCHED+idCmdFirst, FALSE,
  1226. &mii);
  1227. CheckMenuItem(hmenu,
  1228. FSIDM_NOTIFY_MISSED+idCmdFirst,
  1229. g_fNotifyMiss ? MF_CHECKED : MF_UNCHECKED);
  1230. #if !defined(_CHICAGO_)
  1231. EnableMenuItem(hmenu,
  1232. FSIDM_AT_ACCOUNT+idCmdFirst,
  1233. MFS_ENABLED == uiPauseEnable ?
  1234. MF_ENABLED : MF_DISABLED | MF_GRAYED);
  1235. #endif // !defined(_CHICAGO_)
  1236. }
  1237. break;
  1238. }
  1239. case DVM_INVOKECOMMAND:
  1240. {
  1241. HMENU &hmenu = m_qcm.hmenu;
  1242. UINT id = (UINT)wParam + m_qcm.idCmdFirst;
  1243. DWORD dwState;
  1244. hr = GetSchSvcState(dwState);
  1245. if (FAILED(hr))
  1246. {
  1247. dwState = SERVICE_STOPPED;
  1248. }
  1249. switch (wParam)
  1250. {
  1251. case FSIDM_SORTBYNAME:
  1252. ShellFolderView_ReArrange(hwndOwner, COLUMN_NAME);
  1253. break;
  1254. case FSIDM_SORTBYSCHEDULE:
  1255. ShellFolderView_ReArrange(hwndOwner, COLUMN_SCHEDULE);
  1256. break;
  1257. case FSIDM_SORTBYNEXTRUNTIME:
  1258. ShellFolderView_ReArrange(hwndOwner, COLUMN_NEXTRUNTIME);
  1259. break;
  1260. case FSIDM_SORTBYLASTRUNTIME:
  1261. ShellFolderView_ReArrange(hwndOwner, COLUMN_LASTRUNTIME);
  1262. break;
  1263. case FSIDM_SORTBYSTATUS:
  1264. ShellFolderView_ReArrange(hwndOwner, COLUMN_STATUS);
  1265. break;
  1266. #if !defined(_CHICAGO_)
  1267. case FSIDM_SORTBYLASTEXITCODE:
  1268. ShellFolderView_ReArrange(hwndOwner, COLUMN_LASTEXITCODE);
  1269. break;
  1270. case FSIDM_SORTBYCREATOR:
  1271. ShellFolderView_ReArrange(hwndOwner, COLUMN_CREATOR);
  1272. break;
  1273. #endif // !defined(_CHICAGO_)
  1274. case FSIDM_NEWJOB:
  1275. if (UserCanChangeService(m_pszMachine))
  1276. {
  1277. PromptForServiceStart(hwndOwner);
  1278. }
  1279. hr = CreateAJobForApp(NULL);
  1280. break;
  1281. case FSIDM_STOP_SCHED:
  1282. if (dwState == SERVICE_STOPPED ||
  1283. dwState == SERVICE_STOP_PENDING)
  1284. {
  1285. hr = StartScheduler();
  1286. if (FAILED(hr))
  1287. {
  1288. SchedUIErrorDialog(hwndOwner, IERR_STARTSVC, (LPTSTR) NULL);
  1289. }
  1290. }
  1291. else
  1292. {
  1293. hr = StopScheduler();
  1294. if (FAILED(hr))
  1295. {
  1296. SchedUIErrorDialog(hwndOwner, IERR_STOPSVC, (LPTSTR) NULL);
  1297. }
  1298. }
  1299. break;
  1300. case FSIDM_PAUSE_SCHED:
  1301. hr = PauseScheduler(dwState != SERVICE_PAUSED &&
  1302. dwState != SERVICE_PAUSE_PENDING);
  1303. break;
  1304. #if !defined(_CHICAGO_)
  1305. case FSIDM_AT_ACCOUNT:
  1306. DialogBox(g_hInstance,
  1307. MAKEINTRESOURCE(IDD_AT_ACCOUNT_DLG),
  1308. hwndOwner,
  1309. SetAtAccountDlgProc);
  1310. break;
  1311. #endif // !defined(_CHICAGO_)
  1312. case FSIDM_NOTIFY_MISSED:
  1313. {
  1314. LONG lErr;
  1315. HKEY hSchedKey = NULL;
  1316. lErr = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1317. SCH_AGENT_KEY,
  1318. 0,
  1319. KEY_SET_VALUE,
  1320. &hSchedKey);
  1321. if (lErr != ERROR_SUCCESS)
  1322. {
  1323. DEBUG_OUT((DEB_ERROR, "RegOpenKeyEx of Scheduler key %uL\n", lErr));
  1324. break;
  1325. }
  1326. // Toggle the global var state
  1327. g_fNotifyMiss = !g_fNotifyMiss;
  1328. // Persist the change in the registry
  1329. ULONG cbData = sizeof(g_fNotifyMiss);
  1330. lErr = RegSetValueEx(hSchedKey,
  1331. SCH_NOTIFYMISS_VALUE,
  1332. 0,
  1333. REG_DWORD,
  1334. (LPBYTE) &g_fNotifyMiss,
  1335. cbData);
  1336. RegCloseKey(hSchedKey);
  1337. // If the change couldn't be persisted, undo it.
  1338. if (lErr != ERROR_SUCCESS)
  1339. {
  1340. DEBUG_OUT((DEB_ERROR, "RegSetValueEx of notify miss %uL\n", lErr));
  1341. g_fNotifyMiss = !g_fNotifyMiss;
  1342. }
  1343. break;
  1344. }
  1345. case FSIDM_VIEW_LOG:
  1346. OnViewLog(m_pszMachine, hwndOwner);
  1347. break;
  1348. default:
  1349. DEBUG_OUT((DEB_ERROR, "Unknown DVM_INVOKECOMMAND<%u>\n",wParam));
  1350. hr = E_FAIL;
  1351. }
  1352. break;
  1353. }
  1354. case DVM_GETTOOLTIPTEXT:
  1355. case DVM_GETHELPTEXT:
  1356. {
  1357. UINT idCmd = (UINT)LOWORD(wParam);
  1358. UINT cchMax = (UINT)HIWORD(wParam);
  1359. UINT uiToggle = 0;
  1360. LPSTR pszText = (LPSTR)lParam;
  1361. if (idCmd == FSIDM_STOP_SCHED || idCmd == FSIDM_PAUSE_SCHED)
  1362. {
  1363. DWORD dwState;
  1364. hr = GetSchSvcState(dwState);
  1365. if (FAILED(hr))
  1366. {
  1367. dwState = SERVICE_STOPPED;
  1368. }
  1369. if ((dwState == SERVICE_STOPPED ||
  1370. dwState == SERVICE_STOP_PENDING) &&
  1371. idCmd == FSIDM_STOP_SCHED)
  1372. {
  1373. uiToggle = MH_TEXT_TOGGLE;
  1374. }
  1375. else
  1376. {
  1377. if ((dwState == SERVICE_PAUSED ||
  1378. dwState == SERVICE_PAUSE_PENDING) &&
  1379. idCmd == FSIDM_PAUSE_SCHED)
  1380. {
  1381. uiToggle = MH_TEXT_TOGGLE;
  1382. }
  1383. }
  1384. }
  1385. LoadString(g_hInstance, idCmd + IDS_MH_FSIDM_FIRST + uiToggle,
  1386. (LPTSTR)pszText, cchMax);
  1387. break;
  1388. }
  1389. case DVM_DIDDRAGDROP:
  1390. {
  1391. DEBUG_OUT((DEB_USER12, "DVM_DIDDRAGDROP\n"));
  1392. // DWORD dwEffect = wParam;
  1393. // IDataObject * pdtobj = (IDataObject *)lParam;
  1394. //
  1395. // if (!(dwEffect & DROPEFFECT_MOVE))
  1396. // {
  1397. // DEBUG_OUT((DEB_USER1, "DVM_DIDDRAGDROP<Copy>\n"));
  1398. // }
  1399. // else
  1400. // {
  1401. // DEBUG_OUT((DEB_USER1, "DVM_DIDDRAGDROP<Move>\n"));
  1402. // }
  1403. break;
  1404. }
  1405. case DVM_GETWORKINGDIR:
  1406. {
  1407. UINT uMax = (UINT)wParam;
  1408. LPTSTR pszDir = (LPTSTR)lParam;
  1409. lstrcpy(pszDir, m_pszFolderPath);
  1410. break;
  1411. }
  1412. //
  1413. // DVM_INSERTITEM and DVM_DELETEITEM are not processed because the
  1414. // directory change notifications already provide this information.
  1415. //
  1416. // case DVM_INSERTITEM:
  1417. // {
  1418. // PJOBID pjid = (PJOBID)wParam;
  1419. // if (JF_IsValidID((LPCITEMIDLIST)pjid) == TRUE)
  1420. // {
  1421. // DEBUG_OUT((DEB_USER1, "DVM_INSERTITEM <%ws>\n", pjid->GetName()));
  1422. // }
  1423. // break;
  1424. // }
  1425. // case DVM_DELETEITEM:
  1426. // {
  1427. // PDVSELCHANGEINFO psci = (PDVSELCHANGEINFO)lParam;
  1428. //
  1429. // PJOBID pjid = (PJOBID)psci->lParamItem;
  1430. //
  1431. // if (pjid == NULL)
  1432. // {
  1433. // DEBUG_OUT((DEB_USER1, "DVM_DELETEITEM delete all items.\n"));
  1434. // }
  1435. // else if (JF_IsValidID((LPCITEMIDLIST)pjid) == TRUE)
  1436. // {
  1437. // DEBUG_OUT((DEB_USER1, "DVM_DELETEITEM <%ws>\n", pjid->GetName()));
  1438. // }
  1439. // break;
  1440. // }
  1441. case DVM_RELEASE:
  1442. {
  1443. DEBUG_OUT((DEB_USER1, "\tDVM_RELEASE\n"));
  1444. m_pShellView = NULL;
  1445. break;
  1446. }
  1447. case DVM_WINDOWCREATED:
  1448. {
  1449. //
  1450. // If we're opening on the local machine, make sure the sa.dat
  1451. // file is up to date.
  1452. //
  1453. if (!m_pszMachine)
  1454. {
  1455. CheckSaDat(m_pszFolderPath);
  1456. }
  1457. // Save current listview mode
  1458. m_ulListViewModeOnEntry = _GetChildListViewMode(hwndOwner);
  1459. // Register change notifications for the pidl of the Tasks dir
  1460. DEBUG_ASSERT(!m_hwndNotify);
  1461. m_hwndNotify = I_CreateNotifyWnd();
  1462. if (m_hwndNotify == NULL)
  1463. {
  1464. hr = E_OUTOFMEMORY;
  1465. break;
  1466. }
  1467. SendMessage(m_hwndNotify, STUBM_SETDATA, (WPARAM)this, 0);
  1468. if (m_pszFolderPath == NULL)
  1469. {
  1470. hr = _InitRest();
  1471. CHECK_HRESULT(hr);
  1472. BREAK_ON_FAIL(hr);
  1473. }
  1474. LPITEMIDLIST pidl;
  1475. hr = SHILCreateFromPath(m_pszFolderPath, &pidl, NULL);
  1476. CHECK_HRESULT(hr);
  1477. BREAK_ON_FAIL(hr);
  1478. SHChangeNotifyEntry fsne;
  1479. fsne.pidl = pidl;
  1480. fsne.fRecursive = FALSE;
  1481. int fSources = SHCNRF_ShellLevel | SHCNRF_InterruptLevel;
  1482. //| SHCNRF_NewDelivery;
  1483. LONG fEvents = SHCNE_DISKEVENTS | SHCNE_RENAMEITEM | SHCNE_CREATE |
  1484. SHCNE_UPDATEITEM | SHCNE_ATTRIBUTES | SHCNE_DELETE;
  1485. CDll::LockServer(TRUE);
  1486. m_uRegister = SHChangeNotifyRegister(m_hwndNotify, fSources, fEvents,
  1487. JF_FSNOTIFY, 1, &fsne);
  1488. if (!m_uRegister)
  1489. {
  1490. CDll::LockServer(FALSE);
  1491. DEBUG_OUT_LASTERROR;
  1492. }
  1493. break;
  1494. }
  1495. case DVM_WINDOWDESTROY:
  1496. {
  1497. //
  1498. // Restore the listview mode that we found on entry, unless the
  1499. // user has changed away from report mode.
  1500. //
  1501. if (m_ulListViewModeOnEntry != INVALID_LISTVIEW_STYLE &&
  1502. _GetChildListViewMode(hwndOwner) == LVS_REPORT)
  1503. {
  1504. _SetViewMode(hwndOwner, m_ulListViewModeOnEntry);
  1505. }
  1506. if (m_uRegister)
  1507. {
  1508. SHChangeNotifyDeregister(m_uRegister);
  1509. CDll::LockServer(FALSE);
  1510. m_uRegister = 0;
  1511. }
  1512. if (m_hwndNotify)
  1513. {
  1514. BOOL fOk = DestroyWindow(m_hwndNotify);
  1515. m_hwndNotify = NULL;
  1516. if (!fOk)
  1517. {
  1518. DEBUG_OUT_LASTERROR;
  1519. }
  1520. }
  1521. break;
  1522. }
  1523. case SFVM_GETHELPTOPIC:
  1524. {
  1525. SFVM_HELPTOPIC_DATA * phtd = (SFVM_HELPTOPIC_DATA*)lParam;
  1526. StrCpyW(phtd->wszHelpFile, L"mstask.chm");
  1527. break;
  1528. }
  1529. default:
  1530. hr = E_FAIL;
  1531. #if DBG==1
  1532. JFDbgOutCallbackMsg(uMsg);
  1533. #endif // DBG==1
  1534. }
  1535. return hr;
  1536. }
  1537. //+--------------------------------------------------------------------------
  1538. //
  1539. // Member: CJobFolder::_SetViewMode
  1540. //
  1541. // Synopsis: Select the listview mode specified by [ulListViewStyle].
  1542. //
  1543. // Arguments: [hwndOwner] - explorer window handle
  1544. // [ulListViewStyle] - LVS_* in LVS_TYPEMASK.
  1545. //
  1546. // History: 07-25-1997 DavidMun Created
  1547. //
  1548. //---------------------------------------------------------------------------
  1549. void
  1550. CJobFolder::_SetViewMode(
  1551. HWND hwndOwner,
  1552. ULONG ulListViewStyle)
  1553. {
  1554. switch (ulListViewStyle)
  1555. {
  1556. case LVS_ICON:
  1557. PostMessage(hwndOwner, WM_COMMAND, VIEW_ICON_MENU_ID, 0);
  1558. break;
  1559. case LVS_REPORT:
  1560. PostMessage(hwndOwner, WM_COMMAND, VIEW_DETAILS_MENU_ID, 0);
  1561. break;
  1562. case LVS_SMALLICON:
  1563. PostMessage(hwndOwner, WM_COMMAND, VIEW_SMALLICON_MENU_ID, 0);
  1564. break;
  1565. case LVS_LIST:
  1566. PostMessage(hwndOwner, WM_COMMAND, VIEW_LIST_MENU_ID, 0);
  1567. break;
  1568. default:
  1569. DEBUG_OUT((DEB_ERROR,
  1570. "CJobFolder::_SetViewMode: invalid view mode 0x%x\n",
  1571. ulListViewStyle));
  1572. break;
  1573. }
  1574. }
  1575. //+--------------------------------------------------------------------------
  1576. //
  1577. // Function: EnumChildWindowCallback
  1578. //
  1579. // Synopsis: Fill hwnd pointed to by [lParam] with [hwnd] if [hwnd] has
  1580. // class WC_LISTVIEW.
  1581. //
  1582. //
  1583. // Arguments: [hwnd] - window to check
  1584. // [lParam] - pointer to HWND
  1585. //
  1586. // Returns: TRUE - continue enumeration
  1587. // FALSE - [hwnd] is listview, *(HWND*)[lParam] = [hwnd], stop
  1588. // enumerating
  1589. //
  1590. // Modifies: *(HWND*)[lParam]
  1591. //
  1592. // History: 07-25-1997 DavidMun Created
  1593. //
  1594. //---------------------------------------------------------------------------
  1595. BOOL CALLBACK
  1596. EnumChildWindowCallback(
  1597. HWND hwnd,
  1598. LPARAM lParam)
  1599. {
  1600. TCHAR tszClassName[80];
  1601. GetClassName(hwnd, tszClassName, ARRAYLEN(tszClassName));
  1602. if (!lstrcmpi(tszClassName, WC_LISTVIEW))
  1603. {
  1604. *(HWND *)lParam = hwnd;
  1605. return FALSE;
  1606. }
  1607. return TRUE;
  1608. }
  1609. //+--------------------------------------------------------------------------
  1610. //
  1611. // Member: CJobFolder::_GetChildListViewMode
  1612. //
  1613. // Synopsis: Return the LVS_* value representing the mode of the first
  1614. // child listview control found for [hwndOwner].
  1615. //
  1616. // Arguments: [hwndOwner] -
  1617. //
  1618. // Returns: LVS_ICON, LVS_SMALLICON, LVS_REPORT, LVS_LIST, or
  1619. // INVALID_LISTVIEW_STYLE.
  1620. //
  1621. // History: 07-25-1997 DavidMun Created
  1622. //
  1623. //---------------------------------------------------------------------------
  1624. ULONG
  1625. CJobFolder::_GetChildListViewMode(
  1626. HWND hwndOwner)
  1627. {
  1628. HWND hwnd = NULL;
  1629. EnumChildWindows(hwndOwner,
  1630. EnumChildWindowCallback,
  1631. (LPARAM)&hwnd);
  1632. if (!hwnd)
  1633. {
  1634. DEBUG_OUT((DEB_ERROR,
  1635. "_GetChildListViewMode: can't find child listview\n"));
  1636. return INVALID_LISTVIEW_STYLE;
  1637. }
  1638. LONG lStyle = GetWindowLong(hwnd, GWL_STYLE);
  1639. return lStyle & LVS_TYPEMASK;
  1640. }
  1641. BOOL
  1642. CJobFolder::_ObjectAlreadyPresent(
  1643. LPTSTR pszObj)
  1644. {
  1645. BOOL fPresent = FALSE;
  1646. PJOBID pjid;
  1647. LPTSTR pszName = PathFindFileName(pszObj);
  1648. LPTSTR pszExt = PathFindExtension(pszName);
  1649. TCHAR tcSave;
  1650. if (pszExt)
  1651. {
  1652. tcSave = *pszExt;
  1653. *pszExt = TEXT('\0');
  1654. }
  1655. int cObjs = (int) ShellFolderView_GetObjectCount(m_hwndOwner);
  1656. for (int i=0; i < cObjs; i++)
  1657. {
  1658. pjid = (PJOBID)ShellFolderView_GetObject(m_hwndOwner, i);
  1659. if (lstrcmpi(pjid->GetName(), pszName) == 0)
  1660. {
  1661. fPresent = TRUE;
  1662. break;
  1663. }
  1664. }
  1665. if (pszExt)
  1666. {
  1667. *pszExt = tcSave;
  1668. }
  1669. return fPresent;
  1670. }
  1671. LRESULT
  1672. CJobFolder::HandleFsNotify(
  1673. LONG lNotification,
  1674. LPCITEMIDLIST* ppidl)
  1675. {
  1676. HRESULT hr = S_OK;
  1677. CJobID jid;
  1678. LRESULT lr;
  1679. TCHAR from[MAX_PATH];
  1680. TCHAR to[MAX_PATH];
  1681. SHGetPathFromIDList(ppidl[0], from);
  1682. DEBUG_OUT((DEB_USER1, "First pidl<%ws>\n", from));
  1683. switch (lNotification)
  1684. {
  1685. case SHCNE_RENAMEITEM:
  1686. {
  1687. DEBUG_OUT((DEB_USER1, "SHCNE_RENAMEITEM\n"));
  1688. LPTSTR psFrom = PathFindFileName(from) - 1;
  1689. *psFrom = TEXT('\0');
  1690. SHGetPathFromIDList(ppidl[1], to);
  1691. DEBUG_OUT((DEB_USER1, "Second pidl<%ws>\n", to));
  1692. LPTSTR psTo = PathFindFileName(to) - 1;
  1693. *psTo = TEXT('\0');
  1694. BOOL fFromJF = (lstrcmpi(m_pszFolderPath, from) == 0);
  1695. BOOL fToJF = (lstrcmpi(m_pszFolderPath, to) == 0);
  1696. *psFrom = TEXT('\\');
  1697. *psTo = TEXT('\\');
  1698. if (fFromJF == FALSE)
  1699. {
  1700. if (fToJF == FALSE)
  1701. {
  1702. break; // Nothing to do with job folder
  1703. }
  1704. //
  1705. // ADD object
  1706. //
  1707. // First check if this object doesn't already exist in the UI
  1708. if (_ObjectAlreadyPresent(to) == FALSE)
  1709. {
  1710. hr = jid.Load(NULL, to);
  1711. CHECK_HRESULT(hr);
  1712. BREAK_ON_FAIL(hr);
  1713. _AddObject(&jid);
  1714. }
  1715. }
  1716. else
  1717. {
  1718. if (fToJF == TRUE)
  1719. {
  1720. // Rename
  1721. hr = jid.Load(NULL, to);
  1722. CHECK_HRESULT(hr);
  1723. BREAK_ON_FAIL(hr);
  1724. CJobID jidOld;
  1725. jidOld.LoadDummy(PathFindFileName(from));
  1726. hr = _UpdateObject(&jidOld, &jid);
  1727. }
  1728. else
  1729. {
  1730. // Delete
  1731. // Need to create a dummy jobid
  1732. jid.LoadDummy(PathFindFileName(from));
  1733. _RemoveObject(&jid);
  1734. }
  1735. }
  1736. break;
  1737. }
  1738. case SHCNE_CREATE:
  1739. {
  1740. DEBUG_OUT((DEB_USER1, "SHCNE_CREATE\n"));
  1741. if (_ObjectAlreadyPresent(from) == FALSE)
  1742. {
  1743. //
  1744. // Not present, so add it.
  1745. //
  1746. hr = jid.Load(NULL, from);
  1747. if (hr == S_FALSE)
  1748. {
  1749. //
  1750. // Task is hidden. Don't display it.
  1751. //
  1752. break;
  1753. }
  1754. CHECK_HRESULT(hr);
  1755. BREAK_ON_FAIL(hr);
  1756. hr = _AddObject(&jid);
  1757. }
  1758. break;
  1759. }
  1760. case SHCNE_DELETE:
  1761. DEBUG_OUT((DEB_USER1, "SHCNE_DELETE\n"));
  1762. jid.LoadDummy(from);
  1763. _RemoveObject(&jid);
  1764. break;
  1765. case SHCNE_UPDATEDIR:
  1766. DEBUG_OUT((DEB_USER1, "SHCNE_UPDATEDIR\n"));
  1767. this->OnUpdateDir();
  1768. break;
  1769. case SHCNE_UPDATEITEM:
  1770. DEBUG_OUT((DEB_USER1, "SHCNE_UPDATEITEM\n"));
  1771. hr = jid.Load(NULL, from);
  1772. if (hr == S_FALSE)
  1773. {
  1774. //
  1775. // Task is hidden. Don't display it. Always remove from the ID list
  1776. // to take care of the case where this notification was due to the
  1777. // task being hidden.
  1778. //
  1779. _RemoveObject(&jid);
  1780. break;
  1781. }
  1782. CHECK_HRESULT(hr);
  1783. BREAK_ON_FAIL(hr);
  1784. hr = _UpdateObject(&jid, &jid);
  1785. break;
  1786. default:
  1787. DEBUG_OUT((DEB_USER1, "JF_FSNOTIFY unprocessed <0x%x>\n", lNotification));
  1788. #ifdef _CHICAGO_
  1789. wsprintfA(to, "JF_FSNOTIFY unprocessed <0x%x>\n", lNotification);
  1790. DbxDisplay(to);
  1791. #endif
  1792. }
  1793. return 0L;
  1794. }
  1795. LRESULT
  1796. CALLBACK
  1797. NotifyWndProc(
  1798. HWND hWnd,
  1799. UINT iMessage,
  1800. WPARAM wParam,
  1801. LPARAM lParam)
  1802. {
  1803. DEBUG_OUT((DEB_USER12, "NWP<0x%x>\n", iMessage));
  1804. switch (iMessage)
  1805. {
  1806. case STUBM_SETDATA:
  1807. SetWindowLongPtr(hWnd, 0, wParam);
  1808. return TRUE;
  1809. case STUBM_GETDATA:
  1810. return GetWindowLongPtr(hWnd, 0);
  1811. case JF_FSNOTIFY:
  1812. {
  1813. CJobFolder * pjf = (CJobFolder*)GetWindowLongPtr(hWnd, 0);
  1814. if (pjf == NULL)
  1815. {
  1816. DEBUG_OUT((DEB_ERROR, "NotifyWndProc: NULL CJobFolder pointer\n"));
  1817. return FALSE;
  1818. }
  1819. pjf->HandleFsNotify((LONG)lParam, (LPCITEMIDLIST*)wParam);
  1820. return TRUE;
  1821. }
  1822. default:
  1823. return DefWindowProc(hWnd, iMessage, wParam, lParam);
  1824. }
  1825. }
  1826. TCHAR const c_szNotifyWindowClass[] = TEXT("JF Notify Window Class");
  1827. TCHAR const c_szNULL[] = TEXT("");
  1828. HWND
  1829. I_CreateNotifyWnd(void)
  1830. {
  1831. WNDCLASS wndclass;
  1832. if (!GetClassInfo(g_hInstance, c_szNotifyWindowClass, &wndclass))
  1833. {
  1834. wndclass.style = 0;
  1835. wndclass.lpfnWndProc = NotifyWndProc;
  1836. wndclass.cbClsExtra = 0;
  1837. wndclass.cbWndExtra = sizeof(PVOID) * 2;
  1838. wndclass.hInstance = g_hInstance;
  1839. wndclass.hIcon = NULL;
  1840. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  1841. wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  1842. wndclass.lpszMenuName = NULL;
  1843. wndclass.lpszClassName = c_szNotifyWindowClass;
  1844. if (!RegisterClass(&wndclass))
  1845. return NULL;
  1846. }
  1847. return CreateWindowEx(WS_EX_TOOLWINDOW, c_szNotifyWindowClass, c_szNULL,
  1848. WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
  1849. NULL, NULL, g_hInstance, NULL);
  1850. }
  1851. #if DBG==1
  1852. void
  1853. JFDbgOutCallbackMsg(
  1854. UINT uMsg)
  1855. {
  1856. #define PROCESS_MSG(M) \
  1857. case M: DEBUG_OUT((DEB_USER12, "UNPROCESSED msg<%s, %d>\n", #M, M)); break;
  1858. #define DONT_PROCESS_MSG(M) \
  1859. case M: break;
  1860. switch (uMsg)
  1861. {
  1862. DONT_PROCESS_MSG(DVM_GETHELPTEXT)
  1863. DONT_PROCESS_MSG(DVM_GETTOOLTIPTEXT)
  1864. DONT_PROCESS_MSG(DVM_GETBUTTONINFO)
  1865. DONT_PROCESS_MSG(DVM_GETBUTTONS)
  1866. DONT_PROCESS_MSG(DVM_INITMENUPOPUP)
  1867. DONT_PROCESS_MSG(DVM_SELCHANGE)
  1868. PROCESS_MSG(DVM_DRAWITEM)
  1869. DONT_PROCESS_MSG(DVM_MEASUREITEM)
  1870. DONT_PROCESS_MSG(DVM_EXITMENULOOP)
  1871. PROCESS_MSG(DVM_RELEASE)
  1872. DONT_PROCESS_MSG(DVM_GETCCHMAX)
  1873. PROCESS_MSG(DVM_FSNOTIFY)
  1874. DONT_PROCESS_MSG(DVM_WINDOWCREATED)
  1875. DONT_PROCESS_MSG(DVM_WINDOWDESTROY)
  1876. PROCESS_MSG(DVM_REFRESH)
  1877. DONT_PROCESS_MSG(DVM_SETFOCUS)
  1878. DONT_PROCESS_MSG(DVM_KILLFOCUS)
  1879. PROCESS_MSG(DVM_QUERYCOPYHOOK)
  1880. PROCESS_MSG(DVM_NOTIFYCOPYHOOK)
  1881. DONT_PROCESS_MSG(DVM_GETDETAILSOF)
  1882. DONT_PROCESS_MSG(DVM_COLUMNCLICK)
  1883. PROCESS_MSG(DVM_QUERYFSNOTIFY)
  1884. PROCESS_MSG(DVM_DEFITEMCOUNT)
  1885. PROCESS_MSG(DVM_DEFVIEWMODE)
  1886. PROCESS_MSG(DVM_UNMERGEMENU)
  1887. PROCESS_MSG(DVM_INSERTITEM)
  1888. PROCESS_MSG(DVM_DELETEITEM)
  1889. DONT_PROCESS_MSG(DVM_UPDATESTATUSBAR)
  1890. DONT_PROCESS_MSG(DVM_BACKGROUNDENUM)
  1891. PROCESS_MSG(DVM_GETWORKINGDIR)
  1892. DONT_PROCESS_MSG(DVM_GETCOLSAVESTREAM)
  1893. DONT_PROCESS_MSG(DVM_SELECTALL)
  1894. PROCESS_MSG(DVM_DIDDRAGDROP)
  1895. PROCESS_MSG(DVM_FOLDERISPARENT)
  1896. default:
  1897. DEBUG_OUT((DEB_USER12, "UNKNOWN message <%d> !!!!\n", uMsg));
  1898. }
  1899. }
  1900. #endif // DBG==1