|
|
/////////////////////////////////////////////////////////////////////////////
// FILE : CoverPages.cpp //
// //
// DESCRIPTION : The implementation of fax cover pages node. //
// //
// AUTHOR : yossg //
// //
// HISTORY : //
// Feb 9 2000 yossg Create //
// Oct 17 2000 yossg //
// //
// Copyright (C) 2000 Microsoft Corporation All Rights Reserved //
/////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "snapin.h"
#include "FaxServer.h"
#include "FaxServerNode.h"
#include "CoverPages.h"
#include "oaidl.h"
#include "Icons.h"
#include <faxreg.h>
#include <commdlg.h>
#include "CovNotifyWnd.h"
#include <FaxUtil.h>
//////////////////////////////////////////////////////////////
// {4D0480C7-3DE2-46ca-B03F-5C018DF1AF4D}
static const GUID CFaxCoverPagesNodeGUID_NODETYPE = { 0x4d0480c7, 0x3de2, 0x46ca, { 0xb0, 0x3f, 0x5c, 0x1, 0x8d, 0xf1, 0xaf, 0x4d } };
const GUID* CFaxCoverPagesNode::m_NODETYPE = &CFaxCoverPagesNodeGUID_NODETYPE; const OLECHAR* CFaxCoverPagesNode::m_SZNODETYPE = OLESTR("4D0480C7-3DE2-46ca-B03F-5C018DF1AF4D"); const CLSID* CFaxCoverPagesNode::m_SNAPIN_CLASSID = &CLSID_Snapin;
//
// Static members
//
CColumnsInfo CFaxCoverPagesNode::m_ColsInfo; HANDLE CFaxCoverPagesNode::m_hStopNotificationThreadEvent = NULL;
/*
- CFaxCoverPagesNode::Init - * Purpose: * Create Event for shut down notification. * * Arguments: * * Return: * OLE error code */ HRESULT CFaxCoverPagesNode::Init() { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::Init")); HRESULT hRc = S_OK; DWORD ec = ERROR_SUCCESS;
//
// Get Sever Cover-page Dir for the current administrated server
//
CComBSTR bstrServerName = ((CFaxServerNode *)GetRootNode())->GetServerName(); if (!bstrServerName) { DebugPrintEx(DEBUG_ERR, TEXT("Out of memory. Failed to get server name.")); hRc = E_OUTOFMEMORY; goto Exit; }
if(!GetServerCpDir(bstrServerName, m_pszCovDir, sizeof(m_pszCovDir)/sizeof(m_pszCovDir[0]) //*//
) ) { ec = GetLastError(); if (ERROR_FILE_NOT_FOUND == ec) { DebugPrintEx( DEBUG_ERR, _T("Failed to find Server Cover-Page Dir. (ec : %ld)"), ec);
} else { DebugPrintEx( DEBUG_ERR, _T("Failed to get Server Cover-Page Dir. (ec : %ld)"), ec); } hRc = HRESULT_FROM_WIN32(ec); goto Exit; }
//
// Create the shutdown event. This event will be signaled when the app is
// about to quit.
//
if (NULL != m_hStopNotificationThreadEvent) // can happen while retargeting
{ hRc = RestartNotificationThread(); if (S_OK != hRc) { DebugPrintEx( DEBUG_ERR, _T("Fail to RestartNotificationThread.")); } } else //first time here.
{ m_hStopNotificationThreadEvent = CreateEvent (NULL, // No security
TRUE, // Manual reset
FALSE, // Starts clear
NULL); // Unnamed
if (NULL == m_hStopNotificationThreadEvent) { ec = GetLastError (); DebugPrintEx( DEBUG_ERR, TEXT("Fail to CreateEvent.")); //CR: NodeMsgBox(IDS_FAIL2CREATE_EVENT);
hRc = HRESULT_FROM_WIN32(ec);
goto Exit; } }
Exit: return hRc; }
/*
- CFaxCoverPagesNode::InsertColumns - * Purpose: * Adds columns to the default result pane. * * Arguments: * [in] pHeaderCtrl - IHeaderCtrl in the console-provided default result view pane * * Return: * OLE error code */ HRESULT CFaxCoverPagesNode::InsertColumns(IHeaderCtrl *pHeaderCtrl) { DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::InsertColumns")); HRESULT hRc = S_OK;
static ColumnsInfoInitData ColumnsInitData[] = { {IDS_COVERPAGES_COL1, FXS_NORMAL_COLUMN_WIDTH}, {IDS_COVERPAGES_COL2, FXS_NORMAL_COLUMN_WIDTH}, {IDS_COVERPAGES_COL3, FXS_NORMAL_COLUMN_WIDTH}, {LAST_IDS, 0} };
hRc = m_ColsInfo.InsertColumnsIntoMMC(pHeaderCtrl, _Module.GetResourceInstance(), ColumnsInitData); CHECK_RETURN_VALUE_AND_PRINT_DEBUG (_T("m_ColsInfo.InsertColumnsIntoMMC"))
Cleanup: return(hRc); }
/*
- CFaxCoverPagesNode::PopulateResultChildrenList - * Purpose: * Create the FaxInboundRoutingMethods children nodes * * Arguments: * * Return: * OLE error code */ HRESULT CFaxCoverPagesNode::PopulateResultChildrenList() { DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::PopulateResultChildrenList")); HRESULT hRc = S_OK;
CFaxCoverPageNode * pCoverPage = NULL; WCHAR szFileName[MAX_PATH+1];
size_t itFullDirectoryPathLen; TCHAR* pFullDirectoryPathEnd; //pointer to the NULL after dir path with '\'
WIN32_FIND_DATA findData;
DWORD ec; BOOL bFindRes; HANDLE hFile = INVALID_HANDLE_VALUE;
szFileName[0]= 0;
ATLASSERT (NULL != m_pszCovDir ); ATLASSERT ( wcslen(m_pszCovDir) < (MAX_PATH - sizeof(FAX_COVER_PAGE_FILENAME_EXT)/sizeof(WCHAR) - 1) );
//
// Create cover page mask
//
wcscpy(szFileName, m_pszCovDir); wcscat(szFileName, FAX_PATH_SEPARATOR_STR);
itFullDirectoryPathLen = wcslen(szFileName); pFullDirectoryPathEnd = wcschr(szFileName, L'\0');
wcscat(szFileName, FAX_COVER_PAGE_MASK);
//
// Find First File
//
hFile = FindFirstFile(szFileName, &findData); if(INVALID_HANDLE_VALUE == hFile) { ec = GetLastError(); if(ERROR_FILE_NOT_FOUND != ec) { hRc = HRESULT_FROM_WIN32(ec); DebugPrintEx( DEBUG_ERR, _T("FindFirstFile Failed. (ec: %ld)"), ec); goto Error; } else { DebugPrintEx( DEBUG_MSG, _T("No server cover pages were found.")); goto Exit; } } //
// while loop - add cover pages to the result pane view
//
bFindRes = TRUE; while(bFindRes) { if(itFullDirectoryPathLen + _tcslen(findData.cFileName) < MAX_PATH ) { _tcsncpy(pFullDirectoryPathEnd, findData.cFileName, MAX_PATH - itFullDirectoryPathLen); if (IsValidCoverPage(szFileName)) { //
// add the cover page to result pane
//
pCoverPage = NULL;
pCoverPage = new CFaxCoverPageNode(this, m_pComponentData); if (!pCoverPage) { hRc = E_OUTOFMEMORY; NodeMsgBox(IDS_MEMORY); DebugPrintEx( DEBUG_ERR, _T("Out of memory. (hRc: %08X)"), hRc); goto Error; } else { //
// Init
//
pCoverPage->InitParentNode(this);
hRc = pCoverPage->Init(&findData); if (FAILED(hRc)) { DebugPrintEx( DEBUG_ERR, _T("Fail to init cover page. (hRc: %08X)"), hRc); // done by called func NodeMsgBox(IDS_FAIL2INIT_COVERPAGE_DATA);
goto Error; } //
// add to list
//
hRc = this->AddChildToList(pCoverPage); if (FAILED(hRc)) { DebugPrintEx( DEBUG_ERR, _T("Fail to add property page for General Tab. (hRc: %08X)"), hRc);
NodeMsgBox(IDS_FAIL2ADD_COVERPAGE); goto Error; } else { pCoverPage = NULL; } } } else { DebugPrintEx( DEBUG_ERR, _T("File %ws was found to be an invalid *.cov file."), pFullDirectoryPathEnd); } } else { DebugPrintEx( DEBUG_ERR, _T("The file %ws path is too long"), pFullDirectoryPathEnd); }
//
// Find Next File
//
bFindRes = FindNextFile(hFile, &findData); if(!bFindRes) { ec = GetLastError(); if (ERROR_NO_MORE_FILES == ec) { break; } else { DebugPrintEx( DEBUG_ERR, _T("FindNexTFile Failed. (ec: %ld)"), ec);
hRc = HRESULT_FROM_WIN32(ec);
goto Exit; } } } //while(bFindRes)
//
// Create the Server's Cover-Page Directory listener notification thread
//
if (m_bIsFirstPopulateCall) { m_NotifyWin = new CFaxCoverPageNotifyWnd(this); if (!m_NotifyWin) { hRc = E_OUTOFMEMORY; NodeMsgBox(IDS_MEMORY); DebugPrintEx( DEBUG_ERR, TEXT("Out of memory.")); goto Exit; }
RECT rcRect; ZeroMemory(&rcRect, sizeof(rcRect));
HWND hWndNotify = m_NotifyWin->Create(NULL, rcRect, NULL, //LPCTSTR szWindowName
WS_POPUP, //DWORD dwStyle
0x0, 0);
if (!(::IsWindow(hWndNotify))) { DebugPrintEx( DEBUG_ERR, _T("Failed to create window."));
hWndNotify = NULL; delete m_NotifyWin; m_NotifyWin = NULL;
goto Exit; }
hRc = StartNotificationThread(); if( S_OK != hRc) { //DbgPrint by Called Func.
m_NotifyWin->DestroyWindow(); delete m_NotifyWin; m_NotifyWin = NULL;
goto Exit; }
//
// Update boolean member
//
m_bIsFirstPopulateCall = FALSE;
DebugPrintEx( DEBUG_MSG, _T("Succeed to create server cover-page directory listener thread and to create notification window")); } ATLASSERT(S_OK == hRc); goto Exit;
Error: ATLASSERT(S_OK != hRc); if ( NULL != pCoverPage ) { delete pCoverPage; pCoverPage = NULL; } //
// Get rid of what we had.
//
{ // Delete each node in the list of children
int iSize = m_ResultChildrenList.GetSize(); for (int j = 0; j < iSize; j++) { pCoverPage = (CFaxCoverPageNode *) m_ResultChildrenList[j]; ATLASSERT(pCoverPage); delete pCoverPage; pCoverPage = NULL; }
// Empty the list
m_ResultChildrenList.RemoveAll();
// We no longer have a populated list.
m_bResultChildrenListPopulated = FALSE; } Exit: if (INVALID_HANDLE_VALUE != hFile) { if (!FindClose(hFile)) { DebugPrintEx( DEBUG_MSG, _T("Failed to FindClose()(ec: %ld)"), GetLastError()); } }
return hRc; }
/*
- CFaxCoverPagesNode::SetVerbs - * Purpose: * What verbs to enable/disable when this object is selected * * Arguments: * [in] pConsoleVerb - MMC ConsoleVerb interface * * Return: * OLE Error code */ HRESULT CFaxCoverPagesNode::SetVerbs(IConsoleVerb *pConsoleVerb) { HRESULT hRc = S_OK;
//
// We want the default verb to be expand node children
//
hRc = pConsoleVerb->SetDefaultVerb(MMC_VERB_OPEN);
return hRc; }
/*
- CFaxCoverPagesNode::OnRefresh - * Purpose: * Called when refreshing the object. * * Arguments: * * Return: * OLE error code */ /* virtual */HRESULT CFaxCoverPagesNode::OnRefresh(LPARAM arg, LPARAM param, IComponentData *pComponentData, IComponent * pComponent, DATA_OBJECT_TYPES type) { DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::OnRefresh")); HRESULT hRc = S_OK;
//
// Call the base class (do also repopulate)
//
hRc = CBaseFaxOutboundRulesNode::OnRefresh(arg, param, pComponentData, pComponent, type); if ( FAILED(hRc) ) { DebugPrintEx( DEBUG_ERR, _T("Fail to call base class's OnRefresh. (hRc: %08X)"), hRc); goto Exit; }
Exit: return hRc;
}
/*
- CFaxCoverPagesNode::DoRefresh - * Purpose: * Refresh the view * * Arguments: * [in] pRoot - The root node * * Return: * OLE Error code */
HRESULT CFaxCoverPagesNode::DoRefresh(CSnapInObjectRootBase *pRoot) { CComPtr<IConsole> spConsole;
//
// Repopulate children
//
RepopulateResultChildrenList();
if (pRoot) { //
// Get the console pointer
//
ATLASSERT(pRoot->m_nType == 1 || pRoot->m_nType == 2); if (pRoot->m_nType == 1) { //
// m_ntype == 1 means the IComponentData implementation
//
CSnapin *pCComponentData = static_cast<CSnapin *>(pRoot); spConsole = pCComponentData->m_spConsole; } else { //
// m_ntype == 2 means the IComponent implementation
//
CSnapinComponent *pCComponent = static_cast<CSnapinComponent *>(pRoot); spConsole = pCComponent->m_spConsole; } } else { ATLASSERT(m_pComponentData); spConsole = m_pComponentData->m_spConsole; }
ATLASSERT(spConsole); spConsole->UpdateAllViews(NULL, NULL, NULL);
return S_OK; }
HRESULT CFaxCoverPagesNode::DoRefresh() { DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::DoRefresh()")); HRESULT hRc = S_OK; CComPtr<IConsole> spConsole;
//
// Repopulate children
//
ATLASSERT( m_pComponentData != NULL ); ATLASSERT( m_pComponentData->m_spConsole != NULL );
hRc = m_pComponentData->m_spConsole->UpdateAllViews( NULL, NULL, FXS_HINT_DELETE_ALL_RSLT_ITEMS); if (FAILED(hRc)) { DebugPrintEx( DEBUG_ERR, _T("Unexpected error - Fail to UpdateAllViews (clear).")); NodeMsgBox(IDS_FAIL2REFRESH_THEVIEW); } RepopulateResultChildrenList();
hRc = m_pComponentData->m_spConsole->UpdateAllViews( NULL, NULL, NULL); if (FAILED(hRc)) { DebugPrintEx( DEBUG_ERR, _T("Unexpected error - Fail to UpdateAllViews.")); NodeMsgBox(IDS_FAIL2REFRESH_THEVIEW); }
return hRc; }
/*
- CFaxCoverPagesNode::OnNewCoverPage - * Purpose: * * * Arguments: * [out] bHandled - Do we handle it? * [in] pRoot - The root node * * Return: * OLE Error code */ HRESULT CFaxCoverPagesNode::OnNewCoverPage(bool &bHandled, CSnapInObjectRootBase *pRoot) { DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::OnNewCoverPage")); UNREFERENCED_PARAMETER (pRoot); UNREFERENCED_PARAMETER (bHandled);
DWORD ec = ERROR_SUCCESS; ec = OpenCoverPageEditor(CComBSTR(L"")); if (ERROR_SUCCESS != ec) { DebugPrintEx( DEBUG_ERR, _T("Fail to OpenCoverPageEditor. (ec : %ld)"), ec);
return HRESULT_FROM_WIN32( ec ); } return S_OK; }
/*
- CFaxCoverPagesNode::OpenCoverPageEditor - * Purpose: * Delete cover page * * Arguments: * [in] bstrFileName - The cover page file name * * Assumption: * Setup prepares a shortcut to the cover page editor in the * registry "App Path". Due to this fact ShellExecute needs only the * file name of the editor and not its full path. * Return: * Standard Win32 error code */ DWORD CFaxCoverPagesNode::OpenCoverPageEditor( BSTR bstrFileName) { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::OpenCoverPageEditor")); DWORD dwRes = ERROR_SUCCESS; CComBSTR bstrCovEditor;
HINSTANCE hCovEditor;
//
// get cover pages editor file
//
bstrCovEditor = FAX_COVER_IMAGE_NAME; if (!bstrCovEditor) { dwRes = ERROR_NOT_ENOUGH_MEMORY; DebugPrintEx( DEBUG_ERR, _T("Failed to allocate string - out of memory"));
goto Exit; } //
// start cover page editor
//
hCovEditor = ShellExecute( NULL, TEXT("open"), // Command
bstrCovEditor, (bstrFileName && lstrlen(bstrFileName)) ? // Do we have a file name?
bstrFileName : // YES - use it as command line argument
TEXT("/Common"), // NO - start the CP editor in the common CP folder
m_pszCovDir, SW_RESTORE ); if( (DWORD_PTR)hCovEditor <= 32 ) { // ShellExecute fail
dwRes = PtrToUlong(hCovEditor); DebugPrintEx( DEBUG_ERR, _T("Failed to run ShellExecute. (ec : %ld)"), dwRes);
goto Exit; }
ATLASSERT( ERROR_SUCCESS == dwRes);
Exit: return dwRes;
}
/*
- CFaxCoverPagesNode::OnAddCoverPageFile - * Purpose: * * * Arguments: * [out] bHandled - Do we handle it? * [in] pRoot - The root node * * Return: * OLE Error code */ HRESULT CFaxCoverPagesNode::OnAddCoverPageFile(bool &bHandled, CSnapInObjectRootBase *pRoot) { DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::OnAddCoverPageFile")); HRESULT hRc = S_OK; DWORD ec = ERROR_SUCCESS;
//
// Function Call: browse and copy a cover page
//
if (!BrowseAndCopyCoverPage( m_pszCovDir, FAX_COVER_PAGE_EXT_LETTERS ) ) { DebugPrintEx( DEBUG_MSG, _T("BrowseAndCopyCoverPage Canceled by user or Failed.")); return S_OK; //error is teated in the called func. MMC continue as usual.
} else //Success
{ //
// Repopulate: refresh the entire cover page result pane view
//
DoRefresh(pRoot); }
return S_OK; }
/*
- CFaxCoverPagesNode::BrowseAndCopyCoverPage - * Purpose: * Presents a common file open dialog for the purpose of selecting a file name * * Arguments: * [in] pInitialDir - server cover page directory path * [in] pCovPageExtensionLetters - cover page's 3 leeters extension * * Return: * TRUE - got a good file name, user pressed the OK button to override file, file was copy * FALSE - got nothing or user pressed the CANCEL button, or error occures. * * the FileName is changed to have the selected file name. */
BOOL CFaxCoverPagesNode::BrowseAndCopyCoverPage( LPTSTR pInitialDir, LPWSTR pCovPageExtensionLetters )
{ DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::BrowseAndCopyCoverPage"));
DWORD dwError = ERROR_SUCCESS; HRESULT ret = S_OK;
WCHAR filter[FXS_MAX_TITLE_LEN] = {0}; WCHAR filename[MAX_PATH]; WCHAR ftitle[MAX_PATH]; WCHAR title[FXS_MAX_TITLE_LEN]; TCHAR szDestinationFilePath[MAX_PATH] = {0}; TCHAR szServerCoverPagePath[MAX_PATH];
LPTSTR pExtension; LPTSTR pFilename; INT n;
OPENFILENAME of; //
// (1) Init
//
//
// Check in parameters
//
ATLASSERT( NULL != pInitialDir && 0 != pInitialDir[0] ); ATLASSERT( NULL != pInitialDir && sizeof(FAX_COVER_PAGE_EXT_LETTERS)/sizeof(WCHAR) != _tcslen(pCovPageExtensionLetters) ); //
// Prepare parameters for the copy operation (later)
//
n = _tcslen(pInitialDir); wcscpy(szServerCoverPagePath , pInitialDir); //
// Prepare the OPENFILE structure fields
//
// Compose the file-type filter string
if (::LoadString(_Module.GetResourceInstance(), IDS_CP_FILETYPE, title, FXS_MAX_TITLE_LEN) == 0) { NodeMsgBox(IDS_MEMORY); return FALSE; }
_snwprintf(filter, ARR_SIZE(filter)-1, TEXT("%s (%s)%c%s%c%c"), title, FAX_COVER_PAGE_MASK, NUL, FAX_COVER_PAGE_MASK, NUL, NUL);
if (::LoadString(_Module.GetResourceInstance(), IDS_BROWSE_COVERPAGE, title, FXS_MAX_TITLE_LEN) == 0) { NodeMsgBox(IDS_MEMORY); return FALSE; } filename[0] = NUL; ftitle[0] = NUL;
//
// Init the OPENFILE structure
//
of.lStructSize = sizeof( OPENFILENAME ); of.hwndOwner = NULL; of.hInstance = GetModuleHandle( NULL ); of.lpstrFilter = filter; of.lpstrCustomFilter = NULL; of.nMaxCustFilter = 0; of.nFilterIndex = 1; of.lpstrFile = filename; of.nMaxFile = MAX_PATH; of.lpstrFileTitle = ftitle; of.nMaxFileTitle = MAX_PATH; of.lpstrInitialDir = pInitialDir; of.lpstrTitle = title; of.Flags = OFN_EXPLORER | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST; //OFN_ENABLEHOOK ;
of.nFileOffset = 0; of.nFileExtension = 0; of.lpstrDefExt = pCovPageExtensionLetters; of.lCustData = 0; of.lpfnHook = NULL; //BrowseHookProc;
of.lpTemplateName = NULL;
//
// (2) Call the "Open File" dialog
//
if (! GetOpenFileName(&of)) { DebugPrintEx( DEBUG_MSG, _T("GetOpenFileName was canceled by user."));
return FALSE; }
//
// (3) Check the output of the source path, filename and extension
//
//
// a. Make sure the selected filename has the correct extension
//
//
// Find the filename portion given a filename:
// return a pointer to the '.' character if successful
// NULL if there is no extension
//
pFilename = &filename[of.nFileOffset]; pExtension = _tcsrchr(filename, _T('.')); if ( (pExtension == NULL) || (_tcsicmp(pExtension, FAX_COVER_PAGE_FILENAME_EXT) != EQUAL_STRING) ) { NodeMsgBox(IDS_BAD_CP_EXTENSION); return FALSE; }
//
// b. Check if the selected file directory is the
// default server cover page directory
//
if (_tcsnicmp(filename, szServerCoverPagePath, n) == EQUAL_STRING) { NodeMsgBox(IDS_CP_DUPLICATE); //YESNO
// Work was already done. We are leaving...
goto Exit; }
//
// The check if the selected file is already inside the
// cover page directory is done with the copy operation itself.
//
//
// The check if the destination cover page directory exists done
// while the copy operation itself.
//
//
// (4) Copy the selected cover page file to the Server Cover page directory
//
//
// a. prepare from pSelected the destination path
//
if (n + 1 + _tcslen(pFilename) >= MAX_PATH || pFilename >= pExtension) { NodeMsgBox(IDS_FILENAME_TOOLONG); return FALSE; } _snwprintf(szDestinationFilePath, ARR_SIZE(szDestinationFilePath)-1, TEXT("%s%s%s%c"), szServerCoverPagePath, FAX_PATH_SEPARATOR_STR, pFilename, NUL);
//
// b. Copy the selected cover page file
// to the server cover page default directory
//
if (!CopyFile(filename, szDestinationFilePath, TRUE)) { dwError = GetLastError(); if ( ERROR_FILE_EXISTS == dwError) { DebugPrintEx(DEBUG_MSG, _T("Copy cover page already exists at destination."));
ret = NodeMsgBox(IDS_CP_DUP_YESNO, MB_YESNO | MB_ICONQUESTION ); if ((HRESULT)IDYES == ret) { //Copy any way
if (!CopyFile(filename, szDestinationFilePath, FALSE)) { dwError = GetLastError(); DebugPrintEx(DEBUG_ERR, _T("Copy cover page Failed (ec = %ld)."), dwError);
NodeMsgBox(IDS_FAILED2COPY_COVERPAGE);
return FALSE; } DebugPrintEx(DEBUG_MSG, _T("Copy cover page done any way.")); } else //ret == IDNO
{ DebugPrintEx(DEBUG_MSG, _T("Copy cover page was canceled by user due to file existance at destination.")); //lets stay friends even after this operation cancel..
return TRUE; } } //dwError != ERROR_FILE_EXISTS
else { DebugPrintEx(DEBUG_ERR, _T("Copy cover page Failed (ec = %ld)."), dwError); NodeMsgBox(IDS_FAILED2COPY_COVERPAGE); return FALSE; } } Exit:
return TRUE; }
/*
- CFaxCoverPagesNode::DeleteCoverPage - * Purpose: * Delete cover page * * Arguments: * [in] bstrName - The cover page full path * [in] pChildNode - The node to be deleted * * Return: * OLE Error code */
HRESULT CFaxCoverPagesNode::DeleteCoverPage(BSTR bstrName, CFaxCoverPageNode *pChildNode) { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::DeleteRule")); HRESULT hRc = S_OK; DWORD ec = ERROR_SUCCESS;
ATLASSERT(bstrName); ATLASSERT(pChildNode); if (!DeleteFile(bstrName)) { ec = GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Fail to DeleteFile. (ec: %ld)"), ec);
goto Error; }
//
// Remove from MMC result pane
//
ATLASSERT(pChildNode); hRc = RemoveChild(pChildNode); if (FAILED(hRc)) { DebugPrintEx( DEBUG_ERR, TEXT("Fail to remove rule. (hRc: %08X)"), hRc); //NodeMsgBox by Caller func.
return hRc; } //
// Call the group destructor
//
delete pChildNode; ATLASSERT(S_OK == hRc); DebugPrintEx( DEBUG_MSG, _T("The rule was removed successfully.")); goto Exit;
Error: ATLASSERT(ERROR_SUCCESS != ec); hRc = HRESULT_FROM_WIN32(ec); //NodeMsgBox by Caller func.;
Exit: return hRc; }
/*
- CFaxCoverPagesNode::InitDisplayName - * Purpose: * To load the node's Displayed-Name string. * * Arguments: * * Return: * OLE error code */ HRESULT CFaxCoverPagesNode::InitDisplayName() { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::InitDisplayName"));
HRESULT hRc = S_OK;
if (!m_bstrDisplayName.LoadString(_Module.GetResourceInstance(), IDS_DISPLAY_STR_COVERPAGES)) { hRc = E_OUTOFMEMORY; goto Error; } ATLASSERT( S_OK == hRc); goto Exit;
Error: ATLASSERT( S_OK != hRc);
m_bstrDisplayName = L"";
DebugPrintEx( DEBUG_ERR, TEXT("Fail to Load server name string.")); NodeMsgBox(IDS_MEMORY);
Exit: return hRc; } /*
- CFaxCoverPagesNode::NotifyThreadProc - * Purpose: * To load the node's Displaed-Name string. * * Arguments: * [in] - pointer to the Fax Cover-Pages Node * Return: * WIN32 error code */ DWORD WINAPI CFaxCoverPagesNode::NotifyThreadProc ( LPVOID lpParameter) { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::NotifyThreadProc")); DWORD dwRes = ERROR_SUCCESS; HRESULT hRc = S_OK;
CFaxCoverPagesNode *pCovFolder = (CFaxCoverPagesNode *)lpParameter;
ATLASSERT (pCovFolder);
HANDLE hWaitHandles[2]; DWORD dwNotifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE; //
// register for a first folder notification
//
hWaitHandles[0] = FindFirstChangeNotification( pCovFolder->m_pszCovDir, FALSE, dwNotifyFilter); if(INVALID_HANDLE_VALUE == hWaitHandles[0]) { dwRes = GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to FindFirstChangeNotification. (ec : %ld)"), dwRes);
return dwRes; }
while(TRUE) { hWaitHandles[1] = m_hStopNotificationThreadEvent; if (NULL == hWaitHandles[1]) { //
// We're shutting down
//
goto Exit; }
//
// wait for folder notification or shutdown
//
dwRes = WaitForMultipleObjects(2, hWaitHandles, FALSE, INFINITE);
switch (dwRes) { case WAIT_OBJECT_0:
//
// folder notification
//
if(NULL != pCovFolder->m_NotifyWin && pCovFolder->m_NotifyWin->IsWindow()) { if ( !pCovFolder->m_NotifyWin->PostMessage(WM_NEW_COV)) { DebugPrintEx(DEBUG_ERR, _T("Fail to PostMessage")); // do not exit. continue!
} }
break;
case WAIT_OBJECT_0 + 1: //
// Shutdown is now in progress
//
DebugPrintEx( DEBUG_MSG, _T("Shutdown in progress"));
dwRes = ERROR_SUCCESS; goto Exit;
case WAIT_FAILED: dwRes = GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to WaitForMultipleObjects. (ec : %ld)"), dwRes);
goto Exit;
case WAIT_TIMEOUT: DebugPrintEx( DEBUG_ERR, _T("Reach WAIT_TIMEOUT in INFINITE wait!"));
ATLASSERT(FALSE);
goto Exit; default: DebugPrintEx( DEBUG_ERR, _T("Failed. Unexpected error (ec : %ld)"), dwRes);
ATLASSERT(0); goto Exit; }
//
// register for a next folder notification
//
if(!FindNextChangeNotification(hWaitHandles[0])) { dwRes = GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to FindNextChangeNotification (ec : %ld)"), dwRes);
goto Exit; } }
Exit: //
// close notification handel
//
if(!FindCloseChangeNotification(hWaitHandles[0])) { dwRes = GetLastError(); DebugPrintEx( DEBUG_ERR, _T("Failed to FindCloseChangeNotification. (ec : %ld)"), dwRes); }
return dwRes;
} // NotifyThreadProc
/*
- CFaxCoverPagesNode::StartNotificationThread - * Purpose: * Start the server cover page directory listning thread. * * Arguments: * * Return: * OLE Error code */ HRESULT CFaxCoverPagesNode::StartNotificationThread() { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::StartNotificationThread")); HRESULT hRc = S_OK; DWORD ec = ERROR_SUCCESS;
//
// create thread
//
DWORD dwThreadId; m_hNotifyThread = CreateThread ( NULL, // No security
0, // Default stack size
NotifyThreadProc,// Thread procedure
(LPVOID)this, // Parameter
0, // Normal creation
&dwThreadId // We must have a thread id for win9x
); if (NULL == m_hNotifyThread) { ec = GetLastError (); DebugPrintEx( DEBUG_ERR, _T("Fail to CreateThread. (ec: %ld)"), ec); hRc = HRESULT_FROM_WIN32(ec);
goto Exit; }
Exit: return hRc; }
/*
- CFaxCoverPagesNode::StopNotificationThread - * Purpose: * Stop the server cover page directory listning thread. * * Arguments: * * Return: * OLE Error code */ HRESULT CFaxCoverPagesNode::StopNotificationThread() { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::StopNotificationThread")); HRESULT hRc = S_OK; //
// Signal the event telling all our thread the app. is shutting down
//
SetEvent (m_hStopNotificationThreadEvent);
//
// wait for the thread
//
if (NULL != m_hNotifyThread ) { DWORD dwWaitRes = WaitForSingleObject(m_hNotifyThread, INFINITE); switch(dwWaitRes) { case WAIT_OBJECT_0: //Success
DebugPrintEx( DEBUG_MSG, _T("Succeed to WaitForSingleObject from notify thread. (ec : %ld)")); break;
case WAIT_FAILED: dwWaitRes = GetLastError(); if (ERROR_INVALID_HANDLE != dwWaitRes) { DebugPrintEx( DEBUG_ERR, _T("Failed to WaitForSingleObject. (ec : %ld)"), dwWaitRes);
hRc = E_FAIL; } break; case WAIT_TIMEOUT: DebugPrintEx( DEBUG_ERR, _T("WAIT_TIMEOUT - Failed to WaitForSingleObject. (ec : %ld)"), dwWaitRes);
hRc = E_FAIL; ATLASSERT(FALSE);
break; default: DebugPrintEx( DEBUG_ERR, _T("Failed to WaitForSingleObject. (ec : %ld)"), dwWaitRes);
hRc = E_FAIL;
break; } CloseHandle (m_hNotifyThread); m_hNotifyThread = NULL; }
return hRc; }
/*
- CFaxCoverPagesNode::RestartNotificationThread - * Purpose: * Restart the server cover page directory listning thread. * * Arguments: * * Return: * OLE Error code */ HRESULT CFaxCoverPagesNode::RestartNotificationThread() { DEBUG_FUNCTION_NAME(_T("CFaxCoverPagesNode::RestartNotificationThread")); HRESULT hRc = S_OK;
//
// Stop
//
hRc = StopNotificationThread(); if (S_OK != hRc) { //DbgMsg And MsgBox by called func.
goto Exit; }
//
// Reset Shutdown Event handle
//
if (m_hStopNotificationThreadEvent) { ResetEvent (m_hStopNotificationThreadEvent); }
//
// Start
//
hRc = StartNotificationThread(); if (S_OK != hRc) { //DbgMsg And MsgBox by called func.
goto Exit; }
Exit: return hRc; }
/*
+ + CFaxCoverPagesNode::OnShowContextHelp * * Purpose: * Overrides CSnapinNode::OnShowContextHelp. * * Arguments: * * Return: - OLE error code - */ HRESULT CFaxCoverPagesNode::OnShowContextHelp( IDisplayHelp* pDisplayHelp, LPOLESTR helpFile) { return DisplayContextHelp(pDisplayHelp, helpFile, HLP_COVER_PAGES); }
///////////////////////////////////////////////////////////////////
/*
- CFaxCoverPagesNode::UpdateMenuState - * Purpose: * Overrides the ATL CSnapInItemImpl::UpdateMenuState * which only have one line inside it "return;" * This function implements the grayed\ungrayed view for the * the Enable and the Disable menus. * * Arguments:
* [in] id - unsigned int with the menu IDM value * [out] pBuf - string * [out] flags - pointer to flags state combination unsigned int * * Return: * no return value - void function */ void CFaxCoverPagesNode::UpdateMenuState(UINT id, LPTSTR pBuf, UINT *flags) { DEBUG_FUNCTION_NAME( _T("CFaxCoverPagesNode::UpdateMenuState"));
UNREFERENCED_PARAMETER (pBuf); switch (id) { case IDM_NEW_COVERPAGE:
*flags = IsFaxComponentInstalled(FAX_COMPONENT_CPE) ? MF_ENABLED : MF_GRAYED; break;
default: break; } return; }
|