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.

563 lines
12 KiB

  1. //____________________________________________________________________________
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1995 - 1996.
  5. //
  6. // File: jobpages.cxx
  7. //
  8. // Contents:
  9. //
  10. // Classes:
  11. //
  12. // Functions:
  13. //
  14. // History: 3/5/1996 RaviR Created
  15. //
  16. //____________________________________________________________________________
  17. #include "..\pch\headers.hxx"
  18. #pragma hdrstop
  19. #include <mstask.h>
  20. #include "defines.h"
  21. #include "..\inc\resource.h"
  22. #include "..\folderui\dbg.h"
  23. #include "..\folderui\macros.h"
  24. #include "..\folderui\util.hxx"
  25. #include "..\rc.h"
  26. #include "shared.hxx"
  27. #include "schedui.hxx"
  28. #define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
  29. //
  30. // extern EXTERN_C
  31. //
  32. extern HINSTANCE g_hInstance;
  33. //
  34. // Local constants
  35. //
  36. TCHAR const FAR c_szNULL[] = TEXT("");
  37. TCHAR const FAR c_szStubWindowClass[] = TEXT("JobPropWnd");
  38. #define STUBM_SETDATA (WM_USER + 1)
  39. #define STUBM_GETDATA (WM_USER + 2)
  40. #define JF_PROPSHEET_STUB_CLASS 78345
  41. LRESULT
  42. CALLBACK
  43. StubWndProc(
  44. HWND hWnd,
  45. UINT iMessage,
  46. WPARAM wParam,
  47. LPARAM lParam)
  48. {
  49. switch(iMessage)
  50. {
  51. case STUBM_SETDATA:
  52. SetWindowLongPtr(hWnd, 0, wParam);
  53. return TRUE;
  54. case STUBM_GETDATA:
  55. return GetWindowLongPtr(hWnd, 0);
  56. default:
  57. return DefWindowProc(hWnd, iMessage, wParam, lParam);
  58. }
  59. }
  60. HWND I_CreateStubWindow(void)
  61. {
  62. WNDCLASS wndclass;
  63. if (!GetClassInfo(g_hInstance, c_szStubWindowClass, &wndclass))
  64. {
  65. wndclass.style = 0;
  66. wndclass.lpfnWndProc = StubWndProc;
  67. wndclass.cbClsExtra = 0;
  68. wndclass.cbWndExtra = sizeof(PVOID) * 2;
  69. wndclass.hInstance = g_hInstance;
  70. wndclass.hIcon = NULL;
  71. wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
  72. wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);
  73. wndclass.lpszMenuName = NULL;
  74. wndclass.lpszClassName = c_szStubWindowClass;
  75. if (!RegisterClass(&wndclass))
  76. return NULL;
  77. }
  78. return CreateWindowEx(WS_EX_TOOLWINDOW, c_szStubWindowClass, c_szNULL,
  79. WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,
  80. NULL, NULL, g_hInstance, NULL);
  81. }
  82. HANDLE
  83. StuffStubWindow(
  84. HWND hwnd,
  85. LPTSTR pszFile)
  86. {
  87. DWORD dwProcId;
  88. HANDLE hSharedFile;
  89. UINT uiFileSize;
  90. uiFileSize = (lstrlen(pszFile) + 1) * sizeof(TCHAR);
  91. GetWindowThreadProcessId(hwnd, &dwProcId);
  92. hSharedFile = SCHEDAllocShared(NULL, sizeof(int)+uiFileSize, dwProcId);
  93. if (hSharedFile)
  94. {
  95. LPBYTE lpb = (LPBYTE)SCHEDLockShared(hSharedFile, dwProcId);
  96. if (lpb)
  97. {
  98. *(int *)lpb = JF_PROPSHEET_STUB_CLASS;
  99. CopyMemory(lpb+sizeof(int), pszFile, uiFileSize);
  100. SCHEDUnlockShared(lpb);
  101. SendMessage(hwnd, STUBM_SETDATA, (WPARAM)hSharedFile, 0);
  102. return hSharedFile;
  103. }
  104. SCHEDFreeShared(hSharedFile, dwProcId);
  105. }
  106. return NULL;
  107. }
  108. HWND
  109. FindOtherStub(
  110. LPTSTR pszFile)
  111. {
  112. HWND hwnd;
  113. //
  114. // BUGBUG using getwindow in a loop is not safe. this code should
  115. // use EnumWindows instead. From win32 sdk:
  116. //
  117. // "[EnumWindows] is more reliable than calling the GetWindow function in
  118. // a loop. An application that calls GetWindow to perform this task risks
  119. // being caught in an infinite loop or referencing a handle to a window
  120. // that has been destroyed."
  121. //
  122. for (hwnd = FindWindow(c_szStubWindowClass, NULL);
  123. hwnd != NULL;
  124. hwnd = GetWindow(hwnd, GW_HWNDNEXT))
  125. {
  126. TCHAR szClass[80];
  127. // find stub windows only
  128. GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
  129. if (lstrcmpi(szClass, c_szStubWindowClass) == 0)
  130. {
  131. int iClass;
  132. HANDLE hSharedFile;
  133. DWORD dwProcId;
  134. LPTSTR pszTemp;
  135. GetWindowThreadProcessId(hwnd, &dwProcId);
  136. hSharedFile = (HANDLE)SendMessage(hwnd, STUBM_GETDATA, 0, 0);
  137. if (hSharedFile)
  138. {
  139. LPBYTE lpb;
  140. lpb = (LPBYTE)SCHEDLockShared(hSharedFile, dwProcId);
  141. pszTemp = (LPTSTR) (lpb + sizeof(int));
  142. if (lpb)
  143. {
  144. iClass = *(int *)lpb;
  145. if (iClass == JF_PROPSHEET_STUB_CLASS &&
  146. lstrcmpi(pszTemp, pszFile) == 0)
  147. {
  148. SCHEDUnlockShared(lpb);
  149. return hwnd;
  150. }
  151. SCHEDUnlockShared(lpb);
  152. }
  153. }
  154. }
  155. }
  156. return NULL;
  157. }
  158. STDMETHODIMP
  159. I_GetTaskPage(
  160. ITask * pIJob,
  161. TASKPAGE tpType,
  162. BOOL fPersistChanges,
  163. HPROPSHEETPAGE * phPage)
  164. {
  165. TRACE_FUNCTION(I_GetTaskPage);
  166. HRESULT hr = S_OK;
  167. LPOLESTR polestr = NULL;
  168. do
  169. {
  170. //
  171. // Ensure that the object has a file name.
  172. //
  173. IPersistFile * ppf = NULL;
  174. hr = pIJob->QueryInterface(IID_IPersistFile, (void **)&ppf);
  175. CHECK_HRESULT(hr);
  176. BREAK_ON_FAIL(hr);
  177. hr = ppf->GetCurFile(&polestr);
  178. CHECK_HRESULT(hr);
  179. BREAK_ON_FAIL(hr);
  180. ppf->Release();
  181. if (hr == S_FALSE)
  182. {
  183. hr = STG_E_NOTFILEBASEDSTORAGE;
  184. CHECK_HRESULT(hr);
  185. break;
  186. }
  187. //
  188. // Establish if this task exists within a task's folder.
  189. //
  190. LPTSTR ptszJobPath;
  191. #ifdef UNICODE
  192. ptszJobPath = polestr;
  193. #else
  194. TCHAR tszJobPath[MAX_PATH + 1];
  195. hr = UnicodeToAnsi(tszJobPath, polestr, MAX_PATH + 1);
  196. CHECK_HRESULT(hr);
  197. BREAK_ON_FAIL(hr);
  198. ptszJobPath = tszJobPath;
  199. #endif
  200. if (ptszJobPath == NULL)
  201. {
  202. hr = E_OUTOFMEMORY;
  203. CHECK_HRESULT(hr);
  204. break;
  205. }
  206. //
  207. // Get the page
  208. //
  209. switch (tpType)
  210. {
  211. case TASKPAGE_TASK:
  212. {
  213. hr = GetGeneralPage(pIJob, ptszJobPath, fPersistChanges, phPage);
  214. CHECK_HRESULT(hr);
  215. break;
  216. }
  217. case TASKPAGE_SCHEDULE:
  218. hr = GetSchedulePage(pIJob, ptszJobPath, fPersistChanges, phPage);
  219. CHECK_HRESULT(hr);
  220. break;
  221. case TASKPAGE_SETTINGS:
  222. hr = GetSettingsPage(pIJob, ptszJobPath, fPersistChanges, phPage);
  223. CHECK_HRESULT(hr);
  224. break;
  225. default:
  226. hr = E_INVALIDARG;
  227. CHECK_HRESULT(hr);
  228. break;
  229. }
  230. } while (0);
  231. if (polestr != NULL)
  232. {
  233. CoTaskMemFree(polestr);
  234. }
  235. return hr;
  236. }
  237. HRESULT
  238. DisplayJobProperties(
  239. LPDATAOBJECT pdtobj)
  240. {
  241. TRACE_FUNCTION(DisplayJobProperties);
  242. HRESULT hr = S_OK;
  243. HANDLE hSharedFile = NULL;
  244. HWND hwnd = NULL;
  245. ITask * pIJob = NULL;
  246. do
  247. {
  248. //
  249. // Extract the job name from the data object.
  250. //
  251. STGMEDIUM stgm;
  252. FORMATETC fmte = {CF_HDROP, (DVTARGETDEVICE *)NULL,
  253. DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
  254. hr = pdtobj->GetData(&fmte, &stgm);
  255. CHECK_HRESULT(hr);
  256. BREAK_ON_FAIL(hr);
  257. TCHAR szFile[MAX_PATH];
  258. UINT cchRet = DragQueryFile((HDROP)stgm.hGlobal, 0, szFile, MAX_PATH);
  259. ReleaseStgMedium(&stgm);
  260. if (cchRet == 0)
  261. {
  262. return E_FAIL;
  263. }
  264. //
  265. // See if the property page for this job is already being displayed.
  266. //
  267. if (NULL != (hwnd = FindOtherStub(szFile)))
  268. {
  269. SwitchToThisWindow(GetLastActivePopup(hwnd), TRUE);
  270. break;
  271. }
  272. else
  273. {
  274. hwnd = I_CreateStubWindow();
  275. hSharedFile = StuffStubWindow(hwnd, szFile);
  276. }
  277. //
  278. // Bind to the ITask interface.
  279. //
  280. hr = JFCreateAndLoadTask(NULL, szFile, &pIJob);
  281. BREAK_ON_FAIL(hr);
  282. LPTSTR pName = PathFindFileName(szFile);
  283. LPTSTR pExt = PathFindExtension(pName);
  284. if (pExt)
  285. {
  286. *pExt = TEXT('\0');
  287. }
  288. //
  289. // Add the pages.
  290. //
  291. HPROPSHEETPAGE ahpage[MAX_PROP_PAGES];
  292. PROPSHEETHEADER psh;
  293. ZeroMemory(&psh, sizeof(psh));
  294. psh.dwSize = sizeof(PROPSHEETHEADER);
  295. psh.dwFlags = PSH_DEFAULT;
  296. psh.hwndParent = hwnd;
  297. psh.hInstance = g_hInstance;
  298. psh.pszCaption = pName;
  299. psh.phpage = ahpage;
  300. hr = AddGeneralPage(psh, pIJob);
  301. CHECK_HRESULT(hr);
  302. hr = AddSchedulePage(psh, pIJob);
  303. CHECK_HRESULT(hr);
  304. hr = AddSettingsPage(psh, pIJob);
  305. CHECK_HRESULT(hr);
  306. hr = AddSecurityPage(psh, pdtobj);
  307. CHECK_HRESULT(hr);
  308. if (psh.nPages == 0)
  309. {
  310. DEBUG_OUT((DEB_USER1, "No pages to display.\n"));
  311. hr = E_FAIL;
  312. break;
  313. }
  314. PropertySheet(&psh);
  315. } while (0);
  316. if (pIJob != NULL)
  317. {
  318. pIJob->Release();
  319. }
  320. SCHEDFreeShared(hSharedFile, GetCurrentProcessId());
  321. if (hwnd)
  322. {
  323. DestroyWindow(hwnd);
  324. }
  325. return hr;
  326. }
  327. HRESULT
  328. DisplayJobProperties(
  329. LPTSTR pszJob,
  330. ITask * pIJob)
  331. {
  332. Win4Assert(pszJob != NULL);
  333. Win4Assert(pIJob != NULL);
  334. HRESULT hr = S_OK;
  335. PROPSHEETHEADER psh;
  336. ZeroMemory(&psh, sizeof(psh));
  337. do
  338. {
  339. //
  340. // Determine the job name.
  341. //
  342. TCHAR szName[MAX_PATH];
  343. lstrcpy(szName, PathFindFileName(pszJob));
  344. LPTSTR pExt = PathFindExtension(szName);
  345. if (pExt)
  346. {
  347. *pExt = TEXT('\0');
  348. }
  349. //
  350. // Add the pages.
  351. //
  352. HPROPSHEETPAGE ahpage[MAX_PROP_PAGES];
  353. psh.dwSize = sizeof(PROPSHEETHEADER);
  354. psh.dwFlags = PSH_DEFAULT;
  355. psh.hwndParent = I_CreateStubWindow();
  356. psh.hInstance = g_hInstance;
  357. psh.pszCaption = szName;
  358. psh.phpage = ahpage;
  359. hr = AddGeneralPage(psh, pIJob);
  360. CHECK_HRESULT(hr);
  361. hr = AddSchedulePage(psh, pIJob);
  362. CHECK_HRESULT(hr);
  363. hr = AddSettingsPage(psh, pIJob);
  364. CHECK_HRESULT(hr);
  365. if (psh.nPages == 0)
  366. {
  367. DEBUG_OUT((DEB_USER1, "No pages to display.\n"));
  368. hr = E_FAIL;
  369. break;
  370. }
  371. PropertySheet(&psh);
  372. } while (0);
  373. if (psh.hwndParent)
  374. {
  375. DestroyWindow(psh.hwndParent);
  376. }
  377. return hr;
  378. }
  379. HRESULT
  380. GetJobPath(
  381. ITask * pIJob,
  382. LPTSTR * ppszJobPath)
  383. {
  384. HRESULT hr = S_OK;
  385. LPOLESTR polestr = NULL;
  386. IPersistFile * ppf = NULL;
  387. do
  388. {
  389. //
  390. // Get the object name
  391. //
  392. hr = pIJob->QueryInterface(IID_IPersistFile, (void **)&ppf);
  393. CHECK_HRESULT(hr);
  394. BREAK_ON_FAIL(hr);
  395. hr = ppf->GetCurFile(&polestr);
  396. CHECK_HRESULT(hr);
  397. BREAK_ON_FAIL(hr);
  398. LPTSTR pszJobPath = NULL;
  399. #ifdef UNICODE
  400. pszJobPath = NewDupString(polestr);
  401. CoTaskMemFree(polestr);
  402. #else
  403. char szName[MAX_PATH + 1];
  404. hr = UnicodeToAnsi(szName, polestr, MAX_PATH+1);
  405. CoTaskMemFree(polestr);
  406. CHECK_HRESULT(hr);
  407. BREAK_ON_FAIL(hr);
  408. pszJobPath = NewDupString(szName);
  409. #endif
  410. if (pszJobPath == NULL)
  411. {
  412. hr = E_OUTOFMEMORY;
  413. CHECK_HRESULT(hr);
  414. break;
  415. }
  416. *ppszJobPath = pszJobPath;
  417. } while (0);
  418. if (ppf != NULL)
  419. {
  420. ppf->Release();
  421. }
  422. return hr;
  423. }