Exemple #1
0
VOID WINAPI HashSaveStart( HWND hWndOwner, HSIMPLELIST hListRaw )
{
    // Explorer will be blocking as long as this function is running, so we
    // want to return as quickly as possible and leave the work up to the
    // thread that we are going to spawn

    PHASHSAVECONTEXT phsctx = SLSetContextSize(hListRaw, sizeof(HASHSAVECONTEXT));

    if (phsctx)
    {
        HANDLE hThread;

        phsctx->hWnd = hWndOwner;
        phsctx->hListRaw = hListRaw;

        InterlockedIncrement(&g_cRefThisDll);
        SLAddRef(hListRaw);

        if (hThread = CreateThreadCRT(HashSaveThread, phsctx))
        {
            CloseHandle(hThread);
            return;
        }

        // If the thread creation was successful, the thread will be
        // responsible for decrementing the ref count
        SLRelease(hListRaw);
        InterlockedDecrement(&g_cRefThisDll);
    }
}
STDMETHODIMP CHashCheck::Drop( LPDATAOBJECT pdtobj, DWORD grfKeyState, POINTL pt, PDWORD pdwEffect )
{
	FORMATETC format = { CF_HDROP, NULL, DVASPECT_CONTENT, -1, TYMED_HGLOBAL };
	STGMEDIUM medium;

	UINT uThreads = 0;

	if (pdtobj && pdtobj->GetData(&format, &medium) == S_OK)
	{
		if (HDROP hDrop = (HDROP)GlobalLock(medium.hGlobal))
		{
			UINT uDrops = DragQueryFile(hDrop, -1, NULL, 0);
			UINT cchPath;
			LPTSTR lpszPath;

			// Reduce the likelihood of a race condition when trying to create
			// an activation context by creating it before creating threads
			ActivateManifest(FALSE);

			for (UINT uDrop = 0; uDrop < uDrops; ++uDrop)
			{
				if ( (cchPath = DragQueryFile(hDrop, uDrop, NULL, 0)) &&
				     (lpszPath = (LPTSTR)malloc((cchPath + 1) * sizeof(TCHAR))) )
				{
					InterlockedIncrement(&g_cRefThisDll);

					HANDLE hThread;

					if ( (DragQueryFile(hDrop, uDrop, lpszPath, cchPath + 1) == cchPath) &&
					     (!(GetFileAttributes(lpszPath) & FILE_ATTRIBUTE_DIRECTORY)) &&
					     (hThread = CreateThreadCRT(HashVerifyThread, lpszPath)) )
					{
						// The thread should free lpszPath, not us
						CloseHandle(hThread);
						++uThreads;
					}
					else
					{
						free(lpszPath);
						InterlockedDecrement(&g_cRefThisDll);
					}
				}
			}

			GlobalUnlock(medium.hGlobal);
		}

		ReleaseStgMedium(&medium);
	}

	if (uThreads)
	{
		// DROPEFFECT_LINK would work here as well; it really doesn't matter
		*pdwEffect = DROPEFFECT_COPY;
		return(S_OK);
	}
	else
	{
		// We shouldn't ever be hitting this case
		*pdwEffect = DROPEFFECT_NONE;
		return(E_INVALIDARG);
	}
}
Exemple #3
0
INT_PTR CALLBACK HashSaveDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
    PHASHSAVECONTEXT phsctx;

    switch (uMsg)
    {
    case WM_INITDIALOG:
    {
        phsctx = (PHASHSAVECONTEXT)lParam;

        // Associate the window with the context and vice-versa
        phsctx->hWnd = hWnd;
        SetWindowLongPtr(hWnd, DWLP_USER, (LONG_PTR)phsctx);

        SetAppIDForWindow(hWnd, TRUE);

        HashSaveDlgInit(phsctx);

        phsctx->ex.pfnWorkerMain = HashSaveWorkerMain;
        phsctx->hThread = CreateThreadCRT(NULL, phsctx);

        if (!phsctx->hThread || WaitForSingleObject(phsctx->hThread, 1000) != WAIT_TIMEOUT)
        {
            WorkerThreadCleanup((PCOMMONCONTEXT)phsctx);
            EndDialog(hWnd, 0);
        }

        return(TRUE);
    }

    case WM_DESTROY:
    {
        SetAppIDForWindow(hWnd, FALSE);
        break;
    }

    case WM_ENDSESSION:
    case WM_CLOSE:
    {
        phsctx = (PHASHSAVECONTEXT)GetWindowLongPtr(hWnd, DWLP_USER);
        goto cleanup_and_exit;
    }

    case WM_COMMAND:
    {
        phsctx = (PHASHSAVECONTEXT)GetWindowLongPtr(hWnd, DWLP_USER);

        switch (LOWORD(wParam))
        {
        case IDC_PAUSE:
        {
            WorkerThreadTogglePause((PCOMMONCONTEXT)phsctx);
            return(TRUE);
        }

        case IDC_CANCEL:
        {
cleanup_and_exit:
            phsctx->dwFlags |= HCF_EXIT_PENDING;
            WorkerThreadStop((PCOMMONCONTEXT)phsctx);
            WorkerThreadCleanup((PCOMMONCONTEXT)phsctx);
            EndDialog(hWnd, 0);
            break;
        }
        }

        break;
    }

    case WM_TIMER:
    {
        // Vista: Workaround to fix their buggy progress bar
        KillTimer(hWnd, TIMER_ID_PAUSE);
        phsctx = (PHASHSAVECONTEXT)GetWindowLongPtr(hWnd, DWLP_USER);
        if (phsctx->status == PAUSED)
            SetProgressBarPause((PCOMMONCONTEXT)phsctx, PBST_PAUSED);
        return(TRUE);
    }

    case HM_WORKERTHREAD_DONE:
    {
        phsctx = (PHASHSAVECONTEXT)wParam;
        WorkerThreadCleanup((PCOMMONCONTEXT)phsctx);
        EndDialog(hWnd, 0);
        return(TRUE);
    }

    case HM_WORKERTHREAD_UPDATE:
    {
        phsctx = (PHASHSAVECONTEXT)wParam;
        ++phsctx->cHandledMsgs;
        SendMessage(phsctx->hWndPBTotal, PBM_SETPOS, phsctx->cHandledMsgs, 0);
        return(TRUE);
    }

    case HM_WORKERTHREAD_TOGGLEPREP:
    {
        HashCalcTogglePrep((PHASHSAVECONTEXT)wParam, (BOOL)lParam);
        return(TRUE);
    }
    }

    return(FALSE);
}
Exemple #4
0
INT_PTR CALLBACK HashVerifyDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
{
	PHASHVERIFYCONTEXT phvctx;

	switch (uMsg)
	{
		case WM_INITDIALOG:
		{
			phvctx = (PHASHVERIFYCONTEXT)lParam;

			// Associate the window with the context and vice-versa
			phvctx->hWnd = hWnd;
			SetWindowLongPtr(hWnd, DWLP_USER, (LONG_PTR)phvctx);

			SetAppIDForWindow(hWnd, TRUE);

			HashVerifyDlgInit(phvctx);

			phvctx->ex.pfnWorkerMain = HashVerifyWorkerMain;
			phvctx->hThread = CreateThreadCRT(NULL, phvctx);

			if (!phvctx->hThread)
				WorkerThreadCleanup((PCOMMONCONTEXT)phvctx);

			// Initialize the summary
			SendMessage(phvctx->hWndPBTotal, PBM_SETRANGE32, 0, phvctx->cTotal);
			HashVerifyUpdateSummary(phvctx, NULL);

			return(TRUE);
		}

		case WM_DESTROY:
		{
			SetAppIDForWindow(hWnd, FALSE);
			break;
		}

		case WM_ENDSESSION:
		case WM_CLOSE:
		{
			phvctx = (PHASHVERIFYCONTEXT)GetWindowLongPtr(hWnd, DWLP_USER);
			goto cleanup_and_exit;
		}

		case WM_COMMAND:
		{
			phvctx = (PHASHVERIFYCONTEXT)GetWindowLongPtr(hWnd, DWLP_USER);

			switch (LOWORD(wParam))
			{
				case IDC_PAUSE:
				{
					WorkerThreadTogglePause((PCOMMONCONTEXT)phvctx);
					return(TRUE);
				}

				case IDC_STOP:
				{
					WorkerThreadStop((PCOMMONCONTEXT)phvctx);
					return(TRUE);
				}

				case IDC_EXIT:
				{
					cleanup_and_exit:
					phvctx->dwFlags |= HCF_EXIT_PENDING;
					WorkerThreadStop((PCOMMONCONTEXT)phvctx);
					WorkerThreadCleanup((PCOMMONCONTEXT)phvctx);
					EndDialog(hWnd, 0);
					break;
				}
			}

			break;
		}

		case WM_NOTIFY:
		{
			LPNMHDR pnm = (LPNMHDR)lParam;

			if (pnm && pnm->idFrom == IDC_LIST)
			{
				phvctx = (PHASHVERIFYCONTEXT)GetWindowLongPtr(hWnd, DWLP_USER);

				switch (pnm->code)
				{
					case LVN_GETDISPINFO:
					{
						HashVerifyListInfo(phvctx, (LPNMLVDISPINFO)lParam);
						return(TRUE);
					}
					case NM_CUSTOMDRAW:
					{
						SetWindowLongPtr(hWnd, DWLP_MSGRESULT, HashVerifySetColor(phvctx, (LPNMLVCUSTOMDRAW)lParam));
						return(TRUE);
					}
					case LVN_ODFINDITEM:
					{
						SetWindowLongPtr(hWnd, DWLP_MSGRESULT, HashVerifyFindItem(phvctx, (LPNMLVFINDITEM)lParam));
						return(TRUE);
					}
					case LVN_COLUMNCLICK:
					{
						HashVerifySortColumn(phvctx, (LPNMLISTVIEW)lParam);
						return(TRUE);
					}
					case LVN_ITEMCHANGED:
					{
						if (((LPNMLISTVIEW)lParam)->uChanged & LVIF_STATE)
							phvctx->bFreshStates = FALSE;
						break;
					}
					case LVN_ODSTATECHANGED:
					{
						phvctx->bFreshStates = FALSE;
						break;
					}
				}
			}

			break;
		}

		case WM_TIMER:
		{
			// Vista: Workaround to fix their buggy progress bar
			KillTimer(hWnd, TIMER_ID_PAUSE);
			phvctx = (PHASHVERIFYCONTEXT)GetWindowLongPtr(hWnd, DWLP_USER);
			if (phvctx->status == PAUSED)
				SetProgressBarPause((PCOMMONCONTEXT)phvctx, PBST_PAUSED);
			return(TRUE);
		}

		case HM_WORKERTHREAD_DONE:
		{
			phvctx = (PHASHVERIFYCONTEXT)wParam;
			WorkerThreadCleanup((PCOMMONCONTEXT)phvctx);
			return(TRUE);
		}

		case HM_WORKERTHREAD_UPDATE:
		{
			phvctx = (PHASHVERIFYCONTEXT)wParam;
			++phvctx->cHandledMsgs;
			HashVerifyUpdateSummary(phvctx, (PHASHVERIFYITEM)lParam);
			return(TRUE);
		}

		case HM_WORKERTHREAD_SETSIZE:
		{
			phvctx = (PHASHVERIFYCONTEXT)wParam;

			// At the time we receive this message, cSentMsgs will be the ID of
			// the item the worker thread is currently working on, and
			// cHandledMsgs will be the ID of the item for which the SETSIZE
			// message was intended for; we need to update the UI only if
			// the worker thread is still working on this item when we process
			// this message; otherwise, we can just wait for the UPDATE message.

			if (phvctx->cSentMsgs == phvctx->cHandledMsgs)
				ListView_RedrawItems(phvctx->hWndList, phvctx->cHandledMsgs, phvctx->cHandledMsgs);

			return(TRUE);
		}
	}

	return(FALSE);
}