예제 #1
0
BOOL CBackgroundUpdater::Stop()
{
#ifdef THREADDISABLE_BACKROUNDUPDATER
	return TRUE;
#else
	BuDebugMessage("BU: Stop");

	if (m_hThread==NULL)
	{
		if (GetLocateDlg()->m_pBackgroundUpdater!=NULL)
			delete this;
		return FALSE;
	}
		
		
	// Creating a copy of thread handle and using
	HANDLE hThread;
	DuplicateHandle(GetCurrentProcess(),m_hThread,GetCurrentProcess(),
                    &hThread,0,FALSE,DUPLICATE_SAME_ACCESS);
	DebugOpenThread(hThread);


	DWORD status;
	BOOL bRet=::GetExitCodeThread(hThread,&status);
	if (bRet && status==STILL_ACTIVE)
	{
		InterlockedExchange(&m_lIgnoreItemsAndGoToSleep,TRUE);

		// Signal stop event
		SetEvent(m_phEvents[0]);
		
		// Wait for ending
		WaitForSingleObject(hThread,750);

		if (GetLocateDlg()->m_pBackgroundUpdater!=NULL)
		{
			BOOL bTerminated=FALSE;

			status=0;
			bRet=::GetExitCodeThread(hThread,&status);
			if (bRet && status==STILL_ACTIVE)
			{
				if (TerminateThread(hThread,1,TRUE))
					bTerminated=TRUE;
			}
	
			if (bTerminated)
				delete this;
		}
	}

	CloseHandle(hThread);
	DebugCloseThread(hThread);
	return TRUE;
#endif
}
예제 #2
0
void CSubAction::DoMenuCommand()
{
	CLocateDlg* pLocateDlg=GetLocateDlg();
	if (pLocateDlg==NULL)
		return;

	if (GetCurrentThreadId()==GetTrayIconWnd()->GetLocateDlgThread()->GetThreadId())
		pLocateDlg->OnCommand(LOWORD(m_nMenuCommand),0,NULL);
	else
		pLocateDlg->SendMessage(WM_COMMAND,MAKEWPARAM(LOWORD(m_nMenuCommand),0),0);
}
예제 #3
0
void CSubAction::DoResultListItems()
{
	if (m_nResultList==ExecuteCommand)
	{
		if (m_szCommand!=NULL)
			CLocateDlg::ExecuteCommand(m_szCommand);
		return;
	}
	
	CLocateDlg* pLocateDlg=GetLocateDlg();
	if (pLocateDlg==NULL)
		return;

	/*if (GetCurrentThreadId()==GetTrayIconWnd()->m_pLocateDlgThread->m_nThreadID)
		pLocateDlg->OnExecuteResultAction(m_nResultList,m_pExtraInfo);
	else*/
		pLocateDlg->SendMessage(WM_RESULTLISTACTION,m_nSubAction,(LPARAM)m_pExtraInfo);
}
예제 #4
0
CBackgroundUpdater::~CBackgroundUpdater()
{	
	InterlockedExchangePointer((PVOID*)&GetLocateDlg()->m_pBackgroundUpdater,NULL);
	

	
	CloseHandle(m_phEvents[0]);
	DebugCloseEvent(m_phEvents[0]);
	CloseHandle(m_phEvents[1]);
	DebugCloseEvent(m_phEvents[1]);

	DeleteCriticalSection(&m_csUpdateList);


	// Closing handle
	if (m_hThread!=NULL)
	{
		// We are still running
		CloseHandle(m_hThread);
		DebugCloseThread(m_hThread);
		m_hThread=NULL;
	}
}
예제 #5
0
inline CCheckFileNotificationsThread::~CCheckFileNotificationsThread()
{	
	FnDebugMessage("FN: destructor called");
	
	ASSERT((m_lState==sInitializing && m_nHandles==0) || m_lState==sStopping || m_lState==sTerminated);
	ASSERT(m_lState==sTerminated || m_hThread!=NULL);
	

	InterlockedExchangePointer((PVOID*)&GetLocateDlg()->m_pFileNotificationsThread,NULL);



	// Freeing handles
	DestroyHandles();
	
	

	// Delete file 
	if (m_pFile!=NULL)
		delete[] m_pFile;



	// Closing stop event
	CloseHandle(m_hStopEvent);
	DebugCloseEvent(m_hStopEvent);


	// Closing handle
	if (m_hThread!=NULL)
	{
		// We are still running
		CloseHandle(m_hThread);
		DebugCloseThread(m_hThread);
		m_hThread=NULL;
	}
}
예제 #6
0
BOOL CShortcut::IsWhenAndWhereSatisfied(HWND hSystemTrayWnd)  const
{
	if ((m_dwFlags&sfKeyTypeMask)==sfLocal)
	{
#ifndef KEYHOOK_EXPORTS
		CLocateDlg* pLocateDlg=GetLocateDlg();
		if (pLocateDlg!=NULL)
		{
			// Check if desired tab is chosen
			switch (pLocateDlg->GetCurrentTab())
			{
			case 0: // Name tab
				if (!(m_wWhenPressed&wpNameTabShown))
					return FALSE;
				break;
			case 1: // Size and Date tab
				if (!(m_wWhenPressed&wpSizeDateTabShown))
					return FALSE;
				break;
			case 2: // Advanced tab
				if (!(m_wWhenPressed&wpAdvancedTabShown))
					return FALSE;
				break;
			}

			// Check if "Find as you tybe" is running when not desired and vise verca
			if (pLocateDlg->IsInstantSearchingFlagSet(CLocateDlg::isRunning))
			{
				if (m_wWhenPressed&wpDisableWhenISRunning)
					return FALSE;
			}
			else
			{
				if (m_wWhenPressed&wpDisableWhenISNotRunning)
					return FALSE;
			}

		}
		return TRUE;
#else
		return FALSE;
#endif
	}

	if (m_pClass==NULL && m_pTitle==NULL)
		return TRUE;

	HWND hWnd=GetForegroundWindow();
	if (hWnd==NULL)
		return FALSE;

	// Checking class 
	if (m_pClass!=NULL)
	{
        if (m_pClass==LPCSTR(-1))
			return HWND(SendMessage(hSystemTrayWnd,WM_GETLOCATEDLG,0,0))==hWnd;
		

		char szClassName[200]="";
		GetClassName(hWnd,szClassName,200);

		if (!DoClassOrTitleMatch(szClassName,m_pClass))
			return FALSE;
	}

	// Checking class name
	if (m_pTitle!=NULL)
	{
		char szTitleName[200];
		GetWindowText(hWnd,szTitleName,200);
		
		if (!DoClassOrTitleMatch(szTitleName,m_pTitle))
			return FALSE;
	}
	return TRUE;
}
예제 #7
0
void CSubAction::DoMisc()
{
	if (m_nMisc==ExecuteCommandMisc)
	{
		if (m_szCommand!=NULL)
			CLocateDlg::ExecuteCommand(m_szCommand);
		return;
	}
	else if (m_nMisc==InsertAsterisks)
	{
		CLocateDlg* pLocateDlg=GetLocateDlg();
		if (pLocateDlg==NULL)
			return;

		CStringW Text;
		pLocateDlg->m_NameDlg.m_Name.GetText(Text);
		DWORD dwSelStart=pLocateDlg->m_NameDlg.m_Name.GetEditSel();
		WORD wSelEnd=HIWORD(dwSelStart);
		dwSelStart&=0xFFFF;

		// If asterisks are already at the beginning and the end, replace spaces
		if (Text[0]==L'*' && Text.LastChar()==L'*')
			Text.ReplaceChars(L' ',L'*');
		else 
		{
			if (Text[0]!=L'*')
			{
				Text.InsChar(0,L'*');
				
				// Update selection
				if (dwSelStart==wSelEnd)
				{
					dwSelStart++;
					wSelEnd++;
				}
				else 
				{
					if (dwSelStart>0)
						dwSelStart++;
					wSelEnd++;
				}
			}
			
			if (Text.LastChar()!=L'*')
			{
				// Update selection first
				if (wSelEnd==Text.GetLength())
				{
					if (dwSelStart==wSelEnd)
						dwSelStart++;
					wSelEnd++; 
				}

				Text.Append(L'*');
			}
		}

		pLocateDlg->m_NameDlg.m_Name.SetText(Text);
		pLocateDlg->m_NameDlg.m_Name.SetEditSel(dwSelStart,wSelEnd);
		pLocateDlg->OnFieldChange(CLocateDlg::isNameChanged);
		return;
	}
	

	// Send/Post Message

	BOOL bFreeWParam=FALSE,bFreeLParam=FALSE;
	
	HWND hWnd=NULL;
	WPARAM wParam=NULL,lParam=NULL;

	if (m_pSendMessage->szWindow[0]=='0')
	{
		if (m_pSendMessage->szWindow[1]=='x' || 
			m_pSendMessage->szWindow[1]=='X')
		{
			// Hex value
			LPWSTR szTemp;
			hWnd=(HWND)wcstoul(m_pSendMessage->szWindow+2,&szTemp,16);
		}
	}
	else if (strcasecmp(m_pSendMessage->szWindow,L"HWND_BROADCAST")==0)
		hWnd=HWND_BROADCAST;
	else if (GetLocateDlg()!=NULL && strcasecmp(m_pSendMessage->szWindow,L"LOCATEDLG")==0)
		hWnd=*GetLocateDlg();
	else if (strcasecmp(m_pSendMessage->szWindow,L"LOCATEST")==0)
		hWnd=*GetTrayIconWnd();
	else if (wcsncmp(m_pSendMessage->szWindow,L"Find",4)==0)
	{
		int nIndex=(int)FirstCharIndex(m_pSendMessage->szWindow,L'(');
		if (nIndex!=-1)
		{
			LPCWSTR pText=m_pSendMessage->szWindow+nIndex+1;
			LPWSTR pClassAndWindow[3]={NULL,NULL,NULL};
			
			nIndex=(int)FirstCharIndex(pText,L',');
			if (nIndex==-1)
			{
				nIndex=(int)FirstCharIndex(pText,L')');
				if (nIndex==-1)
					pClassAndWindow[0]=alloccopy(pText);
				else
					pClassAndWindow[0]=alloccopy(pText,nIndex);
			}
			else
			{
				pClassAndWindow[0]=alloccopy(pText,nIndex);
				pText+=nIndex+1;

				nIndex=(int)FirstCharIndex(pText,L')');
				pClassAndWindow[1]=alloccopy(pText,nIndex);
			}

			EnumWindows(WindowEnumProc,LPARAM(pClassAndWindow));

			// Third cell is handle to window
			hWnd=(HWND)pClassAndWindow[2];

			delete[] pClassAndWindow[0];
			if (pClassAndWindow[1])
				delete[] pClassAndWindow[1];
		}
	}
	


	// Parse wParam
	if (m_pSendMessage->szWParam!=NULL)
	{
		if (m_pSendMessage->szWParam[0]=='0')
		{
			if (m_pSendMessage->szWParam[1]=='x' || 
				m_pSendMessage->szWParam[1]=='X')
			{
				// Hex value
				LPWSTR szTemp;
				wParam=(WPARAM)wcstoul(m_pSendMessage->szWParam+2,&szTemp,16);
			}
			else if (m_pSendMessage->szWParam[1]!='\0')
			{
				DWORD dwLength;
				wParam=(WPARAM)dataparser(m_pSendMessage->szWParam,istrlen(m_pSendMessage->szWParam),gmalloc,&dwLength);
				*((BYTE*)wParam+dwLength)=0;
				bFreeWParam=TRUE;
			}
		}
		else if ((wParam=_wtoi(m_pSendMessage->szWParam))==0)
		{
			DWORD dwLength;
			wParam=(WPARAM)dataparser(m_pSendMessage->szWParam,istrlen(m_pSendMessage->szWParam),gmalloc,&dwLength);
			*((BYTE*)wParam+dwLength)=0;
			bFreeWParam=TRUE;
		}
	}

	// Parse lParam
	if (m_pSendMessage->szLParam!=NULL)
	{
		if (m_pSendMessage->szLParam[0]=='0')
		{
			if (m_pSendMessage->szLParam[1]=='x' || 
				m_pSendMessage->szLParam[1]=='X')
			{
				// Hex value
				LPWSTR szTemp;
				lParam=(WPARAM)wcstoul(m_pSendMessage->szLParam+2,&szTemp,16);
			}
			else if (m_pSendMessage->szLParam[1]!='\0')
			{
				DWORD dwLength;
				lParam=(WPARAM)dataparser(m_pSendMessage->szLParam,istrlen(m_pSendMessage->szLParam),gmalloc,&dwLength);
				*((BYTE*)lParam+dwLength)=0;
				bFreeLParam=TRUE;
			}
		}
		else if ((lParam=_wtoi(m_pSendMessage->szLParam))==0)
		{
			DWORD dwLength;
			lParam=(WPARAM)dataparser(m_pSendMessage->szLParam,istrlen(m_pSendMessage->szLParam),gmalloc,&dwLength);
			*((BYTE*)lParam+dwLength)=0;
            bFreeLParam=TRUE;
		}
	}

	if (hWnd!=NULL)
	{
		if (m_nMisc==PostMessage)
			::PostMessage(hWnd,m_pSendMessage->nMessage,wParam,lParam);
		else
			::SendMessage(hWnd,m_pSendMessage->nMessage,wParam,lParam);
	}

	if (bFreeWParam)
		GlobalFree((HANDLE)wParam);
	if (bFreeLParam)
		GlobalFree((HANDLE)lParam);

}
예제 #8
0
void CSubAction::DoPresets()
{
	CLocateDlg* pLocateDlg=GetLocateDlg();
	if (pLocateDlg!=NULL && m_szPreset!=NULL)
		pLocateDlg->LoadPreset(m_szPreset);
}
예제 #9
0
void CSubAction::DoChangeValue()
{
	CLocateDlg* pLocateDlg=GetLocateDlg();
	if (pLocateDlg==NULL || m_szValue==NULL)
		return;
	
	// Get handle to control
	CWnd Control(pLocateDlg->GetDlgItem(LOWORD(m_nControl)));
	HWND hInDialog=*pLocateDlg;

	if (Control.GetHandle()==NULL)
		Control.SetHandle(pLocateDlg->m_NameDlg.GetDlgItem(LOWORD(m_nControl)));
	if (Control.GetHandle()==NULL)
		Control.SetHandle(pLocateDlg->m_SizeDateDlg.GetDlgItem(LOWORD(m_nControl)));
	if (Control.GetHandle()==NULL)
		Control.SetHandle(pLocateDlg->m_AdvancedDlg.GetDlgItem(LOWORD(m_nControl)));

	ASSERT(Control.GetHandle()!=NULL);

	if (!Control.IsWindowEnabled())
		return;

	char szClass[100];
	GetClassName(Control,szClass,100);
	if (_stricmp(szClass,"EDIT")==0)
	{
		Control.SetWindowText(m_szValue);
		::SendMessage(Control.GetParent(),WM_COMMAND,MAKEWPARAM(m_nControl,EN_CHANGE),LPARAM((HWND)Control));
	}
	else if (_stricmp(szClass,"COMBOBOX")==0)
	{
		if ((Control.GetStyle()&CBS_DROPDOWNLIST)!=CBS_DROPDOWNLIST)
		{
			Control.SetWindowText(m_szValue);
			::SendMessage(Control.GetParent(),WM_COMMAND,MAKEWPARAM(m_nControl,CBN_EDITCHANGE),LPARAM((HWND)Control));
		}
		else
		{
			Control.SendMessage(CB_SETCURSEL,_wtoi(m_szValue));
			::SendMessage(Control.GetParent(),WM_COMMAND,MAKEWPARAM(m_nControl,CBN_SELCHANGE),LPARAM((HWND)Control));
		}
	}
	else if (_stricmp(szClass,"BUTTON")==0)
	{
		if (Control.GetStyle()&BS_CHECKBOX)  // This also takes radiobuttons
		{
			Control.SendMessage(BM_SETCHECK,_wtoi(m_szValue));
			::SendMessage(Control.GetParent(),WM_COMMAND,MAKEWPARAM(m_nControl,BN_CLICKED),LPARAM((HWND)Control));
		}
	}
	else if (_stricmp(szClass,"ComboBoxEx32")==0)
	{
		CComboBoxEx cb(Control);
		cb.SetCurSel(-1);
		cb.SetItemText(-1,m_szValue);
	}
	else if (_stricmp(szClass,"SysDateTimePick32")==0)
	{
		SYSTEMTIME st;
		GetLocalTime(&st);
		st.wHour=0;
		st.wMinute=0;
		st.wSecond=0;
		st.wMilliseconds=0;
		
		if (wcslen(m_szValue)>=8)
		{
			
		
			WCHAR szTemp[5];
			MemCopyW(szTemp,m_szValue,4);
			szTemp[4]='\0';
			st.wYear=(WORD)_wtol(szTemp);

			MemCopyW(szTemp,m_szValue+4,2);
			szTemp[2]='\0';
			st.wMonth=(WORD)_wtol(szTemp);

			MemCopyW(szTemp,m_szValue+6,2);
			szTemp[2]='\0';
			st.wDay=(WORD)_wtol(szTemp);

		}
		else
		{
			int nIndex=CTime::GetIndex(st.wDay,st.wMonth,st.wYear);
			if (m_szValue[0]='-')
				nIndex-=(WORD)_wtol(m_szValue+1);
			else 
				nIndex+=(WORD)_wtol(m_szValue);

			CTime::GetDayFromIndex(nIndex,st.wDay,st.wMonth,st.wYear);
		}
		Control.SendMessage(DTM_SETSYSTEMTIME,GDT_VALID,LPARAM(&st));
	}
}
예제 #10
0
void CSubAction::DoHelp()
{
	CTargetWnd* pWnd=GetLocateDlg();
	if (pWnd==NULL)
		pWnd=GetTrayIconWnd();
	
	switch(m_nHelp)
	{
	case HelpShowHelp:
		{
			HELPINFO h;
			h.cbSize=sizeof(HELPINFO);
			h.iContextType=HELPINFO_WINDOW;
			h.hItemHandle=GetFocus();
			
			if (pWnd==GetLocateDlg())
			{
				// If comboboxes are selected, the edit in size of combo
				// may have focus. 
				HWND hParent=GetParent((HWND)h.hItemHandle);
				while (hParent!=NULL && hParent!=*pWnd &&
					hParent!=((CLocateDlg*)pWnd)->m_NameDlg &&
					hParent!=((CLocateDlg*)pWnd)->m_SizeDateDlg &&
					hParent!=((CLocateDlg*)pWnd)->m_AdvancedDlg)
				{
					h.hItemHandle=hParent;
					hParent=GetParent(hParent);
				}
			}


			h.iCtrlId=GetDlgCtrlID((HWND)h.hItemHandle);
			h.dwContextId=0;
			GetCursorPos(&h.MousePos);
			pWnd->OnHelp(&h);
			break;
		}
	case HelpCloseHelp:
		pWnd->HtmlHelp(HH_CLOSE_ALL,0);
		break;
	case HelpShowTopics:
		pWnd->HtmlHelp(HH_DISPLAY_TOPIC,0);
		break;
	case HelpIndex:
		pWnd->HtmlHelp(HH_DISPLAY_INDEX,0);
		break;
	case HelpTOC:
		pWnd->HtmlHelp(HH_DISPLAY_TOC,0);
		break;
	case HelpSearch:
		{
			HH_FTS_QUERY q;
			ZeroMemory(&q,sizeof(HH_FTS_QUERY));
			q.cbStruct=sizeof(HH_FTS_QUERY);

			pWnd->HtmlHelp(HH_DISPLAY_SEARCH,(DWORD_PTR)&q);
			break;
		}
	};

}
예제 #11
0
void CSubAction::DoShowHideDialog()
{
	CLocateDlg* pLocateDlg=GetLocateDlg();
	
	switch(m_nDialogCommand)
	{
	case ShowDialog:
		GetTrayIconWnd()->OnLocate();
		break;
	case MinimizeDialog:
		if (pLocateDlg!=NULL)
			pLocateDlg->ShowWindow(CWnd::swMinimize);
		break;
	case CloseDialog:
		if (pLocateDlg!=NULL)
			pLocateDlg->PostMessage(WM_CLOSE);
		break;
	case ShowOrHideDialog:
		if (pLocateDlg!=NULL)
		{
			WINDOWPLACEMENT wp;
			wp.length=sizeof(WINDOWPLACEMENT);
			pLocateDlg->GetWindowPlacement(&wp);
			if (wp.showCmd!=SW_SHOWMINIMIZED &&wp.showCmd!=SW_HIDE)
				pLocateDlg->ShowWindow(CWnd::swMinimize);
			else 
				GetTrayIconWnd()->OnLocate();
		}
		break;
	case OpenOrCloseDialog:
		if (pLocateDlg!=NULL)
		{
			WINDOWPLACEMENT wp;
			wp.length=sizeof(WINDOWPLACEMENT);
			pLocateDlg->GetWindowPlacement(&wp);
			if (wp.showCmd!=SW_SHOWMINIMIZED && wp.showCmd!=SW_HIDE)
				pLocateDlg->PostMessage(WM_CLOSE);
			else
				GetTrayIconWnd()->OnLocate();
		}
		else
			GetTrayIconWnd()->OnLocate();
		break;
	case RestoreDialog:
		if (pLocateDlg!=NULL)
			pLocateDlg->ShowWindow(CWnd::swRestore);
		break;
	case MaximizeDialog:
		if (pLocateDlg!=NULL)
			pLocateDlg->ShowWindow(CWnd::swMaximize);
		break;
	case MaximizeOrRestoreDialog:
		if (pLocateDlg!=NULL)
		{
			WINDOWPLACEMENT wp;
			wp.length=sizeof(WINDOWPLACEMENT);
			pLocateDlg->GetWindowPlacement(&wp);
			if (wp.showCmd!=SW_SHOWMAXIMIZED)
				pLocateDlg->ShowWindow(CWnd::swMaximize);
			else
				pLocateDlg->ShowWindow(CWnd::swRestore);
		}
		break;        
	case ShowOpenOrHideDialog:  
		if (pLocateDlg==NULL)
			GetTrayIconWnd()->OnLocate();
		else if (pLocateDlg!=NULL)
		{
			WINDOWPLACEMENT wp;
			wp.length=sizeof(WINDOWPLACEMENT);
			pLocateDlg->GetWindowPlacement(&wp);
			if (wp.showCmd!=SW_SHOWMINIMIZED &&wp.showCmd!=SW_HIDE)
				pLocateDlg->ShowWindow(CWnd::swMinimize);
			else 
				GetTrayIconWnd()->OnLocate();
		}
		break;
	case ShowDialogAndGetDirFromExplorer:
		{
			LPWSTR pPath=GetPathFromExplorer();
			GetTrayIconWnd()->OnLocate();

			if (pPath!=NULL)
			{
				CLocateDlg* pLocateDlg=GetLocateDlg();
				if (pLocateDlg!=NULL)
					pLocateDlg->SetPath(pPath);
				delete[] pPath;
			}
			break;
		}
		break;
	case StopLocatingOrCloseWindow:
		if (pLocateDlg!=NULL)
		{
			if (pLocateDlg->IsLocating())
				pLocateDlg->OnStop();
			else
				pLocateDlg->PostMessage(WM_CLOSE);
		}
		break;
	}
}
예제 #12
0
BOOL CCheckFileNotificationsThread::CreateHandlesOld()
{
	ASSERT(m_pEventHandles==NULL);
	ASSERT(m_lState==sInitializing);

	FnDebugMessage("FN: creating handles (old method)");
	

	CLocateDlg* pLocateDlg=GetLocateDlg();
	ASSERT(pLocateDlg!=NULL);
	
	// Loads roods from databases so that we know what to listen
	CArrayFAP<LPWSTR> aRoots;
	const CArray<PDATABASE>& aAllDatabases=GetLocateApp()->GetDatabases();
	CArray<PDATABASE> aUsedDatabases;
	for (int i=0;i<aAllDatabases.GetSize();i++)
	{
		if (pLocateDlg->IsDatabaseUsedInSearch(aAllDatabases[i]->GetID()))
			aUsedDatabases.Add(aAllDatabases[i]);
	}
	if (aUsedDatabases.GetSize()==0)
		return FALSE;
	CDatabaseInfo::GetRootsFromDatabases(aRoots,aUsedDatabases);
	if (aRoots.GetSize()==0)
		return FALSE;
	

	// Create arrays for event handles and data structures
	//
	// The first handle in m_pEventHandles is stop event, the rest are change notification 
	// objects returned by FindFirstChangeNotification function.
	// The first pointer in m_pRoots is NULL, the rest are pointers
	// to root directory. The lists are terminated with NULL
    
	// Allocating arraysn, note that the size of the list is not 
	// necessary aRoots.GetSize()+2 if FindFirstChangeNotification returns error
	m_pEventHandles=new HANDLE[aRoots.GetSize()+1];
	ASSERT(m_pEventHandles!=NULL);
	
	m_pRoots=new LPWSTR[aRoots.GetSize()+1];
	ASSERT(m_pRoots!=NULL);
	
	
	// First handle in event handles array is stop handle and 
	// first pointer to root directory is NULL,
	// so that each element in m_pEventHandles (with index >0) 
	// corresponds to element in m_pRoots array with the same index
	m_pEventHandles[0]=m_hStopEvent;
	m_pRoots[0]=NULL;


	// Creating handles for directories in aRoots array using FindFirstChangeNotification
	m_nHandles=1;
	
	for (int i=0;i<aRoots.GetSize();i++)
	{
		if (m_lFlags&fwStopWhenPossible)
		{
			// Notify to Stop() that we are going to stop what 
			// we are doing
			SetEvent(m_hStopEvent);
			InterlockedExchange(&m_lState,sStopping);
			break;
		}


		CStringW sRoot=aRoots.GetAt(i);

		// If root of the type "X:", change it to "X:\"
		if (sRoot[1]==':' && sRoot[2]=='\0')
			sRoot << L'\\';
		
				
#ifdef _DEBUG_LOGGING
		// If logging is on, do not use change notifications for root containing log file
		LPCSTR pLogFile=GetDebugLoggingFile();
		if (pLogFile!=NULL)
		{
			// No debug logging for drive containing hfcdebug.log

			char* szPath=alloccopyWtoA(sRoot);
			MakeLower(szPath);
			BOOL bSame=strncmp(szPath,pLogFile,sRoot.GetLength())==0;
			delete[] szPath;
            if (bSame)
				continue;
		}
#endif
		

		// Create find change notification objects
		if (IsUnicodeSystem())
			m_pEventHandles[m_nHandles]=FindFirstChangeNotificationW(sRoot,TRUE,
				FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE);
		else
			m_pEventHandles[m_nHandles]=FindFirstChangeNotification(W2A(sRoot),TRUE,
				FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE);
		
		if (m_pEventHandles[m_nHandles]==INVALID_HANDLE_VALUE)
		{
			// FindFirstChangeNotification returned error, skipping this directory
			continue;
		}

		DebugOpenEvent(m_pEventHandles[m_nHandles]);


		sRoot.MakeLower();
		sRoot.FreeExtra();
		m_pRoots[m_nHandles]=sRoot.GiveBuffer();
		m_nHandles++;

	}


	

	FnDebugMessage("FN handles created");
	return TRUE;
}
예제 #13
0
BOOL CCheckFileNotificationsThread::Stop()
{
	// Stopping background notifier
	FnDebugMessage("FN: stopping");
	
	// First check whether thread is already stopped
	if (m_hThread==NULL)
	{
		FnDebugMessage("FN: already stopped");
		return FALSE;
	}

	// Creating a copy of thread handle and using
	HANDLE hThread;
	DuplicateHandle(GetCurrentProcess(),m_hThread,GetCurrentProcess(),
                    &hThread,0,FALSE,DUPLICATE_SAME_ACCESS);
	DebugOpenThread(hThread);
	
	
	ASSERT(m_lState==sInitializing || m_lState==sWaiting || 
		m_lState==sProcessing || m_lState==sStopping);

	// First, try some friendly ways to terminate thread

	switch (m_lState)
	{
	case sInitializing:
		// Still initializing, say that processing can be stopped
		FnDebugMessage("FN: thread still initializing");
		InterlockedExchange(&m_lFlags,m_lFlags|fwStopWhenPossible);
		
		// First wait that initialization is ended
		if (WaitForSingleObject(m_hStopEvent,500)!=WAIT_OBJECT_0)
			break;
		
		// Wait that ending processes are handled
		WaitForSingleObject(m_hThread,1000);
		break;
	case sWaiting:
		FnDebugMessage("FN: thread waiting");
		
		// Waiting events, so give it
		SetEvent(m_hStopEvent);
		
		// Wait that ending processes are handled
		WaitForSingleObject(m_hThread,1000);
		break;
	case sProcessing:
		FnDebugMessage("FN: thread is processing");
		InterlockedExchange(&m_lFlags,m_lFlags|fwStopWhenPossible);
		
		
		// Wait that ending processes are handled
		if (GetCurrentThreadId()==GetTrayIconWnd()->GetLocateDlgThread()->GetThreadId())
		{
			// This Stop() is called from CLocateDlg, it is possible
			// that RunninProcNew sens messages to this window.
			// Taking care of that
			for (int i=0;i<40;i++)
			{
				PostQuitMessage(0);
				GetTrayIconWnd()->GetLocateDlgThread()->ModalLoop();
				if (WaitForSingleObject(hThread,50)!=WAIT_TIMEOUT)
					break;
			}
		}
		else
			WaitForSingleObject(hThread,2000);
		break;
		
	};			

	
	
	if (GetLocateDlg()->m_pFileNotificationsThread!=NULL)
	{
		// So that didn't go very well, use harder ways
		InterlockedExchange(&m_lState,sTerminated);

		DWORD status=0;
		BOOL bRet=::GetExitCodeThread(hThread,&status);
		BOOL bTerminated=FALSE;

		
		if (bRet && status==STILL_ACTIVE)
		{
			if (::TerminateThread(hThread,1,TRUE))
				bTerminated=TRUE;
		}

		if (bTerminated)
			delete this;
	}

	// Closing dublicated handle
	CloseHandle(hThread);	
	DebugCloseThread(hThread);
	return TRUE;
}
예제 #14
0
BOOL CCheckFileNotificationsThread::CreateHandlesNew()
{
	ASSERT(m_pEventHandles==NULL);
	ASSERT(m_lState==sInitializing);

	FnDebugMessage("FN: creating handles");

	CLocateDlg* pLocateDlg=GetLocateDlg();
	ASSERT(pLocateDlg!=NULL);

	// Loads roods from databases so that we know what to listen
	CArrayFAP<LPWSTR> aRoots;
	const CArray<PDATABASE>& aAllDatabases=GetLocateApp()->GetDatabases();
	CArray<PDATABASE> aUsedDatabases;
	for (int i=0;i<aAllDatabases.GetSize();i++)
	{
		if (pLocateDlg->IsDatabaseUsedInSearch(aAllDatabases[i]->GetID()))
			aUsedDatabases.Add(aAllDatabases[i]);
	}
	if (aUsedDatabases.GetSize()==0)
		return FALSE;
	CDatabaseInfo::GetRootsFromDatabases(aRoots,aUsedDatabases);
	if (aRoots.GetSize()==0)
		return FALSE;
	
	
	// Create arrays for event handles and data structures
	//
	// The first handle in m_pEventHandles is stop event, the rest of
	// handles are events which are used in overlay structure (m_pDirDatas[i].ol)
	// The first pointer in m_pDirDatas is NULL, the rest are pointers
	// to DIRCHANGEDATA structures. 
	// The lists are terminated with NULL
    
	// Allocating arraysn, note that the size of the list is not 
	// necessary aRoots.GetSize()+2 if CreateFileW or m_pReadDirectoryChangesW
	// return error
	m_pEventHandles=new HANDLE[aRoots.GetSize()+1];
	ASSERT(m_pEventHandles!=NULL);
	
	m_pDirDatas=new DIRCHANGEDATA*[aRoots.GetSize()+1];
	ASSERT(m_pDirDatas!=NULL);
	
	

	// First event in events array is stop event and first pointer to 
	// DIRCHANGEDATA structure is NULL, so that each element in m_pEventHandles (with index >0) 
	// corresponds to element in m_pChangeDatas with the same index
	m_pEventHandles[0]=m_hStopEvent;
	m_pDirDatas[0]=NULL;



	// Creating handles and DIRCHANGEDATA structures for directories in aRoots array
	m_nHandles=1; // Number of handles currently in arrays, first element is stop event / NULL
	DIRCHANGEDATA* pDirData=NULL; 
	
	for (int i=0;i<aRoots.GetSize();i++)
	{
		if (m_lFlags&fwStopWhenPossible)
		{
			// Notify to Stop() that we are going to stop what 
			// we are doing
			InterlockedExchange(&m_lState,sStopping);
			SetEvent(m_hStopEvent);
			break;
		}


		CStringW sRoot=aRoots.GetAt(i);

		// If root of the type "X:", change it to "X:\"
		if (sRoot[1]==':' && sRoot[2]=='\0')
			sRoot << L'\\';
		

	/*
#ifdef _DEBUG_LOGGING
		// If logging is on, do not use change notifications for root containing log file
		LPCSTR pLogFile=GetDebugLoggingFile();
		if (pLogFile!=NULL)
		{
			// No debug logging for drive containing hfcdebug.log

			char* szPath=alloccopyWtoA(sRoot);
			MakeLower(szPath);
			BOOL bSame=strncmp(szPath,pLogFile,sRoot.GetLength())==0;
			delete[] szPath;
            if (bSame)
				continue;
		}
#endif
	*/	

		// Allocating new DIRCHANGEDATA struct
		if (pDirData==NULL)
		{
			pDirData=new DIRCHANGEDATA;
			// Create event for overlay structure
			pDirData->ol.hEvent=CreateEvent(NULL,FALSE,FALSE,NULL);
			DebugOpenEvent(pDirData->ol.hEvent);
			
			// Allocate buffer
			pDirData->pBuffer=new BYTE[CHANGE_BUFFER_LEN];
		}

		// Create handle to directory
		if (IsUnicodeSystem())
			pDirData->hDirHandle=CreateFileW(sRoot,GENERIC_READ /*FILE_LIST_DIRECTORY*/,FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
				NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,NULL);
		else
			pDirData->hDirHandle=CreateFile(W2A(sRoot),GENERIC_READ /*FILE_LIST_DIRECTORY*/,FILE_SHARE_READ|FILE_SHARE_DELETE|FILE_SHARE_WRITE,
				NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED,NULL);
		
		// If pDirData handle is invalid, skip this root
		if (pDirData->hDirHandle==INVALID_HANDLE_VALUE)
			continue;

		
		DebugOpenHandle(dhtFile,pDirData->hDirHandle,sRoot);


		// Test this again
		if (m_lFlags&fwStopWhenPossible)
		{
			// Notify to Stop() that we are going to stop what 
			// we are doing
			InterlockedExchange(&m_lState,sStopping);
			SetEvent(m_hStopEvent);
			break;
		}



		
		// Start to read directory changes, asynchronous mode
		BOOL bRet=m_pReadDirectoryChangesW(pDirData->hDirHandle,pDirData->pBuffer,CHANGE_BUFFER_LEN,TRUE,
			FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|
            FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE|
            FILE_NOTIFY_CHANGE_CREATION|FILE_NOTIFY_CHANGE_SECURITY,
			NULL,&pDirData->ol,NULL);
		
				
		if (!bRet)
		{
			// Cannot read directory changes (maybe UNC path), closing directory handle and skipping 
			// this directory. Allocated pDirData can be left untouched for the next try
			CloseHandle(pDirData->hDirHandle);
			DebugCloseHandle(dhtFile,pDirData->hDirHandle,sRoot);
			continue;
		}


		// And yet again
		if (m_lFlags&fwStopWhenPossible)
		{
			// Notify to Stop() that we are going to stop what 
			// we are doing
			SetEvent(m_hStopEvent);
			InterlockedExchange(&m_lState,sStopping);
			break;
		}



		// Copy root path to pDirData structure
		if (sRoot.LastChar()!=L'\\')
			sRoot << L'\\';
		sRoot.MakeLower();
		sRoot.FreeExtra();
		pDirData->dwRootLength=sRoot.GetLength();
		pDirData->pRoot=sRoot.GiveBuffer();


		// Handle in m_pEventHandles was the event used in overlay structure, set it
		m_pEventHandles[m_nHandles]=pDirData->ol.hEvent;

		// Add pointer to m_pDirDatas structure
		ASSERT(m_nHandles<UINT(aRoots.GetSize()+2));
		m_pDirDatas[m_nHandles]=pDirData;
		m_nHandles++;


		// New DIRCHANGEDATA structure should be allocated
		pDirData=NULL;


	}

	
	// Free extra DIRCHANGEDATA structure
	if (pDirData!=NULL)
		delete pDirData;

	


	FnDebugMessage("FN handles created");
	return TRUE;
}
예제 #15
0
BOOL CCheckFileNotificationsThread::RunningProcOld()
{
	// Delete this when this functions ends
	CAutoPtr<CCheckFileNotificationsThread> thisPtr=this;

	if (!CreateHandlesOld())
		return FALSE;

	
	
	for (;;)
	{
		FnDebugMessage("FN goes to sleep");
		InterlockedExchange(&m_lState,sWaiting);
		DWORD nRet=WaitForMultipleObjects(m_nHandles,m_pEventHandles,FALSE,INFINITE);
		InterlockedExchange(&m_lState,sProcessing);
		FnDebugMessage1("FN waked nRet=%X",nRet);

		
		
		if (nRet==WAIT_OBJECT_0) // The first is end event
		{
			// First event signalled, this event is for stopping
			// So do nothing here and exit
			FnDebugMessage("FN stopping event signalled, exiting");
			break;
		}
		else if (nRet>WAIT_OBJECT_0 && nRet<WAIT_OBJECT_0+m_nHandles)
		{
			//BkgDebugFormatMessage4("Something is changed in %S",m_pRoots[nRet-WAIT_OBJECT_0],0,0,0);

			CLocateDlg* pLocateDlg=GetLocateDlg();
			
			// Locate dialog is also closed, stopping this process
			if (pLocateDlg==NULL)
				break;

			if (!pLocateDlg->IsLocating()) // if locating in process, do nothing
			{
				while (pLocateDlg->m_pBackgroundUpdater!=NULL &&
					!pLocateDlg->m_pBackgroundUpdater->m_lIsWaiting)
					Sleep(200);
				
				// Stop if required
				if (m_lFlags&fwStopWhenPossible)
					break;
					
				// Updating changed items by checking all items
				UpdateItemsInRoot(m_pRoots[nRet-WAIT_OBJECT_0],pLocateDlg);		
			}

			// Check this again 
			if (m_lFlags&fwStopWhenPossible)
				break;

#ifdef _DEBUG_LOGGING
			BOOL bRet=FindNextChangeNotification(m_pEventHandles[nRet-WAIT_OBJECT_0]);
			FnDebugMessage3("CCheckFileNotificationsThread::RunningProcOld(): FindNextChangeNotification returns %X, nret=%X, nRet-WAIT_OBJECT_0=%X",bRet,nRet,nRet-WAIT_OBJECT_0);
#else	
			FindNextChangeNotification(m_pEventHandles[nRet-WAIT_OBJECT_0]);
#endif		

			// Finally, before going to sleep, check that shell we continue
			if (m_lFlags&fwStopWhenPossible)
				break;
		}
		else 
		{
			FnDebugMessage3("FN nRet not handled, nRet=0x%X, handles=%d, GetLastError()=0x%X",nRet,m_nHandles,GetLastError());
		}
	}
	


	InterlockedExchange(&m_lState,sStopping);
			

	
	
	//BkgDebugMessage("CCheckFileNotificationsThread::RunningProcOld() END");
	return FALSE;
}
예제 #16
0
BOOL CCheckFileNotificationsThread::RunningProcNew()
{
	FnDebugMessage("FN: RunningProcNew started");
	
	// Delete this when this functions ends
	CAutoPtr<CCheckFileNotificationsThread> thisPtr=this;

	// Creating handles
	if (!CreateHandlesNew())
		return FALSE;
	
	
	DWORD dwOut;

	for (;;)
	{
		FnDebugMessage("FN goes to sleep");
		InterlockedExchange(&m_lState,sWaiting);
		DWORD nRet=WaitForMultipleObjects(m_nHandles,m_pEventHandles,FALSE,INFINITE);
		InterlockedExchange(&m_lState,sProcessing);
		FnDebugMessage1("FN waked nRet=%X",nRet);


		if (nRet==WAIT_OBJECT_0) 
		{
			// First event signalled, this event is for stopping
			// So do nothing here and exit
			FnDebugMessage("FN stopping event signalled, exiting");
			break;
		}
		else if (nRet>WAIT_OBJECT_0 && nRet<WAIT_OBJECT_0+m_nHandles)
		{
			CLocateDlg* pLocateDlg=GetLocateDlg();
			
            // Locate dialog is also closed, stopping this process
			if (pLocateDlg==NULL)
				break;

			
			DIRCHANGEDATA* pChangeData=m_pDirDatas[nRet-WAIT_OBJECT_0];
			
			// Asking changes
			if (!pLocateDlg->IsLocating()) // if locating in process, do nothing
			{
				if (GetOverlappedResult(pChangeData->hDirHandle,&pChangeData->ol,&dwOut,FALSE))
				{
					// If GetOverlappedResults took so long that Stop() has given during this time
					// stop right now
					if (m_lFlags&fwStopWhenPossible)
						break;
					
					while (pLocateDlg->m_pBackgroundUpdater!=NULL &&
						!pLocateDlg->m_pBackgroundUpdater->m_lIsWaiting)
						Sleep(200);
					
					
					if (dwOut==0)
						UpdateItemsInRoot(pChangeData->pRoot,pLocateDlg);
					else
					{
						FILE_NOTIFY_INFORMATION* pStruct=(FILE_NOTIFY_INFORMATION*)pChangeData->pBuffer;
						while (1)
						{
							// Check stop state again
							if (m_lFlags&fwStopWhenPossible)
								break;

							DWORD dwLength=pStruct->FileNameLength/2;

							// Skip log files
							BOOL bSkipThisFile=FALSE;
							int nFilePart;
							for (nFilePart=dwLength-1;nFilePart>=0 && pStruct->FileName[nFilePart]!=L'\\';nFilePart--);
							nFilePart++;

							// Skipping ntuser.dat.log file
							if (dwLength-nFilePart==14)
							{
								if (_wcsnicmp(pStruct->FileName+nFilePart,L"ntuser.dat.log",14)==0)
									bSkipThisFile=TRUE;
							}

#ifdef _DEBUG
							// Skipping HFCDebug.log
							if (dwLength-nFilePart==12)
							{
								if (_wcsnicmp(pStruct->FileName+nFilePart,L"HFCDebug.log",12)==0)
									bSkipThisFile=TRUE;
							}
#endif

							if (!bSkipThisFile)
							{
								m_pFile=new WCHAR[pChangeData->dwRootLength+dwLength+2];
								MemCopyW(m_pFile,pChangeData->pRoot,pChangeData->dwRootLength);
								MemCopyW(m_pFile+pChangeData->dwRootLength,pStruct->FileName,dwLength);
								dwLength+=pChangeData->dwRootLength;
								m_pFile[dwLength]='\0';
								MakeLower(m_pFile);

								
								//DebugFormatMessage("BN: file=%S action=%d",m_pFile,pStruct->Action);

								switch(pStruct->Action)
								{
								case FILE_ACTION_ADDED:
								case FILE_ACTION_RENAMED_NEW_NAME:
									FileCreated(m_pFile,dwLength,pLocateDlg);
									break;
								case FILE_ACTION_REMOVED:
								case FILE_ACTION_RENAMED_OLD_NAME:
									FileDeleted(m_pFile,dwLength,pLocateDlg);
									break;
								case FILE_ACTION_MODIFIED:
									FileModified(m_pFile,dwLength,pLocateDlg);
									break;
								}
								
								delete[] m_pFile;
								m_pFile=NULL;
							}

							if (pStruct->NextEntryOffset==0)
								break;
							*((char**)&pStruct)+=pStruct->NextEntryOffset;

							
						}		
					}
				}
			}
			
			// Check this again 
			if (m_lFlags&fwStopWhenPossible)
				break;

			
			// Coing to listen changes
			FnDebugMessage("FN: going to listen changes");
			BOOL bRet=m_pReadDirectoryChangesW(pChangeData->hDirHandle,pChangeData->pBuffer,CHANGE_BUFFER_LEN,TRUE,
				FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|
				FILE_NOTIFY_CHANGE_ATTRIBUTES|FILE_NOTIFY_CHANGE_SIZE|FILE_NOTIFY_CHANGE_LAST_WRITE|
				FILE_NOTIFY_CHANGE_CREATION|FILE_NOTIFY_CHANGE_SECURITY,
				&dwOut,&pChangeData->ol,NULL);
			FnDebugMessage("FN: m_pReadDirectoryChangesW returned");
			

			if (!bRet)
			{
				// ReadDirectoryChangesW failed, reset event manually
				FnDebugMessage("FN: ReadDirectoryChangesW failed");
				ResetEvent(pChangeData->ol.hEvent);
			}


			// Finally, before going to sleep, check that shell we continue
			if (m_lFlags&fwStopWhenPossible)
				break;

		}
	}


	InterlockedExchange(&m_lState,sStopping);

	FnDebugMessage("FN RunningProcNew ends");
	return FALSE;
}