//+------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997. // // File: OneStop.cpp // // Contents: Main application // // Classes: // // Notes: // // History: 05-Nov-97 rogerg Created. // //-------------------------------------------------------------------------- #include "precomp.h" // Global Variables: HINSTANCE g_hInst = NULL; // current instance LANGID g_LangIdSystem; // LangId of system we are running on. DWORD g_WMTaskbarCreated; // TaskBar Created WindowMessage; // Forward declarations of functions included in this code module: BOOL InitApplication(HINSTANCE); BOOL InitInstance(HINSTANCE hInstance, int nCmdShow,CMsgServiceHwnd *pMsgService); void UnitApplication(); BOOL SetupUserEnvironment(); //+--------------------------------------------------------------------------- // // Function: WinMain, public // // Synopsis: The start of all things // // Arguments: Standard WinMain. // // Returns: // // Modifies: // // History: 18-Nov-97 rogerg Created. // //---------------------------------------------------------------------------- #ifdef _DEBUG extern DWORD g_ThreadCount; #endif // _DEBUG int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { MSG msg; CMsgServiceHwnd *pMsgService; BOOL fMsgServiceCreated = FALSE; HRESULT hr; g_hInst = hInstance; // Store instance handle in our global variable #ifdef _DEBUG InitDebugFlags(); #endif // _DEBUG InitCommonLib(); g_LangIdSystem = GetSystemDefaultLangID(); SetupUserEnvironment(); if (!hPrevInstance) { // Perform instance initialization: if (!InitApplication(hInstance)) { return (FALSE); } } hr = CoInitializeEx(NULL,COINIT_MULTITHREADED | COINIT_DISABLE_OLE1DDE); // main thread is freeThreaded if (FAILED(hr)) { AssertSz(0,"CoInitFailed"); return FALSE; } // Initialize the Message Service for all threads if (S_OK != InitMessageService()) { AssertSz(0,"Unable to Init Message Service"); return FALSE; } // crate a MessageService for main thread pMsgService = new CMsgServiceHwnd; if (pMsgService) { fMsgServiceCreated = pMsgService->Initialize(GetCurrentThreadId(),MSGHWNDTYPE_MAINTHREAD); Assert(fMsgServiceCreated); } if (fMsgServiceCreated && InitInstance(hInstance, nCmdShow,pMsgService)) { // hAccelTable = LoadAccelerators (hInstance, APPNAME); // Currently don't have any accelerators // Main message loop: while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } } else { msg.wParam = 0; if (pMsgService) // get rid of this threads messageService pMsgService->Destroy(); } UnitApplication(); // unitialize application. return (int)(msg.wParam); lpCmdLine; // This will prevent 'unused formal parameter' warnings } //+--------------------------------------------------------------------------- // // Function: InitApplication, public // // Synopsis: Peforms any application specific tasks // // Arguments: [hInstance] - hInstance. // // Returns: // // Modifies: // // History: 18-Nov-97 rogerg Created. // //---------------------------------------------------------------------------- BOOL InitApplication(HINSTANCE hInstance) { return TRUE; } //+--------------------------------------------------------------------------- // // Function: UnitApplication, public // // Synopsis: Peforms any application specific cleanup // // Arguments: // // Returns: // // Modifies: // // History: 19-Jun-98 rogerg Created. // //---------------------------------------------------------------------------- void UnitApplication() { ReleaseConnectionObjects(); // release global connection object class. gSingleNetApiObj.DeleteNetApiObj(); // get rid of globa NetObj Assert(g_ThreadCount == 0); // make sure all our threads are cleaned up. CoFreeUnusedLibraries(); CoUninitialize(); UnInitCommonLib(); } //+--------------------------------------------------------------------------- // // Function: InitInstance, public // // Synopsis: Peforms instance specific initialization // // Arguments: [hInstance] - hInstance. // [nCmdShow] - value to start windows as // [pMsgService] - Message service for this instance // // Returns: TRUE will put application into a message loop // FALSE will cause application to terminate immediately // // Modifies: // // History: 18-Nov-97 rogerg Created. // //---------------------------------------------------------------------------- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow,CMsgServiceHwnd *pMsgService) { HRESULT hr; CCmdLine cmdLine; DWORD cmdLineFlags; BOOL fEmbeddingFlag; ATOM aWndClass; g_WMTaskbarCreated = RegisterWindowMessage(L"TaskbarCreated"); // get taskbar created message. cmdLine.ParseCommandLine(); cmdLineFlags = cmdLine.GetCmdLineFlags(); fEmbeddingFlag = cmdLineFlags & CMDLINE_COMMAND_EMBEDDING; // register a windows class to store the icon for the OneStop dialogs // get an icon for the dialog WNDCLASS wc; wc.style = CS_DBLCLKS | CS_SAVEBITS | CS_BYTEALIGNWINDOW; wc.lpfnWndProc = DefDlgProcW; // WRAPPER, need wrappers for LoadIcon/LoadCursor. wc.cbClsExtra = 0; wc.cbWndExtra = DLGWINDOWEXTRA; wc.hInstance = g_hInst; wc.hIcon = LoadIcon(g_hInst, MAKEINTRESOURCE(IDI_SYNCMGR)); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH) (COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = TEXT(MAINDIALOG_HWNDCLASSNAME); aWndClass = RegisterClass(&wc); Assert(aWndClass); // if register flag is passed, just register and return. if (cmdLineFlags & CMDLINE_COMMAND_REGISTER) { AssertSz(0,"SyncMgr launched with obsolete /register flag."); return FALSE; } INITCOMMONCONTROLSEX controlsEx; controlsEx.dwSize = sizeof(INITCOMMONCONTROLSEX); controlsEx.dwICC = ICC_USEREX_CLASSES | ICC_WIN95_CLASSES | ICC_NATIVEFNTCTL_CLASS; InitCommonControlsEx(&controlsEx); hr = InitObjectManager(pMsgService); // Initialize Object manager if (S_OK != hr) { Assert(S_OK == hr); return FALSE; } hr = InitConnectionObjects(); // initialize connection objects. if (S_OK != hr) { Assert(S_OK == hr); return FALSE; } // If the embedding flag is set force a Register. // Review - Activate as Interactive user doesn't work for Logoff // don't register class factory for schedules or Idle since if an error occurs // we want TS to launch us again next time it is time for the // schedule to Fire. if (!(cmdLineFlags & CMDLINE_COMMAND_SCHEDULE) && !(cmdLineFlags & CMDLINE_COMMAND_IDLE)) { hr = RegisterOneStopClassFactory(fEmbeddingFlag); } else { hr = S_OK; } // if didn't force a register then continue on our journey // and wait to fail until CoCreateInstance does Assert( (S_OK == hr) || !fEmbeddingFlag); if (S_OK == hr || !fEmbeddingFlag ) { // if only /Embedding is specified we were launch to service someone else so // dont' do anything, just wait for them to connect. if (!fEmbeddingFlag) { LPPRIVSYNCMGRSYNCHRONIZEINVOKE pUnk; // If there are other command lines or known to the proper thing. (manual, schedule, etc.). // addref our lifetime in case update doesn't take, treat as external // since invoke can go to another process. AddRefOneStopLifetime(TRUE /*External*/); // if class factory registered successful then CoCreate if (SUCCEEDED(hr)) { // CODE REVIEW: // NOTENOTE: // Is this a valid use of CLSCTX_ALL ? hr = CoCreateInstance(CLSID_SyncMgrp,NULL,CLSCTX_ALL,IID_IPrivSyncMgrSynchronizeInvoke,(void **) &pUnk); } // if have failure either from class factory or CoCreateIntance // then create a class directlry. if (FAILED(hr)) { // this is really an error path that shouldn't happen. // AssertSz(SUCCEEDED(hr),"COM Activation Failed"); // If COM Activation Fails go ahead and create a class directly // unless it is a schedule or idle event. if ( !(cmdLineFlags & CMDLINE_COMMAND_SCHEDULE) && !(cmdLineFlags & CMDLINE_COMMAND_IDLE) ) { pUnk = new CSynchronizeInvoke; hr = pUnk ? S_OK : E_OUTOFMEMORY; // Assert(S_OK == hr); } } if (S_OK == hr) { AllowSetForegroundWindow(ASFW_ANY); // let mobsync.exe come to front if necessary if (cmdLineFlags & CMDLINE_COMMAND_LOGON) { pUnk->Logon(); } else if (cmdLineFlags & CMDLINE_COMMAND_LOGOFF) { pUnk->Logoff(); } else if (cmdLineFlags & CMDLINE_COMMAND_SCHEDULE) { pUnk->Schedule(cmdLine.GetJobFile()); } else if (cmdLineFlags & CMDLINE_COMMAND_IDLE) { pUnk->Idle(); } else { // default is a manual sync pUnk->UpdateAll(); } pUnk->Release(); } else { // AssertSz(0,"Unable to Create Invoke Instance"); } ReleaseOneStopLifetime(TRUE /*External*/); // Release our reference. } return TRUE; // even on failure return true, locking will take care of releasing object. } return (FALSE); // if couldn't forward the update then end. } //+--------------------------------------------------------------------------- // // Function: SetupUserEnvironment,private // // Synopsis: Sets up any use environment variables we need to run. // // When we are launched as interactive User by DCOM the // environment variables aren't set so we need to set // any up that us or the handlers rely on. // // Arguments: // // Returns: // // Modifies: // // History: 14-Aug-98 rogerg Created. // //---------------------------------------------------------------------------- #define SZ_ENVIRONVARIABLE_USERPROFILE TEXT("USERPROFILE") #define SZ_ENVIRONVARIABLE_USERNAME TEXT("USERNAME") BOOL SetupUserEnvironment() { HANDLE hToken = NULL; BOOL fValidToken; BOOL fSetEnviron = FALSE; BOOL fSetUserName = FALSE; // setup the User Profile Dir fValidToken = TRUE; if (!OpenThreadToken (GetCurrentThread(), TOKEN_READ,TRUE, &hToken)) { if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken)) { AssertSz(0,"Failed to GetToken"); fValidToken = FALSE; } } if (fValidToken) { DWORD cbSize; // Call GetUserProfile once for Size and then again for real allocation cbSize = 0; GetUserProfileDirectory(hToken,NULL,&cbSize); if (cbSize > 0) { WCHAR *pwszProfileDir = (WCHAR *) ALLOC(cbSize*sizeof(WCHAR)); if (pwszProfileDir && GetUserProfileDirectory(hToken,pwszProfileDir,&cbSize)) { fSetEnviron = SetEnvironmentVariable(SZ_ENVIRONVARIABLE_USERPROFILE,pwszProfileDir); } if (pwszProfileDir) { FREE(pwszProfileDir); } } Assert(fSetEnviron); // assert if anything fails when we have a valid token CloseHandle(hToken); } // setup the UserName TCHAR szBuffer[UNLEN + 1]; DWORD dwBufSize = ARRAYSIZE(szBuffer); if (GetUserName(szBuffer,&dwBufSize)) { fSetUserName = SetEnvironmentVariable(SZ_ENVIRONVARIABLE_USERNAME,szBuffer); Assert(fSetUserName); } return (fSetEnviron && fSetUserName); }