// Notiflag.cpp : Defines the entry point for the application. //*********************************************************************** // Reads a local XML file, hits the given url and gets back xml string // with another url, places an icon in system tray and links it to the url.. // Copyright : Microsoft Corporation. PSSODEV team. // // Author : K J Babu (v-kjbad) // Pramod Walvekar (v-pramwa) // //*********************************************************************** //includes #include "stdafx.h" #include "resource.h" #include "Notiflag.h" #include //#define _WIN32_IE 0x0500 #include #include #include #include #include #include #include #include #include //#include //defined in notiflag.h //#define WM_ICON WM_USER+333 #define WM_ICON 0xBFFF #define ID_MYICON 5 // Global Variables: HINSTANCE g_hInst; // current instance WCHAR szTitle[_MAX_PATH + 1]; // title bar text WCHAR szTaskName[_MAX_PATH + 1]; WCHAR szWindowClass[_MAX_PATH + 1]; // window class name WCHAR szURL[_MAX_PATH + 1]; // URL to call if user clicks on the icon HRESULT hr = ERROR_SUCCESS; HWND g_Hwnd; //****************************************************************** // Main function // // checks for the program instance // reads the client's incident list xml file // makes a call to remoteURL and reads the returned xml // adds program's executable path in the registry and // loads the icon in system area (tray) // waits for the single click on the icon and on single click // removes the entry from the registry, load the IE window with URL // and exits. //****************************************************************** extern "C" int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { MSG msg; int tmpDbgFlag; int nNumArgs = 0; LPCTSTR *cmdArgs = (LPCTSTR*)CommandLineToArgvW(GetCommandLineW(), &nNumArgs); #ifdef _DEBUG MessageBox(0, cmdArgs[0], L"app path", 0); #endif LoadString(hInstance, IDS_APP_TITLE, szTitle, _MAX_PATH); // check the previous instance of the program here // return if program is already running. HANDLE hMutex = CreateMutex(NULL,TRUE,szTitle); if(ERROR_ALREADY_EXISTS == GetLastError()) return 0; /* * Set the debug-heap flag to keep freed blocks in the * heap's linked list - This will allow us to catch any * inadvertent use of freed memory */ tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmpDbgFlag |= _CRTDBG_DELAY_FREE_MEM_DF; tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF; _CrtSetDbgFlag(tmpDbgFlag); // check if there are any command line parameters if (nNumArgs > 1) { // check if the first parameter is either /t or -t, which indicates AddNotiTask if((_tcscmp(cmdArgs[1], L"/t") == 0)||(_tcscmp(cmdArgs[1], L"-t") == 0)) { // as first argument is /t or -t, run the AddNotiTask component hr = CallAddNotiTask(hInstance, cmdArgs, lpCmdLine); if(FAILED(hr)) goto endMain; } } else { hr = CallNotiflag(hInstance); if(FAILED(hr)) goto endMain; //*** change the priorty of the program SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); // ***** All house keeping work done. start the program now... // Perform application initialization: if (!InitInstance (hInstance, nCmdShow)) goto endMain; #ifdef _DEBUG MessageBox(0, L"Loading Icon...", L"NotiFlag: msg", 0); #endif // add the icon in system tray HICON hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_FLAGICON)); if(hIcon != NULL) { BOOL bRet = MyTaskBarAddIcon(g_Hwnd, ID_MYICON, hIcon); DestroyIcon(hIcon); if (bRet == FALSE)// failed to create the system icon goto endMain; } #ifdef _DEBUG MessageBox(0, L"Icon loaded! waiting for click", L"NotiFlag: msg", 0); #endif // main message loop while (GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } #ifdef _DEBUG MessageBox(0, L"closing NotiFlag program", L"NotiFlag: msg", 0); #endif // remove the icon from system tray and do other cleaning, exit. // } CloseHandle(hMutex); return (int)msg.wParam; endMain: CloseHandle(hMutex); return -1; } //********************************************************************************* // MyRegisterClass // // PURPOSE: Registers the window class. //********************************************************************************* ATOM MyRegisterClass(HINSTANCE hInstance) { USES_CONVERSION; WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_FLAGICON); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCTSTR)IDC_NOTIFLAG; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_FLAGICON ); return RegisterClassEx(&wcex); } //********************************************************************************* // InitInstance(HANDLE, int) // // PURPOSE: Saves instance handle and creates main window // // COMMENTS: // // In this function, we save the instance handle in a global variable and // create and display the main program window. //********************************************************************************* BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { // create the window with no display g_Hwnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); return (g_Hwnd)?TRUE:FALSE; } //********************************************************************************* // WndProc(HWND, unsigned, WORD, LONG) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return //********************************************************************************* LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_COMMAND: switch(LOWORD(wParam)) { case IDC_DISABLE: // if user chose to disable task hr = DisableTask(); // disable the task if (FAILED(hr)) #ifdef _DEBUG MessageBox(hWnd,L"Failed to disable task",L"PSSIncidentNotification",MB_OK); #endif MyTaskBarDeleteIcon(g_Hwnd,ID_MYICON); // remove icon from tray DestroyWindow(g_Hwnd); // end application break; case IDC_SETFREQUENCY: // if user chose to change the frequency of the task hr = EditTask(); // display task schedule settings so user can change it if (FAILED(hr)) #ifdef _DEBUG MessageBox(hWnd,L"No Changes in task",L"PSSIncidentNotification",MB_OK); #endif break; default: break; } break; case WM_ICON: { if ((UINT)lParam == WM_LBUTTONDOWN) { // Show new Browser window with the given URL ShellExecute(g_Hwnd, L"open", szURL, NULL, NULL, SW_SHOWNORMAL); MyTaskBarDeleteIcon(g_Hwnd,ID_MYICON); DestroyWindow(g_Hwnd); } //if(((UINT)lParam == 0x204) || ((UINT)lParam == 0x205)) if ((UINT)lParam == WM_RBUTTONDOWN) // if user clicks right button { POINT sPoint; HMENU hMenu=LoadMenu(g_hInst,MAKEINTRESOURCE(IDC_NOTIFLAG)); // load menu if(hMenu!=NULL) { HMENU hSubMenu=GetSubMenu(hMenu,0); GetCursorPos(&sPoint); // get location of mouse SetForegroundWindow(hWnd); TrackPopupMenu(hSubMenu,TPM_LEFTALIGN|TPM_TOPALIGN|TPM_RIGHTBUTTON ,sPoint.x,sPoint.y,0,hWnd,NULL); // track the menu PostMessage(hWnd, WM_NULL, 0, 0); DestroyMenu(hMenu); } } break; } case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } //**************************************************************************** // MyTaskBarAddIcon // // adds an icon to system tray. // Returns : TRUE if successful, or FALSE otherwise. //**************************************************************************** BOOL MyTaskBarAddIcon(HWND hwnd, UINT uID, HICON hicon) { NOTIFYICONDATA tnid={0}; // Find out what version of the shell we are using for tray icon stuff HINSTANCE hShellDll; DLLGETVERSIONPROC pDllGetVersion; DLLVERSIONINFO dvi; BOOL bUseTrayBalloon = FALSE; // balloon tooltip is supported only in shell32.dll 5.0, so check the version hShellDll = LoadLibrary(L"Shell32.dll"); if(hShellDll != NULL) { // enable balloon tooltip if IE version is greater than 5 pDllGetVersion = (DLLGETVERSIONPROC) GetProcAddress(hShellDll, "DllGetVersion"); dvi.cbSize = sizeof(dvi); if(pDllGetVersion != NULL && SUCCEEDED((*pDllGetVersion)(&dvi))) if(dvi.dwMajorVersion >= 5) bUseTrayBalloon = TRUE; FreeLibrary(hShellDll); } //fill icon structure tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = uID; tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; tnid.uCallbackMessage = WM_ICON; tnid.hIcon = hicon; LoadString(g_hInst, IDS_TOOLTIP, tnid.szTip, MAXSTRLEN(tnid.szTip)); if (bUseTrayBalloon) // if IE version supports this then... { tnid.uFlags |= NIF_INFO; tnid.uTimeout = 60000; // in milliseconds tnid.dwInfoFlags = NIIF_INFO; LoadString(g_hInst, IDS_BALLOONTITLE, tnid.szInfoTitle, MAXSTRLEN(tnid.szInfoTitle)); LoadString(g_hInst, IDS_BALLOONTIP, tnid.szInfo, MAXSTRLEN(tnid.szInfo)); } return Shell_NotifyIcon(NIM_ADD, &tnid); } //**************************************************************************** // MyTaskBarDeleteIcon // // deletes an icon from the taskbar status area. // Returns : TRUE if successful, or FALSE otherwise. //**************************************************************************** BOOL MyTaskBarDeleteIcon(HWND hwnd, UINT uID) { NOTIFYICONDATA tnid; tnid.cbSize = sizeof(NOTIFYICONDATA); tnid.hWnd = hwnd; tnid.uID = uID; return Shell_NotifyIcon(NIM_DELETE, &tnid); } //**************************************************************************** // LoadThisXml // // Load the given file in XMLDOM object and returns that pointer // Returns : XMLDom pointer //*************************************************************************** CComPtr LoadThisXml(const WCHAR *csFileName) { // get smart pointer to IXMLDOMDocument interface CComPtr pXmlDoc; VARIANT vFile; CComVariant vtest; VARIANT_BOOL vb=1; HRESULT hr; CComBSTR bstrVal(csFileName); // this has the output file //initialize the variant VariantInit(&vFile); vFile.vt = VT_BSTR; //specify that it contains a string hr = CoCreateInstance(CLSID_DOMDocument, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pXmlDoc); if (FAILED(hr)) return NULL; //increase ref count, else pointer will be released twice before CoUnInitialize() and // will throw exception pXmlDoc.p->AddRef(); V_BSTR(&vFile) = bstrVal; pXmlDoc->put_async(VARIANT_FALSE); hr = pXmlDoc->load(vFile, &vb); if (FAILED (hr) || vb == 0) return NULL; VariantClear(&vFile); return pXmlDoc; } //**************************************************************************** // LoadHTTPRequestXml // // Makes the request to the asp page and gets the XML out of Response. // Returns : XMLDom pointer //**************************************************************************** CComPtr LoadHTTPRequestXml(WCHAR *csURL, CComPtr pDoc) { CComPtr pXmlDoc; CComPtr pRequest; CComPtr pDispRes; CComPtr pDisp; HRESULT hr; // create an instance of XMLHTTPRequest and open the connection hr = CoCreateInstance(CLSID_XMLHTTPRequest, NULL, CLSCTX_INPROC_SERVER, IID_IXMLHttpRequest, (void**)&pRequest); if (FAILED(hr)) goto endRequestXml; //hr = pRequest->open(CComBSTR(L("POST")), CComBSTR(csURL), _variantL(VARIANT_FALSE)); hr = pRequest->open( CComBSTR( L"POST" ), CComBSTR( csURL ), CComVariant(VARIANT_FALSE), CComVariant(), CComVariant()); if(FAILED(hr)) goto endRequestXml; hr = pRequest->setRequestHeader(CComBSTR(L"ACCEPT_LANGUAGE"),CComBSTR(L"en-us")); if(FAILED(hr)) goto endRequestXml; // send the xml now. Get the Dispatch pointer of XML hr = pDoc->QueryInterface(IID_IDispatch, (void **)&pDisp); if (FAILED(hr)) goto endRequestXml; #ifdef _DEBUG MessageBox(0, L"calling send", L"NotiFlag: LoadHTTPRequestXml", 0); #endif // call send VARIANT varDisp; varDisp.vt = VT_DISPATCH; varDisp.pdispVal = pDisp; hr = pRequest->send(varDisp); if (FAILED(hr)) goto endRequestXml; VariantClear(&varDisp); #ifdef _DEBUG MessageBox(0, L"calling getxmlresponse", L"NotiFlag: LoadHTTPRequestXml", 0); #endif // Read the response hr = pRequest->get_responseXML(&pDispRes); if (FAILED(hr)) goto endRequestXml; // get the XMLDom pointer from iDispatch hr = pDispRes->QueryInterface(IID_IXMLDOMDocument, (void **)&pXmlDoc); if (FAILED(hr)) goto endRequestXml; return pXmlDoc; endRequestXml: return NULL; } //*********************************************************************************** // GetNodeValue // // Reads the node value from the given XMLDOMDocument and copies into csValue. // Returns : 0 = success & -ve = error. //*********************************************************************************** int GetNodeValue(CComPtr pXmlDoc,const WCHAR *csNode, WCHAR *csValue) { CComPtr pNode; CComBSTR bstrIdValue(csNode); CComVariant vIdValue; HRESULT hr; // get to the node hr = pXmlDoc->selectSingleNode(bstrIdValue, &pNode); if (FAILED(hr) || pNode == NULL) return -1; // read the value of the specified tag hr = pNode->get_nodeValue(&vIdValue); if (FAILED(hr)) return -1; { USES_CONVERSION; wcscpy( csValue, vIdValue.bstrVal ); } return 0; } //*********************************************************************************** // CallNotiflag // // Loads local xml file and extracts url from it, hits the url, retrieves xml string // Loads the retrieved xml string, checks a few conditions and if met, // loads an icon in the system tray and when the user clicks on the icon, // it takes him to that url in the HSS browser // Returns : S_OK for success, E_FAIL for failure //*********************************************************************************** HRESULT CallNotiflag(HINSTANCE hInstance) { #ifdef _DEBUG MessageBox(0, L"Notiflag is active", L"Active", 0); #endif // Initialize global strings LoadString(hInstance, IDS_APP_TITLE, szTitle, _MAX_PATH); LoadString(hInstance, IDC_NOTIFLAG, szWindowClass, _MAX_PATH); MyRegisterClass(hInstance); hr = CoInitialize(NULL); if (FAILED(hr)) goto endNoti; { //*** to read the xml file info //declare smart pointers to XMLDOMDocument Interface CComPtr pSvrXmlDoc; CComPtr pUserXmlDoc; //string variables to hold xml file path and node text WCHAR csXmlFilePath[_MAX_PATH + 1]; WCHAR csUserXmlFile[_MAX_PATH + 1]; WCHAR csNode[_MAX_PATH + 1]; WCHAR csValue[1024]; WCHAR csUserProfile[_MAX_PATH + 1]; csValue[0] = '\0'; // get the user profile path LoadString(hInstance, IDS_USERPROFILE, csUserProfile, _MAX_PATH); GetEnvironmentVariable(csUserProfile, csUserXmlFile, _MAX_PATH); //concatenate the xml file name to the profile path LoadString(hInstance, IDS_XMLFILEPATH, csXmlFilePath, _MAX_PATH); _tcscat(csUserXmlFile, csXmlFilePath); #ifdef _DEBUG MessageBox(0, csUserXmlFile, L"NotiFlag: client xml", 0); #endif // load this xml file if ((pUserXmlDoc = LoadThisXml(csUserXmlFile)) == NULL) goto endNoti; //get the value of the node "IncidentID" LoadString(hInstance, IDS_INCIDENTID, csNode, _MAX_PATH); if (GetNodeValue(pUserXmlDoc, csNode, csValue)) goto endNoti; if (csValue[0] != '\0') { //get the value of the node "RemoteURL" LoadString(hInstance, IDS_REMOTEURL, csNode, _MAX_PATH); if (GetNodeValue(pUserXmlDoc, csNode, csValue)) goto endNoti; } #ifdef _DEBUG MessageBox(0, L"calling the asp file", L"NotiFlag: msg", 0); #endif // load the server ASP page and load returned XML string in XMLDOM if ((pSvrXmlDoc = LoadHTTPRequestXml(csValue, pUserXmlDoc)) == NULL) goto endNoti; _tcscpy(csValue, L"\0"); //get the value of the node "ResponseCount" LoadString(hInstance, IDS_RESPONSECOUNT, csNode, _MAX_PATH); if (GetNodeValue(pSvrXmlDoc, csNode, csValue)) goto endNoti; if ((atoi((const char *)csValue)) <= 0) goto endNoti; // else proceed #ifdef _DEBUG MessageBox(0, L"reading values", L"NotiFlag: main", 0); #endif // load the URL to hit LoadString(hInstance, IDS_LOCATIONTOHIT, csNode, _MAX_PATH); if (GetNodeValue(pSvrXmlDoc, csNode, szURL) || szURL == NULL) goto endNoti; // load the serverdatetime LoadString(hInstance, IDS_SERVERDATETIME, csNode, _MAX_PATH); if (GetNodeValue(pSvrXmlDoc, csNode, csValue)) goto endNoti; #ifdef _DEBUG MessageBox(0, L"putting date and saving client xml", L"NotiFlag: main", 0); #endif } //Close the COM library and release resources CoUninitialize(); return hr=S_OK; endNoti: CoUninitialize(); return hr=E_FAIL; } //*********************************************************************************** // CallAddNotiTask // // Creates a new task in the scheduler // Returns : S_OK for success, E_FAIL for failure //*********************************************************************************** HRESULT CallAddNotiTask(HINSTANCE hInstance, LPCTSTR *cmdArgs,LPTSTR lpCmdLine) { #ifdef _DEBUG MessageBox(0, L"AddNotiTask is Active", L"Active", 0); MessageBox(0, cmdArgs[1], L"First argument", 0); #endif hr = CoInitialize(NULL); if (FAILED(hr)) goto endAddNotiTask; { // smart interface pointers CComPtr pITS; CComPtr pITaskUnknown; CComPtr pIScheduledWorkItem; CComPtr pITaskTrigger; CComPtr pITask; CComBSTR bstrAccName(lpCmdLine); CComBSTR bstrVal; WCHAR szUserName[_MAX_PATH + 1]; WCHAR szRegEntry[_MAX_PATH + 1]; DWORD cchUserName = MAXSTRLEN(szUserName); if ( !GetUserName( szUserName, &cchUserName ) ) goto endAddNotiTask; BOOL bTaskExists=FALSE; // Create a Task Schedular object ... hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pITS); if (FAILED(hr)) goto endAddNotiTask; //////////////////////////////////////////////////////// // Check/Create a work item/Task //////////////////////////////////////////////////////// LoadString(hInstance, IDS_TASKNAME, szTaskName, _MAX_PATH); // check if the work item already exists if(SUCCEEDED(pITS->Activate((LPCWSTR)szTaskName, IID_ITask, &pITaskUnknown))) { bTaskExists = TRUE; hr = pITaskUnknown.QueryInterface(&pITask); goto endAddNotiTask; } else { // create a new work item hr = pITS->NewWorkItem(szTaskName, // Name of task CLSID_CTask, // Class identifier IID_ITask, // Interface identifier (IUnknown**)&pITask); // Address of task interface } if (FAILED(hr)) goto endAddNotiTask; // set the account information hr = pITask->QueryInterface(IID_IScheduledWorkItem, (void**)&pIScheduledWorkItem); if (FAILED(hr) || pIScheduledWorkItem==NULL) goto endAddNotiTask; hr = pIScheduledWorkItem->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON|TASK_FLAG_INTERACTIVE); // TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); if (FAILED(hr)) goto endAddNotiTask; hr = pIScheduledWorkItem->SetAccountInformation((LPCWSTR)szUserName, NULL); if (FAILED(hr)) goto endAddNotiTask; // get the exe path ... { bstrVal = cmdArgs[0]; hr = pITask->SetApplicationName(bstrVal); if (FAILED (hr)) goto endAddNotiTask; } /////////////////////////////////////////////////////////////////// // Define TASK_TRIGGER structure. // Check/Create the new trigger. /////////////////////////////////////////////////////////////////// TASK_TRIGGER pTrigger; ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); if (bTaskExists) { hr = pIScheduledWorkItem->GetTrigger(0, &pITaskTrigger); if (FAILED(hr) || pITaskTrigger == NULL) goto endAddNotiTask; hr = pITaskTrigger->GetTrigger(&pTrigger); if (FAILED(hr)) goto endAddNotiTask; } else { WORD piNewTrigger; hr = pIScheduledWorkItem->CreateTrigger(&piNewTrigger, &pITaskTrigger); if (FAILED(hr)) goto endAddNotiTask; } if (FAILED(hr) || pITaskTrigger == NULL) goto endAddNotiTask; // add the entry in the registry { TCHAR szExePath[_MAX_PATH + 1]; HKEY hKey; if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\PSS\\Notification", 0, KEY_ALL_ACCESS, &hKey)) { #ifdef _DEBUG MessageBox(0, L"no registry entry", L"notitask", 0); #endif // if key doesnt exist, use default values pTrigger.wStartHour = 2; // start from the 1st hour pTrigger.wStartMinute = 0; pTrigger.MinutesDuration = 1440; // for 24 hours pTrigger.MinutesInterval = 15; // every 1 hour // Note that wBeginDay, wBeginMonth, and wBeginYear must // be set to a valid day, month, and year respectively. pTrigger.wBeginDay = 1; // Required - 1st pTrigger.wBeginMonth = 12; // Required - December pTrigger.wBeginYear = 2000; // Required - 2000 } else { #ifdef _DEBUG MessageBox(0, L"registry entry exists", L"notitask", 0); #endif // if key exists, read from registry DWORD lpType = 4; // type buffer DWORD lpData=0; // data buffer DWORD lpcbData=sizeof(DWORD); // size of data buffer LoadString(NULL, IDS_WSTARTHOUR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (LPBYTE)&lpData, &lpcbData )) return -1; pTrigger.wStartHour = (WORD)lpData; // start from the 1st hour LoadString(NULL, IDS_WSTARTMINUTE, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (LPBYTE)&lpData, &lpcbData )) return -1; pTrigger.wStartMinute = (WORD)lpData; LoadString(NULL, IDS_MINUTESDURATION, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (LPBYTE)&lpData, &lpcbData )) return -1; pTrigger.MinutesDuration = (WORD)lpData; // for 24 hours LoadString(NULL, IDS_FREQUENCY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.MinutesInterval = (WORD)lpData; // for 24 hours LoadString(NULL, IDS_WBEGINDAY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.wBeginDay = (WORD)lpData; // date of the month LoadString(NULL, IDS_WBEGINMONTH, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.wBeginMonth = (WORD)lpData; // month LoadString(NULL, IDS_WBEGINYEAR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegQueryValueEx(hKey, szRegEntry,0, &lpType, (BYTE *)&lpData, &lpcbData )) return -1; pTrigger.wBeginYear = (WORD)lpData; // year } pTrigger.TriggerType = TASK_TIME_TRIGGER_DAILY; pTrigger.Type.Daily.DaysInterval = 1; // daily!! // get the application's executable path ::GetModuleFileName(hInstance, szExePath, _MAX_PATH); if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\PSS\\Notification", 0, KEY_ALL_ACCESS, &hKey)) { DWORD dwDisposition; DWORD szwStartHour = 1; DWORD szwStartMinute = 0; DWORD szMinutesDuration=1440; DWORD szMinutesInterval =15; DWORD szwBeginDay = 1; DWORD szwBeginMonth = 12; DWORD szwBeginYear = 2000; LoadString(NULL, IDS_REGKEY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegCreateKeyEx(HKEY_CURRENT_USER, szRegEntry, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &hKey, &dwDisposition)) return -1; LoadString(NULL, IDS_WSTARTHOUR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartHour, sizeof(szwStartHour))) return -1; LoadString(NULL, IDS_WSTARTMINUTE, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartMinute, sizeof(szwStartMinute))) return -1; LoadString(NULL, IDS_MINUTESDURATION, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesDuration, sizeof(szMinutesDuration))) return -1; LoadString(NULL, IDS_FREQUENCY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesInterval, sizeof(szMinutesInterval))) return -1; LoadString(NULL, IDS_WBEGINDAY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginDay, sizeof(szwBeginDay))) return -1; LoadString(NULL, IDS_WBEGINMONTH, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginMonth, sizeof(szwBeginMonth))) return -1; LoadString(NULL, IDS_WBEGINYEAR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginYear, sizeof(szwBeginYear))) return -1; } RegCloseKey(hKey); } // Call ITaskTrigger::SetTrigger to set trigger criteria. hr = pITaskTrigger->SetTrigger (&pTrigger); if (FAILED(hr)) goto endAddNotiTask; ///////////////////////////////////////////////////////////////// // Call IUnknown::QueryInterface to get a pointer to // IPersistFile and IPersistFile::Save to save // the new task to disk. ///////////////////////////////////////////////////////////////// CComPtr pIPersistFile; hr = pITask->QueryInterface(IID_IPersistFile, (void **)&pIPersistFile); if (FAILED(hr) || pIPersistFile == NULL) goto endAddNotiTask; hr = pIPersistFile->Save(NULL, FALSE); if (FAILED(hr)) goto endAddNotiTask; } CoUninitialize(); return hr = S_OK; endAddNotiTask: CoUninitialize(); return hr=E_FAIL; } HRESULT DisableTask() { hr = CoInitialize(NULL); if (FAILED(hr)) goto endDisable; { CComPtr pITS; CComPtr pITaskUnknown; CComPtr pIScheduledWorkItem; CComPtr pITaskTrigger; CComPtr pITask; WCHAR szUserName[_MAX_PATH + 1]; DWORD cchUserName = MAXSTRLEN(szUserName); if ( !GetUserName( szUserName, &cchUserName ) ) goto endDisable; hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pITS); if (FAILED(hr)) goto endDisable; LoadString(NULL, IDS_TASKNAME, szTaskName, _MAX_PATH); if(SUCCEEDED(pITS->Activate((LPCWSTR)szTaskName, IID_ITask, &pITaskUnknown))) { hr = pITaskUnknown.QueryInterface(&pITask); if (FAILED(hr)) goto endDisable; } hr = pITask->QueryInterface(IID_IScheduledWorkItem, (void**)&pIScheduledWorkItem); if (FAILED(hr) || pIScheduledWorkItem==NULL) goto endDisable; //set the flags to disable the task hr = pIScheduledWorkItem->SetFlags(TASK_FLAG_RUN_ONLY_IF_LOGGED_ON|TASK_FLAG_INTERACTIVE|TASK_FLAG_DISABLED); // TASK_FLAG_RUN_ONLY_IF_LOGGED_ON); if (FAILED(hr)) goto endDisable; // set the account information hr = pIScheduledWorkItem->SetAccountInformation((LPCWSTR)szUserName, NULL); if (FAILED(hr)) goto endDisable; ///////////////////////////////////////////////////////////////// // Call IUnknown::QueryInterface to get a pointer to // IPersistFile and IPersistFile::Save to save // the new task to disk. ///////////////////////////////////////////////////////////////// CComPtr pIPersistFile; hr = pITask->QueryInterface(IID_IPersistFile, (void **)&pIPersistFile); if (FAILED(hr) || pIPersistFile == NULL) goto endDisable; hr = pIPersistFile->Save(NULL, FALSE); if (FAILED(hr)) goto endDisable; } CoUninitialize(); return hr=S_OK; endDisable: CoUninitialize(); return hr=E_FAIL; } HRESULT EditTask() { hr = CoInitialize(NULL); if (FAILED(hr)) goto endEdit; { CComPtr pITS; CComPtr pITask; CComPtr pITaskTrigger; hr = CoCreateInstance(CLSID_CTaskScheduler, NULL, CLSCTX_INPROC_SERVER, IID_ITaskScheduler, (void **) &pITS); if (FAILED(hr)) goto endEdit; LoadString(NULL, IDS_TASKNAME, szTaskName, _MAX_PATH); hr = pITS->Activate(szTaskName, IID_ITask, (IUnknown**) &pITask); if (FAILED(hr)) goto endEdit; /////////////////////////////////////////////////////////////////// // Call ITask::QueryInterface to retrieve the IProvideTaskPage // interface, and call IProvideTaskPage::GetPage to retrieve the // task page. /////////////////////////////////////////////////////////////////// TASKPAGE tpType = TASKPAGE_SCHEDULE; BOOL fPersistChanges = TRUE; HPROPSHEETPAGE phPage; CComPtr pIProvTaskPage; hr = pITask->QueryInterface(IID_IProvideTaskPage, (void **)&pIProvTaskPage); if (FAILED(hr)) goto endEdit; hr = pIProvTaskPage->GetPage(tpType, fPersistChanges, &phPage); if (FAILED(hr)) goto endEdit; ////////////////////////////////////////////////////////////////// // Display the page using additional code ////////////////////////////////////////////////////////////////// PROPSHEETHEADER psh; ZeroMemory(&psh, sizeof(PROPSHEETHEADER)); psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW; psh.phpage = &phPage; psh.nPages = 1; INT_PTR psResult = PropertySheet(&psh); if (psResult <= 0) goto endEdit; /////////////////////////////////////////////////////////////////// // Define TASK_TRIGGER structure. // Check/Create the new trigger. /////////////////////////////////////////////////////////////////// TASK_TRIGGER pTrigger; ZeroMemory(&pTrigger, sizeof (TASK_TRIGGER)); pTrigger.cbTriggerSize = sizeof (TASK_TRIGGER); hr = pITask->GetTrigger(0, &pITaskTrigger); if (FAILED(hr) || pITaskTrigger == NULL) goto endEdit; hr = pITaskTrigger->GetTrigger(&pTrigger); if (FAILED(hr)) goto endEdit; // add the entry in the registry { DWORD szwStartHour = 1; DWORD szwStartMinute = 0; DWORD szMinutesDuration = 1440; DWORD szMinutesInterval =15; DWORD szwBeginDay = 1; DWORD szwBeginMonth = 12; DWORD szwBeginYear = 2000; WCHAR szRegEntry[_MAX_PATH + 1]; HKEY hKey; szwStartHour = pTrigger.wStartHour; szwStartMinute = pTrigger.wStartMinute; szMinutesInterval = pTrigger.MinutesInterval; szMinutesDuration = pTrigger.MinutesDuration; szwBeginDay = pTrigger.wBeginDay; szwBeginMonth = pTrigger.wBeginMonth; szwBeginYear = pTrigger.wBeginYear; LoadString(NULL, IDS_REGKEY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS == RegOpenKeyEx(HKEY_CURRENT_USER, szRegEntry, 0, KEY_ALL_ACCESS, &hKey)) { LoadString(NULL, IDS_WSTARTHOUR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartHour, sizeof(szwStartHour))) goto endEdit; LoadString(NULL, IDS_WSTARTMINUTE, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwStartMinute, sizeof(szwStartMinute))) goto endEdit; LoadString(NULL, IDS_MINUTESDURATION, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesDuration, sizeof(szMinutesDuration))) goto endEdit; LoadString(NULL, IDS_FREQUENCY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szMinutesInterval, sizeof(szMinutesInterval))) goto endEdit; LoadString(NULL, IDS_WBEGINDAY, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginDay, sizeof(szwBeginDay))) goto endEdit; LoadString(NULL, IDS_WBEGINMONTH, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginMonth, sizeof(szwBeginMonth))) goto endEdit; LoadString(NULL, IDS_WBEGINYEAR, szRegEntry, _MAX_PATH); if (ERROR_SUCCESS != RegSetValueEx(hKey, szRegEntry, 0, REG_DWORD, (const BYTE *)&szwBeginYear, sizeof(szwBeginYear))) goto endEdit; } RegCloseKey(hKey); } } CoUninitialize(); return hr=S_OK; endEdit: CoUninitialize(); return hr=E_FAIL; }