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.

495 lines
13 KiB

  1. //+-------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1997.
  5. //
  6. // File: OneStop.cpp
  7. //
  8. // Contents: Main application
  9. //
  10. // Classes:
  11. //
  12. // Notes:
  13. //
  14. // History: 05-Nov-97 rogerg Created.
  15. //
  16. //--------------------------------------------------------------------------
  17. #include "precomp.h"
  18. // Global Variables:
  19. HINSTANCE g_hInst = NULL; // current instance
  20. OSVERSIONINFOA g_OSVersionInfo; // osVersionInfo, setup by WinMain.
  21. LANGID g_LangIdSystem; // LangId of system we are running on.
  22. DWORD g_WMTaskbarCreated; // TaskBar Created WindowMessage;
  23. // HACCEL hAccelTable = NULL; // currently don't have any accelerators.
  24. // Foward declarations of functions included in this code module:
  25. BOOL InitApplication(HINSTANCE);
  26. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow,CMsgServiceHwnd *pMsgService);
  27. void UnitApplication();
  28. BOOL SetupUserEnvironment();
  29. //+---------------------------------------------------------------------------
  30. //
  31. // Function: WinMain, public
  32. //
  33. // Synopsis: The start of all things
  34. //
  35. // Arguments: Standard WinMain.
  36. //
  37. // Returns:
  38. //
  39. // Modifies:
  40. //
  41. // History: 18-Nov-97 rogerg Created.
  42. //
  43. //----------------------------------------------------------------------------
  44. #ifdef _DEBUG
  45. extern DWORD g_ThreadCount;
  46. #endif // _DEBUG
  47. int APIENTRY WinMain(HINSTANCE hInstance,
  48. HINSTANCE hPrevInstance,
  49. LPSTR lpCmdLine,
  50. int nCmdShow)
  51. {
  52. MSG msg;
  53. CMsgServiceHwnd *pMsgService;
  54. BOOL fMsgServiceCreated = FALSE;
  55. HRESULT hr;
  56. g_hInst = hInstance; // Store instance handle in our global variable
  57. #ifdef _DEBUG
  58. InitDebugFlags();
  59. #endif // _DEBUG
  60. g_OSVersionInfo.dwOSVersionInfoSize = sizeof(g_OSVersionInfo);
  61. if (!GetVersionExA(&g_OSVersionInfo))
  62. {
  63. AssertSz(0,"Unable to GetOS Version");
  64. return FALSE; // bail if can't get OSVersion
  65. }
  66. BOOL fOSUnicode = (VER_PLATFORM_WIN32_NT == g_OSVersionInfo.dwPlatformId) ? TRUE : FALSE;
  67. InitCommonLib(fOSUnicode);
  68. g_LangIdSystem = GetSystemDefaultLangID();
  69. SetupUserEnvironment();
  70. if (!hPrevInstance) {
  71. // Perform instance initialization:
  72. if (!InitApplication(hInstance)) {
  73. return (FALSE);
  74. }
  75. }
  76. #if _ZAWTRACK
  77. InitZawTrack();
  78. #endif _ZAWTRACK
  79. hr = CoInitializeEx(NULL,COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); // main thread is freeThreaded
  80. if (FAILED(hr))
  81. {
  82. AssertSz(0,"CoInitFailed");
  83. return FALSE;
  84. }
  85. // Initialize the Message Service for all threads
  86. if (NOERROR != InitMessageService())
  87. {
  88. AssertSz(0,"Unable to Init Message Service");
  89. return FALSE;
  90. }
  91. // crate a MessageService for main thread
  92. pMsgService = new CMsgServiceHwnd;
  93. if (NULL != pMsgService)
  94. {
  95. fMsgServiceCreated = pMsgService->Initialize(GetCurrentThreadId(),MSGHWNDTYPE_MAINTHREAD);
  96. Assert(fMsgServiceCreated);
  97. }
  98. if (fMsgServiceCreated && InitInstance(hInstance, nCmdShow,pMsgService))
  99. {
  100. // hAccelTable = LoadAccelerators (hInstance, APPNAME); // Currently don't have any accelerators
  101. // Main message loop:
  102. while (GetMessage(&msg, NULL, 0, 0))
  103. {
  104. if (1 /* !TranslateAccelerator(msg.hwnd,hAccelTable, &msg) */)
  105. {
  106. TranslateMessage(&msg);
  107. DispatchMessage(&msg);
  108. }
  109. }
  110. }
  111. else
  112. {
  113. msg.wParam = 0;
  114. if (pMsgService) // get rid of this threads messageService
  115. pMsgService->Destroy();
  116. }
  117. UnitApplication(); // unitialize application.
  118. return (int)(msg.wParam);
  119. lpCmdLine; // This will prevent 'unused formal parameter' warnings
  120. }
  121. //+---------------------------------------------------------------------------
  122. //
  123. // Function: InitApplication, public
  124. //
  125. // Synopsis: Peforms any application specific tasks
  126. //
  127. // Arguments: [hInstance] - hInstance.
  128. //
  129. // Returns:
  130. //
  131. // Modifies:
  132. //
  133. // History: 18-Nov-97 rogerg Created.
  134. //
  135. //----------------------------------------------------------------------------
  136. BOOL InitApplication(HINSTANCE hInstance)
  137. {
  138. return TRUE;
  139. }
  140. //+---------------------------------------------------------------------------
  141. //
  142. // Function: UnitApplication, public
  143. //
  144. // Synopsis: Peforms any application specific cleanup
  145. //
  146. // Arguments:
  147. //
  148. // Returns:
  149. //
  150. // Modifies:
  151. //
  152. // History: 19-Jun-98 rogerg Created.
  153. //
  154. //----------------------------------------------------------------------------
  155. void UnitApplication()
  156. {
  157. ReleaseConnectionObjects(); // release global connection object class.
  158. gSingleNetApiObj.DeleteNetApiObj(); // get rid of globa NetObj
  159. Assert(g_ThreadCount == 0); // make sure all our threads are cleaned up.
  160. CoFreeUnusedLibraries();
  161. CoUninitialize();
  162. UnInitCommonLib();
  163. #if _ZAWTRACK
  164. UninitZawTrack();
  165. #endif _ZAWTRACK
  166. WALKARENA(); // check for memleaks
  167. }
  168. //+---------------------------------------------------------------------------
  169. //
  170. // Function: InitInstance, public
  171. //
  172. // Synopsis: Peforms instance specific initialization
  173. //
  174. // Arguments: [hInstance] - hInstance.
  175. // [nCmdShow] - value to start windows as
  176. // [pMsgService] - Message service for this instance
  177. //
  178. // Returns: TRUE will put application into a message loop
  179. // FALSE will cause application to terminate immediately
  180. //
  181. // Modifies:
  182. //
  183. // History: 18-Nov-97 rogerg Created.
  184. //
  185. //----------------------------------------------------------------------------
  186. BOOL InitInstance(HINSTANCE hInstance, int nCmdShow,CMsgServiceHwnd *pMsgService)
  187. {
  188. HRESULT hr;
  189. CCmdLine cmdLine;
  190. DWORD cmdLineFlags;
  191. BOOL fEmbeddingFlag;
  192. ATOM aWndClass;
  193. g_WMTaskbarCreated = RegisterWindowMessage(L"TaskbarCreated"); // get taskbar created message.
  194. cmdLine.ParseCommandLine();
  195. cmdLineFlags = cmdLine.GetCmdLineFlags();
  196. fEmbeddingFlag = cmdLineFlags & CMDLINE_COMMAND_EMBEDDING;
  197. //register a windows class to store the icon for the OneStop dialogs
  198. //get an icon for the dialog
  199. WNDCLASS wc;
  200. wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW;
  201. // if unicode use the wide version of the def else use the ANSI
  202. wc.lpfnWndProc = WideWrapIsUnicode() ? DefDlgProcW : DefDlgProcA;
  203. // WRAPPER, need wrappers for LoadIcon/LoadCursor.
  204. wc.cbClsExtra = 0;
  205. wc.cbWndExtra = DLGWINDOWEXTRA;
  206. wc.hInstance = g_hInst;
  207. wc.hIcon = LoadIconA(g_hInst,(LPSTR) MAKEINTRESOURCE(IDI_SYNCMGR));
  208. wc.hCursor = LoadCursorA(NULL,(LPSTR) IDC_ARROW);
  209. wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1);
  210. wc.lpszMenuName = NULL;
  211. wc.lpszClassName = TEXT(MAINDIALOG_HWNDCLASSNAME);
  212. aWndClass = RegisterClass(&wc);
  213. Assert(aWndClass);
  214. // if register flag is passed, just register and return.
  215. if (cmdLineFlags & CMDLINE_COMMAND_REGISTER)
  216. {
  217. AssertSz(0,"SyncMgr launched with obsolete /register flag.");
  218. return FALSE;
  219. }
  220. INITCOMMONCONTROLSEX controlsEx;
  221. controlsEx.dwSize = sizeof(INITCOMMONCONTROLSEX);
  222. controlsEx.dwICC = ICC_USEREX_CLASSES | ICC_WIN95_CLASSES | ICC_NATIVEFNTCTL_CLASS;
  223. InitCommonControlsEx(&controlsEx);
  224. hr = InitObjectManager(pMsgService); // Initialize Object manager
  225. if (NOERROR != hr)
  226. {
  227. Assert(NOERROR == hr);
  228. return FALSE;
  229. }
  230. hr = InitConnectionObjects(); // initialize connection objects.
  231. if (NOERROR != hr)
  232. {
  233. Assert(NOERROR == hr);
  234. return FALSE;
  235. }
  236. // If the embedding flag is set force a Register.
  237. // Review - Activate as Interactive user doesn't work for Logoff
  238. // don't register class factory for schedules or Idle since if an error occurs
  239. // we want TS to launch us again next time it is time for the
  240. // schedule to Fire.
  241. if (!(cmdLineFlags & CMDLINE_COMMAND_SCHEDULE)
  242. && !(cmdLineFlags & CMDLINE_COMMAND_IDLE))
  243. {
  244. hr = RegisterOneStopClassFactory(fEmbeddingFlag);
  245. }
  246. else
  247. {
  248. hr = NOERROR;
  249. }
  250. // if didn't force a register then continue on our journey
  251. // and wait to fail until CoCreateInstance does
  252. Assert(NOERROR == hr || !fEmbeddingFlag);
  253. if (NOERROR == hr || !fEmbeddingFlag )
  254. {
  255. // if only /Embedding is specified we were launch to service someone else so
  256. // dont' do anything, just wait for them to connect.
  257. if (!fEmbeddingFlag)
  258. {
  259. LPPRIVSYNCMGRSYNCHRONIZEINVOKE pUnk;
  260. // If there are other command lines or known to the proper thing. (manual, schedule, etc.).
  261. // addref our lifetime in case update doesn't take, treat as external
  262. // since invoke can go to another process.
  263. AddRefOneStopLifetime(TRUE /*External*/);
  264. // if class factory registered successful then CoCreate
  265. if (SUCCEEDED(hr))
  266. {
  267. hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_ALL,
  268. IID_IPrivSyncMgrSynchronizeInvoke,(void **) &pUnk);
  269. }
  270. // if have failure either from class factory or CoCreateIntance
  271. // then create a class directlry.
  272. if (FAILED(hr))
  273. {
  274. // this is really an error path that shouldn't happen.
  275. // AssertSz(SUCCEEDED(hr),"COM Activation Failed");
  276. // If COM Activation Fails go ahead and create a class directly
  277. // unless it is a schedule or idle event.
  278. if ( !(cmdLineFlags & CMDLINE_COMMAND_SCHEDULE)
  279. && !(cmdLineFlags & CMDLINE_COMMAND_IDLE) )
  280. {
  281. pUnk = new CSynchronizeInvoke;
  282. hr = pUnk ? NOERROR : E_OUTOFMEMORY;
  283. // Assert(NOERROR == hr);
  284. }
  285. }
  286. if (NOERROR == hr)
  287. {
  288. AllowSetForegroundWindow(ASFW_ANY); // let mobsync.exe come to front if necessary
  289. if (cmdLineFlags & CMDLINE_COMMAND_LOGON)
  290. {
  291. pUnk->Logon();
  292. }
  293. else if (cmdLineFlags & CMDLINE_COMMAND_LOGOFF)
  294. {
  295. pUnk->Logoff();
  296. }
  297. else if (cmdLineFlags & CMDLINE_COMMAND_SCHEDULE)
  298. {
  299. pUnk->Schedule(cmdLine.GetJobFile());
  300. }
  301. else if (cmdLineFlags & CMDLINE_COMMAND_IDLE)
  302. {
  303. pUnk->Idle();
  304. }
  305. else
  306. {
  307. // default is a manual sync
  308. pUnk->UpdateAll();
  309. }
  310. pUnk->Release();
  311. }
  312. else
  313. {
  314. // AssertSz(0,"Unable to Create Invoke Instance");
  315. }
  316. ReleaseOneStopLifetime(TRUE /*External*/); // Release our reference.
  317. }
  318. return TRUE; // even on failure return true, locking will take care of releasing object.
  319. }
  320. return (FALSE); // if couldn't forward the update then end.
  321. }
  322. //+---------------------------------------------------------------------------
  323. //
  324. // Function: SetupUserEnvironment,private
  325. //
  326. // Synopsis: Sets up any use environment variables we need to run.
  327. //
  328. // When we are launched as interactive User by DCOM the
  329. // environment variables aren't set so we need to set
  330. // any up that us or the handlers rely on.
  331. //
  332. // Arguments:
  333. //
  334. // Returns:
  335. //
  336. // Modifies:
  337. //
  338. // History: 14-Aug-98 rogerg Created.
  339. //
  340. //----------------------------------------------------------------------------
  341. #define SZ_ENVIRONVARIABLE_USERPROFILE TEXT("USERPROFILE")
  342. #define SZ_ENVIRONVARIABLE_USERNAME TEXT("USERNAME")
  343. BOOL SetupUserEnvironment()
  344. {
  345. HANDLE hToken = NULL;
  346. BOOL fValidToken;
  347. BOOL fSetEnviron = FALSE;
  348. BOOL fSetUserName = FALSE;
  349. // only need to setup the user environment if we are on NT
  350. if (VER_PLATFORM_WIN32_NT != g_OSVersionInfo.dwPlatformId)
  351. {
  352. return TRUE;
  353. }
  354. // setup the User Profile Dir
  355. fValidToken = TRUE;
  356. if (!OpenThreadToken (GetCurrentThread(), TOKEN_READ,TRUE, &hToken))
  357. {
  358. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ,
  359. &hToken))
  360. {
  361. AssertSz(0,"Failed to GetToken");
  362. fValidToken = FALSE;
  363. }
  364. }
  365. if (fValidToken)
  366. {
  367. DWORD cbSize;
  368. // Call GetUserProfile once for Size and then again for real allocation
  369. cbSize = 0;
  370. GetUserProfileDirectory(hToken,NULL,&cbSize);
  371. if (cbSize > 0)
  372. {
  373. WCHAR *pwszProfileDir = (WCHAR *) ALLOC(cbSize*sizeof(WCHAR));
  374. if (pwszProfileDir && GetUserProfileDirectory(hToken,pwszProfileDir,&cbSize))
  375. {
  376. fSetEnviron = SetEnvironmentVariable(SZ_ENVIRONVARIABLE_USERPROFILE,pwszProfileDir);
  377. }
  378. if (pwszProfileDir)
  379. {
  380. FREE(pwszProfileDir);
  381. }
  382. }
  383. Assert(fSetEnviron); // assert if anything fails when we have a valid token
  384. CloseHandle(hToken);
  385. }
  386. // setup the UserName
  387. TCHAR szBuffer[UNLEN + 1];
  388. DWORD dwBufSize = sizeof(szBuffer)/sizeof(TCHAR);
  389. if (GetUserName(szBuffer,&dwBufSize))
  390. {
  391. fSetUserName = SetEnvironmentVariable(SZ_ENVIRONVARIABLE_USERNAME,szBuffer);
  392. Assert(fSetUserName);
  393. }
  394. return (fSetEnviron && fSetUserName);
  395. }