From b0671221e549b7411da0d566d23f200107c85029 Mon Sep 17 00:00:00 2001
From: jthedering <51533355+jthedering@users.noreply.github.com>
Date: Sun, 3 Jan 2016 17:24:33 +0000
Subject: [PATCH] Fixed: When a file was selected for the Convolution command
in the Configuration Editor that was not readable by the audio service, no
warning appeared.
---
Benchmark/Benchmark.vcxproj | 8 +--
Configurator/Configurator.vcxproj | 8 +--
Editor/Editor.pro | 2 +-
Editor/guis/ConvolutionFilterGUI.cpp | 47 +++++++++++-----
Editor/translations/Editor_de.qm | Bin 21941 -> 22385 bytes
Editor/translations/Editor_de.ts | 77 +++++++++++++++------------
EqualizerAPO.vcxproj | 8 +--
helpers/RegistryHelper.cpp | 52 ++++++++++++++++++
helpers/RegistryHelper.h | 1 +
9 files changed, 141 insertions(+), 62 deletions(-)
diff --git a/Benchmark/Benchmark.vcxproj b/Benchmark/Benchmark.vcxproj
index f1c7f2d..74782f6 100644
--- a/Benchmark/Benchmark.vcxproj
+++ b/Benchmark/Benchmark.vcxproj
@@ -97,7 +97,7 @@
Console
true
- muparserxd.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserxd.lib;version.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
@@ -110,7 +110,7 @@
Console
true
- muparserxd.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserxd.lib;version.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
@@ -128,7 +128,7 @@
true
true
true
- muparserx.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserx.lib;version.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
@@ -146,7 +146,7 @@
true
true
true
- muparserx.lib;version.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserx.lib;version.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
diff --git a/Configurator/Configurator.vcxproj b/Configurator/Configurator.vcxproj
index 621d777..c848422 100644
--- a/Configurator/Configurator.vcxproj
+++ b/Configurator/Configurator.vcxproj
@@ -138,7 +138,7 @@
Windows
true
- audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)
+ audioeng.lib;version.lib;Shlwapi.lib;authz.lib;comctl32.lib;%(AdditionalDependencies)
@@ -151,7 +151,7 @@
Windows
true
- audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)
+ audioeng.lib;version.lib;Shlwapi.lib;authz.lib;comctl32.lib;%(AdditionalDependencies)
@@ -168,7 +168,7 @@
true
true
true
- audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)
+ audioeng.lib;version.lib;Shlwapi.lib;authz.lib;comctl32.lib;%(AdditionalDependencies)
@@ -185,7 +185,7 @@
true
true
true
- audioeng.lib;version.lib;Shlwapi.lib;comctl32.lib;%(AdditionalDependencies)
+ audioeng.lib;version.lib;Shlwapi.lib;authz.lib;comctl32.lib;%(AdditionalDependencies)
diff --git a/Editor/Editor.pro b/Editor/Editor.pro
index 85b4131..4226fd9 100644
--- a/Editor/Editor.pro
+++ b/Editor/Editor.pro
@@ -234,7 +234,7 @@ FORMS += \
guis/StageFilterGUI.ui
INCLUDEPATH += $$PWD/.. "C:/Program Files/libsndfile/include" "C:/Program Files/fftw3" "C:/Program Files/muparserx_v3_0_1/parser"
-LIBS += advapi32.lib version.lib ole32.lib Shlwapi.lib libsndfile-1.lib libfftw3f-3.lib
+LIBS += advapi32.lib version.lib ole32.lib Shlwapi.lib authz.lib libsndfile-1.lib libfftw3f-3.lib
build_pass:CONFIG(debug, debug|release) {
LIBS += muparserxd.lib
diff --git a/Editor/guis/ConvolutionFilterGUI.cpp b/Editor/guis/ConvolutionFilterGUI.cpp
index b88f27b..43fc33a 100644
--- a/Editor/guis/ConvolutionFilterGUI.cpp
+++ b/Editor/guis/ConvolutionFilterGUI.cpp
@@ -21,6 +21,7 @@
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
#include
+#include "helpers/RegistryHelper.h"
#include "ConvolutionFilterGUI.h"
#include "ui_ConvolutionFilterGUI.h"
@@ -102,27 +103,45 @@ void ConvolutionFilterGUI::updateFileInfo()
}
else
{
- path = fileInfo.absoluteFilePath();
+ path = QDir::toNativeSeparators(fileInfo.absoluteFilePath());
- SF_INFO info;
- SNDFILE* file = sf_wchar_open(path.toStdWString().c_str(), SFM_READ, &info);
- if (file == NULL)
+ ACCESS_MASK mask = GENERIC_READ;
+ try
{
- error = tr("Unsupported file format");
+ mask = RegistryHelper::getFileAccessForUser(path.toStdWString(), SECURITY_LOCAL_SERVICE_RID);
+ }
+ catch (RegistryException e)
+ {
+ // ignore
+ }
+
+ if ((mask & GENERIC_READ) != GENERIC_READ && (mask & FILE_GENERIC_READ) != FILE_GENERIC_READ)
+ {
+ error = tr("The file is not readable for the audio service.\nChange the file permissions or copy the file to the config directory.");
labelsVisible = false;
}
else
{
- int sampleRate = info.samplerate;
- double length = info.frames * 1000.0 / sampleRate;
-
- ui->labelLengthValue->setText(tr("%0 ms (%1 samples)").arg(length).arg(info.frames));
- ui->labelSampleRateValue->setText(tr("%0 Hz").arg(sampleRate));
- sf_close(file);
-
- if (sampleRate != deviceSampleRate)
+ SF_INFO info;
+ SNDFILE* file = sf_wchar_open(path.toStdWString().c_str(), SFM_READ, &info);
+ if (file == NULL)
{
- error = tr("The file sample rate does not match the device sample rate (%0 Hz)!\nSelect a different file or change the device configuration.").arg(deviceSampleRate);
+ error = tr("Unsupported file format");
+ labelsVisible = false;
+ }
+ else
+ {
+ int sampleRate = info.samplerate;
+ double length = info.frames * 1000.0 / sampleRate;
+
+ ui->labelLengthValue->setText(tr("%0 ms (%1 samples)").arg(length).arg(info.frames));
+ ui->labelSampleRateValue->setText(tr("%0 Hz").arg(sampleRate));
+ sf_close(file);
+
+ if (sampleRate != deviceSampleRate)
+ {
+ error = tr("The file sample rate does not match the device sample rate (%0 Hz)!\nSelect a different file or change the device configuration.").arg(deviceSampleRate);
+ }
}
}
}
diff --git a/Editor/translations/Editor_de.qm b/Editor/translations/Editor_de.qm
index 150511dc3886a94d1eacc0766f814a723d69006c..1486545f6fb94c442dd1c70501586e98d1c6adad 100644
GIT binary patch
delta 2131
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
-
+
No file selected
Keine Datei gewählt
@@ -303,41 +303,48 @@
Länge:
-
+
Select impulse response file
Impulsantwort auswählen
-
+
Impulse response (*.wav *.flac *.ogg)
Impulsantwort (*.wav *.flac *.ogg)
-
+
File not found
Datei nicht gefunden
-
+
+ The file is not readable for the audio service.
+Change the file permissions or copy the file to the config directory.
+ Die Datei ist für den Audiodienst nicht lesbar.
+Ändern Sie die Dateiberechtigungen oder kopieren Sie die Datei in das config-Verzeichnis.
+
+
+
Unsupported file format
Nicht unterstütztes Dateiformat
-
+
%0 ms (%1 samples)
%0 ms (%1 Samples)
-
+
%0 Hz
%0 Hz
-
+
The file sample rate does not match the device sample rate (%0 Hz)!
Select a different file or change the device configuration.
Die Abtastrate der Datei stimmt nicht mit der Abtastrate des Geräts (%0 Hz) überein!
-Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.
+Wählen Sie eine andere Datei oder ändern Sie die Konfiguration des Geräts.
@@ -773,18 +780,18 @@ Wählen Sie eine andere Datei or ändern Sie die Konfiguration des Geräts.
-
+
Frequency response (*.csv)
Frequenzgang (*.csv)
-
+
All files (*.*)
Alle Dateien (*.*)
-
+
Export frequency response
Frequenzgang exportieren
@@ -1137,8 +1144,8 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?
-
-
+
+
Error
Fehler
@@ -1148,23 +1155,23 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?Fehler beim Lesen der Konfigurationsdatei: %0
-
+
Error while writing configuration file: %0
Fehler beim Schreiben der Konfigurationsdatei: %0
-
+
Only %0/%1 bytes have been written!
Nur %0/%1 Bytes wurden geschrieben!
+
-
From device
Von Gerät
-
+
%0 dB
%0 dB
@@ -1173,7 +1180,7 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?%0 ms (%1 Samp.)
-
+
%0 ms (%1 s.)
%0 ms (%1 S.)
@@ -1182,46 +1189,46 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?%0 ms (%1 Samples)
-
+
%0 ms
%0 ms
-
+
%0 % (one core)
%0 % (ein Kern)
-
-
-
+
+
+
Restart required
Neustart erforderlich
-
-
-
+
+
+
Configuration Editor will be restarted to apply the changed settings. Proceed?
Konfigurationseditor wird neugestartet, um die geänderten Einstellungen zu übernehmen. Fortsetzen?
-
+
Unsaved changes
Ungespeicherte Änderungen
-
+
The configuration file %0 has unsaved changes.
Die Konfigurationsdatei %0 hat ungespeicherte Änderungen.
-
+
Do you want to save the changes before closing the file?
Möchten Sie die Änderungen speichern, bevor die Datei geschlossen wird?
-
+
Open file
Datei öffnen
@@ -1231,18 +1238,18 @@ Möchten Sie die Configurator-Anwendung starten, um das Problem zu beheben?Automatisch (%0)
-
-
+
+
E-APO configurations (*.txt)
E-APO-Konfigurationen (*.txt)
-
+
Save file as
Datei speichern unter
-
+
Unsaved
Ungespeichert
diff --git a/EqualizerAPO.vcxproj b/EqualizerAPO.vcxproj
index 1f80157..84b283c 100644
--- a/EqualizerAPO.vcxproj
+++ b/EqualizerAPO.vcxproj
@@ -99,7 +99,7 @@
Windows
true
- muparserxd.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserxd.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
EqualizerAPO.def
@@ -116,7 +116,7 @@
Windows
true
- muparserxd.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserxd.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
EqualizerAPO.def
@@ -138,7 +138,7 @@
true
true
true
- muparserx.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserx.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
EqualizerAPO.def
@@ -157,7 +157,7 @@
true
true
true
- muparserx.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
+ muparserx.lib;audioeng.lib;version.lib;wmcodecdspuuid.lib;AudioBaseProcessingObject.lib;audiomediatypecrt.lib;Shlwapi.lib;authz.lib;libsndfile-1.lib;libfftw3f-3.lib;%(AdditionalDependencies)
EqualizerAPO.def
diff --git a/helpers/RegistryHelper.cpp b/helpers/RegistryHelper.cpp
index 265e269..7c3abaf 100644
--- a/helpers/RegistryHelper.cpp
+++ b/helpers/RegistryHelper.cpp
@@ -22,6 +22,7 @@
#include
#include
#include
+#include
#include "StringHelper.h"
#include "RegistryHelper.h"
@@ -410,6 +411,57 @@ void RegistryHelper::takeOwnership(wstring key)
LocalFree(sd);
}
+ACCESS_MASK RegistryHelper::getFileAccessForUser(std::wstring path, unsigned long rid)
+{
+ ACCESS_MASK result;
+
+ PSECURITY_DESCRIPTOR sd;
+ if (GetNamedSecurityInfoW(path.c_str(), SE_FILE_OBJECT, DACL_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION
+ | GROUP_SECURITY_INFORMATION, NULL, NULL, NULL, NULL, &sd) != ERROR_SUCCESS)
+ throw RegistryException(L"Error in GetNamedSecurityInfoW while getting file access");
+
+ AUTHZ_RESOURCE_MANAGER_HANDLE manager;
+ if (!AuthzInitializeResourceManager(AUTHZ_RM_FLAG_NO_AUDIT, NULL, NULL, NULL, NULL, &manager))
+ throw RegistryException(L"Error in AuthzInitializeResourceManager while getting file access");
+
+ PSID sid = NULL;
+ SID_IDENTIFIER_AUTHORITY authority = SECURITY_NT_AUTHORITY;
+ if (!AllocateAndInitializeSid(&authority, 1, rid, 0, 0, 0, 0, 0, 0, 0, &sid))
+ throw RegistryException(L"Error in AllocateAndInitializeSid while getting file access");
+
+ LUID unusedId = {0};
+ AUTHZ_CLIENT_CONTEXT_HANDLE context;
+ if (!AuthzInitializeContextFromSid(0, sid, manager, NULL, unusedId, NULL, &context))
+ throw RegistryException(L"Error in AuthzInitializeContextFromSid while getting file access");
+
+ AUTHZ_ACCESS_REQUEST request = {0};
+
+ request.DesiredAccess = MAXIMUM_ALLOWED;
+ request.PrincipalSelfSid = NULL;
+ request.ObjectTypeList = NULL;
+ request.ObjectTypeListLength = 0;
+ request.OptionalArguments = NULL;
+
+ AUTHZ_ACCESS_REPLY reply = {0};
+ BYTE buf[1024];
+ RtlZeroMemory(buf, sizeof(buf));
+ reply.ResultListLength = 1;
+ reply.GrantedAccessMask = (ACCESS_MASK*)buf;
+ reply.Error = (DWORD*)(buf + sizeof(ACCESS_MASK));
+
+ if (!AuthzAccessCheck(0, context, &request, NULL, sd, NULL, 0, &reply, NULL))
+ throw RegistryException(L"Error in AuthzAccessCheck while getting file access");
+
+ result = *reply.GrantedAccessMask;
+
+ AuthzFreeContext(context);
+ FreeSid(sid);
+ AuthzFreeResourceManager(manager);
+ LocalFree(sd);
+
+ return result;
+}
+
bool RegistryHelper::keyExists(wstring key)
{
bool result;
diff --git a/helpers/RegistryHelper.h b/helpers/RegistryHelper.h
index ba0676a..af6fe1e 100644
--- a/helpers/RegistryHelper.h
+++ b/helpers/RegistryHelper.h
@@ -49,6 +49,7 @@ public:
static void deleteKey(std::wstring key);
static void makeWritable(std::wstring key);
static void takeOwnership(std::wstring key);
+ static ACCESS_MASK getFileAccessForUser(std::wstring path, unsigned long rid);
static std::vector enumSubKeys(std::wstring key);
static bool keyExists(std::wstring key);
static bool valueExists(std::wstring key, std::wstring valuename);