Leaked source code of windows server 2003
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.
 
 
 
 
 
 

566 lines
14 KiB

// ProgView.cpp : Implementation of CProgView
#include "stdafx.h"
#include <commctrl.h>
#include "ProgView.h"
#include <strsafe.h>
/////////////////////////////////////////////////////////////////////////////
// CProgView
LRESULT
CProgView::OnNotifyListView(
int idCtrl,
LPNMHDR pnmh,
BOOL& bHandled
)
{
if (idCtrl != IDC_FILE_LIST) {
bHandled = FALSE;
return 0;
}
if (pnmh->code == NM_DBLCLK)
{
return OnDblclkListprograms(idCtrl, pnmh, bHandled);
}
// see that we get the notification to fill-in the details
return NotifyProgramList(m_pProgramList, pnmh, bHandled);
}
LRESULT
CProgView::OnDblclkListprograms(
int idCtrl,
LPNMHDR pnmh,
BOOL& bHandled)
{
LPNMITEMACTIVATE lpnmh;
LRESULT SelFile;
WCHAR FileName[MAX_PATH];
if (idCtrl != IDC_FILE_LIST) {
bHandled = FALSE;
return 0;
}
lpnmh = (LPNMITEMACTIVATE) pnmh;
// we have a double-click !
SelFile = SendDlgItemMessage(m_hwnd, IDC_FILE_LIST,
LVM_GETSELECTIONMARK,
0, 0);
if (SelFile >= 0)
{
GetSelectedItem();
GetSelectionInformation(PROGLIST_EXENAME, FileName, sizeof(FileName));
StringCchCopyW(m_wszRetFileName, MAX_PATH, FileName);
if (lpnmh->iSubItem == 0 &&
lpnmh->iItem == SelFile)
{
// A file is selected, we can end the dialog
m_nCmdPopulate = CMD_EXIT;
EndDialog(m_hwnd, IDOK);
SetEvent(m_hEventCmd);
}
}
bHandled = TRUE;
return 0;
}
STDMETHODIMP CProgView::GetSelectedItem()
{
GetProgramListSelection(m_pProgramList);
return S_OK;
}
STDMETHODIMP CProgView::get_SelectionName(LPWSTR pBuffer, ULONG Size)
{
if (!m_Safe) {
return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
}
GetProgramListSelectionDetails(m_pProgramList, 0, pBuffer, Size);
return S_OK;
}
STDMETHODIMP CProgView::GetSelectionInformation(LONG lInformationClass, LPWSTR pBuffer, ULONG Size)
{
if (!m_Safe) {
return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
}
GetProgramListSelectionDetails(m_pProgramList, lInformationClass, pBuffer, Size);
return S_OK;
}
VOID
CProgView::ShowProgressWindows(BOOL bProgress)
{
HDWP hDefer = ::BeginDeferWindowPos(4);
DWORD dwProgressFlag = bProgress ? SWP_SHOWWINDOW : SWP_HIDEWINDOW;
DWORD dwListFlag = bProgress ? SWP_HIDEWINDOW : SWP_SHOWWINDOW;
hDefer = ::DeferWindowPos(hDefer, GetDlgItem(m_hwnd, IDC_ANIMATE), NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|dwProgressFlag);
hDefer = ::DeferWindowPos(hDefer, GetDlgItem(m_hwnd, IDC_SEARCH_STATUS), NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|dwProgressFlag);
hDefer = ::DeferWindowPos(hDefer, GetDlgItem(m_hwnd, IDC_SEARCH_STATUS2), NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|dwProgressFlag);
hDefer = ::DeferWindowPos(hDefer, GetDlgItem(m_hwnd, IDC_SEARCH_STATUS3), NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|dwProgressFlag);
hDefer = ::DeferWindowPos(hDefer, GetDlgItem(m_hwnd, IDC_SEARCH_FINISHED), NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|dwListFlag);
hDefer = ::DeferWindowPos(hDefer, GetDlgItem(m_hwnd, IDC_FILE_LIST), NULL,
0, 0, 0, 0,
SWP_NOSIZE|SWP_NOMOVE|SWP_NOZORDER|dwListFlag);
EndDeferWindowPos(hDefer);
}
STDMETHODIMP CProgView::PopulateList()
{
HANDLE hThread;
ResetEvent(m_hEventCancel);
ResetEvent(m_hEventCmd);
// if (!m_bInPlaceActive) {
// InPlaceActivate(OLEIVERB_INPLACEACTIVATE);
// }
if (m_hThreadPopulate == NULL) {
m_hThreadPopulate = CreateThread(NULL, 0, _PopulateThreadProc, (LPVOID)this, 0, NULL);
}
if (m_hThreadPopulate != NULL && !IsScanInProgress()) {
m_nCmdPopulate = CMD_SCAN;
SetEvent(m_hEventCmd);
}
return S_OK;
}
BOOL CProgView::PopulateListInternal()
{
if (InterlockedCompareExchange(&m_PopulateInProgress, TRUE, FALSE) == TRUE) {
//
// populate in progress -- quit
//
return FALSE;
}
if (m_pProgramList != NULL) {
CleanupProgramList(m_pProgramList);
m_pProgramList = NULL;
}
ShowProgressWindows(TRUE);
Animate_OpenEx(GetDlgItem(m_hwnd, IDC_ANIMATE), _Module.GetModuleInstance(), MAKEINTRESOURCE(IDA_FINDANIM));
Animate_Play(GetDlgItem(m_hwnd, IDC_ANIMATE), 0, -1, -1);
PostMessage(m_hwnd, WM_VIEW_CHANGED, 0, 0);
// FireViewChange();
// if (m_bInPlaceActive) {
/* HCURSOR hcWait = (HCURSOR)::LoadImage(NULL,
MAKEINTRESOURCE(IDC_WAIT),
IMAGE_CURSOR,
0, 0,
LR_DEFAULTSIZE|LR_SHARED);
// HCURSOR hcWait = ::LoadCursor(_Module.GetResourceInstance(),
// MAKEINTRESOURCE(IDC_WAIT));
HCURSOR hcSave = SetCursor(hcWait);
*/
//
// malloc used on this thread should NOT be used on UI thread
//
InitializeProgramList(&m_pProgramList, GetDlgItem(m_hwnd, IDC_FILE_LIST));
PopulateProgramList(m_pProgramList, this, m_hEventCancel);
// SetCursor(hcSave);
Animate_Stop(GetDlgItem(m_hwnd, IDC_ANIMATE));
Animate_Close(GetDlgItem(m_hwnd, IDC_ANIMATE));
ShowProgressWindows();
InterlockedCompareExchange(&m_PopulateInProgress, FALSE, TRUE);
PostMessage(m_hwnd, WM_VIEW_CHANGED, 0, 0);
PostMessage(m_hwnd, WM_LIST_POPULATED, 0, 0); // we are done, signal to the main thread
// FireViewChange();
// } else {
// m_bPendingPopulate = TRUE;
// }
return TRUE;
}
DWORD WINAPI
CProgView::_PopulateThreadProc(
LPVOID lpvParam
)
{
CProgView* pProgView = (CProgView*)lpvParam;
DWORD dwWait;
BOOL bExit = FALSE;
HRESULT hr = CoInitialize(NULL);
if (!SUCCEEDED(hr)) {
return FALSE;
}
//
// keep this thread alive, block it on a command event
//
while(!bExit) {
dwWait = WaitForSingleObject(pProgView->m_hEventCmd, INFINITE);
if (dwWait != WAIT_OBJECT_0) {
break; // get out, we are being killed
}
//
// get the command
//
switch(pProgView->m_nCmdPopulate) {
case CMD_NONE:
break;
case CMD_EXIT:
bExit = TRUE;
//
// intentional fall-through
//
case CMD_CLEANUP:
if (pProgView->m_pProgramList) {
CleanupProgramList(pProgView->m_pProgramList);
pProgView->m_pProgramList = NULL;
}
break;
case CMD_SCAN:
pProgView->PopulateListInternal();
break;
}
pProgView->m_nCmdPopulate = CMD_NONE;
}
CoUninitialize();
return TRUE;
}
STDMETHODIMP
CProgView::UpdateListItem(
BSTR pTarget,
VARIANT *pKeys,
BOOL *pResult
)
{
VARIANT vKeys;
VariantInit(&vKeys);
CComBSTR bstrKeys;
HRESULT hr;
if (!m_pProgramList) {
return S_OK;
}
if (!m_Safe) {
return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
}
if (pKeys->vt == VT_NULL || pKeys->vt == VT_EMPTY) {
*pResult = UpdateProgramListItem(m_pProgramList, pTarget, NULL);
return S_OK;
}
hr = VariantChangeType(&vKeys, pKeys, 0, VT_BSTR);
if (SUCCEEDED(hr)) {
bstrKeys = vKeys.bstrVal;
if (bstrKeys.Length()) {
*pResult = UpdateProgramListItem(m_pProgramList, pTarget, bstrKeys);
} else {
*pResult = FALSE;
}
}
VariantClear(&vKeys);
return S_OK;
}
STDMETHODIMP CProgView::CancelPopulateList()
{
if (m_hEventCancel && InterlockedCompareExchange(&m_PopulateInProgress, TRUE, TRUE) == TRUE) {
SetEvent(m_hEventCancel);
}
return S_OK;
}
STDMETHODIMP CProgView::get_ItemCount(VARIANT* pVal)
{
if (!m_Safe) {
return HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED);
}
pVal->vt = VT_I4;
pVal->intVal = (int)ListView_GetItemCount(GetDlgItem(m_hwnd, IDC_FILE_LIST));
return S_OK;
}
//
// expand env -- lives in util.cpp
// we have a bit differing implementation here
//
LPWSTR
ExpandEnvironmentVars(
LPWSTR lpszCmd
)
{
DWORD dwLength;
LPTSTR lpBuffer = NULL;
BOOL bExpanded = FALSE;
LPWSTR strCmd;
TCHAR szBuffer[MAX_PATH];
if (_tcschr(lpszCmd, TEXT('%')) == NULL) {
goto out;
}
dwLength = ExpandEnvironmentStrings(lpszCmd, NULL, 0);
if (!dwLength) {
goto out;
}
if (dwLength < CHARCOUNT(szBuffer)) {
lpBuffer = szBuffer;
} else {
lpBuffer = new TCHAR[dwLength];
if (NULL == lpBuffer) {
goto out;
}
}
dwLength = ExpandEnvironmentStrings(lpszCmd, lpBuffer, dwLength);
if (!dwLength) {
goto out;
}
strCmd = lpBuffer;
bExpanded = TRUE;
out:
if (!bExpanded) {
strCmd = lpszCmd;
}
if (lpBuffer && lpBuffer != szBuffer) {
delete[] lpBuffer;
}
return strCmd;
}
#if 0
STDMETHODIMP CProgView::put_ExcludeFiles(BSTR newVal)
{
// parse exclude files, put them into our blacklist
wstring strFile;
LPCWSTR pch = newVal;
LPCWSTR pend;
m_ExcludedFiles.clear();
while (pch != NULL && *pch != TEXT('\0')) {
pch += _tcsspn(pch, TEXT(" \t"));
// begining
// find the ;
pend = _tcschr(pch, TEXT(';'));
if (pend == NULL) {
// from pch to the end
strFile = pch;
pch = NULL; // will bail out
} else {
strFile = wstring(pch, (wstring::size_type)(pend - pch));
pch = pend + 1; // one past ;
}
// add
if (strFile.length()) {
strFile = ExpandEnvironmentVars(strFile.c_str());
m_ExcludedFiles.insert(StrUpCase(strFile));
}
}
return S_OK;
}
STDMETHODIMP CProgView::get_ExcludeFiles(BSTR* pVal)
{
// parse exclude files, put them into our blacklist
STRSET::iterator iter;
CComBSTR bstrFiles;
for (iter = m_ExcludedFiles.begin(); iter != m_ExcludedFiles.end(); ++iter) {
if (bstrFiles.Length()) {
bstrFiles += TEXT(';');
}
bstrFiles += (*iter).c_str();
}
*pVal = bstrFiles.Copy();
return S_OK;
}
BOOL CProgView::IsFileExcluded(LPCTSTR pszFile)
{
wstring strFile = pszFile;
STRSET::iterator iter;
iter = m_ExcludedFiles.find(StrUpCase(strFile));
return iter != m_ExcludedFiles.end();
}
#endif // 0
LRESULT
CProgView::OnCommand(WPARAM wParam, LPARAM lParam)
{
WORD wCode = HIWORD(wParam);
WORD wId = LOWORD(wParam);
LRESULT SelFile;
WCHAR FileName[MAX_PATH];
switch(wId)
{
case IDOK:
SelFile = SendDlgItemMessage(m_hwnd, IDC_FILE_LIST,
LVM_GETSELECTIONMARK,
0, 0);
if (SelFile >= 0)
{
GetSelectedItem();
GetSelectionInformation(PROGLIST_EXENAME, FileName, sizeof(FileName));
StringCchCopyW(m_wszRetFileName, MAX_PATH, FileName);
}
// Fall through
case IDCANCEL:
m_nCmdPopulate = CMD_EXIT;
EndDialog(m_hwnd, wId);
SetEvent(m_hEventCmd);
return 0;
default:
return 1; // not handled
}
return 1; // not handled
}
LRESULT
CProgView::OnNotify(WPARAM wParam, LPARAM lParam)
{
WORD wId = LOWORD(wParam);
BOOL bVal;
BOOL& bHandled = bVal;
switch(wId)
{
default:
break;
case IDC_FILE_LIST:
return OnNotifyListView((int) wParam, (LPNMHDR) lParam, bHandled);
break;
}
return 1;
}
INT_PTR CALLBACK
Dialog_GetProgFromList(
HWND hwnd,
UINT Message,
WPARAM wparam,
LPARAM lparam
)
{
BOOL bHandled;
CProgView* pProgWinData;
pProgWinData = (CProgView *) GetWindowLongPtr(hwnd, GWLP_USERDATA);
if (Message != WM_INITDIALOG && pProgWinData == NULL)
{
return FALSE;
}
switch (Message)
{
case WM_INITDIALOG:
// Assert(pProgWinData == NULL);
pProgWinData = new CProgView();
if (!pProgWinData)
{
return -1;
}
pProgWinData->m_hwnd = hwnd;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) pProgWinData);
SetFocus(hwnd);
pProgWinData->OnInitDialog(Message, wparam, lparam, &bHandled);
break;
case WM_COMMAND:
if (pProgWinData->OnCommand(wparam, lparam) == 0)
{
return TRUE;
}
break;
case WM_NOTIFY:
if (pProgWinData->OnNotify(wparam, lparam) == 0)
{
return TRUE;
}
break;
case WM_DESTROY:
delete pProgWinData;
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR) NULL);
break;
}
return FALSE;
}