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.

476 lines
15 KiB

  1. // genpage.cpp : implementation file
  2. //
  3. #include "precomp.hxx"
  4. #ifdef _DEBUG
  5. #define new DEBUG_NEW
  6. #undef THIS_FILE
  7. static char THIS_FILE[] = __FILE__;
  8. #endif
  9. /////////////////////////////////////////////////////////////////////////////
  10. // CGeneralPage property page
  11. IMPLEMENT_DYNCREATE(CGeneralPage, CPropertyPage)
  12. CGeneralPage::CGeneralPage() : CPropertyPage(CGeneralPage::IDD)
  13. {
  14. //{{AFX_DATA_INIT(CGeneralPage)
  15. m_szName = _T("");
  16. m_szDeploy = _T("");
  17. m_szDescription = _T("");
  18. m_szLocale = _T("");
  19. m_szPath = _T("");
  20. m_szVer = _T("");
  21. m_fShow = TRUE;
  22. //}}AFX_DATA_INIT
  23. m_hConsoleHandle = NULL;
  24. m_bUpdate = FALSE;
  25. }
  26. CGeneralPage::~CGeneralPage()
  27. {
  28. }
  29. void CGeneralPage::DoDataExchange(CDataExchange* pDX)
  30. {
  31. CPropertyPage::DoDataExchange(pDX);
  32. //{{AFX_DATA_MAP(CGeneralPage)
  33. DDX_Control(pDX, IDC_DEPLOY, m_cbDeploy);
  34. DDX_CBString(pDX, IDC_DEPLOY, m_szDeploy);
  35. DDX_Text(pDX, IDC_NAME, m_szName);
  36. DDX_Text(pDX, IDC_DESCRIPTION, m_szDescription);
  37. DDX_Text(pDX, IDC_LOCALE, m_szLocale);
  38. DDX_Text(pDX, IDC_PATH, m_szPath);
  39. DDX_Text(pDX, IDC_VERSION, m_szVer);
  40. DDX_Control(pDX, IDC_CPU, m_cbCPU);
  41. DDX_Control(pDX, IDC_OS, m_cbOS);
  42. DDX_Check(pDX, IDC_CHECK1, m_fShow);
  43. //}}AFX_DATA_MAP
  44. }
  45. BEGIN_MESSAGE_MAP(CGeneralPage, CPropertyPage)
  46. //{{AFX_MSG_MAP(CGeneralPage)
  47. ON_WM_DESTROY()
  48. ON_EN_CHANGE(IDC_NAME, OnChangeName)
  49. ON_EN_CHANGE(IDC_PATH, OnChangePath)
  50. ON_EN_CHANGE(IDC_DESCRIPTION, OnChangeDescription)
  51. ON_BN_CLICKED(IDC_CHECK1, OnChangeShow)
  52. ON_CBN_SELCHANGE(IDC_DEPLOY, OnSelchangeDeploy)
  53. ON_CBN_SELCHANGE(IDC_OS, OnChangeOS)
  54. ON_CBN_SELCHANGE(IDC_CPU, OnChangeCPU)
  55. ON_EN_CHANGE(IDC_VERSION, OnChangeVersion)
  56. //}}AFX_MSG_MAP
  57. END_MESSAGE_MAP()
  58. /////////////////////////////////////////////////////////////////////////////
  59. // CGeneralPage message handlers
  60. void CGeneralPage::OnDestroy()
  61. {
  62. // Note - This needs to be called only once.
  63. // If called more than once, it will gracefully return an error.
  64. MMCFreeNotifyHandle(m_hConsoleHandle);
  65. CPropertyPage::OnDestroy();
  66. m_pData->fBlockDeletion = FALSE;
  67. // Delete the CGeneralPage object
  68. delete this;
  69. }
  70. BOOL CGeneralPage::OnApply()
  71. {
  72. if (m_pIAppManagerActions == NULL || m_pIClassAdmin == NULL)
  73. {
  74. return FALSE;
  75. }
  76. // put up an hourglass (this could take a while)
  77. CHourglass hourglass;
  78. CString szNewScriptPath;
  79. CString szOldScriptPath;
  80. HRESULT hr;
  81. if (m_bUpdate == TRUE)
  82. {
  83. PACKAGEDETAIL NewDetails;
  84. memcpy(&NewDetails, m_pData->pDetails, sizeof(PACKAGEDETAIL));
  85. // UNDONE - validate the data
  86. NewDetails.pszPackageName = (LPOLESTR) ((LPCTSTR)m_szName);
  87. swscanf((LPOLESTR)((LPCTSTR)m_szVer), _T("%u.%u"),&(NewDetails.Platform.dwVersionHi),&(NewDetails.Platform.dwVersionLo));
  88. NewDetails.Platform.dwPlatformId = m_cbOS.GetCurSel();
  89. NewDetails.Platform.dwProcessorArch = m_cbCPU.GetCurSel() == 1 ? PROCESSOR_ARCHITECTURE_ALPHA : PROCESSOR_ARCHITECTURE_INTEL;
  90. NewDetails.dwActFlags = (m_pData->pDetails->dwActFlags & (! (ACTFLG_Published | ACTFLG_Assigned | ACTFLG_UserInstall)));
  91. BOOL fAssign = FALSE;
  92. if (m_szDeploy == m_szPublished)
  93. {
  94. NewDetails.dwActFlags |= ACTFLG_Published;
  95. }
  96. else
  97. {
  98. NewDetails.dwActFlags |= ACTFLG_Assigned;
  99. fAssign = TRUE;
  100. }
  101. NewDetails.dwActFlags |= ((!m_fShow) ? 0 : ACTFLG_UserInstall);
  102. BOOL fMoveScript = (NewDetails.dwActFlags & (ACTFLG_Assigned | ACTFLG_Published))
  103. != (m_pData->pDetails->dwActFlags & (ACTFLG_Assigned | ACTFLG_Published))
  104. || (NewDetails.Platform.dwProcessorArch != m_pData->pDetails->Platform.dwProcessorArch);
  105. if (fMoveScript)
  106. {
  107. // Find out if script file can in fact be moved
  108. BOOL fCanMoveScript = FALSE;
  109. szOldScriptPath = m_pData->szPath;
  110. CString szTemp = szOldScriptPath;
  111. szTemp.MakeLower();
  112. int i = szTemp.Find(_T("\\published\\"));
  113. if (i < 0)
  114. {
  115. i = szTemp.Find(_T("\\assigned\\")); // cover all the bases
  116. }
  117. if (i >= 0)
  118. {
  119. // finally make sure it's got an .aas extension
  120. if (szTemp.Right(4) == _T(".aas"))
  121. {
  122. DWORD dwAttributes = GetFileAttributes(m_pData->szPath);
  123. if ((dwAttributes != 0xffffffff) && ((dwAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0))
  124. {
  125. fCanMoveScript = TRUE;
  126. }
  127. }
  128. }
  129. if (fCanMoveScript)
  130. {
  131. // Build new path
  132. szNewScriptPath = szOldScriptPath;
  133. // Strip off everything up to "\\published" or "\\assigned"
  134. szNewScriptPath = szNewScriptPath.Left(i);
  135. szNewScriptPath +=
  136. (NewDetails.dwActFlags & ACTFLG_Assigned) != 0
  137. ? _T("\\Assigned") : _T("\\Published");
  138. szNewScriptPath +=
  139. NewDetails.Platform.dwProcessorArch == PROCESSOR_ARCHITECTURE_ALPHA
  140. ? _T("\\Alpha\\") : _T("\\x86\\");
  141. {
  142. TCHAR Name [_MAX_FNAME];
  143. TCHAR Ext [_MAX_EXT];
  144. TCHAR ScriptNameAndPath[_MAX_PATH ];
  145. _tsplitpath( szOldScriptPath, NULL, NULL, Name, Ext );
  146. szNewScriptPath += Name;
  147. szNewScriptPath += Ext;
  148. }
  149. // Try and move it
  150. if (!MoveFileEx(szOldScriptPath,
  151. szNewScriptPath,
  152. MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH))
  153. {
  154. // wasn't moved
  155. fMoveScript = FALSE;
  156. // UNDONE - put up a message that the scrip file wasn't moved?
  157. }
  158. else
  159. {
  160. m_pData->szPath = szNewScriptPath;
  161. NewDetails.pszPath = (LPOLESTR)(LPCOLESTR)m_pData->szPath;
  162. }
  163. }
  164. else
  165. {
  166. // wasn't moved so make sure we don't try and move it back later
  167. fMoveScript = FALSE;
  168. }
  169. }
  170. NewDetails.pszProductName = (LPOLESTR) ((LPCTSTR)m_szDescription);
  171. BOOL fPathChanged = m_szPath != m_pData->szIconPath;
  172. BOOL fChangeBoth = 0 == wcscmp(m_pData->pDetails->pszPath, m_pData->pDetails->pszIconPath);
  173. if (fPathChanged)
  174. {
  175. // user changed the path
  176. NewDetails.pszIconPath = (LPOLESTR)((LPCTSTR)m_szPath);
  177. if (fChangeBoth)
  178. {
  179. NewDetails.pszPath = (LPOLESTR)((LPCTSTR)m_szPath);
  180. }
  181. }
  182. hr = m_pIClassAdmin->DeletePackage(m_pData->pDetails->pszPackageName);
  183. if (SUCCEEDED(hr))
  184. {
  185. hr = m_pIClassAdmin->NewPackage(&NewDetails);
  186. }
  187. if (FAILED(hr))
  188. {
  189. if (fMoveScript)
  190. {
  191. // changed location for deployment back to what it was
  192. // before we failed to change the info in the class store
  193. // (Note that we're assuming that if we could change it one way
  194. // we can change it back.)
  195. if (MoveFileEx(szNewScriptPath,
  196. szOldScriptPath,
  197. MOVEFILE_COPY_ALLOWED|MOVEFILE_WRITE_THROUGH))
  198. {
  199. m_pData->szPath = szOldScriptPath;
  200. m_pData->pDetails->pszPath = (LPOLESTR)(LPCOLESTR)m_pData->szPath;
  201. }
  202. }
  203. hr = m_pIClassAdmin->NewPackage(m_pData->pDetails);
  204. // need to move this message
  205. ::MessageBox(NULL,
  206. L"Couldn't apply changes. Verify that the class store's server is active.",
  207. L"ERROR",
  208. MB_OK);
  209. return FALSE;
  210. }
  211. else
  212. {
  213. if (fMoveScript)
  214. {
  215. // Notify clients of change
  216. if (m_pIAppManagerActions)
  217. {
  218. m_pIAppManagerActions->NotifyClients(FALSE);
  219. }
  220. }
  221. }
  222. memcpy(m_pData->pDetails, &NewDetails, sizeof(PACKAGEDETAIL));
  223. if (m_pData->pDetails->dwActFlags & ACTFLG_Assigned)
  224. {
  225. m_pData->type = DT_ASSIGNED;
  226. }
  227. else
  228. {
  229. m_pData->type = DT_PUBLISHED;
  230. }
  231. m_pData->szType = m_szDeploy;
  232. // Up above, we set NewDetails.pszPackageName to m_szName.
  233. // We can't leave it set to that because m_szName is a member
  234. // variable of this property sheet class object and will be released
  235. // when the property sheet goes away. We need to copy it to
  236. // m_pData->szName (which is a CString and therefore has it's own
  237. // memory store) and then set the details back to it so it doesn't
  238. // get freed from under us.
  239. m_pData->szName = m_szName;
  240. m_pData->pDetails->pszPackageName = (LPOLESTR)((LPCTSTR)m_pData->szName);
  241. // same problem with szDesc
  242. m_pData->szDesc = m_szDescription;
  243. m_pData->pDetails->pszProductName = (LPOLESTR)((LPCTSTR)m_pData->szDesc);
  244. if (fPathChanged)
  245. {
  246. m_pData->szIconPath = m_szPath;
  247. m_pData->pDetails->pszIconPath = (LPOLESTR)((LPCTSTR)m_pData->szIconPath);
  248. // user changed the path
  249. if (fChangeBoth)
  250. {
  251. m_pData->szPath = m_szPath;
  252. m_pData->pDetails->pszPath = (LPOLESTR)((LPCTSTR)m_pData->szIconPath);
  253. }
  254. }
  255. if (m_szPath != m_pData->szIconPath)
  256. {
  257. // user changed the path
  258. if (wcscmp(m_pData->pDetails->pszPath, m_pData->pDetails->pszIconPath))
  259. {
  260. // If the paths were the same to start with then change 'em both.
  261. m_pData->szPath = m_szPath;
  262. m_pData->pDetails->pszPath = (LPOLESTR)((LPCTSTR)m_pData->szPath);
  263. }
  264. m_pData->szIconPath = m_szPath;
  265. m_pData->pDetails->pszIconPath = (LPOLESTR)((LPCTSTR)m_pData->szIconPath);
  266. }
  267. SetStringData(m_pData);
  268. MMCPropertyChangeNotify(m_hConsoleHandle, (long) m_cookie);
  269. m_bUpdate = FALSE;
  270. }
  271. return CPropertyPage::OnApply();
  272. }
  273. BOOL CGeneralPage::OnInitDialog()
  274. {
  275. TCHAR szBuffer[256];
  276. m_pData->fBlockDeletion = TRUE;
  277. m_szName = m_pData->szName;
  278. m_szDescription = m_pData->szDesc;
  279. m_szLocale = m_pData->szLoc;
  280. m_szPath = m_pData->szIconPath;
  281. m_szDeploy = m_pData->szType;
  282. wsprintf(szBuffer, _T("%u.%u"), m_pData->pDetails->Platform.dwVersionHi, m_pData->pDetails->Platform.dwVersionLo);
  283. m_szVer = szBuffer;
  284. m_fShow = m_pData->pDetails->dwActFlags & ACTFLG_UserInstall ? 1 : 0;
  285. CPropertyPage::OnInitDialog();
  286. // unmarshal the IAppManagerActions interface
  287. HRESULT hr = CoGetInterfaceAndReleaseStream(m_pIStreamAM, IID_IAppManagerActions, (void **) &m_pIAppManagerActions);
  288. if (!SUCCEEDED(hr))
  289. {
  290. #if DBG == 1
  291. ::MessageBox(NULL,
  292. L"Couldn't marshal IAppManagerActions",
  293. L"DEBUG ERROR",
  294. MB_OK);
  295. #endif
  296. m_pIAppManagerActions = NULL;
  297. return FALSE;
  298. // BUGBUG - what should I do here? Disallow changes?
  299. }
  300. // unmarshal the IClassAdmin interface
  301. hr = CoGetInterfaceAndReleaseStream(m_pIStream, IID_IClassAdmin, (void **) &m_pIClassAdmin);
  302. if (!SUCCEEDED(hr))
  303. {
  304. #if DBG == 1
  305. ::MessageBox(NULL,
  306. L"Couldn't marshal IClassAdmin",
  307. L"DEBUG ERROR",
  308. MB_OK);
  309. #endif
  310. m_pIClassAdmin = NULL;
  311. // BUGBUG - what should I do here? Disallow changes?
  312. }
  313. ::LoadString(ghInstance, IDS_DATATYPES, szBuffer, 256);
  314. m_szAssigned = szBuffer;
  315. // Test to be sure it can be assigned.
  316. // If it's not a Darwin package then it can't be assigned and
  317. // the option won't even be presented to the user.
  318. if (m_pIAppManagerActions)
  319. {
  320. hr = m_pIAppManagerActions->CanPackageBeAssigned(m_cookie);
  321. }
  322. if (hr == ERROR_SUCCESS)
  323. {
  324. m_cbDeploy.AddString(szBuffer);
  325. }
  326. ::LoadString(ghInstance, IDS_DATATYPES+1, szBuffer, 256);
  327. m_szPublished = szBuffer;
  328. m_cbDeploy.AddString(szBuffer);
  329. m_cbDeploy.SelectString(0, m_szDeploy);
  330. int i;
  331. for (i = 0; i < (sizeof(m_rgszOS) / sizeof(m_rgszOS[0])); i++)
  332. {
  333. ::LoadString(ghInstance, IDS_OS + i + 1, szBuffer, 256);
  334. m_rgszOS[i] = szBuffer;
  335. m_cbOS.AddString(szBuffer);
  336. }
  337. m_cbOS.SetCurSel(m_pData->pDetails->Platform.dwPlatformId);
  338. for (i = 0; i < (sizeof(m_rgszCPU) / sizeof(m_rgszCPU[0])); i++)
  339. {
  340. ::LoadString(ghInstance, IDS_HW + (i == 0 ? PROCESSOR_ARCHITECTURE_INTEL : PROCESSOR_ARCHITECTURE_ALPHA), szBuffer, 256);
  341. m_rgszCPU[i] = szBuffer;
  342. m_cbCPU.AddString(szBuffer);
  343. }
  344. m_cbCPU.SetCurSel(m_pData->pDetails->Platform.dwProcessorArch == PROCESSOR_ARCHITECTURE_ALPHA ? 1 : 0);
  345. return TRUE; // return TRUE unless you set the focus to a control
  346. // EXCEPTION: OCX Property Pages should return FALSE
  347. }
  348. void CGeneralPage::OnChangeShow()
  349. {
  350. // TODO: If this is a RICHEDIT control, the control will not
  351. // send this notification unless you override the CPropertyPage::OnInitDialog()
  352. // function to send the EM_SETEVENTMASK message to the control
  353. // with the ENM_CHANGE flag ORed into the lParam mask.
  354. // TODO: Add your control notification handler code here
  355. SetModified();
  356. m_bUpdate = TRUE;
  357. }
  358. void CGeneralPage::OnChangePath()
  359. {
  360. SetModified();
  361. m_bUpdate = TRUE;
  362. }
  363. void CGeneralPage::OnChangeCPU()
  364. {
  365. SetModified();
  366. m_bUpdate = TRUE;
  367. }
  368. void CGeneralPage::OnChangeOS()
  369. {
  370. TCHAR * rgszVer[] =
  371. {
  372. _T("3.1"),
  373. _T("4.1"),
  374. _T("5.0")
  375. };
  376. int i = m_cbOS.GetCurSel();
  377. m_szVer = rgszVer[i];
  378. GetDlgItem(IDC_VERSION)->SetWindowText(m_szVer);
  379. SetModified();
  380. m_bUpdate = TRUE;
  381. }
  382. void CGeneralPage::OnChangeVersion()
  383. {
  384. SetModified();
  385. m_bUpdate = TRUE;
  386. }
  387. void CGeneralPage::OnChangeName()
  388. {
  389. // TODO: If this is a RICHEDIT control, the control will not
  390. // send this notification unless you override the CPropertyPage::OnInitDialog()
  391. // function to send the EM_SETEVENTMASK message to the control
  392. // with the ENM_CHANGE flag ORed into the lParam mask.
  393. // TODO: Add your control notification handler code here
  394. SetModified();
  395. m_bUpdate = TRUE;
  396. }
  397. void CGeneralPage::OnChangeDescription()
  398. {
  399. // TODO: If this is a RICHEDIT control, the control will not
  400. // send this notification unless you override the CPropertyPage::OnInitDialog()
  401. // function to send the EM_SETEVENTMASK message to the control
  402. // with the ENM_CHANGE flag ORed into the lParam mask.
  403. // TODO: Add your control notification handler code here
  404. SetModified();
  405. m_bUpdate = TRUE;
  406. }
  407. void CGeneralPage::OnSelchangeDeploy()
  408. {
  409. // TODO: Add your control notification handler code here
  410. SetModified();
  411. m_bUpdate = TRUE;
  412. }