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.

443 lines
11 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1981 - 1999
  4. Module Name:
  5. irrecvprogress.cpp
  6. Abstract:
  7. Author:
  8. Rahul Thombre (RahulTh) 4/30/1998
  9. Revision History:
  10. 4/30/1998 RahulTh
  11. Created this module.
  12. --*/
  13. // IrRecvProgress.cpp : implementation file
  14. //
  15. #include "precomp.hxx"
  16. #ifdef _DEBUG
  17. #define new DEBUG_NEW
  18. #undef THIS_FILE
  19. static char THIS_FILE[] = __FILE__;
  20. #endif
  21. /////////////////////////////////////////////////////////////////////////////
  22. // CIrRecvProgress dialog
  23. CIrRecvProgress::CIrRecvProgress(wchar_t * MachineName,
  24. boolean bSuppressRecvConf,
  25. CWnd* pParent /*=NULL*/)
  26. : m_szMachineName (MachineName), m_fFirstXfer (TRUE), m_bDlgDestroyed (TRUE)
  27. {
  28. DWORD dwPrompt;
  29. m_ptl = NULL;
  30. m_dwMagicID = RECV_MAGIC_ID;
  31. m_bRecvFromCamera = FALSE;
  32. if (bSuppressRecvConf)
  33. {
  34. m_fDontPrompt = TRUE;
  35. m_bRecvFromCamera = TRUE;
  36. if (m_szMachineName.IsEmpty())
  37. {
  38. m_szMachineName.LoadString (IDS_CAMERA);
  39. }
  40. }
  41. else
  42. {
  43. dwPrompt = GetIRRegVal (TEXT("RecvConf"), 1);
  44. m_fDontPrompt = dwPrompt ? FALSE : TRUE;
  45. if (m_szMachineName.IsEmpty())
  46. {
  47. m_szMachineName.LoadString (IDS_UNKNOWN_DEVICE);
  48. }
  49. }
  50. //
  51. // No permitted directory yet.
  52. //
  53. m_LastPermittedDirectory[0] = 0;
  54. appController->PostMessage (WM_APP_KILL_TIMER);
  55. InterlockedIncrement (&g_lUIComponentCount);
  56. Create(IDD,appController);
  57. //{{AFX_DATA_INIT(CIrRecvProgress)
  58. // NOTE: the ClassWizard will add member initialization here
  59. //}}AFX_DATA_INIT
  60. }
  61. void CIrRecvProgress::DoDataExchange(CDataExchange* pDX)
  62. {
  63. CDialog::DoDataExchange(pDX);
  64. //{{AFX_DATA_MAP(CIrRecvProgress)
  65. DDX_Control(pDX, IDC_RECV_XFERANIM, m_xferAnim);
  66. DDX_Control(pDX, IDC_SAVEDICON, m_icon);
  67. DDX_Control(pDX, IDC_DONETEXT, m_DoneText);
  68. DDX_Control(pDX, IDC_RECV_CONNECTIONTEXT, m_machDesc);
  69. DDX_Control(pDX, IDC_RECVDESCRIPTION, m_recvDesc);
  70. DDX_Control(pDX, IDC_XFER_DESC, m_xferDesc);
  71. DDX_Control(pDX, IDC_MACHNAME, m_Machine);
  72. DDX_Control(pDX, IDC_FILENAME, m_File);
  73. DDX_Control(pDX, IDC_CLOSEONCOMPLETE, m_btnCloseOnComplete);
  74. DDX_Control(pDX, IDC_ABORT, m_btnCancel);
  75. //}}AFX_DATA_MAP
  76. }
  77. BEGIN_MESSAGE_MAP(CIrRecvProgress, CDialog)
  78. //{{AFX_MSG_MAP(CIrRecvProgress)
  79. ON_BN_CLICKED (IDC_ABORT, OnCancel)
  80. //}}AFX_MSG_MAP
  81. END_MESSAGE_MAP()
  82. /////////////////////////////////////////////////////////////////////////////
  83. // CIrRecvProgress message handlers
  84. void CIrRecvProgress::OnCancel()
  85. {
  86. m_xferAnim.Stop();
  87. m_xferAnim.Close();
  88. CancelReceive( g_hIrRpcHandle, (COOKIE) this );
  89. DestroyWindow();
  90. }
  91. void CIrRecvProgress::PostNcDestroy()
  92. {
  93. BOOL fNoUIComponents = (0 == InterlockedDecrement (&g_lUIComponentCount));
  94. if (fNoUIComponents && !g_deviceList.GetDeviceCount())
  95. {
  96. //there are no UI components displayed and there are no devices in
  97. //range. Start the timer. If the timer expires, the app. will quit.
  98. appController->PostMessage (WM_APP_START_TIMER);
  99. }
  100. delete this;
  101. }
  102. void CIrRecvProgress::ShowProgressControls (int nCmdShow)
  103. {
  104. m_xferAnim.ShowWindow (nCmdShow);
  105. m_xferDesc.ShowWindow (nCmdShow);
  106. m_machDesc.ShowWindow (nCmdShow);
  107. m_Machine.ShowWindow (nCmdShow);
  108. m_recvDesc.ShowWindow (nCmdShow);
  109. m_File.ShowWindow (nCmdShow);
  110. m_btnCloseOnComplete.ShowWindow (nCmdShow);
  111. }
  112. void CIrRecvProgress::ShowSummaryControls (int nCmdShow)
  113. {
  114. m_icon.ShowWindow (nCmdShow);
  115. m_DoneText.ShowWindow (nCmdShow);
  116. }
  117. void CIrRecvProgress::DestroyAndCleanup(
  118. DWORD status
  119. )
  120. {
  121. //AFX_MANAGE_STATE (AfxGetStaticModuleState());
  122. CString szFormat;
  123. CString szDisplay;
  124. m_xferAnim.Stop();
  125. m_xferAnim.Close();
  126. //destroy the window right away if the "Close on complete" check-box is
  127. //checked.
  128. if (m_btnCloseOnComplete.GetCheck())
  129. {
  130. DestroyWindow();
  131. return;
  132. }
  133. //if we are here, the user wanted the window to stay even after the
  134. //receive was completed. So hide the progress controls and show the
  135. //summary controls.
  136. ShowProgressControls (SW_HIDE);
  137. ShowSummaryControls (SW_SHOW);
  138. if (0 == status)
  139. {
  140. szFormat = g_Strings.CompletedSuccess;
  141. szDisplay.Format (szFormat, m_szMachineName);
  142. m_DoneText.SetWindowText(szDisplay);
  143. }
  144. else if (ERROR_CANCELLED == status)
  145. {
  146. m_DoneText.SetWindowText (g_Strings.RecvCancelled);
  147. }
  148. else
  149. {
  150. LPVOID lpMessageBuffer;
  151. TCHAR ErrDesc [ERROR_DESCRIPTION_LENGTH];
  152. CString ErrorDescription;
  153. CString Message;
  154. if (!FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER |
  155. FORMAT_MESSAGE_IGNORE_INSERTS |
  156. FORMAT_MESSAGE_FROM_SYSTEM,
  157. NULL, // ignored
  158. status,
  159. 0, // try default language ids
  160. (LPTSTR) &lpMessageBuffer,
  161. 0,
  162. NULL // ignored
  163. ))
  164. {
  165. wsprintf(ErrDesc, g_Strings.ErrorNoDescription, status);
  166. //using the overloaded CString assignment operator. It is
  167. //essentially a string copy, but MFC takes care of allocating
  168. //and freeing the destination buffer.
  169. ErrorDescription = ErrDesc;
  170. }
  171. else
  172. {
  173. //Note: this is not a pointer assignment. We are using the
  174. //overloaded CString assignment operator which essentially
  175. //does a string copy. (see comments above)
  176. ErrorDescription = (TCHAR *) lpMessageBuffer;
  177. LocalFree (lpMessageBuffer);
  178. }
  179. Message = g_Strings.ReceiveError;
  180. //using overloaded CString + operator. Has the same effect as wcscat
  181. //but MFC takes care of allocating and freeing the destination buffers
  182. Message += ErrorDescription;
  183. m_DoneText.SetWindowText(Message);
  184. }
  185. m_btnCancel.SetWindowText(g_Strings.Close);
  186. m_btnCancel.SetFocus();
  187. }
  188. BOOL CIrRecvProgress::DestroyWindow()
  189. {
  190. if (m_bDlgDestroyed)
  191. return m_bDlgDestroyed;
  192. //if a taskbar button had been put up, remove it now.
  193. if (m_ptl)
  194. {
  195. m_ptl->DeleteTab(m_hWnd);
  196. m_ptl->Release();
  197. m_ptl = NULL;
  198. }
  199. m_bDlgDestroyed=TRUE;
  200. CWnd::DestroyWindow();
  201. return TRUE;
  202. }
  203. BOOL CIrRecvProgress::OnInitDialog()
  204. {
  205. HRESULT hr = E_FAIL;
  206. RECT rc;
  207. int newWidth, newHeight, xshift, yshift;
  208. CWnd * pDesktop = NULL;
  209. CDialog::OnInitDialog();
  210. m_bDlgDestroyed = FALSE;
  211. //start with a hidden window if prompting is not turned off.
  212. if (!m_fDontPrompt)
  213. ShowWindow (SW_HIDE);
  214. else
  215. ShowWindow (SW_SHOW);
  216. //if the sender is a camera, the cancel operation is not supported,
  217. //so change the cancel button to Close
  218. if (m_bRecvFromCamera)
  219. m_btnCancel.SetWindowText(g_Strings.Close);
  220. //first display the progress controls and hide the summary controls.
  221. ShowProgressControls (SW_SHOW);
  222. ShowSummaryControls (SW_HIDE);
  223. //set the appropriate values for the progress controls.
  224. m_xferAnim.Open(IDR_TRANSFER_AVI);
  225. m_xferAnim.Play(0, -1, -1);
  226. m_File.SetWindowText (TEXT(""));
  227. m_Machine.SetWindowText (m_szMachineName);
  228. //add a button to the taskbar for this window
  229. hr = CoInitialize(NULL);
  230. if (SUCCEEDED(hr))
  231. hr = CoCreateInstance(CLSID_TaskbarList,
  232. NULL,
  233. CLSCTX_INPROC_SERVER,
  234. IID_ITaskbarList,
  235. (LPVOID*)&m_ptl);
  236. if (SUCCEEDED(hr))
  237. {
  238. hr = m_ptl->HrInit();
  239. }
  240. else
  241. {
  242. m_ptl = NULL;
  243. }
  244. if (m_ptl)
  245. {
  246. if (SUCCEEDED(hr))
  247. m_ptl->AddTab(m_hWnd);
  248. else
  249. {
  250. m_ptl->Release();
  251. m_ptl = NULL;
  252. }
  253. }
  254. //reposition the window so that it is at the center of the screen
  255. //also push this window to the top after activating it
  256. GetClientRect (&rc);
  257. newHeight = rc.bottom;
  258. newWidth = rc.right;
  259. pDesktop = GetDesktopWindow();
  260. pDesktop->GetClientRect (&rc);
  261. yshift = (rc.bottom - newHeight)/2;
  262. xshift = (rc.right - newWidth)/2;
  263. //there might be a problem if someday the dialog should
  264. //get larger than the desktop. But then, there is no way
  265. //we can fit that window inside the desktop anyway.
  266. //So the best we can do is place it at the top left corner
  267. xshift = (xshift >= 0)?xshift:0;
  268. yshift = (yshift >= 0)?yshift:0;
  269. appController->SetForegroundWindow();
  270. SetActiveWindow();
  271. SetWindowPos (&wndTop, xshift, yshift, -1, -1,
  272. SWP_NOSIZE | SWP_NOOWNERZORDER);
  273. m_btnCancel.SetFocus();
  274. return FALSE; // return TRUE unless you set the focus to a control
  275. // EXCEPTION: OCX Property Pages should return FALSE
  276. }
  277. DWORD
  278. CIrRecvProgress::GetPermission(
  279. wchar_t Name[],
  280. BOOL fDirectory
  281. )
  282. {
  283. TCHAR szCompactName [COMPACT_PATHLEN + 1];
  284. CString szName;
  285. DWORD len;
  286. DWORD Status = ERROR_SUCCESS;
  287. if (Name[0] == '\\')
  288. {
  289. ++Name;
  290. }
  291. //
  292. // Don't issue a blanket authorization for files in the RFF,
  293. // but allow the service to chdir there.
  294. //
  295. if (fDirectory && wcslen(Name) == 0)
  296. {
  297. return ERROR_SUCCESS;
  298. }
  299. //
  300. // If the file or directory lies outside our last approved directory tree, ask permission.
  301. //
  302. if (m_LastPermittedDirectory[0] == 0 ||
  303. 0 != wcsncmp(m_LastPermittedDirectory, Name, wcslen(m_LastPermittedDirectory)))
  304. {
  305. Status = PromptForPermission(Name, fDirectory);
  306. }
  307. //
  308. // Update the current file name if we got the permission
  309. //
  310. if (ERROR_SUCCESS == Status)
  311. {
  312. szName = Name;
  313. len = wcslen (Name);
  314. if (COMPACT_PATHLEN < len)
  315. {
  316. if (PathCompactPathEx (szCompactName, Name, COMPACT_PATHLEN + 1, 0))
  317. szName = szCompactName;
  318. }
  319. m_File.SetWindowText(szName);
  320. }
  321. return Status;
  322. }
  323. DWORD
  324. CIrRecvProgress::PromptForPermission(
  325. wchar_t Name[],
  326. BOOL fDirectory
  327. )
  328. {
  329. CRecvConf dlgConfirm (this);
  330. DWORD Status = ERROR_SUCCESS;
  331. DWORD len;
  332. BOOL bUnhide = FALSE;
  333. if (m_fDontPrompt)
  334. goto PromptEnd;
  335. //we need to ask the user for permission.
  336. if (m_fFirstXfer)
  337. {
  338. // dlgConfirm.ShowAllYes (FALSE);
  339. m_fFirstXfer = FALSE;
  340. bUnhide = TRUE;
  341. }
  342. dlgConfirm.InitNames (m_szMachineName, Name, fDirectory);
  343. switch (dlgConfirm.DoModal())
  344. {
  345. case IDALLYES:
  346. m_fDontPrompt = TRUE;
  347. case IDYES:
  348. Status = ERROR_SUCCESS;
  349. break;
  350. case IDCANCEL:
  351. Status = ERROR_CANCELLED;
  352. break;
  353. default:
  354. Status = GetLastError();
  355. }
  356. PromptEnd:
  357. if (fDirectory && ERROR_SUCCESS == Status)
  358. {
  359. wcscpy( m_LastPermittedDirectory, Name);
  360. len = wcslen (Name);
  361. //make sure that the name is slash terminated.
  362. if (L'\\' != Name[len - 1])
  363. wcscat (m_LastPermittedDirectory, TEXT("\\"));
  364. }
  365. if (m_fFirstXfer || bUnhide)
  366. ShowWindow(SW_SHOW);
  367. return Status;
  368. }