BOOL CRegKey::DeleteKey(HKEY hKey,LPCWSTR szKey) { if (!IsUnicodeSystem()) return DeleteKey(hKey,W2A(szKey)); HKEY hSubKey; FILETIME ft; DWORD cb; WCHAR szSubKey[200]; if (RegOpenKeyExW(hKey,szKey,0, KEY_ENUMERATE_SUB_KEYS|KEY_SET_VALUE,&hSubKey)!=ERROR_SUCCESS) return TRUE; DebugOpenHandle(dhtRegKey,hSubKey,szKey); for(;;) { cb=400; if (RegEnumKeyExW(hSubKey,0,szSubKey,&cb,NULL, NULL,NULL,&ft)==ERROR_NO_MORE_ITEMS) break; DeleteKey(hSubKey,szSubKey); } RegCloseKey(hSubKey); DebugCloseHandle(dhtRegKey,hSubKey,szKey); RegDeleteKeyW(hKey,szKey); return TRUE; }
LONG CRegKey::RenameSubKey(HKEY hKey,LPCSTR szOldName,LPCSTR szNewName) { HKEY hSource,hDestination; LONG lErr=RegOpenKeyEx(hKey,szOldName,0,KEY_READ,&hSource); if (lErr!=ERROR_SUCCESS) return lErr; DebugOpenHandle(dhtRegKey,hSource,szOldName); lErr=RegCreateKeyEx(hKey,szNewName,0,NULL,0,KEY_ALL_ACCESS,NULL,&hDestination,NULL); if (lErr!=ERROR_SUCCESS) { RegCloseKey(hSource); return lErr; } DebugOpenHandle(dhtRegKey,hDestination,szNewName); LONG lRet=CopyKey(hSource,hDestination); RegCloseKey(hSource); DebugCloseHandle(dhtRegKey,hSource,szOldName); RegCloseKey(hDestination); DebugCloseHandle(dhtRegKey,hDestination,szNewName); if (lRet==ERROR_SUCCESS) { RegDeleteKey(hKey,szOldName); return ERROR_SUCCESS; } return lRet; }
BOOL CBackgroundUpdater::Start() { BuDebugMessage("CBackgroundUpdater::Start() BEGIN"); if (m_hThread!=NULL) { BuDebugMessage("CBackgroundUpdater::Start() ALREADY STARTED"); return FALSE; } DWORD dwThreadID; HANDLE hThread=CreateThread(NULL,0,UpdaterThreadProc,this,CREATE_SUSPENDED,&dwThreadID); DebugOpenHandle(dhtThread,hThread,"BackgroundUpdater"); DebugFormatMessage("BU started, thread ID=%X",dwThreadID); if (hThread==NULL) return FALSE; InterlockedExchangePointer(&m_hThread,hThread); SetThreadPriority(m_hThread,THREAD_PRIORITY_BELOW_NORMAL); InterlockedExchange(&m_lIsWaiting,FALSE); ResumeThread(m_hThread); BuDebugMessage("CBackgroundUpdater::Start() END"); return TRUE; }
LONG CRegKey::OpenKey(HKEY hKey,LPCWSTR lpszSubKey,DWORD fStatus,LPSECURITY_ATTRIBUTES lpSecurityAttributes) { if (!IsUnicodeSystem()) return OpenKey(hKey,W2A(lpszSubKey),fStatus,lpSecurityAttributes); REGSAM samDesired=0; DWORD fdwOptions; LONG ret; if (m_hKey!=NULL) { RegCloseKey(m_hKey); DebugCloseHandle(dhtRegKey,&m_hKey,lpszSubKey); } if (fStatus==samAll) samDesired=KEY_ALL_ACCESS; else { if (fStatus&samCreateLink) samDesired|=KEY_CREATE_LINK; if (fStatus&samCreateSubkey) samDesired|=KEY_CREATE_SUB_KEY; if (fStatus&samEnumerateSubkeys) samDesired|=KEY_ENUMERATE_SUB_KEYS; if (fStatus&samExecute) samDesired|=KEY_EXECUTE; if (fStatus&samNotify) samDesired|=KEY_NOTIFY; if (fStatus&samQueryValue) samDesired|=KEY_QUERY_VALUE; if (fStatus&samSetValue) samDesired|=KEY_SET_VALUE; } if (fStatus&optionVolatile) fdwOptions=REG_OPTION_VOLATILE; else fdwOptions=REG_OPTION_NON_VOLATILE; if (fStatus&openExist) ret=RegOpenKeyExW(hKey,lpszSubKey,0,samDesired,&m_hKey); else { DWORD type; ret=RegCreateKeyExW(hKey,lpszSubKey,0,NULL,fdwOptions,samDesired,lpSecurityAttributes,&m_hKey,&type); } if (ret!=ERROR_SUCCESS) m_hKey=NULL; else DebugOpenHandle(dhtRegKey,m_hKey,lpszSubKey); return ret; }
void CTargetWnd::OnNcDestroy() { WindowProc(WM_NCDESTROY,0,0); // For WaitForWindow() CString name; name.SetBase(32); name << "WFWE" << (ULONGLONG)this; HANDLE hEvent=OpenEvent(EVENT_MODIFY_STATE,FALSE,name); DebugOpenHandle(dhtEvent,hEvent,name); SetEvent(hEvent); CloseHandle(hEvent); DebugCloseHandle(dhtEvent,hEvent,name); // No more messages to this class ::SetWindowLongPtr(m_hWnd,GWLP_USERDATA,0); }
BOOL CCheckFileNotificationsThread::Start() { if (m_hThread!=NULL) return FALSE; DWORD dwThreadID; m_hThread=CreateThread(NULL,0,NotificationThreadProc,this,CREATE_SUSPENDED,&dwThreadID); DebugOpenHandle(dhtThread,m_hThread,"CheckFileNotifications"); FnDebugMessage1("FN: thread started ID=%X",(DWORD)dwThreadID); if (m_hThread==NULL) return FALSE; SetThreadPriority(m_hThread,THREAD_PRIORITY_BELOW_NORMAL); ResumeThread(m_hThread); return TRUE; }
BOOL CRegKey::DeleteKey(HKEY hKey,LPCSTR szKey) { HKEY hSubKey; FILETIME ft; DWORD cb; char szSubKey[200]; if (RegOpenKeyEx(hKey,szKey,0, KEY_ENUMERATE_SUB_KEYS|KEY_SET_VALUE,&hSubKey)!=ERROR_SUCCESS) return TRUE; DebugOpenHandle(dhtRegKey,hSubKey,szKey); for(;;) { cb=200; if (RegEnumKeyEx(hSubKey,0,szSubKey,&cb,NULL, NULL,NULL,&ft)==ERROR_NO_MORE_ITEMS) break; DeleteKey(hSubKey,szSubKey); } RegCloseKey(hSubKey); DebugCloseHandle(dhtRegKey,hSubKey,szKey); RegDeleteKey(hKey,szKey); return TRUE; }
// First, couple of registry extensions LONG CRegKey::CopyKey(HKEY hSource,HKEY hDestination) { LONG lRet=ERROR_SUCCESS; // First copy subkeys char szName[1000]; DWORD cb,i; for (i=0;;i++) { char szClass[1000]; DWORD cb2=1000; cb=1000; if (RegEnumKeyEx(hSource,i,szName,&cb,NULL,szClass,&cb2,NULL)!=ERROR_SUCCESS) break; HKEY hSubSource,hSubDestination; LONG lErr=RegOpenKeyEx(hSource,szName,0,KEY_READ,&hSubSource); if (lErr!=ERROR_SUCCESS) { lRet=lErr; continue; } DebugOpenHandle(dhtRegKey,hSubSource,szName); lErr=RegCreateKeyEx(hDestination,szName,0,szClass,0,KEY_ALL_ACCESS,NULL,&hSubDestination,NULL); if (lErr!=ERROR_SUCCESS) { RegCloseKey(hSubSource); lRet=lErr; continue; } DebugOpenHandle(dhtRegKey,hSubDestination,szName); if (CopyKey(hSubSource,hSubDestination)<=0) lRet=lErr; RegCloseKey(hSubSource); RegCloseKey(hSubDestination); DebugCloseRegKey(hSubSource); DebugCloseRegKey(hSubDestination); } // Now copying values for (i=0;;i++) { cb=1000; DWORD dwType,dwDataSize; if (RegEnumValue(hSource,i,szName,&cb,NULL,&dwType,NULL,&dwDataSize)!=ERROR_SUCCESS) break; BYTE* pData=new BYTE[dwDataSize+1]; LONG lErr; if ((lErr=RegQueryValueEx(hSource,szName,NULL,NULL,pData,&dwDataSize))!=ERROR_SUCCESS) lRet=lErr; else if ((lErr=RegSetValueEx(hDestination,szName,NULL,dwType,pData,dwDataSize))!=ERROR_SUCCESS) lRet=lErr; delete[] pData; } return lRet; }
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; }