void QWinSettingsPrivate::remove(const QString &uKey) { if (writeHandle() == 0) { setStatus(QSettings::AccessError); return; } QString rKey = escapedKey(uKey); // try to delete value bar in key foo LONG res; HKEY handle = openKey(writeHandle(), registryPermissions, keyPath(rKey)); if (handle != 0) { res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(keyName(rKey).utf16())); RegCloseKey(handle); } // try to delete key foo/bar and all subkeys handle = openKey(writeHandle(), registryPermissions, rKey); if (handle != 0) { deleteChildGroups(handle); if (rKey.isEmpty()) { QStringList childKeys = childKeysOrGroups(handle, QSettingsPrivate::ChildKeys); for (int i = 0; i < childKeys.size(); ++i) { QString group = childKeys.at(i); LONG res = RegDeleteValue(handle, reinterpret_cast<const wchar_t *>(group.utf16())); if (res != ERROR_SUCCESS) { qWarning("QSettings: RegDeleteValue failed on subkey \"%s\": %s", group.toLatin1().data(), errorCodeToString(res).toLatin1().data()); } } } else { #if defined(Q_OS_WINCE) // For WinCE always Close the handle first. RegCloseKey(handle); #endif res = RegDeleteKey(writeHandle(), reinterpret_cast<const wchar_t *>(rKey.utf16())); if (res != ERROR_SUCCESS) { qWarning("QSettings: RegDeleteKey failed on key \"%s\": %s", rKey.toLatin1().data(), errorCodeToString(res).toLatin1().data()); } } RegCloseKey(handle); } }
QWinSettingsPrivate::~QWinSettingsPrivate() { if (deleteWriteHandleOnExit && writeHandle() != 0) { #if defined(Q_OS_WINCE) remove(regList.at(0).key()); #else QString emptyKey; DWORD res = RegDeleteKey(writeHandle(), reinterpret_cast<const wchar_t *>(emptyKey.utf16())); if (res != ERROR_SUCCESS) { qWarning("QSettings: Failed to delete key \"%s\": %s", regList.at(0).key().toLatin1().data(), errorCodeToString(res).toLatin1().data()); } #endif } for (int i = 0; i < regList.size(); ++i) regList[i].close(); }
//---------------------------------------------------------------------------- // writeHandleAndInject // Writes the internal mIEMainWindow to the mem file and invokes the page // action broker to inject the page actions DLL into the IE process. HRESULT Proxy::writeHandleAndInject(DWORD aProcessId) { // detect bitness of target process CHandle process(::OpenProcess( PROCESS_QUERY_LIMITED_INFORMATION, FALSE, aProcessId )); if( !process ) { return HRESULT_FROM_WIN32(::GetLastError()); } BOOL is64 = Is64bitProcess(process); process.Close(); // write window handle CHandle fileMapping; HRESULT hr = writeHandle(mIEMainWindow, fileMapping.m_h); if (FAILED(hr)) { return hr; } // prepare broker process STARTUPINFO startInfo; ::ZeroMemory( &startInfo, sizeof( startInfo ) ); startInfo.cb = sizeof( startInfo ); startInfo.dwFlags |= STARTF_USESHOWWINDOW; startInfo.wShowWindow = FALSE; PROCESS_INFORMATION processInfo; ::ZeroMemory( &processInfo, sizeof( processInfo ) ); // pass process-ID CString params; params.Format(_T("%lu"), aProcessId); // path for broker exe to use CString path; path.Format(_T("%s%s"), (is64) ? mInstallPath64 : mInstallPath32, sBrokerExec); if( ::CreateProcess( path.GetBuffer(MAX_PATH), params.GetBuffer(MAX_PATH), NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &startInfo, &processInfo ) ){ ::WaitForSingleObject( processInfo.hProcess, INFINITE ); ::CloseHandle( processInfo.hThread ); ::CloseHandle( processInfo.hProcess ); return S_OK; } // something went wrong. Call GetLastError BEFORE closing file handle! DWORD dw = ::GetLastError(); fileMapping.Close(); return HRESULT_FROM_WIN32(dw); }
bool QWinSettingsPrivate::isWritable() const { return writeHandle() != 0; }
void QWinSettingsPrivate::sync() { RegFlushKey(writeHandle()); }
void QWinSettingsPrivate::set(const QString &uKey, const QVariant &value) { if (writeHandle() == 0) { setStatus(QSettings::AccessError); return; } QString rKey = escapedKey(uKey); HKEY handle = createOrOpenKey(writeHandle(), registryPermissions, keyPath(rKey)); if (handle == 0) { setStatus(QSettings::AccessError); return; } DWORD type; QByteArray regValueBuff; // Determine the type switch (value.type()) { case QVariant::List: case QVariant::StringList: { // If none of the elements contains '\0', we can use REG_MULTI_SZ, the // native registry string list type. Otherwise we use REG_BINARY. type = REG_MULTI_SZ; QStringList l = variantListToStringList(value.toList()); QStringList::const_iterator it = l.constBegin(); for (; it != l.constEnd(); ++it) { if ((*it).length() == 0 || stringContainsNullChar(*it)) { type = REG_BINARY; break; } } if (type == REG_BINARY) { QString s = variantToString(value); regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2); } else { QStringList::const_iterator it = l.constBegin(); for (; it != l.constEnd(); ++it) { const QString &s = *it; regValueBuff += QByteArray((const char*)s.utf16(), (s.length() + 1) * 2); } regValueBuff.append((char)0); regValueBuff.append((char)0); } break; } case QVariant::Int: case QVariant::UInt: { type = REG_DWORD; qint32 i = value.toInt(); regValueBuff = QByteArray((const char*)&i, sizeof(qint32)); break; } case QVariant::LongLong: case QVariant::ULongLong: { type = REG_QWORD; qint64 i = value.toLongLong(); regValueBuff = QByteArray((const char*)&i, sizeof(qint64)); break; } case QVariant::ByteArray: // fallthrough intended default: { // If the string does not contain '\0', we can use REG_SZ, the native registry // string type. Otherwise we use REG_BINARY. QString s = variantToString(value); type = stringContainsNullChar(s) ? REG_BINARY : REG_SZ; if (type == REG_BINARY) { regValueBuff = QByteArray((const char*)s.utf16(), s.length() * 2); } else { regValueBuff = QByteArray((const char*)s.utf16(), (s.length() + 1) * 2); } break; } } // set the value LONG res = RegSetValueEx(handle, reinterpret_cast<const wchar_t *>(keyName(rKey).utf16()), 0, type, reinterpret_cast<const unsigned char*>(regValueBuff.constData()), regValueBuff.size()); if (res == ERROR_SUCCESS) { deleteWriteHandleOnExit = false; } else { qWarning("QSettings: failed to set subkey \"%s\": %s", rKey.toLatin1().data(), errorCodeToString(res).toLatin1().data()); setStatus(QSettings::AccessError); } RegCloseKey(handle); }
int MtpFfsCompatHandle::sendFile(mtp_file_range mfr) { uint64_t file_length = mfr.length; uint32_t given_length = std::min(static_cast<uint64_t>(MAX_MTP_FILE_SIZE), file_length + sizeof(mtp_data_header)); uint64_t offset = mfr.offset; int packet_size = getPacketSize(mBulkIn); // If file_length is larger than a size_t, truncating would produce the wrong comparison. // Instead, promote the left side to 64 bits, then truncate the small result. int init_read_len = std::min( static_cast<uint64_t>(packet_size - sizeof(mtp_data_header)), file_length); unsigned char *data = mIobuf[0].bufs.data(); unsigned char *data2 = mIobuf[1].bufs.data(); posix_fadvise(mfr.fd, 0, 0, POSIX_FADV_SEQUENTIAL | POSIX_FADV_NOREUSE); struct aiocb aio; aio.aio_fildes = mfr.fd; struct aiocb *aiol[] = {&aio}; int ret, length; int error = 0; bool read = false; bool write = false; // Send the header data mtp_data_header *header = reinterpret_cast<mtp_data_header*>(data); header->length = htole32(given_length); header->type = htole16(2); /* data packet */ header->command = htole16(mfr.command); header->transaction_id = htole32(mfr.transaction_id); // Some hosts don't support header/data separation even though MTP allows it // Handle by filling first packet with initial file data if (TEMP_FAILURE_RETRY(pread(mfr.fd, reinterpret_cast<char*>(data) + sizeof(mtp_data_header), init_read_len, offset)) != init_read_len) return -1; if (writeHandle(mBulkIn, data, sizeof(mtp_data_header) + init_read_len) == -1) return -1; file_length -= init_read_len; offset += init_read_len; ret = init_read_len + sizeof(mtp_data_header); // Break down the file into pieces that fit in buffers while (file_length > 0) { if (read) { // Wait for the previous read to finish aio_suspend(aiol, 1, nullptr); ret = aio_return(&aio); if (ret == -1) { errno = aio_error(&aio); return -1; } if (static_cast<size_t>(ret) < aio.aio_nbytes) { errno = EIO; return -1; } file_length -= ret; offset += ret; std::swap(data, data2); read = false; write = true; } if (error == -1) { return -1; } if (file_length > 0) { length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length); // Queue up another read aio_prepare(&aio, data, length, offset); aio_read(&aio); read = true; } if (write) { if (writeHandle(mBulkIn, data2, ret) == -1) { error = -1; } write = false; } } if (ret % packet_size == 0) { // If the last packet wasn't short, send a final empty packet if (TEMP_FAILURE_RETRY(::write(mBulkIn, data, 0)) != 0) { return -1; } } return 0; }
int MtpFfsCompatHandle::write(const void* data, size_t len) { return writeHandle(mBulkIn, data, len); }