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.

388 lines
11 KiB

  1. /*++
  2. Microsoft Windows
  3. Copyright (C) Microsoft Corporation, 1981 - 1998
  4. Module Name:
  5. irftp.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. // irftp.cpp : Defines the class behaviors for the application.
  14. //
  15. #include "precomp.hxx"
  16. BOOL
  17. StartIrMon(
  18. VOID
  19. );
  20. #ifdef _DEBUG
  21. #define new DEBUG_NEW
  22. #undef THIS_FILE
  23. static char THIS_FILE[] = __FILE__;
  24. #endif
  25. BOOL LoadGlobalStrings();
  26. /////////////////////////////////////////////////////////////////////////////
  27. // CIrftpApp
  28. BEGIN_MESSAGE_MAP(CIrftpApp, CWinApp)
  29. //{{AFX_MSG_MAP(CIrftpApp)
  30. // NOTE - the ClassWizard will add and remove mapping macros here.
  31. // DO NOT EDIT what you see in these blocks of generated code!
  32. //}}AFX_MSG
  33. ON_COMMAND(ID_HELP, CWinApp::OnHelp)
  34. END_MESSAGE_MAP()
  35. /////////////////////////////////////////////////////////////////////////////
  36. // CIrftpApp construction
  37. CIrftpApp::CIrftpApp()
  38. {
  39. // TODO: add construction code here,
  40. // Place all significant initialization in InitInstance
  41. }
  42. /////////////////////////////////////////////////////////////////////////////
  43. // The one and only CIrftpApp object
  44. CIrftpApp theApp;
  45. ////////////////////////////////////////////////////////////////////////////
  46. // The instance handle for this app.
  47. HINSTANCE g_hInstance;
  48. ///////////////////////////////////////////////////////////////////////////
  49. //the main application UI. this is now global because it might be
  50. //invoked from multiple file, especially the RPC server functions
  51. CIrftpDlg AppUI;
  52. ///////////////////////////////////////////////////////////////////////////
  53. //the controller window for the application. This is necessary to
  54. //create the illusion of parentless send progress dialog boxes.
  55. //actually it is not possible to have parentless and modeless dialog
  56. //boxes. Thus, these dialog boxes actually have the controller window
  57. //as their parent
  58. //This is necessary because the AppUI may come and go and in fact
  59. //never come up at all.
  60. CController* appController = NULL;
  61. ////////////////////////////////////////////////////////////////////////////
  62. //global variable that keeps track of the number of UI components displayed
  63. //by irftp at the moment. Note: we start with -1 because we don't want to
  64. //count the first CController window which is the main app. window.
  65. //
  66. LONG g_lUIComponentCount = -1;
  67. ////////////////////////////////////////////////////////////////////////////
  68. //global variable that keeps track of the handle to the help window (if any)
  69. //The HtmlHelp window is the only one that cannot be tracked using the
  70. //g_lUIComponentCount. So we need this var. to figure out if the help window
  71. //is still up.
  72. HWND g_hwndHelp = NULL;
  73. ////////////////////////////////////////////////////////////////////////////
  74. //global variable that keeps track of whether there is a shortcut to
  75. //the app on the desktop or not
  76. //0 implies that there is a link on the desktop and -1 implies that there
  77. //is no link on the desktop.
  78. //this value is basically an indicator of not only the presence of
  79. //the shortcut on the desktop, but also of the link in the send to
  80. //folder
  81. ////////////////////////////////////////////////////////////////////////////
  82. //the list of devices in range
  83. CDeviceList g_deviceList;
  84. /////////////////////////////////////////////////////////////////////////////
  85. // CIrftpApp initialization
  86. BOOL CIrftpApp::InitInstance()
  87. {
  88. DWORD Status;
  89. error_status_t err;
  90. CError error;
  91. BOOL bSetForeground = FALSE;
  92. int i = 0;
  93. HWND hwndApp = NULL;
  94. HANDLE hMutex = NULL;
  95. BOOL fFirstInstance = FALSE;
  96. AfxEnableControlContainer();
  97. //set the global instance handle
  98. g_hInstance = AfxGetInstanceHandle();
  99. CCommandLine cLine;
  100. ParseCommandLine (cLine);
  101. //
  102. // Load strings.
  103. //
  104. if (FALSE == LoadGlobalStrings()) {
  105. return FALSE;
  106. }
  107. if(cLine.m_fInvalidParams) //if invalid command line parameters, terminate.
  108. {
  109. error.ShowMessage (IDS_INVALID_PARAMETERS);
  110. return FALSE; //exit the app., first instance or not.
  111. }
  112. //
  113. // check if another instance is already running and act accordingly.
  114. //
  115. hMutex = CreateMutex (NULL, FALSE, SINGLE_INST_MUTEX);
  116. if (hMutex != NULL) {
  117. //
  118. // got the mutex, see if we created it or it existed before and we opened it
  119. //
  120. Status = GetLastError();
  121. fFirstInstance = (ERROR_ALREADY_EXISTS != Status);
  122. } else {
  123. //we could not create the mutex, so must fail.
  124. return FALSE;
  125. }
  126. if (cLine.m_fServerStart) {
  127. //
  128. // irmon is starting irftp, better be the first instance
  129. //
  130. if (!fFirstInstance) {
  131. //
  132. // not the first instance give up
  133. //
  134. // OutputDebugStringA("irftp could not start as server\n");
  135. return FALSE;
  136. }
  137. // OutputDebugStringA("irftp started as server\n");
  138. } else {
  139. //
  140. // it is a client session starting, we need the server to be running
  141. //
  142. if (fFirstInstance) {
  143. // OutputDebugStringA("irftp could not start as Client\n");
  144. return FALSE;
  145. }
  146. // OutputDebugStringA("irftp started as Client\n");
  147. }
  148. if (!fFirstInstance) {
  149. hwndApp = GetPrimaryAppWindow();
  150. //
  151. // note: it is important to successfully set the the first instance of the app. as the
  152. // foreground window.since the first instance has already started, it is very unlikely
  153. // that it will be the foreground process therefore it will be unable to set itself as
  154. // the foreground process and therefore any calls to SetActiveWindow etc. in that instance
  155. // will not cause any changes in the Z-order or input focus. Therefore, this instance
  156. // needs to make the first instance the foreground process so that any dialogs etc. put up
  157. // by the windows do not show up obscured by other apps. or without focus. The current
  158. // instance is able to set the first instance as the foreground process because this
  159. // instance is either itself the foreground process or is started by the current
  160. // foreground process.
  161. //
  162. if (hwndApp && (!cLine.m_fHideApp)) {
  163. bSetForeground = ::SetForegroundWindow (hwndApp);
  164. }
  165. if (cLine.m_fFilesProvided) {
  166. COPYDATASTRUCT cStruct;
  167. cStruct.dwData = cLine.m_iListLen;
  168. cStruct.cbData = cLine.m_iListLen * sizeof(wchar_t);
  169. cStruct.lpData = (LPVOID)(cLine.m_lpszFilesList);
  170. SendMessage(hwndApp,WM_COPYDATA, (WPARAM)NULL, (LPARAM)(&cStruct));
  171. } else if (cLine.m_fShowSettings) {
  172. PostMessage(hwndApp,WM_APP_TRIGGER_SETTINGS,0,0);
  173. } else if (!cLine.m_fHideApp) {
  174. PostMessage(hwndApp,WM_APP_TRIGGER_UI,0,0);
  175. } else {
  176. //
  177. // do nothing otherwise.
  178. //
  179. }
  180. //
  181. // for some reason, SetForegroundWindow does not succeed if the window which we are trying
  182. // to put in the foreground does not have any visible windows. So if a user transfers some
  183. // files and then dismisses the wireless link dialog, then at this point, the hidden parent
  184. // window is not the foreground window. So, we try for 10 seconds to get the window in the
  185. // foreground. It is okay to spin here because other than getting the window to the top of
  186. // the Z-order everything else has already been done. Here, we just want to give the shell
  187. // enough time to put up the common file open dialog. Note that we stop spinning the moment
  188. // we succeed in setting the first instance as the foreground window.
  189. //
  190. if (!bSetForeground && hwndApp && (!cLine.m_fHideApp))
  191. {
  192. i = 0;
  193. do
  194. {
  195. if (::SetForegroundWindow (hwndApp))
  196. break;
  197. else
  198. Sleep (100);
  199. } while ( i++ < 100 );
  200. }
  201. CloseHandle (hMutex);
  202. return FALSE; //exit the app. rather than starting the message pump
  203. }
  204. // Standard initialization
  205. // If you are not using these features and wish to reduce the size
  206. // of your final executable, you should remove from the following
  207. // the specific initialization routines you do not need.
  208. #ifdef _AFXDLL
  209. Enable3dControls(); // Call this when using MFC in a shared DLL
  210. #else
  211. Enable3dControlsStatic(); // Call this when linking to MFC statically
  212. #endif
  213. //
  214. // if we reach here, it means that this is the first instance of the app.
  215. //
  216. m_pMainWnd = appController = new CController (cLine.m_fHideApp);
  217. if (!appController) {
  218. return FALSE;
  219. }
  220. appController->ShowWindow(SW_HIDE);
  221. appController->SetWindowText (MAIN_WINDOW_TITLE);
  222. g_lpszDesktopFolder[0] = '\0'; //precautionary measures
  223. g_lpszSendToFolder [0] = '\0';
  224. return StartIrMon();
  225. }
  226. GLOBAL_STRINGS g_Strings;
  227. BOOL
  228. LoadGlobalStrings()
  229. {
  230. #define LOAD_STRING(id, str) \
  231. if (0 == LoadString( g_hInstance, id, g_Strings.str, sizeof(g_Strings.str)/sizeof(wchar_t))) \
  232. { \
  233. return FALSE; \
  234. }
  235. LOAD_STRING( IDS_CLOSE, Close )
  236. LOAD_STRING( IDS_NODESC_ERROR, ErrorNoDescription )
  237. LOAD_STRING( IDS_COMPLETED, CompletedSuccess )
  238. LOAD_STRING( IDS_RECV_ERROR, ReceiveError )
  239. LOAD_STRING( IDS_CONNECTING, Connecting )
  240. LOAD_STRING( IDS_RECV_CANCELLED, RecvCancelled )
  241. return TRUE;
  242. }
  243. #include <irmonftp.h>
  244. HANDLE ThreadHandle=NULL;
  245. BOOL CIrftpApp::ExitInstance()
  246. {
  247. if (ThreadHandle != NULL) {
  248. DWORD WaitResult;
  249. SignalIrmonExit();
  250. WaitResult=WaitForSingleObject(ThreadHandle,60*1000);
  251. #if DBG
  252. if (WaitResult== WAIT_TIMEOUT) {
  253. OutputDebugStringA("IRFTP: Timeout waiting for irmon to exit\n");
  254. }
  255. #endif
  256. }
  257. return CWinApp::ExitInstance();
  258. }
  259. DWORD
  260. IrmonThreadStart(
  261. PVOID COntext
  262. )
  263. {
  264. ServiceMain(0,NULL);
  265. return 0;
  266. }
  267. BOOL
  268. StartIrMon(
  269. VOID
  270. )
  271. {
  272. DWORD ThreadId;
  273. SetInstance(GetModuleHandle(NULL));
  274. ThreadHandle=CreateThread(
  275. NULL,
  276. NULL,
  277. IrmonThreadStart,
  278. NULL,
  279. 0,
  280. &ThreadId
  281. );
  282. return (ThreadHandle != NULL);
  283. }