static BOOL ensure_not_running(LPCWSTR dest) { DWORD processes[4096], needed, num; unsigned int i; WCHAR name[4*MAX_PATH] = L"<unknown>"; HANDLE h; DWORD len; LPWSTR fname = NULL; if ( !EnumProcesses( processes, sizeof(processes), &needed ) ) { return true; } num = needed / sizeof(DWORD); for (i = 0; i < num; i++) { if (processes[i] == 0) continue; h = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, processes[i] ); if (h != NULL) { len = GetProcessImageFileNameW(h, name, 4*MAX_PATH); CloseHandle(h); if (len != 0) { name[len] = 0; fname = PathFindFileName(name); if (wcscmp(fname, L"calibre.exe") == 0) { show_error(L"Calibre appears to be running on your computer. Please quit it before trying to install Calibre Portable."); return false; } } } } return true; }
// // Helper method to tell us if a given process ID corresponds to Lightroom // bool IsLightroomProcess( DWORD processId ) { bool isLightroomProcess = false; HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION, FALSE, processId ); if( hProcess ) { WCHAR wszFilename[ MAX_PATH + 1 ]; if( GetProcessImageFileNameW( hProcess, wszFilename, MAX_PATH ) > 0 ) isLightroomProcess = ( wcsstr( wszFilename, wszLightroomExe ) != NULL ); CloseHandle( hProcess ); } return isLightroomProcess; }
WCHAR * GetProcessNameInDeviceForm(HANDLE hProcess, DWORD *exitTag, DWORD *lastErrorCode) { WCHAR *fileName = malloc(sizeof(*fileName) * MAX_NAME_PATH); if (NULL == fileName) { *exitTag = 1; return NULL; } if (0 == GetProcessImageFileNameW(hProcess, fileName, MAX_PATH)) { *exitTag = 2; *lastErrorCode = GetLastError(); free(fileName); return NULL; } return fileName; }
bool ProcessLister::getAbsoluteFilePath(HANDLE hProcess, Process * process) { WCHAR processPath[MAX_PATH]; bool retVal = false; wcscpy_s(process->fullPath, L"Unknown path"); if(!hProcess) { //missing rights return false; } if (GetProcessImageFileNameW(hProcess, processPath, _countof(processPath)) > 0) { if (!deviceNameResolver->resolveDeviceLongNameToShort(processPath, process->fullPath)) { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getAbsoluteFilePath :: resolveDeviceLongNameToShort failed with path %s", processPath); #endif //some virtual volumes MessageBoxW(0, processPath, L"Cannot resolve this path!", MB_ICONERROR); } else { retVal = true; } } else { #ifdef DEBUG_COMMENTS Scylla::debugLog.log(L"getAbsoluteFilePath :: GetProcessImageFileName failed %u", GetLastError()); #endif if (GetModuleFileNameExW(hProcess, 0, process->fullPath, _countof(process->fullPath)) != 0) { retVal = true; } } return retVal; }
int wmain() { BOOL isWow64 = FALSE; IsWow64Process(GetCurrentProcess(), &isWow64); std::cout << "IsWow64" << " : " << isWow64 << std::endl; if (init_ntdll_func(isWow64) == false) { printf("Cannot load functions!\n"); return -1; } wchar_t calcPath[MAX_PATH] = { 0 }; ExpandEnvironmentStringsW(L"%SystemRoot%\\system32\\calc.exe", calcPath, MAX_PATH); wchar_t *targetPath = calcPath; wchar_t my_name[MAX_PATH] = { 0 }; GetModuleFileNameW(NULL, my_name, MAX_PATH); PTEB myTeb = NtCurrentTeb(); PPEB myPeb = myTeb->ProcessEnvironmentBlock; //> if (RtlEnterCriticalSection(myPeb->FastPebLock) != STATUS_SUCCESS) { return -2; } bool is_ok = update_params_in_peb(isWow64, myPeb, targetPath); RtlLeaveCriticalSection(myPeb->FastPebLock); //< if (!is_ok) { return -1; } MessageBoxW(GetDesktopWindow(), L"My momma calls me calc :D", L"Hello", MB_OK); //read the real path: wchar_t real_path[MAX_PATH] = { 0 }; GetProcessImageFileNameW(NtCurrentProcess(), real_path, MAX_PATH); //display the real path: MessageBoxW(GetDesktopWindow(), real_path, L"Real path:", MB_OK); return 0; }
bool isProcessRunning(int pid, const std::string &fileName) { if (pid <= 0) return false; qiLogDebug() << "Checking if process #" << pid << " is running"; std::string commandLine; #if BOOST_OS_WINDOWS HANDLE processHandle = OpenProcess( PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, static_cast<DWORD>(pid)); if (!processHandle) return false; qiLogDebug() << "Got handle for process #" << pid; DWORD exitCode = 0xFFFFFF; if (!GetExitCodeProcess(processHandle, &exitCode)) return false; if (exitCode != STILL_ACTIVE) return false; qiLogDebug() << "Process #" << pid << " is running"; if (fileName.empty()) return true; qiLogDebug() << "Checking process name for #" << pid; WCHAR winCommandLine[MAX_PATH]; DWORD clSize = GetProcessImageFileNameW( processHandle, winCommandLine, sizeof(winCommandLine) / sizeof(*winCommandLine)); CloseHandle(processHandle); if(clSize <= 0) return false; commandLine = qi::Path::fromNative(winCommandLine).str(); #elif BOOST_OS_MACOS int numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, NULL, 0); if (numberOfProcesses == 0) { qiLogError() << "Cannot get number of processes"; return false; } std::vector<int> pids(numberOfProcesses, 0); numberOfProcesses = proc_listpids(PROC_ALL_PIDS, 0, pids.data(), sizeof(int) * pids.size()); if (numberOfProcesses == 0) { qiLogError() << "Cannot get list of processes"; return false; } if (std::find(pids.begin(), pids.end(), pid) == pids.end()) return false; if (fileName.empty()) return true; char procPidPath[PROC_PIDPATHINFO_MAXSIZE]; int res = proc_pidpath(pid, procPidPath, sizeof(char) * PROC_PIDPATHINFO_MAXSIZE); if (!res) { qiLogDebug() << "Failed to get process info: " << strerror(errno); return false; } commandLine = procPidPath; #else // Linux std::string pathInProc = "/proc/" + to_string(pid) + "/cmdline"; bool cmdLineFilePresentButEmpty = false; do { boost::filesystem::ifstream file(pathInProc); qiLogDebug() << "process #" << pid << " " << (file.is_open() ? "exists" : "does not exist"); if (!file) return false; if (fileName.empty()) { file.close(); return true; } std::string buff; file >> buff; file.close(); commandLine.assign(buff.data(), std::strlen(buff.c_str())); cmdLineFilePresentButEmpty = commandLine.empty(); } while(cmdLineFilePresentButEmpty); #endif qiLogDebug() << "process #" << pid << " full command was: " << commandLine; const std::string actualProcessName = qi::Path(commandLine).filename(); qiLogDebug() << "process #" << pid << " executable was: " << actualProcessName << ", expected: " << (fileName + qi::path::detail::binSuffix()); return actualProcessName == (fileName + qi::path::detail::binSuffix()); }
static DWORD WINAPI SearchProcessThread(LPVOID param) { const char *access_rights_str[8] = { "n", "r", "w", "rw", "x", "rx", "wx", "rwx" }; char tmp[MAX_PATH]; NTSTATUS status = STATUS_SUCCESS; PSYSTEM_HANDLE_INFORMATION_EX handles = NULL; POBJECT_NAME_INFORMATION buffer = NULL; ULONG_PTR i; ULONG_PTR pid[2]; ULONG_PTR last_access_denied_pid = 0; ULONG bufferSize; USHORT wHandleNameLen; WCHAR *wHandleName = NULL; HANDLE dupHandle = NULL; HANDLE processHandle = NULL; BOOLEAN bFound = FALSE, bGotExePath, verbose = !_bQuiet; ULONG access_rights = 0; DWORD size; char exe_path[MAX_PATH] = { 0 }; wchar_t wexe_path[MAX_PATH]; int cur_pid; PF_INIT_OR_SET_STATUS(NtQueryObject, Ntdll); PF_INIT_OR_SET_STATUS(NtDuplicateObject, NtDll); PF_INIT_OR_SET_STATUS(NtClose, NtDll); StrArrayClear(&BlockingProcess); if (NT_SUCCESS(status)) status = PhCreateHeap(); if (NT_SUCCESS(status)) status = PhEnumHandlesEx(&handles); if (!NT_SUCCESS(status)) { uprintf("Warning: Could not enumerate process handles: %s", NtStatusError(status)); goto out; } pid[0] = (ULONG_PTR)0; cur_pid = 1; wHandleName = utf8_to_wchar(_HandleName); wHandleNameLen = (USHORT)wcslen(wHandleName); bufferSize = 0x200; buffer = PhAllocate(bufferSize); if (buffer == NULL) goto out; for (i = 0; ; i++) { ULONG attempts = 8; PSYSTEM_HANDLE_TABLE_ENTRY_INFO_EX handleInfo = (i < handles->NumberOfHandles) ? &handles->Handles[i] : NULL; if ((dupHandle != NULL) && (processHandle != NtCurrentProcess())) { pfNtClose(dupHandle); dupHandle = NULL; } // Update the current handle's process PID and compare against last // Note: Be careful about not trying to overflow our list! pid[cur_pid] = (handleInfo != NULL) ? handleInfo->UniqueProcessId : -1; if (pid[0] != pid[1]) { cur_pid = (cur_pid + 1) % 2; // If we're switching process and found a match, print it if (bFound) { vuprintf("● '%s' (pid: %ld, access: %s)", exe_path, pid[cur_pid], access_rights_str[access_rights & 0x7]); static_sprintf(tmp, "● %s (%s)", exe_path, access_rights_str[access_rights & 0x7]); StrArrayAdd(&BlockingProcess, tmp, TRUE); bFound = FALSE; access_rights = 0; } // Close the previous handle if (processHandle != NULL) { if (processHandle != NtCurrentProcess()) pfNtClose(processHandle); processHandle = NULL; } } CHECK_FOR_USER_CANCEL; // Exit loop condition if (i >= handles->NumberOfHandles) break; // Don't bother with processes we can't access if (handleInfo->UniqueProcessId == last_access_denied_pid) continue; // Filter out handles that aren't opened with Read (bit 0), Write (bit 1) or Execute (bit 5) access if ((handleInfo->GrantedAccess & 0x23) == 0) continue; // Open the process to which the handle we are after belongs, if not already opened if (pid[0] != pid[1]) { status = PhOpenProcess(&processHandle, PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, (HANDLE)handleInfo->UniqueProcessId); // There exists some processes we can't access if (!NT_SUCCESS(status)) { uuprintf("SearchProcess: Could not open process %ld: %s", handleInfo->UniqueProcessId, NtStatusError(status)); processHandle = NULL; if (status == STATUS_ACCESS_DENIED) { last_access_denied_pid = handleInfo->UniqueProcessId; } continue; } } // Now duplicate this handle onto our own process, so that we can access its properties if (processHandle == NtCurrentProcess()) { if (_bIgnoreSelf) continue; dupHandle = (HANDLE)handleInfo->HandleValue; } else { status = pfNtDuplicateObject(processHandle, (HANDLE)handleInfo->HandleValue, NtCurrentProcess(), &dupHandle, 0, 0, 0); if (!NT_SUCCESS(status)) continue; } // Filter non-storage handles. We're not interested in them and they make NtQueryObject() freeze if (GetFileType(dupHandle) != FILE_TYPE_DISK) continue; // A loop is needed because the I/O subsystem likes to give us the wrong return lengths... do { ULONG returnSize; // TODO: We might potentially still need a timeout on ObjectName queries, as PH does... status = pfNtQueryObject(dupHandle, ObjectNameInformation, buffer, bufferSize, &returnSize); if (status == STATUS_BUFFER_OVERFLOW || status == STATUS_INFO_LENGTH_MISMATCH || status == STATUS_BUFFER_TOO_SMALL) { uuprintf("SearchProcess: Realloc from %d to %d", bufferSize, returnSize); bufferSize = returnSize; PhFree(buffer); buffer = PhAllocate(bufferSize); } else { break; } } while (--attempts); if (!NT_SUCCESS(status)) { uuprintf("SearchProcess: NtQueryObject failed for handle %X of process %ld: %s", handleInfo->HandleValue, handleInfo->UniqueProcessId, NtStatusError(status)); continue; } // Don't bother comparing if we are looking for full match and the length is different if ((!_bPartialMatch) && (wHandleNameLen != buffer->Name.Length)) continue; // Likewise, if we are looking for a partial match and the current length is smaller if ((_bPartialMatch) && (wHandleNameLen > buffer->Name.Length)) continue; // Match against our target string if (wcsncmp(wHandleName, buffer->Name.Buffer, wHandleNameLen) != 0) continue; // If we are here, we have a process accessing our target! bFound = TRUE; // Keep a mask of all the access rights being used access_rights |= handleInfo->GrantedAccess; // The Executable bit is in a place we don't like => reposition it if (access_rights & 0x20) access_rights = (access_rights & 0x03) | 0x04; access_mask |= (BYTE) (access_rights & 0x7) + 0x80; // Bit 7 is always set if a process was found // If this is the very first process we find, print a header if (exe_path[0] == 0) vuprintf("WARNING: The following process(es) or service(s) are accessing %s:", _HandleName); // First, we try to get the executable path using GetModuleFileNameEx bGotExePath = (GetModuleFileNameExU(processHandle, 0, exe_path, MAX_PATH - 1) != 0); // The above may not work on Windows 7, so try QueryFullProcessImageName (Vista or later) if (!bGotExePath) { size = MAX_PATH; PF_INIT(QueryFullProcessImageNameW, kernel32); if ( (pfQueryFullProcessImageNameW != NULL) && (bGotExePath = pfQueryFullProcessImageNameW(processHandle, 0, wexe_path, &size)) ) wchar_to_utf8_no_alloc(wexe_path, exe_path, sizeof(exe_path)); } // Still nothing? Try GetProcessImageFileName. Note that GetProcessImageFileName uses // '\Device\Harddisk#\Partition#\' instead drive letters if (!bGotExePath) { bGotExePath = (GetProcessImageFileNameW(processHandle, wexe_path, MAX_PATH) != 0); if (bGotExePath) wchar_to_utf8_no_alloc(wexe_path, exe_path, sizeof(exe_path)); } // Complete failure => Just craft a default process name that includes the PID if (!bGotExePath) { safe_sprintf(exe_path, MAX_PATH, "Unknown_Process_%" PRIu64, (ULONGLONG)handleInfo->UniqueProcessId); } } out: if (exe_path[0] != 0) vuprintf("You should close these applications before attempting to reformat the drive."); else vuprintf("NOTE: Could not identify the process(es) or service(s) accessing %s", _HandleName); free(wHandleName); PhFree(buffer); PhFree(handles); PhDestroyHeap(); ExitThread(0); }