Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

442 lines
14 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (c) 2002 Microsoft Corporation
  4. //
  5. // Module Name:
  6. // ResProp.cpp
  7. //
  8. // Description:
  9. // Implementation of the resource extension property page classes.
  10. //
  11. // Author:
  12. // <name> (<e-mail name>) Mmmm DD, 2002
  13. //
  14. // Revision History:
  15. //
  16. // Notes:
  17. //
  18. /////////////////////////////////////////////////////////////////////////////
  19. #include "stdafx.h"
  20. #include "VSSTaskEx.h"
  21. #include "ResProp.h"
  22. #include "ExtObj.h"
  23. #include "DDxDDv.h"
  24. #include "BasePage.inl"
  25. #include "HelpData.h"
  26. #include <mstask.h>
  27. #ifdef _DEBUG
  28. #define new DEBUG_NEW
  29. #undef THIS_FILE
  30. static char THIS_FILE[] = __FILE__;
  31. #endif
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CVSSTaskParamsPage property page
  34. /////////////////////////////////////////////////////////////////////////////
  35. IMPLEMENT_DYNCREATE( CVSSTaskParamsPage, CBasePropertyPage )
  36. /////////////////////////////////////////////////////////////////////////////
  37. // Message Maps
  38. BEGIN_MESSAGE_MAP( CVSSTaskParamsPage, CBasePropertyPage )
  39. //{{AFX_MSG_MAP(CVSSTaskParamsPage)
  40. ON_EN_CHANGE( IDC_PP_VSSTASK_APPLICATIONNAME, OnChangeRequiredField )
  41. ON_BN_CLICKED(IDC_SCHEDULE, OnSchedule)
  42. //}}AFX_MSG_MAP
  43. // TODO: Modify the following lines to represent the data displayed on this page.
  44. ON_EN_CHANGE( IDC_PP_VSSTASK_APPLICATIONPARAMS, CBasePropertyPage::OnChangeCtrl )
  45. ON_EN_CHANGE( IDC_PP_VSSTASK_CURRENTDIRECTORY, CBasePropertyPage::OnChangeCtrl )
  46. END_MESSAGE_MAP()
  47. /////////////////////////////////////////////////////////////////////////////
  48. //++
  49. //
  50. // CVSSTaskParamsPage::CVSSTaskParamsPage
  51. //
  52. // Description:
  53. // Default constructor.
  54. //
  55. // Arguments:
  56. // None.
  57. //
  58. // Return Value:
  59. // None.
  60. //
  61. //--
  62. /////////////////////////////////////////////////////////////////////////////
  63. CVSSTaskParamsPage::CVSSTaskParamsPage( void )
  64. : CBasePropertyPage(
  65. CVSSTaskParamsPage::IDD,
  66. g_aHelpIDs_IDD_PP_VSSTASK_PARAMETERS,
  67. g_aHelpIDs_IDD_WIZ_VSSTASK_PARAMETERS
  68. )
  69. {
  70. // TODO: Modify the following lines to represent the data displayed on this page.
  71. //{{AFX_DATA_INIT(CVSSTaskParamsPage)
  72. m_strCurrentDirectory = _T("");
  73. m_strApplicationName = _T("");
  74. m_strApplicationParams = _T("");
  75. m_pbTriggerArray = NULL;
  76. m_dwTriggerArraySize = 0;
  77. //}}AFX_DATA_INIT
  78. // Setup the property array.
  79. {
  80. m_rgProps[ epropCurrentDirectory ].SetExpandSz( REGPARAM_VSSTASK_CURRENTDIRECTORY, m_strCurrentDirectory, m_strPrevCurrentDirectory );
  81. m_rgProps[ epropApplicationName ].Set( REGPARAM_VSSTASK_APPLICATIONNAME, m_strApplicationName, m_strPrevApplicationName );
  82. m_rgProps[ epropApplicationParams ].Set( REGPARAM_VSSTASK_APPLICATIONPARAMS, m_strApplicationParams, m_strPrevApplicationParams );
  83. m_rgProps[ epropTriggerArray ].Set ( REGPARAM_VSSTASK_TRIGGERARRAY, m_pbTriggerArray, m_dwTriggerArraySize, m_pbPrevTriggerArray, m_dwPrevTriggerArraySize, 0);
  84. } // Setup the property array
  85. m_iddPropertyPage = IDD_PP_VSSTASK_PARAMETERS;
  86. m_iddWizardPage = IDD_WIZ_VSSTASK_PARAMETERS;
  87. } //*** CVSSTaskParamsPage::CVSSTaskParamsPage()
  88. /////////////////////////////////////////////////////////////////////////////
  89. //++
  90. //
  91. // CVSSTaskParamsPage::DoDataExchange
  92. //
  93. // Description:
  94. // Do data exchange between the dialog and the class.
  95. //
  96. // Arguments:
  97. // pDX [IN OUT] Data exchange object
  98. //
  99. // Return Value:
  100. // None.
  101. //
  102. //--
  103. /////////////////////////////////////////////////////////////////////////////
  104. void CVSSTaskParamsPage::DoDataExchange( CDataExchange * pDX )
  105. {
  106. if ( ! pDX->m_bSaveAndValidate || ! BSaved() )
  107. {
  108. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  109. // TODO: Modify the following lines to represent the data displayed on this page.
  110. //{{AFX_DATA_MAP(CVSSTaskParamsPage)
  111. DDX_Control( pDX, IDC_PP_VSSTASK_CURRENTDIRECTORY, m_editCurrentDirectory );
  112. DDX_Control( pDX, IDC_PP_VSSTASK_APPLICATIONNAME, m_editApplicationName );
  113. DDX_Text( pDX, IDC_PP_VSSTASK_CURRENTDIRECTORY, m_strCurrentDirectory );
  114. DDX_Text( pDX, IDC_PP_VSSTASK_APPLICATIONNAME, m_strApplicationName );
  115. DDX_Text( pDX, IDC_PP_VSSTASK_APPLICATIONPARAMS, m_strApplicationParams );
  116. //}}AFX_DATA_MAP
  117. // Handle numeric parameters.
  118. if ( ! BBackPressed() )
  119. {
  120. } // if: back button not pressed
  121. // TODO: Add any additional field validation here.
  122. if ( pDX->m_bSaveAndValidate )
  123. {
  124. // Make sure all required fields are present.
  125. if ( ! BBackPressed() )
  126. {
  127. DDV_RequiredText( pDX, IDC_PP_VSSTASK_APPLICATIONNAME, IDC_PP_VSSTASK_APPLICATIONNAME_LABEL, m_strApplicationName );
  128. } // if: back button not pressed
  129. } // if: saving data from dialog
  130. } // if: not saving or haven't saved yet
  131. CBasePropertyPage::DoDataExchange( pDX );
  132. } //*** CVSSTaskParamsPage::DoDataExchange()
  133. /////////////////////////////////////////////////////////////////////////////
  134. //++
  135. //
  136. // CVSSTaskParamsPage::OnInitDialog
  137. //
  138. // Description:
  139. // Handler for the WM_INITDIALOG message.
  140. //
  141. // Arguments:
  142. // None.
  143. //
  144. // Return Value:
  145. // TRUE We need the focus to be set for us.
  146. // FALSE We already set the focus to the proper control.
  147. //
  148. //--
  149. /////////////////////////////////////////////////////////////////////////////
  150. BOOL CVSSTaskParamsPage::OnInitDialog( void )
  151. {
  152. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  153. CBasePropertyPage::OnInitDialog();
  154. // TODO:
  155. // Limit the size of the text that can be entered in edit controls.
  156. return TRUE; // return TRUE unless you set the focus to a control
  157. // EXCEPTION: OCX Property Pages should return FALSE
  158. } //*** CVSSTaskParamsPage::OnInitDialog()
  159. /////////////////////////////////////////////////////////////////////////////
  160. //++
  161. //
  162. // CVSSTaskParamsPage::OnSetActive
  163. //
  164. // Description:
  165. // Handler for the PSN_SETACTIVE message.
  166. //
  167. // Arguments:
  168. // None.
  169. //
  170. // Return Value:
  171. // TRUE Page successfully initialized.
  172. // FALSE Page not initialized.
  173. //
  174. //--
  175. /////////////////////////////////////////////////////////////////////////////
  176. BOOL CVSSTaskParamsPage::OnSetActive( void )
  177. {
  178. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  179. // Enable/disable the Next/Finish button.
  180. if ( BWizard() )
  181. {
  182. EnableNext( BAllRequiredFieldsPresent() );
  183. } // if: displaying a wizard
  184. return CBasePropertyPage::OnSetActive();
  185. } //*** CVSSTaskParamsPage::OnSetActive()
  186. /////////////////////////////////////////////////////////////////////////////
  187. //++
  188. //
  189. // CVSSTaskParamsPage::OnChangeRequiredField
  190. //
  191. // Description:
  192. // Handler for the EN_CHANGE message on the Share name or Path edit
  193. // controls.
  194. //
  195. // Arguments:
  196. // None.
  197. //
  198. // Return Value:
  199. // None.
  200. //
  201. //--
  202. /////////////////////////////////////////////////////////////////////////////
  203. void CVSSTaskParamsPage::OnChangeRequiredField( void )
  204. {
  205. AFX_MANAGE_STATE( AfxGetStaticModuleState() );
  206. OnChangeCtrl();
  207. if ( BWizard() )
  208. {
  209. EnableNext( BAllRequiredFieldsPresent() );
  210. } // if: displaying a wizard
  211. } //*** CVSSTaskParamsPage::OnChangeRequiredField()
  212. /////////////////////////////////////////////////////////////////////////////
  213. //++
  214. //
  215. // CVSSTaskParamsPage::BAllRequiredFieldsPresent
  216. //
  217. // Description:
  218. // Handler for the EN_CHANGE message on the Share name or Path edit
  219. // controls.
  220. //
  221. // Arguments:
  222. // None.
  223. //
  224. // Return Value:
  225. // None.
  226. //
  227. //--
  228. /////////////////////////////////////////////////////////////////////////////
  229. BOOL CVSSTaskParamsPage::BAllRequiredFieldsPresent( void ) const
  230. {
  231. BOOL _bPresent;
  232. if ( 0
  233. || (m_editApplicationName.GetWindowTextLength() == 0)
  234. )
  235. {
  236. _bPresent = FALSE;
  237. } // if: required field not present
  238. else
  239. {
  240. _bPresent = TRUE;
  241. } // else: all required fields are present
  242. return _bPresent;
  243. } //*** CVSSTaskParamsPage::BAllRequiredFieldsPresent()
  244. /////////////////////////////////////////////////////////////////////////////
  245. //++
  246. //
  247. // CVSSTaskParamsPage::OnSchedule
  248. //
  249. // Description:
  250. // Handler for "Schedule" button.
  251. //
  252. // Arguments:
  253. // None.
  254. //
  255. // Return Value:
  256. // None.
  257. //
  258. //--
  259. /////////////////////////////////////////////////////////////////////////////
  260. void CVSSTaskParamsPage::OnSchedule()
  261. {
  262. HRESULT hr = S_OK;
  263. TASKPAGE tpType = TASKPAGE_SCHEDULE;
  264. BOOL fTaskCreated = FALSE;
  265. HPROPSHEETPAGE phPage;
  266. PROPSHEETHEADER psh;
  267. LPCWSTR pwszTaskName = L"$CluAdmin$Task$";
  268. INT_PTR psResult;
  269. ITaskScheduler *pITS = NULL;
  270. ITask *pITask = NULL;
  271. IProvideTaskPage *pIProvTaskPage = NULL;
  272. ITaskTrigger *pITaskTrigger = NULL;
  273. DWORD dwOffset;
  274. PTASK_TRIGGER pTrigger;
  275. TASK_TRIGGER aTrigger;
  276. WORD iTriggerEnum, iTriggerCount;
  277. do {
  278. try { // catch any exceptions
  279. hr = CoCreateInstance(CLSID_CTaskScheduler,
  280. NULL,
  281. CLSCTX_INPROC_SERVER,
  282. IID_ITaskScheduler,
  283. (void **) &pITS);
  284. if (FAILED(hr)) break;
  285. /////////////////////////////////////////////////////////////////
  286. // Call ITaskScheduler::NewWorkItem to create a temporary task.
  287. /////////////////////////////////////////////////////////////////
  288. hr = pITS->NewWorkItem(pwszTaskName, // Name of task
  289. CLSID_CTask, // Class identifier
  290. IID_ITask, // Interface identifier
  291. (IUnknown**)&pITask); // Address of task interface
  292. if (FAILED(hr)) break;
  293. fTaskCreated = TRUE;
  294. ///////////////////////////////////////////////////////////////////
  295. // Fill in the trigger info from the parameters
  296. ///////////////////////////////////////////////////////////////////
  297. dwOffset = 0;
  298. while (dwOffset < m_dwTriggerArraySize)
  299. {
  300. pTrigger = (PTASK_TRIGGER)((BYTE *)m_pbTriggerArray + dwOffset);
  301. if (dwOffset + pTrigger->cbTriggerSize > m_dwTriggerArraySize)
  302. {
  303. hr = ERROR_INVALID_DATA;
  304. break;
  305. }
  306. hr = pITask->CreateTrigger(&iTriggerEnum, &pITaskTrigger);
  307. if (FAILED(hr)) break;
  308. hr = pITaskTrigger->SetTrigger (pTrigger);
  309. if (FAILED(hr)) break;
  310. dwOffset += pTrigger->cbTriggerSize;
  311. }
  312. if (FAILED(hr)) break;
  313. ///////////////////////////////////////////////////////////////////
  314. // Call ITask::QueryInterface to retrieve the IProvideTaskPage
  315. // interface, and call IProvideTaskPage::GetPage to retrieve the
  316. // task page.
  317. ///////////////////////////////////////////////////////////////////
  318. hr = pITask->QueryInterface(IID_IProvideTaskPage,
  319. (void **)&pIProvTaskPage);
  320. if (FAILED(hr)) break;
  321. hr = pIProvTaskPage->GetPage(tpType,
  322. FALSE,
  323. &phPage);
  324. ZeroMemory(&psh, sizeof(PROPSHEETHEADER));
  325. psh.dwSize = sizeof(PROPSHEETHEADER);
  326. psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW;
  327. psh.phpage = &phPage;
  328. psh.nPages = 1;
  329. psResult = PropertySheet(&psh);
  330. if (psResult <= 0) break;
  331. ///////////////////////////////////////////////////////////////////
  332. // Fill in the new trigger info
  333. ///////////////////////////////////////////////////////////////////
  334. hr = pITask->GetTriggerCount(&iTriggerCount);
  335. if (FAILED(hr)) break;
  336. pTrigger = (PTASK_TRIGGER) new BYTE [iTriggerCount * sizeof(TASK_TRIGGER)];
  337. for (iTriggerEnum = 0; iTriggerEnum < iTriggerCount; iTriggerEnum++)
  338. {
  339. hr = pITask->GetTrigger(iTriggerEnum, &pITaskTrigger);
  340. if (FAILED(hr)) break;
  341. hr = pITaskTrigger->GetTrigger(&aTrigger);
  342. if (FAILED(hr)) break;
  343. pTrigger[iTriggerEnum] = aTrigger;
  344. }
  345. if (FAILED(hr)) break;
  346. ///////////////////////////////////////////////////////////////////
  347. // Switch the trigger info with the old data
  348. ///////////////////////////////////////////////////////////////////
  349. delete [] m_pbTriggerArray;
  350. m_dwTriggerArraySize = iTriggerCount * sizeof(TASK_TRIGGER);
  351. m_pbTriggerArray = (BYTE *) pTrigger;
  352. }
  353. catch ( CMemoryException * exc )
  354. {
  355. exc->Delete();
  356. hr = E_OUTOFMEMORY;
  357. }
  358. } while (0);
  359. // If anything failed, dump a message
  360. //
  361. if (FAILED(hr))
  362. {
  363. CString strMsg;
  364. CString strMsgId;
  365. strMsgId.Format(L"%08.8x", hr);
  366. strMsg.FormatMessage(IDS_FAILED_TO_SETUP_SCHEDULE, strMsgId, 1, 2, 3);
  367. AfxMessageBox(strMsg, MB_OK | MB_ICONEXCLAMATION);
  368. strMsgId.Empty();
  369. strMsg.Empty();
  370. }
  371. // Cleanup
  372. //
  373. if (fTaskCreated) pITS->Delete(pwszTaskName);
  374. if (pITaskTrigger != NULL) pITaskTrigger->Release();
  375. if (pIProvTaskPage != NULL) pIProvTaskPage->Release();
  376. if (pITask != NULL) pITask->Release();
  377. if (pITS != NULL) pITS->Release();
  378. }