|
|
//____________________________________________________________________________
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1995 - 1996.
//
// File: jobpages.cxx
//
// Contents:
//
// Classes:
//
// Functions:
//
// History: 3/5/1996 RaviR Created
//
//____________________________________________________________________________
#include "..\pch\headers.hxx"
#pragma hdrstop
#include <mstask.h>
#include "defines.h"
#include "..\inc\resource.h"
#include "..\inc\common.hxx"
#include "..\folderui\dbg.h"
#include "..\folderui\macros.h"
#include "..\folderui\util.hxx"
#include "..\rc.h"
#include "shared.hxx"
#include "schedui.hxx"
#define ARRAYSIZE(a) (sizeof(a)/sizeof(a[0]))
//void LogIt(WCHAR* pLine)
//{
// FILE* pFile;
// pFile = fopen("C:\\hmh.log", "a+");
//
// if (pFile)
// {
// fputws(pLine, pFile);
// fflush(pFile);
// fclose(pFile);
// }
//}
//void LogFunnyString(WCHAR* pLine, UINT count)
//{
// FILE* pFile;
// pFile = fopen("C:\\hmh.log", "a+");
//
// if (pFile)
// {
// fputws(L"Funny file name:\n\t",pFile);
// for(UINT i = 0; i < count; i++)
// fputwc(pLine[i], pFile);
// fputws(L"\n",pFile);
//
// fflush(pFile);
// fclose(pFile);
// }
//}
//
// extern EXTERN_C
//
extern HINSTANCE g_hInstance;
//
// Local constants
//
TCHAR const FAR c_szNULL[] = TEXT(""); TCHAR const FAR c_szStubWindowClass[] = TEXT("JobPropWnd");
#define STUBM_SETDATA (WM_USER + 1)
#define STUBM_GETDATA (WM_USER + 2)
#define JF_PROPSHEET_STUB_CLASS 78345
LRESULT CALLBACK StubWndProc( HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam) { switch(iMessage) { case STUBM_SETDATA: SetWindowLongPtr(hWnd, 0, wParam); return TRUE;
case STUBM_GETDATA: return GetWindowLongPtr(hWnd, 0);
default: return DefWindowProc(hWnd, iMessage, wParam, lParam); } }
HWND I_CreateStubWindow(void) { WNDCLASS wndclass;
if (!GetClassInfo(g_hInstance, c_szStubWindowClass, &wndclass)) { wndclass.style = 0; wndclass.lpfnWndProc = StubWndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = sizeof(PVOID) * 2; wndclass.hInstance = g_hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = c_szStubWindowClass;
if (!RegisterClass(&wndclass)) return NULL; }
return CreateWindowEx(WS_EX_TOOLWINDOW, c_szStubWindowClass, c_szNULL, WS_OVERLAPPED, CW_USEDEFAULT, CW_USEDEFAULT, 0, 0, NULL, NULL, g_hInstance, NULL); }
HANDLE StuffStubWindow( HWND hwnd, LPTSTR pszFile) { DWORD dwProcId; HANDLE hSharedFile; UINT uiFileSize;
uiFileSize = (lstrlen(pszFile) + 1) * sizeof(TCHAR);
GetWindowThreadProcessId(hwnd, &dwProcId);
hSharedFile = SCHEDAllocShared(NULL, sizeof(int)+uiFileSize, dwProcId);
if (hSharedFile) { LPBYTE lpb = (LPBYTE)SCHEDLockShared(hSharedFile, dwProcId);
if (lpb) { *(int *)lpb = JF_PROPSHEET_STUB_CLASS; CopyMemory(lpb+sizeof(int), pszFile, uiFileSize); SCHEDUnlockShared(lpb); SendMessage(hwnd, STUBM_SETDATA, (WPARAM)hSharedFile, 0); return hSharedFile; } SCHEDFreeShared(hSharedFile, dwProcId); }
return NULL; }
HWND FindOtherStub( LPTSTR pszFile) { HWND hwnd;
//
// BUGBUG using getwindow in a loop is not safe. this code should
// use EnumWindows instead. From win32 sdk:
//
// "[EnumWindows] is more reliable than calling the GetWindow function in
// a loop. An application that calls GetWindow to perform this task risks
// being caught in an infinite loop or referencing a handle to a window
// that has been destroyed."
//
for (hwnd = FindWindow(c_szStubWindowClass, NULL); hwnd != NULL; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) { TCHAR szClass[80];
// find stub windows only
GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
if (lstrcmpi(szClass, c_szStubWindowClass) == 0) { int iClass; HANDLE hSharedFile; DWORD dwProcId; LPTSTR pszTemp;
GetWindowThreadProcessId(hwnd, &dwProcId);
hSharedFile = (HANDLE)SendMessage(hwnd, STUBM_GETDATA, 0, 0);
if (hSharedFile) { LPBYTE lpb;
lpb = (LPBYTE)SCHEDLockShared(hSharedFile, dwProcId); pszTemp = (LPTSTR) (lpb + sizeof(int));
if (lpb) { iClass = *(int *)lpb;
if (iClass == JF_PROPSHEET_STUB_CLASS && lstrcmpi(pszTemp, pszFile) == 0) { SCHEDUnlockShared(lpb); return hwnd; }
SCHEDUnlockShared(lpb); } } } } return NULL; }
STDMETHODIMP I_GetTaskPage( ITask * pIJob, TASKPAGE tpType, BOOL fPersistChanges, HPROPSHEETPAGE * phPage) { TRACE_FUNCTION(I_GetTaskPage);
HRESULT hr = S_OK; LPOLESTR polestr = NULL;
do { //
// Ensure that the object has a file name.
//
IPersistFile * ppf = NULL;
hr = pIJob->QueryInterface(IID_IPersistFile, (void **)&ppf);
CHECK_HRESULT(hr); BREAK_ON_FAIL(hr);
hr = ppf->GetCurFile(&polestr);
CHECK_HRESULT(hr); BREAK_ON_FAIL(hr);
ppf->Release();
if (hr == S_FALSE) { hr = STG_E_NOTFILEBASEDSTORAGE;
CHECK_HRESULT(hr); break; }
//
// Establish if this task exists within a task's folder.
//
LPTSTR ptszJobPath; ptszJobPath = polestr; if (ptszJobPath == NULL) { hr = E_OUTOFMEMORY; CHECK_HRESULT(hr); break; }
//
// Get the page
//
switch (tpType) { case TASKPAGE_TASK: { hr = GetGeneralPage(pIJob, ptszJobPath, fPersistChanges, phPage); CHECK_HRESULT(hr); break; } case TASKPAGE_SCHEDULE: hr = GetSchedulePage(pIJob, ptszJobPath, fPersistChanges, phPage); CHECK_HRESULT(hr); break;
case TASKPAGE_SETTINGS: hr = GetSettingsPage(pIJob, ptszJobPath, fPersistChanges, phPage); CHECK_HRESULT(hr); break;
default: hr = E_INVALIDARG; CHECK_HRESULT(hr); break; }
} while (0);
if (polestr != NULL) { CoTaskMemFree(polestr); }
return hr; }
HRESULT DisplayJobProperties( LPDATAOBJECT pdtobj) { TRACE_FUNCTION(DisplayJobProperties);
HRESULT hr = S_OK; HANDLE hSharedFile = NULL; HWND hwnd = NULL; ITask * pIJob = NULL;
do { //
// Extract the job name from the data object.
//
STGMEDIUM stgm; FORMATETC fmte = {CF_HDROP, (DVTARGETDEVICE *)NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL};
hr = pdtobj->GetData(&fmte, &stgm);
CHECK_HRESULT(hr); BREAK_ON_FAIL(hr);
TCHAR szFile[MAX_PATH + 1]; UINT cchRet = DragQueryFile((HDROP)stgm.hGlobal, 0, szFile, MAX_PATH + 1); ReleaseStgMedium(&stgm);
if (cchRet == 0) { return E_FAIL; }
//
// See if the property page for this job is already being displayed.
//
if (NULL != (hwnd = FindOtherStub(szFile))) { SwitchToThisWindow(GetLastActivePopup(hwnd), TRUE); break; } else { hwnd = I_CreateStubWindow(); hSharedFile = StuffStubWindow(hwnd, szFile); }
//
// Bind to the ITask interface.
//
hr = JFCreateAndLoadTask(NULL, szFile, &pIJob); // if (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND))
// {
// LogIt(L"Got a path not found error\n");
// LogFunnyString(szFile, cchRet);
// }
// hack: sometimes we get a corrupted directory name
// let's see if we can't djinn up a proper name instead...
if (hr == HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND)) { WCHAR* pFoundName = PathFindFileName(szFile); WCHAR trialPath[MAX_PATH +1]; WCHAR* pTasksFolder;
if (SUCCEEDED(GetTasksFolder(&pTasksFolder))) { StringCchCopy(trialPath, MAX_PATH +1, pTasksFolder); StringCchCat(trialPath, MAX_PATH +1, L"\\"); StringCchCat(trialPath, MAX_PATH +1, pFoundName);
if (SUCCEEDED(hr = JFCreateAndLoadTask(NULL, trialPath, &pIJob))) StringCchCopy(szFile, MAX_PATH +1, trialPath);
delete[] pTasksFolder; } }
BREAK_ON_FAIL(hr);
LPTSTR pName = PathFindFileName(szFile); LPTSTR pExt = PathFindExtension(pName);
if (pExt) { *pExt = TEXT('\0'); }
//
// Add the pages.
//
HPROPSHEETPAGE ahpage[MAX_PROP_PAGES]; PROPSHEETHEADER psh;
SecureZeroMemory(&psh, sizeof(psh));
psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_DEFAULT; psh.hwndParent = hwnd; psh.hInstance = g_hInstance; psh.pszCaption = pName; psh.phpage = ahpage;
hr = AddGeneralPage(psh, pIJob); CHECK_HRESULT(hr);
hr = AddSchedulePage(psh, pIJob); CHECK_HRESULT(hr);
hr = AddSettingsPage(psh, pIJob); CHECK_HRESULT(hr);
hr = AddSecurityPage(psh, pdtobj); CHECK_HRESULT(hr);
if (psh.nPages == 0) { DEBUG_OUT((DEB_USER1, "No pages to display.\n")); hr = E_FAIL; break; }
PropertySheet(&psh);
} while (0);
if (pIJob != NULL) { pIJob->Release(); }
SCHEDFreeShared(hSharedFile, GetCurrentProcessId());
if (hwnd) { DestroyWindow(hwnd); }
return hr; }
HRESULT DisplayJobProperties( LPTSTR pszJob, ITask * pIJob) { Win4Assert(pszJob != NULL); Win4Assert(pIJob != NULL);
HRESULT hr = S_OK; PROPSHEETHEADER psh;
SecureZeroMemory(&psh, sizeof(psh));
do { //
// Determine the job name.
//
TCHAR szName[MAX_PATH + 1]; StringCchCopy(szName, MAX_PATH + 1, PathFindFileName(pszJob));
LPTSTR pExt = PathFindExtension(szName);
if (pExt) { *pExt = TEXT('\0'); }
//
// Add the pages.
//
HPROPSHEETPAGE ahpage[MAX_PROP_PAGES];
psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_DEFAULT; psh.hwndParent = I_CreateStubWindow(); psh.hInstance = g_hInstance; psh.pszCaption = szName; psh.phpage = ahpage;
hr = AddGeneralPage(psh, pIJob); CHECK_HRESULT(hr);
hr = AddSchedulePage(psh, pIJob); CHECK_HRESULT(hr);
hr = AddSettingsPage(psh, pIJob); CHECK_HRESULT(hr);
if (psh.nPages == 0) { DEBUG_OUT((DEB_USER1, "No pages to display.\n")); hr = E_FAIL; break; }
PropertySheet(&psh);
} while (0);
if (psh.hwndParent) { DestroyWindow(psh.hwndParent); }
return hr; }
HRESULT GetJobPath( ITask * pIJob, LPTSTR * ppszJobPath) { HRESULT hr = S_OK; LPOLESTR polestr = NULL; IPersistFile * ppf = NULL;
do { //
// Get the object name
//
hr = pIJob->QueryInterface(IID_IPersistFile, (void **)&ppf);
CHECK_HRESULT(hr); BREAK_ON_FAIL(hr);
hr = ppf->GetCurFile(&polestr);
CHECK_HRESULT(hr); BREAK_ON_FAIL(hr);
LPTSTR pszJobPath = NULL; pszJobPath = NewDupString(polestr); CoTaskMemFree(polestr); if (pszJobPath == NULL) { hr = E_OUTOFMEMORY; CHECK_HRESULT(hr); break; }
*ppszJobPath = pszJobPath;
} while (0);
if (ppf != NULL) { ppf->Release(); }
return hr; }
|