File indexing completed on 2024-04-21 03:55:07

0001 /*
0002     This file is part of the KDE libraries
0003     SPDX-FileCopyrightText: 2014 Alex Richardson <arichardson.kde@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-only
0006 */
0007 #include "kioglobal_p.h"
0008 
0009 #include <QDebug>
0010 #include <QFile>
0011 #include <QFileInfo>
0012 
0013 #include <qt_windows.h>
0014 
0015 KIOCORE_EXPORT bool KIOPrivate::isProcessAlive(qint64 pid)
0016 {
0017     HANDLE procHandle = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
0018     bool alive = false;
0019     if (procHandle != INVALID_HANDLE_VALUE) {
0020         DWORD exitCode;
0021         if (GetExitCodeProcess(procHandle, &exitCode)) {
0022             alive = exitCode == STILL_ACTIVE;
0023         }
0024         CloseHandle(procHandle);
0025     }
0026     return alive;
0027 }
0028 
0029 // A callback to shutdown cleanly (no forced kill)
0030 BOOL CALLBACK closeProcessCallback(HWND hwnd, LPARAM lParam)
0031 {
0032     DWORD id;
0033     GetWindowThreadProcessId(hwnd, &id);
0034     if (id == (DWORD)lParam) {
0035         PostMessage(hwnd, WM_CLOSE, 0, 0);
0036     }
0037     return TRUE;
0038 }
0039 
0040 KIOCORE_EXPORT void KIOPrivate::sendTerminateSignal(qint64 pid)
0041 {
0042     // no error checking whether kill succeeded, Linux code also just sends a SIGTERM without checking
0043     HANDLE procHandle = OpenProcess(SYNCHRONIZE | PROCESS_TERMINATE, FALSE, pid);
0044     if (procHandle != INVALID_HANDLE_VALUE) {
0045         EnumWindows(&closeProcessCallback, (LPARAM)pid);
0046         CloseHandle(procHandle);
0047     }
0048 }
0049 
0050 KIOCORE_EXPORT bool KIOPrivate::createSymlink(const QString &source, const QString &destination, KIOPrivate::SymlinkType type)
0051 {
0052 #if _WIN32_WINNT >= 0x600
0053     DWORD flag;
0054     if (type == KIOPrivate::DirectorySymlink) {
0055         flag = SYMBOLIC_LINK_FLAG_DIRECTORY;
0056     } else if (type == KIOPrivate::FileSymlink) {
0057         flag = 0;
0058     } else {
0059         // Guess the type of the symlink based on the source path
0060         // If the source is a directory we set the flag SYMBOLIC_LINK_FLAG_DIRECTORY, for files
0061         // and non-existent paths we create a symlink to a file
0062         DWORD sourceAttrs = GetFileAttributesW((LPCWSTR)source.utf16());
0063         if (sourceAttrs != INVALID_FILE_ATTRIBUTES && (sourceAttrs & FILE_ATTRIBUTE_DIRECTORY)) {
0064             flag = SYMBOLIC_LINK_FLAG_DIRECTORY;
0065         } else {
0066             flag = 0;
0067         }
0068     }
0069     bool ok = CreateSymbolicLinkW((LPCWSTR)destination.utf16(), (LPCWSTR)source.utf16(), flag);
0070     if (!ok) {
0071         // create a .lnk file
0072         ok = QFile::link(source, destination);
0073     }
0074     return ok;
0075 #else
0076     qWarning("KIOPrivate::createSymlink: not implemented");
0077     return false;
0078 #endif
0079 }
0080 
0081 KIOCORE_EXPORT int kio_windows_lstat(const char *path, QT_STATBUF *buffer)
0082 {
0083     int result = QT_STAT(path, buffer);
0084     if (result != 0) {
0085         return result;
0086     }
0087     const QString pathStr = QFile::decodeName(path);
0088     // QFileInfo currently only checks for .lnk file in isSymlink() -> also check native win32 symlinks
0089     const DWORD fileAttrs = GetFileAttributesW((LPCWSTR)pathStr.utf16());
0090     if (fileAttrs != INVALID_FILE_ATTRIBUTES && (fileAttrs & FILE_ATTRIBUTE_REPARSE_POINT) || QFileInfo(pathStr).isSymLink()) {
0091         buffer->st_mode |= QT_STAT_LNK;
0092     }
0093     return result;
0094 }
0095 
0096 KIOCORE_EXPORT bool KIOPrivate::changeOwnership(const QString &file, KUserId newOwner, KGroupId newGroup)
0097 {
0098 #pragma message("TODO")
0099     qWarning("KIOPrivate::changeOwnership: not implemented yet");
0100     return false;
0101 }