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.

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